gsd-core Codex 泄漏扫描器修复解析:基于 gsd-file-manifest.json 的路径检查收敛与 bare ~/.claude 替换
【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载导读本文围绕 gsd-core 安装器bin/install.js中 Codex 泄漏扫描器leak scanner的一次缺陷修复changeset 记录于 .changeset/archived/sunny-lynx-rally.md对应 PR #570展开。该修复解决三个相互关联的子缺陷泄漏扫描误伤用户自有文件、路径转换漏掉无尾斜杠的 bare~/.claude引用、以及 agents 清单漏记.toml文件。读完本文你将理解 gsd-core 如何在多运行时安装场景下把路径检查收敛到 GSD 自有文件掌握 manifest 机制、转换器替换规则与对应回归测试的完整技术细节。背景为什么需要泄漏扫描器gsd-core 是一个面向多种 AI 编码运行时Claude Code、Codex、Copilot、Cline、Windsurf、OpenCode、Hermes、Qwen、Kimi 等的安装/工作流分发核心。同一份宿主无关的 Claude 工作流文档在安装到非 Claude 运行时前必须经过内容转换copyWithPathReplacement等转换管线把~/.claude/、$HOME/.claude/、gsd:等 Claude 专属引用改写成目标运行时的对应形态。一旦转换遗漏某处.claude路径引用生成的配置或提示词就会指向错误或不存在的配置目录——这正是“泄漏leak”。因此安装器在收尾阶段内置一个泄漏扫描器作为转换管线的验证兜底verification backstop。修复前的三个子缺陷SUB-BUG A / B / C该次修复源自 issue #570测试套件 tests/codex-config-install.test.cjs 在文件头注释中精确记录了三个子缺陷编号子缺陷修复前行为修复方式SUB-BUG A扫描范围失控scanForLeakedPaths递归扫描整个targetDir把用户预先存在的、合法提及~/.claude的私人文件如memories/raw_memories.md也误报为泄漏只扫描gsd-file-manifest.json中记录的 GSD 自有文件SUB-BUG Bbare 路径漏替换convertClaudeToCodexMarkdown只替换带尾斜杠的~/.claude/configDir ~/.claude无斜杠等 bare 形式残留增加 bare 形式的 word-boundary 替换SUB-BUG Cagents 清单漏记.tomlwriteManifest对agents/目录只匹配.md后缀Codex 安装的是.tomlagent 文件因此这些文件对 manifest 及基于 manifest 的扫描不可见writeManifest同时记录.toml修复一manifest 收敛扫描范围修复后泄漏扫描不再全目录遍历而是以安装器自己写入的gsd-file-manifest.json为唯一范围依据。bin/install.js 中实现如下仅当运行时不拥有 Claude 路径!_hostBehaviors(runtime).ownsClaudePaths时才触发扫描读取targetDir/gsd-file-manifest.json取其files对象的键集合作为待检文件清单若 manifest 缺失或解析失败则整体跳过扫描manifestFiles null而不是回退到全目录遍历——宁可漏报也不误报逐个文件读取内容用正则/(?:~|\$HOME)\/\.claude\b/g统计残留引用命中即输出黄色警告前 5 个文件 总数汇总例如⚠ Found 2 unreplaced .claude path reference(s) in 1 file(s): agents/gsd-executor.toml (2)这消除了 SUB-BUG A 的典型误报场景用户在自己的~/.codex/memories/raw_memories.md中写“I used to work in ~/.claude”由于该文件不在 manifest 中扫描器不再对其告警回归测试见 tests/codex-config-install.test.cjs。manifest 本身的记录面gsd-file-manifest.json由writeManifest()bin/install.js在安装成功落盘结构含{ manifestVersion: 2, version: gsd 包版本, timestamp: ISO 时间, mode: full, runtime: codex, scope: global, files: { gsd-core/...: sha 哈希, agents/gsd-executor.toml: sha 哈希, ...: ... } }值得注意的细节manifestVersion当前为 2见 src/installer-migrations.cts与versionGSD 包版本是两个独立字段避免文档 schema 版本与包版本耦合runtime/scope字段使 Installed Surface Resolver 能回答“哪些 surface、以何种 scope、为哪个运行时安装”而不必从目录位置反推用户自有工件如gsd-core/USER-PROFILE.md定义于USER_OWNED_ARTIFACTS不写入 manifest——否则saveLocalPatches()会把每次重装都误判为“本地补丁”bug #2771回归测试见 tests/install.test.cjsmanifest 的读取侧做了防御性归一化非整数、字符串、0、负数等一律按 v1 处理normalizeManifestVersionsrc/installer-migrations.cts且 Installed Surface Resolver 会拒绝读取符号链接路径下的 manifest把它当作安全边界。修复二bare ~/.claude 的路径替换修复前convertClaudeToCodexMarkdownbin/install.js的路径替换只覆盖带尾斜杠的形式converted converted.replace(/\$HOME\/\.claude\//g, $HOME/.codex/); converted converted.replace(/~\/\.claude\//g, ~/.codex/); converted converted.replace(/\.\/\.claude\//g, ./.codex/);而configDir ~/.claude、dir $HOME/.claude这类**裸引用无尾斜杠**会原样残留。修复在尾斜杠形式之后追加了 bare 形式利用\b词边界防止过度替换converted converted.replace(/\$HOME\/\.claude\b/g, $HOME/.codex); converted converted.replace(/~\/\.claude\b/g, ~/.codex);顺序刻意安排先处理带斜杠形式再处理 bare 形式避免~/.claude/hooks/被\b形式提前改写成~/.codex/hooks/后再被其他规则二次改写。同样的“bare 形式补替换”模式也同步应用到了 Copilot 转换器convertClaudeToCopilotContentbin/install.js该处用捕获组(\/|\b)在一次正则中同时覆盖两种形式。回归测试见 tests/codex-config-install.test.cjs断言转换后不再存在/(?:~|\$HOME)\/\.claude\b/。同类修复还被推广到 Trae / Windsurf 转换器见 CHANGELOG.md 相关条目#983/#995bare 形式按 Codex/Cline 的 #570/#782 对齐。附加修正~/include 形式的强制重写除了扫描bin/install.js 还在 manifest 范围内对 Codex 安装额外执行一次机械重写把残留的~/.claude/gsd-core/与$HOME/.claude/gsd-core/include 引用改写为~/.codex/gsd-core/与$HOME/.codex/gsd-core/问题 #4667。理由是~/形式会解析进 Claude 安装副本在双运行时机器上版本可能不一致在纯 Codex 机器上根本不存在。该重写只作用于 manifest 记录的.md/.toml文件跳过CHANGELOG.md失败时静默跳过扫描仍作为最终兜底。修复三writeManifest 记录 agents/gsd-*.tomlCodex 运行时把 agent 写成agents/gsd-*.toml而非其他运行时的.md。修复前 writeManifest 的 agents 分支 只匹配.md后缀导致这些.toml文件不进 manifest ⇒ 基于 manifest 的泄漏扫描对其不可见SUB-BUG C 的直接后果也不参与saveLocalPatches()的本地补丁检测与卸载清理。修复后的匹配条件为if (file.startsWith(gsd-) (file.endsWith(.md) || file.endsWith(.toml))) { manifest.files[agents/ file] fileHash(path.join(agentsDir, file)); }对应回归测试 tests/codex-config-install.test.cjs 的断言逻辑先验证 Codex 安装确实写出了至少一个gsd-*.toml避免测试空转断言gsd-file-manifest.json存在断言manifest.files中至少存在一个agents/gsd-*.toml键。修复的联动效应更新流程与工作流文档泄漏扫描的收敛并非孤岛。同一正则/(?:~|\$HOME)\/\.claude\b/g也被 tests/update-workflow.test.cjs 用作源码侧的守门gsd-core/workflows/update.md不允许出现 bare无尾斜杠的~/.claude引用——因为copyWithPathReplacement的 replacer 处理带斜杠形式而不处理 bare 形式任何 bare 引用都会在安装时被扫描器标记为未解析路径。这形成了“源文档守门 安装后扫描”的双层防线源码侧lint/测试在变更进入仓库前拦截 bare.claude引用安装侧manifest 收敛的扫描器兜底捕获任何从转换管线中漏出的残留。小结sunny-lynx-rally这次修复PR #570把 Codex 泄漏扫描器从“全目录误报”修正为“manifest 收敛”补齐了 bare~/.claude的替换缺口并让agents/gsd-*.toml进入 manifest 的管控面。三处改动共享同一个设计原则扫描与追踪必须建立在安装器自己写的、结构完整的清单之上而不是对目标目录做启发式猜测。这一原则也贯穿 manifest 的其他用途——本地补丁检测、卸载清理、Installed Surface Resolver 的安装面查询以及~/include 的重写全部以gsd-file-manifest.json为单一事实来源。如需深入可继续阅读安装器主体bin/install.jswriteManifest见 L9915泄漏扫描见 L12361manifest schema 与归一化src/installer-migrations.cts安装面解析src/installed-surface-resolver.cts回归测试tests/codex-config-install.test.cjs、tests/install.test.cjs、tests/update-workflow.test.cjs赞分享【免费下载链接】gsd-coreGit. Ship. Done - Core项目地址https://gitcode.com/gh_mirrors/ge/gsd-core点击查看免费下载相关推荐gsd-core 命名空间收敛机制解析Claude Hook 安装时 /gsd:cmd → /gsd-cmd 重写原理与实现gsd core 命名空间收敛机制解析Claude Hook 安装时 /gsd:cmd → /gsd cmd 重写原理与实现 本篇技术指南围绕 gsd cgsd-core 更新检查修复解析scoped 包名 opengsd/gsd-core 与 update_available 的正确实现gsd core 更新检查修复解析scoped 包名 opengsd/gsd core 与 update_available 的正确实现 导读 本文以 .cgsd-core Progress 路由的规划前假设检查统一规范化 /gsd-discuss-phase 替代路径gsd core Progress 路由的规划前假设检查统一规范化 /gsd discuss phase 替代路径 导读 本篇文章以 gsd core 仓库上一篇3分钟变身AI绘画大师SDXL Prompt Styler如何让你的提示词拥有魔法下一篇如何30分钟搞定黑苹果安装新手教程OpCore Simplify自动工具快速配置指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考