brainiac-fizzy 0.0.23 → 0.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/brainiac/plugins/fizzy/delegators.rb +6 -1
- data/lib/brainiac/plugins/fizzy/handlers/assignment.rb +22 -2
- data/lib/brainiac/plugins/fizzy/handlers/comments.rb +3 -1
- data/lib/brainiac/plugins/fizzy/helpers.rb +16 -0
- data/lib/brainiac/plugins/fizzy/hooks.rb +54 -4
- data/lib/brainiac/plugins/fizzy/prompts.rb +1 -0
- data/lib/brainiac/plugins/fizzy/version.rb +1 -1
- data/lib/brainiac/plugins/fizzy.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d280084c82934cffbe0868040f944eab1f244ccc10563db9b7bd8a338f86d175
|
|
4
|
+
data.tar.gz: 47343a66a5232ea0bdc3d5e0ad8244692e7b4a8ee22efc91656f0e06e6a00c8d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f6c5ddfde5c2eaf03ad0ce86bd996f6d28d1662be8e486015b16edf6c9a158d91638db521ea6f8d269b795d5f64c590e22cc0905c5fcfda7cb9a68c7494ddfd2
|
|
7
|
+
data.tar.gz: 3371c4fd11abbcdbee4ca7d5b520b1bba0180ad1c61e4172ca77cc95820cef496fc24380a71c97eb0bbe9ce4e5e48fa6934224ad605f393a5db8afb2b6b04f25
|
|
@@ -25,12 +25,17 @@ def prefetch_card_context(card_number, repo_path:, agent_name: nil)
|
|
|
25
25
|
Brainiac::Plugins::Fizzy::Helpers.prefetch_card_context(card_number, repo_path: repo_path, agent_name: agent_name)
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
+
def resolve_github_agent_env(agent_name, github_repo)
|
|
29
|
+
Brainiac::Plugins::Fizzy::Helpers.resolve_github_agent_env(agent_name, github_repo)
|
|
30
|
+
end
|
|
31
|
+
|
|
28
32
|
def fetch_intent_context(card_number, repo_path:, agent_name: nil)
|
|
29
33
|
Brainiac::Plugins::Fizzy::Helpers.fetch_intent_context(card_number, repo_path: repo_path, agent_name: agent_name)
|
|
30
34
|
end
|
|
31
35
|
|
|
32
36
|
def move_card_to_column(card_number, column_name, project_config:, agent_name: nil, board_key: nil)
|
|
33
|
-
Brainiac::Plugins::Fizzy::Helpers.move_card_to_column(card_number, column_name, project_config: project_config, agent_name: agent_name,
|
|
37
|
+
Brainiac::Plugins::Fizzy::Helpers.move_card_to_column(card_number, column_name, project_config: project_config, agent_name: agent_name,
|
|
38
|
+
board_key: board_key)
|
|
34
39
|
end
|
|
35
40
|
|
|
36
41
|
def append_fizzy_comment_footer(card_number, project_config:, agent_name: nil, since: nil)
|
|
@@ -113,7 +113,13 @@ end
|
|
|
113
113
|
def setup_assigned_worktree(repo_path, branch, card_internal_id, card_number, project_key, agent_name, board_key: nil)
|
|
114
114
|
debounced_repo_fetch(repo_path)
|
|
115
115
|
worktree_path = File.join(File.dirname(repo_path), "#{File.basename(repo_path)}--#{branch}")
|
|
116
|
-
|
|
116
|
+
|
|
117
|
+
# Allow plugins (e.g., brainiac-basecamp) to override the base branch for epic workflows.
|
|
118
|
+
base_ref = if defined?(resolve_base_branch)
|
|
119
|
+
resolve_base_branch(repo_path: repo_path, card_number: card_number, project_key: project_key)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
worktree_path = create_or_reuse_worktree(repo_path: repo_path, branch: branch, base_ref: base_ref, worktree_path: worktree_path)
|
|
117
123
|
|
|
118
124
|
source_data = { "card_internal_id" => card_internal_id, "card_number" => card_number }
|
|
119
125
|
source_data["board_key"] = board_key if board_key
|
|
@@ -134,6 +140,15 @@ def dispatch_assigned_card(card_number:, card_internal_id:, title:, tags:, branc
|
|
|
134
140
|
"CARD_NUMBER" => card_number, "CARD_TITLE" => title,
|
|
135
141
|
"BRANCH" => branch, "COMMENT_CREATOR" => agent_name
|
|
136
142
|
}
|
|
143
|
+
|
|
144
|
+
# Resolve custom PR target (for epic branch workflows)
|
|
145
|
+
pr_target = resolve_pr_target(repo_path: project_config["repo_path"], card_number: card_number, project_key: project_key)
|
|
146
|
+
template_vars["PR_TARGET_INSTRUCTION"] = if pr_target
|
|
147
|
+
"**IMPORTANT: Open the PR targeting the `#{pr_target}` branch " \
|
|
148
|
+
"(not main).** Use: `gh pr create --base #{pr_target}`"
|
|
149
|
+
else
|
|
150
|
+
""
|
|
151
|
+
end
|
|
137
152
|
brain_ctx = build_brain_context(
|
|
138
153
|
agent_name: agent_name, card_title: title,
|
|
139
154
|
card_number: card_number, project_key: project_key, source: :fizzy
|
|
@@ -151,12 +166,17 @@ def dispatch_assigned_card(card_number:, card_internal_id:, title:, tags:, branc
|
|
|
151
166
|
end
|
|
152
167
|
|
|
153
168
|
card_key = "card-#{card_number}"
|
|
169
|
+
|
|
170
|
+
# Inject GitHub App token so agent's gh commands run as their bot identity
|
|
171
|
+
github_repo = project_config["github_repo"]
|
|
172
|
+
agent_github_env = resolve_github_agent_env(agent_name, github_repo)
|
|
173
|
+
|
|
154
174
|
pid, log_file = run_agent(prompt,
|
|
155
175
|
project_config: project_config, chdir: worktree_path,
|
|
156
176
|
log_name: "assigned-#{card_number}", model: model, effort: effort,
|
|
157
177
|
agent_name: agent_name, card_number: card_number, source: :fizzy,
|
|
158
178
|
source_context: { card_number: card_number, board_key: board_key, dispatched_at: Time.now },
|
|
159
|
-
cli_provider: cli_provider_override)
|
|
179
|
+
cli_provider: cli_provider_override, env: agent_github_env)
|
|
160
180
|
register_session(card_key, pid, log_file: log_file, supersede_key: card_key, agent_name: agent_name)
|
|
161
181
|
|
|
162
182
|
Thread.new { move_card_to_column(card_number, "right_now", project_config: project_config, agent_name: agent_name, board_key: board_key) }
|
|
@@ -565,7 +565,9 @@ def dispatch_followup_comment(ctx, card_key:, card_number:, work_dir:)
|
|
|
565
565
|
|
|
566
566
|
register_session(card_key, pid, log_file: log_file, supersede_key: card_key, agent_name: ctx.agent_name)
|
|
567
567
|
|
|
568
|
-
Thread.new
|
|
568
|
+
Thread.new do
|
|
569
|
+
move_card_to_column(card_number, "right_now", project_config: ctx.project_config, agent_name: ctx.agent_name, board_key: ctx.board_key)
|
|
570
|
+
end
|
|
569
571
|
|
|
570
572
|
{ status: "follow_up", card: card_number, card_internal_id: ctx.card_internal_id,
|
|
571
573
|
worktree: work_dir, project: ctx.project_key }
|
|
@@ -33,6 +33,22 @@ module Brainiac
|
|
|
33
33
|
fizzy_env_for(AI_AGENT_NAME)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
+
# Resolve GitHub App token for an agent so gh CLI runs as their bot identity.
|
|
37
|
+
# Uses brainiac-github's AppClient if available.
|
|
38
|
+
def resolve_github_agent_env(agent_name, github_repo)
|
|
39
|
+
return {} unless github_repo
|
|
40
|
+
|
|
41
|
+
if defined?(Brainiac::Plugins::Github::AppClient)
|
|
42
|
+
repo_owner = github_repo.split("/").first
|
|
43
|
+
token = Brainiac::Plugins::Github::AppClient.installation_token_for(agent_name, repo_owner: repo_owner)
|
|
44
|
+
return { "GH_TOKEN" => token } if token
|
|
45
|
+
end
|
|
46
|
+
{}
|
|
47
|
+
rescue StandardError => e
|
|
48
|
+
LOG.warn "[Fizzy] Could not resolve GitHub token for #{agent_name}: #{e.message}" if defined?(LOG)
|
|
49
|
+
{}
|
|
50
|
+
end
|
|
51
|
+
|
|
36
52
|
def prefetch_card_context(card_number, repo_path:, agent_name: nil)
|
|
37
53
|
env = fizzy_env_for(agent_name || AI_AGENT_NAME)
|
|
38
54
|
card_details = fetch_card_details(card_number, repo_path: repo_path, env: env)
|
|
@@ -51,7 +51,7 @@ module Brainiac
|
|
|
51
51
|
# Retry once after a short delay to account for Fizzy API propagation.
|
|
52
52
|
# The agent may have posted its comment just before exiting, and the API
|
|
53
53
|
# might not return it immediately in a list call.
|
|
54
|
-
|
|
54
|
+
unless found_comment
|
|
55
55
|
sleep 5
|
|
56
56
|
found_comment = Helpers.append_fizzy_comment_footer(card_number,
|
|
57
57
|
project_config: ctx[:project_config],
|
|
@@ -167,17 +167,63 @@ module Brainiac
|
|
|
167
167
|
rescue StandardError => e
|
|
168
168
|
LOG.error "[Fizzy] Error in pr_merged hook: #{e.message}" if defined?(LOG)
|
|
169
169
|
end
|
|
170
|
+
|
|
171
|
+
# Also listen for epic branch merges (from brainiac-basecamp)
|
|
172
|
+
# Move card to UAT when merged to any tracked branch
|
|
173
|
+
Brainiac.on(:pr_merged_to_branch) do |ctx|
|
|
174
|
+
card_number = ctx[:card_number]
|
|
175
|
+
next unless card_number
|
|
176
|
+
|
|
177
|
+
# Find the work item to get card info
|
|
178
|
+
branch = ctx[:branch]
|
|
179
|
+
work_item = find_work_item_by_branch(branch) if respond_to?(:find_work_item_by_branch, true)
|
|
180
|
+
work_item ||= Object.respond_to?(:find_work_item_by_branch, true) ? Object.send(:find_work_item_by_branch, branch) : nil
|
|
181
|
+
|
|
182
|
+
next unless work_item
|
|
183
|
+
|
|
184
|
+
_internal_id, card_info = work_item
|
|
185
|
+
card_agent = card_info["agent"]
|
|
186
|
+
board_key = card_info.dig("sources", "fizzy", "board_key")
|
|
187
|
+
|
|
188
|
+
# Load project config
|
|
189
|
+
project_key = card_info.dig("sources", "fizzy", "project") || card_info["project"]
|
|
190
|
+
projects_file = File.join(ENV.fetch("BRAINIAC_DIR", File.join(Dir.home, ".brainiac")), "projects.json")
|
|
191
|
+
projects = File.exist?(projects_file) ? JSON.parse(File.read(projects_file)) : {}
|
|
192
|
+
project_config = projects[project_key] || {}
|
|
193
|
+
repo_path = project_config["repo_path"]
|
|
194
|
+
|
|
195
|
+
next unless repo_path
|
|
196
|
+
|
|
197
|
+
# Move card to UAT (same as main merge)
|
|
198
|
+
LOG.info "[Fizzy] PR merged to #{ctx[:base_branch]} for card ##{card_number} — moving to UAT" if defined?(LOG)
|
|
199
|
+
Helpers.move_card_to_column(card_number, "uat",
|
|
200
|
+
project_config: project_config,
|
|
201
|
+
agent_name: card_agent,
|
|
202
|
+
board_key: board_key)
|
|
203
|
+
record_self_move(card_number)
|
|
204
|
+
rescue StandardError => e
|
|
205
|
+
LOG.error "[Fizzy] Error in pr_merged_to_branch hook: #{e.message}" if defined?(LOG)
|
|
206
|
+
end
|
|
170
207
|
end
|
|
171
208
|
|
|
172
209
|
# PR review received — post status comment on card
|
|
210
|
+
# Only for changes_requested reviews that need action, not for approvals or gate reviews
|
|
173
211
|
def register_pr_review_received
|
|
174
212
|
Brainiac.on(:pr_review_received) do |ctx|
|
|
175
213
|
card_number = ctx[:card_number]
|
|
176
214
|
next unless card_number
|
|
177
215
|
|
|
216
|
+
# Only post status for changes_requested — approvals don't need a Fizzy comment
|
|
217
|
+
review_state = ctx[:review_state]
|
|
218
|
+
next unless review_state == "changes_requested"
|
|
219
|
+
|
|
220
|
+
# Skip if this is a gate agent review (handled by brainiac-basecamp)
|
|
221
|
+
reviewer = ctx[:reviewer]
|
|
222
|
+
next if reviewer&.match?(/-(brainiac|bot)\b/i)
|
|
223
|
+
|
|
178
224
|
Thread.new do
|
|
179
225
|
env = Helpers.fizzy_env_for(ctx[:agent_name])
|
|
180
|
-
status_comment = "<p>🔄 Code review received from @#{
|
|
226
|
+
status_comment = "<p>🔄 Code review received from @#{reviewer}. Updates in progress...</p>"
|
|
181
227
|
run_cmd("fizzy", "comment", "create", "--card", card_number.to_s, "--body", status_comment,
|
|
182
228
|
chdir: ctx[:repo_path], env: env)
|
|
183
229
|
rescue StandardError => e
|
|
@@ -375,7 +421,11 @@ module Brainiac
|
|
|
375
421
|
"--board", board_id, "--all", "--json",
|
|
376
422
|
chdir: Dir.home)
|
|
377
423
|
unless status.success?
|
|
378
|
-
parsed =
|
|
424
|
+
parsed = begin
|
|
425
|
+
JSON.parse(stdout)
|
|
426
|
+
rescue StandardError
|
|
427
|
+
nil
|
|
428
|
+
end
|
|
379
429
|
if parsed&.dig("code") == "forbidden"
|
|
380
430
|
LOG.warn "[Fizzy] Webhook check failed for board '#{board_key}' (admin_token lacks permission)"
|
|
381
431
|
else
|
|
@@ -384,7 +434,7 @@ module Brainiac
|
|
|
384
434
|
next
|
|
385
435
|
end
|
|
386
436
|
|
|
387
|
-
webhooks =
|
|
437
|
+
webhooks = JSON.parse(stdout)["data"] || []
|
|
388
438
|
webhooks.each do |webhook|
|
|
389
439
|
next unless webhook["name"]&.start_with?("brainiac")
|
|
390
440
|
next if webhook["active"]
|
|
@@ -59,6 +59,7 @@ module Brainiac
|
|
|
59
59
|
You have been assigned Fizzy card #{{CARD_NUMBER}}: "{{CARD_TITLE}}".
|
|
60
60
|
You are on branch "{{BRANCH}}" in a fresh worktree.
|
|
61
61
|
Implement the task, commit, push, and open a PR (link back to Fizzy).
|
|
62
|
+
{{PR_TARGET_INSTRUCTION}}
|
|
62
63
|
|
|
63
64
|
**Response destination: Post your response as a comment on Fizzy card #{{CARD_NUMBER}}.**
|
|
64
65
|
Your comment MUST include a concise summary of what you did, a PR link, and the branch name.
|
|
@@ -178,7 +178,7 @@ module Brainiac
|
|
|
178
178
|
config = DEPLOYMENTS_CONFIG["environments"] || {}
|
|
179
179
|
halt 404, { error: "Unknown environment: #{env_key}" }.to_json unless config.key?(env_key)
|
|
180
180
|
request.body.rewind
|
|
181
|
-
|
|
181
|
+
begin
|
|
182
182
|
JSON.parse(request.body.read)
|
|
183
183
|
rescue StandardError
|
|
184
184
|
{}
|