CBEPX fork. Install with
claude plugin marketplace add CBEPX/codex-plugin-ccthenclaude plugin install codex@cbepx. Differences from upstream are listed in CHANGELOG.md. Upstream: openai/codex-plugin-cc.
Use Codex from inside Claude Code for code reviews or to delegate tasks to Codex.
This plugin is for Claude Code users who want an easy way to start using Codex from the workflow they already have.
/codex:reviewfor a normal read-only Codex review/codex:adversarial-reviewfor a steerable challenge review/codex:rescue,/codex:transfer,/codex:status,/codex:result, and/codex:cancelto delegate work, hand off sessions, and manage background jobs
- ChatGPT subscription (incl. Free) or OpenAI API key.
- Usage will contribute to your Codex usage limits. Learn more.
- Node.js 18.18 or later
Add the marketplace in Claude Code:
/plugin marketplace add CBEPX/codex-plugin-ccInstall the plugin:
/plugin install codex@cbepxReload plugins:
/reload-pluginsThen run:
/codex:setup/codex:setup will tell you whether Codex is ready. If Codex is missing and npm is available, it can offer to install Codex for you.
If you prefer to install Codex yourself, use:
npm install -g @openai/codexIf Codex is installed but not logged in yet, run:
!codex loginAfter install, you should see:
- the slash commands listed below
- the
codex:codex-rescuesubagent in/agents
One simple first run is:
/codex:review --background
/codex:status
/codex:resultRuns a normal Codex review on your current work. It gives you the same quality of code review as running /review inside Codex directly.
Note
Code review especially for multi-file changes might take a while. It's generally recommended to run it in the background.
Use it when you want:
- a review of your current uncommitted changes
- a review of your branch compared to a base branch like
main
Use --base <ref> for branch review. It also supports --wait and --background. It is not steerable and does not take custom focus text. Use /codex:adversarial-review when you want to challenge a specific decision or risk area.
Examples:
/codex:review
/codex:review --base main
/codex:review --backgroundThis command is read-only and will not perform any changes. When run in the background you can use /codex:status to check on the progress and /codex:cancel to cancel the ongoing task.
Runs a steerable review that questions the chosen implementation and design.
It can be used to pressure-test assumptions, tradeoffs, failure modes, and whether a different approach would have been safer or simpler.
It uses the same review target selection as /codex:review, including --base <ref> for branch review.
It also supports --wait and --background. Unlike /codex:review, it can take extra focus text after the flags.
Use it when you want:
- a review before shipping that challenges the direction, not just the code details
- review focused on design choices, tradeoffs, hidden assumptions, and alternative approaches
- pressure-testing around specific risk areas like auth, data loss, rollback, race conditions, or reliability
Examples:
/codex:adversarial-review
/codex:adversarial-review --base main challenge whether this was the right caching and retry design
/codex:adversarial-review --background look for race conditions and question the chosen approachThis command is read-only. It does not fix code.
Hands a task to Codex through the codex:codex-rescue subagent.
Use it when you want Codex to:
- investigate a bug
- try a fix
- continue a previous Codex task
- take a faster or cheaper pass with a smaller model
Note
Depending on the task and the model you choose these tasks might take a long time and it's generally recommended to force the task to be in the background or move the agent to the background.
It supports --background, --wait, --resume, and --fresh. If you omit --resume and --fresh, the plugin can offer to continue the latest rescue thread for this repo.
Examples:
/codex:rescue investigate why the tests started failing
/codex:rescue fix the failing test with the smallest safe patch
/codex:rescue --resume apply the top fix from the last run
/codex:rescue --model gpt-6-astra --effort medium investigate the flaky integration test
/codex:rescue --model spark fix the issue quickly
/codex:rescue --background investigate the regressionYou can also just ask for a task to be delegated to Codex:
Ask Codex to redesign the database connection to be more resilient.
Notes:
-
if you do not pass
--modelor--effort, Codex chooses its own defaults. -
--effortacceptsnone,minimal,low,medium,high,xhigh,max, andultra. Which of those a given model supports comes from the local Codex model catalogue: when--modelnames a catalogued model, the plugin rejects an effort that model does not list, and otherwise leaves the check to Codex — runcodex debug modelsto see the reasoning levels each model advertises. -
model aliases resolve against the local Codex model catalogue (
$CODEX_HOME/models_cache.json, elsecodex debug models --bundled): an alias picks the listed model whose slug ends in-<alias>, lowest priority number first, newest family on ties; todaysol->gpt-6-sol,astra->gpt-6-astra,luna->gpt-6-luna,terra->gpt-5.6-terra,spark->gpt-5.3-codex-spark,mini->gpt-5.4-mini; runcodex debug modelsto see yours. An exact model slug passes through unchanged, and when the model is in the catalogue--effortis checked against the reasoning levels it lists -
--config key=value(repeatable, also on/codex:reviewand/codex:adversarial-review) forwards aconfig.tomloverride to the Codex thread, e.g.--config model_provider=ollama. On--resume-lastthe plugin opens a fresh app-server session (cold resume) so--configoverrides, sandbox and approval policy take effect; model and effort for the resumed turn are sent on the turn, never on the resume request. In a--background/--awaitjob record the config keys are recorded and the values are never stored (they read back as[redacted]instatus/result): the real values live only in the job's private 0600jobs/<id>.request.json, which the worker consumes and deletes. -
follow-up rescue requests can continue the latest Codex task in the repo
-
under the hood,
/codex:rescueand thecodex-rescueagent are each a singlescripts/codex-companion.mjs task --await --prompt-stdin <flags>call:--await [--await-timeout-ms <ms>]launches the same tracked background job as--background, then waits for it (default 540000 ms), and--prompt-stdinreads the prompt as stdin verbatim (so it cannot be combined with--args-stdin,--prompt-file, or prompt text on the command line). Exit code is 0 when the job completed, 1 when it failed or was cancelled, and 3 when the wait times out while the job is still queued or running — exit 3 prints aRe-run: node "<abs>" result <id> --wait --timeout-ms 540000hint, which is the only follow-up call the rescue flow makes. With--args-stdin(and a single-string$ARGUMENTS), a backslash escapes only a following quote, backslash or whitespace and stays literal before anything else, soC:\Users\mesurvives but\\server\sharebecomes\server\share; use--prompt-stdinfor byte-exact text. -
result <id> [--wait [--timeout-ms <ms>]]answers a different question, so it has its own contract:resultexits 0 for any terminal record (completed, failed or cancelled) and 3 while the job is still active. Its exit code means "a result was retrieved", not "the job succeeded" — unliketask --awaitit never returns 1 for a failed job, so read the rendered record for the outcome. A plainresult <id>on a still-running job prints the same--waithint and exits 3 instead of failing (fixes upstream #498/#524, which reported "No job found" for a running job).--jsonon either returns{ job, storedJob }(or, on a timeout, thestatus --jsonsnapshot plus aresumeCommandfield). -
The detached worker outlives the companion only when the companion returns on its own (exit 3); a host process-tree kill — e.g. Claude Code's Bash timeout — also kills the worker, so keep
--await-timeout-msbelow the host limit (default 540000 < 600000). -
--turn-timeout-ms <ms>(orCODEX_TURN_TIMEOUT_MS, also on/codex:reviewand/codex:adversarial-review) bounds a single Codex turn: on expiry it interrupts the turn and returns a structured failed result ("turn timed out after<ms>ms") instead of hanging. Default is0(unbounded). The budget travels with a--background/--awaitjob, so a detached worker enforces it too. The interrupt is not trusted on its own: the run waits up to 10 s for the turn's terminal notification, and if none arrives the failure says so ("interrupt not acknowledged — the turn may still be running in the shared runtime, check status or cancel"), because a shared broker runtime can keep executing a turn nobody is listening to any more. A run that owns its own app-server (a cold--resume-last) closes it in that case, which does stop the turn (stdin EOF, thenSIGTERM, thenSIGKILL, so the close is bounded too). Partial output on a timed-out turn is best-effort: only whole items Codex had already completed are kept, so a turn interrupted mid-message reports less text than Codex had produced. -
the
SessionEndhook works to one absolute budget (SESSION_END_BUDGET_MS, 12 s;CODEX_COMPANION_SESSION_END_BUDGET_MScan only shorten it — a larger value is ignored with a note, since the hook timeout is fixed), and every bounded step inside it — the workspace state lock, each broker handshake, the busy retries, the teardown probe — is clamped to what is left of that budget.hooks/hooks.jsongivesSessionEnda 15 s timeout, which must stay above the budget: below it Claude Code would kill the hook mid-decision instead of letting it report one. A test asserts the pair, so the two numbers cannot drift apart. -
if a background job's session ends while
CODEX_COMPANION_BROKER_IDLE_TIMEOUT_MS=0, the shared broker that keeps running for that job never self-terminates on its own — its normal idle exit is disabled in that configuration, so the broker only goes away once the job finishes (or is reaped as dead) and a laterSessionEndruns. -
the
SessionEndbroker teardown line ([codex] Broker teardown: ... reason=<reason>) names one of:reason meaning no-pidno broker pid was recorded; nothing to signal identity-matchthe pid was proven to be this broker by its recorded identity, so the signal was attempted ( signalledsays whether it landed)command-line-matcha record without an identity was proven by its command line, so the signal was attempted identity-mismatchthe pid is no longer provably ours (another process, or a command line that did not match or could not be read); left alone identity-unavailablethe identity could not be read (e.g. on Windows under Constrained Language Mode/AppLocker); left alone process-missingWindows: the pid was provably gone before anything was signalled; /codex:cancelleaves the job to the reaper (unless the worker already wrote its final record), other kills clean the record upkill-failedthe ownership probe or the kill threw, or (Windows, method handle) the kill left survivors or its outcome could not be verified; the broker may still be running
Creates a persistent Codex thread from the current Claude Code session and prints a codex resume <session-id> command.
Use it when you started a debugging or implementation conversation in Claude Code and want to continue that same context directly in Codex.
Examples:
/codex:transfer
/codex:transfer --source ~/.claude/projects/-Users-me-repo/<session-id>.jsonlThe plugin's existing SessionStart hook supplies the current transcript path automatically; --source is available as a manual override. The transfer uses Codex's external-agent session importer, so it follows the same conversion rules as importing Claude history in the Codex App and creates visible turns that can be continued in the App or TUI. The source must be under ~/.claude/projects ($CLAUDE_CONFIG_DIR/projects when CLAUDE_CONFIG_DIR is set), and older Codex versions that do not expose session import must be upgraded before using this command.
Shows running and recent Codex jobs for the current repository.
Examples:
/codex:status
/codex:status task-abc123Use it to:
- check progress on background work
- see the latest completed job
- confirm whether a task is still running
status <id> --wait [--timeout-ms <ms>] blocks until the job reaches a terminal status; it exits 1 when the wait times out while the job is still running (with --json too, whose snapshot carries waitTimedOut: true), and the text output ends with Timed out after <N>s while the job was still running.
Shows the final stored Codex output for a finished job.
When available, it also includes the Codex session ID so you can reopen that run directly in Codex with codex resume <session-id>.
Examples:
/codex:result
/codex:result task-abc123
/codex:result task-abc123 --wait
/codex:result task-abc123 --wait --timeout-ms 60000On a job that already has a terminal record (completed, failed, or cancelled), /codex:result exits 0 and shows it — the exit code reports that a result was retrieved, not whether the job succeeded. On a job that is still queued or running, a plain /codex:result <id> prints a Re-run: … result <id> --wait hint and exits 3 instead of failing; add --wait [--timeout-ms <ms>] (default 540000 ms) to block until the job reaches a terminal status instead of returning immediately. --json returns { job, storedJob } (or, on a --wait timeout, the status --json snapshot plus a resumeCommand field).
Cancels an active background Codex job.
A job whose turn runs through the shared broker is cancelled by interrupting the turn: /codex:cancel waits up to 10 s for the job's own final record and then answers cancelled. If the turn does not end (the runtime ignored or refused the interrupt), it answers cancellationPending with reason: turn-not-interrupted and exit 1, stops nothing, and the job stays running; re-run the cancel or wait for the turn. A job that owns its app-server (a cold --resume-last, transport: direct in status --json) is stopped by stopping its worker, without a turn interrupt (turnInterruptAttempted: false).
Examples:
/codex:cancel
/codex:cancel task-abc123Checks whether Codex is installed and authenticated. If Codex is missing and npm is available, it can offer to install Codex for you.
You can also use /codex:setup to manage the optional review gate.
/codex:setup --enable-review-gate
/codex:setup --disable-review-gateWhen the review gate is enabled, the plugin uses a Stop hook to run a targeted Codex review based on Claude's response. If that review finds issues, the stop is blocked so Claude can address them first. When the review itself fails (timeout, killed by a signal, invalid output), the block reason says why and ends with Disable with /codex:setup --disable-review-gate. The hooks read their input from stdin against a deadline (1 s for SessionEnd, before its budget starts; 5 s for SessionStart; 2 s for Stop), so a disabled gate never waits on a stdin Claude Code leaves open, while an enabled gate blocks when the input never arrives. With the gate on and a host that never closes stdin or never sends the input, every stop is blocked; run /codex:setup --disable-review-gate to get out.
To pin the model and reasoning effort the gate's review uses, independently of your Codex config:
/codex:setup --review-gate-model spark --review-gate-effort low
/codex:setup --review-gate-model inherit --review-gate-effort inheritModel aliases (spark, astra, sol, luna, terra, mini) resolve the same way as for /codex:rescue; inherit clears the pin so the review uses your Codex config again.
Warning
The review gate can create a long-running Claude/Codex loop and may drain usage limits quickly. Only enable it when you plan to actively monitor the session.
By default the gate blocks at most 3 consecutive rounds in a single session, then lets the stop through. Set CODEX_REVIEW_GATE_MAX_ROUNDS to change that cap:
# allow at most 5 stop-gate review rounds per session, then let the stop proceed
export CODEX_REVIEW_GATE_MAX_ROUNDS=5When unset, the cap is 3. Set it to 0 explicitly to keep the gate unbounded (the pre-1.3.0 behavior). The count is per session, increments on each blocked round (tracked via stop_hook_active), and resets once a stop is allowed or a fresh user turn begins.
/codex:review/codex:rescue investigate why the build is failing in CI/codex:adversarial-review --background
/codex:rescue --background investigate the flaky testThen check in with:
/codex:status
/codex:resultThe Codex plugin wraps the Codex app server. It uses the global codex binary installed in your environment and applies the same configuration.
If you want to change the default reasoning effort or the default model that gets used by the plugin, you can define that inside your user-level or project-level config.toml. For example to always use gpt-6-astra on high for a specific project you can add the following to a .codex/config.toml file at the root of the directory you started Claude in:
model = "gpt-6-astra"
model_reasoning_effort = "high"Your configuration will be picked up based on:
- user-level config in
~/.codex/config.toml - project-level overrides in
.codex/config.toml - project-level overrides only load when the project is trusted
Check out the Codex docs for more configuration options.
Delegated tasks and any stop gate run can also be directly resumed inside Codex by running codex resume either with the specific session ID you received from running /codex:result or /codex:status or by selecting it from the list.
This way you can review the Codex work or continue the work there.
If you are already signed into Codex on this machine, that account should work immediately here too. This plugin uses your local Codex CLI authentication.
If you only use Claude Code today and have not used Codex yet, you will also need to sign in to Codex with either a ChatGPT account or an API key. Codex is available with your ChatGPT subscription, and codex login supports both ChatGPT and API key sign-in. Run /codex:setup to check whether Codex is ready, and use !codex login if it is not.
No. This plugin delegates through your local Codex CLI and Codex app server on the same machine.
That means:
- it uses the same Codex install you would use directly
- it uses the same local authentication state
- it uses the same repository checkout and machine-local environment
Yes. If you already use Codex, the plugin picks up the same configuration.
Every write to this workspace's job state is serialized by a ticket lock: each command takes a numbered ticket in state.lock.d/ and waits for the tickets ahead of it. See docs/state-and-lifecycle.md.
The same lock refuses to guess. See docs/state-and-lifecycle.md.
Yes. Because the plugin uses your local Codex CLI, your existing sign-in method and config still apply.
If you need to point the built-in OpenAI provider at a different endpoint, set openai_base_url in your Codex config.
Requirements: cmd.exe and Windows PowerShell 5.1 (both ship with Windows; no Store pwsh needed); codex and npm on the Windows PATH as .cmd/.exe. Kills from stored records (/codex:cancel, SessionEnd cleanup, broker teardown) verify the process before killing it. /codex:cancel answers cancelled, or cancellationPending (the job stays running) with survivors (pid and identity) when part of the tree outlived the kill, or with reason: identity-unavailable when the process could not be verified (for example while the shared broker is still starting, or under PowerShell Constrained Language Mode), or with reason: turn-not-interrupted while a brokered job's turn is still running (see /codex:cancel above); SessionEnd keeps a record whose kill outcome is unknown (kept=true), including a refused or failed kill whose worker has already exited, and re-judges it next time. Details, limits and the state-directory fallback: docs/windows.md.
The plugin runtime supports Node.js 18.18 or later; the development tooling below
(eslint, c8, Stryker) needs Node.js 24. npm run build also needs the codex CLI
on PATH, because it generates the app-server protocol types first.
npm run check— the full local gate: version metadata, changelog, lint, typecheck (npm run build), typecheck of tests and scripts, and the test suite.npm run setup:git-hooks— points git at.githooks/(pre-commit runs lint and typecheck). The setting lives in the shared.git/config, so it applies to the main checkout and every worktree and replaces any.git/hooks/*; typecheck runsprebuild, so committing needs thecodexCLI onPATH.npm run test:coverage— runs the suite under c8 and writesreports/coverage/; thresholds live in.c8rc.json(88% lines and statements, 78% branches, 95% functions).npm run test:mutation:critical— Stryker overargs.mjsandmodel-catalog.mjs, reports inreports/mutation/(also runs weekly in CI).- Working rules for agents and maintainers:
AGENTS.mdanddocs/agent/.
Coverage includes the companion, broker and hook subprocesses that tests spawn,
because c8 passes NODE_V8_COVERAGE to child processes. It has limits: a child
killed with SIGKILL or taskkill /F leaves no coverage dump, a detached broker or
worker may exit after the report is written, and Windows-only branches are not
measured on the ubuntu CI job.