Skip to content

About

Use Codex from Claude Code to review code or delegate tasks.

Resources

Stars

1 star

Watchers

0 watching

Forks

 
 

Repository files navigation

Codex plugin for Claude Code

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.

Note

This repository is a fork of openai/codex-plugin-cc. It tracks upstream main and carries a set of community pull requests that are still open upstream — mostly broker/background-job lifecycle fixes plus a few extra flags. See Differences From Upstream for the full list.

What You Get

  • /codex:review for a normal read-only Codex review
  • /codex:adversarial-review for a steerable challenge review
  • /codex:rescue, /codex:transfer, /codex:status, /codex:result, and /codex:cancel to delegate work, hand off sessions, and manage background jobs
  • /codex:setup to check that Codex is installed and signed in, and to toggle the optional stop-time review gate

Commands At A Glance

Command What it does Main flags
/codex:review read-only Codex review of your current work --wait, --background, --base <ref>, --scope <auto|working-tree|branch>, --model <model|spark|sol|luna|astra>, --effort <level>
/codex:adversarial-review steerable review that challenges the approach same as /codex:review, plus free-form focus text
/codex:rescue delegate investigation or a fix to Codex --background, --wait, --resume, --resume-thread <id>, --fresh, --ephemeral, --model <model|spark|sol|luna|astra>, --effort, --write, --sandbox <mode>, --read-root <dir>
/codex:transfer turn this Claude session into a resumable Codex thread --source <claude-jsonl>
/codex:status show active and recent Codex jobs [job-id], --wait, --timeout-ms <ms>, --all
/codex:result show the stored output of a finished job [job-id]
/codex:cancel cancel an active background job [job-id]
/codex:setup check the Codex install, manage the review gate --enable-review-gate, --disable-review-gate

Accepted --effort values are none, minimal, low, medium, high, and xhigh. An unrecognised --flag is not silently swallowed into the prompt: the plugin warns on stderr and passes the token through as text.

What The Background Runtime Guarantees

Delegated work outlives the Claude session that started it, so most of this fork's divergence from upstream is about what happens when something dies at the wrong moment. In short:

  • A job's state is checked, not trusted. Every status, result and cancel reconciles the record against the worker process, so a run whose worker died does not read as running forever.
  • Ending a session never reports an outcome that did not happen. In-flight jobs are interrupted and recorded as cancelled; a turn that cannot be interrupted keeps its runtime alive instead, on a bounded window.
  • One broker per workspace, shut down by the last session out. It is never torn down while another session has work in flight, and a departed client's Codex threads are unsubscribed rather than left to leak notifications into the next one.
  • A finished job keeps a record, with its cause. Sessions end without erasing what ran, so /codex:status answers with an outcome rather than "No job found".
  • Nothing the plugin writes is world-readable, and nothing is half-written. State, job files, logs and the review-gate config are 0600 and written through a temp file and a rename.
  • Node is found where you actually installed it. Hooks resolve a supported toolchain through scripts/run-node.sh, preferring your version manager over a system install.

Background Runtime Limits and Where State Lives say what bounds those windows and where the files are.

Requirements

  • ChatGPT subscription (incl. Free) or OpenAI API key.
    • Usage will contribute to your Codex usage limits. Learn more.
  • Node.js 18.18 or later.
    • It does not have to be on the system PATH: the hooks resolve Node through scripts/run-node.sh, which also looks in nvm, fnm, asdf, mise, Volta and Homebrew toolchains, preferring one that ships codex alongside it. Set CODEX_COMPANION_NODE to an executable path to pin a specific one.
  • On Windows: Git Bash (the shell Git for Windows installs), because the hooks run scripts/run-node.sh through it.
    • Nothing else is spawned through a shell. codex and npm are .cmd shims, so they are invoked as an explicit cmd.exe /d /s /c call; everything else — git, taskkill, powershell.exe, the background worker — is spawned directly. That matters: routing through a POSIX shell makes MSYS rewrite Windows-style switches, which is why taskkill /PID … /T /F used to fail and background workers could not be stopped.
    • The shared broker listens on a named pipe rather than a Unix socket, and has no filesystem artifact to clean up.

Install

Add the marketplace in Claude Code:

/plugin marketplace add Edo771977/codex-plugin-cc

(Use openai/codex-plugin-cc instead if you want upstream without the imported fixes. The marketplace name is openai-codex either way, so only one of the two can be added at a time.)

Install the plugin:

/plugin install codex@openai-codex

Reload plugins:

/reload-plugins

Then 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/codex

If Codex is installed but not logged in yet, run:

!codex login

After install, you should see:

  • the slash commands listed below
  • the codex:codex-rescue subagent in /agents

One simple first run is:

/codex:review --background
/codex:status
/codex:result

Usage

/codex:review

Runs 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, --background, --scope <auto|working-tree|branch>, and — like /codex:rescue — --model <model|spark|sol|luna|astra> to pick the reviewing model. --effort <level> is accepted and validated here, but the plugin does not pass it to a native review: Codex runs that review at its own reasoning effort. This review is also not steerable and takes no custom focus text. Use /codex:adversarial-review when you want to challenge a specific decision or risk area, or when the reasoning effort has to be yours to choose.

Examples:

/codex:review
/codex:review --base main
/codex:review --background
/codex:review --base main --model gpt-5.4-mini --effort high

This 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.

/codex:adversarial-review

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, --background, --model <model|spark|sol|luna|astra>, and --effort <level>. 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 approach

This command is read-only. It does not fix code.

/codex:rescue

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, --resume-thread <id>, --fresh, --ephemeral, --model <model|spark|sol|luna|astra>, --effort <level>, --write, --sandbox <read-only|workspace-write|danger-full-access>, and repeatable --read-root <directory>. If you omit the resume flags, 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 --resume-thread thr_0199... keep working on that specific thread
/codex:rescue --model gpt-5.4-mini --effort medium investigate the flaky integration test
/codex:rescue --model spark fix the issue quickly
/codex:rescue --background investigate the regression
/codex:rescue --sandbox read-only explain how the cache invalidation works
/codex:rescue --sandbox danger-full-access run the integration tests and fix what fails
/codex:rescue --read-root ./src --read-root ./tests inspect only the approved paths

You 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 --model or --effort, Codex chooses its own defaults.
  • if you say spark, the plugin maps that to gpt-5.3-codex-spark
  • the GPT-6 models have short aliases too: sol, luna and astra map to gpt-6-sol, gpt-6-luna and gpt-6-astra. Aliases are case-insensitive and are expanded by the plugin on every command that takes --model, so a full slug and its alias behave identically. Any other value reaches Codex as you typed it, minus surrounding whitespace — which also means these four words are reserved: a model genuinely named sol on a custom provider cannot be selected by that name
  • follow-up rescue requests can continue the latest Codex task in the repo
  • --resume/--resume-last continues the newest thread for this repository; --resume-thread <id> continues one specific thread (the id is printed by /codex:status and /codex:result). --resume, --resume-thread, and --fresh are mutually exclusive.
  • --ephemeral runs without persisting the Codex thread: nothing is added to Codex's Recent list, and there is no thread to come back to. Useful for disposable, fire-and-forget work — many parallel subtasks from an orchestrating agent, say — where the persistent threads are only noise. It is refused together with --resume, --resume-last and --resume-thread, an ephemeral run is never offered as a --resume-last candidate, and /codex:status and /codex:result stop printing a codex resume line for it. Without the flag nothing changes: threads persist exactly as before.
  • --sandbox applies to /codex:rescue only; the review commands stay read-only. It takes precedence over --write and counts only before the task text. Rescue runs edit files inside the repository by default (workspace-write); read-only blocks edits, and danger-full-access disables the Codex sandbox entirely, so Codex can write outside the repository and use the network without asking. Reserve it for tasks the sandbox blocks.
  • a resumed thread keeps the sandbox it was started with while the plugin's shared app-server still holds it, which is the normal case inside one Claude Code session (Codex CLI 0.153.2 applies a new mode only when it loads the thread again from disk). task refuses a resume whose sandbox differs from what the app-server reports; resume with the same --sandbox, or start a new thread with --fresh.
  • each --read-root <directory> must name an existing directory and opts into an OS-enforced permission profile that denies local command reads outside the listed directories and Codex's minimal runtime paths
  • a scoped --write (or --sandbox workspace-write) requires the approved read roots to cover the workspace directory and uses Codex's built-in :workspace write policy; --read-root is rejected together with --sandbox danger-full-access
  • scoped reads require Codex 0.138.0 or later and fail closed when the runtime cannot enforce permission profiles
  • filesystem profiles apply to local sandboxed commands, not web search, MCP servers, connectors, browser tools, or computer use

/codex:transfer

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>.jsonl

The 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 live under a Claude projects root — ~/.claude/projects, or $CLAUDE_CONFIG_DIR/projects when you have relocated your Claude config — and older Codex versions that do not expose session import must be upgraded before using this command.

/codex:status

Shows running and recent Codex jobs for the current repository.

Examples:

/codex:status
/codex:status task-abc123

Use it to:

  • check progress on background work
  • see the latest completed job
  • confirm whether a task is still running

A job's status is reconciled against its worker process before it is reported, so a background run whose worker died is not shown as running forever:

  • worker gone, no Codex thread started → terminated-unknown
  • worker gone while a Codex turn may still be running → still active, with the phase worker-exited-turn-unknown

That second state is the one case the plugin cannot resolve on its own: the turn is server-side and the process that knew its id is gone. It clears when the turn's runtime does — see Background Runtime Limits.

/codex:result

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>.

A run that failed without crashing — a rejected model, an unsupported parameter — stores the error text too, so a failed job says why it failed rather than only that it did.

Examples:

/codex:result
/codex:result task-abc123

/codex:cancel

Cancels an active background Codex job: it records the cancellation, interrupts the Codex turn, and then kills the worker — in that order, so a crash midway never leaves an interrupted turn with no recorded outcome.

Examples:

/codex:cancel
/codex:cancel task-abc123

Notes:

  • a job that finished while you were typing is reported as already finished rather than failing the command
  • naming a job whose record went stale (its worker died mid-write) repairs the record and reports the real outcome
  • a cancel is refused when the worker exited after Codex accepted the turn but before it recorded the turn id: that turn may still be running and there is nothing to address it by, so reporting it cancelled would be a lie. The job stays active until its runtime goes.

/codex:setup

Checks 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.

Enabling review gate

/codex:setup --enable-review-gate
/codex:setup --disable-review-gate

When 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.

On the continuation turn that follows a block, the gate does not review again: Claude Code re-invokes the hook with stop_hook_active, and re-running the review there would just block again until the harness's retry cap ends the turn. The skip is reported as a system message, so run /codex:review --wait yourself when you want the fixes verified.

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.

Typical Flows

Review Before Shipping

/codex:review

Hand A Problem To Codex

/codex:rescue investigate why the build is failing in CI

Start Something Long-Running

/codex:adversarial-review --background
/codex:rescue --background investigate the flaky test

Then check in with:

/codex:status
/codex:result

Codex Integration

The Codex plugin wraps the Codex app server. It uses the global codex binary installed in your environment and applies the same configuration.

Common Configurations

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-5.4-mini 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-5.4-mini"
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.

Background Runtime Limits

Background tasks and reviews run through a shared, workspace-local broker process that outlives the Claude session that started it. A few environment variables bound how long different parts of that runtime are allowed to stay alive; all default to sensible values and accept 0 to disable the limit entirely.

Variable Default Purpose
CODEX_BROKER_IDLE_SHUTDOWN_MS 10 minutes How long the shared broker may sit with no connected client before shutting itself down.
CODEX_BROKER_PROCESS_SCAN_MS 10 seconds How often the broker re-reads its app-server's process tree, so that shutdown can still reach a child whose parent has already exited. 0 keeps only the readings at startup and at shutdown.
CODEX_BROKER_STARTUP_TIMEOUT_MS 5 minutes How long the broker may spend starting up (spawning its app-server and MCP servers) before it gives up and tears itself down.
CODEX_TASK_WORKER_TTL_MS 24 hours Ceiling on a detached background task's wall-clock lifetime — a runaway guard, not a task deadline.
CODEX_COMPANION_HEARTBEAT_INTERVAL_MS 15 seconds How often a running worker stamps its job record to say it is still there.
CODEX_COMPANION_HEARTBEAT_STALE_MS 10 minutes How long that stamp may go unrefreshed before the job counts as lost. Deliberately far larger than the interval: a loaded machine or a suspended laptop delays a stamp without the worker being gone.
CODEX_COMPANION_STALL_AFTER_MS 10 minutes How long a live run may produce nothing before /codex:status flags it as possibly stalled. Advisory only — the job is never failed on this.

Set any of these in the environment before starting Claude Code, for example:

export CODEX_BROKER_IDLE_SHUTDOWN_MS=1800000  # 30 minutes

CODEX_BROKER_IDLE_SHUTDOWN_MS does double duty: it also bounds how long a job whose worker died with a turn still possibly running keeps the runtime up (the worker-exited-turn-unknown state above). Session end leaves the broker alive for such a job instead of killing the turn under it; once that window passes, the next session end reclaims both. With the timer disabled (0), the fallback is 24 hours rather than forever.

When the broker shuts down — at session end, on its idle timer, or because its app-server died — it takes the app-server's process tree with it: its MCP servers, and anything a Codex turn started that is still running, a dev server left in the background included. What ignores SIGTERM for a second gets SIGKILL. A process remembered from an earlier reading is signalled only while the same pid still shows the same start time, so a pid the system has since given to something else is never touched; members of the broker's own process group need no such check, since only the broker can have created that group.

A daemon that a command started and that detached into a session of its own — a Gradle daemon, an ssh ControlPersist master, another workspace's broker started by a nested claude -p — is left running: it serves others from then on. Only a direct child of the app-server is reaped after detaching like that, since that is how an MCP server it started looks. Session ids are read on Linux only; elsewhere every process is treated as possibly detached, so only the app-server, its direct children and the broker's group are reaped. On Windows the existing taskkill /T teardown is all there is: there are no process groups to read, and children are not reparented.

These are advanced knobs for tuning resource usage in long-running or resource-constrained environments; most users will never need to touch them.

Where State Lives

What Where Notes
jobs, logs, broker record $CLAUDE_PLUGIN_DATA/state/<workspace>/, or a temp-dir fallback CLAUDE_PLUGIN_DATA is only set when the plugin runs as a hook, so both locations are real. Reads check both, writes go to the current one.
review-gate flag $CODEX_HOME/plugin-cc/config/<workspace>.json Durable on purpose: clearing the state dir, or a different CLAUDE_PLUGIN_DATA, must not silently turn the gate off. Written privately (0600) and atomically.
Codex threads and auth wherever your Codex CLI keeps them The plugin never holds a second copy — see the FAQ.

One broker serves every session in a workspace. It is shut down by the last session out, never by a session that still has another's work in flight, and it releases its Codex thread subscriptions as clients disconnect, so a departed session's notifications never reach the next one.

Skills The Plugin Carries

Three internal skills ship with the plugin. None is user-invocable: they are contracts the rescue subagent and the result presentation follow, and they are listed here because they decide how your request reaches Codex.

Skill What it governs
codex-cli-runtime The forwarding contract: the subagent's only job is to call task once and return its stdout unchanged. It also fixes what the subagent may not do — no setup, review, status, result or cancel, no reasoning through the problem itself.
gpt-6-prompting How a request is turned into a Codex brief: which model to pick (Luna for bulk and well-specified work, Sol for multi-file implementation and review, Astra for architecture or a second opinion), which reasoning effort, and per-model recipes for diagnosis, implementation, review, research and vision.
codex-result-handling How Codex's output comes back to you: its verdict, findings and file paths preserved as reported, findings ordered by severity, and the distinction between fact, inference and open question kept. It also forbids acting on a review by itself — after presenting findings Claude stops and asks which ones to fix, and a failed Codex run is reported rather than replaced by a Claude-side attempt.

Two notes on the prompting skill, since it is the one that changes what you get:

  • its launch lines use full model slugs (gpt-6-luna, gpt-6-sol, gpt-6-astra). Those slugs also have short aliases here (sol, luna, astra, plus spark → gpt-5.3-codex-spark), so either form works; every other --model value is forwarded to Codex verbatim
  • it advises staying at high effort or below. That is advice about cost, not a limit: --effort xhigh is accepted. max and ultra are not
  • a test reads this fork's own alias map and effort validator and checks every --model/--effort the skill names against them. The effort half is exact; the model half only catches a bare word that is not an alias, because the plugin keeps no list of valid models — a slug it does not know is forwarded and rejected by Codex, not by the plugin

Moving The Work Over To Codex

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.

Differences From Upstream

This fork is openai/codex-plugin-cc main plus a set of community pull requests that are still open upstream. Each one is a separate merge commit, so any of them can be reverted on its own.

Broker and background-job lifecycle:

Upstream PR What it fixes
#541 broker leaks, state races, and signal-masked command failures in the test runtime
#623 session end no longer tears down the shared broker while another session's jobs are still using it
#652 bounds the lifetime of detached brokers and task workers (see Background Runtime Limits)
#659 state written under one CLAUDE_PLUGIN_DATA root is no longer invisible to an invocation that resolves to another, which orphaned brokers and hid jobs
#707 the broker releases its app-server thread subscriptions when a client disconnects, instead of leaking them for its whole lifetime
#728 a job whose worker died no longer reads as "running" forever; /codex:status reconciles the record against the live process
#725 nothing is spawned through the user's shell on Windows, where MSYS path conversion mangled switches like taskkill /PID and left background workers unkillable under Git Bash (this supersedes #735)
#656 /codex:cancel exits non-zero when neither the turn interrupt nor the worker kill confirmed the job stopped, instead of reporting a cancellation nothing proved
#770 npm run build works on Windows: npm runs scripts through cmd.exe, where mkdir -p made a stray -p directory and then failed every build after the first
#775 a fileChange start event without its change list no longer throws and aborts the turn
#772 the stop-review gate keeps a minute of headroom under the Stop hook's budget, so a timed-out review can still say so instead of ending the turn silently
#774 status --wait prints its timeout and exits non-zero, instead of looking like a finished status check
#773 a broker connect that never completes is given up on after 2s and falls back to a direct app-server (the probe half of that PR is not taken: ours already bounds each attempt and reports why it failed)
#776 Windows teardown decides on the root's liveness instead of taskkill's message: a process already gone costs no taskkill at all, and a taskkill that reports failure only because a short-lived descendant exited mid-walk no longer throws at the caller (its broker-endpoint and shutdown-timeout changes are not taken — one is a no-op here, the other is behind what this fork already does)
#779 --ephemeral on task, so a disposable run does not leave a persistent Codex thread behind (extended here to refuse this fork's --resume-thread as well)
#787 a graceful teardown reaches a process that is alive but does not lead its own process group: process.kill(-pid) reports ESRCH for it too, and that was read as "nothing to kill", so such a process only ever met the later force kill
#800 shortening a thread name or job summary no longer cuts a surrogate pair in half, which left a lone surrogate in the JSON and made the app-server drop the request
#809 a turn whose turn/start response carries no turn id still completes: notifications were held until an id turned up, so every later one, turn/completed included, sat in the buffer and the run never finished
#817 the review context keeps the first column of git status --short (an unstaged change lost its leading space) and non-ASCII file names: with git's default core.quotePath, an untracked café.js was listed under a quoted name that does not exist on disk and left out of the review
#831 a /codex:status table cell that already holds \| no longer splits the row: the backslashes in front of a pipe are doubled before the pipe is escaped

Commands and flags:

Upstream PR What it adds
#565 the stop-review gate honors stop_hook_active instead of re-blocking a continuation turn
#724 --read-root <directory> for OS-enforced scoped reads
#727 --resume-thread <id> to continue one specific Codex thread
#729 /codex:transfer works with a relocated CLAUDE_CONFIG_DIR
#742 --sandbox <mode> on task and /codex:rescue
#746 --model/--effort on the review commands, and a warning for unrecognised options
#748 CLAUDE_ENV_FILE skips re-exporting an unchanged value (its rewrite-the-file mechanism is not used: the file is shared with other plugins' hooks, so this fork only ever appends to it)
#731 the review-gate flag is persisted outside the transient state dir, so a different CLAUDE_PLUGIN_DATA no longer silently disables it
#792 a delegated thread is named after the <task> block of a structured prompt, instead of after the instructions that precede it — every thread shaped by the prompting skill used to read Codex Companion Task: <task> …
#737 hooks resolve Node through scripts/run-node.sh, so nvm/fnm/asdf/mise/Volta/Homebrew toolchains work under the minimal hook PATH
#747 runCommand sets an explicit 256 MiB maxBuffer, so a large git diff is no longer truncated at Node's 1 MiB default
#763 a turn that fails without throwing stores its error text, so /codex:result says why it failed
#799 the review commands forbid reading or waiting for the background command's output, instead of naming one tool (BashOutput) that was only one way to do it; the result-handling skill's stop rule keeps its substance and loses the shouting
#808 tests only: inline --key=value keeps every = after the first. The parser already split there, so only the tests are taken; one is adapted, since this fork rejects a boolean value other than true/false where upstream reads --flag=false=extra as true
#811 scripts/bump-version.mjs --help lists the -h alias it already accepted
#816 a slash command's raw arguments keep apostrophes and backslashes: fix the user's bug --background no longer swallows --background into the prompt, and C:\Users\x or \d+ keep their backslashes (its --key=value half was already here)

Where two of these PRs disagreed, the merge commit says which side won and why. The plugin version is deliberately left at the upstream number: these merges do not cut a release.

Beyond the imports, this fork carries fixes for defects the imports themselves surfaced:

  • a busy broker refusing shutdown is reported as a refusal, not an identity rejection, so SessionEnd leaves a shared runtime to the sessions still using it instead of exiting with an error
  • scripts/run-node.sh prefers a user-managed toolchain over a system install, which #737 had inverted (see the note under Requirements)
  • the durable review-gate config is written privately and atomically, so an interrupted write cannot silently disable the gate
  • --read-root works on a resumed thread: the scoped run sends a permission profile rather than a sandbox mode, so asserting the mode had refused every scoped resume — and its advice dropped the write grant. A scoped run on a thread started with the sandbox disabled is still refused
  • cancelling refuses before taking the job's terminal claim, so a refused cancel leaves nothing behind for the next one to turn into a bogus cancelled record
  • a job retained because its turn may still be running keeps the runtime up, stays readable in /codex:status, and expires on a bounded window instead of pinning the broker
  • the state a job is deleted from is the state its files are deleted from, so a prune another process is holding can no longer leave a record without its log and detail file
  • disabling the review gate is not outvoted by a stale enable left under another plugin-data root
  • CLAUDE_ENV_FILE is only ever appended to: it is shared with other plugins' hooks, and rewriting it dropped whatever they had just written
  • teardown never force-kills through a negative pid: a process group is POSIX-only, so on Windows that was an invalid handle and the fallback killed the worker alone, leaving its app-server — and every MCP server under it — running. taskkill /T /F walks the tree there instead
  • a state write that Windows briefly refuses — a scanner or indexer holding the file open, which surfaces as EPERM/EBUSY on the replacing rename — is retried instead of losing the record
  • a live broker that is refusing connections — a full accept backlog, or a Windows named pipe with no free instance — is given a longer window to start accepting again and reused if it does, instead of being replaced by a second broker with its own app-server and MCP servers. A broker that is simply gone still costs nothing: only the probe outcomes that mean "listening, but not right now" buy that wait (#768 raises the duplicate-broker problem upstream; its own two fixes — never tearing down a live broker, and serializing the check-then-create window — were already here, and its blanket 3s probe is not taken, since it would charge every gone broker for the rare busy one)
  • the broker notices when its own app-server dies: it tells every connected client why, closes its endpoint so the next command starts a fresh runtime, and exits — instead of accepting connections in front of a dead backend, where a streaming turn waits forever and every later command hangs (adapted from #797)
  • a write that can no longer reach the runtime fails its request instead of leaving it pending with nothing left to reject it, and an EPIPE on a dead child's stdin no longer takes the whole companion down (adapted from #797)
  • that broker notice is sent only when the app-server exited reporting something. An app-server can exit cleanly right after delivering a final answer, and a run whose answer already arrived completes precisely because the close carried nothing to report — inventing a reason there would fail finished work
  • a worker that is stopped (a Bash timeout, a session ending), crashes, or drains its event loop with the turn unsettled records the failure itself, with the reason, instead of leaving running behind for reconciliation to repair later and without an explanation. A cancellation still wins the terminal status (adapted from #797)
  • a running worker refreshes a heartbeat, so a record whose worker died can no longer read as healthy because the system reused its pid; and a live run that has produced nothing for a while is flagged in /codex:status as possibly stalled — never failed on that alone (adapted from #797; see Background Runtime Limits)
  • the broker takes its app-server's process tree down when it shuts down. Before, a child of the app-server — an MCP server, a command left running — survived every shutdown: closing the app-server does not stop its children, one in a process group of its own is out of reach of a group signal, and one whose parent already exited is reparented where nothing leads to it. The survivors also kept the dead broker's process group alive, so the session-end hook failed with "ownership changed before forced shutdown". The tree is remembered by pid and start time while it is intact, and reaped with a SIGKILL for what outlasts a one-second grace (adapted from #814)
  • an app-server that ignores both the close and SIGTERM no longer outlives its broker: the SIGKILL meant for it waited on a timer, and every caller of the broker's shutdown exits as soon as it returns, so that timer never fired. The session-end hook still reports such a broker as not exited — it stops waiting before the broker's five-second close grace runs out — but the tree is gone a second after that
  • the app-server typecheck (npm run build) passes

Each of those came out of an adversarial review of the merges, re-run after every round of fixes; the reasoning behind each is in its commit message, and each has a regression test that fails without it.

Not imported: #733 (durable startup cancellation) — its behavior is already covered here by the terminal-claim mechanism, and its marker files would add a second source of truth for the same decision. #761 (max/ultra reasoning efforts) — the same proposal was closed upstream as #648. #797 (never lose track of jobs whose worker died, hung, or lost its runtime) — the goals are shared, the design is not: it runs every command through a detached worker that the Claude-side process only attaches to, which replaces this fork's terminal claims, worker TTL and record-first cancellation (50 conflicting hunks, most of them rewrite against rewrite). Its state locking, atomic writes and reconcile-before-read are already here from earlier work. The four mechanisms this fork genuinely lacked were adapted instead, listed above; its --wait-timeout-ms and "still running" notice are not portable without that execution model, because here a foreground command is the run — --background plus status --wait is the equivalent today. #802 (tear down brokers leaked by the tests) — this fork already does it, from #541, and in tests/helpers.mjs rather than in one test file, so every test that makes a temp directory is covered; ours also only tears down sessions carrying our own instance token and reports a teardown that failed instead of swallowing it. #814 (clean up idle app-server process trees) — its process-tree cleanup is adapted above; its own idle timer is not taken, since this fork's broker already shuts itself down when idle and that timer would be a second one, with its own notion of idle read from the job index.

FAQ

Do I need a separate Codex account for this plugin?

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.

Does the plugin use a separate Codex runtime?

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

Will it use the same Codex config I already have?

Yes. If you already use Codex, the plugin picks up the same configuration.

Can I keep using my current API key or base URL setup?

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.

About

Use Codex from Claude Code to review code or delegate tasks.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages