ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

get-shit-done Graphify 自动更新 Hook 无法发布的根因与修复:从 `hooks/` 源码到 `~/.claude/hooks/` 的完整发布链路剖析(3579)

get-shit-done Graphify 自动更新 Hook 无法发布的根因与修复:从 `hooks/` 源码到 `~/.claude/hooks/` 的完整发布链路剖析(3579) get-shit-done Graphify 自动更新 Hook 无法发布的根因与修复从hooks/源码到~/.claude/hooks/的完整发布链路剖析#3579【免费下载链接】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本篇技术指南围绕 changeset 档案 .changeset/fix-3579-graphify-hook-publish.md 展开剖析 get-shit-doneGSD中 Graphify 知识图谱自动更新 Hookgsd-graphify-update.sh因发布链路断点而无法到达用户安装目录的问题并结合 scripts/build-hooks.js 与 bin/install.js 的源码实现讲解源码 hook →hooks/dist/构建产物 → 运行时配置目录三段式发布机制、两处根因修复白名单补齐 子目录镜像以及防回归的 coverage drift guard。读完你将理解 GSD 的 hook 打包与安装模型掌握此类文件从未进入发布物类缺陷的系统性排查与封堵方法。一、GSD 的 hook 发布模型为什么需要一条三段式链路GSD 内置了大量以gsd-*.js/gsd-*.sh命名的 Claude Code 等运行时 hookPostToolUse、PreToolUse、SessionStart、Stop 等。它们不可能直接从仓库源码目录被引用式使用而是必须被打包、拷贝到用户运行时的配置目录例如~/.claude/hooks/。这一过程在源码上被拆成两段、共三个停留点源码层hooks/ 目录下平铺所有 hook 顶层文件外加lib/子目录存放被 hook 调用的分离辅助脚本构建层scripts/build-hooks.js 把顶层 hook 与白名单子目录里的内容物化到 hooks/dist/ 下的构建产物供 npm 包随发布携带参见 tests/package-manifest.test.cjs 中对hooks必须列入package.jsonfiles的约束安装层bin/install.js 读取hooks/dist/的扁平目录将产物镜像拷贝到目标运行时的hooks/目录并完成版本头模板替换、可执行位设置、settings.json钩子注册。任何一层丢失文件最终表现都一样安装目标上不存在该 hook而用户侧往往只有在功能不生效时才察觉到异常——正如本次 #3579 暴露的问题。二、changeset 档案解读Bug #3579 的问题定性.changeset/fix-3579-graphify-hook-publish.md是仓库使用的 changeset变更集记录其 frontmatter 声明了type: Fixed与pr: 3579正文对缺陷给出了精确定义gsd-graphify-update.sh一直缺失于scripts/build-hooks.js的HOOKS_TO_COPY白名单因此它从未进入hooks/dist/而安装器bin/install.js基于hooks/dist/的扁平readdirSync循环拷贝自然也不可能把它复制到~/.claude/hooks/。同时hook 运行时需要的分离重建辅助脚本 hooks/lib/gsd-graphify-rebuild.sh 同样被遗漏——因为build-hooks.js与bin/install.js两者此前只遍历顶层文件从不深入子目录。换句话说这是一个单一表层症状、两层结构缺陷的经典发布事故缺口 1白名单缺失构建脚本使用显式 allowlist新增 hook 若忘记登记构建层便静默跳过缺口 2目录深度受限即使顶层 hook 打包成功其依赖的lib/子目录辅助脚本也不会被任何一层搬运。三、被遗忘的主角Graphify 自动更新 Hook 到底是什么gsd-graphify-update.sh见 hooks/gsd-graphify-update.sh是一个PostToolUse 的 Bash matcher hook在主分支HEAD因 git 操作推进之后自动在后台重建项目知识图谱使后续/gsd-graphify相关查询状态、查询、diff始终基于最新提交的数据。它在功能上是开箱即停的选装件默认关闭即 hook 文件本身是 no-op必须满足.planning/config.json中同时存在graphify.enabled: true与graphify.auto_update: true才真正生效docs/CONFIGURATION.md 中graphify.auto_update默认值为false以保证升级后既有用户行为不变。从脚本头部的注释可见其设计为8 道快速失败门按开销从低到高依次拦截非目标场景参见 hooks/gsd-graphify-update.shstdin 载荷存在且tool_name Bash命令匹配 HEAD 推进类 git 操作git commit/git merge/git pull/git rebase --continue/git cherry-pick或等价的gsd-sdk query commit形态$CI为空CI 环境抑制位于 git 仓库内当前分支 默认分支git.base_branch覆盖否则在main/master/trunk中探测配置文件双重开关均开启graphify二进制在PATH上无重建在途PID 锁kill -0探活容忍陈旧锁。全部通过后hook 会先同步向 .planning/graphs/.last-build-status.json 写入status: running的运行信号随后通过兄弟目录定位HOOK_DIR/lib/gsd-graphify-rebuild.sh并以disown方式分离后台执行重建。关键点在于它依赖路径$HOOK_DIR/lib/gsd-graphify-rebuild.sh——该辅助脚本与 hook 在目录结构上必须是镜像相邻关系这正是修复中反复强调子目录必须同步搬运的根本原因。四、根因拆解链路两个断点的源码证据断点一构建白名单没有登记新 hook在修复前scripts/build-hooks.js 的HOOKS_TO_COPY数组是纯 JS hook 与既有 shell hookgsd-session-state.sh、gsd-validate-commit.sh、gsd-phase-boundary.sh的显式清单并没有包含gsd-graphify-update.sh。构建脚本随后用fs.existsSync(src)检查源文件是否存在并对.js文件执行语法校验new vm.Script(...)防止历史上重复const声明被发布之类的事故然后才把文件以先写 staging 再rename的原子方式落入hooks/dist/见 scripts/build-hooks.js 顶部的注释与renameAtomicWithRetry实现。白名单外的文件即使存在于hooks/顶层也不会进入dist——该机制为防泄漏而设计副作用是新增即漏。断点二构建与安装只遍历顶层文件即使补上白名单构建产物里也只会出现单个 hook 文件。gsd-graphify-update.sh在HOOK_DIR/lib/gsd-graphify-rebuild.sh处查找分离重建辅助脚本而该文件位于 hooks/lib/ 子目录同目录还存放着供.shhook 调用的git-cmd.js。修复前的build-hooks.js主循环仅path.join(HOOKS_DIR, hook)处理顶层文件bin/install.js 的安装循环同样只用fs.readdirSync(hooksSrc)得到的扁平条目 isFile()判断——于是lib/中的内容在发布链路的每一站都被静默丢弃。需要特别注意的是安装器对顶层.sh文件并非简单复制而是要逐字节做{{GSD_VERSION}}占位符替换写入gsd-hook-version版本头供gsd-check-update检测过期并补chmod 0o755可执行位。子目录内的.sh若不被处理就同时失去版本戳 可执行位两层保证详见 bin/install.js 的 hook 拷贝循环。五、修复落地白名单、子目录镜像与注册校验changeset 记载的修复共三条主线均能在源码中逐一验证1. 把 hook 加入构建白名单scripts/build-hooks.js 现在在HOOKS_TO_COPY尾部追加了带注释的条目// Graphify auto-update hook (#3347 / PR #3557 / #3579). Opt-in via // .planning/config.json graphify.auto_update; off by default. gsd-graphify-update.sh2. 构建层新增白名单子目录复制scripts/build-hooks.js 新增常量并接入主流程// Subdirectories under hooks/ whose contents must also ship to dist. Each // entry is copied as hooks/dir/* → hooks/dist/dir/* so detached // helpers (e.g. hooks/lib/gsd-graphify-rebuild.sh) resolve from the hooks // installed runtime path. See #3579. const HOOKS_SUBDIRS_TO_COPY [lib];构建主循环scripts/build-hooks.js随后会针对lib递归readdirSync(srcDir, { withFileTypes: true })仅复制文件条目复用与顶层一致的语法校验 → staging → rename 原子替换逻辑并将.sh的可执行位在首次可观察前就置好chmodSync(stagedDest, 0o755)。产物因此变为hooks/dist/gsd-graphify-update.shhooks/dist/lib/gsd-graphify-rebuild.sh。3. 安装层镜像子目录到目标bin/install.js 对readdirSync(hooksSrc)得到的目录条目分支处理一层递归进入lib/将每个文件镜像写入目标hooks/lib/对.sh同样执行版本占位符替换与可执行位设置。这样 hook 在安装环境里通过dirname $0上溯后拼接lib/gsd-graphify-rebuild.sh的REBUILD_SCRIPT定位就始终成立。此外bin/install.js 的安装后校验清单expectedShHooks同步纳入了gsd-graphify-update.sh缺失时给出非致命警告而 hook 的settings.json注册分支bin/install.js也只有在目标文件真实存在时才往 PostToolUse 事件推送matcher: Bash的配置条目否则会打印Skipped graphify auto-update hook — gsd-graphify-update.sh not found at target。三条防线相互印证避免文件缺失但注册成功或文件在但未注册的隐性半残状态。六、防回归coverage drift guard 与回归测试网changeset 强调最后补上了一道coverage drift guard此后hooks/顶层每个*.sh都必须出现在HOOKS_TO_COPY中杜绝再次出现新增 hook 忘登记、静默不发版。这道防线体现在回归测试上tests/graphify-visualization.test.cjs 新增了#3579的 Gap 1 与安装两段测试先真实执行build-hooks.js断言每个顶层hooks/*.sh都被物化到hooks/dist/若未来有人忘加白名单此用例会直接列出 missing 文件而失败再断言hooks/dist/gsd-graphify-update.sh与hooks/dist/lib/gsd-graphify-rebuild.sh均存在最后以CLAUDE_CONFIG_DIR指向临时目录的方式跑完整安装流程验证两个文件都落地到目标 hooks 目录且安装输出不再出现 Missing expected hook 或 Skipped graphify auto-update hook 警告。tests/orphaned-hooks.test.cjs 则从另一方向守卫生态gsd-check-update-worker.js的受管 hook 清单必须与build-hooks.js中HOOKS_TO_COPY的 JS 条目一致避免运行时更新器与发布清单产生认知分裂。历史回归基线 tests/bug-1834-sh-hooks-installed.test.cjs 早已验证三类社区.shhook 的部署、可执行位与expectedShHooks告警覆盖——#3579 相当于把同类保障平移到 graphify hook 与lib/辅助脚本上。七、从 Bug 中沉淀的工程原则回顾 #3579可以归纳出三条可复用的发布工程经验显式白名单需要配套全量覆盖断言只要发布采用 allowlist就必然引入漏登记这一风险类别必须用测试把源目录实际文件 ⊆ 白名单固化为不可绕过的约束路径寻址的辅助文件必须与主文件同步镜像凡 hook 通过相对路径dirname $0上溯加载兄弟辅助脚本构建与安装两层都必须保留目录结构否则会出现顶层文件在、运行期依赖缺失的隐蔽故障版本戳与可执行位是.shhook 的隐形契约安装层对.sh的{{GSD_VERSION}}替换与0o755处理不可省略否则更新器无法识别过期 hook、运行时直接以不可执行文件启动而报错。对使用者而言本修复是透明的升级到包含 #3579 的版本后重新执行npx get-shit-done-cc --claude --global或对应运行时参数即可在~/.claude/hooks/看到gsd-graphify-update.sh与hooks/lib/gsd-graphify-rebuild.sh只有当你需要让提交自动驱动知识图谱重建时才需在.planning/config.json中显式开启graphify.enabled: true与graphify.auto_update: true其余场景 hook 始终保持零成本空转。【免费下载链接】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),仅供参考
返回列表