feat(ai-tools): Settings → AI Tools, Default/Other lane picker, per-run bypass switch (#40 A1)

Settings → Dashboard gains an AI Tools section (installed tools with
Enabled/Disabled and Set default, available ones with a homepage link,
Refresh). useAiTools shares one catalog copy across the app and replaces
LANE_TOOL_LABEL. The Add-lane modal picks Default (<tool>) or Other…; the
router row reads Native (<tool>) and disables AI Router profiles for tools
that cannot use one. The run form gives catalog tools resume and a red
per-run Bypass permissions switch (Codex too). Claude Code / Codex settings
tabs hide while that tool is disabled. The Workspace probes each lane tool's
CLI fresh.

Docs: CLAUDE.md tool/bypass rule, AGENTS.md, LANES.md, API.md, CLI.md,
server/README.md, OpenAPI fragment + regenerated openapi.yaml.
This commit is contained in:
2026-09-28 11:19:30 +07:00
parent 77917203fd
commit fcfebe44f1
33 changed files with 1306 additions and 153 deletions
+24 -4
View File
@@ -448,7 +448,7 @@ curl -X POST http://localhost:4820/api/lanes/ensure \
}
```
- If a lane already owns the `cwd` **for the requested `tool`**, returns that lane with `created: false` and HTTP `200`. `tool` (`claude`, `codex` or `antigravity`, default `claude`) is part of the identity: adopting the same `cwd` with a different `tool` creates a second, sibling lane rather than adopting the existing one — one `cwd` can back at most one `claude` lane and one `codex` lane at a time. This applies to Repo/Adopt mode only; Worktree mode always gets its own directory.
- If a lane already owns the `cwd` **for the requested `tool`**, returns that lane with `created: false` and HTTP `200`. `tool` (an AI Tools catalog id — `claude`, `codex`, `antigravity`, `gemini`, … — default `claude`) is part of the identity: adopting the same `cwd` with a different `tool` creates a second, sibling lane rather than adopting the existing one — one `cwd` can back at most one lane per tool. An unknown id answers `400 EBADTOOL`; creating a NEW lane for a tool disabled in Settings → AI Tools answers `400 EDISABLED` (an existing lane is still found). This applies to Repo/Adopt mode only; Worktree mode always gets its own directory.
- If the `cwd` is a subdirectory of an existing lane with that same tool, returns the parent lane that owns it. Pass `"exact": true` to skip that: only a lane on this very directory is returned, and a nested one is created as its own lane — the Add-lane modal does this, and shows which lane already owns the folder when the answer is `created: false`.
- If no lane owns the `(cwd, tool)` pair, creates an **adopted** lane and returns it with `created: true` and HTTP `201`.
- A relative or missing `cwd` returns `400 EBADCWD`.
@@ -866,7 +866,7 @@ This command:
### Full command signature
```bash
agenthub stage <stage> [--lane <id>] [--cwd <path>] [--tool claude|codex] [--status <s>] [--evidence <text>] [--note <text>] [--result pass|fail]
agenthub stage <stage> [--lane <id>] [--cwd <path>] [--tool <id>] [--status <s>] [--evidence <text>] [--note <text>] [--result pass|fail]
```
**Parameters:**
@@ -890,7 +890,7 @@ agenthub stage <stage> [--lane <id>] [--cwd <path>] [--tool claude|codex] [--sta
- `--cwd <path>` (optional): working directory to match against a lane's cwd. If omitted, uses the current working directory. Useful when calling from outside the repo.
- `--tool claude|codex` (optional): which tool's lane to address when one directory backs both (see "Which lane a CLI command addresses" below).
- `--tool <id>` (optional): which tool's lane to address when one directory backs both (see "Which lane a CLI command addresses" below).
- `--status <s>` (optional): the lane's overall status (`running`, `idle`, `provisioning`). Allows bundling a status update with the stage report.
@@ -953,7 +953,7 @@ activate`, `lanes up/down/logs`, …) shares one resolver, `resolveLaneArg` in
carries it (`tmux new-session -e`, or an assignment prefix when the argv is
typed into a pane already at a shell prompt). A session inside a
dashboard-started pane therefore never has to guess.
3. `--tool claude|codex`, then the harness's own marker: Claude Code exports
3. `--tool <id>`, then the harness's own marker: Claude Code exports
`CLAUDECODE`/`CLAUDE_CODE_ENTRYPOINT`, so a Claude session identifies itself
for free. **Codex has no equivalent marker** (it only reads `CODEX_HOME`, and
sets `CODEX_SANDBOX*` under a sandbox policy), so a codex session outside a
@@ -1657,3 +1657,23 @@ agenthub stage <stage> [--evidence "..."] # Report the current stage
- `server/routes/lanes.js` — REST API surface
- `bin/agenthub.js` — CLI commands for lanes and stage reporting
- `server/routes/hooks.js` — hook-to-lane binding by cwd, and where detection is invoked
## Lanes on any AI tool
A lane can run any AI coding CLI in the AI Tools catalog (`server/data/ai-tools/*.json`, plus any `*.json` in `DASHBOARD_AI_TOOLS_DIR`, which replaces a built-in file with the same `id` but may not set `launcher`). Settings → Dashboard → **AI Tools** lists what is installed (found on PATH; **Refresh** re-reads the login shell's PATH first) with **Enabled/Disabled** and **Set default**, and what is available to install with a homepage link. The Add-lane modal offers **Default (<tool>)** and **Other…**; `agenthub lanes add --tool <id>` does the same from a terminal.
A catalog file:
```json
{
"id": "antigravity",
"label": "Antigravity",
"detect": ["agy"],
"homepageUrl": "https://antigravity.google/docs/cli/overview",
"prompt": { "mode": "flag", "flag": "-i" },
"resume": ["--continue"],
"bypass": ["--dangerously-skip-permissions"]
}
```
`detect` lists bare command names (the first found on PATH is what runs), `requires` other commands that must be present, `args` fixed leading args, `prompt.mode` one of `argv` (optional `separator: "--"`), `flag` (`flag`), or `after-start` (`delayMs`, default 3000 — the prompt is pasted into the pane once the CLI is up). `resume` enables **Resume last session**; `bypass`/`bypassEnv` enable the run form's per-run **Bypass permissions** switch, which is off every time the form opens. Every non-Claude lane has no pipeline, no agents install and no AI Router (native only, except Codex); running/idle comes from the exited-pane heal sweep.