This repository has been archived on 2026-03-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
AIMisc/code-quality-system/hooks/auto-complete-check.py
T
2026-01-30 00:42:33 +08:00

194 lines
6.7 KiB
Python

#!/usr/bin/env python3
"""
自动完成检查 Hook
拦截任务结束,执行代码质量检查
"""
import json
import sys
import os
from pathlib import Path
# 导入模块
sys.path.insert(0, str(Path(__file__).parent))
from requirements_tracker import generate_requirement_checklist, save_checklist
from code_analyzer import analyze_code_quality, calculate_completeness_score
from notification_sender import notify_check_result
def load_iteration_tracker(project_root):
"""加载迭代计数器"""
tracker_file = Path(project_root) / '.claude' / 'iteration-tracker.json'
if tracker_file.exists():
with open(tracker_file, 'r', encoding='utf-8') as f:
return json.load(f)
return {}
def update_iteration_count(project_root, task_id, increment=True):
"""更新迭代计数"""
tracker = load_iteration_tracker(project_root)
if task_id not in tracker:
tracker[task_id] = 0
if increment:
tracker[task_id] += 1
# 保存
tracker_file = Path(project_root) / '.claude' / 'iteration-tracker.json'
tracker_file.parent.mkdir(parents=True, exist_ok=True)
with open(tracker_file, 'w', encoding='utf-8') as f:
json.dump(tracker, f, ensure_ascii=False, indent=2)
return tracker[task_id]
def reset_iteration_count(project_root, task_id):
"""重置迭代计数(任务完成时)"""
return update_iteration_count(project_root, task_id, increment=False)
def generate_fix_requirements(issues, requirements_checklist):
"""生成修复要求"""
fix_requirements = []
# 从代码问题生成修复要求
if issues['todo']:
fix_requirements.append(f"- 处理 {len(issues['todo'])} 个 TODO/FIXME 项")
if issues['empty_functions']:
fix_requirements.append(f"- 实现以下空函数: {', '.join([f'{i[\"file\"]}:{i[\"line\"]}' for i in issues['empty_functions'][:3]])}")
if issues['placeholders']:
fix_requirements.append(f"- 移除或实现占位符代码 ({len(issues['placeholders'])} 处)")
if issues['commented_code']:
fix_requirements.append(f"- 清理或取消注释代码 ({len(issues['commented_code'])} 处)")
# 从需求清单生成修复要求
unverified = [r for r in requirements_checklist.get('requirements', []) if not r.get('verified', False)]
if unverified:
fix_requirements.append(f"- 验证以下需求已完成:\n " + "\n ".join([f"{i+1}. {r['description']}" for i, r in enumerate(unverified[:5])]))
return "\n".join(fix_requirements) if fix_requirements else "未发现明显问题,建议人工审查"
def perform_quick_check(project_root, task_id, conversation_context=''):
"""执行快速检查"""
# 1. 生成需求检查清单
requirements_checklist = generate_requirement_checklist(project_root, conversation_context)
save_checklist(requirements_checklist, task_id, project_root)
# 2. 代码质量分析
analysis_result = analyze_code_quality(project_root)
score = analysis_result['score']
issues = analysis_result['issues']
# 3. 检查逻辑
passed = score >= 80
critical_issues = len(issues['empty_functions']) + len(issues['placeholders'])
# 4. 获取迭代计数
iteration_count = load_iteration_tracker(project_root).get(task_id, 0)
requires_review = iteration_count >= 3
# 5. 生成结果
result = {
'passed': passed,
'score': score,
'iteration_count': iteration_count,
'requires_review': requires_review,
'issues': analysis_result['summary'],
'total_issues': analysis_result['total_issues']
}
# 6. 决定是否阻止完成
if not passed and not requires_review:
# 增加迭代计数
new_count = update_iteration_count(project_root, task_id)
result['iteration_count'] = new_count
# 生成修复要求
fix_requirements = generate_fix_requirements(issues, requirements_checklist)
result['fix_requirements'] = fix_requirements
result['block_completion'] = True
result['message'] = f'代码质量检查未通过 (评分: {score}/100,迭代: {new_count}/3)'
elif requires_review:
result['block_completion'] = True
result['message'] = f'已达最大迭代次数 ({iteration_count}/3),需要深度审查'
result['trigger_review_agent'] = True
else:
# 通过,重置计数
reset_iteration_count(project_root, task_id)
result['block_completion'] = False
result['message'] = f'代码质量检查通过 (评分: {score}/100)'
return result
def main():
"""主函数"""
try:
# 加载输入
input_data = json.load(sys.stdin)
except json.JSONDecodeError:
input_data = {}
# 获取参数
project_root = input_data.get('projectRoot', os.getcwd())
task_id = input_data.get('taskId', 'default')
conversation_context = input_data.get('conversationContext', '')
# 执行快速检查
check_result = perform_quick_check(project_root, task_id, conversation_context)
# 发送通知(异步,不阻塞)
if check_result.get('passed') or check_result.get('requires_review'):
try:
notify_check_result(check_result)
except Exception:
pass # 通知失败不影响主流程
# 显示终端信息
if not check_result.get('passed'):
print(f"\n{'='*60}", file=sys.stderr)
print(f"⚠️ 代码质量检查未通过", file=sys.stderr)
print(f"{'='*60}", file=sys.stderr)
print(f"评分: {check_result['score']}/100", file=sys.stderr)
print(f"迭代次数: {check_result['iteration_count']}/3", file=sys.stderr)
print(f"\n发现的问题:", file=sys.stderr)
for key, count in check_result['issues'].items():
if count > 0:
print(f" - {key}: {count}", file=sys.stderr)
print(f"\n修复要求:", file=sys.stderr)
print(check_result.get('fix_requirements', ''), file=sys.stderr)
print(f"{'='*60}\n", file=sys.stderr)
# 构造 Hook 输出
output = {
'hookSpecificOutput': {
'hookEventName': 'TaskEnd',
'blockCompletion': check_result.get('block_completion', False),
'additionalContext': check_result.get('fix_requirements', ''),
'triggerReviewAgent': check_result.get('trigger_review_agent', False),
'checkResult': check_result
}
}
# 如果通过,添加成功消息
if check_result.get('passed'):
output['hookSpecificOutput']['message'] = f"✅ 代码质量检查通过 (评分: {check_result['score']}/100)"
# 输出 JSON
print(json.dumps(output, ensure_ascii=False))
if __name__ == '__main__':
main()