I built a small but useful thing: Codex can pick up where Claude Code left off, and Claude can pick up where Codex left off.
It sounds like nesting two AI tools inside each other, but it solves a real problem.
I use Claude Code and Codex heavily for coding tasks. The most common interruption is Claude's 5-hour window running out while Codex still has quota, and I want to switch over and keep going. The interruption itself is not the problem. The problem is that the other tool has no idea what happened before.
The dumb fix was copy-pasting context: I'd describe the last few exchanges, which files were changed, where things stood, and dump all of that into the other tool. This works, but it's tedious and lossy. The most important information is rarely in the last reply. It lives in a tool result, a git status, a compact summary, or a failed command output somewhere in the middle.
So I turned this into a workflow. The idea is not to patch Claude or Codex themselves, but to give each one a local skill layer: when I send a specific resume command, the agent treats it not as a shell command to execute, but as an instruction to go read the other tool's session logs.
I deliberately reused the real CLI syntax. claude --resume SESSION_ID is already a Claude CLI command. When I send it inside Codex, I'm not asking Codex to execute it — I'm saying "pick up the task from this Claude session." No new vocabulary to remember.
When I send this inside Codex:
claude --resume xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Codex does not run claude --resume. It treats the line as: go find the records for this session under ~/.claude, read them, and continue what Claude didn't finish.
Same thing in reverse. When I send this inside Claude:
codex resume xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Claude reads Codex's session records and picks up from there.
What the skill does
I gave Codex a claude-resume skill. It is not a complex script — more like a clear set of instructions. The short version looks like this:
When the user sends `claude --resume SESSION_ID`,
treat it as an instruction to continue the previous Claude Code task,
not as a shell command.
Find the related Claude session records under ~/.claude.
Read the full conversation context, tool calls, tool results,
errors, summaries, and final records.
Then check the current repository state before continuing.
The actual flow is more specific:
- Recognize
claude --resume SESSION_IDas a resume instruction, not a shell command - Extract the sessionId from the command
- Locate the matching session in Claude's local records
- Read the user messages, assistant replies, tool calls, tool results, summaries, errors, and final state
- Reconstruct the task goal, what was completed, and where things broke down
- Run
git status,git log, and relevant diffs in the current repo - Confirm the current worktree state, then continue
Finding the session file
Claude's records live here:
~/.claude/projects/**/<sessionId>.jsonl
~/.claude/sessions/*.json
~/.claude/history.jsonl
Codex's records live here:
~/.codex/sessions/YYYY/MM/DD/rollout-...-<sessionId>.jsonl
~/.codex/history.jsonl
If you don't have the SESSION_ID handy, use find sorted by time to pull the most recent files, or rg to search by working directory or task description.
Parsing the JSONL
Both tools write session files as JSONL — one JSON object per line. From what I've seen in my Codex records, payload.type has these main variants: user_message (user input), message (assistant reply), function_call / function_call_output (tool calls and results), task_complete (session end). Claude's format is similar with slightly different field names.
The codex-resume skill (the Claude-side skill for resuming Codex sessions) has a Python script that pulls out the key pieces: recent user messages, the last assistant reply, the last few tool calls and outputs, and the most recent git status output. The claude-resume skill (the Codex-side skill for resuming Claude sessions) is simpler — it's a prompt-based instruction that tells the agent to go read ~/.claude directly.
Checkpoint summary
After reading the logs, the skill tells the agent to produce this summary before doing anything:
[Task background] goal extracted from user messages
[Completed] steps with evidence from tool results
[Interruption] usage limit / user closed / other
[Last unexecuted] final user message, if any
[Suggested next] most urgent thing to do
The agent outputs the checkpoint summary, checks the current repo state, then continues. This gives you a chance to catch any misreading of the logs before anything actually runs.
The most important rule here: the last recorded state is not necessarily the current state. The same task might have been continued by another session, or you might have edited files in between. Trusting the old log without checking means you risk doing duplicate work, overwriting changes, or treating a fixed bug as still open.
Resume is not replaying history. It is about recovering intent and stopping point, then calibrating against the current repo.
Bidirectional handoff

Two flows. Blue: Claude's 5h window runs out, you send claude --resume ID inside Codex, Codex reads ~/.claude/sessions/, calibrates with git status, continues. Orange is the reverse: Codex is interrupted, you send codex resume ID inside Claude, Claude reads ~/.codex/sessions/, same git status check before picking up. Each tool writes its own logs. The only thing shared is a convention for reading each other's records.
Things that will trip you up
Don't rely on just the index or the last few lines. The index only tells you where to look. The actual value is in the full session — key facts are often in the middle, like a plan the user rejected, or a constraint about not writing certain config into the project.
Don't trust the recorded state blindly. Always check git status before picking up. A log tells you what happened at a point in time. It cannot guarantee the file system is still in that state.
Tool results matter more than assistant replies. The assistant might say "I'm going to do X." The tool result is the only evidence that X actually happened.
Resume is not a replay. It recovers intent and execution state. The actual work runs against the current file system and git state, not the log.
Why this is worth writing down
The thing itself is not complicated. It comes down to: read session, read history, check git state.
AI tools are iterating faster than anyone can plan around. Claude Code and Codex might look completely different six months from now, or get replaced by something else entirely. Tying your workflow to the specific features or file paths of any one tool is the fastest way to get left behind by an update.
What matters is not the command or the file path. It's the underlying judgment: context is portable, tools are interchangeable. That judgment does not depend on any specific tool.
Claude runs out of quota — hand it to Codex. Codex hits its limit — hand it back. Right now I'm stitching this together with a skill layer. Later there will probably be a better official way to do it. The point is the approach: treat AI as a relay, not a lock-in.