fix(meta): 補齊稽核缺失並修掉護欄失效

What:依 jsc-meta:skill-check 的稽核結果修正技能與工具——補上每個步驟的可檢核完成條件、
把留在內文的標準輸入輸出流程下放 tools/、修正查表與退碼路由造成的誤判。

Why:稽核發現這些缺失會讓技能在實際執行時走錯分支或靜默通過。
完成條件缺漏是最常被違反的一項;退碼誤判與查表錯誤則會讓良性狀況被當成失敗。

How:逐項對照 references/guidelines.md 的審核檢查清單修正,新增的工具都有
documented exit codes,並以真實執行驗證每條路徑。

Who:jsc-meta:skill-check 例行稽核(2026-08-25)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-25 14:58:54 +08:00
co-authored by Claude Opus 5
parent 287e3ff113
commit 9ab5b42864
12 changed files with 490 additions and 51 deletions
+77
View File
@@ -0,0 +1,77 @@
#!/usr/bin/env sh
# verify-skill-removed.sh — 刪除技能後,實地檢查各 CLI 的磁碟上有沒有殘留。
#
# 用法: verify-skill-removed.sh <domain> <skill-name>
#
# 行為: 先用 jsc-cli/tools/detect-clis.sh 找出已安裝的 CLI,再逐一 grep 該 CLI 的技能快取
# 與 hook 設定,找技能名稱字面與指令形式 /jsc-{domain}:{name}。
# 未安裝的 CLI 不檢查;設定位置不存在就跳過(安靜降級,不算殘留)。
#
# 檢查位置(每個 CLI 的技能快取與 hook 設定):
# claude — ~/.claude/plugins/、~/.claude/settings.json、~/.claude/settings.local.json
# codex — ${CODEX_HOME:-~/.codex}/(config.toml 的 notify、AGENTS.md、plugins/)
# copilot — ~/.config/copilot/
# antigravity — ~/.antigravity/、~/.config/antigravity/
# kiro — ~/.kiro/、工作目錄的 .kiro/hooks/
#
# 輸出: 檢查過的位置一行一個(stderr),殘留一行一個 {file}:{line}:{內容}(stdout)。
# 沒有殘留會印「無殘留」到 stderr,區別於「什麼都沒檢查」。
# 結束碼: 0=沒有殘留 1=有殘留 2=用法錯誤 3=沒偵測到任何 CLI 或找不到可檢查的位置
set -u
usage() {
echo 'usage: verify-skill-removed.sh <domain> <skill-name>' >&2
exit 2
}
[ "$#" -eq 2 ] || usage
DOMAIN=$1
SKILL=$2
[ -n "$DOMAIN" ] && [ -n "$SKILL" ] || usage
HERE=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
ROOT="${JSC_PLUGINS_ROOT:-$(CDPATH= cd -- "$HERE/../.." && pwd)}"
DETECT=""
for d in "$ROOT/cli/tools/detect-clis.sh" "$ROOT/jsc-cli/tools/detect-clis.sh"; do
[ -f "$d" ] && { DETECT="$d"; break; }
done
[ -n "$DETECT" ] || { echo "找不到 detect-clis.sh:請先取得 jsc-cli 存取庫" >&2; exit 3; }
CLIS=$(sh "$DETECT" 2>/dev/null | cut -f1)
[ -n "$CLIS" ] || { echo "沒偵測到任何已安裝的 CLI,無處可查" >&2; exit 3; }
cli_paths() { # $1=CLI 代號;印出該 CLI 的技能快取與 hook 設定位置
case "$1" in
claude)
printf '%s\n' "$HOME/.claude/plugins" "$HOME/.claude/settings.json" \
"$HOME/.claude/settings.local.json" ;;
codex)
printf '%s\n' "${CODEX_HOME:-$HOME/.codex}" ;;
copilot)
printf '%s\n' "$HOME/.config/copilot" ;;
antigravity)
printf '%s\n' "$HOME/.antigravity" "$HOME/.config/antigravity" ;;
kiro)
printf '%s\n' "$HOME/.kiro" "./.kiro" ;;
esac
}
checked=0
hit=0
for cli in $CLIS; do
for p in $(cli_paths "$cli"); do
[ -e "$p" ] || continue
checked=$((checked + 1))
echo "檢查 $cli:$p" >&2
out=$(grep -rnI --exclude-dir=.git -e "$SKILL" -e "/jsc-${DOMAIN}:${SKILL}" "$p" 2>/dev/null)
if [ -n "$out" ]; then
printf '%s\n' "$out"
hit=1
fi
done
done
[ "$checked" -gt 0 ] || { echo "偵測到 CLI,但沒有任何設定位置存在,無處可查" >&2; exit 3; }
[ "$hit" -eq 0 ] && echo "無殘留:已檢查 $checked 個位置" >&2
exit $hit