diff --git a/docs/superpowers/plans/2026-07-24-merge-helper.md b/docs/superpowers/plans/2026-07-24-merge-helper.md index e2e0030d..9da66bf2 100644 --- a/docs/superpowers/plans/2026-07-24-merge-helper.md +++ b/docs/superpowers/plans/2026-07-24-merge-helper.md @@ -24,6 +24,7 @@ Record findings in the task notes; feeds A2/A3. ### A3 — `continue_merge` + `abort_merge` MCP tools - TDD: continue after on-disk resolution → committed, task Done, worktree merged; continue with markers remaining → returns conflicts; abort → markers gone, task `WaitingForReview`; both on no-active-merge → clean MCP error; `TaskUpdated` fired. - Add `[McpServerTool] continue_merge(taskId)` → `ContinueMergeAsync`; `abort_merge(taskId)` → `AbortMergeAsync`. Locate the merge from the task's repo/target. Emit `TaskUpdated`. +- **Route both single-task and orchestrated (parent/children) in-progress merges** where locatable from the task (per A1 findings): detect the kind and call the matching engine continue/abort (`TaskMergeService` vs `PlanningMergeOrchestrator.Continue/Abort`). If the orchestrated path can't be located without hub UI state, leave it to the manual fallback (documented in the B1 prompt) and note the gap in `docs/open.md`. - Commit: `feat(worker): add continue_merge and abort_merge MCP tools` --- @@ -32,7 +33,7 @@ Record findings in the task notes; feeds A2/A3. ### B1 — Prompt templates - Add `PromptKind.MergeHelper` + `PromptKind.MergeHelperInitial` to `ClaudeDo.Data/PromptFiles.cs` (file names `merge-helper-system.md` / `merge-helper-initial.md`, built-in `DefaultFor`, `Render` tokens for the initial brief). -- System prompt encodes §7 behaviour (per-status algorithm, ask-on-uncertainty, MCP-only merge state, summary format). +- System prompt encodes §7 behaviour (per-status algorithm, ask-on-uncertainty, summary format). Merge-state rule: **prefer MCP tools whenever they apply**; hand-merge (Edit + `git commit -- `) is an accepted fallback only for merges the MCP tools can't reach (§5.3), never a shortcut around them. - Initial brief renders a task table `{id,title,status,list,repo}` + scope label. - TDD: `PromptFiles` tests — kinds resolve, defaults non-empty, `Render` substitutes brief tokens. - Commit: `feat(data): add merge-helper prompt templates` diff --git a/docs/superpowers/specs/2026-07-24-merge-helper-design.md b/docs/superpowers/specs/2026-07-24-merge-helper-design.md index 49875857..67cca5f7 100644 --- a/docs/superpowers/specs/2026-07-24-merge-helper-design.md +++ b/docs/superpowers/specs/2026-07-24-merge-helper-design.md @@ -21,7 +21,7 @@ This reuses the existing ConPTY infrastructure (UI-process embedded terminal) an | Which tasks does the helper handle? | **Free choice, any status.** User hand-picks; helper acts per-status. | | How are tasks selected for a run? | **Checkbox dialog before launch** (candidates listed, user ticks). | | Merge authority / review-gate | **Auto-merge; asks interactively on uncertainty.** The app's per-task diff-gate is intentionally bypassed for helper-driven merges. | -| Conflict handling | **Build MCP conflict tools** so the helper resolves conflicts in the working tree itself, asking only when unsure (Option B). | +| Conflict handling | **Build MCP conflict tools** so the helper resolves conflicts in the working tree itself, asking only when unsure (Option B). The helper must handle **all** cases including parent/children unit merges; where the MCP path doesn't reach, **manual resolution by hand (Edit + git) is an accepted fallback** (user-confirmed 2026-07-24). | --- @@ -81,9 +81,12 @@ Reuse the *exact* engine methods the UI already uses — `TaskMergeService.Merge - Emit the existing `TaskUpdated` event after continue/abort so the UI list re-buckets live. - Guard against a repo already mid-merge (`Blocked`) — surface it to the agent rather than clobbering. -### 5.3 v1 boundary — parent/children unit merges +### 5.3 Parent/children unit merges -`review_task approve` on a task **with children** drives `PlanningMergeOrchestrator` (multi-step unit merge with its own continue/abort). Autonomous MCP conflict resolution for that orchestrated path is **out of scope for v1**: if a unit merge conflicts, the helper reports it and hands off to the UI (as today). Clean unit merges still complete autonomously. Childless single-task merges — the common review/merge case — get full autonomous conflict resolution. This limit is called out to the user, not hidden. +`review_task approve` on a task **with children** drives `PlanningMergeOrchestrator` (a multi-step unit merge with its own continue/abort on the hub). The helper must handle these too. Two paths, tried in order: + +1. **MCP (preferred):** `continue_merge` / `abort_merge` detect *which* kind of in-progress merge the task has (single-task `TaskMergeService` vs orchestrated `PlanningMergeOrchestrator`) and route to the matching engine continue/abort. This keeps the orchestrated path engine-mediated over MCP too. Implement if the orchestrator's continue/abort can be located from the task without shared hub UI state (verify in A1). +2. **Manual fallback (accepted):** where the MCP path genuinely can't reach an in-progress merge, the helper resolves the conflict markers on disk (Read/Edit) and completes the merge by hand (`git add ` + `git commit`, or `git merge --continue`). The user has explicitly accepted hand-merging as a fallback. The system prompt still mandates: **prefer the MCP tools whenever they apply**; only drop to raw git for cases the MCP tools don't cover, and honour the shared-checkout rule (`git commit -- `, never a bare commit that sweeps peers' index). --- @@ -131,7 +134,7 @@ For each selected task, act by status: - **WaitingForReview:** `get_task_diff` (stat first, then full if needed), sanity-check the change against the task's intent, then `review_task approve` with `leaveConflictsInTree:true`. - **Clean →** merged, task Done. - **Conflict (`conflict_in_tree`) →** open the conflicted files under `repoPath` (Read/Edit), resolve the markers guided by both sides' intent, then `continue_merge`. If the resolution is non-obvious or risky, **ask the user in the terminal** before continuing. `abort_merge` if the user declines or it's unsafe. -- **Parent with children:** clean unit merge proceeds; on conflict, report and tell the user to resolve in the UI (§5.3). +- **Parent with children:** clean unit merge proceeds; on conflict, resolve via the MCP tools if they reach the orchestrated merge, else hand-merge the markers and complete it (§5.3) — asking the user first when the resolution is non-obvious. Cross-cutting rules (in the prompt): - Ask the user interactively for anything ambiguous, risky, or destructive — that is the point of the ConPTY session. @@ -173,7 +176,6 @@ Delivered as one plan with three phases (see the plan doc). Phase A is independe ## 10. Out of scope (v1) -- Autonomous conflict resolution for parent/children **unit** merges (§5.3) — report + UI hand-off only. - Resuming a merge-helper session (`--resume`); sessions are ephemeral. - A non-interactive/headless merge-helper (this is deliberately a ConPTY interactive session). - Cross-list *batching* semantics beyond "act on each selected task independently."