#!/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