feat(kanban): auto-resolve merge-all conflicts with an agent
When the merge-all batch hits a conflict, spawn a conflict-resolution agent in the main worktree (where the merge is mid-conflict), await it, and continue the batch through the remaining branches instead of aborting for manual resolution. - worktrees: replace abort-on-conflict mergeBranches with non-aborting attemptMerge (leaves the tree mid-merge, returns conflicted paths), plus abortMerge/hasMergeInProgress/unmergedPaths/createRecoveryBranch. Batch types gain conflict/resolutionRunId/recoveryRef. - prompt: buildConflictResolutionPrompt resolves both sides preserving intent, honors repo conventions (no Rust warning suppression), runs cargo/pnpm checks, then completes the merge with a commit. - runs: mergeAll() is async; per branch it attemptMerges, and on conflict starts a streamable resolution run in REPO_ROOT, awaits it, and verifies the merge actually completed (no MERGE_HEAD, clean tree) before continuing — otherwise aborts and halts. A mergeBatchInProgress guard prevents two batches at once; a pre-batch recovery ref snapshots HEAD. - route: /runs/merge-all is async; node request/socket timeouts disabled so a long multi-conflict batch survives. - UI: per-branch status shows "conflict resolved by agent" + resolution run id; a recovery-ref banner documents how to roll the batch back. Safety: resolution only counts if verified; otherwise the merge is aborted and main left clean. Resolution runs are real agent_runs (stream into the dock, stoppable) and own no worktree. EOF && echo "" && git log --oneline -3
This commit is contained in:
@@ -144,8 +144,18 @@ orchestrator.post('/runs/:id/merge', (c) => {
|
||||
return c.json(mergeBranch(run.branch));
|
||||
});
|
||||
|
||||
/** Merge all reviewable agent branches into the main branch sequentially. */
|
||||
orchestrator.post('/runs/merge-all', (c) => c.json(runManager.mergeAll()));
|
||||
/** Merge all reviewable agent branches into the main branch sequentially,
|
||||
* spawning a conflict-resolution agent on any conflict. May block for a long
|
||||
* time while agents resolve conflicts. */
|
||||
orchestrator.post('/runs/merge-all', async (c) => {
|
||||
try {
|
||||
const result = await runManager.mergeAll();
|
||||
return c.json(result);
|
||||
} catch (err) {
|
||||
const message = err instanceof Error ? err.message : 'merge-all failed';
|
||||
return c.json({ error: message }, 409);
|
||||
}
|
||||
});
|
||||
|
||||
/** Whether a Bevy playtest is running for a run. */
|
||||
orchestrator.get('/runs/:id/bevy', (c) => {
|
||||
|
||||
Reference in New Issue
Block a user