Files
ISEP/scripts/test-isep-doctor-live.sh
T
Leo fbc56b9e59 isep-doctor 判準改成「每一個 Claude Code 自己回報有沒有載入」,不再看設定長相(inkstone/ISEP#150 → c6995)
同一台 Mac 有 CLI 與 Desktop 內建兩個 Claude Code,讀同一份 ~/.claude 卻不一定同結論:
settings 多了 path 時 Desktop 2.1.266 忽略 inkstone marketplace、CLI 2.1.220 照常載入(c6991)。
第一版看到 path 就對整台判 ,在 CLI 上是假陽性。

- 逐一找 CLI(PATH)與 Desktop(最新版本,數字排序),各跑 plugin list --json,依 errors 各判各的
- 設定比對只在某一個真的報錯時當解釋+修法,永遠不單獨判 
- 查不了 ⇒ ◐、離開碼 2,不講成 
- test-isep-doctor.sh 離線 11 條(假 claude 可執行檔);舊版跑這份 pass=1 fail=10
- test-isep-doctor-live.sh 實機 3 條:真的 CLI 2.1.220/Desktop 2.1.266,隔離 HOME 重現有/無 path,不動 ~/.claude
- 盤點表與 plugin.json 描述的腳本數 62→65(這棵樹上實數)

版本號待總管定。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 16:23:40 +08:00

65 lines
4.2 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# 實測:scripts/isep-doctor 對**真的** Claude Code(這台的 CLI 與 Desktop 內建那一份)判得對不對(inkstone/ISEP#150
#
# 不動 ~/.claude:把 inkstone marketplace 與 isep 安裝紀錄複製到 mktemp 的隔離 HOME
# 分別放「有 path」「沒有 path」兩份 settings.json,用真的可執行檔跑 doctor。
# 會打網路:只有 Claude Code 自己可能匿名讀 git.uncle6.meGitea),不碰 GitHub、不寫任何遠端。
#
# 期望(09-13 在 CLI 2.1.220Desktop 2.1.266 上實測過的行為):
# 沒有 path ⇒ 兩個都 ✅,離開碼 0 (真陰性)
# 有 path、Desktop 2.1.266 ⇒ ❌ 並點名 path (真陽性)
# 有 path、CLI 2.1.220 ⇒ ✅,不因設定長相被判 ❌ (舊版 doctor 的假陽性)
# 版本不是這兩個時,該版本那一格印 SKIP(行為可能不同,不假裝驗過)。
set -u
HERE="$(cd "$(dirname "$0")" && pwd)"
R="$HOME/.claude/plugins"
[ -d "$R/cache/inkstone" ] && [ -d "$R/marketplaces/inkstone" ] || { echo "SKIP:這台沒有安裝 isep@inkstone,無從複製"; exit 0; }
CLI=$(command -v claude || true)
DESK=$(ls -d "$HOME/Library/Application Support/Claude/claude-code/"*/claude.app/Contents/MacOS/claude 2>/dev/null \
| python3 -c 'import sys,re;L=[l.strip() for l in sys.stdin if l.strip()];k=lambda p:tuple(int(x) for x in re.search(r"/claude-code/([0-9.]+)/",p).group(1).split(".") if x);print(sorted(L,key=k)[-1] if L else "")')
BINS=""; [ -n "$CLI" ] && BINS="CLI=$CLI"; [ -n "$DESK" ] && BINS="${BINS:+$BINS:}Desktop=$DESK"
[ -n "$BINS" ] || { echo "SKIP:找不到任何 Claude Code"; exit 0; }
vcli=$([ -n "$CLI" ] && "$CLI" --version | awk '{print $1}'); vdesk=$([ -n "$DESK" ] && "$DESK" --version | awk '{print $1}')
echo "CLI=${CLI:-} ${vcli:-}Desktop=${DESK:-} ${vdesk:-}"
T=$(mktemp -d); trap 'rm -rf "$T"' EXIT
C="$T/home/.claude"; mkdir -p "$C/plugins/cache" "$C/plugins/marketplaces"
cp -R "$R/cache/inkstone" "$C/plugins/cache/" && cp -R "$R/marketplaces/inkstone" "$C/plugins/marketplaces/"
python3 - "$R" "$C" <<'EOF'
import json, sys
R, C = sys.argv[1], sys.argv[2]
km = json.load(open(R + "/known_marketplaces.json"))
json.dump({"inkstone": json.loads(json.dumps(km["inkstone"]).replace(R, C + "/plugins"))}, open(C + "/plugins/known_marketplaces.json", "w"))
ip = json.load(open(R + "/installed_plugins.json"))
ip["plugins"] = {"isep@inkstone": ip["plugins"]["isep@inkstone"]}
json.dump(json.loads(json.dumps(ip).replace(R, C + "/plugins")), open(C + "/plugins/installed_plugins.json", "w"))
src = {"source": "git", "url": "https://git.uncle6.me/inkstone/ISEP.git"}
json.dump({"enabledPlugins": {"isep@inkstone": True}, "extraKnownMarketplaces": {"inkstone": {"source": src}}}, open(C + "/settings.nopath.json", "w"))
src["path"] = "/Users/youlinhsieh/Documents/tech_projects/ISEP"
json.dump({"enabledPlugins": {"isep@inkstone": True}, "extraKnownMarketplaces": {"inkstone": {"source": src}}}, open(C + "/settings.path.json", "w"))
EOF
cp -R "$C" "$T/pristine"
pass=0; fail=0; skip=0
doctor() { # settings 變體
rm -rf "$C" && cp -R "$T/pristine" "$C" && cp "$C/settings.$1.json" "$C/settings.json"
OUT=$(cd "$T" && env -u CLAUDE_CODE_CHILD_SESSION HOME="$T/home" ISEP_DOCTOR_CLAUDE_BINS="$BINS" python3 "$HERE/isep-doctor" 2>&1); CODE=$?
echo "── settings=$1exit=$CODE"; printf '%s\n' "$OUT" | sed 's/^/ /'
}
has() { printf '%s' "$OUT" | grep -q -- "$1"; }
judge() { if eval "$2"; then pass=$((pass+1)); echo "ok $1"; else fail=$((fail+1)); echo "FAIL $1"; fi; }
doctor nopath
judge "真陰性:沒有 path → 離開碼 0、沒有 ❌" '[ "$CODE" = 0 ] && ! has "❌"'
doctor path
if [ "$vdesk" = 2.1.266 ]; then
judge "真陽性:Desktop 2.1.266 有 path → ❌ 並點名 path、離開碼 1" '[ "$CODE" = 1 ] && has "❌ Desktop 2.1.266" && has "多了 path"'
else skip=$((skip+1)); echo "SKIP 真陽性:Desktop 是 ${vdesk:-},不是 2.1.266"; fi
if [ "$vcli" = 2.1.220 ]; then
judge "假陽性:CLI 2.1.220 有 path 但實際載入 → ✅" 'has "✅ CLI 2.1.220"'
else skip=$((skip+1)); echo "SKIP 假陽性:CLI 是 ${vcli:-},不是 2.1.220"; fi
echo "pass=$pass fail=$fail skip=$skip"; [ "$fail" = 0 ]