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
+20 -4
View File
@@ -19,7 +19,8 @@
* the session (one-click Start/Resume) and is just one of possibly several
* attached clients tmux already keeps in sync.
*
* Spawns `claude` or `codex` in the tmux pane based on the tool parameter.
* Spawns `claude`, `codex` or `agy` (Antigravity) in the tmux pane based on
* the tool parameter.
*
* A lane can hold up to four sessions, one per Workspace split pane: pane 0 is
* `agenthub-lane-<laneId>` (the lane's own `run_id`), panes 1–3 are
@@ -55,7 +56,7 @@ const ALLOWED_PERMISSION_MODES = new Set([
]);
// Pane commands that mean "idle shell prompt, safe to type a command into".
const SHELL_COMMANDS = new Set(["sh", "bash", "zsh", "fish", "dash", "ksh", "csh", "tcsh"]);
const VALID_TOOLS = new Set(["claude", "codex"]);
const VALID_TOOLS = new Set(["claude", "codex", "antigravity"]);
const CODEX_SANDBOXES = new Set(["read-only", "workspace-write", "danger-full-access"]);
const CODEX_APPROVALS = new Set(["on-request", "never"]);
// Codex has no `--effort` flag; reasoning effort is a config override.
@@ -137,8 +138,23 @@ function buildCodexArgv({
return argv;
}
/**
* Antigravity's `agy` has no model, effort or permission-mode flag, so only
* resume and the first prompt reach it. `-i` keeps the session interactive
* after that prompt (`-p` would print and exit). `--dangerously-skip-permissions`
* is never emitted, same rule as Codex's bypass flags.
*/
function buildAntigravityArgv({ resumeLast, initialPrompt }) {
const argv = ["agy"];
if (resumeLast) argv.push("--continue");
if (initialPrompt) argv.push("-i", initialPrompt);
return argv;
}
function buildArgv(args) {
return args.tool === "codex" ? buildCodexArgv(args) : buildClaudeArgv(args);
if (args.tool === "codex") return buildCodexArgv(args);
if (args.tool === "antigravity") return buildAntigravityArgv(args);
return buildClaudeArgv(args);
}
/**
@@ -258,7 +274,7 @@ function spawnRun(args) {
// separate `external` row. Every run here is one interactive pane.
mode: "interactive",
cwd,
tool: tool === "codex" ? "codex" : "claude",
tool,
model: model || null,
permissionMode: permissionMode || "auto",
effort: effort || null,