Files
ewoooc/.claude/hooks/commit-quality.js
ogt 0099543c05
Some checks failed
CD Pipeline / deploy (push) Failing after 5m18s
fix(security): 全域健檢 — 40 項安全/Bug/品質修復
🔴 Critical
- auto_heal_service: 補 import re + sqlalchemy.text + 修正 orchestrator 變數名
  + autoheal_playbook→playbooks 表名 + _alert_and_store cooldown 修復
- aider_heal_executor: shell injection 改 shell=False + list 參數
- docker-compose: DISABLE_LOGIN 改 env var + 移除密碼 fallback + POSTGRES_HOST 修正
- app.py: /api/backup /api/run_task 等 6 個管理 API 加 @login_required
- config.py + pg_sync + e2e_test: 移除 wooo_pg_2026 hardcoded 密碼 fallback
- pg_backup.sh: 移除 TELEGRAM_TOKEN= 中間變數,直接用 $TELEGRAM_BOT_TOKEN
- migration 014: trigger_pattern→match_pattern + 補 error_type NOT NULL 欄位

🟡 High
- telegram_bot_service: str(e) 改通用訊息 + session try/finally + 移除 pa:/pr: 舊 callback
- run_scheduler: ElephantAlpha thread 死亡監控 + 自動重啟 + Telegram 告警
  + agent_context 03:30 TTL 定時清理任務
- openclaw_learning_service: build_rag_context 兩路徑加 .limit(200)
- hooks: commit-quality + momo-prod-guard 空 catch 改 stderr+exit(1)
- scripts/code_review: auto_yes 預設改 false
- db_backup_service: PGPASSWORD 透過 env dict 傳遞

📦 Migrations
- 013_autoheal: 修正建表順序 playbooks→incidents(外鍵前向引用)
- 018_add_missing_indexes: heal_logs/incidents 外鍵索引 + cleanup_expired_agent_context()

🟢 Infrastructure
- requirements.txt: 加版本下界 Flask>=2.3 SQLAlchemy>=1.4 等
- cd.yaml: 新增 run_scheduler.py + run_telegram_bot.py 監聽路徑
- .gitignore: insert_playbook_local.py 加入忽略

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 01:12:23 +08:00

64 lines
2.4 KiB
JavaScript
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.
/**
* commit-quality.js — PreToolUse Hook
* 阻擋 debugger 語句 + 硬編碼 Secret 進入 commit。
* 已針對 momo 環境加入 Telegram/Gemini/Gitea/Anthropic pattern。
*/
const { spawnSync } = require('child_process');
let d = '';
process.stdin.on('data', c => d += c);
process.stdin.on('end', () => {
try {
const i = JSON.parse(d);
const cmd = i.tool_input?.command || '';
if (!/git commit/.test(cmd) || /--amend/.test(cmd)) { process.stdout.write(d); return; }
const r = spawnSync('git', ['diff', '--cached', '--name-only', '--diff-filter=ACMR'], { encoding: 'utf8' });
const files = (r.stdout || '').trim().split('\n').filter(Boolean);
let blocked = false;
for (const f of files) {
if (!/\.(js|jsx|ts|tsx|py|sh|json|yaml|yml)$/.test(f)) continue;
const cr = spawnSync('git', ['show', ':' + f], { encoding: 'utf8' });
const c = cr.stdout || '';
if (/\.(js|jsx|ts|tsx)$/.test(f) && /\bdebugger\b/.test(c)) {
process.stderr.write(`[commit-quality] ERROR: debugger statement in ${f}\n`);
blocked = true;
}
const secrets = [
// 通用 API Keys
[/sk-[a-zA-Z0-9]{20,}/, 'OpenAI API Key'],
[/ghp_[a-zA-Z0-9]{36}/, 'GitHub PAT'],
[/AKIA[A-Z0-9]{16}/, 'AWS Access Key'],
[/AIza[a-zA-Z0-9_-]{35}/, 'Google API Key'],
// momo 專屬
[/\d{8,12}:[A-Za-z0-9_-]{35}/, 'Telegram Bot Token'],
[/TELEGRAM[_\s]*(?:BOT[_\s]*)?TOKEN\s*=\s*["']?[^\s"']{20,}/, 'Telegram Token 環境變數'],
[/GEMINI_API_KEY\s*=\s*["']?[A-Za-z0-9_-]{20,}/, 'Gemini API Key'],
[/sk-ant-api[0-9a-zA-Z_-]{20,}/, 'Anthropic API Key'],
[/glpat-[a-zA-Z0-9_-]{20}/, 'Gitea/GitLab PAT'],
[/GITEA[_\s]*TOKEN\s*=\s*["']?[^\s"']{20,}/, 'Gitea Token 環境變數'],
];
for (const [pattern, label] of secrets) {
if (pattern.test(c)) {
process.stderr.write(`[commit-quality] ERROR: 偵測到 ${label} in ${f}\n`);
blocked = true;
}
}
}
if (blocked) {
process.stderr.write('[commit-quality] Commit 已阻擋。請移除上述敏感資訊後重試。\n');
process.exit(2);
}
} catch (e) {
process.stderr.write(`[commit-quality] hook internal error: ${e.message}\n`);
// Hook 內部錯誤不應阻擋 commit但要留下記錄
// 若希望更保守(阻擋),改為 process.exit(1)
}
process.stdout.write(d);
});