跳转到内容

Codex 交互机制

说明 Codex CLI 如何通过生命周期 hooks 把会话状态推送到 Global Pet Assistant。

当前集成是单向的:Codex CLI 通过 lifecycle hooks 把会话状态推给 GlobalPetAssistant,宠物应用不会反向控制 Codex。宠物最多通过受限 action 打开 Codex、项目目录、日志或 URL,但不读取 Codex 内部状态,也不执行 Codex 命令。

这条边界很重要:宠物是 Codex 状态的桌面投影,不是 Codex 的控制面。

本机全局 Codex 配置位于 ~/.codex/config.toml。它配置了默认模型、推理强度、沙箱策略、approval policy、插件和 Codex 自己的 notify 命令。这些属于 Codex CLI 的整体运行环境。

GlobalPetAssistant 与 Codex 的直接交互不依赖全局 notify。真正的集成入口在仓库本地 .codex/

.codex/config.toml
.codex/hooks.json
.codex/hooks/codex-pet-event.py

仓库本地配置启用:

[features]
codex_hooks = true

然后 hooks.json 为具体 Codex 生命周期事件注册命令 hook。Codex 在事件发生时把 hook payload 写到脚本 stdin,脚本把它转换成宠物事件,再 POST 到本地事件接口。

完整链路是:

Codex lifecycle event
-> .codex/hooks.json command hook
-> .codex/hooks/codex-pet-event.py reads stdin JSON
-> map Codex payload to LocalPetEvent
-> POST http://127.0.0.1:17321/events
-> EventRouter selects visible state
-> PetBehaviorController updates animation
-> floating pet shows running / waiting / review / failed

脚本发送失败不会让 Codex 任务失败。宠物应用没启动、接口不可达或请求失败时,hook 只写日志并返回成功。这保证桌面提示层不会阻断真实开发工作。

当前映射关注四个生命周期点:

Codex hookPet event type宠物状态语义
SessionStartcodex.session.startrunningCodex 会话启动或恢复。
UserPromptSubmitcodex.turn.runningrunning用户提交 prompt,Codex 开始处理。
PermissionRequestcodex.permission.requestwaitingCodex 正在等待工具或权限审批。
Stopcodex.turn.reviewreviewCodex 当前 turn 结束,等待用户查看结果。

脚本会把 Codex session_id 压缩进 source,并把完整 session 放入 dedupeKey。因此同一个 Codex 会话的多次生命周期更新会覆盖同一条桌面线程,而不是刷出一串独立通知。

cwd 会作为独立字段传给宠物。UI 可以用它显示当前项目目录名,让用户知道是哪一个仓库的 agent 状态在变化。

从读取到的全局配置看,Codex 当前运行在比较完整的 agent 环境里:启用了插件系统、unified exec、shell snapshot、memories、goals、Browser/GitHub/Gmail/Vercel 等插件,并设置了 workspace-write sandbox 和 on-request 审批。

这些配置影响 Codex 自己如何工作,但不改变宠物协议。宠物只消费 hook 产生的 JSON 事件。也就是说,即使 Codex 的模型、插件或审批策略变化,只要 hook payload 和映射脚本还在,桌面宠物的集成方式仍然稳定。

全局 notify 更像 Codex 自带的 turn 结束通知通道;GlobalPetAssistant 的 hook 集成则是更细粒度的生命周期通道。后者能区分 running、waiting、review 等状态,所以更适合驱动宠物动画。

集成提供两个 Codex 侧关闭开关:

CODEX_PET_EVENTS_DISABLED=1
~/.codex/global-pet-assistant-disabled

当开关启用时,hook 直接退出,不触达宠物接口。脚本和应用都会写 JSONL 日志到 ~/.global-pet-assistant/logs,分别记录 hook 映射、发送结果、事件接收、拒绝原因和运行时状态。

这使问题排查可以沿着两段看:先确认 Codex 是否触发 hook,再确认宠物应用是否接受事件。

如果要把这套集成从单仓库推广到所有 Codex 工作区,推荐把 hook 配置上移到用户级 ~/.codex/hooks.json,但保留同一个本地事件协议。仓库本地 hook 适合验证设计;全局 hook 适合成为日常桌面基础设施。

如果后续需要双向能力,建议仍然避免让宠物直接执行 Codex 命令。更合理的边界是让 action 打开 Codex app、指定项目目录或可审阅日志,把决策权留给用户。