Module: Brainiac::Plugins::Basecamp::Client
- Defined in:
- lib/brainiac/plugins/basecamp/client.rb
Overview
Wrapper around the basecamp CLI binary.
Shells out with --json for structured responses.
Class Method Summary collapse
-
.add_comment(recording_id, content, project:) ⇒ Hash?
Add a comment to a recording (todo, card, message, etc.).
-
.auth_status ⇒ Hash?
Check auth status.
-
.clear_agent_profile ⇒ Object
Clear the current agent profile.
-
.complete_subtask(step_id, project:) ⇒ Hash?
Complete a subtask.
-
.complete_todo(todo_id) ⇒ Hash?
Complete a todo.
-
.get_subtasks(todo_id, project:) ⇒ Hash?
List subtasks (steps) for a todo.
-
.get_todo(todo_id, project:) ⇒ Hash?
Get a todo by ID with subtasks info.
-
.list_projects ⇒ Hash
List projects.
-
.parse_url(url) ⇒ Hash?
Parse a Basecamp URL to extract IDs.
-
.run(*args, profile: nil) ⇒ Hash
Run a basecamp CLI command and return parsed JSON.
-
.run_as(agent_name, *args) ⇒ Hash
Run a basecamp CLI command as a specific agent.
-
.run_safe(*args, profile: nil) ⇒ Hash?
Run a basecamp CLI command, returning nil on failure instead of raising.
-
.with_agent_profile(agent_name) ⇒ Object
Set the current agent profile for basecamp CLI commands.
Class Method Details
.add_comment(recording_id, content, project:) ⇒ Hash?
Add a comment to a recording (todo, card, message, etc.)
116 117 118 |
# File 'lib/brainiac/plugins/basecamp/client.rb', line 116 def add_comment(recording_id, content, project:) run("comments", "create", recording_id.to_s, content, "--in", project.to_s, "--json") end |
.auth_status ⇒ Hash?
Check auth status.
146 147 148 |
# File 'lib/brainiac/plugins/basecamp/client.rb', line 146 def auth_status run_safe("auth", "status", "--json") end |
.clear_agent_profile ⇒ Object
Clear the current agent profile.
22 23 24 |
# File 'lib/brainiac/plugins/basecamp/client.rb', line 22 def clear_agent_profile @current_agent_profile = nil end |
.complete_subtask(step_id, project:) ⇒ Hash?
Complete a subtask.
103 104 105 106 107 108 |
# File 'lib/brainiac/plugins/basecamp/client.rb', line 103 def complete_subtask(step_id, project:) # Use raw API to complete a step run("api", "put", "/buckets/#{project}/card_tables/steps/#{step_id}/completions.json", "--data", '{"completion":"on"}', "--json") end |
.complete_todo(todo_id) ⇒ Hash?
Complete a todo.
124 125 126 |
# File 'lib/brainiac/plugins/basecamp/client.rb', line 124 def complete_todo(todo_id) run("todos", "complete", todo_id.to_s, "--json") end |
.get_subtasks(todo_id, project:) ⇒ Hash?
List subtasks (steps) for a todo.
91 92 93 94 95 96 |
# File 'lib/brainiac/plugins/basecamp/client.rb', line 91 def get_subtasks(todo_id, project:) # Basecamp models todo subtasks as Kanban::Step records # Use the recordings list filtered by type and parent run("recordings", "list", "--in", project.to_s, "--type", "Kanban::Step", "--all", "--json") end |
.get_todo(todo_id, project:) ⇒ Hash?
Get a todo by ID with subtasks info.
82 83 84 |
# File 'lib/brainiac/plugins/basecamp/client.rb', line 82 def get_todo(todo_id, project:) run("todos", "show", todo_id.to_s, "--in", project.to_s, "--json") end |
.list_projects ⇒ Hash
List projects.
131 132 133 |
# File 'lib/brainiac/plugins/basecamp/client.rb', line 131 def list_projects run("projects", "list", "--json") end |
.parse_url(url) ⇒ Hash?
Parse a Basecamp URL to extract IDs.
139 140 141 |
# File 'lib/brainiac/plugins/basecamp/client.rb', line 139 def parse_url(url) run("url", "parse", url, "--json") end |
.run(*args, profile: nil) ⇒ Hash
Run a basecamp CLI command and return parsed JSON.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/brainiac/plugins/basecamp/client.rb', line 40 def run(*args, profile: nil) cmd = ["basecamp"] # Use the specified profile, or fall back to the current agent's name as profile profile ||= @current_agent_profile cmd += ["--profile", profile] if profile cmd += args.flatten LOG.debug "[Basecamp:Client] Running: #{cmd.join(' ')}" if defined?(LOG) && LOG.debug? stdout, stderr, status = Open3.capture3(*cmd) unless status.success? error_body = parse_json_safe(stdout) || parse_json_safe(stderr) error_msg = error_body&.dig("error") || stderr.strip.split("\n").first || "Unknown error" raise ClientError.new(error_msg, exit_code: status.exitstatus, response: error_body) end result = parse_json_safe(stdout) unless result raise ClientError.new("Failed to parse JSON response", exit_code: 0, response: nil) end result end |
.run_as(agent_name, *args) ⇒ Hash
Run a basecamp CLI command as a specific agent.
31 32 33 |
# File 'lib/brainiac/plugins/basecamp/client.rb', line 31 def run_as(agent_name, *args) run(*args, profile: agent_name.downcase) end |
.run_safe(*args, profile: nil) ⇒ Hash?
Run a basecamp CLI command, returning nil on failure instead of raising.
70 71 72 73 74 75 |
# File 'lib/brainiac/plugins/basecamp/client.rb', line 70 def run_safe(*args, profile: nil) run(*args, profile: profile) rescue ClientError => e LOG.warn "[Basecamp:Client] Command failed: #{e.}" if defined?(LOG) nil end |
.with_agent_profile(agent_name) ⇒ Object
Set the current agent profile for basecamp CLI commands. The profile name matches the agent name (e.g., "galen" → basecamp --profile galen).
17 18 19 |
# File 'lib/brainiac/plugins/basecamp/client.rb', line 17 def with_agent_profile(agent_name) @current_agent_profile = agent_name&.downcase end |