c2638668e3
leo 2026-08-20:「同一個 plugin 你用,薄殼也用,保證兩邊同步」
「我要你幫雲端做薄殼,永遠都有問題,你要做的就是這組設定
你自己可以 dogfooding」
搬進來:41 支 hook(51 條註冊)/7 支 command/2 支 skill/23 支腳本。
不搬 .env、wiki、docs——那些是知識不是環境。
51 條 hook 路徑全部從 $CLAUDE_PROJECT_DIR/.claude/hooks/ 改成 ${CLAUDE_PLUGIN_ROOT}/hooks/,
零漏網。那正是薄殼一直壞掉的根:雲端 cwd 不是真身,寫死路徑就斷。
尚未驗證:Claude Code 能不能從私有 Gitea repo 裝 marketplace(要憑證)。
下一步就是在本機實際裝一次,通了才動雲端 bootstrap.sh。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
86 lines
4.0 KiB
Bash
Executable File
86 lines
4.0 KiB
Bash
Executable File
#!/bin/sh
|
|
# browser-verify-guard.sh — Stop hook:**宣稱驗過前端,卻沒有真的用瀏覽器載一次 → 擋**。
|
|
#
|
|
# 🔴 leo 2026-08-08:「**你的環境有 web,你應該用 web 驗,你已經開啓了卻沒有完成,
|
|
# 你要把這個列入規定。**」
|
|
#
|
|
# 病根(同日實撞,leo 抓到而不是我發現):
|
|
# 我「驗前端」的方式是 `curl | grep` 找一個字串——文案在就宣稱通過。
|
|
# 但 **curl 拿到的是 HTML 原始碼:它不執行 JS、不載入 config.js、不發 API 請求**。
|
|
# 於是使用者真正看到的整條紅色錯誤
|
|
# 「設定檔沒載入(config.js),這個頁面連不到你的服務」,**我一次都沒看到**。
|
|
# ⇒ 判準升級:`HTTP 200 不算驗過` → `grep 到字串也不算驗過`
|
|
# → **只有「瀏覽器載入後看起來能用」才算**。
|
|
#
|
|
# 機制:這回合若出現「前端驗過」類宣稱,就要求同一回合真的用過瀏覽器工具。
|
|
# 有 curl 沒有瀏覽器 ⇒ exit 2。
|
|
#
|
|
# 逃生口:這次真的沒有前端可驗(純後端/純腳本)⇒ 在回覆裡明說「本次無前端」,
|
|
# 本 hook 認得這句話就放行——留痕,不是默默略過。
|
|
set -eu
|
|
|
|
TURN="$(cat 2>/dev/null | python3 -c '
|
|
import sys, json
|
|
buf = []
|
|
try:
|
|
d = json.load(sys.stdin)
|
|
t = d.get("transcript_path") or ""
|
|
if t:
|
|
import io, os
|
|
if os.path.exists(t):
|
|
for line in open(t, encoding="utf-8", errors="ignore").readlines()[-40:]:
|
|
try:
|
|
m = json.loads(line)
|
|
except Exception:
|
|
continue
|
|
c = (m.get("message") or {}).get("content")
|
|
if isinstance(c, list):
|
|
for b in c:
|
|
if not isinstance(b, dict):
|
|
continue
|
|
if b.get("type") == "text":
|
|
buf.append(b.get("text", ""))
|
|
elif b.get("type") == "tool_use":
|
|
buf.append(b.get("name", ""))
|
|
buf.append(json.dumps(b.get("input", {}), ensure_ascii=False))
|
|
elif isinstance(c, str):
|
|
buf.append(c)
|
|
except Exception:
|
|
pass
|
|
print("\n".join(buf))
|
|
' 2>/dev/null || echo "")"
|
|
[ -z "$TURN" ] && exit 0
|
|
|
|
# 有沒有「前端/畫面驗過」的宣稱?
|
|
printf '%s' "$TURN" | grep -qiE '前端(驗|測|複驗|確認)|畫面(驗|確認|複驗)|用戶.{0,6}看到的|驗前端|抓實際畫面' || exit 0
|
|
|
|
# 明說沒有前端 ⇒ 放行(留痕)
|
|
printf '%s' "$TURN" | grep -qE '本次無前端|沒有前端可驗|純後端|不涉及前端' && exit 0
|
|
|
|
# 真的用過瀏覽器嗎?
|
|
printf '%s' "$TURN" | grep -qE 'Claude_Browser__(preview_start|navigate|computer|get_page_text|read_console_messages)' && exit 0
|
|
|
|
cat >&2 <<'EOF'
|
|
🖥️ 前端驗證警察:你宣稱驗了畫面,但**這回合沒有用過瀏覽器**。
|
|
|
|
【leo 2026-08-08】「**你的環境有 web,你應該用 web 驗,你已經開啓了卻沒有完成。**」
|
|
|
|
【為什麼 curl | grep 不算】curl 拿到的是 **HTML 原始碼**——
|
|
它**不執行 JS、不載入 config.js、不發 API 請求**。
|
|
08-08 實撞:我 grep 到文案就說「前端驗過」,
|
|
而使用者實際看到的是整條紅色「設定檔沒載入(config.js)」——**那個畫面我一次都沒看到**。
|
|
|
|
改用這三步(看畫面,不是看原始碼):
|
|
mcp__Claude_Browser__preview_start {url: "<用戶會走的網址>"}
|
|
mcp__Claude_Browser__computer {action: "screenshot"}
|
|
mcp__Claude_Browser__read_console_messages {onlyErrors: true}
|
|
|
|
要看的是:有沒有錯誤橫幅/資料是不是還卡在「載入中…」/console 有沒有紅字。
|
|
|
|
⚠️ 順帶:用 curl 查線上狀態時,`?cb=$RANDOM` **繞不掉 Cloudflare 邊緣快取**——
|
|
要加 `-H "Cache-Control: no-cache"`,否則你可能是在驗快取而不是驗線上。
|
|
|
|
本次真的沒有前端可驗 ⇒ 在回覆裡明說「本次無前端」即放行。
|
|
EOF
|
|
exit 2
|