文件,三臺(tái)系統(tǒng),零改動(dòng):Superpowers 的 Polyglot 跨平臺(tái) Hook 是怎么做到的)
一個(gè)文件,三臺(tái)系統(tǒng),零改動(dòng):Superpowers 的 Polyglot 跨平臺(tái) Hook 是怎么做到的【免費(fèi)下載鏈接】superpowersAn agentic skills framework software development methodology that works.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/su/superpowersSuperpowers 的 hooks 目錄里藏著一個(gè)很實(shí)用的跨平臺(tái)技巧:借助 polyglot(多語(yǔ)言)腳本,讓同一條 SessionStart hook 在 Windows、macOS 和 Linux 上都能跑,不用為不同系統(tǒng)維護(hù)兩套命令。如果你是那種經(jīng)常在三臺(tái)設(shè)備之間切來(lái)切去、又給 Claude Code 插件寫過(guò)鉤子腳本的人,這套寫法值得花十分鐘拆開看看。先從一個(gè)真實(shí)的翻車現(xiàn)場(chǎng)說(shuō)起你剛給插件寫了一個(gè) SessionStart hook,在 Mac 上測(cè)試一切正常:會(huì)話啟動(dòng)時(shí)注入技能說(shuō)明,省得每次手動(dòng)貼。然后你換到一臺(tái) Windows 機(jī)器上開工。事情開始不對(duì)勁:.sh文件被當(dāng)成普通文本,雙擊直接彈開記事本;鉤子命令里帶引號(hào)的路徑被 CMD 的引號(hào)規(guī)則剝掉一層,解析報(bào)錯(cuò);更坑的是手動(dòng)在終端里跑腳本沒問(wèn)題,作為 hook 就靜悄悄不執(zhí)行——這種沒有報(bào)錯(cuò)的失敗,排查起來(lái)最耗時(shí)。問(wèn)題不在你的腳本邏輯,而在 Windows 上根本不存在直接跑.sh這件事:CMD 不認(rèn)識(shí)$VAR,路徑是反斜杠,而就算裝了 Git Bash,bash也未必在 PATH 里。Superpowers 的解法不是給每個(gè)系統(tǒng)寫一份腳本,而是用一個(gè)文件同時(shí)喂飽 CMD 和 bash。一句話定位Superpowers 是一個(gè) agentic 技能框架 開發(fā)方法論,它的 hook 子系統(tǒng)用了一個(gè)多語(yǔ)言派發(fā)器加無(wú)擴(kuò)展名鉤子腳本的組合,把Windows 上跑 bash 鉤子這件臟活全包了:插件照常工作,鉤子在三個(gè)系統(tǒng)上都生效,找得到 bash 就執(zhí)行,找不到就安靜跳過(guò),不會(huì)把整個(gè)插件帶崩。原理拆解:一扇門,兩條暗道先看派發(fā)器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} $可以把它想象成一扇門,門牌上貼著兩種語(yǔ)言寫的告示:bash 走這條道。對(duì) Unix shell 來(lái)說(shuō),:是一個(gè)什么都不做的空命令,而 CMDBLOCK啟動(dòng)了一個(gè) here 文檔。于是從echo off到exit /b 0的整塊 CMD 內(nèi)容,全被當(dāng)成 here 文檔的數(shù)據(jù)吞掉,一個(gè)字都不會(huì)執(zhí)行。文檔結(jié)束標(biāo)記CMDBLOCK出現(xiàn)后,shell 繼續(xù)往下走,執(zhí)行底部真正的 Unix 邏輯。CMD 走那條道。CMD 把第一行: CMDBLOCK看成一個(gè)無(wú)害的標(biāo)簽,然后開始逐行執(zhí)行后面的批處理命令:確定腳本目錄、查找 bash、調(diào)用鉤子。最后exit /b直接退出批處理,后面的 Unix 代碼它永遠(yuǎn)看不到。同一份字節(jié),兩種解釋器,各走各的暗道,互不干擾。這就是 polyglot 包裝器的核心。Windows 那一半還做了兩件事值得注意:按順序找 bash:先試C:\Program Files\Git\bin\bash.exe,再試C:\Program Files (x86)下的,最后where bash找 PATH(覆蓋 MSYS2、Cygwin 等安裝方式);找不到就exit /b 0:不報(bào)錯(cuò)、不中斷,插件繼續(xù)正常工作,只是跳過(guò)這次上下文注入。寧可靜默降級(jí),也不讓鉤子把宿主應(yīng)用搞壞。一個(gè)容易被忽略的細(xì)節(jié):腳本為什么沒有 .sh 后綴倉(cāng)庫(kù)里的鉤子腳本叫session-start,不是session-start.sh。這不是命名潔癖,而是防一個(gè)具體行為:Claude Code 在 Windows 上會(huì)給任何命令里含.sh的條目自動(dòng)前置bash,等于繞過(guò)你的派發(fā)器自己跑,結(jié)果就是鉤子看起來(lái)不生效。所以這套方案是成對(duì)生效的:派發(fā)器統(tǒng)一入口:hooks/run-hook.cmd鉤子腳本無(wú)擴(kuò)展名:session-start配置文件指向派發(fā)器并傳腳本名hooks/hooks.json里的對(duì)應(yīng)配置長(zhǎng)這樣(路徑加了引號(hào),因?yàn)?{CLAUDE_PLUGIN_ROOT}可能含空格):{ type: command, command: \${CLAUDE_PLUGIN_ROOT}/hooks/run-hook.cmd\ session-start, shell: bash }其中shell: bash也值得說(shuō)一句:它強(qiáng)制走 Git Bash 路線。如果機(jī)器上沒裝 Git Bash,你會(huì)收到一個(gè)請(qǐng)安裝 Git for Windows的可執(zhí)行提示,而不是一條莫名其妙的 shell 解析錯(cuò)誤。快速上手:三步跑起來(lái)第一步,克隆倉(cāng)庫(kù)(Windows 上同樣適用):git clone https://gitcode.com/GitHub_Trending/su/superpowers第二步,打開三個(gè)文件,把入口—派發(fā)—邏輯的關(guān)系對(duì)上號(hào):hooks/hooks.json— 聲明鉤子事件和派發(fā)命令hooks/run-hook.cmd— polyglot 派發(fā)器,跨平臺(tái)入口hooks/session-start— 真正的鉤子邏輯,純 bash第三步,驗(yàn)證行為。倉(cāng)庫(kù)自帶測(cè)試腳本tests/hooks/test-session-start.sh,改完派發(fā)器或鉤子后跑一遍,確認(rèn)三個(gè)平臺(tái)的輸出格式(JSON 注入內(nèi)容)沒被破壞。如果你的插件要加新鉤子,不用復(fù)制派發(fā)器——把run-hook.cmd的邏輯抄進(jìn)自己的插件,新鉤子只需要一個(gè)無(wú)擴(kuò)展名腳本,命令里多傳一個(gè)參數(shù)就行。進(jìn)階模式:把派發(fā)器當(dāng)可復(fù)用組件用run-hook.cmd的用法是run-hook.cmd 腳本名 [參數(shù)...],腳本名取自第一個(gè)參數(shù)。這意味著一個(gè)插件有 N 個(gè)鉤子,也只需要這一個(gè)派發(fā)文件,每個(gè)鉤子各自維護(hù)一段 bash 邏輯。hooks-cursor.json里就是這么復(fù)用的:同一個(gè)派發(fā)命令,Cursor 側(cè)只換了事件名的寫法。寫這些無(wú)擴(kuò)展名 bash 腳本時(shí),項(xiàng)目里有幾條經(jīng)驗(yàn)可以直接抄:優(yōu)先用 bash 內(nèi)建命令。鉤子不以登錄 shell(-l)方式運(yùn)行,PATH 里有什么全看宿主環(huán)境。session-start里做 JSON 轉(zhuǎn)義就沒碰sed/awk,而是用純參數(shù)替換:s${s//\\/\\\\} s${s//\/\\\} s${s//$\n/\\n}逐類字符替換、只靠?jī)?nèi)建語(yǔ)法,哪個(gè)系統(tǒng)上都成立。所有變量展開都加引號(hào):$VAR;命令替換用$(...)而不是反引號(hào);輸出用printf。別依賴登錄 shell 的環(huán)境。鉤子環(huán)境和你手動(dòng)開終端的環(huán)境不是一回事,這正是終端里能跑、當(dāng)鉤子就不行的常見根源。改動(dòng)派發(fā)器之后,以hooks/run-hook.cmd的代碼為準(zhǔn)去對(duì)照文檔,再跑一次測(cè)試,這是項(xiàng)目里寫明的維護(hù)約定。避坑排查:三個(gè)看起來(lái)沒壞的假象現(xiàn)象一:Windows 上鉤子靜默不執(zhí)行,連個(gè)報(bào)錯(cuò)都沒有。原因:派發(fā)器三個(gè)位置都沒找到 bash,按設(shè)計(jì)exit /b 0退出了。這是靜默降級(jí)的正常行為,不是你的 bug。 解法:把 Git for Windows 裝到標(biāo)準(zhǔn)路徑,或確保bash在 PATH 里(比如你裝了 MSYS2/Cygwin)。現(xiàn)象二:Linux 上正常,Windows 上什么都不做。八成是腳本文件名帶了.sh擴(kuò)展名,觸發(fā)了 Windows 側(cè)的自動(dòng)前置邏輯,派發(fā)路徑被繞開了。 解法:鉤子腳本一律去掉擴(kuò)展名,hooks.json里的命令參數(shù)同步改成無(wú)擴(kuò)展名。現(xiàn)象三:任何系統(tǒng)上鉤子都不觸發(fā)。這通常是事件名對(duì)不上:Claude Code 的 matcher 是startup|clear|compact,Cursor 用的是sessionStart。 解法:核對(duì)hooks.json里的 matcher 和你所用宿主實(shí)際發(fā)出的事件名,兩個(gè)平臺(tái)的差異在hooks/hooks.json與hooks/hooks-cursor.json里可以直接對(duì)照。還有一個(gè)通用技巧:懷疑是環(huán)境問(wèn)題時(shí),別猜。模擬鉤子的執(zhí)行環(huán)境手動(dòng)跑一遍派發(fā)命令,再跑tests/hooks/test-session-start.sh,大多數(shù)時(shí)好時(shí)壞的問(wèn)題會(huì)在復(fù)現(xiàn)的瞬間露出馬腳。回到開頭那臺(tái) Windows 機(jī)器再回到開頭那個(gè)場(chǎng)景:同一條 SessionStart hook,現(xiàn)在在你同事的 Windows 機(jī)器上也會(huì)準(zhǔn)時(shí)注入上下文了——沒有雙份腳本,沒有平臺(tái)判斷,沒有這臺(tái)機(jī)器再試一次。Superpowers 這套 polyglot 派發(fā)器加無(wú)擴(kuò)展名腳本的寫法,核心收益就一句話:鉤子邏輯只寫一遍,bash 找不到就優(yōu)雅退出,找得到就在任何系統(tǒng)上準(zhǔn)時(shí)執(zhí)行。如果你也在做多平臺(tái) Claude Code 插件,hooks/目錄下的這三個(gè)文件值得逐行讀一遍,比任何跨平臺(tái)教程都短,而且全是能直接抄的生產(chǎn)實(shí)現(xiàn)。【免費(fèi)下載鏈接】superpowersAn agentic skills framework software development methodology that works.項(xiàng)目地址: https://gitcode.com/GitHub_Trending/su/superpowers創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考