jiantw83 0c83495ba8 fix(version-guard): 把 jsc-ask:ask 與 jsc-gitea:wiki 加進豁免清單
What:版本守門 hook 的豁免清單新增 jsc-ask:ask 與 jsc-gitea:wiki 兩支技能,並在檔頭註解補上理由。

Why:jsc-cli:deploy 要問使用者 install/update/uninstall,一定會呼叫 jsc-ask:ask;ask 問完又一定寫回 wiki 才算完成。這兩支只要版本落後就被擋下,訊息還指回 /jsc-cli:deploy,deploy 卡在問不出模式那一步,形成死鎖,跟直接擋 deploy 是同一種問題。

How:在 case "$skill" 的豁免比對加上 jsc-ask:ask 與 jsc-gitea:wiki 兩個樣式,維持原本 exit 0 的略過行為;檔頭豁免清單註解同步補上兩條說明,講清楚死鎖成因。

Who:hooks/version-guard.sh 的外掛版本守門功能,影響 jsc-cli:deploy 的部署流程。
2026-08-26 18:40:11 +08:00
2026-08-21 04:42:09 +00:00

jsc-hooks — 跨 CLI Hooks

jsc 技能組的 hooks domain:所有 hook 只放在這個 repo(技能準則)。腳本為 POSIX shell,同時支援 stdin JSON(Claude 格式)與環境變數輸入,適用 claude / codex / copilot / antigravity / kiro。

安裝、更新、移除

Marketplace 統一為 jsc(https://gitea.jsc.idv.tw/plugins/meta.git),安裝 token 為 jsc-hooks@jsc。每個指令一行:

CLI 安裝 更新 移除
claude claude plugin marketplace add https://gitea.jsc.idv.tw/plugins/meta.git && claude plugin install jsc-hooks@jsc claude plugin marketplace update jsc && claude plugin update jsc-hooks@jsc claude plugin uninstall jsc-hooks@jsc
codex codex plugin marketplace add https://gitea.jsc.idv.tw/plugins/meta.git && codex plugin add jsc-hooks@jsc codex plugin marketplace upgrade jsc codex plugin remove jsc-hooks@jsc
copilot copilot plugin marketplace add https://gitea.jsc.idv.tw/plugins/meta.git && copilot plugin install jsc-hooks@jsc copilot plugin marketplace update jsc && copilot plugin update jsc-hooks@jsc copilot plugin uninstall jsc-hooks@jsc
antigravity git clone https://gitea.jsc.idv.tw/plugins/hooks.git ~/plugins/hooks && agy plugin install ~/plugins/hooks git -C ~/plugins/hooks pull && agy plugin uninstall jsc-hooks && agy plugin install ~/plugins/hooks agy plugin uninstall jsc-hooks
kiro kiro-cli plugin marketplace add https://gitea.jsc.idv.tw/plugins/meta.git && kiro-cli plugin install jsc-hooks@jsc kiro-cli plugin marketplace update jsc && kiro-cli plugin update jsc-hooks@jsc kiro-cli plugin uninstall jsc-hooks@jsc

antigravity 不支援 gitea URL 安裝,改用本地 clone 路徑。批次操作五個 CLI:使用 /jsc-cli:deploy。

舊入口 plugins/jsc 已移除,marketplace 正本移到 plugins/meta。marketplace 名稱仍是 jsc(取自 marketplace.json 的 name 欄位,與存取庫名無關),安裝 token 不變;已從舊入口安裝過的人先執行 claude plugin marketplace remove jsc,再依上表重新 add。

Hooks

腳本 事件 作用
hooks/ste100-guard.sh UserPromptSubmit 注入 STE100 繁體中文輸出規則(hook > prompt 強制層)
hooks/session-timer.sh SessionStart / Stop / SessionEnd 記錄工作階段起訖。子指令:start 記起始時間(已有紀錄就不動,給 claude 這種每階段有自己 session id 的 CLI)、restart 一律覆寫起始時間(給接不到 session id 的 kiro,不覆寫會把上一階段算進來)、mark 更新最後活動時間、report 供 jsc-log:worklog 取花費時間
hooks/version-guard.sh PreToolUse(Skill) 技能使用前的版本前置檢查:本機實際載入版本落後遠端發佈版本就以 exit 2 擋下該次呼叫並提示更新指令(更新指令依當前 CLI 給)。只擋落後這一種情況:超前放行(開發技能組時本機本來就會超前),讀不到本機版本、推導不出站台、查不到遠端版本也一律放行。逃生門 JSC_VERSION_GUARD=off。豁免 jsc-cli:deploy、jsc-hooks:hooks-install、jsc-cli:models、jsc-meta:*
hooks/skill-usage.sh PostToolUse(Skill) 記錄技能使用與呼叫鏈到 $JSC_HOME/usage/*.jsonl,供 jsc-log:stats 統計
hooks/sdlc-gate.sh UserPromptSubmit、PreToolUse(Skill) SDLC 階段能力標籤閘門與模型鎖:lock {stage} 由 jsc-sdlc 階段技能呼叫,從 transcript 讀出實際模型 id 比對該階段必要標籤($JSC_HOME/model-tags.tsv),不符就拒絕上鎖;check 在模型不符時以 exit 2 擋下該輪提示(其他 hook 一律 exit 0,此處是刻意例外);unlock 為逃生門。另含工作包 PR 閘門:wp-lock {owner}/{repo} {index} 記下一筆未結清的工作包 PR、wp-unlock {owner}/{repo} {index} 結清那一筆(檔案不存在也算成功)、wp-report 印出所有未結清、wp-check {prompt|skill} 為 hook 模式。狀態檔一個工作包一支,在 $JSC_HOME/wp/{owner}-{repo}-{index}.pr,刻意不綁 session——PR 沒合併時換一個工作階段照樣要擋;一個工作包一支鎖檔是為了讓好幾個互不相依的工作包能同時記在案,不會互相覆蓋掉對方的鎖。wp-check prompt 只注入提醒、絕不擋提示(擋了連「去修那支 PR」的對話都送不出去);wp-check skill 在有未結清 PR 時以 exit 2 擋下 plan、analyze、maintain,但一律放行 implement(結清 PR 正是 implement 的步驟,擋它會鎖死流程)——這一層是整個存取庫共用的粗粒度提醒,「某個候選工作包能不能挑」的細粒度判斷在 jsc-sdlc/tools/wp-gate.sh check-deps,不是這裡。逃生門 JSC_WP_GATE=off。這道閘門只讀檔案、不打網路,PR 的真實合併狀態由 jsc-sdlc/tools/wp-gate.sh 查證

Claude 由 hooks/hooks.json 自動接線五支 hook;其他 CLI 用 hooks-install 技能接線、改裝包裝啟動器,或降級為規則檔。

覆蓋範圍要據實看待:只有 claude 同時有 PreToolUse 與 UserPromptSubmit,五支 hook 全接得上,回報 wired。codex、copilot、antigravity、kiro 都沒有 pre-tool hook,接不上 version-guard.sh 的版本前置檢查,SDLC 模型鎖也只剩技能步驟檢查,這四個 CLI 一律回報 degraded,靠 /jsc-cli:deploy 定期更新。codex 另外沒有工作階段開始事件,計時改由 tools/jsc-wrap.sh 的 codex 別名在啟動當下開始;沒走別名啟動時,時間從第一輪回應算起。

version-guard.sh report 是非 hook 的子指令:印出每個已安裝 jsc plugin 的 「{domain} {本機} {遠端} {落後|最新|超前|查詢失敗}」,最後一行 behind {落後個數}。 本機沒有 Claude 的 plugin 註冊檔時改印 noregistry {路徑} 再接 behind 0, 代表這台機器無法做版本檢查,跟「全部最新」是兩件事。查遠端版本走與 hook 同一份快取 與同一個 JSC_VERSION_TTL,一次部署不會為每個 domain 各打一輪網路。 jsc-cli:deploy 用它決定要不要把「更新」設成推薦選項。

工具

腳本 用途
tools/jsc-wrap.sh 沒有完整 hook 系統的 CLI 的包裝啟動器:匯出 JSC_CLI、JSC_SESSION_ID,前後接 session-timer.sh,結束時自動跑 scan-logs.sh 回填。JSC_CLI 存 CLI 代號,實際執行的是對應的執行檔(antigravity 是 agy、kiro 是 kiro-cli)
tools/scan-logs.sh 離線回填:解析 copilot、antigravity、codex 的原生日誌,把技能用量與階段界線補進 $JSC_HOME,重掃不重複
tools/report-error.sh 失敗回報流程:把一筆 hook 或工具異常寫成 wiki 的 ERROR_{HASH},並在 ERROR_CONTENTS 附上一列索引。wiki 位置由 jsc-gitea 的 gitea.sh wiki-repo ERROR 解析,解析不出來就安靜降級。由操作者手動執行,或由 hooks-install 在 wire-cli.sh 回報 status=failed 時執行;不接在失敗的 hook 上自動觸發(hook 一律安靜 exit 0,自我回報會疊出迴圈)
tools/wire-cli.sh 單一 CLI 的 hook 生命週期,共三個用法。{cli} 是接線:對應的設定編輯、包裝別名安裝、hook 檔建立,皆以 <!-- jsc-hooks -->(或 # jsc-hooks)標記整段重寫,重跑等同先移除再重裝;寫完每個檔案會重讀驗證位置正確才回報成功(codex 的 notify 必須是根層鍵、kiro 的 JSON 必須成對且 on、run 在最上層),以 status=wired|degraded|skipped|failed 回報。purge {cli} 是移除:把該 CLI 的所有 hook 清掉,含非 jsc 的第三方項目,動到的檔案先原樣備份到 $JSC_HOME/backup/hooks/{cli}/{yyyyMMdd_HHmmss}/,備份失敗就不移除,移除後重讀驗證,驗不過自動還原備份,以 status=purged|skipped|failed 回報。smoke {cli} 是執行期冒煙測試:五支 hook 各跑一次,非零退出即為錯誤(唯一例外是 sdlc-gate.sh check 的 exit 2,那是階段鎖的設計行為),以 status=ok|failed 回報。status {cli} 是唯讀盤點:只讀設定檔判斷標記段落在不在,不寫檔也不執行 hook,每個接線點印一行 item<TAB>{項目}<TAB>{路徑}<TAB>{present|missing},以 status=wired|degraded|unwired|skipped 回報(結束碼 0、1、5、3)。體檢類技能(/jsc-cli:doctor)只能用這個子命令,另外三個都會動到環境
tools/scan-hook-errors.sh 掃 CLI 原生紀錄找 hook 的執行期錯誤(接線寫對、跑起來出錯)。只有 claude 有 hook 結果紀錄,掃 ~/.claude/projects/**/*.jsonl 的 hook_non_blocking_error 與非空 hookErrors;codex、copilot、antigravity、kiro 沒有等價紀錄,一律回報 unavailable 並指向 wire-cli.sh smoke {cli}。每筆錯誤附加一行 JSON 到 $JSC_HOME/errors/hooks.jsonl,jsc 欄位標明是不是 jsc 自己的 hook(第三方 hook 的錯誤只回報,不由 jsc 修正);去重與 scan-logs.sh 同法,重掃只讀新增段落,以 status=clean|errors|unavailable 回報

失敗回報範本

這兩個模板是失敗回報頁的文案來源,由 tools/report-error.sh 填欄位後寫進 wiki。 用法:tools/report-error.sh --hook {名稱} --exit {碼} --summary {摘要},錯誤輸出摘要走標準輸入。

範本 用途
templates/error-page.md 單筆 hook 異常頁 ERROR_{HASH},記錄當次失敗的觸發條件、錯誤摘要與處理結果。
templates/error-contents.md 異常目錄 ERROR_CONTENTS,彙整所有異常頁,方便先看最新問題再往下追。

Skills 目錄

呼叫方式:Claude / Antigravity /jsc-hooks:{name};Codex ${name};Copilot / Kiro 描述需求自動觸發。

hooks-install

把五支 hook 接線到所有已安裝的 CLI,每個 CLI 走四道關卡:先 tools/wire-cli.sh purge {cli} 備份後移除所有 hook(含非 jsc 的第三方項目,乾淨起跑才分得清後續失敗是誰的),再 tools/wire-cli.sh {cli} 接線(claude 由 hooks.json 自動接線,無需寫入),接著 tools/wire-cli.sh smoke {cli} 驗執行期,最後 tools/scan-hook-errors.sh --cli {cli} 掃原生紀錄。codex、copilot、antigravity 由接線腳本裝上 tools/jsc-wrap.sh 包裝別名補上計時與用量回填(結束時自動跑 tools/scan-logs.sh),語言規則仍重寫到各自的規則檔(以 <!-- jsc-hooks --> 標記整段取代,等同先移除再重裝,不重複追加)。codex、copilot、antigravity、kiro 的 SDLC 模型鎖降級為技能步驟檢查,鎖檔仍由 SDLC 技能直接呼叫 sdlc-gate.sh lock 寫入;這四個 CLI 沒有 pre-tool hook,版本前置檢查接不上,腳本會在 reason 裡講明,只有 claude 回報 wired,也只有 claude 掃得到執行期錯誤紀錄。任一關卡出錯(purge、接線、冒煙失敗,或掃到 jsc=true 的執行期錯誤)就先寫 ERROR_{HASH},再交給 repair 技能接手並以 develop PR 收尾;此時允許中止剩下的安裝,但修正一定要開始。掃到 jsc=false 的第三方 hook 錯誤只回報,不轉修正。

repair

接手 hooks-install 或 report-error.sh 留下的失敗:讀 ERROR_{HASH} 與相關檔案後,把診斷拆給安裝中的其他 AI agent CLI 當 sub agent,彙整建議修正、實作 hooks repo 的修補、同步 manifest,最後以 develop 為基底開 PR。只有在真的沒有可用 CLI 時,才退回主 agent 自己判讀。

環境變數

變數 用途 未設定時
JSC_HOME Hook 資料目錄 預設 ~/.jsc
JSC_WIKI_REPO_ERROR ERROR_CONTENTS、ERROR_{HASH} 所在的 {owner}/{repo} 退回 JSC_WIKI_REPO
JSC_WIKI_REPO 未逐類設定時的共用 wiki {owner}/{repo} tools/report-error.sh 安靜降級,不寫 wiki
JSC_CLAUDE_SETTINGS_DIR tools/wire-cli.sh purge claude 要清 hooks 鍵的設定檔目錄。指向一份複製品就能完整測過刪鍵邏輯,不必拿使用者本人的設定檔當測試場 預設 ~/.claude
JSC_VERSION_GUARD 設 off 完全略過版本前置檢查(離線工作用) 啟用檢查
JSC_VERSION_TTL 遠端版本查詢的快取秒數 預設 600
JSC_WP_GATE 設 off 完全略過工作包 PR 閘門(wp-check 一律放行) 啟用閘門
JSC_CLI / JSC_SESSION_ID / JSC_SKILL / JSC_TOOL_NAME 非 Claude CLI 接線時由 tools/jsc-wrap.sh 或接線設定提供,代替 stdin JSON 的 session_id、skill、tool_name(version-guard.sh 也收沒有前綴的 SKILL、TOOL_NAME) 安靜降級
JSC_MODEL 非 Claude CLI 的目前模型,供 sdlc-gate.sh 比對;優先序在 transcript 實際值與 stdin model 之後 改讀 ~/.claude/settings.json,再不行就安靜降級

相關 domain

  • jsc-cli:CLI 偵測(tools/detect-clis.sh)
  • jsc-log:讀取本 domain 產出的工時與用量資料
S
Description
No description provided
Readme
2.4 MiB
Languages
Shell 100%