codeguard-testgen 1.0.10 ā 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +297 -2
- package/dist/config.d.ts +26 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +68 -2
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1425 -507
- package/dist/index.js.map +1 -1
- package/dist/reviewEngine.d.ts +38 -0
- package/dist/reviewEngine.d.ts.map +1 -0
- package/dist/reviewEngine.js +571 -0
- package/dist/reviewEngine.js.map +1 -0
- package/dist/toolExecutors.d.ts +82 -0
- package/dist/toolExecutors.d.ts.map +1 -0
- package/dist/toolExecutors.js +354 -0
- package/dist/toolExecutors.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review finding structure
|
|
3
|
+
*/
|
|
4
|
+
export interface ReviewFinding {
|
|
5
|
+
stepId: string;
|
|
6
|
+
stepName: string;
|
|
7
|
+
severity: 'critical' | 'high' | 'medium' | 'low';
|
|
8
|
+
category: string;
|
|
9
|
+
title: string;
|
|
10
|
+
file: string;
|
|
11
|
+
function?: string;
|
|
12
|
+
issue: string;
|
|
13
|
+
currentCode?: string;
|
|
14
|
+
recommendedCode?: string;
|
|
15
|
+
rationale: string;
|
|
16
|
+
source: 'ai' | 'tool';
|
|
17
|
+
toolName?: string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Step result structure
|
|
21
|
+
*/
|
|
22
|
+
export interface StepResult {
|
|
23
|
+
stepId: string;
|
|
24
|
+
stepName: string;
|
|
25
|
+
findings: ReviewFinding[];
|
|
26
|
+
executionTime: number;
|
|
27
|
+
success: boolean;
|
|
28
|
+
error?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Generate unified code review using parallel multi-step approach
|
|
32
|
+
*/
|
|
33
|
+
export declare function generateParallelReview(filesToReview: Array<{
|
|
34
|
+
filePath: string;
|
|
35
|
+
diff: string;
|
|
36
|
+
functions: string[];
|
|
37
|
+
}>): Promise<void>;
|
|
38
|
+
//# sourceMappingURL=reviewEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewEngine.d.ts","sourceRoot":"","sources":["../src/reviewEngine.ts"],"names":[],"mappings":"AAoCA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,IAAI,GAAG,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA2fD;;GAEG;AACH,wBAAsB,sBAAsB,CAC1C,aAAa,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,EAAE,CAAA;CAAC,CAAC,GAC1E,OAAO,CAAC,IAAI,CAAC,CAwEf"}
|
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.generateParallelReview = generateParallelReview;
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const config_1 = require("./config");
|
|
40
|
+
const config_2 = require("./config");
|
|
41
|
+
const index_1 = require("./index");
|
|
42
|
+
const toolExecutors_1 = require("./toolExecutors");
|
|
43
|
+
const CONFIG = (0, config_1.loadConfig)();
|
|
44
|
+
/**
|
|
45
|
+
* Tool call cache for preventing duplicate analysis
|
|
46
|
+
*/
|
|
47
|
+
const toolCallCache = new Map();
|
|
48
|
+
/**
|
|
49
|
+
* Generate cache key from tool name and arguments
|
|
50
|
+
*/
|
|
51
|
+
function getCacheKey(toolName, args) {
|
|
52
|
+
return `${toolName}:${JSON.stringify(args)}`;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Execute tool with caching
|
|
56
|
+
*/
|
|
57
|
+
async function executeCachedTool(toolName, args) {
|
|
58
|
+
const cacheKey = getCacheKey(toolName, args);
|
|
59
|
+
if (toolCallCache.has(cacheKey)) {
|
|
60
|
+
return toolCallCache.get(cacheKey);
|
|
61
|
+
}
|
|
62
|
+
const result = await (0, index_1.executeTool)(toolName, args);
|
|
63
|
+
toolCallCache.set(cacheKey, result);
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Pre-analyze files to populate cache with common context
|
|
68
|
+
*/
|
|
69
|
+
async function preAnalyzeFiles(files) {
|
|
70
|
+
console.log(`\nš Pre-analyzing ${files.length} file(s)...`);
|
|
71
|
+
const startTime = Date.now();
|
|
72
|
+
// Analyze files in parallel
|
|
73
|
+
await Promise.all(files.map(async (file) => {
|
|
74
|
+
try {
|
|
75
|
+
// Cache file structure analysis
|
|
76
|
+
await executeCachedTool('analyze_file_ast', { file_path: file.filePath });
|
|
77
|
+
// Cache imports
|
|
78
|
+
await executeCachedTool('get_imports_ast', { file_path: file.filePath });
|
|
79
|
+
// Cache type definitions
|
|
80
|
+
await executeCachedTool('get_type_definitions', { file_path: file.filePath });
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
console.warn(` Warning: Could not pre-analyze ${file.filePath}`);
|
|
84
|
+
}
|
|
85
|
+
}));
|
|
86
|
+
const duration = ((Date.now() - startTime) / 1000).toFixed(1);
|
|
87
|
+
console.log(` ā Pre-analysis complete in ${duration}s (${toolCallCache.size} items cached)`);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Execute AI-based review step
|
|
91
|
+
*/
|
|
92
|
+
async function executeAIReviewStep(step, files, reviewConfig) {
|
|
93
|
+
const startTime = Date.now();
|
|
94
|
+
console.log(`\nš¤ Executing AI step: ${step.name}`);
|
|
95
|
+
try {
|
|
96
|
+
const timestamp = new Date().toISOString().split('T')[0];
|
|
97
|
+
const totalFunctions = files.reduce((sum, f) => sum + f.functions.length, 0);
|
|
98
|
+
// Build context for files
|
|
99
|
+
const filesContext = files.map(f => `- ${f.filePath}: ${f.functions.join(', ')}`).join('\n');
|
|
100
|
+
// Build ruleset section
|
|
101
|
+
const rulesetSection = step.ruleset && step.ruleset.length > 0
|
|
102
|
+
? `## RULES TO CHECK
|
|
103
|
+
|
|
104
|
+
${step.ruleset.map((rule, idx) => `${idx + 1}. ${rule}`).join('\n')}
|
|
105
|
+
`
|
|
106
|
+
: '';
|
|
107
|
+
// Create focused prompt for this step
|
|
108
|
+
const reviewPrompt = `You are a senior software engineer conducting a focused code review for **${step.category.toUpperCase()}** issues.
|
|
109
|
+
|
|
110
|
+
## CONTEXT
|
|
111
|
+
Review Category: ${step.name}
|
|
112
|
+
Total files changed: ${files.length}
|
|
113
|
+
Total functions changed: ${totalFunctions}
|
|
114
|
+
|
|
115
|
+
Changed files and functions:
|
|
116
|
+
${filesContext}
|
|
117
|
+
|
|
118
|
+
${rulesetSection}
|
|
119
|
+
## GIT DIFFS
|
|
120
|
+
|
|
121
|
+
${files.map(f => `### ${f.filePath}
|
|
122
|
+
\`\`\`diff
|
|
123
|
+
${f.diff}
|
|
124
|
+
\`\`\`
|
|
125
|
+
`).join('\n')}
|
|
126
|
+
|
|
127
|
+
## YOUR TASK
|
|
128
|
+
|
|
129
|
+
Analyze the changed code ONLY for **${step.category}** issues. Use the available tools to understand the full context before providing findings.
|
|
130
|
+
|
|
131
|
+
**Available Tools:**
|
|
132
|
+
- analyze_file_ast(filePath) - Get file structure
|
|
133
|
+
- get_function_ast(filePath, functionName) - Get function implementation
|
|
134
|
+
- get_imports_ast(filePath) - Get file dependencies
|
|
135
|
+
- get_type_definitions(filePath) - Get type definitions
|
|
136
|
+
- search_codebase(query) - Search for patterns across codebase
|
|
137
|
+
- find_file(pattern) - Find files by pattern
|
|
138
|
+
|
|
139
|
+
**IMPORTANT:**
|
|
140
|
+
- Pre-analysis has been done. You can request additional context via tools.
|
|
141
|
+
- Focus ONLY on ${step.category} issues
|
|
142
|
+
- Be thorough but avoid false positives
|
|
143
|
+
- Provide specific, actionable findings
|
|
144
|
+
- Include code examples in your findings
|
|
145
|
+
|
|
146
|
+
## OUTPUT FORMAT
|
|
147
|
+
|
|
148
|
+
Provide your findings as a JSON array. Each finding must have:
|
|
149
|
+
- severity: "critical" | "high" | "medium" | "low"
|
|
150
|
+
- title: Brief title of the issue
|
|
151
|
+
- file: File path
|
|
152
|
+
- function: Function name (if applicable)
|
|
153
|
+
- issue: Detailed description of the problem
|
|
154
|
+
- currentCode: Code snippet showing the issue (optional)
|
|
155
|
+
- recommendedCode: Suggested fix (optional)
|
|
156
|
+
- rationale: Why this is important
|
|
157
|
+
|
|
158
|
+
**Response Format:**
|
|
159
|
+
\`\`\`json
|
|
160
|
+
{
|
|
161
|
+
"findings": [
|
|
162
|
+
{
|
|
163
|
+
"severity": "high",
|
|
164
|
+
"title": "Issue title",
|
|
165
|
+
"file": "path/to/file.ts",
|
|
166
|
+
"function": "functionName",
|
|
167
|
+
"issue": "Description of the issue",
|
|
168
|
+
"currentCode": "// problematic code",
|
|
169
|
+
"recommendedCode": "// improved code",
|
|
170
|
+
"rationale": "Why this matters"
|
|
171
|
+
}
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
\`\`\`
|
|
175
|
+
|
|
176
|
+
Start by analyzing the code with tools, then provide your findings in JSON format.`;
|
|
177
|
+
const messages = [
|
|
178
|
+
{
|
|
179
|
+
role: 'user',
|
|
180
|
+
content: reviewPrompt
|
|
181
|
+
}
|
|
182
|
+
];
|
|
183
|
+
let iterations = 0;
|
|
184
|
+
const maxIterations = 20;
|
|
185
|
+
let findingsCollected = false;
|
|
186
|
+
let findings = [];
|
|
187
|
+
while (iterations < maxIterations) {
|
|
188
|
+
iterations++;
|
|
189
|
+
const response = await (0, index_1.callAI)(messages, index_1.TOOLS, CONFIG.aiProvider);
|
|
190
|
+
// Check for text content with findings
|
|
191
|
+
if (response.content) {
|
|
192
|
+
const content = typeof response.content === 'string' ? response.content : JSON.stringify(response.content);
|
|
193
|
+
messages.push({ role: 'assistant', content });
|
|
194
|
+
// Try to extract JSON findings
|
|
195
|
+
const jsonMatch = content.match(/```json\s*(\{[\s\S]*?\})\s*```/);
|
|
196
|
+
if (jsonMatch) {
|
|
197
|
+
try {
|
|
198
|
+
const parsed = JSON.parse(jsonMatch[1]);
|
|
199
|
+
if (parsed.findings && Array.isArray(parsed.findings)) {
|
|
200
|
+
findings = parsed.findings.map((f) => ({
|
|
201
|
+
stepId: step.id,
|
|
202
|
+
stepName: step.name,
|
|
203
|
+
severity: f.severity || 'medium',
|
|
204
|
+
category: step.category,
|
|
205
|
+
title: f.title || 'Issue',
|
|
206
|
+
file: f.file || '',
|
|
207
|
+
function: f.function,
|
|
208
|
+
issue: f.issue || '',
|
|
209
|
+
currentCode: f.currentCode,
|
|
210
|
+
recommendedCode: f.recommendedCode,
|
|
211
|
+
rationale: f.rationale || '',
|
|
212
|
+
source: 'ai'
|
|
213
|
+
}));
|
|
214
|
+
findingsCollected = true;
|
|
215
|
+
break;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch (e) {
|
|
219
|
+
// Not valid JSON, continue
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// Check if AI says it's done
|
|
223
|
+
if (content.toLowerCase().includes('no issues found') ||
|
|
224
|
+
content.toLowerCase().includes('no findings')) {
|
|
225
|
+
findingsCollected = true;
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
// Handle tool calls
|
|
230
|
+
if (!response.toolCalls || response.toolCalls.length === 0) {
|
|
231
|
+
if (!findingsCollected) {
|
|
232
|
+
messages.push({
|
|
233
|
+
role: 'user',
|
|
234
|
+
content: 'Please provide your findings in the JSON format specified above.'
|
|
235
|
+
});
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
// Execute tool calls with caching
|
|
241
|
+
const toolResults = [];
|
|
242
|
+
for (const toolCall of response.toolCalls) {
|
|
243
|
+
const toolResult = await executeCachedTool(toolCall.name, toolCall.input);
|
|
244
|
+
toolResults.push({ id: toolCall.id, name: toolCall.name, result: toolResult });
|
|
245
|
+
}
|
|
246
|
+
// Add tool calls and results to messages (format differs by provider)
|
|
247
|
+
if (CONFIG.aiProvider === 'openai') {
|
|
248
|
+
messages.push({
|
|
249
|
+
role: 'assistant',
|
|
250
|
+
tool_calls: response.toolCalls.map(tc => ({
|
|
251
|
+
id: tc.id,
|
|
252
|
+
type: 'function',
|
|
253
|
+
function: { name: tc.name, arguments: JSON.stringify(tc.input) }
|
|
254
|
+
}))
|
|
255
|
+
});
|
|
256
|
+
for (const tr of toolResults) {
|
|
257
|
+
messages.push({
|
|
258
|
+
role: 'tool',
|
|
259
|
+
tool_call_id: tr.id,
|
|
260
|
+
content: JSON.stringify(tr.result)
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
else if (CONFIG.aiProvider === 'gemini') {
|
|
265
|
+
for (const toolCall of response.toolCalls) {
|
|
266
|
+
messages.push({
|
|
267
|
+
role: 'model',
|
|
268
|
+
functionCall: { name: toolCall.name, args: toolCall.input }
|
|
269
|
+
});
|
|
270
|
+
const result = toolResults.find(tr => tr.name === toolCall.name);
|
|
271
|
+
messages.push({
|
|
272
|
+
role: 'user',
|
|
273
|
+
functionResponse: { name: toolCall.name, response: result?.result }
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
// Claude
|
|
279
|
+
messages.push({
|
|
280
|
+
role: 'assistant',
|
|
281
|
+
content: response.toolCalls.map(tc => ({
|
|
282
|
+
type: 'tool_use',
|
|
283
|
+
id: tc.id,
|
|
284
|
+
name: tc.name,
|
|
285
|
+
input: tc.input
|
|
286
|
+
}))
|
|
287
|
+
});
|
|
288
|
+
messages.push({
|
|
289
|
+
role: 'user',
|
|
290
|
+
content: toolResults.map(tr => ({
|
|
291
|
+
type: 'tool_result',
|
|
292
|
+
tool_use_id: tr.id,
|
|
293
|
+
content: JSON.stringify(tr.result)
|
|
294
|
+
}))
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
const executionTime = Date.now() - startTime;
|
|
299
|
+
console.log(` ā Found ${findings.length} finding(s) in ${(executionTime / 1000).toFixed(1)}s`);
|
|
300
|
+
return {
|
|
301
|
+
stepId: step.id,
|
|
302
|
+
stepName: step.name,
|
|
303
|
+
findings,
|
|
304
|
+
executionTime,
|
|
305
|
+
success: true
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
catch (error) {
|
|
309
|
+
const executionTime = Date.now() - startTime;
|
|
310
|
+
console.error(` ā Error in ${step.name}: ${error.message}`);
|
|
311
|
+
return {
|
|
312
|
+
stepId: step.id,
|
|
313
|
+
stepName: step.name,
|
|
314
|
+
findings: [],
|
|
315
|
+
executionTime,
|
|
316
|
+
success: false,
|
|
317
|
+
error: error.message
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Execute tool-based review step
|
|
323
|
+
*/
|
|
324
|
+
async function executeToolReviewStep(step, files, reviewConfig) {
|
|
325
|
+
const startTime = Date.now();
|
|
326
|
+
try {
|
|
327
|
+
const toolConfig = reviewConfig.tools?.[step.tool];
|
|
328
|
+
if (!toolConfig || !toolConfig.enabled) {
|
|
329
|
+
console.warn(` Tool ${step.tool} is not enabled`);
|
|
330
|
+
return {
|
|
331
|
+
stepId: step.id,
|
|
332
|
+
stepName: step.name,
|
|
333
|
+
findings: [],
|
|
334
|
+
executionTime: 0,
|
|
335
|
+
success: false,
|
|
336
|
+
error: 'Tool not enabled'
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
// Extract changed function ranges for filtering
|
|
340
|
+
const changedFunctions = (0, toolExecutors_1.extractChangedFunctionRanges)(files);
|
|
341
|
+
// Execute tool
|
|
342
|
+
const aiValidationFn = step.config?.aiValidation
|
|
343
|
+
? async (prompt) => {
|
|
344
|
+
const messages = [{ role: 'user', content: prompt }];
|
|
345
|
+
const response = await (0, index_1.callAI)(messages, [], CONFIG.aiProvider);
|
|
346
|
+
return typeof response.content === 'string' ? response.content : JSON.stringify(response.content);
|
|
347
|
+
}
|
|
348
|
+
: undefined;
|
|
349
|
+
const toolFindings = await (0, toolExecutors_1.executeToolStep)(step, files, toolConfig, changedFunctions, aiValidationFn);
|
|
350
|
+
// Convert to ReviewFinding format
|
|
351
|
+
const findings = toolFindings.map(f => ({
|
|
352
|
+
stepId: step.id,
|
|
353
|
+
stepName: step.name,
|
|
354
|
+
severity: f.severity,
|
|
355
|
+
category: f.category,
|
|
356
|
+
title: f.message.split('\n')[0].substring(0, 100),
|
|
357
|
+
file: f.file,
|
|
358
|
+
function: undefined,
|
|
359
|
+
issue: f.message,
|
|
360
|
+
currentCode: f.code,
|
|
361
|
+
recommendedCode: undefined,
|
|
362
|
+
rationale: f.aiExplanation || `Detected by ${f.tool} rule: ${f.ruleId}`,
|
|
363
|
+
source: 'tool',
|
|
364
|
+
toolName: f.tool
|
|
365
|
+
}));
|
|
366
|
+
const executionTime = Date.now() - startTime;
|
|
367
|
+
return {
|
|
368
|
+
stepId: step.id,
|
|
369
|
+
stepName: step.name,
|
|
370
|
+
findings,
|
|
371
|
+
executionTime,
|
|
372
|
+
success: true
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
catch (error) {
|
|
376
|
+
const executionTime = Date.now() - startTime;
|
|
377
|
+
console.error(` ā Error in tool step ${step.name}: ${error.message}`);
|
|
378
|
+
return {
|
|
379
|
+
stepId: step.id,
|
|
380
|
+
stepName: step.name,
|
|
381
|
+
findings: [],
|
|
382
|
+
executionTime,
|
|
383
|
+
success: false,
|
|
384
|
+
error: error.message
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Merge review results into unified markdown
|
|
390
|
+
*/
|
|
391
|
+
function mergeReviewResults(stepResults, files, reviewConfig) {
|
|
392
|
+
const timestamp = new Date().toISOString().split('T')[0];
|
|
393
|
+
const totalFunctions = files.reduce((sum, f) => sum + f.functions.length, 0);
|
|
394
|
+
const totalFindings = stepResults.reduce((sum, r) => sum + r.findings.length, 0);
|
|
395
|
+
// Group findings by severity
|
|
396
|
+
const findingsBySeverity = {
|
|
397
|
+
critical: [],
|
|
398
|
+
high: [],
|
|
399
|
+
medium: [],
|
|
400
|
+
low: []
|
|
401
|
+
};
|
|
402
|
+
for (const result of stepResults) {
|
|
403
|
+
for (const finding of result.findings) {
|
|
404
|
+
findingsBySeverity[finding.severity].push(finding);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
// Build markdown sections
|
|
408
|
+
let markdown = `# Code Review
|
|
409
|
+
|
|
410
|
+
**Date**: ${timestamp}
|
|
411
|
+
**Reviewer**: AI Code Review System (Multi-Step Parallel)
|
|
412
|
+
**Files Changed**: ${files.length}
|
|
413
|
+
**Functions Changed**: ${totalFunctions}
|
|
414
|
+
**Total Findings**: ${totalFindings}
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
## Summary
|
|
419
|
+
|
|
420
|
+
Comprehensive multi-step code review completed analyzing ${files.length} file(s) across ${stepResults.filter(r => r.success).length} review categories. Found ${totalFindings} total issue(s) requiring attention.
|
|
421
|
+
|
|
422
|
+
**Review Steps Executed:**
|
|
423
|
+
${stepResults.map(r => `- ${r.stepName}: ${r.findings.length} finding(s) (${(r.executionTime / 1000).toFixed(1)}s)`).join('\n')}
|
|
424
|
+
|
|
425
|
+
---
|
|
426
|
+
|
|
427
|
+
## Files Changed
|
|
428
|
+
|
|
429
|
+
${files.map(f => `- **${f.filePath}**
|
|
430
|
+
- Functions: ${f.functions.join(', ')}`).join('\n')}
|
|
431
|
+
|
|
432
|
+
---
|
|
433
|
+
|
|
434
|
+
## Findings by Severity
|
|
435
|
+
|
|
436
|
+
`;
|
|
437
|
+
// Add findings for each severity level
|
|
438
|
+
for (const [severity, severityFindings] of Object.entries(findingsBySeverity)) {
|
|
439
|
+
if (severityFindings.length === 0)
|
|
440
|
+
continue;
|
|
441
|
+
const emoji = severity === 'critical' ? 'š“' : severity === 'high' ? 'š ' : severity === 'medium' ? 'š”' : 'š¢';
|
|
442
|
+
const label = severity.charAt(0).toUpperCase() + severity.slice(1);
|
|
443
|
+
markdown += `### ${emoji} ${label} Priority Issues (${severityFindings.length})\n\n`;
|
|
444
|
+
for (const finding of severityFindings) {
|
|
445
|
+
markdown += `#### [${finding.stepName}] ${finding.title}\n\n`;
|
|
446
|
+
markdown += `**File**: \`${finding.file}\`\n`;
|
|
447
|
+
if (finding.function) {
|
|
448
|
+
markdown += `**Function**: \`${finding.function}\`\n`;
|
|
449
|
+
}
|
|
450
|
+
markdown += `**Category**: ${finding.category}\n`;
|
|
451
|
+
markdown += `**Source**: ${finding.source}${finding.toolName ? ` (${finding.toolName})` : ''}\n\n`;
|
|
452
|
+
markdown += `**Issue**:\n${finding.issue}\n\n`;
|
|
453
|
+
if (finding.currentCode) {
|
|
454
|
+
markdown += `**Current Code**:\n\`\`\`typescript\n${finding.currentCode}\n\`\`\`\n\n`;
|
|
455
|
+
}
|
|
456
|
+
if (finding.recommendedCode) {
|
|
457
|
+
markdown += `**Recommended Fix**:\n\`\`\`typescript\n${finding.recommendedCode}\n\`\`\`\n\n`;
|
|
458
|
+
}
|
|
459
|
+
markdown += `**Rationale**:\n${finding.rationale}\n\n`;
|
|
460
|
+
markdown += `---\n\n`;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
// Add cross-step concerns if enabled
|
|
464
|
+
if (reviewConfig.options?.includeCrossStepAnalysis) {
|
|
465
|
+
markdown += `## š Cross-Step Concerns\n\n`;
|
|
466
|
+
markdown += `Multiple review steps analyzed the same code from different perspectives. Review findings across all categories to ensure comprehensive coverage.\n\n`;
|
|
467
|
+
markdown += `---\n\n`;
|
|
468
|
+
}
|
|
469
|
+
// Add positive aspects
|
|
470
|
+
if (totalFindings === 0) {
|
|
471
|
+
markdown += `## ā
Positive Aspects\n\n`;
|
|
472
|
+
markdown += `- No significant issues found in the changed code\n`;
|
|
473
|
+
markdown += `- Code appears to follow best practices\n\n`;
|
|
474
|
+
markdown += `---\n\n`;
|
|
475
|
+
}
|
|
476
|
+
// Add summary by step
|
|
477
|
+
markdown += `## š Review Summary by Step\n\n`;
|
|
478
|
+
for (const result of stepResults) {
|
|
479
|
+
markdown += `### ${result.stepName}\n`;
|
|
480
|
+
if (result.success) {
|
|
481
|
+
markdown += `- Findings: ${result.findings.length}\n`;
|
|
482
|
+
markdown += `- Execution time: ${(result.executionTime / 1000).toFixed(1)}s\n`;
|
|
483
|
+
}
|
|
484
|
+
else {
|
|
485
|
+
markdown += `- Status: Failed (${result.error})\n`;
|
|
486
|
+
}
|
|
487
|
+
markdown += `\n`;
|
|
488
|
+
}
|
|
489
|
+
markdown += `---\n\n`;
|
|
490
|
+
markdown += `## Conclusion\n\n`;
|
|
491
|
+
if (totalFindings === 0) {
|
|
492
|
+
markdown += `All review steps completed successfully with no major issues identified. The code changes appear to be well-implemented.\n`;
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
const criticalCount = findingsBySeverity.critical.length;
|
|
496
|
+
const highCount = findingsBySeverity.high.length;
|
|
497
|
+
if (criticalCount > 0) {
|
|
498
|
+
markdown += `š“ **${criticalCount} critical issue(s) require immediate attention.**\n\n`;
|
|
499
|
+
}
|
|
500
|
+
if (highCount > 0) {
|
|
501
|
+
markdown += `š **${highCount} high-priority issue(s) should be addressed soon.**\n\n`;
|
|
502
|
+
}
|
|
503
|
+
markdown += `Review all findings and implement recommended fixes before merging.\n`;
|
|
504
|
+
}
|
|
505
|
+
return markdown;
|
|
506
|
+
}
|
|
507
|
+
/**
|
|
508
|
+
* Generate unified code review using parallel multi-step approach
|
|
509
|
+
*/
|
|
510
|
+
async function generateParallelReview(filesToReview) {
|
|
511
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
512
|
+
console.log(`š Starting Multi-Step Parallel Code Review`);
|
|
513
|
+
console.log(`${'='.repeat(60)}`);
|
|
514
|
+
const overallStartTime = Date.now();
|
|
515
|
+
// Clear cache from any previous run
|
|
516
|
+
toolCallCache.clear();
|
|
517
|
+
// Load review configuration
|
|
518
|
+
const reviewConfig = (0, config_2.loadReviewConfig)();
|
|
519
|
+
const enabledSteps = reviewConfig.reviewSteps.filter(s => s.enabled);
|
|
520
|
+
console.log(`\nš Review Configuration:`);
|
|
521
|
+
console.log(` Enabled steps: ${enabledSteps.length}`);
|
|
522
|
+
console.log(` Max parallel: ${reviewConfig.options?.maxParallelSteps || 4}`);
|
|
523
|
+
console.log(` Files to review: ${filesToReview.length}`);
|
|
524
|
+
// Phase 1: Pre-Analysis
|
|
525
|
+
await preAnalyzeFiles(filesToReview);
|
|
526
|
+
// Phase 2: Parallel Review Execution
|
|
527
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
528
|
+
console.log(`š Phase 2: Parallel Review Execution`);
|
|
529
|
+
console.log(`${'='.repeat(60)}`);
|
|
530
|
+
const stepPromises = enabledSteps.map(step => {
|
|
531
|
+
if (step.type === 'ai') {
|
|
532
|
+
return executeAIReviewStep(step, filesToReview, reviewConfig);
|
|
533
|
+
}
|
|
534
|
+
else if (step.type === 'tool') {
|
|
535
|
+
return executeToolReviewStep(step, filesToReview, reviewConfig);
|
|
536
|
+
}
|
|
537
|
+
else {
|
|
538
|
+
return Promise.resolve({
|
|
539
|
+
stepId: step.id,
|
|
540
|
+
stepName: step.name,
|
|
541
|
+
findings: [],
|
|
542
|
+
executionTime: 0,
|
|
543
|
+
success: false,
|
|
544
|
+
error: 'Unknown step type'
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
});
|
|
548
|
+
const stepResults = await Promise.all(stepPromises);
|
|
549
|
+
// Phase 3: Merge Results
|
|
550
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
551
|
+
console.log(`š Phase 3: Merging Results`);
|
|
552
|
+
console.log(`${'='.repeat(60)}`);
|
|
553
|
+
const reviewMarkdown = mergeReviewResults(stepResults, filesToReview, reviewConfig);
|
|
554
|
+
// Write review file
|
|
555
|
+
const reviewsDir = path.join(process.cwd(), 'reviews');
|
|
556
|
+
if (!fs.existsSync(reviewsDir)) {
|
|
557
|
+
fs.mkdirSync(reviewsDir, { recursive: true });
|
|
558
|
+
}
|
|
559
|
+
const reviewFilePath = path.join(reviewsDir, 'code_review.md');
|
|
560
|
+
fs.writeFileSync(reviewFilePath, reviewMarkdown, 'utf-8');
|
|
561
|
+
const overallDuration = ((Date.now() - overallStartTime) / 1000).toFixed(1);
|
|
562
|
+
const totalFindings = stepResults.reduce((sum, r) => sum + r.findings.length, 0);
|
|
563
|
+
console.log(`\n${'='.repeat(60)}`);
|
|
564
|
+
console.log(`ā
Multi-Step Review Complete!`);
|
|
565
|
+
console.log(`${'='.repeat(60)}`);
|
|
566
|
+
console.log(` Total findings: ${totalFindings}`);
|
|
567
|
+
console.log(` Total time: ${overallDuration}s`);
|
|
568
|
+
console.log(` Review saved to: ${reviewFilePath}`);
|
|
569
|
+
console.log(`${'='.repeat(60)}\n`);
|
|
570
|
+
}
|
|
571
|
+
//# sourceMappingURL=reviewEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewEngine.js","sourceRoot":"","sources":["../src/reviewEngine.ts"],"names":[],"mappings":"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"}
|