get-shit-done v1.39.0-rc.6 发版说明解读:Codex Hooks 迁移加固、`--minimal` 轻量安装与 RC 发布纪律
本文围绕 docs/RELEASE-v1.39.0-rc.6.md 展开,梳理 get-shit-done(Claude Code 的元提示词 / 上下文工程 / 规格驱动开发系统)1.39.0 候选版本周期内的真实工程变更:rc.6 的"纯重发"语义、rc.5 的 Codex hooks TOML 迁移加固五连修复、rc.4 引入的 --minimal 轻量安装档与 Codex config.toml 原子写保护。读完后,你既能掌握这套 RC 发布纪律与相关安装/更新命令,也能理解安装器底层 TOML 迁移与原子写实现背后的防御性设计。
1. rc.6 版本状态:什么是"纯重发的候选版"
rc.6 的发布注记开宗明义:rc.6 是 rc.5 的一次重新发布(republish),没有并入任何新修复。发布分支 release/1.39.0 在没有先合并 main 的前提下,把版本号从 1.39.0-rc.5 提升到 1.39.0-rc.6,因此打 tag 时分支内容与 rc.5 相比是逐字节等价(byte-for-byte equivalent),只多了一个版本号变更提交:
$ git log v1.39.0-rc.5..v1.39.0-rc.6 --pretty='%h %s'
388118d8 chore: bump to 1.39.0-rc.6
这对使用者意味着一个很实际的结论:已经在 1.39.0-rc.5 上的用户没有任何需要安装的新内容。仓库中并存着 docs/RELEASE-v1.39.0-rc.5.md 与 docs/RELEASE-v1.39.0-rc.4.md,可交叉对照各版本内容;rc.6 注记中"What was in rc.5 / What was in rc.4"两个章节即是对既有内容的完整回溯,说明这类文档刻意保持"每个 tag 都自洽可读"的发布纪律。
从发布流程角度,rc.6 揭示了一条候选版经验:候选 tag 必须反映"合并 main 之后的发布分支状态"。rc.6 的下一步被明确写为 rc.7——先合并 main 到 release/1.39.0,让 rc.5 之后落地的八个修复(#2828、#2829、#2831、#2832、#2835、#2836、#2838、#2839)真正到达 npm registry。仓库中对应的回归测试文件(如 tests/bug-2829-local-install-sdk-path.test.cjs、tests/bug-2831-opencode-home-path-prefix.test.cjs、tests/bug-2836-audit-open-summary-uat-drift.test.cjs、tests/bug-2838-summary-rescue-gitignored-planning.test.cjs、tests/bug-2839-review-fix-transactional-cleanup.test.cjs)就是这些修复"等待被合并进发布流"的证据。
RC 发布纪律要点:任何 RC 都应从「与 main 同步后的 release 分支」切出;只 bump 版本号而不合并主干,会产出 rc.6 这种内容空转的候选版本,徒增下游甄别成本。
2. rc.5 核心修复:Codex hooks 迁移器的五连加固(#2809)
rc.6 文档回溯的 rc.5 主要修复是 #2809:针对 Codex 双层嵌套 hooks schema([[hooks.<Event>]] → [[hooks.<Event>.hooks]])迁移路径上的五个边界缺陷。这五个缺陷是在五轮 code review 中发现的,对应关系如下表(完整继承自原文档):
| 发现的问题 | 修复方式 |
|---|---|
parseHooksBody 使用裸正则(/^([\w.]+)\s*=/),会静默丢弃 status-message 这类带连字符的键以及任何带引号的 TOML 键 |
替换为 parseTomlKey()——仓库中已有的完整 TOML 键解析器 |
buildNestedBlock 无条件输出 [[hooks.TYPE.hooks]],即使没有 handler 字段,也会产出 type = "command" 但无 command 的畸形条目 |
增加守卫:仅含 matcher、不含 handler 字段的片段只输出事件条目块 |
legacyMapSections 过滤器用 section.path.startsWith('hooks.') 判断却不检查段数,导致 [hooks.SessionStart.hooks] 这种三段表被误判为事件条目,重放成虚假的嵌套事件 |
改用 section.segments.length === 2(此前已对 staleNamespacedAotSections 应用过同样的修复) |
缺少含点的带引号事件名的回归测试——[[hooks."before.tool"]] 是 2 段路径却有 3 个点号部分,若用 split('.') 判断会被误分类 |
新增回归测试;带引号含点的事件名被正确当作单一的双段命名空间 |
安装测试里的 handler 命令路径断言用正则(/gsd-check-update\.js/)而非精确绝对路径 |
强化为 assert.strictEqual,使用 path.join(codexHome, 'hooks', 'gsd-check-update.js') |
2.1 底层实现佐证
这些修复的落点可以在安装器 bin/install.js 中核实:
- 键解析的演进:原文档所述"裸正则丢键"问题,对应源码中从脆弱正则走向
parseTomlKey(line)的完整键解析路径。bin/install.js 定义parseTomlKey,并在多处复用同一解析逻辑(如 bin/install.js),其中专门有注释说明"使用parseTomlKey以便连字符键(如status-message)和带引号键被正确处理"(见 bin/install.js)。TOML 允许键名含点号与连字符,而它们必须被引号包裹才合法——这正是"裸正则分词"与"引用语境中键 + 用点号分段的键路径"必须分开处理的原因。 - 分段计数的严谨性:
[[hooks."before.tool"]]这类引号内带点的键,字面上点号多于逻辑分段数,因此任何依赖split('.')的判段都不可靠;必须借助真正的 TOML 解析语义(2 段路径 = 事件命名空间 +hooks子表)而非字符串切分。这与"先前的staleNamespacedAotSections修复"共享同一修复范式。
该修复之所以重要,是因为 Codex 的新版 schema 要求 [[hooks.<Event>]] + [[hooks.<Event>.hooks]](type = "command")这种双层数组表结构;若迁移器把用户已有的 [hooks.SessionStart.hooks] 误判为事件条目,或把无 handler 的 matcher-only 片段硬凑成缺失 command 的 hook 块,都会产出 Codex 无法加载的配置。
3. rc.4 变更回溯(rc.6 文档完整继承)
3.1 新增:--minimal 安装档(#2762)
rc.4 引入 --minimal 安装旗标(别名 --core-only,见 bin/install.js),它只写入支撑主工作流循环的六个核心技能:
new-project discuss-phase plan-phase execute-phase help update
不安装任何 gsd-* 子代理。两种模式对冷启动系统提示的开销差异如下(来自原文档数据):
| 模式 | 冷启动系统提示开销 |
|---|---|
| full(默认) | ~12k tokens |
| minimal | ~700 tokens |
- 对上下文窗口在 32K–128K 的本地 LLM 尤其有用;Sonnet 4.6 / Opus 4.7 云端模型用户不需要它——完整技能面才是云端模型的正确默认值。
- 安装清单(install manifest)会记录
mode: "minimal" | "full"。任何时刻运行不带--minimal的gsd update,即可扩展回完整技能集。
源码佐证:从 bin/install.js 可以还原这条模式的解析与落盘逻辑:--minimal / --core-only 被映射为名为 core 的内部 profile(--minimal 是 core profile 的向后兼容别名),经 resolveEffectiveProfile 决策优先级为:① --minimal → core;② 显式 --profile=<name> 覆盖 marker;③ 目标目录已存在 marker 则遵循 marker(防止 gsd update 时被静默扩展);④ 兜底 full。同时:
--minimal/--core-only与--profile=互斥,同时指定会直接报错退出(bin/install.js)。- core profile 无传递依赖,用空 manifest 走
stageSkillsForMode(严格核心白名单,不闭合传递依赖)。 - 源码注释明确"
--minimal实际上会收缩此前 full 安装的体积"(bin/install.js),安装日志会打印Skipping agents (minimal install — run gsd update without --minimal to add full surface)(bin/install.js)。 - 核心循环技能清单在仓库中有多处一致性声明,例如 commands/gsd/surface.md 的技能分类元数据即列出
core_loop: new-project discuss-phase plan-phase execute-phase help update。
3.2 修复:Codex 安装不再破坏 ~/.codex/config.toml(#2760)
rc.4 另一关键修复针对安装器写入 Codex 配置时的破坏性风险。修复后安装器具备六重防御(完整继承自原文档):
- 无条件清理遗留
[agents](单括号)与[[agents]](序列)块——在当前 Codex TOML schema 下两者均非法,无论该文件是否有 GSD marker(防止第三方工具或"marker 被删"的旧文件在重装时复发)。 - 按用户配置既有形态输出 GSD 托管的 hook:若用户已有
[[hooks.<Event>]]命名空间 AoT 条目则沿用同形,否则输出顶层[[hooks]]。 - 写入时迁移遗留的
[hooks.<Event>](map 格式)为[[hooks.<Event>]](数组格式)。 - 原子写入:先写临时文件再
renameSync覆盖,杜绝半写文件(bin/install.js 的注释即说明"先写<target>.tmp-<pid>-<n>,再renameSync覆盖目标,中途失败不会截断目标文件")。 - 写后严格 TOML 校验:拒绝重复键、重复表头、值后残留字节、不支持的取值类型。
- 失败即回滚:任何写前/写时失败都会恢复安装前快照并报错中止,而不是"警告后继续"。
测试佐证:仓库用专门的回归测试锁定这些行为。tests/bug-2760-codex-install-defensive.test.cjs 的头部注释归纳了"防御三重奏":Hooks AoT 降级缺陷(用户已有 [[hooks.SessionStart]] 时追加顶层 [[hooks]] 会破坏往返写入)、[agents]/[[agents]] 清理鲁棒性、以及写后校验 + 恢复备份。测试标题进一步说明 Codex 0.124.0+ 的 schema 要求:只有 [[hooks.SessionStart]] + [[hooks.SessionStart.hooks]](type = "command")形式才被接受,既不是扁平 [[hooks]] + event 字段形式,也不是缺 .hooks 的单块形式。对"静默 drop 键、半写文件、schema 不合法"这三类问题的组合防御,正是该修复"安装器绝不产出坏 Codex CLI"承诺的来源。
4. 安装预发布版本
RC 版本发布在 npm 的 next tag 下,安装方式与原文档一致:
# npm 全局安装(跟随 next tag)
npm install -g get-shit-done-cc@next
# npx 一次性执行
npx get-shit-done-cc@next
锁定到本 RC 的精确版本:
npm install -g get-shit-done-cc@1.39.0-rc.6
若想体验 rc.4 起加入的 --minimal 轻量档(仅六个核心技能、约 700 tokens 冷启动开销,适合 32K–128K 上下文本地模型),可组合使用:
npx get-shit-done-cc@next --minimal
# 或等价别名
npx get-shit-done-cc@next --core-only
之后随时用不带 --minimal 的 gsd update 扩展回完整技能集;--profile= 系列参数则提供比 --minimal 更精细的可组合安装选择。
5. 后续规划(What's next)
原文档对未来步骤的规划同样值得关注,它构成了对 RC 发布纪律的闭环印证:
- rc.7:从合并
main之后的release/1.39.0切出,使 rc.5 后落地的八个修复(#2828、#2829、#2831、#2832、#2835、#2836、#2838、#2839)真正到达 registry。 - finalize:当含完整 main 分支内容的 RC 稳定后,对发布工作流执行
finalize,将1.39.0提升到latesttag。
也就是说,rc.6 文档本身既是一份"当前无可安装新内容"的状态通告,也是 rc.7 的排队说明——发布注记作为流水线的一部分,承担了让下游使用者精确判断"要不要升级、升级到什么"的职责。
6. 总结与证据索引
rc.6 文档的阅读价值不在于新功能(它是 rc.5 的逐字节重发),而在于它是 get-shit-done 1.39.0 候选周期的一块拼图:
- Codex hooks 双层嵌套 schema 迁移是高风险路径,裸正则键解析、无 handler 空块、字符串切分代替语义分段等五类缺陷都有对应的"发现→修复→回归测试"闭环(#2809)。
- 配置写回必须原子且可回滚:#2760 的"临时文件 +
renameSync+ 写后严格 TOML 校验 + 失败恢复快照"四步组合,可视为任何"程序改写用户配置文件"场景的可复制范本。 --minimal让同一系统在云端与本地模型之间都能落地:通过安装清单记录mode、marker 防止更新被静默扩展、gsd update随时可回全量,兼顾了灵活性与可预期性。
如需深入,建议按以下顺序查阅仓库证据:
- bin/install.js——
--minimal/--core-only参数解析(L199 附近)、core profile 决策与 marker 逻辑(L7930 附近)、parseTomlKey(L3224)、原子写实现(L4575 附近); - tests/bug-2760-codex-install-defensive.test.cjs——Codex 安装防御行为的完整回归测试;
- tests/bug-2808-skill-hyphen-name.test.cjs 与
bug-28xx系列测试文件——rc.5 后等待进入 rc.7 的修复证据; - docs/RELEASE-v1.39.0-rc.5.md、docs/RELEASE-v1.39.0-rc.4.md——本文档回溯内容的原始出处;
- commands/gsd/surface.md——核心循环技能清单的元数据声明。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python08
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00