feat(kanban): merge-all branches + floating running-agents dock

Two board-level additions:

Merge all reviewable agent branches into the main branch sequentially:
- worktrees.mergeBranches() merges candidates in order, advancing HEAD each
  time; refuses if the main tree is dirty, and on the first conflict aborts
  that merge (main left clean) and stops — prior merges stay, untried
  branches reported as unattempted.
- runManager.mergeAll() picks candidates (settled runs that own their
  worktree, branch present, not yet in HEAD; deduped, oldest-first) — so
  refinement runs (which inherit a worktree) are correctly excluded.
- POST /runs/merge-all; ⬇ Merge all button in the board header opens a
  results modal (per-branch ✓/⇢/⚠, conflict banner, inline git output).

Floating dock to view/open running agents (front-end only):
- RunningAgentsBar pins bottom-right (below the card modal), lists every
  running run with live elapsed times, and opens that card's modal on click;
  auto-hides when nothing runs, collapsible otherwise.
EOF && echo "" && git log --oneline -4
This commit is contained in:
2026-06-17 21:04:51 -04:00
parent 408bdb6dd7
commit d538ccdd4e
8 changed files with 636 additions and 1 deletions

View File

@@ -144,6 +144,9 @@ 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()));
/** Whether a Bevy playtest is running for a run. */
orchestrator.get('/runs/:id/bevy', (c) => {
const run = runManager.get(c.req.param('id'));