codex-subagents
codex-subagents offloads time-consuming or parallel tasks to background subagents, keeping your main agent's context lean and efficient. It's ideal for scenarios requiring multiple parallel research threads, context isolation to prevent information overload, or executing long-running tasks without blocking the main process. This enables parallel processing and decoupled execution, significantly boosting work efficiency and context management.
npx skills add https://github.com/obra/external-subagents --skill codex-subagentsBefore / After Comparison
1 组When the main agent needs to conduct multiple complex research tasks or long analyses simultaneously, its context quickly bloats, leading to slow responses and difficulty processing subsequent instructions due to information overload. Tasks must be executed sequentially, which is time-consuming and inefficient.
By assigning each research task to an independent subagent, the main agent's context remains lean. Subagents execute in parallel, significantly reducing the total time to complete all research and ensuring the main agent stays responsive and focused.
Codex Subagents
Overview
codex-subagent offloads work to background threads so your main context stays lean. Threads run detached by default; use wait/peek to check results.
Critical rules:
- You cannot send to a running thread. Always wait before sending follow-ups.
- Use
--permissions read-onlyor--permissions workspace-write(notworkspace-read)
For detailed workflow documentation, see reference/workflow.md.
When to Use
| Situation | Why subagents help |
|---|---|
| Parallel research tasks | Multiple threads run simultaneously |
| Context would bloat | Research stays in separate thread |
| Long-running work | Detached execution, check later |
Don't use for: Quick inline questions, tightly-coupled work needing your current state.
Core Workflow
1. start with --prompt (inline text or stdin)
2. wait/peek → check result
3. send → resume with follow-up (ONLY after thread stops)
4. archive/clean → lifecycle management
The Running Thread Rule
You CANNOT send to a running thread. This is the #1 mistake.
# WRONG - thread might still be running
echo "followup" | codex-subagent send thread-abc --prompt -
# RIGHT - wait first, then send
codex-subagent wait --threads thread-abc
echo "followup" | codex-subagent send thread-abc --prompt -
Resumable statuses: completed, failed, stopped, waiting
Quick Reference
| Command | Purpose | Key flags |
|---|---|---|
start | Launch new thread | --role, --permissions, --prompt, --label, -w |
send | Resume stopped thread | <thread-id>, --prompt, -w |
peek | Read newest unseen message | <thread-id>, --save-response |
log | Full history | <thread-id>, --tail, --json |
status | Thread summary | <thread-id> |
wait | Block until threads stop | --threads, --labels, --all, --follow-last |
list | Show threads | --status, --label, --role |
archive | Move completed to archive | --completed, --yes, --dry-run |
clean | Delete old archives | --older-than-days, --yes |
Prompt input: --prompt "text" for simple prompts, --prompt - reads from stdin (for multi-line), -f/--prompt-file for files
Positional thread IDs: peek abc123 works like peek -t abc123
Common Patterns
Simple inline prompt
codex-subagent start --role researcher --permissions read-only \
--label "quick-task" --prompt "List all exported functions in src/lib/"
Multi-line prompt (heredoc)
cat <<'EOF' | codex-subagent start --role researcher --permissions read-only --label "auth-research" --prompt -
Research authentication patterns in this codebase:
1. Find all auth-related files
2. Document the auth flow
3. Note any security concerns
EOF
Parallel research
# Launch multiple researchers
cat <<'EOF' | codex-subagent start --role researcher --permissions read-only --label "API: Stripe" --prompt -
Research Stripe API authentication methods and best practices
EOF
cat <<'EOF' | codex-subagent start --role researcher --permissions read-only --label "API: Twilio" --prompt -
Research Twilio API authentication methods and best practices
EOF
# Wait for all, see results
codex-subagent wait --labels "API:" --follow-last
Blocking task
# -w blocks until complete (may take minutes)
cat <<'EOF' | codex-subagent start --role researcher --permissions read-only --prompt - -w --save-response result.txt
Analyze error handling patterns in src/
EOF
cat result.txt
Warning: -w blocks for as long as the agent runs. For long tasks, prefer detached mode with wait --follow-last.
Cleanup old work
# Two-phase: archive completed, then clean old archives
codex-subagent archive --completed --yes
codex-subagent clean --older-than-days 30 --yes
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| "profile does not exist" | Wrong permissions | Use read-only or workspace-write (not workspace-read) |
| "not resumable" error | Thread still running | wait first, then send |
| "different controller" | Wrong session | Use --controller-id or check list |
| Thread disappeared | Was archived | Check archive dir or re-run task |
Checklist
-
starthas--role,--permissions,--prompt, and--label - Permissions are
read-onlyorworkspace-write -
waitbeforesend(never send to running thread) - Results captured with
--save-responseorpeek
codex-subagent-cli
A TypeScript CLI for launching and managing Codex subagents without bloating the primary agent's context. Threads run via codex exec --json, with metadata stored under .codex-subagent.
Getting Started
cd dev
npm install
npm run build
All commands assume Node 20+ and npm 10+. The build outputs codex-subagent to the repo root.
CLI Usage
codex-subagent <command> [options]
Installing as a Codex Skill
Clone this repository to ~/.codex/skills/using-subagents-as-codex/:
git clone https://github.com/obra/external-subagents ~/.codex/skills/using-subagents-as-codex
cd ~/.codex/skills/using-subagents-as-codex/dev
npm install
npm run build
Codex will use the relative path codex-subagent when invoking the CLI from the skill.
Global flags
--root <path>: override the default.codex-subagentroot.--controller-id <id>: override the auto-detected controlling Codex session (use this when multiple Codex windows should share the same subagent state).
| Command | Purpose |
|---|---|
start | Launch a new Codex exec thread with explicit role/policy (defaults to detached, so it returns immediately; add --wait to block). |
send | Resume an existing thread with a new prompt (defaults to detached, add --wait to block). |
peek | Show the newest unseen assistant message (read-only; --verbose prints last-activity info). |
log | View the stored NDJSON history (supports --tail, --raw, --verbose). |
status | Summarize the latest activity for a thread (latest message, idle time, optional log tail). |
watch | Continuously peek a thread at an interval (use --duration-ms to exit cleanly). |
wait | Block until specific threads (or labels/all threads) reach a stopped state; optional timeout + “follow last assistant” output. |
archive | Move completed thread logs/state into .codex-subagent/archive/... (with --yes/--dry-run). |
label | Attach/update a friendly label for a thread so list is easier to scan. |
list | List every thread owned by the current controller (and show a “Launch diagnostics” section when detached start/send attempts are still pending or have failed, including error logs). |
Per-command notes:
startrequires--role,--policy, and--prompt-file(write prompts to files to avoid shell quoting issues). Policies are mapped to safe--sandbox/--profilecombinations automatically.start --manifest tasks.json(or--manifest-stdin) launches multiple prompts from a single JSON payload. Each task entry acceptsprompt,role,policy,cwd,label,persona,outputLast, andwait. This is the fastest way to spin up a whole squad of helpers; reference prompts inline in JSON so you don’t have to create dozens of temp files.start --json prompt.json(or--json -with stdin) accepts a single structured payload:{ "prompt": "...", "role": "researcher", "policy": "workspace-write", "cwd": "/repo", "label": "Task", "persona": "reviewer", "output_last": "last.txt", "wait": true }. Fields mirror the CLI flags, so you can drop prompt files entirely for ad-hoc work.send --json followup.jsonworks the same way for resume turns (prompt,cwd,persona,output_last,wait).startwarns that long-running Codex sessions may take minutes or hours. Use the default detached mode when you just want the work to continue in the background, and--waitwhen you truly need to stream the run inline.start/sendaccept--cwd <path>to automatically prepend “work inside /path” instructions,--labelto tag new threads, and--persona <name>to merge Anthropic-style agent personas (project.codex/agents/,~/.codex/agents/, superpowersagents/). Model aliases (haiku,sonnet,opus,inherit) are mapped onto safe Codex policies; if a persona setsmodel: sonnet, we’ll useworkspace-write, etc.sendneeds--thread+--prompt-fileand, likestart, runs detached unless you pass--wait. If a persona was set when the thread started, latersendcalls reuse the same persona automatically unless you override it with--persona.peek,log,watchall require--threadand never call Codex (they read the local log/registry).peek/logaccept--verboseto print last activity timestamps even when nothing changed;watchadds--duration-msso you can stop polling automatically instead of relying on Ctrl+C.status --thread <id> [--tail 5] [--stale-minutes 15]gives a one-shot summary (latest assistant turn, idle duration, and a suggestion to nudge if the thread has been idle longer than the threshold).wait --threads id1,id2 --follow-lastpolls the registry/logs until every selected thread stops. Use--labels label-a,label-bor--all-controllerto track batches launched via manifests,--interval-msto tune polling frequency, and--timeout-msto fail fast instead of waiting forever. When--follow-lastis set you’ll also see the final assistant reply for each thread as it finishes.--print-promptshows the fully composed prompt (persona + working directory instructions) before launching Codex. Add--dry-runto skip the Codex invocation entirely after printing—handy for sanity-checking inputs.label --thread <id> --label "Task X"lets you rename an existing thread after the fact (pass an empty string to clear it).archive --thread <id> --yesmoves a completed thread into the archive. Use--completed --yesto archive all completed threads, or--dry-runto preview.listnow prints aLaunch diagnosticssection whenever a detachedstart/sendattempt hasn’t reached Codex yet or failed immediately. Failed launches appear withNOT RUNNINGplus the captured error message and a pointer to.codex-subagent/state/launch-errors/<launch-id>.log; pending launches older than ~2 minutes emit a “still waiting for Codex” warning so you know to investigate.
JSON prompt payloads
Skip ad-hoc prompt files by piping JSON straight into start or send:
cat <<'JSON' | codex-subagent start \
--role researcher \
--policy workspace-write \
--json - \
--print-prompt
{
"prompt": "List open bugs, then propose a fix.",
"cwd": "/Users/jesse/repos/service",
"label": "Bug sweep",
"persona": "triage",
"output_last": "/tmp/bugs-last.txt",
"wait": true
}
JSON
The same schema works for send:
codex-subagent send --thread 019... --json followup.json --wait
Relative paths inside the JSON payload are resolved against the file’s directory (or the current working directory when using stdin), so you can keep everything self-contained beside your manifest/prompt files.
Launch diagnostics & troubleshooting
- Where errors live: Every detached
start/sendattempt writes a record to.codex-subagent/state/launches.jsonuntil Codex produces a thread turn. If launch fails (missing profile, sandbox denial, etc.), the CLI preserves the full stderr/stack under.codex-subagent/state/launch-errors/<launch-id>.logandlistmarks the attempt asNOT RUNNING. - How to detect issues: Run
codex-subagent listafter launching helpers. If theLaunch diagnosticssection shows a pending attempt with the warning “still waiting for Codex (no thread yet),” Codex hasn’t even started—re-run the prompt or inspect the log file. Failed entries include the exact error plus the log path so you can fix the root cause before retrying. - Thread failures after resume: When a detached
sendfails, the owning thread’s status flips toNOT RUNNINGand the reason appears vialist+status.status --thread <id>now prints the failure message directly, so you can summarize the issue without re-reading the log. - Home directory sandboxing: If the environment blocks writes to
~/.codex(common under workspace-only sandboxes),codex-subagentautomatically runscodex execwithCODEX_HOME=./.codex-home(created in the current working directory) and best-effort copies~/.codex/auth.json+~/.codex/config.tomlinto it..codex-home/is gitignored but contains credentials—treat it like a secret. - Claude backend (optional): Claude support is behind a feature flag. Set
CODEX_SUBAGENT_ENABLE_CLAUDE=1to use--backend claude.
Demo
npm run demo spins up a throwaway thread and then attaches watch so you can see updates flow through without any manual wiring.
Development
- Format:
npm run format:fix - Lint:
npm run lint - Type-check:
npm run typecheck - Tests:
npm run test - Build bundle:
npm run build
peek/log/watch share NDJSON logs under .codex-subagent/logs/<thread>.ndjson. Registry metadata lives in .codex-subagent/state/threads.json (commit this file only when intentionally sharing test fixtures).
Policies & Safety
Subagents must never run in "allow everything" mode. The CLI enforces this by refusing dangerous policies and mapping safe ones to explicit --sandbox/--profile parameters when invoking codex exec. Every thread is also tagged with the controller session ID (auto-detected from the parent Codex pro
...
User Reviews (0)
Write a Review
No reviews yet
Statistics
User Rating
Rate this Skill