@yejianfei.billy/subagent-cli
v0.1.24
Published
Delegate tasks to sub-agent CLI instances (Claude Code, Codex, Gemini CLI)
Maintainers
Readme
subagent-cli
AI agents orchestrating AI agents — a unified CLI for Claude Code, Codex, and other coding terminals. The Gemini CLI adapter is preserved for legacy use but no longer maintained (Google announced shutdown of Gemini CLI on 2026-06-18, migrating users to Antigravity CLI).
Assign tasks. Review approvals. Collect results.
Why?
subagent-cli automates Spec-Driven Development across multiple agents — without changing how you already work.
Main Agent writes spec → Codex spec review ⇄ revise
↓ approved
Main Agent writes plan → Codex plan review ⇄ revise
↓ approved
Codex codes → Claude Code review ⇄ fix
↓ approved
Ship ✓Quick Start
npm install -g @yejianfei.billy/subagent-cli# 1. Start a session
subagent-cli open -s haiku --cwd /path/to/project
# → { "session": "a1b2c3d4" }
# 2. Always check state before sending commands
subagent-cli check --session a1b2c3d4
# → { "status": "IDLE" }
# 3. Send a task (blocks until done or approval needed)
subagent-cli prompt --session a1b2c3d4 "Create a hello world Express server"
# → { "status": "approval_needed", "approval": { "tool": "Write", "target": "server.js" } }
# 4. Approve / reject / allow
subagent-cli approve --session a1b2c3d4
# → { "status": "done", "output": "Created server.js with Express hello world..." }
# 5. Close when done
subagent-cli close --session a1b2c3d4All commands output JSON wrapped in =====SUBAGENT_JSON===== delimiters for reliable extraction from mixed stdout.
Tip: Always run
checkbeforeprompt/approve/reject/allow. Internal state may drift from actual terminal state. Use--force(-f) to send keys regardless of state.
Use Cases
Coding delegation — Your main agent (e.g. Opus) breaks down a feature into subtasks, delegates each to a cheaper/faster sub-agent (Haiku, Kimi, Codex), reviews the results, and iterates. Each sub-agent runs in a fully isolated PTY with its own environment, tools, and MCP servers.
Independent review — Send code to a different model family for review. A Claude agent delegates review to Codex, or vice versa. Cross-vendor oversight catches blind spots that same-family models share.
Main Agent (Opus)
├── delegate coding ──→ Sub-agent A (Haiku / Kimi)
├── delegate review ──→ Sub-agent B (Codex)
└── collect & verify resultsIntegrate with Your AI Agent
Add any of the following sections to your CLAUDE.md, AGENTS.md, or equivalent instructions file.
Basic — Core Workflow
---
name: subagent-delegation
description: Delegate subtasks to independent coding agents via subagent-cli
---
Use `subagent-cli` to delegate subtasks to independent coding agents.
Run `subagent-cli --help` for all commands.
## Workflow
1. `subagent-cli subagents` - List available sub-agents
2. `subagent-cli sessions --cwd .` - Check for existing sessions to reuse
3. `subagent-cli open -s haiku --cwd .` - Start new session (or `open --session <id>` to resume)
4. `subagent-cli check --session <id>` - Verify state before every command
5. `subagent-cli prompt --session <id> "task"` - Send task (blocks until done or approval)
6. Handle approvals:
- `approve --session <id>` - Approve tool use
- `reject --session <id> "reason"` - Reject with new instruction
- `allow --session <id>` - Approve via option 2
7. `subagent-cli close --session <id>` - Close when done
## Wait for State
- `check --session <id> --wait IDLE` - Poll until IDLE
- `check --session <id> --wait IDLE --output last` - Poll + return extracted reply
- `check --session <id> --wait IDLE --timeout 30` - Poll with timeout
- If the session enters ASKING during `--wait`, returns immediately with `409 APPROVAL_NEEDED`
## Session Management
- `sessions --status CLOSED` - List closed sessions
- `delete --session <id>` - Delete one session
- `delete --closed` - Delete all closed sessions
- `delete --all` - Close active + delete all
## Rules
- Always `check` (or `check --wait`) before sending commands — internal state may drift from terminal.
- Use `--force` to send keys regardless of internal state.
- Reuse sessions for follow-up tasks. Only create new sessions for unrelated work.
- If a command times out, use `check` + `output` to inspect state before deciding next action.Spec / Plan Review
---
name: subagent-spec-review
description: Delegate spec or plan document review to a sub-agent, auto-revise and re-review until approved
---
Send a spec or plan document to a sub-agent for independent review.
The main agent revises based on findings and re-submits — loop until the reviewer approves.
## Flow
1. `subagent-cli open -s codex --cwd .` — open reviewer in a different model than the author.
2. `subagent-cli prompt --session <id> "Review the spec at <path>. Categorize findings as auto-fixable vs needs-user-decision."`
3. Reviewer returns findings; main agent revises auto-fixable issues directly in the doc.
4. Send `Re-review the spec at <path>` in the same session — reviewer re-reads from disk.
5. Repeat until reviewer reports no issues. Escalate needs-user-decision items to the user.Coding Delegation
---
name: subagent-code-developer
description: Delegate coding tasks to sub-agents for independent execution
---
Delegate coding tasks to sub-agents. The sub-agent works independently in its own
terminal — the main agent only handles approvals and collects results.
## Flow
1. `subagent-cli sessions --cwd . --status IDLE` — reuse existing sessions first.
2. `subagent-cli open -s <subagent> --cwd <dir>` — new session only if needed.
3. `subagent-cli prompt --session <id> "<task>"` — blocks until done or approval needed.
4. Handle approvals: `approve` / `reject "reason"` / `allow`.
5. `check --wait IDLE --output last` — wait for completion and get extracted reply.
Returns 409 APPROVAL_NEEDED immediately if approval is required.
## Task Prompt
Send self-contained tasks — the sub-agent has no shared context with the main agent:
Goal: <what to achieve>
Scope: <files/directories to modify>
Constraints: <project rules, boundaries>
Verification: <commands to run>Code Review
---
name: subagent-code-review
description: Delegate code review to a sub-agent in a different model, auto-fix findings, re-review until clean
---
Delegate review to a sub-agent running a different model (e.g. Codex reviews Claude output).
Auto-fix mechanical issues and re-review in a loop until all issues are resolved.
## Flow
1. Open a session with a different adapter than the one that wrote the code.
2. Send review prompt with file path and criteria.
3. Sub-agent returns findings categorized as:
- **Auto-fixable** (naming, types, logic errors) — main agent fixes and re-reviews.
- **Needs user decision** (architecture, scope) — escalate to user.
4. After fixing, send re-review prompt in the same session.
5. Sub-agent re-reads the full file from scratch and re-evaluates.
6. Repeat until clean. Reuse the same session for all review rounds.Supported Terminals
| Adapter | Status | CLI Tool |
| ------------- | ------------- | ----------------------------------------------------- |
| claude-code | ✅ | Claude Code |
| codex | ✅ | OpenAI Codex CLI |
| gemini-cli | ⚠️ Deprecated | Gemini CLI — Google shutdown on 2026-06-18, users migrate to Antigravity CLI. This adapter is no longer maintained. |
CLI Reference
| Command | Options | Description |
| ----------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------- |
| subagents | | List available subagent configurations |
| sessions | --cwd <path> --status <state> | List sessions (active + closed), filter by cwd or state |
| open | -s, --subagent <name> --cwd <path> --session <id> --role <text> --reuse --auto --timeout <s> [text] | Create or resume session. Optional [text] sends a prompt after open. --reuse returns most-recent idle/closed session with same cwd+subagent (set idle.fast_reuse=true to make this the default). --auto turns on auto-approve before sending [text] (ASKING auto-confirmed, wait runs through to IDLE). --role overrides config role (new sessions only) |
| prompt | --session <id> --timeout <s> --auto <text> | Send task, blocks until done or approval needed. --auto turns on auto-approve before sending (ASKING auto-confirmed, runs through to IDLE) |
| approve | --session <id> --timeout <s> -f [text] | Approve tool use. Optional text typed before approval |
| allow | --session <id> --timeout <s> -f | Approve via option 2. Scope depends on target CLI |
| reject | --session <id> --timeout <s> -f [text] | Reject tool use. Optional text sent as new instruction |
| auto | --session <id> --off | Toggle auto-approve for the session |
| cancel | --session <id> | Cancel running task |
| status | --session <id> | Get internal session state (sync) |
| check | --session <id> --wait <state> --timeout <s> --output <type> | Get state. --wait polls until target state; 409 if ASKING (unless autoApprove is on — then keeps polling, since ASKING gets auto-confirmed internally) |
| output | --session <id> --type <screen\|history\|last> | Get terminal output. last = extracted sub-agent reply |
| close | --session <id> | Close session (omit --session to close all). History preserved |
| delete | --session <id> --closed --all | Delete session, all closed, or everything |
| exit | --session <id> | Graceful exit the sub-agent process |
| daemon | start\|stop\|status --port <port> | Manage the App daemon. Single-instance globally: start refuses if a live daemon exists on any port. stop uses HTTP shutdown |
Global option: -c, --config <path> — Custom config file path.
Configuration
Config file: ~/.subagent-cli/config.json (auto-created on first run)
{
"port": 7100,
"idle": { "timeout": 300, "check_interval": 30, "manager_timeout": 120, "reuse_ratio": 0.5, "fast_reuse": false },
"terminal": { "cols": 220, "rows": 50, "scrollback": 5000 },
"subagents": {
"haiku": {
"adapter": "claude-code",
"description": "Claude Haiku",
"role": "You are a helpful assistant.",
"command": "claude",
"args": [],
"env": { "ANTHROPIC_MODEL": "haiku" }
},
"kimi": {
"adapter": "claude-code",
"description": "Fast coding, ultra low cost",
"command": "claude",
"args": [],
"env": {
"CLAUDE_CODE_OAUTH_TOKEN": "",
"ENABLE_TOOL_SEARCH": "false",
"ANTHROPIC_MODEL": "kimi-k2.5",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "kimi-k2.5",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "kimi-k2.5",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "kimi-k2.5",
"ANTHROPIC_BASE_URL": "https://api.kimi.com/coding/",
"ANTHROPIC_API_KEY": "${KIMI_API_KEY}"
}
},
"codex": {
"adapter": "codex",
"description": "OpenAI Codex CLI (GPT-5.5)",
"role": "You are a helpful assistant.",
"command": "codex",
"args": ["--ask-for-approval", "untrusted", "-m", "gpt-5.5"],
"env": {}
},
"gemini": {
"adapter": "gemini-cli",
"description": "Gemini CLI",
"role": "You are a helpful assistant.",
"command": "gemini",
"args": [],
"env": {}
}
}
}Top-level
| Key | Type | Default | Description |
| ------ | -------- | ----------------- | --------------------------------------------- |
| home | string | ~/.subagent-cli | Override home directory for sessions and data |
| port | number | 7100 | App daemon HTTP port |
idle — Idle monitoring
| Key | Type | Default | Description |
| ---------------------- | -------- | ------- | ---------------------------------------------------------------------- |
| idle.timeout | number | 300 | Session idle timeout (seconds). Auto-close when exceeded |
| idle.check_interval | number | 30 | How often to check for idle sessions (seconds) |
| idle.manager_timeout | number | 120 | App auto-exit delay when no sessions remain (seconds). -1 to disable |
| idle.reuse_ratio | number | 0.5 | --reuse cooldown: idle session must be idle for at least timeout * reuse_ratio seconds before reuse |
| idle.fast_reuse | boolean| false | Make --reuse the default for open. Pass --no-reuse to opt out |
terminal — PTY terminal settings
| Key | Type | Default | Description |
| --------------------- | -------- | ------- | -------------------------------------------------------- |
| terminal.cols | number | 220 | Terminal width in columns. Wide to prevent line wrapping |
| terminal.rows | number | 50 | Terminal height in rows |
| terminal.scrollback | number | 5000 | Scrollback buffer size (lines) |
subagents.<name> — Subagent definitions
| Key | Type | Required | Description |
| ------------- | ---------- | -------- | --------------------------------------------------------------------- |
| adapter | string | Yes | Adapter type: claude-code or codex |
| description | string | Yes | Human-readable description, shown in subagents list |
| command | string | Yes | CLI command to spawn (e.g., claude, codex) |
| args | string[] | Yes | Additional command-line arguments |
| role | string | No | System prompt sent during session initialization to establish context |
| env | object | Yes | Environment variables passed to the spawned process |
Environment variable handling:
"${VAR}"— References a system environment variable, resolved at App startup""(empty string) — Explicitly deletes the variable from the spawned process environment
Important: If your current account uses
CLAUDE_CODE_OAUTH_TOKEN(e.g., Claude Pro/Max subscription), the subagent process will inherit it. Since OAuth token has the highest authentication priority in Claude Code, you must set"CLAUDE_CODE_OAUTH_TOKEN": ""in env to delete it, otherwiseANTHROPIC_API_KEYandANTHROPIC_BASE_URLwill be ignored. See thekimiexample above.
Model aliases: ANTHROPIC_MODEL in env supports shorthand: sonnet, opus, haiku. Other env keys like ANTHROPIC_DEFAULT_*_MODEL require full model IDs.
Architecture
Main Agent (Claude Code / Codex / ...)
│ stdout JSON
▼
┌──────────────────────┐ ┌──────────────────────────┐
│ subagent-cli (CLI) │ │ Browser Debug Viewer │
│ thin HTTP client │ │ xterm.js + WebSocket │
└──────────┬───────────┘ └─────────────┬────────────┘
│ HTTP │ WebSocket
▼ ▼
┌────────────────────────────────────────────────────────────┐
│ App Daemon (localhost:7100) │
│ ┌─ Session ─────────────────────────────────────────┐ │
│ │ Adapter (state machine) + PtyXterm + History │ │
│ └───────────────────────────────────────────────────┘ │
│ ┌─ Session ... ─────────────────────────────────────┐ │
│ └───────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────┘- CLI — Short-lived process. Receives commands, forwards to App via HTTP, returns JSON.
- App — Long-running daemon. Manages sessions, monitors idle timeouts, auto-exits when unused.
- Session — Adapter (state machine) + PtyXterm (node-pty + xterm/headless) + SessionHistory.
The CLI auto-detects the App daemon via TCP probe. If not running, it forks one automatically.
Debug Viewer
Built-in web terminal at http://localhost:7100/viewer — real-time xterm.js rendering with keyboard input forwarding and connection status indicator.
Development
npm install # install dependencies
npm run build # webpack production build
npm run watch # webpack watch mode
npm test # unit tests (node:test)
npm run test:e2e:claude # Claude Code end-to-end tests
npm run test:e2e:codex # Codex end-to-end testsRequirements: Node.js 18+ (uses built-in fetch). macOS and Linux only — Windows is not supported.
Note
This project was fully developed through Claude Code vibe coding. For any copyright concerns, please open an Issue.
License
Apache-2.0
