feat(doctor): 納入 skill 與 hook 實測

This commit is contained in:
2026-08-28 16:31:06 +08:00
parent bfd01f71c4
commit f7be015934
4 changed files with 108 additions and 36 deletions
+94 -24
View File
@@ -3,7 +3,7 @@
# 用法:
# test-clis.sh [cli...]
# 輸出(TSV):
# test<TAB>{cli}<TAB>{test}<TAB>{指令}<TAB>{結束碼}<TAB>{判定}<TAB>{說明}
# test<TAB>{area}<TAB>{cli}<TAB>{test}<TAB>{指令}<TAB>{結束碼}<TAB>{判定}<TAB>{說明}
# summary<TAB>{ok}<TAB>{warn}<TAB>{fail}<TAB>{skipped}
# 判定:
# ok 實際命令成功
@@ -37,9 +37,9 @@ cli_bin() {
esac
}
emit() { # cli test command code verdict detail
printf 'test\t%s\t%s\t%s\t%s\t%s\t%s\n' "$1" "$2" "$3" "$4" "$5" "$6"
case "$5" in
emit() { # area cli test command code verdict detail
printf 'test\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' "$1" "$2" "$3" "$4" "$5" "$6" "$7"
case "$6" in
ok) ok_count=$((ok_count + 1)) ;;
warn) warn_count=$((warn_count + 1)) ;;
fail) fail_count=$((fail_count + 1)) ;;
@@ -63,7 +63,9 @@ run_capture() { # $@=command
return 0
}
run_required() { # cli test command...
run_required() { # area cli test command...
area=$1
shift
cli=$1
test_name=$2
shift 2
@@ -72,15 +74,17 @@ run_required() { # cli test command...
code=$RUN_CODE
detail=$RUN_TEXT
if [ "$code" -eq 0 ]; then
emit "$cli" "$test_name" "$cmd_text" "$code" ok "$detail"
emit "$area" "$cli" "$test_name" "$cmd_text" "$code" ok "$detail"
elif [ "$code" -eq 124 ]; then
emit "$cli" "$test_name" "$cmd_text" "$code" fail "命令逾時(${TIMEOUT_SECONDS} 秒)"
emit "$area" "$cli" "$test_name" "$cmd_text" "$code" fail "命令逾時(${TIMEOUT_SECONDS} 秒)"
else
emit "$cli" "$test_name" "$cmd_text" "$code" fail "$detail"
emit "$area" "$cli" "$test_name" "$cmd_text" "$code" fail "$detail"
fi
}
run_optional() { # cli test command...
run_optional() { # area cli test command...
area=$1
shift
cli=$1
test_name=$2
shift 2
@@ -89,11 +93,11 @@ run_optional() { # cli test command...
code=$RUN_CODE
detail=$RUN_TEXT
if [ "$code" -eq 0 ]; then
emit "$cli" "$test_name" "$cmd_text" "$code" ok "$detail"
emit "$area" "$cli" "$test_name" "$cmd_text" "$code" ok "$detail"
elif [ "$code" -eq 124 ]; then
emit "$cli" "$test_name" "$cmd_text" "$code" fail "命令逾時(${TIMEOUT_SECONDS} 秒)"
emit "$area" "$cli" "$test_name" "$cmd_text" "$code" fail "命令逾時(${TIMEOUT_SECONDS} 秒)"
else
emit "$cli" "$test_name" "$cmd_text" "$code" warn "$detail"
emit "$area" "$cli" "$test_name" "$cmd_text" "$code" warn "$detail"
fi
}
@@ -102,32 +106,98 @@ has_cli() {
"$DETECT" | awk -F '\t' -v name="$name" '$1 == name { found = 1 } END { exit found ? 0 : 1 }'
}
latest_dir() {
for pat in "$@"; do
# shellcheck disable=SC2086
ls -d $pat 2>/dev/null | sort | tail -n1
done | tail -n1
}
claude_plugin_root() {
reg="$HOME/.claude/plugins/installed_plugins.json"
[ -f "$reg" ] || return 1
tr -d '\n' < "$reg" \
| sed -n 's/.*"jsc-cli@jsc"[[:space:]]*:[[:space:]]*\[[^]]*"installPath"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' \
| head -n1
}
skill_root() {
case "$1" in
claude) claude_plugin_root ;;
codex) latest_dir "$HOME/.codex/plugins/cache/jsc/jsc-cli"/* ;;
copilot) printf '%s\n' "$HOME/.copilot/installed-plugins/jsc/jsc-cli" ;;
antigravity) latest_dir "$HOME/.antigravity"/*/jsc-cli "$HOME/.config/antigravity"/*/jsc-cli ;;
kiro) printf '%s\n' "$HOME/.kiro/skills/jsc-cli" ;;
*) return 1 ;;
esac
}
skill_file() {
root=$(skill_root "$1" 2>/dev/null || true)
[ -n "$root" ] || return 1
for f in "$root/skills/doctor/SKILL.md" "$root/doctor/SKILL.md"; do
[ -f "$f" ] && { printf '%s\n' "$f"; return 0; }
done
return 1
}
hooks_wire() {
if [ -n "${JSC_HOOKS_TOOLS:-}" ] && [ -f "$JSC_HOOKS_TOOLS/wire-cli.sh" ]; then
printf '%s\n' "$JSC_HOOKS_TOOLS/wire-cli.sh"
return 0
fi
for f in "$HERE/../../hooks/tools/wire-cli.sh" "$HOME/.codex/plugins/cache/jsc/jsc-hooks"/*/tools/wire-cli.sh "$HOME/.claude/plugins/cache/jsc/jsc-hooks"/*/tools/wire-cli.sh "$HOME/.copilot/installed-plugins/jsc/jsc-hooks/tools/wire-cli.sh"; do
[ -f "$f" ] && { printf '%s\n' "$f"; return 0; }
done
return 1
}
test_skill() {
cli=$1
if f=$(skill_file "$cli" 2>/dev/null); then
emit skill "$cli" doctor-skill "$f" 0 ok "找到 doctor SKILL.md"
else
emit skill "$cli" doctor-skill "jsc-cli doctor skill" "-" fail "找不到已安裝的 doctor SKILL.md"
fi
}
test_hooks() {
cli=$1
if wire=$(hooks_wire 2>/dev/null); then
run_required hook "$cli" hook-smoke sh "$wire" smoke "$cli"
else
emit hook "$cli" hook-smoke "wire-cli.sh smoke $cli" "-" skipped "找不到 wire-cli.sh"
fi
}
test_one() {
cli=$1
bin=$(cli_bin "$cli") || usage
path=$(command -v "$bin" 2>/dev/null || true)
if [ -z "$path" ]; then
emit "$cli" executable "$bin" "-" skipped "未偵測到執行檔"
emit cli "$cli" executable "$bin" "-" skipped "未偵測到執行檔"
return 0
fi
case "$cli" in
antigravity)
run_required "$cli" version "$path" --version
run_optional "$cli" help "$path" --help
run_required "$cli" plugin-list "$path" plugin list
run_required cli "$cli" version "$path" --version
run_optional cli "$cli" help "$path" --help
run_required cli "$cli" plugin-list "$path" plugin list
;;
kiro)
run_required "$cli" version "$path" --version
run_optional "$cli" help "$path" --help-all
run_optional "$cli" plugin-list "$path" plugin list
run_required cli "$cli" version "$path" --version
run_optional cli "$cli" help "$path" --help-all
run_optional cli "$cli" plugin-list "$path" plugin list
;;
*)
run_required "$cli" version "$path" --version
run_optional "$cli" help "$path" --help
run_required "$cli" plugin-list "$path" plugin list
run_required cli "$cli" version "$path" --version
run_optional cli "$cli" help "$path" --help
run_required cli "$cli" plugin-list "$path" plugin list
;;
esac
test_skill "$cli"
test_hooks "$cli"
}
if [ "$#" -eq 0 ]; then
@@ -135,7 +205,7 @@ if [ "$#" -eq 0 ]; then
fi
if [ "$#" -eq 0 ]; then
emit all executable "-" "-" skipped "未偵測到任何支援的 CLI"
emit cli all executable "-" "-" skipped "未偵測到任何支援的 CLI"
printf 'summary\t%s\t%s\t%s\t%s\n' "$ok_count" "$warn_count" "$fail_count" "$skipped_count"
exit 0
fi
@@ -147,7 +217,7 @@ for cli in "$@"; do
test_one "$cli"
else
bin=$(cli_bin "$cli") || usage
emit "$cli" executable "$bin" "-" skipped "未偵測到執行檔"
emit cli "$cli" executable "$bin" "-" skipped "未偵測到執行檔"
fi
;;
*) usage ;;