- name
- using-codex
- description
- This skill should be used whenever the user asks to "use codex", "ask codex", "delegate to codex", "second opinion from codex/gpt", "have codex review", "run this in codex", "codex workflow", "let gpt implement", or wants OpenAI Codex involved in review, planning, implementation, research, or a Workflow, and when deciding whether a task is better handed to Codex than done in Claude.
# Using Codex from Claude Code
`codex-bridge` runs OpenAI Codex through `codex app-server` and prints one compact JSON envelope. The full Codex output always lands in a file; the envelope carries only status, ids, usage, and a bounded `summary`. This is what keeps Claude tokens low: never relay Codex prose through a subagent when a file path will do.
## The one command
```
node "${CLAUDE_PLUGIN_ROOT}/scripts/codex-bridge.mjs" run --preset <preset> --task "<one to three sentences>"
```
Envelope fields: `status` (completed | unconfirmed | failed | stalled | timeout | interrupted), `thread_id`, `turn_id`, `out_file` (full final message), `result_file` (full parsed object of a `--schema` run), `events_file`, `usage`, `duration_s`, `idle_timeout_s`, `hard_timeout_s` (null unless `--timeout` was given), `model_applied` (the model that actually ran), `summary`, `files_changed`, `commands_run`, `diff_file` (the turn's diff, when there was one), `questions` and `questions_file` (anything Codex asked and got no answer to), `error`. An `implement` run also carries the task contract: `outcome` (done | partial | blocked, downgraded by the bridge when the evidence does not support "done"), `checks`, `open_questions`, `contract_violations` and `continuation` (a resume handle when the work is not done). Branch on `outcome`, not on the prose. `unconfirmed` means the final answer arrived but the server could not confirm the turn ended: read `out_file`, but treat it as unverified.
Other commands: `review`, `resume <thread|--last>`, `result [--last|run-id] [--full]`, `status [--last|run-id]`, `steer`, `threads`, `worktrees`, `doctor`, `server start|stop|status|release`, `presets`. Output is quiet by default; `--verbose` streams progress to stderr. Run `codex-bridge.mjs help` for flags.
On the shared server a run collects only its own thread *and* turn, so a concurrent run's output can never land in this envelope. `--all-events` additionally records the rejected traffic in `events_file` for debugging; it is never attributed.
## How long a turn runs
A turn takes as long as Codex needs; there is no wall-clock limit. The watchdog is `--idle-timeout`
(default 600 s), which fires only when **no** event has arrived for that long, i.e. the turn is
genuinely stalled rather than slow. A stalled run comes back as `status: "stalled"`, distinct from
`timeout`.
`--timeout` adds an optional absolute cap on the **whole command**, not on each phase: connecting,
the handshake, model selection, opening the thread and the turn itself all share the one budget, so
`--timeout 60` means the command is done in about a minute. Only a small bounded tail for
interrupting and closing may follow it.
## Codex may delegate
Codex spawns its own subagents when a task suits it, and their work is attributed back into the
run: `commands_run` and `files_changed` include theirs, and `subagents[]` lists each one with its
label and counts. Ask for it explicitly when a task splits cleanly ("delegate these three checks to
parallel subagents, then consolidate"): it is one Codex turn and one Claude call regardless of how
many subagents run.
## Pick a preset
| Preset | Use for | Sandbox | Effort | Model |
|---|---|---|---|---|
| `consult` | second opinion, design critique, "try to refute this" | read-only | xhigh | default |
| `review` | code review of a diff (`review` command) | read-only | high | default |
| `plan` | implementation plan before coding | read-only | xhigh | default |
| `implement` | make the change, run tests; thread persists for `resume` | workspace-write | high | sol, then terra |
| `research` | facts that need live web search | read-only | medium | sol, then terra |
| `quick` | lookups, small transforms, yes/no checks | read-only | xhigh | luna, then spark |
`default` is a **tier**, resolved against the live catalog at run time: whatever Codex marks as its default model (gpt-6-astra at the time of writing), not a pinned id and not the user's `config.toml` pin. It is reserved for the short, judgement-heavy presets; `implement` and `research` name a cheaper candidate list so Astra is not spent on every long run, and `quick` runs a small model at high effort. `--model config` inherits the user's pin; `--model <id>` is sent as given. An effort the chosen model does not advertise is dropped rather than sent, so `ultra` only reaches a model that offers it. `model_applied` in the envelope says what actually ran.
This table is a summary; `references/presets.md` is the authoritative matrix (timeouts, summary lengths, extras). Override per call with `--model`, `--effort`, `--sandbox` or `--write`, `--timeout`, `--schema`. Sandbox is always sent explicitly; the user's `danger-full-access` config never leaks into a run.
## When to delegate
Delegate when a second model adds value or when the work is long and self-contained: independent review of a diff Claude wrote, refuting a hypothesis, a long implementation while Claude keeps working, research needing live web search, or a burst of parallel mechanical tasks. Do not delegate a two-minute edit; the round trip alone is twenty seconds.
## Writing the task (point, don't paste)
Codex has full repository access. Name files, functions, and commands; do not paste their contents. Bridge threads read the project's `AGENTS.md`, or `CLAUDE.md` when there is none (per-thread `project_doc_fallback_filenames`; `claude_md_fallback: false` in settings turns that off), and carry the relay contract as developer instructions, so the task need not repeat either. The envelope's `instruction_sources` lists what was loaded. A good task is one to three sentences plus, if needed, the acceptance criterion:
```
--task "Refute this claim by reading scripts/lib/process.mjs: on Windows the vendored codex.exe is resolved before any shell spawn."
--task "Implement --retries N for scripts/codex-bridge.mjs run (retry transport failures only). Add a node:test case in tests/. Run npm test."
```
The preset template already fixes the response contract (length caps, ordering, file:line references). For a long brief, write it to a file and pass `--task-file`. To invoke one of Codex's own skills explicitly, pass `--skill <name>` (repeatable): the name is resolved through `skills/list` for the working directory and sent as the documented skill input item, and an unknown or disabled name fails before any turn.
## Ordinary sessions: call the script directly
Use Bash yourself. No subagent is needed. For anything over a minute, use `run_in_background: true`; the envelope arrives with the completion notification, and `result --last` re-prints it. Read `out_file` with Read only when `summary` was truncated or the detail matters.
For an `implement` while you are editing the same checkout, add `--worktree`: Codex works in its own checkout branched from HEAD, the envelope's `diff_file` is the complete patch to apply or review, and your tree is untouched (a dirty checkout is refused unless you pass `--worktree-from HEAD`). `worktrees remove <run-id>` cleans up afterwards.
A run in the background can be redirected with `steer --last --task "…"` (shared server only) and inspected with `status --last`, which also recovers a run whose process died by asking the server what became of the turn.
Continue a persisted thread instead of re-explaining: `resume --last --task "Now add tests for the edge case you mentioned."` Threads from `consult`, `plan` and `implement` persist by default (named `[claude] <preset>: <task head>` in the user's Codex history); add `--persist` to any other preset. `threads prune --older-than 14` archives old bridge threads. A resumed thread keeps the sandbox, model and effort it ran under unless you pass a flag, so an `implement` thread stays writable; `--last` is scoped to this Claude session when the SessionStart hook ran.
## Fan-out: prefer the native runner
For a fan-out where every stage is a Codex turn (review panels, sweeps, adversarial verification),
use `scripts/codex-workflow.mjs`. It runs the whole thing in one Node process with no Claude agent
in the loop, so nothing relays output, stages can run for as long as they need, and completed calls
are cached for `--resume`:
```
node "${CLAUDE_PLUGIN_ROOT}/scripts/codex-workflow.mjs" run \
"${CLAUDE_PLUGIN_ROOT}/workflows/review-panel.mjs" --args @lenses.json
```
Launch it with `run_in_background: true`; read `result` from the summary it prints. See
`references/native-runner.md` for the script API and the bundled workflows.
When your own judgement belongs between Codex stages, run one native workflow, read its
`result.json`, decide, and launch the next: one Bash call per stage and no relaying agent. The
Claude Workflow tool path (a Haiku agent forwarding one command line) was removed: an LLM call
that copies stdout costs tokens and needed guard hooks to keep it honest, and the native runner
covers every all-Codex fan-out.
For fan-out over many small items, consider one Codex turn that does the fan-out itself with Codex subagents (on by default in current Codex as `multi_agent_v2`); that costs one Claude call instead of N.
## Concurrency and the shared server
Each `run` spawns a private `codex app-server` (about 2 s startup plus MCP servers from the user's config). Parallel runs are independent processes. For many short calls, `server start` launches one loopback WebSocket server; `--via ws` or `shared_server: true` in settings routes runs through it, and `codex agents --remote ws://127.0.0.1:4517` lets the user watch them. Thread-scoped `--config` keys and `--search` apply on both transports (they travel in `thread/start.config`); process-scoped keys only reach a private server.
## Failure handling
`status: failed` with `error_kind` from Codex (`UsageLimitExceeded`, `Unauthorized`, `ContextWindowExceeded`, `SandboxError`) or an HTTP error body. `RateLimitPreflight` means the account was already past `rate_limit_refuse_percent` and no turn was started; `rate_limit.resets_at` says when to retry. `timeout` means the turn was interrupted at `--timeout`; the partial `summary` is whatever Codex had said. Run `doctor` when nothing works. Codex usage counts against the user's ChatGPT or API limits.
## Additional resources
- `references/presets.md`: preset matrix, template contracts, how to add a preset.
- `references/protocol.md`: app-server methods the runtime uses, envelope schema, run store layout.
- `references/native-runner.md`: the codex-workflow script API, run directory layout, and resume.
在 GitHub 查看