专题课 插件桥接 · Runtime 通信

Claude 是如何
调用 Codex 的

/codex:rescue 出发,把 Claude 插件命令子代理codex-companion.mjsCodex App Server JSON-RPCstdio / socket broker 一次拆清。

6关键链路层
2通信分段
2传输模式
1桥接脚本核心

一句话结论

Claude 不是在模型内部“切换成 Codex”。真实发生的事情是:Claude Code 的插件命令触发一个 Claude 子代理,子代理再通过 Bash 启动本地 Node 脚本 codex-companion.mjs,这个桥接脚本再通过 Codex App Server 的 JSON-RPC 协议 把任务送到 codex app-server 运行时。

01 · 完整调用链

主图:从插件命令到 Codex runtime 的完整桥接过程。你可以把它理解成“Claude 负责调度,本地脚本负责桥接,Codex runtime 负责真正执行”。
阶段发生了什么对应角色
1. Slash 命令用户输入 /codex:rescue ...,命中插件命令定义Claude Code 插件
2. 子代理路由命令规则要求把任务转给 codex:codex-rescueClaude 子代理系统
3. 本地命令执行子代理仅执行一条 Bash:node codex-companion.mjs task ...Bash 工具
4. 桥接编排codex-companion.mjs 解析参数、恢复线程、记录 job、决定前后台Node 桥接脚本
5. 协议请求桥接脚本发 thread/startturn/start 等 JSON-RPC 请求Codex App Server Client
6. 真正执行Codex runtime 在自己的 thread / turn 中推理、调用工具、改文件并返回结果codex app-server

02 · Claude 与 Codex 之间到底靠什么通信

别把这件事想成“Claude 把请求直接打到 Codex API”。在这个插件方案里,通信其实分成了 两段

分段实现方式重点理解
Claude → 插件脚本插件命令 + 子代理 + Bash 工具调用Claude 最终是在本地启动一个 Node 进程,不是内部切换模型
插件脚本 → Codex runtimeCodex App Server JSON-RPC这里才是结构化协议层,请求如 initializethread/startturn/start

也就是说,Claude 负责调度本地工具,而 Codex App Server 负责 runtime 协议。这两层不要混在一起看。

03 · codex-companion.mjs 到底是什么

它不是 Codex 本体,而是插件侧的桥接器 / 编排器。Claude 把任务交给它,它再把任务交给 Codex runtime。

  • 解析 taskreviewstatusresultcancel 等命令。
  • 处理 --resume--fresh--background--model--effort
  • 在当前仓库下记录 job 状态、threadIdturnId、日志文件。
  • 决定是直接启动 codex app-server,还是复用 broker 共享运行时。
  • 把 Codex 返回的事件、错误、最终输出整理成 Claude 可展示的文本。
/codex:rescue
-> commands/rescue.md
-> codex:codex-rescue
-> node codex-companion.mjs task ...
-> runAppServerTurn(...)
-> codex app-server JSON-RPC
-> Codex thread / turn 执行

04 · 源码定位表:每个文件在这条链里负责什么

这一节的目标不是把所有文件都看完,而是让你先建立文件职责地图。这样后面继续深挖时,不会在仓库里盲找。

文件角色你进去主要看什么
plugins/codex/commands/rescue.mdClaude 插件命令定义Slash 命令如何路由到子代理、何时询问 resume、最终要求子代理只执行什么命令
plugins/codex/agents/codex-rescue.mdClaude 子代理 prompt 契约为什么它被设计成“薄转发器”、默认是否带 --write、如何处理 --resume / --fresh
plugins/codex/scripts/codex-companion.mjs插件侧桥接主入口命令解析、task/review/status/result/cancel 分发、前后台 job、resume-candidate 逻辑
plugins/codex/scripts/lib/codex.mjsCodex runtime 协议适配层runAppServerTurn()runAppServerReview()、thread/start、turn/start、事件捕获与结果整理
plugins/codex/scripts/lib/app-server.mjsApp Server 客户端JSON-RPC message 如何走、何时 spawn("codex", ["app-server"])、何时走 broker
plugins/codex/scripts/app-server-broker.mjs共享运行时 broker本地 socket 如何复用同一个 Codex runtime、busy 时怎么拒绝并发请求
plugins/codex/scripts/session-lifecycle-hook.mjsClaude 会话生命周期 hookSessionStart / SessionEnd 时怎样注入环境变量、清理 broker、清理后台任务
plugins/codex/scripts/lib/state.mjs仓库级状态与 job 存储为什么 resume 和 status 是“按工作区”工作的、job 文件落在哪里
plugins/codex/scripts/lib/tracked-jobs.mjs任务跟踪层threadId / turnId / logFile / sessionId 如何随着执行过程被记录下来

05 · 逐文件讲解顺序:第一次读这个插件建议怎么走

推荐按“从外到内”的顺序读。也就是先看 Claude 这边怎样发起,再看桥接脚本怎样接,再看 Codex runtime 怎样吃进去。

顺序先读哪个为什么先读它
Step 1plugins/codex/commands/rescue.md先看用户命令入口,能马上知道 Claude 被要求做什么、不该做什么
Step 2plugins/codex/agents/codex-rescue.md再看子代理 prompt,理解为什么它几乎不自己思考、只负责转发
Step 3plugins/codex/scripts/codex-companion.mjs这是整条链真正的总调度器,先建立全局视角最值
Step 4plugins/codex/scripts/lib/codex.mjs看桥接脚本怎样调用 App Server,以及 thread / turn 是怎么跑起来的
Step 5plugins/codex/scripts/lib/app-server.mjs看清 JSON-RPC 客户端、stdio 直连和 broker 复用的分叉点
Step 6plugins/codex/scripts/app-server-broker.mjs如果你关心性能、复用和 socket,这一层最关键
Step 7plugins/codex/scripts/session-lifecycle-hook.mjs + lib/state.mjs最后补会话环境变量、resume、status、cancel 这些“为什么能记住上次任务”的外围机制

读法建议:第一次不要一上来就钻 app-server.mjs。如果你还没先看清 rescue.mdcodex-companion.mjs,你很容易只看到协议细节,却不知道整条链为什么要这样设计。

06 · 这样传输会不会慢?是不是应该全改成 socket?

通常不是这里慢。真正耗时的往往是 模型推理工具执行文件扫描首次启动 runtime,而不是本地进程间这点通信开销。

模式承载通道适合什么
直接模式stdio单次直连、简单稳定、跨平台
共享模式broker + 本地 socket复用一个长期存活的 Codex runtime,减少重复启动成本

关键点:不是“未来能不能改成 socket”,而是这个插件方案本来就同时支持 stdio本地 socket broker 两条路径。

07 · 为什么有时会掉到错误的工作目录

如果 Claude 侧转发任务时没有把正确的 cwd 或会话上下文带过去,Codex runtime 看到的工作目录就可能不是项目根,而是插件安装目录、当前 shell 目录,甚至你之前看到的 ~/.local/bin。这种情况通常不是协议层出了问题,而是桥接时的上下文绑定有偏差。

08 · 关键源码锚点

  • reference/reference_skill/codex-plugin-cc/plugins/codex/commands/rescue.md
  • reference/reference_skill/codex-plugin-cc/plugins/codex/agents/codex-rescue.md
  • reference/reference_skill/codex-plugin-cc/plugins/codex/scripts/codex-companion.mjs
  • reference/reference_skill/codex-plugin-cc/plugins/codex/scripts/lib/codex.mjs
  • reference/reference_skill/codex-plugin-cc/plugins/codex/scripts/lib/app-server.mjs
  • reference/reference_skill/codex-plugin-cc/plugins/codex/scripts/app-server-broker.mjs
  • reference/reference_skill/codex-plugin-cc/plugins/codex/scripts/session-lifecycle-hook.mjs

09 · 课程里最该记住的分层

Claude 负责插件命令与子代理调度,codex-companion.mjs 负责桥接与编排,Codex App Server 负责协议与运行时,Codex 模型只是在最底层真正做推理的那一层。把这四层分开看,这个系统就会一下子清楚很多。