ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

一个文件,三台系统,零改动:Superpowers 的 Polyglot 跨平台 Hook 是怎么做到的

一个文件,三台系统,零改动:Superpowers 的 Polyglot 跨平台 Hook 是怎么做到的 一个文件,三台系统,零改动:Superpowers 的 Polyglot 跨平台 Hook 是怎么做到的【免费下载链接】superpowersAn agentic skills framework software development methodology that works.项目地址: https://gitcode.com/GitHub_Trending/su/superpowersSuperpowers 的 hooks 目录里藏着一个很实用的跨平台技巧:借助 polyglot(多语言)脚本,让同一条 SessionStart hook 在 Windows、macOS 和 Linux 上都能跑,不用为不同系统维护两套命令。如果你是那种经常在三台设备之间切来切去、又给 Claude Code 插件写过钩子脚本的人,这套写法值得花十分钟拆开看看。先从一个真实的翻车现场说起你刚给插件写了一个 SessionStart hook,在 Mac 上测试一切正常:会话启动时注入技能说明,省得每次手动贴。然后你换到一台 Windows 机器上开工。事情开始不对劲:.sh文件被当成普通文本,双击直接弹开记事本;钩子命令里带引号的路径被 CMD 的引号规则剥掉一层,解析报错;更坑的是手动在终端里跑脚本没问题,作为 hook 就静悄悄不执行——这种没有报错的失败,排查起来最耗时。问题不在你的脚本逻辑,而在 Windows 上根本不存在直接跑.sh这件事:CMD 不认识$VAR,路径是反斜杠,而就算装了 Git Bash,bash也未必在 PATH 里。Superpowers 的解法不是给每个系统写一份脚本,而是用一个文件同时喂饱 CMD 和 bash。一句话定位Superpowers 是一个 agentic 技能框架 开发方法论,它的 hook 子系统用了一个多语言派发器加无扩展名钩子脚本的组合,把Windows 上跑 bash 钩子这件脏活全包了:插件照常工作,钩子在三个系统上都生效,找得到 bash 就执行,找不到就安静跳过,不会把整个插件带崩。原理拆解:一扇门,两条暗道先看派发器hooks/run-hook.cmd的开头几行:: CMDBLOCK echo off set HOOK_DIR%~dp0 ... exit /b 0 CMDBLOCK SCRIPT_DIR$(cd $(dirname $0) pwd) exec bash ${SCRIPT_DIR}/${SCRIPT_NAME} $可以把它想象成一扇门,门牌上贴着两种语言写的告示:bash 走这条道。对 Unix shell 来说,:是一个什么都不做的空命令,而 CMDBLOCK启动了一个 here 文档。于是从echo off到exit /b 0的整块 CMD 内容,全被当成 here 文档的数据吞掉,一个字都不会执行。文档结束标记CMDBLOCK出现后,shell 继续往下走,执行底部真正的 Unix 逻辑。CMD 走那条道。CMD 把第一行: CMDBLOCK看成一个无害的标签,然后开始逐行执行后面的批处理命令:确定脚本目录、查找 bash、调用钩子。最后exit /b直接退出批处理,后面的 Unix 代码它永远看不到。同一份字节,两种解释器,各走各的暗道,互不干扰。这就是 polyglot 包装器的核心。Windows 那一半还做了两件事值得注意:按顺序找 bash:先试C:\Program Files\Git\bin\bash.exe,再试C:\Program Files (x86)下的,最后where bash找 PATH(覆盖 MSYS2、Cygwin 等安装方式);找不到就exit /b 0:不报错、不中断,插件继续正常工作,只是跳过这次上下文注入。宁可静默降级,也不让钩子把宿主应用搞坏。一个容易被忽略的细节:脚本为什么没有 .sh 后缀仓库里的钩子脚本叫session-start,不是session-start.sh。这不是命名洁癖,而是防一个具体行为:Claude Code 在 Windows 上会给任何命令里含.sh的条目自动前置bash,等于绕过你的派发器自己跑,结果就是钩子看起来不生效。所以这套方案是成对生效的:派发器统一入口:hooks/run-hook.cmd钩子脚本无扩展名:session-start配置文件指向派发器并传脚本名hooks/hooks.json里的对应配置长这样(路径加了引号,因为${CLAUDE_PLUGIN_ROOT}可能含空格):{ type: command, command: \${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\ session-start, shell: bash }其中shell: bash也值得说一句:它强制走 Git Bash 路线。如果机器上没装 Git Bash,你会收到一个请安装 Git for Windows的可执行提示,而不是一条莫名其妙的 shell 解析错误。快速上手:三步跑起来第一步,克隆仓库(Windows 上同样适用):git clone https://gitcode.com/GitHub_Trending/su/superpowers第二步,打开三个文件,把入口—派发—逻辑的关系对上号:hooks/hooks.json— 声明钩子事件和派发命令hooks/run-hook.cmd— polyglot 派发器,跨平台入口hooks/session-start— 真正的钩子逻辑,纯 bash第三步,验证行为。仓库自带测试脚本tests/hooks/test-session-start.sh,改完派发器或钩子后跑一遍,确认三个平台的输出格式(JSON 注入内容)没被破坏。如果你的插件要加新钩子,不用复制派发器——把run-hook.cmd的逻辑抄进自己的插件,新钩子只需要一个无扩展名脚本,命令里多传一个参数就行。进阶模式:把派发器当可复用组件用run-hook.cmd的用法是run-hook.cmd 脚本名 [参数...],脚本名取自第一个参数。这意味着一个插件有 N 个钩子,也只需要这一个派发文件,每个钩子各自维护一段 bash 逻辑。hooks-cursor.json里就是这么复用的:同一个派发命令,Cursor 侧只换了事件名的写法。写这些无扩展名 bash 脚本时,项目里有几条经验可以直接抄:优先用 bash 内建命令。钩子不以登录 shell(-l)方式运行,PATH 里有什么全看宿主环境。session-start里做 JSON 转义就没碰sed/awk,而是用纯参数替换:s${s//\\/\\\\} s${s//\/\\\} s${s//$\n/\\n}逐类字符替换、只靠内建语法,哪个系统上都成立。所有变量展开都加引号:$VAR;命令替换用$(...)而不是反引号;输出用printf。别依赖登录 shell 的环境。钩子环境和你手动开终端的环境不是一回事,这正是终端里能跑、当钩子就不行的常见根源。改动派发器之后,以hooks/run-hook.cmd的代码为准去对照文档,再跑一次测试,这是项目里写明的维护约定。避坑排查:三个看起来没坏的假象现象一:Windows 上钩子静默不执行,连个报错都没有。原因:派发器三个位置都没找到 bash,按设计exit /b 0退出了。这是静默降级的正常行为,不是你的 bug。 解法:把 Git for Windows 装到标准路径,或确保bash在 PATH 里(比如你装了 MSYS2/Cygwin)。现象二:Linux 上正常,Windows 上什么都不做。八成是脚本文件名带了.sh扩展名,触发了 Windows 侧的自动前置逻辑,派发路径被绕开了。 解法:钩子脚本一律去掉扩展名,hooks.json里的命令参数同步改成无扩展名。现象三:任何系统上钩子都不触发。这通常是事件名对不上:Claude Code 的 matcher 是startup|clear|compact,Cursor 用的是sessionStart。 解法:核对hooks.json里的 matcher 和你所用宿主实际发出的事件名,两个平台的差异在hooks/hooks.json与hooks/hooks-cursor.json里可以直接对照。还有一个通用技巧:怀疑是环境问题时,别猜。模拟钩子的执行环境手动跑一遍派发命令,再跑tests/hooks/test-session-start.sh,大多数时好时坏的问题会在复现的瞬间露出马脚。回到开头那台 Windows 机器再回到开头那个场景:同一条 SessionStart hook,现在在你同事的 Windows 机器上也会准时注入上下文了——没有双份脚本,没有平台判断,没有这台机器再试一次。Superpowers 这套 polyglot 派发器加无扩展名脚本的写法,核心收益就一句话:钩子逻辑只写一遍,bash 找不到就优雅退出,找得到就在任何系统上准时执行。如果你也在做多平台 Claude Code 插件,hooks/目录下的这三个文件值得逐行读一遍,比任何跨平台教程都短,而且全是能直接抄的生产实现。【免费下载链接】superpowersAn agentic skills framework software development methodology that works.项目地址: https://gitcode.com/GitHub_Trending/su/superpowers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表