ARTICLE DETAIL

资讯详情

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

从“bash 找不到了“到三地通跑:Superpowers 跨平台 Polyglot 钩子实现

从“bash 找不到了“到三地通跑:Superpowers 跨平台 Polyglot 钩子实现 从bash 找不到了到三地通跑Superpowers 跨平台 Polyglot 钩子实现【免费下载链接】superpowersAn agentic skills framework software development methodology that works.项目地址: https://gitcode.com/GitHub_Trending/su/superpowersSuperpowers 是一个为 Claude Code 打造的 agentic 技能框架内置头脑风暴、计划编写、子代理驱动开发等一整套开发工作流技能。本文以 SessionStart 钩子为例讲清楚它如何用一份 polyglot 调度脚本让同一段钩子逻辑在 Windows、macOS、Linux 上不加修改地直接运行。钩子在 Windows 上是怎么坏的三层报错叠加把一段 bash 钩子原样拿到 Windows 上跑通常会连环踩中三个坑执行不了CMD.exe 不认.sh是脚本常直接把它丢给文本编辑器引号解析失败Windows 的回退 shell 对引号开头的路径 后续裸词这类命令串解析规则与 POSIX 不同路径里含括号等元字符时外层引号会被吃掉找不到 bash即便装了 Git BashCMD 运行时 PATH 里往往没有 bash直接报bash is not recognized。Claude Code 侧的应对是在钩子配置里声明shell: bash2.1.81 起支持强制走 Git Bash 通道。但脚本文件本身仍然要同时被两种 shell 正确理解。一份文件两种解释Polyglot 的原理CMD 和 bash 如何各取所需polyglot 调度脚本利用的是一个语法巧合文件首行: CMDBLOCK在 bash 里是空命令 here-doc会把后面整个 CMD 批处理块吞掉CMD.exe 则把它当作标签继续往下执行批处理命令。同一份文件两条互不干扰的执行路径。hooks/run-hook.cmd的结构大致如下: CMDBLOCK echo off REM Windows 分支从调度脚本自身位置定位 hooks 目录 set HOOK_DIR%~dp0 if exist C:\Program Files\Git\bin\bash.exe ( C:\Program Files\Git\bin\bash.exe %HOOK_DIR%%~1 exit /b %ERRORLEVEL% ) REM 此处省略x86 安装目录、PATH 中的 bash、以及未找到时的静默退出 exit /b 0 CMDBLOCK # Unix 分支上面的批处理块已被 here-doc 整体消费 SCRIPT_DIR$(cd $(dirname $0) pwd) SCRIPT_NAME$1 shift exec bash ${SCRIPT_DIR}/${SCRIPT_NAME} $无扩展名也不再用 cygpath两个容易被忽略的设计决定钩子脚本一律无扩展名session-start而非session-start.sh因为 Claude Code 在 Windows 上会给任何路径含.sh的命令自动前缀bash会破坏调度器早期写法靠cygpath转路径、用-l起登录 shell当前实现直接把 Windows 路径交给 bash 原生处理钩子脚本自身保证可独立运行。对应的取舍是三处都找不到 bash 时批处理分支exit /b 0静默退出——插件不报错只是跳过这次钩子注入。调度器模式run-hook.cmd 的三级查找Windows 上找 bash 的三处位置CMD 执行批处理分支时先用%~dp0从调度脚本自己的位置解析出 hooks 目录再按顺序尝试三处 bashC:\Program Files\Git\bin\bash.exe、C:\Program Files (x86)\Git\bin\bash.exe以及 PATH 中的bash覆盖 MSYS2、Cygwin 和非默认安装位置的 Git。命中即执行指定的无扩展名钩子脚本并用exit /b %ERRORLEVEL%把退出码原样传出。仓库中的文件结构与配置整个模式只需要三个文件hooks/hooks.json指向调度器hooks/run-hook.cmd是跨平台入口session-start是真正的钩子逻辑。下面这份 hooks.json 是仓库里的真实配置注意脚本名没有扩展名、路径整体加了引号CLAUDE_PLUGIN_ROOT可能含空格{ hooks: { SessionStart: [ { matcher: startup|clear|compact, hooks: [ { type: command, command: \${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\ session-start, shell: bash, async: false } ] } ] } }钩子脚本的可移植写法约定不依赖外部工具的 JSON 转义示例真实逻辑放在无扩展名脚本里。session-start展示了如何零外部命令JSON 转义靠 bash 参数替换两趟完成不碰 sed、awk比逐字符循环快几个数量级# 纯内置转义每个 ${s//old/new} 都是一次整体替换 escape_for_json() { local s$1 s${s//\\/\\\\} s${s//\/\\\} s${s//$\n/\\n} printf %s $s }推荐 / 避免清单推荐优先纯 bash 内置命令用$(command)而非反引号变量扩展一律带引号$VAR推荐跨平台输出按环境变量区分字段——该脚本按CURSOR_PLUGIN_ROOT/CLAUDE_PLUGIN_ROOT/COPILOT_CLI切换三种 JSON 结构避免同一平台读到重复字段避免依赖需要登录 shell PATH 的外部工具钩子不是以-l方式启动的避免给钩子脚本加.sh后缀会触发 Windows 侧的前缀行为。 钩子不生效时的排查清单四种最常见的失效现象Windows 上钩子静默不跑大概率是 bash 三处都没找到调度器按设计静默退出。装上 Git for Windows 或把 bash 放进 PATH 即可bash is not recognizedbash 不在上述标准位置也不在 PATH确认实际安装目录后更新hooks/run-hook.cmd中的路径终端里能跑、作为钩子跑不了Claude Code 以独立环境运行钩子。先手动设置CLAUDE_PLUGIN_ROOT等环境变量再用cmd /c以相同参数模拟执行复现真实环境改动调度器后跑tests/hooks/test-session-start.sh验证再合入。改调度器时不要抄文档里的代码直接读hooks/run-hook.cmd源码——仓库文档也明确以这份实现为准。【免费下载链接】superpowersAn agentic skills framework software development methodology that works.项目地址: https://gitcode.com/GitHub_Trending/su/superpowers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表