lamps-code-review 0.1.0 → 0.2.0
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/dist/core/analyzer/ai/context.d.ts +29 -0
- package/dist/core/analyzer/ai/context.d.ts.map +1 -0
- package/dist/core/analyzer/ai/context.js +413 -0
- package/dist/core/analyzer/ai/context.js.map +1 -0
- package/dist/core/analyzer/ai/index.d.ts +24 -6
- package/dist/core/analyzer/ai/index.d.ts.map +1 -1
- package/dist/core/analyzer/ai/index.js +157 -97
- package/dist/core/analyzer/ai/index.js.map +1 -1
- package/dist/core/analyzer/ai/passes.d.ts +14 -0
- package/dist/core/analyzer/ai/passes.d.ts.map +1 -0
- package/dist/core/analyzer/ai/passes.js +202 -0
- package/dist/core/analyzer/ai/passes.js.map +1 -0
- package/dist/core/analyzer/ai/slices.d.ts +40 -0
- package/dist/core/analyzer/ai/slices.d.ts.map +1 -0
- package/dist/core/analyzer/ai/slices.js +263 -0
- package/dist/core/analyzer/ai/slices.js.map +1 -0
- package/dist/core/analyzer/dependency/index.d.ts +64 -0
- package/dist/core/analyzer/dependency/index.d.ts.map +1 -0
- package/dist/core/analyzer/dependency/index.js +402 -0
- package/dist/core/analyzer/dependency/index.js.map +1 -0
- package/dist/core/analyzer/index.d.ts +1 -0
- package/dist/core/analyzer/index.d.ts.map +1 -1
- package/dist/core/analyzer/index.js +16 -7
- package/dist/core/analyzer/index.js.map +1 -1
- package/dist/types/index.d.ts +78 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1,55 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
3
|
* AI Analyzer module
|
|
4
|
-
*
|
|
4
|
+
* Multi-pass AI-powered code review using OpenRouter
|
|
5
5
|
*/
|
|
6
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
-
if (k2 === undefined) k2 = k;
|
|
8
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
-
}
|
|
12
|
-
Object.defineProperty(o, k2, desc);
|
|
13
|
-
}) : (function(o, m, k, k2) {
|
|
14
|
-
if (k2 === undefined) k2 = k;
|
|
15
|
-
o[k2] = m[k];
|
|
16
|
-
}));
|
|
17
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
-
}) : function(o, v) {
|
|
20
|
-
o["default"] = v;
|
|
21
|
-
});
|
|
22
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
-
var ownKeys = function(o) {
|
|
24
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
-
var ar = [];
|
|
26
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
-
return ar;
|
|
28
|
-
};
|
|
29
|
-
return ownKeys(o);
|
|
30
|
-
};
|
|
31
|
-
return function (mod) {
|
|
32
|
-
if (mod && mod.__esModule) return mod;
|
|
33
|
-
var result = {};
|
|
34
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
-
__setModuleDefault(result, mod);
|
|
36
|
-
return result;
|
|
37
|
-
};
|
|
38
|
-
})();
|
|
39
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
7
|
exports.OpenRouterError = exports.AIAnalyzer = void 0;
|
|
41
8
|
exports.createAIAnalyzer = createAIAnalyzer;
|
|
42
|
-
const fs = __importStar(require("node:fs"));
|
|
43
9
|
const types_js_1 = require("../types.js");
|
|
44
10
|
const openrouter_js_1 = require("./openrouter.js");
|
|
45
|
-
const prompts_js_1 = require("./prompts.js");
|
|
46
11
|
const index_js_1 = require("../../config/index.js");
|
|
47
|
-
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
const MAX_TOTAL_CONTENT_SIZE = 500 * 1024;
|
|
12
|
+
const context_js_1 = require("./context.js");
|
|
13
|
+
const passes_js_1 = require("./passes.js");
|
|
14
|
+
const prompts_js_1 = require("./prompts.js");
|
|
51
15
|
/**
|
|
52
|
-
* AI-powered code analyzer using OpenRouter
|
|
16
|
+
* Multi-pass AI-powered code analyzer using OpenRouter
|
|
53
17
|
*/
|
|
54
18
|
class AIAnalyzer extends types_js_1.BaseAnalyzer {
|
|
55
19
|
constructor(config) {
|
|
@@ -57,7 +21,9 @@ class AIAnalyzer extends types_js_1.BaseAnalyzer {
|
|
|
57
21
|
this.config = config;
|
|
58
22
|
this.name = 'ai';
|
|
59
23
|
this.phase = 'ai';
|
|
60
|
-
this.description = 'AI-powered code review using OpenRouter';
|
|
24
|
+
this.description = 'Multi-pass AI-powered code review using OpenRouter';
|
|
25
|
+
/** Store static analysis findings from previous phase */
|
|
26
|
+
this.staticFindings = [];
|
|
61
27
|
}
|
|
62
28
|
async analyze(context) {
|
|
63
29
|
const startTime = Date.now();
|
|
@@ -72,35 +38,58 @@ class AIAnalyzer extends types_js_1.BaseAnalyzer {
|
|
|
72
38
|
},
|
|
73
39
|
], startTime, { skipped: true, reason: 'no-api-key' });
|
|
74
40
|
}
|
|
41
|
+
if (context.files.length === 0) {
|
|
42
|
+
return this.createResult([], startTime, {
|
|
43
|
+
skipped: true,
|
|
44
|
+
reason: 'no-files',
|
|
45
|
+
});
|
|
46
|
+
}
|
|
75
47
|
try {
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
48
|
+
// Get dependency graph from static phase results (if available)
|
|
49
|
+
// This will be set by the pipeline from previous phase results
|
|
50
|
+
const graph = this.getDependencyGraph(context) || (0, context_js_1.createEmptyGraph)(context.files);
|
|
51
|
+
// Collect static findings for context
|
|
52
|
+
this.staticFindings = this.getStaticFindings(context);
|
|
53
|
+
// Run all passes
|
|
54
|
+
const allPassResults = [];
|
|
55
|
+
const allFindings = [];
|
|
56
|
+
// Log start
|
|
57
|
+
if (context.config.verbose) {
|
|
58
|
+
console.log('Starting multi-pass AI analysis...');
|
|
59
|
+
}
|
|
60
|
+
// Pass 1: Architecture
|
|
61
|
+
const archResult = await this.runPass('architecture', context, graph, allFindings);
|
|
62
|
+
allPassResults.push(archResult);
|
|
63
|
+
allFindings.push(...archResult.findings);
|
|
64
|
+
if (context.config.verbose) {
|
|
65
|
+
console.log(` Architecture pass: ${archResult.findings.length} findings`);
|
|
66
|
+
}
|
|
67
|
+
// Pass 2: Deep Dive
|
|
68
|
+
const deepResult = await this.runPass('deep-dive', context, graph, allFindings);
|
|
69
|
+
allPassResults.push(deepResult);
|
|
70
|
+
allFindings.push(...deepResult.findings);
|
|
71
|
+
if (context.config.verbose) {
|
|
72
|
+
console.log(` Deep-dive pass: ${deepResult.findings.length} findings`);
|
|
83
73
|
}
|
|
84
|
-
//
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
//
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
suggestion: f.suggestion,
|
|
99
|
-
}));
|
|
100
|
-
return this.createResult(findings, startTime, {
|
|
74
|
+
// Pass 3: Security
|
|
75
|
+
const secResult = await this.runPass('security', context, graph, allFindings);
|
|
76
|
+
allPassResults.push(secResult);
|
|
77
|
+
allFindings.push(...secResult.findings);
|
|
78
|
+
if (context.config.verbose) {
|
|
79
|
+
console.log(` Security pass: ${secResult.findings.length} findings`);
|
|
80
|
+
}
|
|
81
|
+
// Deduplicate findings
|
|
82
|
+
const dedupedFindings = this.deduplicateFindings(allFindings);
|
|
83
|
+
// Combine summaries
|
|
84
|
+
const combinedSummary = allPassResults
|
|
85
|
+
.map((r) => `**${r.pass}**: ${r.summary}`)
|
|
86
|
+
.join('\n\n');
|
|
87
|
+
return this.createResult(dedupedFindings, startTime, {
|
|
101
88
|
model: this.config.model,
|
|
102
|
-
summary:
|
|
103
|
-
|
|
89
|
+
summary: combinedSummary,
|
|
90
|
+
passResults: allPassResults,
|
|
91
|
+
filesAnalyzed: context.files.length,
|
|
92
|
+
multiPass: true,
|
|
104
93
|
});
|
|
105
94
|
}
|
|
106
95
|
catch (error) {
|
|
@@ -121,41 +110,112 @@ class AIAnalyzer extends types_js_1.BaseAnalyzer {
|
|
|
121
110
|
}
|
|
122
111
|
}
|
|
123
112
|
/**
|
|
124
|
-
*
|
|
125
|
-
* Respects size limits and filters appropriately
|
|
113
|
+
* Run a single AI pass
|
|
126
114
|
*/
|
|
127
|
-
async
|
|
128
|
-
|
|
129
|
-
let
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
115
|
+
async runPass(passType, context, graph, previousFindings) {
|
|
116
|
+
// Build context for this pass
|
|
117
|
+
let reviewContext;
|
|
118
|
+
switch (passType) {
|
|
119
|
+
case 'architecture':
|
|
120
|
+
reviewContext = await (0, context_js_1.buildArchitectureContext)(context, graph);
|
|
121
|
+
break;
|
|
122
|
+
case 'deep-dive':
|
|
123
|
+
reviewContext = await (0, context_js_1.buildDeepDiveContext)(context, graph, this.staticFindings, previousFindings.filter((f) => f.ruleId.startsWith('ai/arch')));
|
|
124
|
+
break;
|
|
125
|
+
case 'security':
|
|
126
|
+
reviewContext = await (0, context_js_1.buildSecurityContext)(context, graph);
|
|
139
127
|
break;
|
|
128
|
+
}
|
|
129
|
+
// Skip if no files to review
|
|
130
|
+
if (reviewContext.files.length === 0) {
|
|
131
|
+
return {
|
|
132
|
+
pass: passType,
|
|
133
|
+
findings: [],
|
|
134
|
+
summary: `No relevant files for ${passType} review`,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
// Build prompts
|
|
138
|
+
const systemPrompt = passes_js_1.PASS_SYSTEM_PROMPTS[passType];
|
|
139
|
+
const userPrompt = (0, passes_js_1.buildPassPrompt)(reviewContext, this.config.customPrompt);
|
|
140
|
+
// Call AI
|
|
141
|
+
const apiKey = (0, index_js_1.getOpenRouterKey)();
|
|
142
|
+
const response = await (0, openrouter_js_1.chat)(systemPrompt, userPrompt, this.config, apiKey);
|
|
143
|
+
// Parse response
|
|
144
|
+
const parsed = (0, prompts_js_1.parseAIResponse)(response);
|
|
145
|
+
// Convert to findings with proper severity types
|
|
146
|
+
const findings = parsed.findings.map((f) => ({
|
|
147
|
+
ruleId: f.ruleId,
|
|
148
|
+
severity: f.severity,
|
|
149
|
+
file: f.file,
|
|
150
|
+
line: f.line,
|
|
151
|
+
message: f.message,
|
|
152
|
+
suggestion: f.suggestion,
|
|
153
|
+
}));
|
|
154
|
+
return {
|
|
155
|
+
pass: passType,
|
|
156
|
+
findings,
|
|
157
|
+
summary: parsed.summary,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Get dependency graph from context or previous results
|
|
162
|
+
*/
|
|
163
|
+
getDependencyGraph(context) {
|
|
164
|
+
// The dependency graph is stored in the context by the pipeline
|
|
165
|
+
// after the static phase runs
|
|
166
|
+
const metadata = context._previousResults;
|
|
167
|
+
if (metadata) {
|
|
168
|
+
return (0, context_js_1.getDependencyGraphFromResults)(metadata);
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Get static findings from previous phase
|
|
174
|
+
*/
|
|
175
|
+
getStaticFindings(context) {
|
|
176
|
+
const metadata = context._previousResults;
|
|
177
|
+
if (!metadata)
|
|
178
|
+
return [];
|
|
179
|
+
const staticResult = metadata.find((r) => r.analyzerName === 'static');
|
|
180
|
+
return staticResult?.findings || [];
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Deduplicate findings from multiple passes
|
|
184
|
+
* Keeps the highest severity if duplicates found
|
|
185
|
+
*/
|
|
186
|
+
deduplicateFindings(findings) {
|
|
187
|
+
const seen = new Map();
|
|
188
|
+
const severityOrder = {
|
|
189
|
+
error: 4,
|
|
190
|
+
warning: 3,
|
|
191
|
+
info: 2,
|
|
192
|
+
hint: 1,
|
|
193
|
+
};
|
|
194
|
+
for (const finding of findings) {
|
|
195
|
+
// Create a key based on file, line, and message similarity
|
|
196
|
+
const key = `${finding.file}:${finding.line || 0}:${this.normalizeMessage(finding.message)}`;
|
|
197
|
+
const existing = seen.get(key);
|
|
198
|
+
if (!existing) {
|
|
199
|
+
seen.set(key, finding);
|
|
140
200
|
}
|
|
141
|
-
|
|
142
|
-
//
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
content = await fs.promises.readFile(file.path, 'utf-8');
|
|
201
|
+
else {
|
|
202
|
+
// Keep the one with higher severity
|
|
203
|
+
if (severityOrder[finding.severity] > severityOrder[existing.severity]) {
|
|
204
|
+
seen.set(key, finding);
|
|
146
205
|
}
|
|
147
|
-
result.push({
|
|
148
|
-
...file,
|
|
149
|
-
content,
|
|
150
|
-
});
|
|
151
|
-
totalSize += file.size;
|
|
152
|
-
}
|
|
153
|
-
catch {
|
|
154
|
-
// Skip files that can't be read
|
|
155
|
-
continue;
|
|
156
206
|
}
|
|
157
207
|
}
|
|
158
|
-
return
|
|
208
|
+
return Array.from(seen.values());
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Normalize message for deduplication comparison
|
|
212
|
+
*/
|
|
213
|
+
normalizeMessage(message) {
|
|
214
|
+
return message
|
|
215
|
+
.toLowerCase()
|
|
216
|
+
.replace(/\s+/g, ' ')
|
|
217
|
+
.replace(/[^a-z0-9 ]/g, '')
|
|
218
|
+
.slice(0, 50);
|
|
159
219
|
}
|
|
160
220
|
}
|
|
161
221
|
exports.AIAnalyzer = AIAnalyzer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/analyzer/ai/index.ts"],"names":[],"mappings":";AAAA;;;GAGG
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/analyzer/ai/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pass-Specific Prompts
|
|
3
|
+
* Tailored prompts for each AI review pass
|
|
4
|
+
*/
|
|
5
|
+
import type { ReviewContext, AIPassType } from '../../../types/index.js';
|
|
6
|
+
/**
|
|
7
|
+
* System prompts for each pass type
|
|
8
|
+
*/
|
|
9
|
+
export declare const PASS_SYSTEM_PROMPTS: Record<AIPassType, string>;
|
|
10
|
+
/**
|
|
11
|
+
* Build the user prompt for a specific pass
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildPassPrompt(context: ReviewContext, customPrompt?: string): string;
|
|
14
|
+
//# sourceMappingURL=passes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passes.d.ts","sourceRoot":"","sources":["../../../../src/core/analyzer/ai/passes.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAe,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAEtF;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,UAAU,EAAE,MAAM,CA6C1D,CAAC;AAEF;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,aAAa,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,CAgCrF"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Pass-Specific Prompts
|
|
4
|
+
* Tailored prompts for each AI review pass
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.PASS_SYSTEM_PROMPTS = void 0;
|
|
8
|
+
exports.buildPassPrompt = buildPassPrompt;
|
|
9
|
+
/**
|
|
10
|
+
* System prompts for each pass type
|
|
11
|
+
*/
|
|
12
|
+
exports.PASS_SYSTEM_PROMPTS = {
|
|
13
|
+
architecture: `You are an expert software architect reviewing a codebase's structure and organization.
|
|
14
|
+
|
|
15
|
+
Focus on:
|
|
16
|
+
1. **Project Structure** - Is the organization logical? Are there missing directories or patterns?
|
|
17
|
+
2. **Dependencies** - Are there concerning dependencies? Version issues? Missing dependencies?
|
|
18
|
+
3. **Entry Points** - Are they well-organized? Clear application flow?
|
|
19
|
+
4. **Configuration** - Are configs complete? Missing environment handling?
|
|
20
|
+
5. **Architecture Patterns** - Consistent patterns? Clear separation of concerns?
|
|
21
|
+
6. **Scalability Concerns** - Any obvious bottlenecks or limitations?
|
|
22
|
+
|
|
23
|
+
Be concise and focus on high-level issues. Don't comment on specific code implementation details - those will be covered in the deep dive pass.
|
|
24
|
+
|
|
25
|
+
Respond with valid JSON only. No markdown, no explanations outside the JSON.`,
|
|
26
|
+
'deep-dive': `You are an expert senior software engineer conducting a thorough code review.
|
|
27
|
+
|
|
28
|
+
Focus on:
|
|
29
|
+
1. **Bugs and Logic Errors** - Off-by-one, null handling, race conditions, incorrect conditions
|
|
30
|
+
2. **Performance Issues** - N+1 queries, memory leaks, unnecessary re-renders, inefficient algorithms
|
|
31
|
+
3. **Code Quality** - Complexity, readability, maintainability, code smells
|
|
32
|
+
4. **Best Practices** - Framework-specific patterns, TypeScript/Python idioms, error handling
|
|
33
|
+
5. **Edge Cases** - Unhandled scenarios, missing validation, boundary conditions
|
|
34
|
+
|
|
35
|
+
Be specific and actionable. Include line numbers when possible. Don't nitpick style issues unless they significantly affect readability.
|
|
36
|
+
|
|
37
|
+
Respond with valid JSON only. No markdown, no explanations outside the JSON.`,
|
|
38
|
+
security: `You are a security expert conducting a security-focused code review.
|
|
39
|
+
|
|
40
|
+
Focus on OWASP Top 10 and common vulnerabilities:
|
|
41
|
+
1. **Injection** - SQL, NoSQL, OS command, LDAP injection
|
|
42
|
+
2. **Broken Authentication** - Weak passwords, session issues, credential exposure
|
|
43
|
+
3. **Sensitive Data Exposure** - Unencrypted data, exposed secrets, logging sensitive info
|
|
44
|
+
4. **XXE** - XML external entity attacks
|
|
45
|
+
5. **Broken Access Control** - Missing authorization checks, IDOR, privilege escalation
|
|
46
|
+
6. **Security Misconfiguration** - Default configs, verbose errors, unnecessary features
|
|
47
|
+
7. **XSS** - Stored, reflected, DOM-based cross-site scripting
|
|
48
|
+
8. **Insecure Deserialization** - Untrusted data deserialization
|
|
49
|
+
9. **Using Components with Known Vulnerabilities** - Outdated dependencies
|
|
50
|
+
10. **Insufficient Logging** - Missing audit trails, security event logging
|
|
51
|
+
|
|
52
|
+
Be thorough but avoid false positives. If you're uncertain, mark severity as 'info' rather than 'error'.
|
|
53
|
+
|
|
54
|
+
Respond with valid JSON only. No markdown, no explanations outside the JSON.`,
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Build the user prompt for a specific pass
|
|
58
|
+
*/
|
|
59
|
+
function buildPassPrompt(context, customPrompt) {
|
|
60
|
+
let prompt = '';
|
|
61
|
+
// Add custom prompt if provided
|
|
62
|
+
if (customPrompt) {
|
|
63
|
+
prompt += `## Additional Instructions\n${customPrompt}\n\n`;
|
|
64
|
+
}
|
|
65
|
+
prompt += `## Review Context\n`;
|
|
66
|
+
prompt += `- **Pass Type**: ${context.pass}\n`;
|
|
67
|
+
prompt += `- **Total Files in Codebase**: ${context.metadata.totalFiles}\n`;
|
|
68
|
+
prompt += `- **Files in This Review**: ${context.files.length}\n`;
|
|
69
|
+
prompt += `- **Frameworks**: ${context.metadata.frameworks.join(', ') || 'None detected'}\n`;
|
|
70
|
+
prompt += `- **Focus Areas**: ${context.metadata.focusAreas.join(', ')}\n\n`;
|
|
71
|
+
// Add file tree for architecture pass
|
|
72
|
+
if (context.pass === 'architecture') {
|
|
73
|
+
prompt += `## File Tree\n\`\`\`\n`;
|
|
74
|
+
prompt += context.files.map((f) => f.path).join('\n');
|
|
75
|
+
prompt += `\n\`\`\`\n\n`;
|
|
76
|
+
}
|
|
77
|
+
prompt += `## Files to Review\n\n`;
|
|
78
|
+
// Add file contents
|
|
79
|
+
for (const file of context.files) {
|
|
80
|
+
prompt += formatContextFile(file);
|
|
81
|
+
}
|
|
82
|
+
prompt += getResponseFormat(context.pass);
|
|
83
|
+
return prompt;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Format a context file for the prompt
|
|
87
|
+
*/
|
|
88
|
+
function formatContextFile(file) {
|
|
89
|
+
const extension = file.path.split('.').pop() || 'txt';
|
|
90
|
+
const langId = getLanguageId(extension);
|
|
91
|
+
let content = '';
|
|
92
|
+
content += `### ${file.path}\n`;
|
|
93
|
+
content += `*Reason: ${file.reason}*\n\n`;
|
|
94
|
+
if (file.content) {
|
|
95
|
+
content += `\`\`\`${langId}\n${file.content}\n\`\`\`\n\n`;
|
|
96
|
+
}
|
|
97
|
+
else if (file.slices && file.slices.length > 0) {
|
|
98
|
+
for (const slice of file.slices) {
|
|
99
|
+
content += `**Lines ${slice.startLine}-${slice.endLine}** (${slice.reason}):\n`;
|
|
100
|
+
content += `\`\`\`${langId}\n${slice.content}\n\`\`\`\n\n`;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return content;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Get response format instructions
|
|
107
|
+
*/
|
|
108
|
+
function getResponseFormat(pass) {
|
|
109
|
+
const categories = getCategoriesForPass(pass);
|
|
110
|
+
return `## Response Format
|
|
111
|
+
|
|
112
|
+
Respond with a JSON object containing your findings:
|
|
113
|
+
|
|
114
|
+
\`\`\`json
|
|
115
|
+
{
|
|
116
|
+
"findings": [
|
|
117
|
+
{
|
|
118
|
+
"ruleId": "ai/<category>-<specific-issue>",
|
|
119
|
+
"severity": "error" | "warning" | "info" | "hint",
|
|
120
|
+
"file": "relative/path/to/file.ts",
|
|
121
|
+
"line": 42,
|
|
122
|
+
"message": "Clear description of the issue",
|
|
123
|
+
"suggestion": "How to fix it (optional)"
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"summary": "Brief overall assessment for this ${pass} review"
|
|
127
|
+
}
|
|
128
|
+
\`\`\`
|
|
129
|
+
|
|
130
|
+
Rule ID categories for this pass:
|
|
131
|
+
${categories.map((c) => `- \`ai/${c.id}\` - ${c.description}`).join('\n')}
|
|
132
|
+
|
|
133
|
+
Severity levels:
|
|
134
|
+
- \`error\`: Critical issues that must be fixed
|
|
135
|
+
- \`warning\`: Important issues that should be addressed
|
|
136
|
+
- \`info\`: Suggestions for improvement
|
|
137
|
+
- \`hint\`: Minor observations
|
|
138
|
+
|
|
139
|
+
If there are no issues, return: {"findings": [], "summary": "No significant issues found."}`;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get rule categories for a pass type
|
|
143
|
+
*/
|
|
144
|
+
function getCategoriesForPass(pass) {
|
|
145
|
+
switch (pass) {
|
|
146
|
+
case 'architecture':
|
|
147
|
+
return [
|
|
148
|
+
{ id: 'arch-structure', description: 'Project structure issues' },
|
|
149
|
+
{ id: 'arch-dependency', description: 'Dependency concerns' },
|
|
150
|
+
{ id: 'arch-pattern', description: 'Pattern/consistency issues' },
|
|
151
|
+
{ id: 'arch-config', description: 'Configuration problems' },
|
|
152
|
+
{ id: 'arch-scale', description: 'Scalability concerns' },
|
|
153
|
+
];
|
|
154
|
+
case 'deep-dive':
|
|
155
|
+
return [
|
|
156
|
+
{ id: 'bug-logic', description: 'Logic errors' },
|
|
157
|
+
{ id: 'bug-null', description: 'Null/undefined handling' },
|
|
158
|
+
{ id: 'bug-async', description: 'Async/race conditions' },
|
|
159
|
+
{ id: 'perf-query', description: 'Query performance' },
|
|
160
|
+
{ id: 'perf-memory', description: 'Memory issues' },
|
|
161
|
+
{ id: 'perf-render', description: 'Rendering performance' },
|
|
162
|
+
{ id: 'quality-complexity', description: 'Code complexity' },
|
|
163
|
+
{ id: 'quality-readability', description: 'Readability issues' },
|
|
164
|
+
{ id: 'practice-framework', description: 'Framework best practices' },
|
|
165
|
+
{ id: 'practice-error', description: 'Error handling' },
|
|
166
|
+
];
|
|
167
|
+
case 'security':
|
|
168
|
+
return [
|
|
169
|
+
{ id: 'security-injection', description: 'Injection vulnerabilities' },
|
|
170
|
+
{ id: 'security-auth', description: 'Authentication issues' },
|
|
171
|
+
{ id: 'security-exposure', description: 'Data exposure' },
|
|
172
|
+
{ id: 'security-xss', description: 'Cross-site scripting' },
|
|
173
|
+
{ id: 'security-access', description: 'Access control issues' },
|
|
174
|
+
{ id: 'security-config', description: 'Security misconfiguration' },
|
|
175
|
+
{ id: 'security-crypto', description: 'Cryptography issues' },
|
|
176
|
+
{ id: 'security-secrets', description: 'Exposed secrets' },
|
|
177
|
+
];
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Map file extension to language identifier
|
|
182
|
+
*/
|
|
183
|
+
function getLanguageId(extension) {
|
|
184
|
+
const map = {
|
|
185
|
+
ts: 'typescript',
|
|
186
|
+
tsx: 'tsx',
|
|
187
|
+
js: 'javascript',
|
|
188
|
+
jsx: 'jsx',
|
|
189
|
+
py: 'python',
|
|
190
|
+
json: 'json',
|
|
191
|
+
yaml: 'yaml',
|
|
192
|
+
yml: 'yaml',
|
|
193
|
+
md: 'markdown',
|
|
194
|
+
css: 'css',
|
|
195
|
+
scss: 'scss',
|
|
196
|
+
html: 'html',
|
|
197
|
+
vue: 'vue',
|
|
198
|
+
svelte: 'svelte',
|
|
199
|
+
};
|
|
200
|
+
return map[extension] || extension || 'text';
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=passes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passes.js","sourceRoot":"","sources":["../../../../src/core/analyzer/ai/passes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code Slicing Utilities
|
|
3
|
+
* Extract relevant portions of large files for AI analysis
|
|
4
|
+
*/
|
|
5
|
+
import type { CodeSlice, Finding } from '../../../types/index.js';
|
|
6
|
+
export interface SliceOptions {
|
|
7
|
+
/** Findings from static analysis to slice around */
|
|
8
|
+
staticFindings?: Finding[];
|
|
9
|
+
/** Include all exports */
|
|
10
|
+
includeExports?: boolean;
|
|
11
|
+
/** Include security-sensitive patterns */
|
|
12
|
+
includeSecurity?: boolean;
|
|
13
|
+
/** Include class/function definitions */
|
|
14
|
+
includeDefinitions?: boolean;
|
|
15
|
+
/** Maximum total slice content size */
|
|
16
|
+
maxTotalSize?: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Extract relevant code slices from file content
|
|
20
|
+
*/
|
|
21
|
+
export declare function extractSlices(content: string, filePath: string, options?: SliceOptions): CodeSlice[];
|
|
22
|
+
/**
|
|
23
|
+
* Merge overlapping slices into contiguous blocks
|
|
24
|
+
*/
|
|
25
|
+
export declare function mergeOverlappingSlices(slices: CodeSlice[]): CodeSlice[];
|
|
26
|
+
/**
|
|
27
|
+
* Reconstruct slice content from original file
|
|
28
|
+
* Used after merging to get correct content
|
|
29
|
+
*/
|
|
30
|
+
export declare function reconstructSliceContent(content: string, slices: CodeSlice[]): CodeSlice[];
|
|
31
|
+
/**
|
|
32
|
+
* Estimate token count for content (rough approximation)
|
|
33
|
+
* Uses ~4 characters per token heuristic
|
|
34
|
+
*/
|
|
35
|
+
export declare function estimateTokens(content: string): number;
|
|
36
|
+
/**
|
|
37
|
+
* Get a summary of what a file exports (for architecture pass)
|
|
38
|
+
*/
|
|
39
|
+
export declare function getExportSummary(content: string, extension: string): string[];
|
|
40
|
+
//# sourceMappingURL=slices.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slices.d.ts","sourceRoot":"","sources":["../../../../src/core/analyzer/ai/slices.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AA6BlE,MAAM,WAAW,YAAY;IAC3B,oDAAoD;IACpD,cAAc,CAAC,EAAE,OAAO,EAAE,CAAC;IAC3B,0BAA0B;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,0CAA0C;IAC1C,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,yCAAyC;IACzC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,uCAAuC;IACvC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,YAAiB,GACzB,SAAS,EAAE,CA6Eb;AAyGD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,CAyBvE;AAWD;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE,CAOzF;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAkB7E"}
|