mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-15 02:42:45 +08:00
feat: Add orchestrator and state management for code review process
- Implemented orchestrator logic to manage code review phases, including state reading, action selection, and execution loop. - Defined state schema for review process, including metadata, context, findings, and execution tracking. - Created action catalog detailing actions for context collection, quick scan, deep review, report generation, and completion. - Established error recovery strategies and termination conditions for robust review handling. - Developed issue classification and quality standards documentation to guide review severity and categorization. - Introduced review dimensions with detailed checklists for correctness, security, performance, readability, testing, and architecture. - Added templates for issue reporting and review reports to standardize output and improve clarity.
This commit is contained in:
@@ -0,0 +1,263 @@
|
||||
# Action: Generate Report
|
||||
|
||||
汇总所有发现,生成结构化审查报告。
|
||||
|
||||
## Purpose
|
||||
|
||||
生成最终的代码审查报告:
|
||||
- 汇总所有维度的发现
|
||||
- 按严重程度排序
|
||||
- 提供统计摘要
|
||||
- 输出 Markdown 格式报告
|
||||
|
||||
## Preconditions
|
||||
|
||||
- [ ] state.status === 'running'
|
||||
- [ ] 所有维度已审查完成 (reviewed_dimensions.length === 6)
|
||||
|
||||
## Execution
|
||||
|
||||
```javascript
|
||||
async function execute(state, workDir) {
|
||||
const context = state.context;
|
||||
const findings = state.findings;
|
||||
|
||||
// 1. 汇总所有发现
|
||||
const allFindings = [
|
||||
...findings.correctness,
|
||||
...findings.readability,
|
||||
...findings.performance,
|
||||
...findings.security,
|
||||
...findings.testing,
|
||||
...findings.architecture
|
||||
];
|
||||
|
||||
// 2. 按严重程度排序
|
||||
const severityOrder = { critical: 0, high: 1, medium: 2, low: 3, info: 4 };
|
||||
allFindings.sort((a, b) => severityOrder[a.severity] - severityOrder[b.severity]);
|
||||
|
||||
// 3. 统计
|
||||
const stats = {
|
||||
total_issues: allFindings.length,
|
||||
critical: allFindings.filter(f => f.severity === 'critical').length,
|
||||
high: allFindings.filter(f => f.severity === 'high').length,
|
||||
medium: allFindings.filter(f => f.severity === 'medium').length,
|
||||
low: allFindings.filter(f => f.severity === 'low').length,
|
||||
info: allFindings.filter(f => f.severity === 'info').length,
|
||||
by_dimension: {
|
||||
correctness: findings.correctness.length,
|
||||
readability: findings.readability.length,
|
||||
performance: findings.performance.length,
|
||||
security: findings.security.length,
|
||||
testing: findings.testing.length,
|
||||
architecture: findings.architecture.length
|
||||
}
|
||||
};
|
||||
|
||||
// 4. 生成报告
|
||||
const report = generateMarkdownReport(context, stats, allFindings, state.scan_summary);
|
||||
|
||||
// 5. 保存报告
|
||||
const reportPath = `${workDir}/review-report.md`;
|
||||
Write(reportPath, report);
|
||||
|
||||
return {
|
||||
stateUpdates: {
|
||||
report_generated: true,
|
||||
report_path: reportPath,
|
||||
summary: {
|
||||
...stats,
|
||||
review_duration_ms: Date.now() - new Date(state.started_at).getTime()
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function generateMarkdownReport(context, stats, findings, scanSummary) {
|
||||
const severityEmoji = {
|
||||
critical: '🔴',
|
||||
high: '🟠',
|
||||
medium: '🟡',
|
||||
low: '🔵',
|
||||
info: '⚪'
|
||||
};
|
||||
|
||||
let report = `# Code Review Report
|
||||
|
||||
## 审查概览
|
||||
|
||||
| 项目 | 值 |
|
||||
|------|------|
|
||||
| 目标路径 | \`${context.target_path}\` |
|
||||
| 文件数量 | ${context.file_count} |
|
||||
| 代码行数 | ${context.total_lines} |
|
||||
| 主要语言 | ${context.language} |
|
||||
| 框架 | ${context.framework || 'N/A'} |
|
||||
|
||||
## 问题统计
|
||||
|
||||
| 严重程度 | 数量 |
|
||||
|----------|------|
|
||||
| 🔴 Critical | ${stats.critical} |
|
||||
| 🟠 High | ${stats.high} |
|
||||
| 🟡 Medium | ${stats.medium} |
|
||||
| 🔵 Low | ${stats.low} |
|
||||
| ⚪ Info | ${stats.info} |
|
||||
| **总计** | **${stats.total_issues}** |
|
||||
|
||||
### 按维度统计
|
||||
|
||||
| 维度 | 问题数 |
|
||||
|------|--------|
|
||||
| Correctness (正确性) | ${stats.by_dimension.correctness} |
|
||||
| Security (安全性) | ${stats.by_dimension.security} |
|
||||
| Performance (性能) | ${stats.by_dimension.performance} |
|
||||
| Readability (可读性) | ${stats.by_dimension.readability} |
|
||||
| Testing (测试) | ${stats.by_dimension.testing} |
|
||||
| Architecture (架构) | ${stats.by_dimension.architecture} |
|
||||
|
||||
---
|
||||
|
||||
## 高风险区域
|
||||
|
||||
`;
|
||||
|
||||
if (scanSummary?.risk_areas?.length > 0) {
|
||||
report += `| 文件 | 原因 | 优先级 |
|
||||
|------|------|--------|
|
||||
`;
|
||||
for (const area of scanSummary.risk_areas.slice(0, 10)) {
|
||||
report += `| \`${area.file}\` | ${area.reason} | ${area.priority} |\n`;
|
||||
}
|
||||
} else {
|
||||
report += `未发现明显的高风险区域。\n`;
|
||||
}
|
||||
|
||||
report += `
|
||||
---
|
||||
|
||||
## 问题详情
|
||||
|
||||
`;
|
||||
|
||||
// 按维度分组输出
|
||||
const dimensions = ['correctness', 'security', 'performance', 'readability', 'testing', 'architecture'];
|
||||
const dimensionNames = {
|
||||
correctness: '正确性 (Correctness)',
|
||||
security: '安全性 (Security)',
|
||||
performance: '性能 (Performance)',
|
||||
readability: '可读性 (Readability)',
|
||||
testing: '测试 (Testing)',
|
||||
architecture: '架构 (Architecture)'
|
||||
};
|
||||
|
||||
for (const dim of dimensions) {
|
||||
const dimFindings = findings.filter(f => f.dimension === dim);
|
||||
if (dimFindings.length === 0) continue;
|
||||
|
||||
report += `### ${dimensionNames[dim]}
|
||||
|
||||
`;
|
||||
|
||||
for (const finding of dimFindings) {
|
||||
report += `#### ${severityEmoji[finding.severity]} [${finding.id}] ${finding.category}
|
||||
|
||||
- **严重程度**: ${finding.severity.toUpperCase()}
|
||||
- **文件**: \`${finding.file}\`${finding.line ? `:${finding.line}` : ''}
|
||||
- **描述**: ${finding.description}
|
||||
`;
|
||||
|
||||
if (finding.code_snippet) {
|
||||
report += `
|
||||
\`\`\`
|
||||
${finding.code_snippet}
|
||||
\`\`\`
|
||||
`;
|
||||
}
|
||||
|
||||
report += `
|
||||
**建议**: ${finding.recommendation}
|
||||
`;
|
||||
|
||||
if (finding.fix_example) {
|
||||
report += `
|
||||
**修复示例**:
|
||||
\`\`\`
|
||||
${finding.fix_example}
|
||||
\`\`\`
|
||||
`;
|
||||
}
|
||||
|
||||
report += `
|
||||
---
|
||||
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
report += `
|
||||
## 审查建议
|
||||
|
||||
### 必须修复 (Must Fix)
|
||||
|
||||
${stats.critical + stats.high > 0
|
||||
? `发现 ${stats.critical} 个严重问题和 ${stats.high} 个高优先级问题,建议在合并前修复。`
|
||||
: '未发现必须立即修复的问题。'}
|
||||
|
||||
### 建议改进 (Should Fix)
|
||||
|
||||
${stats.medium > 0
|
||||
? `发现 ${stats.medium} 个中等优先级问题,建议在后续迭代中改进。`
|
||||
: '代码质量良好,无明显需要改进的地方。'}
|
||||
|
||||
### 可选优化 (Nice to Have)
|
||||
|
||||
${stats.low + stats.info > 0
|
||||
? `发现 ${stats.low + stats.info} 个低优先级建议,可根据团队规范酌情处理。`
|
||||
: '无额外建议。'}
|
||||
|
||||
---
|
||||
|
||||
*报告生成时间: ${new Date().toISOString()}*
|
||||
`;
|
||||
|
||||
return report;
|
||||
}
|
||||
```
|
||||
|
||||
## State Updates
|
||||
|
||||
```javascript
|
||||
return {
|
||||
stateUpdates: {
|
||||
report_generated: true,
|
||||
report_path: reportPath,
|
||||
summary: {
|
||||
total_issues: totalCount,
|
||||
critical: criticalCount,
|
||||
high: highCount,
|
||||
medium: mediumCount,
|
||||
low: lowCount,
|
||||
info: infoCount,
|
||||
review_duration_ms: duration
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Output
|
||||
|
||||
- **File**: `review-report.md`
|
||||
- **Location**: `${workDir}/review-report.md`
|
||||
- **Format**: Markdown
|
||||
|
||||
## Error Handling
|
||||
|
||||
| Error Type | Recovery |
|
||||
|------------|----------|
|
||||
| 写入失败 | 尝试备用位置 |
|
||||
| 模板错误 | 使用简化格式 |
|
||||
|
||||
## Next Actions
|
||||
|
||||
- 成功: action-complete
|
||||
Reference in New Issue
Block a user