Repository navigation
[Bug] Codex 集成的四个问题(2.0.28):默认 scope 回归、丢失 session-end hook、strict-config 被自写字段卡住、插件 MCP 路径写死 macOS #621
Description
一句话
在 Linux 上按官方文档接 Codex,会连着撞上四个问题:插件的 MCP server 装得上但起不来,
setup-hooks 默认写到了当前工作目录而不是 ~/.codex,Codex 侧只剩「回忆」没有「记录」,
以及 Evolver 自己写出来的 config 过不了 codex --strict-config。
其中第 2、第 3 条相对 1.x 是行为回归 —— 我装了 @evomap/evolver@1.94.0 做了对照实测。
环境
@evomap/evolver2.0.28(对照组 1.94.0)evolver-codex-plugin@cbff921(manifest 0.2.0)- codex-cli 0.153.0,Linux x86_64(Debian 13),node v24.20.0
以下每一条都是在全新的临时 HOME + CODEX_HOME 里复现的,和我本地的测试环境无关。
1. 插件的 .mcp.json 写死了 macOS Homebrew 的 node 路径
plugins/evolver/.mcp.json(evolver-codex-plugin 仓库,源码 HEAD 里就是如此):
"command": "/opt/homebrew/opt/node@22/bin/node"这个路径在 Linux / Windows 上不存在。Codex 仍然会把 server 注册成 enabled,
但永远 spawn 不起来,九个 evolver_* MCP 工具全部静默不可用。
复现
codex plugin marketplace add /path/to/evolver-codex-plugin
codex plugin add evolver@evomap
codex mcp list实际
Name Command Args Status
evolver-proxy /opt/homebrew/opt/node@22/bin/node ./mcp/evolver-proxy.mjs enabled
codex mcp list 和 codex doctor 都不会提示这个二进制不存在,所以看起来像「装好了」。
期望 —— 只把这一个字段改成 "command": "node"(走 PATH),bridge 立刻正常:
── initialize ✔ evolver-proxy v0.1.0 (protocol 2024-11-05)
── tools/list ✔ 9 tools exposed
evolver-claude-code-plugin 的 .mcp.json 本来就是这么写的。若确实需要锁定 node 大版本,
建议在 mcp/evolver-proxy.mjs 启动时检查并给出可读的报错,而不是钉死某个包管理器的绝对路径。
这条属于
EvoMap/evolver-codex-plugin仓库。为了让四条一起看,先合并提在这里,
需要的话我再单独开一个过去。
2. setup-hooks 的默认 scope 从 user 变成了 project(回归)
插件 README 和它自带的 SKILL.md 都让用户(以及 Codex 自己)这样跑,不带 --scope:
README.md:44— “when you want the same machine-wide workflow in every Codex
project:evolver setup-hooks --platform=codex”plugins/evolver/README.md:98plugins/evolver/skills/evolver/SKILL.md:123—— 这一条是写进 skill 的,
意味着照着 skill 走的 agent 会把.codex/撒进用户的业务仓库
复现
mkdir -p /tmp/proj && cd /tmp/proj && git init -q .
evolver setup-hooks --platform=codex --json2.0.28 实际
{"runtime":"codex","outcome":"installed","files":[".codex/config.toml"],"mode":"mcp-plugin"}写的是 /tmp/proj/.codex/config.toml,~/.codex/config.toml 没动。
1.94.0 对照(同样的命令,同样的干净 HOME)
[setup-hooks] Platform: Codex
[setup-hooks] Config root: <HOME>
[codex] Wrote <HOME>/.codex/hooks.json
[codex] Injected evolution section into <HOME>/AGENTS.md
1.x 默认就是 user scope,和文档说的一致。2.x 默认变成 project,但文档没跟着改。
期望 —— 要么把 Codex runtime 的默认 scope 改回 user,要么把文档和 skill 里的命令
统一加上 --scope=user。现在的组合是「照官方说明逐字执行,会在用户没预期的位置生成配置」。
加上 --scope=user 之后行为是对的,而且正确尊重 CODEX_HOME:
{"runtime":"codex","outcome":"installed","files":["~/.codex/config.toml"],"mode":"mcp-plugin"}3. Codex runtime 不再安装 session-end hook —— 只回忆,不记录(回归)
evolver setup-hooks --runtime=codex --scope=user 在 2.0.28 上只产出两个 hook:
[[hooks.SessionStart]]
matcher = "startup|resume"
[[hooks.SessionStart.hooks]]
command = "evolver inject session-start --hook-stdin"
[[hooks.UserPromptSubmit]]
[[hooks.UserPromptSubmit.hooks]]
command = "evolver inject prompt-recall --hook-stdin"两个都是 recall。没有 SessionEnd,所以一次 Codex 会话读得到历史记忆,
但什么都写不回去 —— 闭环是断的。evolver inject 也确实只有这两个子命令:
用法: evolver inject session-start | evolver inject prompt-recall --hook-stdin
1.94.0 对照,同样的命令写出的 ~/.codex/hooks.json:
{
"hooks": {
"SessionStart": [{ "command": "node .codex/hooks/evolver-session-start.js" }],
"PostToolUse": [{ "command": "node .codex/hooks/evolver-signal-detect.js" }],
"Stop": [{ "command": "node .codex/hooks/evolver-session-end.js" }]
},
"_evolver_managed": true
}也就是 1.x 给 Codex 装的是 SessionStart / PostToolUse / Stop 三件套,
和 evolver-claude-code-plugin 今天仍然在装的三件套完全对应。2.x 丢了后两个。
这不是宿主的限制:codex-cli 0.153.0 支持的 hook 事件包括
SessionStart、UserPromptSubmit、PreToolUse、PostToolUse、PermissionRequest、
PreCompact、PostCompact、SessionEnd、SubagentStart、SubagentStop、Interrupt。
影响 —— 同一个 Evolver 安装,在 Claude Code 上会记录结果,在 Codex 上不会。
任何拿「Codex」对比「Codex + Evolver」的评测,Codex 这边压根没有东西可学。
变通 —— 能力其实是在的,只是没接到 hook 上。evolver ingest 原生认识 Codex rollout:
evolver ingest ~/.codex/sessions/2026/09/03/rollout-*.jsonl
# ingest [codex] …: 4 turn(s) → 1 signal(s)
# [success/success_prose] …
# → recorded as material 01M1K9M38F7FJG9CTAD7BH3ND4 (material.batch_ready)诉求 —— 要么给 Codex runtime 恢复一个 SessionEnd hook 接到 ingest 上;
要么如果 evolver autoexec 是 2.x 的既定替代方案,请在 Codex 接入文档里说明,
因为现在没有任何地方指向它。
4. _evox_product_managed 让 codex --strict-config 直接起不来
setup-hooks --runtime=codex 会往它托管的 Codex 配置里写一个 Codex 不认识的 key:
[mcp_servers.evox-product]
command = "…/node"
args = [ "…/productBridgeShim.js" ]
_evox_product_managed = true复现
export CODEX_HOME=/tmp/sc/.codex
evolver setup-hooks --runtime=codex --scope=user
codex --strict-config exec --skip-git-repo-check </dev/null实际
Error loading config.toml:
/tmp/sc/.codex/config.toml:8:1: unknown configuration field `mcp_servers.evox-product._evox_product_managed`
|
8 | _evox_product_managed = true
| ^^^^^^^^^^^^^^^^^^^^^
Codex 拒绝启动。不带 --strict-config 时它会被忽略,日常使用无影响 ——
但 --strict-config 恰恰是排查配置问题时会用的开关,而它卡在了 Evolver 自己的输出上。
期望 —— 归属标记放到 Codex 不会当作配置解析的地方(Evolver 自己的状态目录,
或者文件里的注释标记),让 Evolver 写出来的配置能通过 Codex 自己的严格校验。
附:顺手撞到的两个小毛病
- 无法识别的 flag 被静默忽略。
evolver setup-hooks --runtime=codex --nonsense=x
正常退出 0 并照常安装。拼错的 flag(包括拼错的--scope)和成功无法区分。
另外--platform=和--runtime=行为等价,但 help 只写了--runtime=,
插件文档只用--platform=,建议统一。 evolver autoexec --help不打印帮助,而是直接把 daemon 起起来
(关掉 stdin 也一样,只能靠 timeout 杀掉,并会留下autoexec.lock)。
Activity
artist-coding commentedon Sep 3, 2026
提错仓库了,已移到插件仓库:EvoMap/evolver-codex-plugin#8
内容不变。其中第 2、3、4 条确实出在
@evomap/evolverCLI 侧,如果维护者希望在本仓库单独跟踪,我可以按条拆开重开。抱歉打扰。