开发code-quality
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
需求追踪器
|
||||
从对话历史和计划文件中提取需求,生成检查清单
|
||||
"""
|
||||
import json
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def load_input():
|
||||
"""加载 Hook 输入数据"""
|
||||
try:
|
||||
return json.load(sys.stdin)
|
||||
except json.JSONDecodeError:
|
||||
return {}
|
||||
|
||||
|
||||
def extract_requirements_from_conversation(conversation_text):
|
||||
"""从对话中提取需求"""
|
||||
requirements = []
|
||||
|
||||
# 需求关键词模式
|
||||
patterns = {
|
||||
'功能需求': r'(需要|实现|添加|创建|开发)\s*([^,。;\n]{5,50})',
|
||||
'技术栈': r'(使用|基于|框架)\s*([^,。;\n]{2,30})',
|
||||
'约束条件': r'(必须|应该|不能|禁止)\s*([^,。;\n]{5,50})',
|
||||
}
|
||||
|
||||
for category, pattern in patterns.items():
|
||||
matches = re.findall(pattern, conversation_text)
|
||||
for match in matches:
|
||||
if isinstance(match, tuple):
|
||||
requirements.append({
|
||||
'category': category,
|
||||
'description': match[-1].strip(),
|
||||
'verified': False
|
||||
})
|
||||
|
||||
return requirements
|
||||
|
||||
|
||||
def read_plan_files(project_root):
|
||||
"""读取项目计划文件"""
|
||||
plan_files = []
|
||||
docs_path = Path(project_root) / 'docs' / 'plans'
|
||||
|
||||
if docs_path.exists():
|
||||
for plan_file in docs_path.glob('*.md'):
|
||||
try:
|
||||
with open(plan_file, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
plan_files.append({
|
||||
'path': str(plan_file),
|
||||
'content': content
|
||||
})
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
return plan_files
|
||||
|
||||
|
||||
def parse_plan_to_checklist(plan_content):
|
||||
"""解析计划文件为检查清单"""
|
||||
checklist = []
|
||||
|
||||
# 提取任务/功能项
|
||||
lines = plan_content.split('\n')
|
||||
for line in lines:
|
||||
line = line.strip()
|
||||
# 匹配 markdown 列表项
|
||||
if line.startswith('- ') or line.startswith('* '):
|
||||
item = line[2:].strip()
|
||||
# 移除 [ ] 或 [x] 标记
|
||||
item = re.sub(r'^\[[ x]\]\s*', '', item)
|
||||
if item:
|
||||
checklist.append({
|
||||
'description': item,
|
||||
'verified': False,
|
||||
'source': 'plan_file'
|
||||
})
|
||||
|
||||
return checklist
|
||||
|
||||
|
||||
def generate_requirement_checklist(project_root, conversation_context=''):
|
||||
"""生成需求检查清单"""
|
||||
checklist = {
|
||||
'requirements': [],
|
||||
'source': 'unknown'
|
||||
}
|
||||
|
||||
# 1. 尝试从计划文件读取
|
||||
plan_files = read_plan_files(project_root)
|
||||
if plan_files:
|
||||
for plan in plan_files:
|
||||
items = parse_plan_to_checklist(plan['content'])
|
||||
checklist['requirements'].extend(items)
|
||||
checklist['source'] = 'plan_files'
|
||||
checklist['plan_files'] = [p['path'] for p in plan_files]
|
||||
|
||||
# 2. 如果没有计划文件,从对话提取
|
||||
if not checklist['requirements'] and conversation_context:
|
||||
items = extract_requirements_from_conversation(conversation_context)
|
||||
checklist['requirements'] = items
|
||||
checklist['source'] = 'conversation'
|
||||
|
||||
return checklist
|
||||
|
||||
|
||||
def save_checklist(checklist, task_id, project_root):
|
||||
"""保存检查清单到临时文件"""
|
||||
cache_dir = Path(project_root) / '.claude' / 'cache'
|
||||
cache_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
checklist_file = cache_dir / f'requirements_{task_id}.json'
|
||||
with open(checklist_file, 'w', encoding='utf-8') as f:
|
||||
json.dump(checklist, f, ensure_ascii=False, indent=2)
|
||||
|
||||
return str(checklist_file)
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数"""
|
||||
input_data = load_input()
|
||||
|
||||
# 获取项目根目录
|
||||
project_root = input_data.get('projectRoot', os.getcwd())
|
||||
|
||||
# 获取对话上下文(如果有)
|
||||
conversation_context = input_data.get('conversationContext', '')
|
||||
|
||||
# 生成检查清单
|
||||
checklist = generate_requirement_checklist(project_root, conversation_context)
|
||||
|
||||
# 保存到缓存
|
||||
task_id = input_data.get('taskId', 'default')
|
||||
checklist_file = save_checklist(checklist, task_id, project_root)
|
||||
|
||||
# 输出结果
|
||||
output = {
|
||||
'checklist_generated': True,
|
||||
'requirements_count': len(checklist['requirements']),
|
||||
'source': checklist['source'],
|
||||
'checklist_file': checklist_file
|
||||
}
|
||||
|
||||
print(json.dumps(output, ensure_ascii=False))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user