Module: Brainiac::Plugins::Github::AppClient

Defined in:
lib/brainiac/plugins/github/app_client.rb

Overview

HTTP client that authenticates as a GitHub App (installation).

When app credentials are configured (app_id + private_key_path + installation_id), API calls are made as the App's bot user — so PR comments, reactions, etc. appear with the App's identity rather than a personal user.

Supports per-agent apps: if "apps" hash in config has an entry for the agent, that agent's app credentials are used (separate avatar/identity per agent). Falls back to shared "app" config, then to gh CLI.

Constant Summary collapse

GITHUB_API =
"https://api.github.com"
TOKEN_EXPIRY_BUFFER =

refresh token 60s before expiry

60

Class Method Summary collapse

Class Method Details

.configured?(agent_key = nil) ⇒ Boolean

Returns true if GitHub App credentials are fully configured. Checks per-agent first, then shared app config. Guards against empty-string values (common in template configs).

Returns:

  • (Boolean)


34
35
36
37
38
39
40
# File 'lib/brainiac/plugins/github/app_client.rb', line 34

def configured?(agent_key = nil)
  id = Config.app_id(agent_key)
  key_path = Config.private_key_path(agent_key)
  inst_id = Config.installation_id(agent_key)

  !!(id && !id.empty? && key_path && inst_id && !inst_id.empty?)
end

.create_comment(repo, pr_number, body, agent_key: nil) ⇒ Hash

POST a comment on an issue or PR.

Parameters:

  • repo (String)

    "owner/repo"

  • pr_number (Integer)
  • body (String)

    comment markdown

  • agent_key (String, nil) (defaults to: nil)

    agent key for per-agent app identity

Returns:

  • (Hash)

    parsed response



49
50
51
# File 'lib/brainiac/plugins/github/app_client.rb', line 49

def create_comment(repo, pr_number, body, agent_key: nil)
  post("/repos/#{repo}/issues/#{pr_number}/comments", { body: body }, agent_key: agent_key)
end

.create_comment_reaction(repo, comment_id, reaction, agent_key: nil) ⇒ Hash

POST a reaction on an issue comment.

Parameters:

  • repo (String)

    "owner/repo"

  • comment_id (Integer)
  • reaction (String)

    e.g. "eyes", "+1", "rocket"

  • agent_key (String, nil) (defaults to: nil)

    agent key for per-agent app identity

Returns:

  • (Hash)

    parsed response



60
61
62
# File 'lib/brainiac/plugins/github/app_client.rb', line 60

def create_comment_reaction(repo, comment_id, reaction, agent_key: nil)
  post("/repos/#{repo}/issues/comments/#{comment_id}/reactions", { content: reaction }, agent_key: agent_key)
end

.create_review_reaction(repo, review_id, reaction, agent_key: nil) ⇒ Hash

POST a reaction on a PR review.

Parameters:

  • repo (String)

    "owner/repo"

  • review_id (Integer)
  • reaction (String)
  • agent_key (String, nil) (defaults to: nil)

    agent key for per-agent app identity

Returns:

  • (Hash)

    parsed response



71
72
73
# File 'lib/brainiac/plugins/github/app_client.rb', line 71

def create_review_reaction(repo, review_id, reaction, agent_key: nil)
  post("/repos/#{repo}/pulls/reviews/#{review_id}/reactions", { content: reaction }, agent_key: agent_key)
end

.get(path, agent_key: nil) ⇒ Hash

GET request to GitHub API.

Parameters:

  • path (String)

    API path (e.g. "/repos/owner/repo/pulls/1")

  • agent_key (String, nil) (defaults to: nil)

    agent key for per-agent app identity

Returns:

  • (Hash)

    parsed response



80
81
82
# File 'lib/brainiac/plugins/github/app_client.rb', line 80

def get(path, agent_key: nil)
  request(:get, path, agent_key: agent_key)
end

.installation_token_for(agent_key = nil, repo_owner: nil) ⇒ Object

Public accessor for installation tokens (used to inject GH_TOKEN into agent env). Returns the raw token string, or nil on failure.



103
104
105
106
107
# File 'lib/brainiac/plugins/github/app_client.rb', line 103

def installation_token_for(agent_key = nil, repo_owner: nil)
  installation_token(agent_key, repo_owner: repo_owner)
rescue StandardError
  nil
end

.post(path, body, agent_key: nil) ⇒ Hash

POST request to GitHub API.

Parameters:

  • path (String)

    API path

  • body (Hash)

    request body

  • agent_key (String, nil) (defaults to: nil)

    agent key for per-agent app identity

Returns:

  • (Hash)

    parsed response



90
91
92
# File 'lib/brainiac/plugins/github/app_client.rb', line 90

def post(path, body, agent_key: nil)
  request(:post, path, body, agent_key: agent_key)
end

.reset!Object

Reset cached tokens (useful for testing or when credentials change).



95
96
97
98
99
# File 'lib/brainiac/plugins/github/app_client.rb', line 95

def reset!
  @mutex.synchronize do
    @tokens = {}
  end
end