feat(wire-cli): 新增唯讀的接線盤點子命令
What: wire-cli.sh 新增 status 子命令,只讀設定檔判斷 jsc 標記段落在不在,不寫檔也不執行 hook。每個接線點印一行 item,以 status=wired、degraded、unwired、skipped 回報。 Why: 體檢類技能要問「hook 接線在不在」,但既有三個子命令都會動到環境:不帶子命令會重新接線、purge 會刪掉、smoke 會真的執行 hook。體檢不該有副作用。 How: 沿用底下接線區塊的同一組檔案位置與標記字串,共用 has_block、toml_root_key、json_top_key 三個判讀函式。codex 的 notify 另外單獨檢查是否落在根層,標記在、鍵被歸進表裡時 codex 讀不到,等同沒接。 Who: 供 jsc-cli:doctor 呼叫的接線檢查。
This commit is contained in:
+84
-2
@@ -4,6 +4,7 @@
|
||||
# wire-cli.sh {claude|codex|copilot|antigravity|kiro} 接線
|
||||
# wire-cli.sh purge {claude|codex|copilot|antigravity|kiro} 備份後移除該 CLI 的所有 hook
|
||||
# wire-cli.sh smoke {claude|codex|copilot|antigravity|kiro} 跑一輪五支 hook,驗執行期
|
||||
# wire-cli.sh status {claude|codex|copilot|antigravity|kiro} 唯讀盤點接線現況,不寫檔也不執行 hook
|
||||
#
|
||||
# purge 移除的是「所有 hook」,含非 jsc 的第三方項目。安裝一律先 purge 再接線:混著別人的
|
||||
# hook 接線,出錯時分不清是誰的 hook 壞掉,也修不了。移除前每個要動的檔案先原樣複製到
|
||||
@@ -41,6 +42,9 @@
|
||||
# 4=failed(寫入或驗證沒過,接線沒生效;由 hooks-install 呼叫 report-error.sh 回報)
|
||||
# 結束碼(purge): 0=purged 2=用法錯誤 3=skipped 4=failed
|
||||
# 結束碼(smoke): 0=ok 2=用法錯誤 4=failed
|
||||
# 結束碼(status): 0=wired 1=degraded 2=用法錯誤 3=skipped 5=unwired(該接的段落缺了至少一項)
|
||||
# status 之外的動作都會寫檔,體檢類技能(/jsc-cli:doctor)只能呼叫 status。判讀邏輯跟接線
|
||||
# 共用同一組檔案位置與標記字串,分兩份實作就會各自漂移,體檢說沒接、實際上接著。
|
||||
#
|
||||
# JSC_CLAUDE_SETTINGS_DIR 可覆寫 claude 使用者層設定檔目錄(預設 ~/.claude)。
|
||||
# 有這個逃生門才測得動 purge 的 JSON 刪鍵:預設路徑是使用者自己的設定檔,拿真檔案試刪
|
||||
@@ -53,14 +57,14 @@ HOOKS="$ROOT/hooks"
|
||||
. "$HOOKS/lib.sh"
|
||||
|
||||
usage() {
|
||||
echo "用法:wire-cli.sh [purge|smoke] {claude|codex|copilot|antigravity|kiro}" >&2
|
||||
echo "用法:wire-cli.sh [purge|smoke|status] {claude|codex|copilot|antigravity|kiro}" >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
# 第一個參數是子命令時走新流程,否則沿用原本的「wire-cli.sh {cli}」接線。
|
||||
action=wire
|
||||
case "${1:-}" in
|
||||
purge|smoke) action="$1"; shift ;;
|
||||
purge|smoke|status) action="$1"; shift ;;
|
||||
esac
|
||||
|
||||
cli="${1:-}"
|
||||
@@ -620,6 +624,84 @@ if [ "$action" = smoke ]; then
|
||||
exit 4
|
||||
fi
|
||||
|
||||
if [ "$action" = status ]; then
|
||||
# 唯讀盤點:只讀設定檔判斷標記段落在不在,不寫檔,也不執行任何 hook。
|
||||
# 檔案位置與標記字串一律沿用底下接線區塊的同一份值,兩邊必須一起改。
|
||||
command -v "$(cli_bin "$cli")" >/dev/null 2>&1 || skip "未偵測到 $(cli_bin "$cli") 執行檔"
|
||||
st_items=$(mktemp) || { printf 'status=failed reason=%s\n' "無法建立暫存檔"; exit 4; }
|
||||
st_missing=0
|
||||
st_degrade=""
|
||||
|
||||
# 記一個檢查點。$1=項目名 $2=路徑 $3=present|missing
|
||||
st_item() {
|
||||
printf 'item\t%s\t%s\t%s\n' "$1" "$2" "$3" >> "$st_items"
|
||||
[ "$3" = present ] || st_missing=$((st_missing + 1))
|
||||
}
|
||||
|
||||
# 檔案存在且帶有該標記才算接上。$1=項目名 $2=檔案 $3=開頭標記行
|
||||
st_block() {
|
||||
if [ -f "$2" ] && has_block "$2" "$3"; then st_item "$1" "$2" present
|
||||
else st_item "$1" "$2" missing; fi
|
||||
}
|
||||
|
||||
# 別名段落只要任何一個既有 rc 檔帶有標記就算接上。$1=項目名 $2=標記名
|
||||
st_rc_alias() {
|
||||
for _rc in "$HOME/.bashrc" "$HOME/.zshrc" "$HOME/.config/fish/config.fish"; do
|
||||
[ -f "$_rc" ] || continue
|
||||
if has_block "$_rc" "# $2"; then st_item "$1" "$_rc" present; return 0; fi
|
||||
done
|
||||
st_item "$1" "$HOME/.bashrc" missing
|
||||
}
|
||||
|
||||
case "$cli" in
|
||||
claude)
|
||||
if [ -f "$HOOKS/hooks.json" ]; then st_item hooks.json "$HOOKS/hooks.json" present
|
||||
else st_item hooks.json "$HOOKS/hooks.json" missing; fi ;;
|
||||
|
||||
codex)
|
||||
config="${CODEX_HOME:-$HOME/.codex}/config.toml"
|
||||
st_block notify "$config" "# jsc-hooks"
|
||||
# 標記在、鍵卻被歸進某張表時 codex 讀不到 notify,等同沒接,所以位置要單獨算一項
|
||||
if [ -f "$config" ] && toml_root_key "$config" notify; then
|
||||
st_item notify-root "$config" present
|
||||
else
|
||||
st_item notify-root "$config" missing
|
||||
fi
|
||||
st_rc_alias alias jsc-hooks:codex
|
||||
st_block ste100 "${CODEX_HOME:-$HOME/.codex}/AGENTS.md" "<!-- jsc-hooks -->"
|
||||
st_degrade="STE100 降級為 prompt 檔,SDLC 模型鎖降級為技能步驟檢查,無 pre-tool hook 可接版本前置檢查" ;;
|
||||
|
||||
copilot)
|
||||
st_rc_alias alias jsc-hooks:copilot
|
||||
st_block ste100 "${JSC_COPILOT_INSTRUCTIONS:-$HOME/.config/copilot/copilot-instructions.md}" "<!-- jsc-hooks -->"
|
||||
st_degrade="STE100 降級為 prompt 檔,SDLC 模型鎖降級為技能步驟檢查,無 pre-tool hook 可接版本前置檢查" ;;
|
||||
|
||||
antigravity)
|
||||
st_rc_alias alias jsc-hooks:antigravity
|
||||
st_block ste100 "${JSC_ANTIGRAVITY_RULES:-$HOME/.antigravity/AGENTS.md}" "<!-- jsc-hooks -->"
|
||||
st_degrade="STE100 降級為 prompt 檔,SDLC 模型鎖降級為技能步驟檢查,無 pre-tool hook 可接版本前置檢查" ;;
|
||||
|
||||
kiro)
|
||||
# kiro 的 hook 檔綁在工作區,這裡看的一律是目前工作目錄底下那一份
|
||||
for _f in ./.kiro/hooks/jsc-hooks-session-start.json ./.kiro/hooks/jsc-hooks.json; do
|
||||
if [ -f "$_f" ] && json_top_key "$_f" run; then st_item "$(basename "$_f" .json)" "$_f" present
|
||||
else st_item "$(basename "$_f" .json)" "$_f" missing; fi
|
||||
done
|
||||
st_degrade="SDLC 模型鎖降級為技能步驟檢查,無 pre-tool hook 可接版本前置檢查" ;;
|
||||
esac
|
||||
|
||||
if [ "$st_missing" -gt 0 ]; then
|
||||
printf 'status=unwired reason=%s\n' "$st_missing 個接線項目缺漏,執行 /jsc-hooks:hooks-install 重新接線"
|
||||
cat "$st_items"; rm -f "$st_items"; exit 5
|
||||
fi
|
||||
if [ -n "$st_degrade" ]; then
|
||||
printf 'status=degraded reason=%s\n' "$st_degrade"
|
||||
cat "$st_items"; rm -f "$st_items"; exit 1
|
||||
fi
|
||||
printf 'status=wired reason=%s\n' "hooks.json 自動接線全部五支 hook"
|
||||
cat "$st_items"; rm -f "$st_items"; exit 0
|
||||
fi
|
||||
|
||||
case "$cli" in
|
||||
claude)
|
||||
bin=$(cli_bin claude)
|
||||
|
||||
Reference in New Issue
Block a user