Part of #6065. Highest-value item in the epic.
Problem
Today's "Copy for AI agents" block (buildAiContextBlock, src/review/unified-comment.ts:492) is ONE combined prompt for the whole PR, built by numbering the same flat blockers: string[] already shown in "Why this is blocked" -- no file/line/rule/suggested-fix metadata, because blockers are plain strings, not structured objects.
The structured, per-finding shape this needs already exists and is unit-tested: FixHandoffBlock / buildFixHandoffBlock(finding: InlineFinding) (src/review/fix-handoff-render.ts) produces { path, line, severity, instruction, suggestedChange?, body } per finding. There's even an aggregate variant, buildFixHandoffAggregateBlock(), whose own doc comment says it mirrors "CodeRabbit's split between a per-finding 'Prompt for AI Agents' collapsible and an aggregate 'Fix all issues' prompt" -- but it's explicitly marked "NOT wired into the unified comment here" and the per-finding version is only wired into its own separate, disabled-by-default "Fix handoff" collapsible (unified-comment-bridge.ts:678), architecturally disconnected from the blockers list.
Proposed fix
- Render each blocker as its own card/section (not a flat bullet), with a per-blocker "Copy AI fix context"
<details> containing the structured FixHandoffBlock content as a fenced code block (GitHub's native copy icon on the fence is sufficient -- no custom JS, matches the existing "Copy for AI agents" pattern's own reasoning).
- Requires threading InlineFinding-shaped structured data into (or alongside)
UnifiedReviewInput.blockers, since it's currently string[]. A blocker with no structured match should fall back to today's plain-text card (graceful degradation, not a hard requirement on every blocker having full metadata).
- Keep the existing whole-PR aggregate prompt available (still useful for fixes spanning every blocker at once) -- demote it to a secondary "Copy all blockers as one prompt" option, not remove it.
- This should make
review.fixHandoff render inline per-blocker when enabled, rather than only in the separate collapsible -- confirm with a fresh read of src/review/fix-handoff.ts's current gating (isFixHandoffEnabled/shouldEmitFixHandoff) before changing default-on behavior.
Files
- src/review/unified-comment.ts
- src/review/unified-comment-bridge.ts
- src/review/fix-handoff.ts
- src/review/fix-handoff-render.ts
- tests covering: blocker with structured context, blocker without (plain-text fallback), aggregate copy-all still works
Part of #6065. Highest-value item in the epic.
Problem
Today's "Copy for AI agents" block (
buildAiContextBlock, src/review/unified-comment.ts:492) is ONE combined prompt for the whole PR, built by numbering the same flatblockers: string[]already shown in "Why this is blocked" -- no file/line/rule/suggested-fix metadata, because blockers are plain strings, not structured objects.The structured, per-finding shape this needs already exists and is unit-tested:
FixHandoffBlock/buildFixHandoffBlock(finding: InlineFinding)(src/review/fix-handoff-render.ts) produces{ path, line, severity, instruction, suggestedChange?, body }per finding. There's even an aggregate variant,buildFixHandoffAggregateBlock(), whose own doc comment says it mirrors "CodeRabbit's split between a per-finding 'Prompt for AI Agents' collapsible and an aggregate 'Fix all issues' prompt" -- but it's explicitly marked "NOT wired into the unified comment here" and the per-finding version is only wired into its own separate, disabled-by-default "Fix handoff" collapsible (unified-comment-bridge.ts:678), architecturally disconnected from the blockers list.Proposed fix
<details>containing the structured FixHandoffBlock content as a fenced code block (GitHub's native copy icon on the fence is sufficient -- no custom JS, matches the existing "Copy for AI agents" pattern's own reasoning).UnifiedReviewInput.blockers, since it's currentlystring[]. A blocker with no structured match should fall back to today's plain-text card (graceful degradation, not a hard requirement on every blocker having full metadata).review.fixHandoffrender inline per-blocker when enabled, rather than only in the separate collapsible -- confirm with a fresh read of src/review/fix-handoff.ts's current gating (isFixHandoffEnabled/shouldEmitFixHandoff) before changing default-on behavior.Files