The Bridge · 10 min mission
Claude From Codex: The Reverse Bridge
Delegate review and rescue to Claude Code from inside Codex — and keep a failover path.
On this page
- Why run the bridge in reverse
- The seven $cc: commands
- How it actually runs: a native Codex plugin hook
- Install and the config prerequisites
- The model aliases: 1M-context Claude, by short name
- The rescue subagent and its flags
- Senior scenario: rescue an architectural refactor at full power
- Resilience pattern: try Codex, fail over to Claude
- The shape to build toward
You live in Codex. That is your home thread, your harness, your muscle memory. But the moment you finish a change, the same problem bites that bites everyone running a single agent: the model that wrote the code is the worst reviewer of it. Same weights, same blind spots, same context that already talked itself into every decision. You want a different model — Claude — to read the diff cold and tell you what Codex missed. Historically that meant opening a second terminal, starting Claude Code by hand, re-pasting the diff, and couriering findings back.
cc-plugin-codex deletes that errand. It runs inside Codex and gives you a handful of $cc: commands that launch tracked Claude Code work — review, rescue, background jobs — and surface the results back into your Codex thread [V]. The README states the division of labor exactly: "Codex stays in charge of the thread. Claude Code does the review and rescue work." [V] You never leave Codex; a second model on a second budget shows up when you call it.
Why run the bridge in reverse
Three wins, none available from one agent talking to itself:
A second model reviewing the author's work. Codex is GPT-family; Claude is Claude. They fail differently. A cross-model review catches the bug your author-model rationalized past.
A second context window. Each $cc: job runs Claude with its own fresh read of the repo — Claude maps the models to their 1M-context variants [V], so even a large diff or a wide blast radius fits. It judges the change on its merits, not on the story Codex told itself getting there.
An off-thread investigation. A --background rescue runs through a Codex-managed subagent while you keep working in Codex; you poll its status and pull the result when it lands [V], instead of blocking your main thread on a long dead-end hunt.
The seven $cc: commands
The plugin ships exactly seven commands, all prefixed $cc: [V]. Three do work (review, adversarial-review, rescue); three manage jobs (status, result, cancel); one is setup. This is the mirror image of the forward bridge's /codex:* set — here the dollar-prefixed verbs run inside Codex and the work runs in Claude.
| Command | What it does [V] |
|---|---|
$cc:review | A read-only Claude Code review of your changes. Defaults to opus + xhigh effort. Reads, judges, reports — it does not edit. |
$cc:adversarial-review | Design-challenging review — questions the approach, tradeoffs, and hidden assumptions. Reach for it on riskier config / template / migration / design changes. |
$cc:rescue | Hand a task to Claude Code — bugs, fixes, investigations, follow-ups. The workhorse, with the richest flag set (next section). Can change code. |
$cc:status | List running and recent Claude Code jobs, or inspect one job. Your dashboard for anything launched --background. |
$cc:result | Open the output of a finished job, pulled back into the Codex thread. |
$cc:cancel | Cancel an active background job (and stop the spend). |
$cc:setup | Verify installation, auth, hooks, and the review gate — and auto-repair the hook trust (covered below). |
How it actually runs: a native Codex plugin hook
A tempting wrong model is that the plugin shells out to claude over raw bash and scrapes stdout. It does not. cc-plugin-codex uses Codex native plugin hooks [V]. The active plugin copy lives under Codex's plugin cache, and its hook commands resolve through the $PLUGIN_ROOT variable — "there is no separate local checkout install" [V]. That is why a marketplace install just works, and why $cc:setup (below) exists to bless the cache copy.
When a $cc: command fires, the plugin spawns a fresh claude -p subprocess per invocation [V] — claude -p is Claude Code's non-interactive "print" mode, so each job is a clean, headless Claude run with no leftover state. Background flows go one level further: instead of stuffing --background into the companion command, they run through a Codex built-in subagent — "Codex-managed subagent turns" — and the job stays attached to your parent Codex session for status, result, and resume [V].
The split is worth holding in your head: Codex orchestrates (it owns the thread, the job tracking, the nudges), and Claude executes (a fresh claude -p per job, in its own context, returning only a result).
Two layers of execution
Foreground job
$cc:review with no --background:
- Plugin spawns a fresh
claude -psubprocess [V] - Claude reads the diff in its own context
- Result returns directly into your Codex thread
- Synchronous — you wait, then read
Background job
$cc:rescue --background …:
- Runs through a Codex built-in subagent (subagent turns) [V]
- Job is tracked, attached to your parent Codex session
- You keep working; Codex nudges you with the exact
$cc:result <job-id>when done [V] $cc:status/$cc:resultare the durable backstop
Install and the config prerequisites
The plugin rides on Codex native plugin hooks, which sit behind two feature gates in your Codex config. Both must be on [V]:
# ~/.codex/config.toml
[features]
hooks = true
plugin_hooks = trueYou rarely set these by hand, because $cc:setup is the repair path [V]: it confirms [features].hooks = true and [features].plugin_hooks = true, then trusts the plugin's current native hook hashes so Codex loads the bundled hooks from the active plugin cache [V]. In plain terms: Codex won't run a plugin's hooks unless their hashes are trusted, and re-running $cc:setup after any update re-blesses the new hashes for you. It is idempotent — safe to re-run for updates [V].
The prerequisite that's easy to forget: this drives a local Claude Code CLI, so Claude itself must be installed and authenticated.
Install from inside Codex
Make sure Claude Code is present and logged in
Run
npm install -g @anthropic-ai/claude-code && claude auth loginonce on your machine [V]. If Claude Code is missing when you run setup,$cc:setupoffers to install it for you [V].Install `cc` from the Sendbird marketplace inside Codex
Add the Sendbird marketplace in Codex and install the plugin named
cc[V]. The optional helpernpx cc-plugin-codex installruns the same marketplace/cache install path and enables the required Codex feature gates for you — and it is idempotent, so it doubles as the updater [V].Run `$cc:setup` once
$cc:setupchecks Claude Code availability, the native plugin hook feature gates, and review-gate state, then trusts the plugin's hook hashes [V]. "All checks should pass. If any fail,$cc:setuptells you what to fix." [V]
The model aliases: 1M-context Claude, by short name
You pick which Claude does the work with --model, using short aliases that resolve to the 1M-context variants [V]:
opus→claude-opus-4-7[1m]— the heavy reviewer, 1M context. Default effortxhigh.sonnet→claude-sonnet-4-6[1m]— faster, still 1M context. Default effort drops tohigh.haiku→claude-haiku-4-5— quick triage. No effort setting.
You can also pass a full model ID directly. Effort is the second dial — --effort takes low, medium, high, xhigh, max [V] — and the default tracks the model (xhigh for opus, high for sonnet, unset for haiku). So a bare $cc:review is, in full, opus at xhigh against a 1M-context window — a genuinely heavyweight read of your diff for one command.
| `--model` | Resolves to | 1M context | Default `--effort` |
|---|---|---|---|
opus | claude-opus-4-7[1m] | Yes | xhigh |
sonnet | claude-sonnet-4-6[1m] | Yes | high |
haiku | claude-haiku-4-5 | No | *(unset)* |
| *full ID* | whatever you pass verbatim | — | per your flag |
The rescue subagent and its flags
$cc:rescue is "the main way to delegate real work — bug fixes, investigations, refactors" [V]. It can change code; the read-only review commands cannot. You aim it with flags along two axes: blocking vs. concurrent, and continue vs. start-clean.
# Investigate, no edits implied by the verb — Claude reads and reasons
$cc:rescue investigate why the tests started failing
# Explicit fix — Claude is allowed to edit (--write is the default)
$cc:rescue fix the failing test with the smallest safe patch
# Continue the most recent Claude task (keep its context) ...
$cc:rescue --resume apply the top fix from the last run
# ... or force a clean run
$cc:rescue --fresh re-investigate from scratch
# Fire-and-keep-working, on a chosen model + effort
$cc:rescue --background --model sonnet --effort medium investigate the flaky testOne sharp, friendly default to know: if you pass neither --resume nor --fresh, rescue checks for a resumable Claude session and asks once whether to continue or start fresh — "your phrasing guides the recommendation" (say "continue the last run" → resume; "start over" → fresh) [V].
| Flag | Effect [V] |
|---|---|
--background | Run concurrently via a Codex built-in subagent; track with $cc:status, retrieve with $cc:result, kill with $cc:cancel. |
--wait | Run synchronously — block until the job completes, then surface the result inline. |
--resume | Continue the most recent Claude Code task, keeping its accumulated context. |
--resume-last | Alias for --resume. |
--fresh | Force a new task — do not resume. |
--write | Allow file edits. This is the default for rescue (it is the command that *changes* code). |
--model <model> | opus / sonnet / haiku (→ 1M-context variants) or a full model ID. Default opus. |
--effort <level> | low · medium · high · xhigh · max. Default xhigh for opus, high for sonnet. |
--base <ref> · --scope <auto\|working-tree\|branch> | Review/scope controls: --base sets the diff base; --scope auto (default) inspects git status and picks working-tree vs. branch. |
Senior scenario: rescue an architectural refactor at full power
You are in Codex mid-way through an architectural refactor — collapsing three overlapping service layers into one, touching ~40 files. Codex has the plan but keeps tripping on a circular-import knot it introduced, and it is the kind of structural problem where you want the heaviest possible second model with the most reasoning budget, reading the whole blast radius at once.
So you hand it to Claude Opus on a 1M-context window at maximum effort, let it run, and then continue the same Claude session to apply its own recommendation — no re-explaining, because --resume keeps Claude's context from the investigation [V].
# Heaviest reviewer, max reasoning, fresh read of the full refactor
$cc:rescue --model opus --effort xhigh untangle the circular import the
service-layer collapse introduced and propose the minimal structural fix
# ... read Claude's analysis, agree with the plan, then continue THAT session
$cc:rescue --resume apply the structural fix you proposed, smallest safe diffThe first call is opus → claude-opus-4-7[1m] at xhigh [V] — Claude reads all 40 files in one context and reasons about the cycle instead of guessing from a snippet. The second call resumes that exact Claude task [V], so it already knows the diagnosis and just executes it. Two commands, one continuous Claude thread, and Codex never lost the wheel.
Resilience pattern: try Codex, fail over to Claude
Now a [P] practitioner pattern, not a shipped feature — it's a thin wrapper you build on top of the [V] commands above. The idea: keep working in Codex, but if a task stalls or fails, automatically hand it to Claude through the bridge instead of giving up.
The shape is a small shell wrapper around your task runner. Try it in Codex's own flow; on a non-zero exit (or a stall you detect), fall back to a $cc:rescue so a different model takes a swing:
# [P] failover wrapper — NOT a plugin feature. Pseudocode you'd wire into
# your own runner; $cc:rescue is the only [V] piece here.
run_task() {
if codex_attempt "$1"; then
echo "Codex handled it."
else
echo "Codex stalled — failing over to Claude via the bridge."
# delegate the SAME task to Claude, heavy model, allowed to fix
cc_rescue --fresh --model opus --effort high --write "$1"
fi
}Why --fresh here: a failover should not inherit Codex's stuck reasoning — you want Claude reading the problem cold [P]. Why --write: a rescue that can't edit can only diagnose; for an autofix path you want it allowed to patch [V]. Treat the wrapper as scaffolding around the one real command ($cc:rescue); the bridge does the work, your script just decides when to pull it.
Try the reverse handoff
Cross-tool terminal simulator
Two terminals, one handoff. Flip who calls whom, pick a command, and press Run handoff to watch the caller delegate to the other tool and get a result back.
Hands the working diff to Codex for an independent review pass.
idle — run a handoff
idle — run a handoff
Knowledge check
From inside Codex, you hand a hard refactor to Claude with $cc:rescue --model opus --effort xhigh, read its diagnosis, and now want Claude to apply that exact plan without re-explaining anything. What do you run?
The shape to build toward
Install once from the Sendbird marketplace, run $cc:setup to trust the hooks, and confirm Claude is logged in via claude auth login [V]. Then reach by intent: $cc:review before you commit, $cc:adversarial-review when you want Codex's assumptions attacked, and $cc:rescue --background when a hard investigation should run off to the side while you keep moving in Codex. Pin --model opus --effort xhigh for the problems that deserve a 1M-context heavyweight, and --resume to let one Claude session both diagnose and fix. Wrap a [P] failover around $cc:rescue if you want automatic try-Codex-then-Claude resilience — but keep the [V] command at its core and don't mistake the wrapper, or any "migrate" one-liner, for a shipped feature. Two models, two contexts, two budgets — one Codex thread.
Reach the end and this star joins your charted sky.