edsger 0.41.0 → 0.41.2
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/.claude/settings.local.json +23 -3
- package/.env.local +12 -0
- package/dist/api/features/__tests__/regression-prevention.test.d.ts +5 -0
- package/dist/api/features/__tests__/regression-prevention.test.js +338 -0
- package/dist/api/features/__tests__/status-updater.integration.test.d.ts +5 -0
- package/dist/api/features/__tests__/status-updater.integration.test.js +497 -0
- package/dist/commands/workflow/pipeline-runner.d.ts +17 -0
- package/dist/commands/workflow/pipeline-runner.js +393 -0
- package/dist/commands/workflow/runner.d.ts +26 -0
- package/dist/commands/workflow/runner.js +119 -0
- package/dist/commands/workflow/workflow-runner.d.ts +26 -0
- package/dist/commands/workflow/workflow-runner.js +119 -0
- package/dist/index.js +0 -0
- package/dist/phases/code-implementation/analyzer-helpers.d.ts +28 -0
- package/dist/phases/code-implementation/analyzer-helpers.js +177 -0
- package/dist/phases/code-implementation/analyzer.d.ts +32 -0
- package/dist/phases/code-implementation/analyzer.js +629 -0
- package/dist/phases/code-implementation/context-fetcher.d.ts +17 -0
- package/dist/phases/code-implementation/context-fetcher.js +86 -0
- package/dist/phases/code-implementation/mcp-server.d.ts +1 -0
- package/dist/phases/code-implementation/mcp-server.js +93 -0
- package/dist/phases/code-implementation/prompts-improvement.d.ts +5 -0
- package/dist/phases/code-implementation/prompts-improvement.js +108 -0
- package/dist/phases/code-implementation-verification/verifier.d.ts +31 -0
- package/dist/phases/code-implementation-verification/verifier.js +196 -0
- package/dist/phases/code-refine/analyzer.d.ts +41 -0
- package/dist/phases/code-refine/analyzer.js +561 -0
- package/dist/phases/code-refine/context-fetcher.d.ts +94 -0
- package/dist/phases/code-refine/context-fetcher.js +423 -0
- package/dist/phases/code-refine-verification/analysis/llm-analyzer.d.ts +22 -0
- package/dist/phases/code-refine-verification/analysis/llm-analyzer.js +134 -0
- package/dist/phases/code-refine-verification/verifier.d.ts +47 -0
- package/dist/phases/code-refine-verification/verifier.js +597 -0
- package/dist/phases/code-review/analyzer.d.ts +29 -0
- package/dist/phases/code-review/analyzer.js +363 -0
- package/dist/phases/code-review/context-fetcher.d.ts +92 -0
- package/dist/phases/code-review/context-fetcher.js +296 -0
- package/dist/phases/feature-analysis/analyzer-helpers.d.ts +10 -0
- package/dist/phases/feature-analysis/analyzer-helpers.js +47 -0
- package/dist/phases/feature-analysis/analyzer.d.ts +11 -0
- package/dist/phases/feature-analysis/analyzer.js +208 -0
- package/dist/phases/feature-analysis/context-fetcher.d.ts +26 -0
- package/dist/phases/feature-analysis/context-fetcher.js +134 -0
- package/dist/phases/feature-analysis/http-fallback.d.ts +20 -0
- package/dist/phases/feature-analysis/http-fallback.js +95 -0
- package/dist/phases/feature-analysis/mcp-server.d.ts +1 -0
- package/dist/phases/feature-analysis/mcp-server.js +144 -0
- package/dist/phases/feature-analysis/prompts-improvement.d.ts +8 -0
- package/dist/phases/feature-analysis/prompts-improvement.js +109 -0
- package/dist/phases/feature-analysis-verification/verifier.d.ts +37 -0
- package/dist/phases/feature-analysis-verification/verifier.js +147 -0
- package/dist/phases/pr-execution/file-assigner.js +20 -12
- package/dist/phases/technical-design/analyzer-helpers.d.ts +25 -0
- package/dist/phases/technical-design/analyzer-helpers.js +39 -0
- package/dist/phases/technical-design/analyzer.d.ts +21 -0
- package/dist/phases/technical-design/analyzer.js +461 -0
- package/dist/phases/technical-design/context-fetcher.d.ts +12 -0
- package/dist/phases/technical-design/context-fetcher.js +39 -0
- package/dist/phases/technical-design/http-fallback.d.ts +17 -0
- package/dist/phases/technical-design/http-fallback.js +151 -0
- package/dist/phases/technical-design/mcp-server.d.ts +1 -0
- package/dist/phases/technical-design/mcp-server.js +157 -0
- package/dist/phases/technical-design/prompts-improvement.d.ts +5 -0
- package/dist/phases/technical-design/prompts-improvement.js +93 -0
- package/dist/phases/technical-design-verification/verifier.d.ts +53 -0
- package/dist/phases/technical-design-verification/verifier.js +170 -0
- package/dist/services/feature-branches.d.ts +77 -0
- package/dist/services/feature-branches.js +205 -0
- package/dist/workflow-runner/config/phase-configs.d.ts +5 -0
- package/dist/workflow-runner/config/phase-configs.js +120 -0
- package/dist/workflow-runner/core/feature-filter.d.ts +16 -0
- package/dist/workflow-runner/core/feature-filter.js +46 -0
- package/dist/workflow-runner/core/index.d.ts +8 -0
- package/dist/workflow-runner/core/index.js +12 -0
- package/dist/workflow-runner/core/pipeline-evaluator.d.ts +24 -0
- package/dist/workflow-runner/core/pipeline-evaluator.js +32 -0
- package/dist/workflow-runner/core/state-manager.d.ts +24 -0
- package/dist/workflow-runner/core/state-manager.js +42 -0
- package/dist/workflow-runner/core/workflow-logger.d.ts +20 -0
- package/dist/workflow-runner/core/workflow-logger.js +65 -0
- package/dist/workflow-runner/executors/phase-executor.d.ts +8 -0
- package/dist/workflow-runner/executors/phase-executor.js +248 -0
- package/dist/workflow-runner/feature-workflow-runner.d.ts +26 -0
- package/dist/workflow-runner/feature-workflow-runner.js +119 -0
- package/dist/workflow-runner/index.d.ts +2 -0
- package/dist/workflow-runner/index.js +2 -0
- package/dist/workflow-runner/pipeline-runner.d.ts +17 -0
- package/dist/workflow-runner/pipeline-runner.js +393 -0
- package/dist/workflow-runner/workflow-processor.d.ts +54 -0
- package/dist/workflow-runner/workflow-processor.js +170 -0
- package/package.json +1 -1
- package/dist/services/lifecycle-agent/__tests__/phase-criteria.test.d.ts +0 -4
- package/dist/services/lifecycle-agent/__tests__/phase-criteria.test.js +0 -133
- package/dist/services/lifecycle-agent/__tests__/transition-rules.test.d.ts +0 -4
- package/dist/services/lifecycle-agent/__tests__/transition-rules.test.js +0 -336
- package/dist/services/lifecycle-agent/index.d.ts +0 -24
- package/dist/services/lifecycle-agent/index.js +0 -25
- package/dist/services/lifecycle-agent/phase-criteria.d.ts +0 -57
- package/dist/services/lifecycle-agent/phase-criteria.js +0 -335
- package/dist/services/lifecycle-agent/transition-rules.d.ts +0 -60
- package/dist/services/lifecycle-agent/transition-rules.js +0 -184
- package/dist/services/lifecycle-agent/types.d.ts +0 -190
- package/dist/services/lifecycle-agent/types.js +0 -12
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Review Analyzer
|
|
3
|
+
* Reviews GitHub PR code and creates review comments with REQUEST_CHANGES
|
|
4
|
+
*/
|
|
5
|
+
import { query } from '@anthropic-ai/claude-code';
|
|
6
|
+
import { logInfo, logError } from '../../utils/logger.js';
|
|
7
|
+
import { Octokit } from '@octokit/rest';
|
|
8
|
+
import { fetchCodeReviewContext, formatContextForPrompt, } from './context-fetcher.js';
|
|
9
|
+
import { getFeedbacksForPhase, formatFeedbacksForContext, } from '../../services/feedbacks.js';
|
|
10
|
+
function userMessage(content) {
|
|
11
|
+
return {
|
|
12
|
+
type: 'user',
|
|
13
|
+
message: { role: 'user', content: content },
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
async function* prompt(reviewPrompt) {
|
|
17
|
+
yield userMessage(reviewPrompt);
|
|
18
|
+
await new Promise((res) => setTimeout(res, 10000));
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Main code review function
|
|
22
|
+
*/
|
|
23
|
+
export const reviewPullRequest = async (options, config) => {
|
|
24
|
+
const { featureId, githubToken, verbose } = options;
|
|
25
|
+
if (verbose) {
|
|
26
|
+
logInfo(`Starting code review for feature ID: ${featureId}`);
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
// Fetch code review context (PR data, files, commits)
|
|
30
|
+
if (verbose) {
|
|
31
|
+
logInfo('Fetching code review context from GitHub PR...');
|
|
32
|
+
}
|
|
33
|
+
const context = await fetchCodeReviewContext(featureId, githubToken, verbose);
|
|
34
|
+
// Check if there are any files to review
|
|
35
|
+
if (context.files.length === 0) {
|
|
36
|
+
if (verbose) {
|
|
37
|
+
logInfo('✅ No files to review in the PR.');
|
|
38
|
+
}
|
|
39
|
+
return {
|
|
40
|
+
featureId,
|
|
41
|
+
status: 'success',
|
|
42
|
+
message: 'No files to review',
|
|
43
|
+
summary: 'No changed files found in the PR',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
if (verbose) {
|
|
47
|
+
logInfo(`📋 Found ${context.files.length} files to review across ${context.commits.length} commits`);
|
|
48
|
+
}
|
|
49
|
+
// Fetch additional feedbacks for code-review phase
|
|
50
|
+
let feedbacksInfo;
|
|
51
|
+
try {
|
|
52
|
+
const feedbacksContext = await getFeedbacksForPhase({ featureId, verbose }, 'code_review');
|
|
53
|
+
if (feedbacksContext.feedbacks.length > 0) {
|
|
54
|
+
feedbacksInfo = formatFeedbacksForContext(feedbacksContext);
|
|
55
|
+
if (verbose) {
|
|
56
|
+
logInfo(`Added ${feedbacksContext.feedbacks.length} human feedbacks to code review context`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (verbose) {
|
|
62
|
+
logInfo(`Note: Could not fetch feedbacks (${error instanceof Error ? error.message : String(error)})`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Create prompt for code review
|
|
66
|
+
const systemPrompt = createSystemPrompt(config);
|
|
67
|
+
const reviewPrompt = createCodeReviewPrompt(featureId, context, feedbacksInfo);
|
|
68
|
+
let lastAssistantResponse = '';
|
|
69
|
+
let structuredReviewResult = null;
|
|
70
|
+
if (verbose) {
|
|
71
|
+
logInfo('Starting Claude analysis for code review...');
|
|
72
|
+
}
|
|
73
|
+
// Use Claude to analyze the code (not using Claude Code SDK for actual implementation)
|
|
74
|
+
// This is a simplified approach - just analyze the code
|
|
75
|
+
for await (const message of query({
|
|
76
|
+
prompt: prompt(reviewPrompt),
|
|
77
|
+
options: {
|
|
78
|
+
appendSystemPrompt: systemPrompt,
|
|
79
|
+
model: config.claude.model || 'sonnet',
|
|
80
|
+
maxTurns: 50, // Limited turns since this is just analysis
|
|
81
|
+
permissionMode: 'bypassPermissions',
|
|
82
|
+
},
|
|
83
|
+
})) {
|
|
84
|
+
if (verbose) {
|
|
85
|
+
logInfo(`Received message type: ${message.type}`);
|
|
86
|
+
}
|
|
87
|
+
// Stream the code review process
|
|
88
|
+
if (message.type === 'assistant' && message.message?.content) {
|
|
89
|
+
for (const content of message.message.content) {
|
|
90
|
+
if (content.type === 'text') {
|
|
91
|
+
lastAssistantResponse += content.text + '\n';
|
|
92
|
+
if (verbose) {
|
|
93
|
+
console.log(`\n🔍 ${content.text}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else if (message.type === 'result') {
|
|
99
|
+
if (message.subtype === 'success') {
|
|
100
|
+
logInfo('\n🛠️ Code review analysis completed, parsing results...');
|
|
101
|
+
try {
|
|
102
|
+
const responseText = message.result || lastAssistantResponse;
|
|
103
|
+
let jsonResult = null;
|
|
104
|
+
const jsonBlockMatch = responseText.match(/```json\s*\n([\s\S]*?)\n\s*```/);
|
|
105
|
+
if (jsonBlockMatch) {
|
|
106
|
+
jsonResult = JSON.parse(jsonBlockMatch[1]);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
jsonResult = JSON.parse(responseText);
|
|
110
|
+
}
|
|
111
|
+
if (jsonResult && jsonResult.review_result) {
|
|
112
|
+
structuredReviewResult = jsonResult.review_result;
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
throw new Error('Invalid JSON structure');
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
logError(`Failed to parse structured review result: ${error}`);
|
|
120
|
+
structuredReviewResult = parseCodeReviewResponse(message.result || lastAssistantResponse);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
logError(`\n⚠️ Code review incomplete: ${message.subtype}`);
|
|
125
|
+
if (message.subtype === 'error_max_turns') {
|
|
126
|
+
logError('💡 Try simplifying the review scope');
|
|
127
|
+
}
|
|
128
|
+
if (lastAssistantResponse) {
|
|
129
|
+
try {
|
|
130
|
+
const responseText = lastAssistantResponse;
|
|
131
|
+
let jsonResult = null;
|
|
132
|
+
const jsonBlockMatch = responseText.match(/```json\s*\n([\s\S]*?)\n\s*```/);
|
|
133
|
+
if (jsonBlockMatch) {
|
|
134
|
+
jsonResult = JSON.parse(jsonBlockMatch[1]);
|
|
135
|
+
if (jsonResult && jsonResult.review_result) {
|
|
136
|
+
structuredReviewResult = jsonResult.review_result;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
structuredReviewResult = parseCodeReviewResponse(lastAssistantResponse);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
logError(`Failed to parse assistant response: ${error}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Create GitHub review with comments
|
|
151
|
+
if (structuredReviewResult) {
|
|
152
|
+
const { summary, comments, overall_assessment } = structuredReviewResult;
|
|
153
|
+
// Initialize Octokit
|
|
154
|
+
const octokit = new Octokit({ auth: githubToken });
|
|
155
|
+
if (!comments || comments.length === 0) {
|
|
156
|
+
if (verbose) {
|
|
157
|
+
logInfo('✅ No issues found. PR looks good!');
|
|
158
|
+
}
|
|
159
|
+
// Create an approval review if no issues found
|
|
160
|
+
const review = await octokit.pulls.createReview({
|
|
161
|
+
owner: context.owner,
|
|
162
|
+
repo: context.repo,
|
|
163
|
+
pull_number: context.pullRequestNumber,
|
|
164
|
+
event: 'APPROVE',
|
|
165
|
+
body: summary ||
|
|
166
|
+
overall_assessment ||
|
|
167
|
+
'Code review completed. No issues found.',
|
|
168
|
+
});
|
|
169
|
+
return {
|
|
170
|
+
featureId,
|
|
171
|
+
status: 'success',
|
|
172
|
+
message: 'Code review completed - no issues found',
|
|
173
|
+
reviewId: review.data.id,
|
|
174
|
+
reviewUrl: review.data.html_url,
|
|
175
|
+
commentsCount: 0,
|
|
176
|
+
summary: summary || 'No issues found',
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
if (verbose) {
|
|
180
|
+
logInfo(`Creating GitHub review with ${comments.length} comments...`);
|
|
181
|
+
}
|
|
182
|
+
// Create review with inline comments
|
|
183
|
+
const reviewComments = comments.map((comment) => ({
|
|
184
|
+
path: comment.file || comment.path,
|
|
185
|
+
line: comment.line,
|
|
186
|
+
body: comment.comment || comment.body,
|
|
187
|
+
}));
|
|
188
|
+
const review = await octokit.pulls.createReview({
|
|
189
|
+
owner: context.owner,
|
|
190
|
+
repo: context.repo,
|
|
191
|
+
pull_number: context.pullRequestNumber,
|
|
192
|
+
event: 'COMMENT',
|
|
193
|
+
body: summary ||
|
|
194
|
+
overall_assessment ||
|
|
195
|
+
'Please address the following review comments.',
|
|
196
|
+
comments: reviewComments,
|
|
197
|
+
});
|
|
198
|
+
if (verbose) {
|
|
199
|
+
logInfo(`✅ GitHub review created: ${review.data.html_url}`);
|
|
200
|
+
logInfo(`Review ID: ${review.data.id}`);
|
|
201
|
+
logInfo(`Comments posted: ${comments.length}`);
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
featureId,
|
|
205
|
+
status: 'success',
|
|
206
|
+
message: 'Code review completed and posted to GitHub',
|
|
207
|
+
reviewId: review.data.id,
|
|
208
|
+
reviewUrl: review.data.html_url,
|
|
209
|
+
commentsCount: comments.length,
|
|
210
|
+
summary: summary || 'Code review completed',
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
return {
|
|
215
|
+
featureId,
|
|
216
|
+
status: 'error',
|
|
217
|
+
message: 'Code review analysis failed or incomplete',
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
223
|
+
logError(`Code review failed: ${errorMessage}`);
|
|
224
|
+
return {
|
|
225
|
+
featureId,
|
|
226
|
+
status: 'error',
|
|
227
|
+
message: `Code review failed: ${errorMessage}`,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
function createSystemPrompt(_config) {
|
|
232
|
+
return `You are an expert code reviewer specializing in thorough, constructive code reviews. Your goal is to analyze pull request code and identify issues, potential bugs, code quality concerns, and areas for improvement.
|
|
233
|
+
|
|
234
|
+
**Your Role**: Review pull request code and provide detailed, actionable feedback.
|
|
235
|
+
|
|
236
|
+
**Review Focus Areas**:
|
|
237
|
+
1. **Code Quality**: Clean code principles, readability, maintainability
|
|
238
|
+
2. **Best Practices**: Language-specific conventions, design patterns
|
|
239
|
+
3. **Potential Bugs**: Logic errors, edge cases, error handling
|
|
240
|
+
4. **Security**: Security vulnerabilities, input validation
|
|
241
|
+
5. **Performance**: Performance issues, optimization opportunities
|
|
242
|
+
6. **Testing**: Test coverage, test quality
|
|
243
|
+
7. **Documentation**: Code comments, documentation completeness
|
|
244
|
+
8. **Architecture**: Design decisions, coupling, cohesion
|
|
245
|
+
|
|
246
|
+
**Important Guidelines**:
|
|
247
|
+
- Be thorough but focus on significant issues
|
|
248
|
+
- Provide constructive, actionable feedback
|
|
249
|
+
- Suggest specific improvements
|
|
250
|
+
- Consider the technical design and requirements
|
|
251
|
+
- Be respectful and professional
|
|
252
|
+
- Focus on issues that truly matter, not nitpicks
|
|
253
|
+
- If code looks good overall, provide positive feedback
|
|
254
|
+
|
|
255
|
+
**CRITICAL - Result Format**:
|
|
256
|
+
You MUST end your response with a JSON object containing the review results in this EXACT format:
|
|
257
|
+
|
|
258
|
+
\`\`\`json
|
|
259
|
+
{
|
|
260
|
+
"review_result": {
|
|
261
|
+
"feature_id": "FEATURE_ID_PLACEHOLDER",
|
|
262
|
+
"summary": "Overall review summary and assessment",
|
|
263
|
+
"overall_assessment": "APPROVE | REQUEST_CHANGES | COMMENT",
|
|
264
|
+
"comments": [
|
|
265
|
+
{
|
|
266
|
+
"file": "path/to/file.ts",
|
|
267
|
+
"line": 42,
|
|
268
|
+
"comment": "Detailed comment about the issue and suggested fix"
|
|
269
|
+
}
|
|
270
|
+
],
|
|
271
|
+
"issues_found": {
|
|
272
|
+
"critical": 0,
|
|
273
|
+
"major": 0,
|
|
274
|
+
"minor": 0
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
\`\`\`
|
|
279
|
+
|
|
280
|
+
**Comment Guidelines**:
|
|
281
|
+
- Each comment should reference a specific file and line number
|
|
282
|
+
- Be specific about what the issue is
|
|
283
|
+
- Provide a suggested fix or improvement
|
|
284
|
+
- Use a constructive, helpful tone
|
|
285
|
+
|
|
286
|
+
**Assessment Options**:
|
|
287
|
+
- **APPROVE**: Code looks good, no significant issues
|
|
288
|
+
- **REQUEST_CHANGES**: Issues found that should be addressed
|
|
289
|
+
- **COMMENT**: Minor suggestions or questions, not blocking
|
|
290
|
+
|
|
291
|
+
Focus on providing valuable, actionable code review feedback.`;
|
|
292
|
+
}
|
|
293
|
+
function createCodeReviewPrompt(featureId, context, feedbacksInfo) {
|
|
294
|
+
let contextInfo = formatContextForPrompt(context);
|
|
295
|
+
if (feedbacksInfo) {
|
|
296
|
+
contextInfo = contextInfo + '\n\n' + feedbacksInfo;
|
|
297
|
+
}
|
|
298
|
+
return `Review the pull request code for feature: ${featureId}
|
|
299
|
+
|
|
300
|
+
${contextInfo}
|
|
301
|
+
|
|
302
|
+
## Code Review Instructions
|
|
303
|
+
|
|
304
|
+
Follow this systematic approach:
|
|
305
|
+
|
|
306
|
+
1. **Understand the Context**: Review the feature description, technical design, user stories, and test cases to understand what the code should accomplish.
|
|
307
|
+
|
|
308
|
+
2. **Analyze Each File**: For each changed file:
|
|
309
|
+
- Review the code changes in the diff
|
|
310
|
+
- Look for code quality issues
|
|
311
|
+
- Check for potential bugs or logic errors
|
|
312
|
+
- Verify error handling
|
|
313
|
+
- Consider security implications
|
|
314
|
+
- Evaluate performance considerations
|
|
315
|
+
- Check test coverage
|
|
316
|
+
|
|
317
|
+
3. **Check Against Requirements**:
|
|
318
|
+
- Does the code implement the technical design correctly?
|
|
319
|
+
- Are all user stories addressed?
|
|
320
|
+
- Are test cases covered?
|
|
321
|
+
|
|
322
|
+
4. **Identify Issues**: Categorize issues by severity:
|
|
323
|
+
- **Critical**: Security vulnerabilities, data loss risks, major bugs
|
|
324
|
+
- **Major**: Logic errors, incorrect implementations, missing error handling
|
|
325
|
+
- **Minor**: Code quality improvements, style issues, optimization suggestions
|
|
326
|
+
|
|
327
|
+
5. **Provide Actionable Feedback**: For each issue:
|
|
328
|
+
- Reference the specific file and line number
|
|
329
|
+
- Explain what the issue is
|
|
330
|
+
- Suggest how to fix it
|
|
331
|
+
- Be constructive and helpful
|
|
332
|
+
|
|
333
|
+
6. **Generate Review Result**: Create a structured JSON response with:
|
|
334
|
+
- Overall summary
|
|
335
|
+
- Assessment (APPROVE/REQUEST_CHANGES/COMMENT)
|
|
336
|
+
- List of comments with file, line, and comment text
|
|
337
|
+
- Count of issues by severity
|
|
338
|
+
|
|
339
|
+
## Important Notes
|
|
340
|
+
- Be thorough but focus on meaningful issues
|
|
341
|
+
- Provide specific, actionable suggestions
|
|
342
|
+
- Consider the context and requirements
|
|
343
|
+
- Be professional and constructive
|
|
344
|
+
- If code is good, say so!
|
|
345
|
+
|
|
346
|
+
Begin by analyzing the changed files and identifying any issues or improvements.`;
|
|
347
|
+
}
|
|
348
|
+
function parseCodeReviewResponse(response) {
|
|
349
|
+
const summaryMatch = response.match(/## Review Summary\n([\s\S]*?)(?=\n##|\n\n|$)/);
|
|
350
|
+
const summary = summaryMatch
|
|
351
|
+
? summaryMatch[1].trim()
|
|
352
|
+
: 'Code review completed';
|
|
353
|
+
return {
|
|
354
|
+
summary,
|
|
355
|
+
comments: [],
|
|
356
|
+
overall_assessment: 'COMMENT',
|
|
357
|
+
issues_found: {
|
|
358
|
+
critical: 0,
|
|
359
|
+
major: 0,
|
|
360
|
+
minor: 0,
|
|
361
|
+
},
|
|
362
|
+
};
|
|
363
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context fetcher for code review phase
|
|
3
|
+
* Fetches GitHub PR data including files, diffs, and commits for review
|
|
4
|
+
*/
|
|
5
|
+
import { Octokit } from '@octokit/rest';
|
|
6
|
+
export interface PRFile {
|
|
7
|
+
filename: string;
|
|
8
|
+
status: string;
|
|
9
|
+
additions: number;
|
|
10
|
+
deletions: number;
|
|
11
|
+
changes: number;
|
|
12
|
+
patch?: string;
|
|
13
|
+
blob_url: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PRCommit {
|
|
16
|
+
sha: string;
|
|
17
|
+
commit: {
|
|
18
|
+
message: string;
|
|
19
|
+
author: {
|
|
20
|
+
name: string;
|
|
21
|
+
date: string;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export interface PRData {
|
|
26
|
+
number: number;
|
|
27
|
+
title: string;
|
|
28
|
+
body: string | null;
|
|
29
|
+
state: string;
|
|
30
|
+
head: {
|
|
31
|
+
ref: string;
|
|
32
|
+
sha: string;
|
|
33
|
+
};
|
|
34
|
+
base: {
|
|
35
|
+
ref: string;
|
|
36
|
+
sha: string;
|
|
37
|
+
};
|
|
38
|
+
user: {
|
|
39
|
+
login: string;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface CodeReviewContext {
|
|
43
|
+
featureId: string;
|
|
44
|
+
featureName: string;
|
|
45
|
+
featureDescription: string | null;
|
|
46
|
+
pullRequestUrl: string;
|
|
47
|
+
pullRequestNumber: number;
|
|
48
|
+
owner: string;
|
|
49
|
+
repo: string;
|
|
50
|
+
prData: PRData;
|
|
51
|
+
files: PRFile[];
|
|
52
|
+
commits: PRCommit[];
|
|
53
|
+
technicalDesign?: string;
|
|
54
|
+
userStories?: any[];
|
|
55
|
+
testCases?: any[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Extract owner, repo, and PR number from GitHub PR URL
|
|
59
|
+
*/
|
|
60
|
+
export declare function parsePullRequestUrl(pullRequestUrl: string): {
|
|
61
|
+
owner: string;
|
|
62
|
+
repo: string;
|
|
63
|
+
prNumber: number;
|
|
64
|
+
} | null;
|
|
65
|
+
/**
|
|
66
|
+
* Fetch PR details
|
|
67
|
+
*/
|
|
68
|
+
export declare function fetchPRDetails(octokit: Octokit, owner: string, repo: string, prNumber: number, verbose?: boolean): Promise<PRData>;
|
|
69
|
+
/**
|
|
70
|
+
* Fetch PR files (changed files with diffs)
|
|
71
|
+
*/
|
|
72
|
+
export declare function fetchPRFiles(octokit: Octokit, owner: string, repo: string, prNumber: number, verbose?: boolean): Promise<PRFile[]>;
|
|
73
|
+
/**
|
|
74
|
+
* Fetch PR commits
|
|
75
|
+
*/
|
|
76
|
+
export declare function fetchPRCommits(octokit: Octokit, owner: string, repo: string, prNumber: number, verbose?: boolean): Promise<PRCommit[]>;
|
|
77
|
+
/**
|
|
78
|
+
* Fetch user stories via MCP
|
|
79
|
+
*/
|
|
80
|
+
export declare function fetchUserStories(featureId: string, verbose?: boolean): Promise<any[]>;
|
|
81
|
+
/**
|
|
82
|
+
* Fetch test cases via MCP
|
|
83
|
+
*/
|
|
84
|
+
export declare function fetchTestCases(featureId: string, verbose?: boolean): Promise<any[]>;
|
|
85
|
+
/**
|
|
86
|
+
* Fetch complete code review context
|
|
87
|
+
*/
|
|
88
|
+
export declare function fetchCodeReviewContext(featureId: string, githubToken: string, verbose?: boolean): Promise<CodeReviewContext>;
|
|
89
|
+
/**
|
|
90
|
+
* Format code review context for prompt
|
|
91
|
+
*/
|
|
92
|
+
export declare function formatContextForPrompt(context: CodeReviewContext): string;
|