Skip to content

Claude ↔ Codex Bridge

Claude ↔ Codex Bridge moves an active coding conversation from Claude Code into Codex, or from Codex back into Claude Code, keeping the same project directory or Git worktree. What you land in is a real claude --resume <id> session or a Codex thread you can keep typing into. The source session is left as it was. It is for people who run both CLIs on the same repository and want to change agent mid task without pasting a summary.

  • Hidden thinking and reasoning, permission state, background processes, and ephemeral tool state are not transferable.
  • Codex encrypted compaction summaries cannot be decrypted. Raw visible history is kept with a compaction boundary, so context living only inside that summary is lost.
  • Environment, system, and developer injections are dropped, because the destination recreates its own environment. Claude sidechains are not copied.
  • No Git operation is performed for you: no commit, reset, stash, checkout, or worktree creation. The source session is never rewritten.
  • Redaction of probable tokens, credentials, private keys, signed URLs, and secret assignments is best effort. It is not a DLP guarantee. Do not transfer a transcript holding secrets you could not copy by hand.
  • Compact tool mode omits results and clips calls; full mode can expose more sensitive output. Neither recreates a running tool process.
  • Automatic opening is implemented for macOS. Elsewhere, use --no-open and run the printed resume command.
  • The process lock is machine local. On a cloud synced project, do not use two computers as simultaneous writers.
  • It does not replace OpenAI’s codex-plugin-cc, which covers the one way Claude to Codex case. This project adds the reverse direction, lineage, and capsule fallback.

Requirements: Python 3.10 or newer, Claude Code, and Codex. Git is optional.

Terminal window
git clone https://github.com/nerln/claude-codex-bridge.git
cd claude-codex-bridge
./bin/agent-switch install --hooks "/path/to/project"
./bin/agent-switch doctor --project "/path/to/project"

The installer links the skill into .agents/skills/switch-agent and .claude/skills/switch-agent, creates private state under .agent-bridge/, and adds hook handlers without deleting existing ones. There is intentionally no destructive uninstall; the README lists the manual steps.

Optional global command:

Terminal window
mkdir -p "$HOME/.local/bin"
ln -s "/path/to/Claude-Codex-Bridge/bin/agent-switch" "$HOME/.local/bin/agent-switch"

The shortest form infers the source side:

Terminal window
agent-switch to codex --task feature-auth --project "/path/to/project"
agent-switch to claude --task feature-auth --project "/path/to/project"

Both directions, stated explicitly:

Terminal window
agent-switch switch --from claude --to codex \
--task feature-auth --project "/path/to/project"
agent-switch switch --from codex --to claude \
--task feature-auth --project "/path/to/project"

--task names a chat lane and defaults to main. Give unrelated chats in the same repository distinct task names, and list them with agent-switch status. From inside the agents, /switch-agent codex and $switch-agent claude do the same thing.

Finish or interrupt the current model turn first, so the source JSONL is stable. For the first transfer in a lane, or when several chats share a working directory, pass --source-session <uuid>. --dry-run shows the plan without writing or opening anything.

Under --transcript auto, the default, the tool resolves the source session from the flag, the task ledger, hook state, or the most recent valid session in the same cwd. It validates the source JSONL structure, session identity, working directory, and CLI version, maps visible turns into a neutral representation, masks and counts probable secrets, compacts tool activity, appends a capsule holding the verified Git and filesystem snapshot, then creates a private native target session, records its lineage, and opens it.

required stops rather than falling back to a capsule only session; off sends the capsule alone. Tool calls default to --tools compact --tool-chars 600, with drop for the smallest transfer and full when you need outputs. Every mode honors --max-chars, 120,000 by default, keeping head and tail with an omission marker. A private .agent-bridge/continuity.json ledger per project holds session IDs and lineage per task, so repeating a switch reuses the planned target instead of duplicating history. If the source changes during publication, the target stays closed and is marked orphaned.

Verified end to end on macOS on 2026-08-01 across Claude Code 2.1.219, which wrote the source transcripts, and 2.1.220, which resumed the transferred session, with Codex 0.146.0-alpha.9.2. Claude to Codex to Claude preserved facts introduced on both sides, the Codex rollout became visible from the deep link alone without a bootstrap turn, and both files the bridge wrote were still 0600 after native resume. That 0600 covers only what the bridge writes: when Codex resumes one of those targets it forks a new rollout under its own umask, world readable on macOS, holding the same conversation. Protect the target directory, not just the target file.

A separate 8.1 MB real world transcript round trip retained facts buried in the middle while cutting the visible transfer to about 64,000 characters.

tools/verify-drift.py is the compatibility canary. It mints unpredictable markers, creates a real Claude session, performs the native round trip, asks both agents to list the markers back without reading any file, and exits non-zero on loss.

Terminal window
python3 tools/verify-drift.py --json

The no-reading restriction is only an instruction in the prompt. No sandbox enforces it: Codex runs under --sandbox read-only, which still permits reads, and Claude runs with no tool restriction. A returned marker shows the round trip carried it into context, assuming the agent obeyed. The probe costs two Claude calls and one Codex call. It is a release and upgrade gate, and it is not meant for every commit.

Supported source format prefixes are currently Claude Code 2.1.* and Codex 0.146.*. An unsupported source falls back in auto and blocks in required; an unsupported target always blocks. Run doctor after every upgrade.