Feat/entire review multi agent#1018
Conversation
Entire-Checkpoint: df2496dfefbe
Entire-Checkpoint: bb4a23783312
Entire-Checkpoint: 7d8205f6348c
Entire-Checkpoint: a8ea2a1b5aa2
Four fixes from end-to-end smoke testing of the multi-agent review flow:
- codex and gemini both require the prompt piped via stdin, not as a
positional arg. Mirror each agent's existing GenerateText invocation:
codex exec --skip-git-repo-check -, gemini -p " ", with
cmd.Stdin = strings.NewReader(prompt). Do NOT mirror the isolation
(TempDir + StripGitEnv) — review MUST fire the agent's hooks to drive
pending-review marker adoption. Relax the HeadlessLauncher contract
doc: Stdin MAY be set when the prompt must be piped; Stdout/Stderr
remain unwired for the caller.
- bubbletea's raw-mode terminal captures Ctrl+C as the byte 0x03 and
converts to tea.KeyMsg{KeyCtrlC} — the OS never sends SIGINT, so the
orchestrator's signal.Notify goroutine never wakes. tea.WithoutSignalHandler
lets us own signal handling but isn't enough on its own. Wire the TUI
model with an onCancel func field; the constructor takes cancelRun
from the orchestrator; the KeyCtrlC handler calls it on first press,
which cancels runCtx and propagates SIGKILL to subprocesses via
exec.CommandContext.
- Reorder the status-classification switch in runSingleAgentTask.
ctx-cancelled + signal-killed delivers an *exec.ExitError with exit
code -1, so errors.As(&exitErr) matched first and classified as
Failed. Check ctx.Err() first so cancelled runs are reported as
AgentRunCancelled with 0 succeeded / 0 failed / N cancelled in the
summary.
- Skip the FinalOutput dump for cancelled agents. The buffered partial
stdout (often 100+ lines of codex hook/tool-call noise) is rarely
useful and the user explicitly asked to stop. Show "(cancelled)" on
the header line and move on.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 6b2243c45a68
There was a problem hiding this comment.
Pull request overview
This PR introduces multi-agent support for entire review, including a parallel orchestrator with a Bubble Tea TUI status table and new headless-launch capabilities for supported agents, plus marker adoption changes to allow multiple agents to tag the same pending review.
Changes:
- Add multi-agent orchestration (
multiReviewOrchestrator) that runs multiple agents in parallel, writes a shared pending-review marker, and prints a combined result summary. - Add a Bubble Tea TUI (
reviewTUIModel) to render per-agent status/progress and previews when output is a TTY. - Introduce
agent.HeadlessLauncherand implement headless launch for Claude Code, Codex, and Gemini CLI; update review dispatching + tests.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| go.mod / go.sum | Add Bubble Tea TUI test dependency (teatest) and related indirect deps. |
| cmd/entire/cli/review.go | Add multi-agent dispatch path, MultiAgentTask/result types, and multi-agent marker adoption logic. |
| cmd/entire/cli/review_multi.go | New parallel orchestrator that runs multiple headless agents and optionally drives the TUI. |
| cmd/entire/cli/review_tui.go | New Bubble Tea model rendering a multi-agent status table with previews and cancellation handling. |
| cmd/entire/cli/review_multi_test.go | Add orchestrator tests using a fake headless agent. |
| cmd/entire/cli/review_tui_test.go | Add Bubble Tea model tests using teatest. |
| cmd/entire/cli/review_test.go | Add tests pinning picker/dispatch behavior via dependency injection. |
| cmd/entire/cli/lifecycle_test.go | Add tests for multi-agent marker adoption behavior. |
| cmd/entire/cli/agent/agent.go | Add HeadlessLauncher interface contract. |
| cmd/entire/cli/agent/claudecode/headless.go (+test) | Add Claude Code headless launch command builder and tests. |
| cmd/entire/cli/agent/codex/headless.go (+test) | Add Codex headless launch command builder and tests. |
| cmd/entire/cli/agent/geminicli/headless.go (+test) | Add Gemini CLI headless launch command builder and tests. |
Entire-Checkpoint: 932e1f838aa4
… multiple versions Claude Code's plugin cache layout is <marketplace>/<plugin>/<version>/, and a single plugin can appear under multiple version directories (e.g. after an update leaves the old content-hash version alongside the new one). The walker emitted one entry per version, so the picker showed `/pr-review-toolkit:review-pr` twice on disks where pr-review-toolkit was cached as both `cf62a6c02dc0` and `unknown`. Collapse by invocation Name after the walk — first-seen wins, ordering otherwise preserved. Regression test asserts a single entry when two version directories carry the same review command. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: ccdce9099840
Pressing Ctrl+O inside the dashboard now opens a full-screen scrollable view of a single agent's live stdout. Arrow keys scroll the buffer (up/down) and cycle between agents (left/right); Esc returns to the dashboard. Ctrl+C is ignored in detail mode so scrolling can't accidentally kill the run — user has to Esc back to cancel. Implementation: one agentBuffer (mutex + bytes.Buffer) per task, shared by the orchestrator's tee writer and the TUI model. Snapshot() copies the current contents on every repaint so the live output updates while the user is drilled in. reviewTUIModel gains detailMode/idx/scroll fields plus termHeight (tracked from WindowSizeMsg) to size the viewport. View() dispatches to a separate detailView() when detailMode is on. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: e2c15aa5c481
Smoke test surfaced stale header lines accumulating in terminal scrollback when watching a codex run drill-in live: the buffer grew mid-view, bubbletea's inline repaint couldn't erase properly, and each frame with a different line count left ghost rows. Also codex emits private-mode CSI sequences (e.g. cursor-hide \x1b[?25l) that the previous regex missed, so those control bytes were passing through into the rendered view and shifting the cursor. Three fixes bundled: - Enter/exit alt-screen via tea.EnterAltScreen / tea.ExitAltScreen on Ctrl+O and Esc. Detail view gets its own screen buffer, dashboard stays on primary. No more drill-in history in scrollback. - Pad the detail render to a fixed line count (viewport height) so every frame returns the same size — stable frame diff even in alt- screen. - Truncate each line to termWidth so codex's wide shell output can't wrap and throw off line counts; extend the ANSI-strip regex to catch ? and ; in CSI parameters (covers cursor-hide/show). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 7ee78eef2d67
Codex exec-mode emits session chrome (banners, hook firings, `exec ...` tool-call blocks, timestamped error logs) interleaved with the actual narrative response. Surfacing all of that in the multi-agent results dump buried the findings under noise. Per-agent output filters now strip codex chrome and slice the final assistant turn out of the cleaned buffer; claude-code and gemini-cli pass through unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 7759a6fcad0d
Without scope guidance, agents picked their own review surface and disagreed: codex defaulted to `origin/main...HEAD` (which pulls in commits inherited from sibling branches), claude defaulted to working-tree-only. The result was inconsistent reviews of different content on the same invocation. The composed prompt now carries an explicit scope clause that pins agents to "commits unique to this branch vs the closest ancestor branch." A new detectScopeBaseRef helper finds the nearest non-self ancestor branch (preferring the most recently authored tip), falling back to the repo's default base. The clause is commits-only — uncommitted bytecode and editor temp files were polluting findings, so users who want uncommitted work reviewed should commit first or say so in the per-run prompt textarea. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: d1a03a7c0b67
LaunchHeadlessCmd implementations called exec.LookPath up front, which made unit tests for argv shape and stdin wiring fail in CI runners that don't have claude/codex/gemini on PATH. Move the lookup to *exec.Cmd.Start by passing the bare binary name to exec.CommandContext — missing-binary errors still surface when the orchestrator runs the command (already classified as AgentRunFailed there), but construction is now infallible. Adds a regression test per agent that scrubs PATH and confirms LaunchHeadlessCmd no longer errors at construction. Updates the HeadlessLauncher interface contract to document the deferred lookup. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 548670d392c1
The multi-agent orchestrator wrote PendingReviewMarker without Skills or Prompt, but the adopting hook unconditionally copied those fields into session state. Multi-agent review sessions therefore persisted with empty ReviewSkills and ReviewPrompt, losing the "what was actually reviewed" trail in checkpoint metadata. Add an AgentEntries map keyed by agent name to PendingReviewMarker. The orchestrator populates one entry per task with that agent's own skills and composed prompt, and adoption looks up the entry matching the adopting agent. Top-level Skills/Prompt remain the single-agent path and the legacy fallback for markers without entries. Reported by Cursor Bugbot on PR #1018 (HIGH severity). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 96f09baae112
The multi-agent picker's cancel branch and the dispatchMultiAgent error-return branch both let errors propagate without setting cmd.SilenceUsage, so cobra dumped a full usage block on top of the actual error message. The single-agent picker already does the right thing — match that pattern here so user-cancelled and runtime-failure paths both produce a concise, scannable error. Reported by Copilot on PR #1018. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 17a53d070bf6
In raw mode, bubbletea captures Ctrl+C as tea.KeyCtrlC and dispatches it to the model — the orchestrator's signal.Notify goroutine never sees a SIGINT. The previous wiring passed cancelRun directly as the model's onCancel, which canceled runCtx but skipped two side effects the sigCh path performs: - Setting the cancelled atomic flag, so callers (and the result classifier) saw Cancelled=false on in-TUI cancels. - Arming the 5s SIGKILL watchdog, so any subprocess that ignored SIGTERM hung forever instead of being force-killed. Wrap onCancel in a sync.Once-guarded helper that flips both. Out-of- TUI cancels (Ctrl+C without a TTY, or external SIGTERM) still reach the original sigCh goroutine and behave the same. Reported by Copilot on PR #1018. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 2d7b15c20084
The tickMsg handler computed duration as now - m.startTime, where startTime is when the TUI itself launched. Agents that entered AgentRunRunning later (e.g., second agent when launches are serialized for any reason) showed inflated time-since-TUI durations on every tick instead of time-since-their-own-start. Stamp runStart on the queued→running transition and tick from there. The on-completion duration in agentStateMsg is unchanged because the orchestrator already measures from its own startTime per task. Reported by Copilot on PR #1018. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 7be800b1f909
stripped[:maxLine-1] sliced by bytes, which could split a multi-byte UTF-8 rune mid-sequence and produce invalid output for non-ASCII agent narrative (em-dashes, CJK, accented Latin). Switch to stringutil.TruncateRunes which already exists for exactly this case elsewhere in the package. Reported by Copilot on PR #1018. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 2f9f57be100f
- Remove unused cancelMsg type and its Update branch in review_tui.go. The type was documented as "orchestrator posts when SIGTERM begins" but had no senders — cancellation already routes through onCancel and the cancelling banner is set there. Dead code. - Fix curly-quote typo in shellQuote's docstring (review_multi_test.go). The conventional shell escape for embedding a single quote inside single quotes is '\'' — the comment had a curly quote U+201D instead of the literal sequence. Both reported by Copilot on PR #1018. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 45de134f4744
Two small fixes that surfaced after the previous PR-feedback batch: - review_tui_test.go: TestTUIModel_TickUsesPerRowRunStart used short-form type assertions (updated.(reviewTUIModel)) which errcheck flags. Wrap them in a t.Helper-tagged asReviewTUIModel helper that fails the test loudly if Update returns the wrong concrete type — same observable behavior, lint-clean. - review_multi_test.go: the previous attempt to fix the curly-quote typo in shellQuote's docstring kept getting normalized back to a curly quote by editor/formatter passes. Reword in plain prose so there are no ambiguous escape characters to round-trip through. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: 8905eba75ebd
|
@BugBot review |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit db7a12d. Configure here.
| // Truncate wide lines so they can't wrap and throw off bubbletea's | ||
| // frame-line count. Scroll with ↑/↓ if you need to see the tail. | ||
| if len(line) > maxLineWidth { | ||
| line = line[:maxLineWidth-1] + "…" |
There was a problem hiding this comment.
Detail view truncates lines by bytes, not runes
Medium Severity
The detailView method truncates lines using byte-level slicing (line[:maxLineWidth-1]), which can split multi-byte UTF-8 characters and produce invalid output. The same file's truncatePreview function correctly uses stringutil.TruncateRunes for rune-safe truncation, and there's even a dedicated test (TestTruncatePreview_RuneSafe) asserting this concern. The detail view missed the same fix.
Reviewed by Cursor Bugbot for commit db7a12d. Configure here.
| if strings.HasPrefix(line, "exec") { | ||
| inExec = true | ||
| continue | ||
| } |
There was a problem hiding this comment.
Overly broad prefix match filters valid narrative content
Medium Severity
filterCodexOutput uses strings.HasPrefix(line, "exec") to detect codex tool-call blocks, but this matches any line starting with "exec" — including legitimate narrative content like "Executing tests revealed…" or "Excellent exception handling…". Matched lines enter the inExec state, silently discarding all subsequent lines until a blank line. The codex format uses a bare exec on its own line; a stricter check like line == "exec" or strings.TrimSpace(line) == "exec" would avoid false positives.
Reviewed by Cursor Bugbot for commit db7a12d. Configure here.
| base = runContext | ||
| } else { | ||
| base = base + "\n\nFor this review: " + runContext | ||
| } |
There was a problem hiding this comment.
Skills template causes triple newline before run context
Low Severity
When composeReviewPrompt builds from skills, the template produces a trailing \n (from the last fmt.Fprintf(&sb, " %d. %s\n", ...)). Appending run context via base + "\n\nFor this review: " then creates a triple newline (\n\n\n) between skills and context. The custom-prompt path produces only a double newline (\n\n). This formatting inconsistency results in an extra blank line in the skills-based prompt.
Reviewed by Cursor Bugbot for commit db7a12d. Configure here.
Closes Phase 2 item 4 (AI-synthesized cross-agent verdict). After the per-agent dumps and the "N agents done" line, prompt the user to opt into a single synthesis pass that resolves the configured summary provider (claude/codex/gemini, same picker `entire explain` uses) and asks it to produce a unified verdict across the per-agent reviews. Default is no — synthesis is one extra LLM call, so it shouldn't fire unless the user explicitly asks. Skipped silently when stdin isn't a TTY (CI, piped output) or fewer than two agents produced usable output. Provider failures degrade gracefully to a one-line "synthesis unavailable" notice rather than blocking the user from committing. Refactor dumpMultiAgentResults into dumpPerAgentReviews + dumpRunCounts + dumpRunFooter so the synthesis step can land between the run counts and the commit hint without further nesting. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> Entire-Checkpoint: c5108ac4e23a
Three Bugbot findings on the latest commits, all real:
- review_tui.go detailView truncates rendered lines by bytes — same
UTF-8-split risk as truncatePreview but I missed the sibling spot
when fixing the first one. Switch to stringutil.TruncateRunes.
- review_multi.go filterCodexOutput uses strings.HasPrefix(line,
"exec") to detect tool-call blocks. Anchor on either bare `^exec$`
or the `exec <cmd> in /<cwd>` shape codex actually emits, so
legitimate narrative like "executed by the runner" or "execution
succeeded" is no longer eaten.
- review.go composeReviewPrompt produced a triple-newline gap when
appending run context to a skills-template base — the template's
trailing \n stacked with the joiner's "\n\n". Trim before joining.
Also refresh the CLAUDE.md `entire review` section to cover what's
shipped on this branch: multi-agent picker, per-run prompt textarea,
AgentEntries on the marker, scope clause + closest-ancestor base
detection, and the cross-agent verdict synthesis prompt. The settings
schema example was also stale — corrected to the current
ReviewConfig{Skills, Prompt} shape.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: a207b0bc3f5b
review/prompt.go's ComposeReviewPrompt assembles the agent prompt from Skills + AlwaysPrompt + PerRunPrompt + scope clause. Empty sections are skipped (no triple-newline gaps — regression class from PR #1018 commit 13415f5). The scope clause pins agents to 'commits unique to this branch vs <closest-ancestor>' to prevent the divergent-default problem where codex used origin/main...HEAD and claude used working-tree-only on the same invocation (fixed in #1018 commit b9ed9c0, structurally enforced here). review/scope.go's detectScopeBaseRef finds the closest non-self ancestor branch by tip timestamp, with fallback chain origin/HEAD → origin/main → origin/master → main → master. ComputeScopeStats and formatScopeBanner produce the 'Reviewing feat/X vs main: 3 commits, 7 files changed, 2 uncommitted' output that CU6 will print before agent launch. Consolidates CU3's placeholder composePrompt and duplicated appendReviewEnv into shared helpers in review/. Each agent reviewer (claudecode, codex, geminicli) now calls review.ComposeReviewPrompt and review.AppendReviewEnv directly. Per-agent local copies removed. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CU9 introduces TUISink, a Sink implementation that renders a per-agent
status dashboard during multi-agent review runs. Composed alongside
DumpSink in TTY mode; non-TTY multi-agent runs continue to use DumpSink
alone.
- review/tui_sink.go: TUISink wraps a Bubble Tea program. AgentEvent
translates each Event into a tea.Msg and sends it via Program.Send.
RunFinished signals the model to render a final dashboard frame and
waits for the user to dismiss with any key.
- review/tui_model.go: reviewTUIModel handles agentEventMsg / tickMsg
/ WindowSizeMsg / KeyMsg. Per-row run-start timestamps stamped on
first event from each agent (regression-prevented: PR #1018 used a
single TUI-start timestamp that inflated late-starting agents'
durations). Single cancel function: KeyCtrlC and out-of-TUI SIGINT
both call the same context.CancelFunc, gated by sync.Once.
- review/tui_detail.go: alt-screen drill-in. Ctrl+O enters; left/right
cycles agents; up/down scrolls; Esc returns. detailView pads to
termHeight so every frame returns the same line count (avoids ghost
rows in the alt-screen frame diff). ANSI/CSI sequences stripped per
line. Rune-safe truncation via stringutil.TruncateRunes.
Wires dispatch in cmd.go's runMultiAgentPath: TTY mode composes
[TUISink, DumpSink] (TUI for live dashboard, DumpSink for post-run
narrative); non-TTY composes [DumpSink] alone. tea.WithoutSignalHandler
keeps SIGINT routing on the cobra root's existing handler so the
single-cancel contract holds even when the TUI captures KeyCtrlC.
Anti-features explicitly NOT recreated:
- sync.Once-guarded onCancel + parallel signal.Notify goroutine: replaced
by a single shared context.CancelFunc gated by one sync.Once on the model
- cancelMsg dead-code type: omitted entirely
- byte-slice truncation: stringutil.TruncateRunes throughout
- single TUI-start timestamp: per-row runStart stamped on first event
- missing alt-screen on drill-in: tea.EnterAltScreen on Ctrl+O
- variable-line-count detail render: detailView pads to termHeight
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
CU9 introduces TUISink, a Sink implementation that renders a per-agent
status dashboard during multi-agent review runs. Composed alongside
DumpSink in TTY mode; non-TTY multi-agent runs continue to use DumpSink
alone.
- review/tui_sink.go: TUISink wraps a Bubble Tea program. AgentEvent
translates each Event into a tea.Msg and sends it via Program.Send.
RunFinished signals the model to render a final dashboard frame and
waits for the user to dismiss with any key.
- review/tui_model.go: reviewTUIModel handles agentEventMsg / tickMsg
/ WindowSizeMsg / KeyMsg. Per-row run-start timestamps stamped on
first event from each agent (regression-prevented: PR #1018 used a
single TUI-start timestamp that inflated late-starting agents'
durations). Single cancel function: KeyCtrlC and out-of-TUI SIGINT
both call the same context.CancelFunc, gated by sync.Once.
- review/tui_detail.go: alt-screen drill-in. Ctrl+O enters; left/right
cycles agents; up/down scrolls; Esc returns. detailView pads to
termHeight so every frame returns the same line count (avoids ghost
rows in the alt-screen frame diff). ANSI/CSI sequences stripped per
line. Rune-safe truncation via stringutil.TruncateRunes.
Wires dispatch in cmd.go's runMultiAgentPath: TTY mode composes
[TUISink, DumpSink] (TUI for live dashboard, DumpSink for post-run
narrative); non-TTY composes [DumpSink] alone. tea.WithoutSignalHandler
keeps SIGINT routing on the cobra root's existing handler so the
single-cancel contract holds even when the TUI captures KeyCtrlC.
Anti-features explicitly NOT recreated:
- sync.Once-guarded onCancel + parallel signal.Notify goroutine: replaced
by a single shared context.CancelFunc gated by one sync.Once on the model
- cancelMsg dead-code type: omitted entirely
- byte-slice truncation: stringutil.TruncateRunes throughout
- single TUI-start timestamp: per-row runStart stamped on first event
- missing alt-screen on drill-in: tea.EnterAltScreen on Ctrl+O
- variable-line-count detail render: detailView pads to termHeight
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>


Summary
Adds a multi-agent mode to
entire review. When multiple eligible agents support headless execution, the CLI multi-selects agents, prompts for optional per-run context, runs N reviews in parallel with a Bubble Tea status table, and (optionally) synthesizes a unified cross-agent verdict at the end.Closes Phase 2 of the
entire reviewredesign (items 1–4) on top of PR #993 / #1009. Phase 1 (install-aware skill picker) shipped separately.Phase 2 — what landed
1. Pick the review agent
81c4c1192).434a6ae96).2. Parallel headless spawn + status table
agent.HeadlessLaunchercapability interface; per-agent implementations for claude-code, codex, gemini-cli (b53d82f1e).Cmd.Startso construction is infallible and unit tests verify argv/stdin contracts without the agent binaries on PATH (880bae867).8e82e407a).multiReviewOrchestratorruns N agents in parallel under a shared cancellation context, owns the pending-review marker lifecycle, and dumps per-agent results once the TUI exits (b0036d737).reviewTUIModel(Bubble Tea) renders a live status table with spinner, per-row duration, token count, and a faint preview line (701bf3948).exec ...blocks, timestamped errors) before the per-agent dump so findings aren't buried (d0f05d1bd).3. Ctrl+O drill-in + aggregated dumps
21920e4f5). Drill-in uses the alt-screen so the table doesn't tear underneath (b2466e5c0).─────── <agent> review ───────block per agent containing the filtered narrative.4. AI-synthesized cross-agent verdict
y/N) prompt after the per-agent dumps. ReusesresolveCheckpointSummaryProvider(the same pickerentire explainuses) to resolve a configured summary agent and asks it to produce a unified verdict with sections for common findings, unique findings, disagreements, and priority order (840239d32).Other improvements
{Skills, Prompt}so each adopting hook records the skills/prompt that that agent actually ran. Single-agent markers keep the legacy top-level fields. Fixes the Bugbot HIGH where multi-agent reviews previously persisted with emptyReviewSkills/ReviewPrompt(52546abf3).origin/main...HEAD, claude defaulted to working-tree-only). The composed prompt now appends a clause that pins agents to "commits unique to this branch vs the closest ancestor branch," withdetectScopeBaseReffinding that ancestor by tip-timestamp (falling back tomain) (b9ed9c074). Commits-only — uncommitted bytecode and editor temp files were polluting findings./foo:barentries in the picker (92d7a98e7).Cancelled=true(26ebe72e1).1744d5402); rune-safe preview truncation so multi-byte UTF-8 doesn't get split mid-rune (68f5a3707).a42912e89).Test plan
mise run check— fmt + lint + unit + integration + canaryentire-dev reviewin a multi-branch repo with both claude-code and codex configured; verified scope clause limits review to commits unique to current branch and synthesis prompt fires only when at least two agents succeed.Review-feedback addressed
All 12 PR comments from Cursor Bugbot + Copilot triaged; 11 fixed across the commits above, 1 (
for i, task := range taskscapture) is a false positive on Go 1.22+ (project is on 1.26.2).🤖 Generated with Claude Code