brainiac-fizzy 0.0.38 → 0.0.40

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: c61ec846d3ddf6b13adfdd9e28d6986b95104fa8f8d7a3542358dafd52f80378
4
- data.tar.gz: 2438032f1be99280f4ef0807a481f204edff399c4c42a1ea82970beb905fb33e
3
+ metadata.gz: 28fbadc41d99487b978f4036cb01b1542845f52f3bd178919be07dcddbc4349f
4
+ data.tar.gz: 2e6211601c03da786f65cec18deff6036ed2706852c48a52940e1aee49c18976
5
5
  SHA512:
6
- metadata.gz: 2b13027d874d36db9e29698bbd21b6d959f640314fdd494ec68b67f177c5f999676ba6fec753a5e09cf8219c19c2701d75a235732888c728fcde1ae379c919fd
7
- data.tar.gz: ddccb8370bc7c2f367fa42551660e2f4dcc50460fee1615d7da4044dfff0728cc1e739e51ac7bbd45f2daa4f5ea139a4fccb6f06b0820085d742641962cc4bc6
6
+ metadata.gz: 0c7ffbb796a4237092775cd64baba8f825545b1dcc11294b6c496c0063c9287f67c036f0684c1ccc294835620120556607013d365a9f509b6143ab8f693a9ac4
7
+ data.tar.gz: 9a54517e3427f2c4bff7a0153caa36cdc25f41baabf14e282ee4506bf50bb6f4f340bc3e787a372844de4c7e3b297018430581bc29099560bb563e862a5f07b1
@@ -25,6 +25,10 @@ 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 prefetch_followup_context(card_number, repo_path:, agent_name: nil)
29
+ Brainiac::Plugins::Fizzy::Helpers.prefetch_followup_context(card_number, repo_path: repo_path, agent_name: agent_name)
30
+ end
31
+
28
32
  def tag_names(tags)
29
33
  Brainiac::Plugins::Fizzy::Helpers.tag_names(tags)
30
34
  end
@@ -164,8 +168,8 @@ DEFAULT_COLUMN_IDS = {
164
168
  # Render planning mode prompt — identical to render_prompt but inserts the planning
165
169
  # instructions between PROMPT_CORE and the channel rules. This was originally defined
166
170
  # in brainiac core's planning.rb but belongs here after the fizzy extraction.
167
- def render_planning_prompt(situation_template, vars = {}, brain_context: "", card_context: "", agent_name: AI_AGENT_NAME,
168
- channel: :fizzy, board_key: nil)
171
+ def render_planning_prompt(situation_template, vars = {}, brain_context: "", card_context: "", comment_history: "",
172
+ agent_name: AI_AGENT_NAME, channel: :fizzy, board_key: nil)
169
173
  plans_dir = Brainiac::Plugins::Fizzy::Planning::PLANS_DIR
170
174
  plan_file = File.join(plans_dir, "card-#{vars["CARD_ID"]}-plan.md")
171
175
 
@@ -178,6 +182,10 @@ def render_planning_prompt(situation_template, vars = {}, brain_context: "", car
178
182
  result += plugin_prompt || CHANNEL_PROMPTS.fetch(channel, "")
179
183
  result += situation_template
180
184
 
185
+ # Comment history (for follow-up scenarios): placed AFTER the triggering comment
186
+ # so the agent sees the current request first, then can reference history as needed
187
+ result += comment_history unless comment_history.empty?
188
+
181
189
  # Pre-post comment check (same as render_prompt — use plugin-registered lookup)
182
190
  plugin_pre_post = Brainiac.channel_pre_post_checks[channel]
183
191
  result += plugin_pre_post if plugin_pre_post
@@ -780,46 +780,58 @@ def build_followup_prompt(ctx, card_number, card_tags, work_dir)
780
780
  if planning_info
781
781
  build_planning_followup_prompt(ctx, card_number, planning_info[:card_id], work_dir)
782
782
  elsif work_dir != ctx.project_config["repo_path"]
783
+ # Use split context for follow-ups: card details at top, comment history AFTER triggering comment
784
+ followup_ctx = prefetch_followup_context(card_number, repo_path: work_dir, agent_name: ctx.agent_name)
783
785
  render_prompt(PROMPT_FOLLOWUP_WORKTREE,
784
786
  ctx.comment_vars.merge("CARD_NUMBER" => card_number, "CARD_ID" => card_number),
785
787
  brain_context: build_brain_context(
786
788
  agent_name: ctx.agent_name, card_number: card_number,
787
789
  project_key: ctx.project_key, comment_body: ctx.plain_text, source: :fizzy
788
790
  ),
789
- card_context: prefetch_card_context(card_number, repo_path: work_dir, agent_name: ctx.agent_name),
791
+ card_context: followup_ctx[:card_details],
792
+ comment_history: followup_ctx[:comment_history],
790
793
  agent_name: ctx.agent_name)
791
794
  else
795
+ # Use split context for follow-ups: card details at top, comment history AFTER triggering comment
796
+ followup_ctx = prefetch_followup_context(card_number, repo_path: ctx.project_config["repo_path"],
797
+ agent_name: ctx.agent_name)
792
798
  render_prompt(PROMPT_FOLLOWUP_NO_WORKTREE,
793
799
  ctx.comment_vars.merge("CARD_INTERNAL_ID" => ctx.card_internal_id, "CARD_ID" => ctx.card_internal_id),
794
800
  brain_context: build_brain_context(
795
801
  agent_name: ctx.agent_name, project_key: ctx.project_key,
796
802
  comment_body: ctx.plain_text, source: :fizzy
797
803
  ),
798
- card_context: prefetch_card_context(card_number, repo_path: ctx.project_config["repo_path"],
799
- agent_name: ctx.agent_name),
804
+ card_context: followup_ctx[:card_details],
805
+ comment_history: followup_ctx[:comment_history],
800
806
  agent_name: ctx.agent_name)
801
807
  end
802
808
  end
803
809
 
804
810
  def build_planning_followup_prompt(ctx, card_number, card_id, work_dir)
805
811
  if work_dir == ctx.project_config["repo_path"]
812
+ # Use split context for follow-ups: card details at top, comment history AFTER triggering comment
813
+ followup_ctx = prefetch_followup_context(card_number, repo_path: ctx.project_config["repo_path"],
814
+ agent_name: ctx.agent_name)
806
815
  render_planning_prompt(PROMPT_FOLLOWUP_NO_WORKTREE,
807
816
  ctx.comment_vars.merge("CARD_INTERNAL_ID" => ctx.card_internal_id, "CARD_ID" => card_id),
808
817
  brain_context: build_brain_context(
809
818
  agent_name: ctx.agent_name, project_key: ctx.project_key,
810
819
  comment_body: ctx.plain_text, source: :fizzy
811
820
  ),
812
- card_context: prefetch_card_context(card_number, repo_path: ctx.project_config["repo_path"],
813
- agent_name: ctx.agent_name),
821
+ card_context: followup_ctx[:card_details],
822
+ comment_history: followup_ctx[:comment_history],
814
823
  agent_name: ctx.agent_name)
815
824
  else
825
+ # Use split context for follow-ups: card details at top, comment history AFTER triggering comment
826
+ followup_ctx = prefetch_followup_context(card_number, repo_path: work_dir, agent_name: ctx.agent_name)
816
827
  render_planning_prompt(PROMPT_FOLLOWUP_WORKTREE,
817
828
  ctx.comment_vars.merge("CARD_NUMBER" => card_number, "CARD_ID" => card_id),
818
829
  brain_context: build_brain_context(
819
830
  agent_name: ctx.agent_name, card_number: card_number,
820
831
  project_key: ctx.project_key, comment_body: ctx.plain_text, source: :fizzy
821
832
  ),
822
- card_context: prefetch_card_context(card_number, repo_path: work_dir, agent_name: ctx.agent_name),
833
+ card_context: followup_ctx[:card_details],
834
+ comment_history: followup_ctx[:comment_history],
823
835
  agent_name: ctx.agent_name)
824
836
  end
825
837
  end
@@ -60,6 +60,35 @@ module Brainiac
60
60
  context
61
61
  end
62
62
 
63
+ # Split card context for follow-up scenarios:
64
+ # - Returns card_details (title + body) separately from comment_history
65
+ # - This allows placing the triggering comment BEFORE historical comments
66
+ # so agents focus on the current request, not the full card history
67
+ # - Uses fewer comments (5 instead of 15) since the agent has memory
68
+ def prefetch_followup_context(card_number, repo_path:, agent_name: nil)
69
+ env = fizzy_env_for(agent_name || AI_AGENT_NAME)
70
+ card_details = fetch_card_details(card_number, repo_path: repo_path, env: env)
71
+ # Fewer comments for follow-ups — agent has memory from prior sessions
72
+ card_comments = fetch_card_comments(card_number, repo_path: repo_path, env: env, limit: 5)
73
+
74
+ details_context = card_details.empty? ? "" : "## Card Details\n#{card_details}\n\n"
75
+
76
+ # Format comment history as secondary reference (placed after triggering comment)
77
+ history_context = ""
78
+ unless card_comments.empty?
79
+ history_context = <<~HISTORY
80
+
81
+ ## Recent Comment History (for reference)
82
+ These are the last few comments on the card. Your PRIMARY focus is the triggering comment above,
83
+ but you can reference this history if needed for context.
84
+
85
+ #{card_comments}
86
+ HISTORY
87
+ end
88
+
89
+ { card_details: details_context, comment_history: history_context }
90
+ end
91
+
63
92
  # Normalize Fizzy tags from webhook hashes ({ "name" => "deploy" })
64
93
  # or API strings ("deploy") into a lowercase name list.
65
94
  def tag_names(tags)
@@ -105,12 +134,12 @@ module Brainiac
105
134
  ""
106
135
  end
107
136
 
108
- def fetch_card_comments(card_number, repo_path:, env:)
137
+ def fetch_card_comments(card_number, repo_path:, env:, limit: 15)
109
138
  output = run_cmd("fizzy", "comment", "list", "--card", card_number.to_s, "--all", chdir: repo_path, env: env)
110
139
  comments = JSON.parse(output)["data"] || []
111
140
  return "" if comments.empty?
112
141
 
113
- comments.last(15).map do |c|
142
+ comments.last(limit).map do |c|
114
143
  body = c.dig("body", "plain_text") || ""
115
144
  body = "#{body[0..500]}..." if body.length > 500
116
145
  "**#{c.dig("creator", "name")}** (#{c["id"]}):\n#{body}"
@@ -18,7 +18,12 @@ module Brainiac
18
18
  Cards move to "Right Now" when you're dispatched and to "Needs Review" when your session ends.
19
19
 
20
20
  ### Formatting
21
- **Fizzy comments use HTML, NOT Markdown.** Use `<h2>`/`<h3>` for sections, `<p>` for paragraphs, `<ul><li>` for lists, `<pre data-language="ruby">` for code blocks, `<strong>` for emphasis. Never use markdown syntax in Fizzy comments.
21
+ **Fizzy comments use HTML, NOT Markdown.** Use `<h2>`/`<h3>` for sections, `<p>` for paragraphs, `<ul><li>` for lists, `<pre data-language="ruby">` for code blocks, `<strong>` for emphasis, `<code>` for inline code. Never use markdown syntax in Fizzy comments.
22
+
23
+ **CRITICAL — wrap EVERY paragraph in its own `<p>` tag.** Blank lines are not
24
+ enough; raw line breaks collapse in HTML and your paragraphs squash into one
25
+ unreadable block. Right: `<p>First point.</p><p>Second point.</p>`. Wrong: two
26
+ lines separated by a blank line and no tags.
22
27
 
23
28
  ### Screenshots (MANDATORY for UI changes)
24
29
  If you touched any `.js`, `.jsx`, `.css`, or `.html` in a web app directory and `./scripts/screenshot-page.sh` exists, screenshot every affected page.
@@ -78,31 +83,40 @@ module Brainiac
78
83
  PROMPT
79
84
 
80
85
  FOLLOWUP_WORKTREE = <<~'PROMPT'
81
- There's a new comment on Fizzy card #{{CARD_NUMBER}} that you've already started working on.
82
- You are in the existing worktree for this card.
86
+ ## ⚠️ CURRENT REQUEST — This is what you need to address NOW
83
87
 
84
- The comment from {{COMMENT_CREATOR}} (comment ID: {{COMMENT_ID}}):
88
+ **New comment from {{COMMENT_CREATOR}}** on Fizzy card #{{CARD_NUMBER}} (comment ID: {{COMMENT_ID}}):
85
89
  """
86
90
  {{COMMENT_BODY}}
87
91
  """
88
92
 
89
- Focus your response on the comment above. If you've already addressed this in a previous session, reply confirming it's done.
90
- Otherwise, make the requested changes, commit, and push.
93
+ **Your task:** This comment is your PRIMARY focus. What the user says HERE takes priority.
94
+ - If you were given a multi-step task and this comment clarifies/modifies one step, apply the clarification AND still complete the other steps
95
+ - If the user asks a new question, answer that question — don't summarize prior work
96
+ - If the user requests a specific change, make that change
97
+ - Check your memory file for context on what's already been discussed/decided
98
+
99
+ You are in the existing worktree for this card. If you've already addressed what's being asked in a previous session, reply confirming it's done.
91
100
 
92
101
  **Response destination: Post your response as a comment on Fizzy card #{{CARD_NUMBER}}.**
93
102
  Do NOT post comments on the GitHub PR — this conversation is happening on the card.
94
103
  PROMPT
95
104
 
96
105
  FOLLOWUP_NO_WORKTREE = <<~PROMPT
97
- There's a new comment on a Fizzy card (internal_id: "{{CARD_INTERNAL_ID}}").
106
+ ## ⚠️ CURRENT REQUEST — This is what you need to address NOW
98
107
 
99
- The comment from {{COMMENT_CREATOR}} (comment ID: {{COMMENT_ID}}):
108
+ **New comment from {{COMMENT_CREATOR}}** on Fizzy card (internal_id: "{{CARD_INTERNAL_ID}}") (comment ID: {{COMMENT_ID}}):
100
109
  """
101
110
  {{COMMENT_BODY}}
102
111
  """
103
112
 
104
- Focus your response on the comment above. If you've already addressed this, reply confirming it's done.
105
- Otherwise, respond accordingly.
113
+ **Your task:** This comment is your PRIMARY focus. What the user says HERE takes priority.
114
+ - If you were given a multi-step task and this comment clarifies/modifies one step, apply the clarification AND still complete the other steps
115
+ - If the user asks a new question, answer that question — don't summarize prior work
116
+ - If the user requests a specific change, make that change
117
+ - Check your memory file for context on what's already been discussed/decided
118
+
119
+ If you've already addressed what's being asked, reply confirming it's done.
106
120
  PROMPT
107
121
 
108
122
  MENTION = <<~PROMPT
@@ -3,7 +3,7 @@
3
3
  module Brainiac
4
4
  module Plugins
5
5
  module Fizzy
6
- VERSION = "0.0.38"
6
+ VERSION = "0.0.40"
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.38
4
+ version: 0.0.40
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Davis