feat(lanes): Antigravity lanes, release exited panes, fresh Codex starts

- antigravity: a third lane tool running Antigravity's `agy` CLI. `-i`
  carries the first prompt, `--continue` resumes; `agy` has no model,
  effort or permission flag, and `--dangerously-skip-permissions` is never
  emitted. No pipeline, no agents install, and no AI Router (native only,
  else EUNSUPPORTED). Add lane gains an Antigravity choice and the binary
  probe maps it to `agy`.
- UI: the lane card no longer renders a frame holding only a "Codex" chip,
  and the prompt box names the lane's CLI ("Ask Codex anything…"), via
  LANE_TOOL_LABEL.
- runs: a pane that exits is released on a 10 s server beat
  (healAllRunIds, DASHBOARD_RUN_HEAL_MS). Codex and Antigravity fire no
  hook, so their lanes stayed "running" until something re-read them.
- codex: Start no longer sends resumeLast — only "Resume last session"
  continues the previous thread.
This commit is contained in:
2026-09-28 10:22:07 +07:00
parent 952e8584f0
commit 9d096b61f7
31 changed files with 257 additions and 93 deletions
+15
View File
@@ -504,6 +504,21 @@ function startBackgroundServices() {
} catch (err) {
console.warn("codex poll failed to start:", err.message);
}
// A codex/antigravity pane that exits fires no hook, so release its lane on
// a beat instead (one `tmux has-session` per lane with a run). Off with
// DASHBOARD_RUN_HEAL_MS=0.
const HEAL_MS = Number(process.env.DASHBOARD_RUN_HEAL_MS ?? 10_000);
if (Number.isFinite(HEAL_MS) && HEAL_MS > 0) {
const { healAllRunIds } = require("./routes/lanes");
const healTimer = setInterval(() => {
try {
healAllRunIds();
} catch (err) {
console.warn("run heal failed:", err.message);
}
}, HEAL_MS);
if (healTimer.unref) healTimer.unref();
}
// Continuous discovery of sessions under ~/.claude/projects. The one-time
// legacy backfill above runs only once (marker-gated), so a project added
// later whose sessions never flow through hooks would otherwise stay invisible