Asia/Shanghai
August 10, 2026

Hand Off a Claude Code Session to Codex Without Starting Over

Claude Code 做到一半,怎样无缝交给 Codex 继续

Mingjian Shao
Hand Off a Claude Code Session to Codex Without Starting Over
I started this article in Claude Code and finished it in Codex. The handoff worked — but the one awkward error is exactly what ordinary users need explained.
OpenAI's official Codex plugin for Claude Code adds a small bridge between the two tools. You can work in Claude Code, then import the current conversation into a resumable Codex thread with visible turn history.This is useful when:
  • Claude has gathered the context, but you want Codex to implement or review;
  • you want a second model to continue the same task instead of writing a fresh handoff brief;
  • you want Codex's desktop experience without losing the decisions already made in Claude Code.
It is not model switching inside one app. It creates a Codex thread from the Claude transcript and returns a session ID you can resume later.Run these slash commands inside Claude Code:
Text
/plugin marketplace add openai/codex-plugin-cc
/plugin install codex@openai-codex
/reload-plugins
/codex:setup
/codex:setup checks Node, npm, the Codex CLI, and Codex authentication. If Codex is missing, the setup flow can install it with npm after asking you first. If authentication is missing, run:
Bash
codex login
The optional review gate makes Claude request a fresh Codex review before it stops after reviewable work:
Text
/codex:setup --enable-review-gate
You do not need the review gate to transfer sessions. Leave it off if you only want handoff.Once setup reports ready: true, run:
Text
/codex:transfer
When auto-detection works, the plugin imports the current transcript and returns something like:
Text
Transferred the Claude session into a Codex thread with visible turn history.
Codex session ID: <session-id>
Resume in Codex: codex resume <session-id>
Keep the session ID. It is your way back into that Codex thread.Transfer creates the Codex thread, but it does not automatically move you into the Desktop app. First resume the thread in Codex CLI:
Bash
codex resume <session-id>
Then run this inside the Codex CLI session:
Text
/app
The Desktop app opens the same thread. At this point you may see:
Text
This is open in another app
Close it there to continue here.
This message is not a failed transfer. The CLI is still open and still owns the live thread, so the Desktop app refuses to write to it at the same time.The handoff has five steps:
Text
Transfer → Resume → /app → Exit CLI → Retry
Go back to the terminal and exit Codex CLI. Then return to Codex Desktop and click Retry. The visible history should load and the Desktop app becomes the active owner of the thread.This last step is easy to miss because /app launches the GUI but does not close the CLI that launched it.My first transfer did not work. I got this:
Text
Could not identify the current Claude transcript.
Retry with --source <path-to-claude-jsonl>.
The documented fallback is technically correct:
Text
/codex:transfer --source ~/.claude/projects/-Users-me-repo/<session-id>.jsonl
But it is not a natural instruction for a normal user. Claude Code encodes the working directory into a folder name, and the filename is a session UUID. Most people should not have to understand or manually assemble either one.Tell Claude Code:
Text
Find the JSONL transcript for this current Claude Code session under
~/.claude/projects. Do not guess the session ID. Scan it for likely raw
secrets without printing their values. If it is safe, give me one exact,
copy-pasteable command:
/codex:transfer --source <absolute-path-to-current-jsonl>
Claude can inspect the live environment, identify the current transcript, and return the literal command. You paste that command once. Do not copy the error message itself into /codex:transfer — it becomes a malformed argument and fails again.This is the most important usability lesson from the whole setup: the fallback path is for the model to resolve, not for the user to construct.The plugin imports the Claude JSONL transcript. It does not create a carefully edited summary first. If a tool call or pasted config exposed an API key in the transcript, that value can travel with the session.Before transferring, ask Claude to:
  • scan for likely secrets;
  • report counts and locations only;
  • never print the matching values;
  • stop the transfer if anything sensitive is found.
The better habit is simpler: never paste raw credentials into an AI conversation. Keep them in a secret manager and refer to the item or environment variable instead.My tested setup on August 10, 2026:
ComponentResult
Node26.7.0
npm12.0.2
Codex CLI0.147.0
Codex plugin1.0.6
AuthenticationChatGPT login, verified
RuntimeDirect, starts on demand
Review gateOptional; enabled for my workspace
After the explicit --source fallback, the conversation arrived in Codex with its visible history. I did not need to rewrite the context or start the investigation again.
Text
1. Install the official OpenAI Codex plugin in Claude Code.
2. Run /codex:setup until it says ready: true.
3. Run /codex:transfer.
4. If transcript detection fails, ask Claude to locate the current JSONL
   and return the complete --source command. Do not build the path yourself.
5. Scan the transcript for secrets before importing it.
6. Keep the returned Codex session ID and resume command.
7. Resume in Codex CLI, run /app, then exit the CLI.
8. Click Retry in Codex Desktop so the GUI can take ownership.
The bridge is genuinely useful. The rough edge is not the transfer itself — it is asking a human to provide a machine-shaped transcript path. Let the machine do that part.Paste this into Claude Code:
Text
Set up OpenAI's Codex plugin and transfer this current Claude session.
Reference: https://mjshao.fun/blog/claude-code-to-codex-transfer
Review gate: [ask me: enable or leave disabled]
1. Check Node, npm, Codex CLI, and Codex authentication.
2. Install openai/codex-plugin-cc only if missing, then reload plugins.
3. Run /codex:setup and show me the result.
4. Locate this session's exact JSONL under ~/.claude/projects; do not guess.
5. Scan it for raw secrets, reporting counts only; stop if any are found.
6. Run /codex:transfer, using the exact --source path if auto-detect fails.
7. Return the Codex session ID and exact resume command.
8. Resume the thread, run /app, exit Codex CLI, and click Retry in Desktop.
9. Verify the Desktop task shows the imported history.
这篇文章在 Claude Code 里开头,在 Codex 里收尾。交接确实跑通了,但中间那个别扭的报错,正是普通用户最需要有人讲明白的地方。
OpenAI 给 Claude Code 做了一个官方 Codex 插件,相当于在两个工具之间搭了一座小桥。你可以先在 Claude Code 里工作,再把当前对话导入一个保留可见历史、以后还能继续的 Codex thread它适合这些场景:
  • Claude 已经把背景查清楚了,但你想让 Codex 继续实现或 review;
  • 你想换一个模型接着干,而不是重新写一份交接文档;
  • 你想用 Codex 桌面端,同时保留 Claude Code 里已经做出的判断和决定。
它不是在一个 App 里切模型,而是把 Claude transcript 导入 Codex,并返回一个以后可以继续打开的 session ID。在 Claude Code 里依次运行:
Text
/plugin marketplace add openai/codex-plugin-cc
/plugin install codex@openai-codex
/reload-plugins
/codex:setup
/codex:setup 会检查 Node、npm、Codex CLI 和 Codex 登录状态。如果缺 Codex CLI,setup 流程会先征求你的同意,再通过 npm 安装。如果还没登录,运行:
Bash
codex login
还有一个可选的 review gate。打开后,Claude 每次完成可 review 的工作、准备停下之前,会先要求一次新的 Codex review:
Text
/codex:setup --enable-review-gate
只想做会话交接的话,不开也完全没问题。当 setup 显示 ready: true,运行:
Text
/codex:transfer
自动识别成功时,插件会导入当前 transcript,并返回类似结果:
Text
Transferred the Claude session into a Codex thread with visible turn history.
Codex session ID: <session-id>
Resume in Codex: codex resume <session-id>
记住这个 session ID。以后要回到该 Codex thread,就靠它。Transfer 只是创建了 Codex thread,并不会自动把你送进桌面端。先在终端恢复该会话:
Bash
codex resume <session-id>
进入 Codex CLI 后,再运行:
Text
/app
桌面端会打开同一个 thread,但这时你可能看到:
Text
This is open in another app
Close it there to continue here.
这不代表 transfer 失败。只是 Codex CLI 还开着,仍然持有这个 live thread;为了避免两个客户端同时写入,桌面端暂时不会接管。完整交接其实是五步:
Text
Transfer → Resume → /app → 退出 CLI → Retry
回到终端,退出 Codex CLI。然后切回 Codex 桌面端,点击 Retry。历史记录加载出来后,桌面端才算正式接管。这个动作很容易漏掉,因为 /app 会启动 GUI,却不会顺手关闭启动它的 CLI。我第一次 transfer 就失败了:
Text
Could not identify the current Claude transcript.
Retry with --source <path-to-claude-jsonl>.
文档给出的 fallback 在技术上没错:
Text
/codex:transfer --source ~/.claude/projects/-Users-me-repo/<session-id>.jsonl
但这对普通用户很不自然。Claude Code 会把当前工作目录编码成一个文件夹名,JSONL 文件名又是 session UUID。正常人既不该理解这套命名,也不该手工拼路径。直接告诉 Claude Code:
Text
请在 ~/.claude/projects 下找到「当前这个 Claude Code 会话」对应的
JSONL transcript,不要猜 session ID。只扫描是否存在疑似明文密钥,
不要输出密钥内容。如果安全,请返回一条可以直接粘贴的完整命令:
/codex:transfer --source <当前 JSONL 的绝对路径>
Claude 能读取当前环境,定位准确文件,再给你一条已经填好绝对路径的命令。你只粘贴一次即可。不要把整段报错复制回 /codex:transfer 后面,那会被当成错误参数,再失败一次。这是整个流程最值得写清楚的一点:--source 后面的路径应该由模型解析,不应该由人手工构造。这个插件导入的是 Claude JSONL transcript,不是先替你整理一份干净摘要。如果某次工具输出或粘贴的配置里出现过 API key,它也可能跟着会话一起过去。Transfer 前,让 Claude 做四件事:
  • 扫描疑似密钥;
  • 只报告数量和位置;
  • 不打印命中的具体值;
  • 一旦发现敏感内容,立即停止 transfer。
更好的习惯其实更简单:不要把明文凭证贴进 AI 对话。把它放在密码管理器里,只告诉 AI 对应的条目名或环境变量名。测试时间是 2026 年 8 月 10 日:
组件结果
Node26.7.0
npm12.0.2
Codex CLI0.147.0
Codex plugin1.0.6
认证ChatGPT 登录,已验证
RuntimeDirect,按需启动
Review gate可选;我的 workspace 已开启
补上明确的 --source 以后,会话带着可见历史进入了 Codex。我不需要重写上下文,也不需要从头再查一遍。
Text
1. 在 Claude Code 安装 OpenAI 官方 Codex 插件。
2. 运行 /codex:setup,直到显示 ready: true。
3. 运行 /codex:transfer。
4. 如果自动识别 transcript 失败,让 Claude 找当前 JSONL 并返回完整的
   --source 命令,不要自己拼路径。
5. 导入前扫描 transcript 是否包含明文密钥。
6. 保存插件返回的 Codex session ID 和 resume 命令。
7. 在 Codex CLI 恢复会话并运行 /app,然后退出 CLI。
8. 回到 Codex 桌面端点 Retry,让 GUI 正式接管。
这座桥本身很好用。真正粗糙的地方不是 transfer,而是让人类提供一条机器风格的 transcript 路径——这部分就该交给机器。把下面这段交给 Claude Code:
Text
请帮我安装 OpenAI Codex 插件,并把当前 Claude 会话交给 Codex。
参考:https://mjshao.fun/blog/claude-code-to-codex-transfer
Review gate:[问我:开启或保持关闭]
1. 检查 Node、npm、Codex CLI 和 Codex 登录状态。
2. 仅在缺失时安装 openai/codex-plugin-cc,然后 reload plugins。
3. 运行 /codex:setup,把结果给我看。
4. 定位当前会话在 ~/.claude/projects 下的准确 JSONL,不要猜。
5. 扫描是否有明文密钥,只报告数量;若有则停止。
6. 运行 /codex:transfer;自动识别失败时使用准确的 --source 路径。
7. 返回 Codex session ID 和完整 resume 命令。
8. 恢复该会话,运行 /app,退出 Codex CLI,再到桌面端点 Retry。
9. 验证桌面端已经显示导入的历史记录。

For AI Agents

This post ships a machine-readable execution plan. Paste the prompt into OpenCode / Claude Code / Cursor / Codex CLI (any agent with shell + file write tools) and it will reproduce the setup with pre-flight checks. Chat-only LLMs without tools should refuse, per the embedded SAFETY clause.
Share this post:
Enjoy this post? Subscribe via RSS: English | 中文