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:
185
.claude/commands/review.md
Normal file
185
.claude/commands/review.md
Normal 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> 替換為實際數值)
|
||||
|
||||
---
|
||||
|
||||
## 階段 1:Agent 路由規則
|
||||
|
||||
依 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 個獨立 Agent(Phase A),vuln-verifier 為條件觸發的 Phase B。
|
||||
|
||||
---
|
||||
|
||||
## 階段 2:Phase 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 → error;CAUTION → warn;APPROVED → info
|
||||
|
||||
---
|
||||
|
||||
## 階段 3:Phase 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 → error;CAUTION → warn;APPROVED → 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
45
scripts/tg_notify.sh
Executable 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"
|
||||
Reference in New Issue
Block a user