ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

get-shit-done 的 Codex 集成修复解析:`hooks.state` 信任状态命名空间与 `hooks.<EVENT>` AoT 事件表的 schema 区分策略

get-shit-done 的 Codex 集成修复解析:`hooks.state` 信任状态命名空间与 `hooks.<EVENT>` AoT 事件表的 schema 区分策略 get-shit-done 的 Codex 集成修复解析hooks.state信任状态命名空间与hooks.EVENTAoT 事件表的 schema 区分策略【免费下载链接】get-shit-doneA light-weight and powerful meta-prompting, context engineering and spec-driven development system for Claude Code by TÂCHES.项目地址: https://gitcode.com/GitHub_Trending/getshi/get-shit-done导读本篇文章聚焦 get-shit-doneGSD为 Claude Code 之外的 AI 运行时尤其 Codex CLI提供安装集成时的一个高价值边界问题——config.toml中hooks.*命名空间同时承载两类语义完全不同的表Codex 自己维护的逐钩子信任持久化状态hooks.state.*与 GSD 安装的事件处理器hooks.EVENT。本文基于 changeset .changeset/mellow-lynx-forage.mdPR 3289还原缺陷根因、修复策略、源码级校验逻辑与回归测试证据读完你将掌握如何在插件/集成工具中为用户的既有配置与自己写入的配置设计不会互相踩踏的 schema 校验规则。一、问题背景一个校验器同时面对两种hooks.*表Codex CLI 的config.toml自 0.124.0 起对 hooks 的书写形态非常严格事件处理器必须以array-of-tablesAoT形式书写例如[[hooks.SessionStart]] [[hooks.SessionStart.hooks]] type command command /usr/local/bin/gsd-check-update而自 Codex CLI 0.130.0 起Codex 又在同一个hooks.*命名空间下新增了逐钩子信任状态的持久化能力。当用户在交互中批准过某个钩子后Codex 会把信任记录写到形如hooks.state.project/...的位置使用普通表regular table而非 AoT[hooks.state] [hooks.state./home/user/.codex/hooks.json:pre_tool_use:0:0] enabled true trusted_hash sha256:abc123于是同一个顶层 keyhooks下出现了两种物理形态完全相反的配置hooks.state.*是普通对象hooks.EVENT是数组。任何对所有hooks.*一视同仁的粗暴校验都会在这里犯下方向相反的两个错误——这正是本 changeset 要解决的问题。二、缺陷根因schema 校验器把所有hooks.*都当作事件表.changeset/mellow-lynx-forage.md 给出了一个简洁有力的Fixed声明get-shit-done-cc --codex不再拒绝合法的 Codexhooks.state信任持久化条目——此前 schema 校验器把每一个hooks.*表都过度归类为事件处理器的 array-of-tables从而在 Codex CLI 0.130.0此时hooks.state.project/...已用于存储逐钩子信任状态上直接破坏安装流程。现在hooks.state.*接受普通表形态而hooks.EVENT仍要求 AoT。从仓库实现可以还原出更完整的失败链路。在 bin/install.js 中validateCodexConfigSchema承担写后 schema 校验post-write schema validation的职责安装器在把config.toml写入磁盘前会解析目标字节流并断言其符合 Codex 期望的形态校验失败则执行快照恢复并中止确保用户永远不会被留在一个 Codex CLI 无法加载的配置上对应源码注释中的 #2760 fix 3见 bin/install.js。该校验器的历史策略注释见 bin/install.js是文件必须能被完整解析为 TOMLagents必须是结构表[agents.name]hooks.Event一旦存在必须是 array-of-tables——Codex ≥0.124 拒绝单括号[hooks.Event]map。当hooks.state被引入后这条所有hooks.*都必须是 AoT的规则产生了两类误伤用户config.toml里已有合法的[hooks.state]/[hooks.state....]普通表校验器却按hooks.EVENT规则要求其必须是数组 → 误报安装被中止反过来如果按校验通过的语义去推断hooks.state被当作事件名输出会与后续 migration / 重新发射逻辑相互干扰。三、修复策略为hooks.state命名空间单独开出豁免路径PR 3289 的核心思路不是放松校验而是给命名空间分层hooks.state.*是 Codex 托管的信任状态区必须用普通表hooks.EVENT才是 GSD / 用户事件处理器必须用 AoT。两条规则各自独立、严格互斥。测试文件 tests/bug-3285-codex-hooks-state-allowed.test.cjs 头部的注释把修复意图讲得很明确Root causevalidateCodexConfigSchema遍历每个hooks.*表段并断言 AoT 形态而没有区分hooks.state.*Codex 管理的逐钩子信任持久化普通表与hooks.EVENT如SessionStart确实要求[[hooks.SessionStart]]的 AoT 形态。Fix为所有以hooks.state开头的表段增加豁免按普通表校验hooks.EVENT路径仍全部要求 AoT。这一策略在源码中体现在三个层面。3.1 写后校验器的分段豁免在validateCodexConfigSchema的 section 头扫描循环中校验器先处理[[hooks.state]]/[[hooks.state.key]]AoT 形态——这种情况下反而要拒绝因为信任状态区不可能是数组// hooks.state.* 是 Codex 的持久化钩子信任命名空间Codex CLI 0.130.0 引入。 // 它使用普通表形态而非 array-of-tables。 // [[hooks.state]] 或 [[hooks.state.key]]AoT是非法的予以拒绝。 if (section.array (section.path hooks.state || section.path.startsWith(hooks.state.))) { return { ok: false, reason: [[${section.path}]] is invalid; hooks.state namespace must use regular tables, }; } // 所有其他 hooks.* 路径如 hooks.SessionStart 事件处理器要求 AoT 形态—— // 裸的 [hooks.Event]单括号是非法的。 if (!section.array section.path.startsWith(hooks.) section.path ! hooks.state !section.path.startsWith(hooks.state.)) { return { ok: false, reason: bare [${section.path}] table is invalid in current Codex schema (expected [[${section.path}]] array-of-tables), }; }这两条if即本 changeset 的完整修复前一条把hooks.state从必须 AoT的错误归类中摘出后一条用精确的前缀排除确保豁免不会泄露给真正的hooks.EVENT。3.2 解析对象的结构性兜底检查section 头扫描之外validateCodexConfigSchema还会对parseTomlToObject解析出的对象做第二层结构性确认见 bin/install.js。对hooks对象的每个子键hooks.state单独分支处理数组形态AoT与标量形态都会被拒绝只有普通对象plain table合法其他子键仍要求是数组。两层检查互为冗余确保无论配置以头注释形态还是解析值形态被误读都能得出同一结论。if (event state) { if (Array.isArray(value)) { return { ok: false, reason: hooks.state must be a regular table/object, got array-of-tables }; } if (typeof value ! object || value null) { return { ok: false, reason: hooks.state must be a regular table/object, got ${typeof value} }; } continue; }3.3 迁移逻辑同样避开hooks.state问题并不只存在于校验器安装流程中还有把旧式[hooks]map 格式迁移为两级嵌套 AoT 的migrateCodexHooksMapFormatbin/install.js。该函数在收集旧式非数组 hooks 段时同样通过段数segments.length 2加前缀排除来识别哪些段值得迁移并在注释里明确把hooks.state与hooks.state.*排除在候选之外——否则 Codex 的信任状态会被误当成名为state的事件重新发射。四、回归测试用 8 组用例钉死命名空间边界tests/bug-3285-codex-hooks-state-allowed.test.cjs 是本变更的回归防线。它同时覆盖单元层直接调用validateCodexConfigSchema其中测试模块通过先设GSD_TEST_MODE再 require../bin/install.js拿到内部导出见该文件第 16-29 行与集成层真实执行install(true, codex)见该文件第 190-214 行并配套搭建了hooks/dist构建前置第 38-45 行与临时CODEX_HOME隔离第 216-219 行。单元测试矩阵非常完整地刻画了允许什么、拒绝什么测试场景期望结果依据裸[hooks.state]表头通过普通表命名空间见第 52-60 行裸[hooks.state.key]含斜杠/冒号须引号包裹的 key通过精确复刻 Codex 0.130.0 写入的信任条目形态见第 62-76 行hooks.state与[[hooks.SessionStart]]共存通过真实世界混合配置见第 78-98 行单括号[hooks.SessionStart]非 AoT拒绝且 reason 须提及该路径豁免不得泄露给事件表见第 100-116 行解析后hooks.state为对象时不触发must be an array通过兜底循环也必须跳过它见第 118-133 行多个hooks.state子键全部通过见第 135-151 行[[hooks.state]]AoT 形态拒绝信任区必须是普通表见第 153-167 行[[hooks.state.foo]]AoT 子键形态拒绝见第 169-183 行集成层则验证了故障场景本身第 225-241 行预置含信任条目的config.toml后安装不抛错并进一步验证信任数据在安装后原样存活第 243-281 行不是简单断言hooks.state仍是对象而是解析安装后文件、确认原始trusted_hash与enabled都被完整保留——这对GSD 安装不得动用户 Codex 信任状态的承诺是决定性的证据。五、同类修复串成的完整拼图hooks.state只是 Codex 集成矩阵的一角把本 changeset 放回仓库的 Codex 安装集成谱系中可以看到它并非孤立修补而是与同目录下多个 changeset 共同构成对 Codex hooks 形态的体系化兼容。这些都是理解本修复价值的上下文.changeset/3346-codex-aot-toml-key.mdPR 3346修复migrateCodexHooksMapFormat把旧式[hooks.X]的路径段原样当作新 AoT 块的叶 key 重发——当旧 key 是file:event:line:col这种位置标识、真实事件名藏在event ...字段里时会产生[[hooks....config.toml:session_start:0:0]]这类 Codex 0.124.0 拒绝加载的表头。修复后event字段名胜出作为叶 key。这与 3289 互为镜像一个解决迁移时选错 key一个解决校验时认错形态。.changeset/3566-codex-hooks-canonical-feature-key.mdPR 3573Codex 自身源码把codex_hooks标记为legacy_key因此安装器在 Codex CLI ≥ 0.130.0 上改写规范的[features].hooks true同时对既有遗留行保留不动交给 Codex 运行时的别名机制处理。这体现了同仓库处理 Codex 版本演进的统一姿态识别 Codex 官方迁移方向写入规范形态绝不破坏用户已有配置。三者在同一原则下收敛GSD 的 Codex 安装器必须在config.toml里精准区分哪些段是 Codex 托管的hooks.state、features别名、信任数据与哪些段是 GSD 写出的hooks.EVENT事件块、agent 元数据只对自己拥有的段负责对用户与 Codex 拥有的段保持最小侵入。六、实践启示给写配置的集成工具的四条校验设计准则命名空间分层先于形态校验当被写入的目标配置如 Codexconfig.toml存在多类*通配语义时先按前缀把命名空间切成互斥集合再为每个集合定义各自的形态规则而不是对hooks.*写一条全局断言。豁免要精确排除而非整体放行修复中用path ! hooks.state !path.startsWith(hooks.state.)双向排除保证[hooks.SessionStart]这样的真事件表依旧被 AoT 规则拒绝——避免为了让新功能通过而误伤旧校验测试用例第 100-116 行就是为此服务的守卫。双通道校验既要扫描 TOML 的 section 头区分[x]与[[x]]的裸/结构语义也要对解析后的对象做结构断言判断数组/普通表/标量两层互补才能覆盖头形态错误与值形态错误两类 bug。把数据存活写进测试仅断言不抛错是不够的本仓库的集成测试进一步验证用户信任条目enabled、trusted_hash在安装后被完整保留这比安装没炸更能守护集成工具的底线承诺。如果你在自己的项目中接入 Codex例如运行 changeset 中记录的npx get-shit-done-cclatest触发 Codex 安装路径当config.toml中出现hooks.state相关键导致工具报 schema 错误时可以先核对工具版本是否已包含本修复对应测试为 tests/bug-3285-codex-hooks-state-allowed.test.cjs若需手工排查可参照上文第三节的校验规则逐段核对hooks.state.*必须是普通表、hooks.EVENT必须是[[...]]数组、事件处理器字段必须嵌套在[[hooks.EVENT.hooks]]之下。理解这条边界也就能理解为什么 Codex 生态中的工具在 0.124.0 到 0.130.0 之间频繁更新 hooks 相关代码——它们都在为信任状态与事件处理这两类语义的共存而重构自己的校验与迁移逻辑。【免费下载链接】get-shit-doneA light-weight and powerful meta-prompting, context engineering and spec-driven development system for Claude Code by TÂCHES.项目地址: https://gitcode.com/GitHub_Trending/getshi/get-shit-done创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表