brainiac-fizzy 0.0.28 → 0.0.29

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5d55859eafd2aeccf63a2083999340a1ce4a77c01b81a8297adf136b0e553b3
4
- data.tar.gz: b1dbff19165dec2cf391f4c258ae2a207457cdc53088ee44062ffda050530a48
3
+ metadata.gz: 93dfc73c8a3984f834883fbc59057446f220cf640ef14feecdc3882eab0f5e79
4
+ data.tar.gz: 16dccf767e981ab8b7ec4f4c9ad570a6af713fe9deb410f0e3163f8745def891
5
5
  SHA512:
6
- metadata.gz: 9438b9143636ab612da09a19be5b672ada809095317ea7ce72d9045acbebe6601d5485ba4bfd234b85edcdb54a6d676edd330a74b4241cc85c0605d590fe523d
7
- data.tar.gz: 93fbe26b2a546b1b72e1025f7af334ac6539efe0c4144338bd6d2929b336e2ed21752cc8a1d4ef2949d380cc72635e945e0dad819afe043570c483ddc889d2d7
6
+ metadata.gz: dfabf4b7239f9fa9181fb327c24660e7c39c0a1558151362330ff67c8c334ba9565239e5da35c1335c67bd5dfdd246cacf8295509e6e61c86b9afb0f2f6be43d
7
+ data.tar.gz: ebafbeceb274b07e70f23f69d8b7123af573d646e58d92eb756b693bf2cf4d87a12ab7fc79ddca3ced785c54d3beca9c8c602a4c655d0158067cc952d441a90f
data/README.md CHANGED
@@ -37,6 +37,8 @@ Fizzy configuration lives in `~/.brainiac/fizzy.json` (same as before):
37
37
  { "id": "user-id-1", "name": "Andy", "human": true },
38
38
  { "id": "agent-id-1", "name": "Galen", "human": false }
39
39
  ],
40
+ "uat_agent": false,
41
+ "uat_agent_tag": "uat",
40
42
  "boards": {
41
43
  "development": {
42
44
  "board_id": "your-board-id",
@@ -51,6 +53,25 @@ Fizzy configuration lives in `~/.brainiac/fizzy.json` (same as before):
51
53
  }
52
54
  ```
53
55
 
56
+ ### UAT agent (`uat_agent`)
57
+
58
+ When a PR is merged and its card moves to the UAT column, Brainiac can dispatch
59
+ an LLM agent to write manual testing steps as a card comment. This spends tokens
60
+ on every merge, so it's **disabled by default**. Set `"uat_agent": true` at the
61
+ top level of `fizzy.json` to opt back in globally. The card still moves to UAT
62
+ and gets the PR-merged comment either way — only the agent dispatch is gated.
63
+
64
+ **Per-card opt-in:** Even with `uat_agent` off globally, you can trigger the UAT
65
+ agent for a single card by adding the `uat` tag to it. When the card's PR merges,
66
+ Brainiac fetches the card's live tags and dispatches the UAT agent if the tag is
67
+ present. Customize the tag name with `"uat_agent_tag": "your-tag"`, or set it to
68
+ `false`/`null` to disable per-card overrides entirely. This gives you three
69
+ states:
70
+
71
+ - `uat_agent: true` — dispatch on every merge
72
+ - `uat_agent: false` (default) + `uat` tag on a card — dispatch for that card only
73
+ - `uat_agent: false` + no tag — never dispatch (pure bookkeeping, zero tokens)
74
+
54
75
  ## What This Plugin Handles
55
76
 
56
77
  | Event | Action |
@@ -82,6 +82,26 @@ module Brainiac
82
82
  nil
83
83
  end
84
84
 
85
+ # Whether to dispatch an LLM agent to write UAT testing steps when a
86
+ # PR is merged and the card moves to UAT. Disabled by default to save
87
+ # tokens — set "uat_agent": true in ~/.brainiac/fizzy.json to enable
88
+ # globally. Individual cards can still opt in via the UAT tag even when
89
+ # this is false (see #uat_agent_tag).
90
+ def uat_agent_enabled?
91
+ @config.fetch("uat_agent", false) == true
92
+ end
93
+
94
+ # The card tag that opts a single card into UAT agent dispatch even
95
+ # when uat_agent is globally disabled. Defaults to "uat". Set
96
+ # "uat_agent_tag": "some-tag" in fizzy.json to customize, or false/null
97
+ # to disable per-card overrides entirely.
98
+ def uat_agent_tag
99
+ value = @config.fetch("uat_agent_tag", "uat")
100
+ return nil if value == false || value.nil? || value.to_s.strip.empty?
101
+
102
+ value.to_s
103
+ end
104
+
85
105
  def authorized?(payload)
86
106
  creator_id = payload.dig("creator", "id")
87
107
  @authorized_user_ids.include?(creator_id)
@@ -134,36 +134,7 @@ module Brainiac
134
134
  # PR merged — post comment on Fizzy card, move to UAT, dispatch UAT agent
135
135
  def register_pr_merged
136
136
  Brainiac.on(:pr_merged) do |ctx|
137
- card_number = ctx[:card_number]
138
- next unless card_number
139
-
140
- card_info = ctx[:card_info]
141
- card_agent = card_info["agent"]
142
- env = Helpers.fizzy_env_for(card_agent)
143
- repo_path = ctx[:repo_path]
144
- board_key = card_info.dig("sources", "fizzy", "board_key") || Config.board_key_for_project(ctx[:project_config])
145
-
146
- # Post PR link comment
147
- pr_url = ctx[:pr_url]
148
- pr_title = ctx[:pr_title]
149
- branch = ctx[:branch]
150
- comment_body = "<p>PR merged into main: <a href=\"#{pr_url}\">#{pr_title}</a></p>" \
151
- "<p>Branch: <code>#{branch}</code></p>"
152
- run_cmd("fizzy", "comment", "create", "--card", card_number.to_s, "--body", comment_body,
153
- chdir: repo_path, env: env)
154
-
155
- # Move card to UAT
156
- Helpers.move_card_to_column(card_number, "uat",
157
- project_config: ctx[:project_config],
158
- agent_name: card_agent,
159
- board_key: board_key)
160
- record_self_move(card_number)
161
-
162
- # Clear deployment tracking
163
- clear_deployment_for_card(card_number) if respond_to?(:clear_deployment_for_card)
164
-
165
- # Dispatch UAT agent
166
- dispatch_fizzy_uat_agent(ctx)
137
+ handle_pr_merged(ctx)
167
138
  rescue StandardError => e
168
139
  LOG.error "[Fizzy] Error in pr_merged hook: #{e.message}" if defined?(LOG)
169
140
  end
@@ -292,6 +263,75 @@ module Brainiac
292
263
 
293
264
  # --- Private helpers ---
294
265
 
266
+ # Body of the :pr_merged hook. Posts the PR link comment, moves the
267
+ # card to UAT, clears deployment tracking, and dispatches the UAT
268
+ # agent when enabled. Extracted from the hook block to keep the
269
+ # registration method within complexity limits.
270
+ def handle_pr_merged(ctx)
271
+ card_number = ctx[:card_number]
272
+ return unless card_number
273
+
274
+ card_info = ctx[:card_info]
275
+ card_agent = card_info["agent"]
276
+ env = Helpers.fizzy_env_for(card_agent)
277
+ repo_path = ctx[:repo_path]
278
+ board_key = card_info.dig("sources", "fizzy", "board_key") || Config.board_key_for_project(ctx[:project_config])
279
+
280
+ # Post PR link comment
281
+ comment_body = "<p>PR merged into main: <a href=\"#{ctx[:pr_url]}\">#{ctx[:pr_title]}</a></p>" \
282
+ "<p>Branch: <code>#{ctx[:branch]}</code></p>"
283
+ run_cmd("fizzy", "comment", "create", "--card", card_number.to_s, "--body", comment_body,
284
+ chdir: repo_path, env: env)
285
+
286
+ # Move card to UAT
287
+ Helpers.move_card_to_column(card_number, "uat",
288
+ project_config: ctx[:project_config],
289
+ agent_name: card_agent,
290
+ board_key: board_key)
291
+ record_self_move(card_number)
292
+
293
+ # Clear deployment tracking
294
+ clear_deployment_for_card(card_number) if respond_to?(:clear_deployment_for_card)
295
+
296
+ # Dispatch UAT agent — off by default to save tokens. Globally
297
+ # enabled via "uat_agent": true, or per-card via the UAT tag
298
+ # (default "uat") even when the global flag is off.
299
+ if uat_agent_dispatch?(card_number, repo_path: repo_path, env: env)
300
+ dispatch_fizzy_uat_agent(ctx)
301
+ else
302
+ log_uat_dispatch_skipped(card_number)
303
+ end
304
+ end
305
+
306
+ # Log that UAT dispatch was skipped for a card (global flag off, no tag).
307
+ def log_uat_dispatch_skipped(card_number)
308
+ return unless defined?(LOG)
309
+
310
+ LOG.info "[Fizzy] UAT agent disabled (set \"uat_agent\": true in fizzy.json, or add the " \
311
+ "\"#{Config.uat_agent_tag}\" tag to this card) — skipping dispatch for card ##{card_number}"
312
+ end
313
+
314
+ # Decide whether to dispatch the UAT agent for a merged card.
315
+ # True when globally enabled, OR when the card carries the configured
316
+ # UAT tag (per-card opt-in). Card tags aren't in the pr_merged ctx, so
317
+ # we fetch them live — only when the global flag is off, to avoid an
318
+ # extra API call when it's already enabled.
319
+ def uat_agent_dispatch?(card_number, repo_path:, env: nil)
320
+ return true if Config.uat_agent_enabled?
321
+
322
+ tag = Config.uat_agent_tag
323
+ return false unless tag && card_number && repo_path
324
+
325
+ tags = Helpers.fetch_card_tags(card_number, repo_path: repo_path, env: env)
326
+ return false unless tags
327
+
328
+ has_tag = Helpers.card_has_tag?(tags, tag)
329
+ if has_tag && defined?(LOG)
330
+ LOG.info "[Fizzy] Card ##{card_number} has \"#{tag}\" tag — dispatching UAT agent despite global flag being off"
331
+ end
332
+ has_tag
333
+ end
334
+
295
335
  def dispatch_fizzy_uat_agent(ctx)
296
336
  card_number = ctx[:card_number]
297
337
  card_info = ctx[:card_info]
@@ -3,7 +3,7 @@
3
3
  module Brainiac
4
4
  module Plugins
5
5
  module Fizzy
6
- VERSION = "0.0.28"
6
+ VERSION = "0.0.29"
7
7
  end
8
8
  end
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brainiac-fizzy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.28
4
+ version: 0.0.29
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Davis