Commit Graph

7 Commits

Author SHA1 Message Date
a487ba2b95 fix(kanban): skip gone branches in merge-all instead of halting
Some checks are pending
CI / TypeScript Check (docs) (push) Waiting to run
CI / TypeScript Check (site) (push) Waiting to run
CI / Rust Check (push) Waiting to run
CI / Security Audit (push) Waiting to run
merge-all halted with "merge: <branch> - not something we can merge" when a
candidate's branch ref no longer resolved (worktree+branch cleaned up
out-of-band while the run row lingered with branch set). That's not a
conflict — there's nothing for a resolution agent to do — yet it stopped
the whole batch.

- Verify each candidate resolves to a commit (resolveRef) before attempting;
  non-resolving branches are skipped (⤳) and the batch continues.
- Null the stale branch on the run row so it stops reappearing as a candidate.
- BatchMergeItem gains `skipped`; the modal shows skipped branches and counts
  them in the summary.
EOF && echo "" && git push 2>&1 | tail -4
2026-06-17 22:20:28 -04:00
607f3fbd8b feat(kanban): auto-resolve merge-all conflicts with an agent
Some checks failed
CI / Rust Check (push) Has been cancelled
CI / TypeScript Check (docs) (push) Has been cancelled
CI / TypeScript Check (site) (push) Has been cancelled
CI / Security Audit (push) Has been cancelled
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
2026-06-17 22:07:49 -04:00
d538ccdd4e 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
2026-06-17 21:04:51 -04:00
408bdb6dd7 fix(kanban): recover and self-heal stuck agent runs
A run could get stranded at 'running' in the UI after a crash/disconnect/
restart, with no way to clear it. Root cause was a race: the SSE history
replay re-asserted a stale `running` status that beat the poll's settled
status, leaving the run showing "Running" + the settle error at once.

Server (runs.ts / runner.ts / index.ts):
- reconcile() on every read force-settles any 'running' run with no live
  runner, so the board self-heals on the next poll (≤3s) — no restart needed.
- forceSettle() emits a persisted `status` event so an open/reconnecting
  SSE stream replays the terminal state last, not a stale `running`.
- Startup orphan-reconciliation now also emits that event (was the gap that
  let the replay re-assert `running` after a server restart).
- Idle watchdog (10min): a silent pi is settled as 'failed' instead of
  hanging forever; SIGKILL escalation (20s) reaps wedged processes.
- stop() now recovers: active→abort, orphaned-but-running→force-stop
  (the Stop button clears wedged runs instead of 409'ing).
- start() catch force-settles 'failed' so a spawn failure never orphans a
  half-created 'running' row.

Client (useOrchestrator.ts):
- patchRun refuses to un-settle a terminal run, dropping stale replayed
  status as a belt-and-suspenders guard against any such race.
EOF && echo "" && git log --oneline -3
2026-06-17 18:53:44 -04:00
6531dc00df feat(kanban): resume runs' chat via Refine + isolate the event stream
Two intertwined changes that both touch the orchestrator hook + run console:

Isolate the agent event stream (perf):
- useRunStream owns the SSE stream + event log locally inside AgentRunBar, so a
  burst of streamed events re-renders only the console — never the board page or
  card modal (which was causing frame drops at run start).
- useOrchestrator is now a registry only; lifecycle events reflect back up via
  stable patchRun/reflectBevy reflectors (effect deps depend on those, not the
  whole object, avoiding a stream-teardown loop).

Session resume for Refine:
- Runs now persist their pi session (drop --no-session); each fresh run captures
  its session JSONL path into a new agent_runs.session_file column (additive,
  idempotent migration).
- Refine resumes the prior run's actual session (--session <path> → appends) in
  that run's own worktree (inherited, never owned), sending the operator's
  feedback as the next message in the same conversation with full prior context.
- owns_worktree guards remove()/cleanup so a refinement never destroys the
  owning run's worktree; bad refinement targets return 409.
- AgentRunBar shows Refine only for settled runs with a recorded session.
EOF && echo "" && git log --oneline -3
2026-06-17 18:34:05 -04:00
e4f0abed20 feat(api): add bevy playtest, worktree review, and drop seeding
- bevy.ts: spawn `cargo run` in a run's worktree to playtest its branch,
  batching build/runtime output as `bevy` events (capped at 2000/run)
- events.ts: shared appendRunEvent/nextSeq so the runner, the agent-driven
  internal mutations, and the bevy launcher all persist through one path
- runs.ts: track per-run bevy processes; stop them before worktree teardown
- worktrees.ts: review/merge ops (isWorktreePresent, mainDirtySummary,
  commitsAheadOfHead, diffPatch/stat, mergeBranch)
- orchestrator routes: diff, merge, bevy start/stop, bevy-status endpoints
- remove seeding: drop seed.ts + data/kanbanCards.ts, the /reset endpoint,
  and boot-time seeding; cards are plain persisted DB records now
2026-06-16 18:17:27 -04:00
efdc34637e feat(api): add backend with kanban, docs store, and orchestrator
Introduce the @void-nav/api Hono + SQLite backend that powers the docs site:
a persisted implementation board (kanban), a custom documentation-pages store
with AI beautify, and an agentic orchestrator that runs `pi` agents per card.

The orchestrator spawns `pi --mode rpc` inside an isolated git worktree per run,
streams slim events over SSE, and lets the agent drive the board/docs via
token-gated internal endpoints (all SQLite writes stay in-process). Interrupted
runs are reconciled to "stopped" on boot.

Workspace wiring: root `dev:api`/`dev:web` scripts with `concurrently`, the
docs Vite `/api` proxy, and `.worktrees/` gitignore.
2026-06-16 15:43:58 -04:00