feat(review): 新增 /review pre-commit code review slash command

- .claude/commands/review.md: 整合 12 Agent 的 pre-commit review 指令
  + 依 diff 類型路由:critic / db-expert / migration-engineer / tool-expert
  + Phase B 條件觸發 vuln-verifier(critic 發現 🔴 時)
  + ≥10 Python 檔案改派 refactor-specialist 主審
  + 最終判決:BLOCKED / CAUTION / APPROVED

- scripts/tg_notify.sh: Telegram 告警工具
  + 7 個流程節點全部發送告警(啟動/每個 Agent 完成/最終判決)
  + 支援 info/warn/error 三級別 + jq/bash 雙備案解析
  + token 未設定時 exit 0,不阻斷 review 流程

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ogt
2026-04-22 01:23:57 +08:00
parent 0099543c05
commit a45b61f326
2 changed files with 230 additions and 0 deletions

185
.claude/commands/review.md Normal file
View File

@@ -0,0 +1,185 @@
# /review — Pre-Commit Code Review
你是 Code Review 協調員。使用者完成需求實作後、commit 前手動執行此指令,請依以下流程完整執行。**禁止跳過任何節點。**
---
## 階段 0準備與分析
執行以下指令:
```bash
git diff --staged --name-only
git diff --staged --stat
git branch --show-current
```
若 staged 無任何變更,輸出「⚠️ 無 staged 變更,請先 git add 後再執行 /review」並停止。
依變更檔案決定本次審查的 Agent 集合(路由規則見下方)。
---
## Telegram 節點 0審查啟動
執行:
```bash
bash scripts/tg_notify.sh info "<b>🔍 Code Review 啟動</b>
📋 分支:$(git branch --show-current)
📁 Staged 變更:<N> 個檔案
🤖 派出 Agent<agent1>, <agent2>, ...
⏳ 審查進行中,請稍候..."
```
(將 <N> 和 <agent list> 替換為實際數值)
---
## 階段 1Agent 路由規則
依 staged 檔案清單,決定派出哪些 Agent
| 條件 | 觸發 Agent |
|------|-----------|
| 任何 `.py` / `.html` / `.js` 變更 | **critic**(必跑) |
| `migrations/*.sql``database/` 變更 | **db-expert** |
| `requirements.txt` / `Dockerfile` / `docker-compose.yml` 變更 | **migration-engineer** |
| `.claude/hooks/` / `settings.json` / `.claude/` 變更 | **tool-expert** |
| Python 檔案變更 ≥ 10 個 | 改派 **refactor-specialist**(取代 critic 為主審) |
| critic 報告含任何 🔴 Critical | 追加 **vuln-verifier**Phase B序列執行 |
最多同時跑 4 個獨立 AgentPhase Avuln-verifier 為條件觸發的 Phase B。
---
## 階段 2Phase A — 平行派出 Agent
將所有 Phase A Agent **在同一訊息中並行呼叫**(多個 Agent tool call
每個 Agent 的 prompt 必須包含:
1. 完整的 `git diff --staged` 輸出(或相關部分)
2. 明確的輸出格式要求:
- 問題清單附 `file:line`
- 嚴重度分級:🔴 Critical / 🟠 High / 🟡 Medium / 🟢 Low
- 最後一行輸出 `VERDICT: BLOCKED``VERDICT: CAUTION``VERDICT: APPROVED`
**critic prompt 範本**
「審查以下 diff找出安全漏洞、品質問題、反模式。每個問題附 file:line + 嚴重度。最後一行輸出 VERDICT: [BLOCKED/CAUTION/APPROVED]。
diff 內容:[貼入 git diff --staged 輸出]」
**db-expert prompt 範本**
「審查以下 migration/DB 相關 diff找出 schema 問題、危險操作、缺失索引、N+1。最後一行輸出 VERDICT: [BLOCKED/CAUTION/APPROVED]。
diff 內容:[貼入相關 diff]」
**migration-engineer prompt 範本**
「審查以下依賴/Docker 變更,找出破壞性升級、版本衝突、危險設定。最後一行輸出 VERDICT: [BLOCKED/CAUTION/APPROVED]。
diff 內容:[貼入相關 diff]」
**tool-expert prompt 範本**
「審查以下 hook/settings 變更確認安全設定未被削弱、hook 邏輯正確。最後一行輸出 VERDICT: [BLOCKED/CAUTION/APPROVED]。
diff 內容:[貼入相關 diff]」
---
## 階段 2.5:每個 Agent 完成後立即發 Telegram
每個 Agent 完成後,**立即**(不等其他 Agent發送節點通知
```bash
bash scripts/tg_notify.sh <level> "<b>[<AGENT_NAME> 完成]</b>
判決:<VERDICT>
問題:🔴 <n> | 🟠 <n> | 🟡 <n> | 🟢 <n>
摘要:<1 句最嚴重問題,若無則「已查,無異狀」>"
```
level 對應BLOCKED → errorCAUTION → warnAPPROVED → info
---
## 階段 3Phase B — vuln-verifier條件觸發
**只有** critic 報告含 🔴 Critical 才執行此階段。
先發 Telegram
```bash
bash scripts/tg_notify.sh warn "<b>🔬 VULN-VERIFIER 啟動</b>
觸發原因critic 發現 <n> 個 Critical 問題
正在驗證漏洞可利用性..."
```
派出 vuln-verifier Agent傳入 critic 完整報告 + 相關 diff要求輸出
- 每個 🔴 問題是否為真實可利用漏洞confirmed / false-positive
- PoC 描述(若 confirmed
- 最後一行 `VERDICT: BLOCKED``VERDICT: APPROVED`
完成後同樣發節點 Telegram 通知。
---
## 階段 4最終判決聚合
依以下規則計算最終判決:
| 判決 | 條件 |
|------|------|
| 🔴 **BLOCKED** | 任一 Agent 輸出 `VERDICT: BLOCKED`,或 vuln-verifier 確認漏洞可利用 |
| 🟡 **CAUTION** | 無 BLOCKED但有任一 Agent 輸出 `VERDICT: CAUTION` |
| 🟢 **APPROVED** | 所有 Agent 輸出 `VERDICT: APPROVED` |
---
## Telegram 節點 FINAL最終判決
```bash
bash scripts/tg_notify.sh <level> "<b>📊 Code Review 完成</b>
最終判決:<🔴 BLOCKED / 🟡 CAUTION / 🟢 APPROVED>
━━━━━━━━━━━━━━━━━━━━
審查 Agent<list>
耗時:~<N> 分鐘
<若 BLOCKED 或 CAUTION>
🔴 必修項目:
• <問題> @ <file:line>
<若 APPROVED>
✅ 可安全 commit"
```
level 對應BLOCKED → errorCAUTION → warnAPPROVED → info
---
## 終端輸出格式
最後在 terminal 顯示完整報告:
```
## /review 審查報告
### 變更範圍
[staged 檔案清單]
### Agent 判決摘要
- critic: APPROVED / CAUTION / BLOCKED
- db-expert: APPROVED若有執行
- ...
### 最終判決:🔴 BLOCKED / 🟡 CAUTION / 🟢 APPROVED
### 必修清單BLOCKED/CAUTION 時顯示)
- [ ] file:line — 問題描述
### 選修建議APPROVED 時顯示)
- [ ] file:line — 建議描述
```
---
## 注意事項
- Telegram 發送失敗**不阻斷** review 流程(`tg_notify.sh` 內部已處理)
- Agent prompt 必須包含實際 diff 內容,不可只說「請 review 最近的 diff」
- 每個 Agent 完成後立即發 Telegram不等全部完成再批量發送
- `scripts/tg_notify.sh` 路徑相對於專案根目錄,確認存在後才呼叫

45
scripts/tg_notify.sh Executable file
View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bash
# scripts/tg_notify.sh — Code Review Telegram 告警工具
# 用法bash scripts/tg_notify.sh <info|warn|error> "<HTML 訊息>"
set -euo pipefail
LEVEL="${1:-info}"
MESSAGE="${2:-}"
TOKEN="${TELEGRAM_BOT_TOKEN:-}"
CHAT_IDS_RAW="${TELEGRAM_CHAT_IDS:-}"
if [[ -z "$TOKEN" ]]; then
echo "[tg_notify] TELEGRAM_BOT_TOKEN 未設定,跳過通知" >&2
exit 0
fi
if [[ -z "$CHAT_IDS_RAW" ]]; then
echo "[tg_notify] TELEGRAM_CHAT_IDS 未設定,跳過通知" >&2
exit 0
fi
case "$LEVEL" in
info) PREFIX="" ;;
warn) PREFIX="⚠️" ;;
error) PREFIX="🚨" ;;
*) PREFIX="📌" ;;
esac
FULL_MSG="${PREFIX} ${MESSAGE}"
# 解析 CHAT_IDS JSON 陣列
if command -v jq &>/dev/null; then
CHAT_IDS=$(echo "$CHAT_IDS_RAW" | jq -r '.[]' 2>/dev/null)
else
CHAT_IDS=$(echo "$CHAT_IDS_RAW" | tr -d '[]" ' | tr ',' '\n')
fi
while IFS= read -r CHAT_ID; do
[[ -z "$CHAT_ID" ]] && continue
curl -s --max-time 10 -X POST \
"https://api.telegram.org/bot${TOKEN}/sendMessage" \
-d "chat_id=${CHAT_ID}" \
--data-urlencode "text=${FULL_MSG}" \
-d "parse_mode=HTML" > /dev/null || \
echo "[tg_notify] 發送到 ${CHAT_ID} 失敗(不阻斷流程)" >&2
done <<< "$CHAT_IDS"