lamps-code-review 0.1.0 → 0.2.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.
Files changed (38) hide show
  1. package/dist/core/analyzer/ai/context.d.ts +29 -0
  2. package/dist/core/analyzer/ai/context.d.ts.map +1 -0
  3. package/dist/core/analyzer/ai/context.js +413 -0
  4. package/dist/core/analyzer/ai/context.js.map +1 -0
  5. package/dist/core/analyzer/ai/index.d.ts +24 -6
  6. package/dist/core/analyzer/ai/index.d.ts.map +1 -1
  7. package/dist/core/analyzer/ai/index.js +191 -97
  8. package/dist/core/analyzer/ai/index.js.map +1 -1
  9. package/dist/core/analyzer/ai/passes.d.ts +14 -0
  10. package/dist/core/analyzer/ai/passes.d.ts.map +1 -0
  11. package/dist/core/analyzer/ai/passes.js +202 -0
  12. package/dist/core/analyzer/ai/passes.js.map +1 -0
  13. package/dist/core/analyzer/ai/slices.d.ts +40 -0
  14. package/dist/core/analyzer/ai/slices.d.ts.map +1 -0
  15. package/dist/core/analyzer/ai/slices.js +263 -0
  16. package/dist/core/analyzer/ai/slices.js.map +1 -0
  17. package/dist/core/analyzer/dependency/index.d.ts +64 -0
  18. package/dist/core/analyzer/dependency/index.d.ts.map +1 -0
  19. package/dist/core/analyzer/dependency/index.js +423 -0
  20. package/dist/core/analyzer/dependency/index.js.map +1 -0
  21. package/dist/core/analyzer/index.d.ts +1 -0
  22. package/dist/core/analyzer/index.d.ts.map +1 -1
  23. package/dist/core/analyzer/index.js +17 -8
  24. package/dist/core/analyzer/index.js.map +1 -1
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js +3 -0
  27. package/dist/index.js.map +1 -1
  28. package/dist/types/index.d.ts +78 -0
  29. package/dist/types/index.d.ts.map +1 -1
  30. package/dist/utils/index.d.ts +1 -0
  31. package/dist/utils/index.d.ts.map +1 -1
  32. package/dist/utils/index.js +6 -0
  33. package/dist/utils/index.js.map +1 -1
  34. package/dist/utils/logger.d.ts +19 -0
  35. package/dist/utils/logger.d.ts.map +1 -0
  36. package/dist/utils/logger.js +62 -0
  37. package/dist/utils/logger.js.map +1 -0
  38. package/package.json +1 -1
@@ -1,55 +1,20 @@
1
1
  "use strict";
2
2
  /**
3
3
  * AI Analyzer module
4
- * Uses OpenRouter to perform AI-powered code review
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
- /** Maximum file size to include in AI analysis (100KB) */
48
- const MAX_FILE_SIZE_FOR_AI = 100 * 1024;
49
- /** Maximum total content size to send to AI (500KB) */
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");
15
+ const logger_js_1 = require("../../../utils/logger.js");
51
16
  /**
52
- * AI-powered code analyzer using OpenRouter
17
+ * Multi-pass AI-powered code analyzer using OpenRouter
53
18
  */
54
19
  class AIAnalyzer extends types_js_1.BaseAnalyzer {
55
20
  constructor(config) {
@@ -57,12 +22,16 @@ class AIAnalyzer extends types_js_1.BaseAnalyzer {
57
22
  this.config = config;
58
23
  this.name = 'ai';
59
24
  this.phase = 'ai';
60
- this.description = 'AI-powered code review using OpenRouter';
25
+ this.description = 'Multi-pass AI-powered code review using OpenRouter';
26
+ /** Store static analysis findings from previous phase */
27
+ this.staticFindings = [];
61
28
  }
62
29
  async analyze(context) {
63
30
  const startTime = Date.now();
31
+ const logger = (0, logger_js_1.getGlobalLogger)();
64
32
  // Check for API key
65
33
  if (!(0, index_js_1.hasOpenRouterKey)()) {
34
+ logger.warn('OPENROUTER_API_KEY not set - skipping AI analysis');
66
35
  return this.createResult([
67
36
  {
68
37
  ruleId: 'ai/no-api-key',
@@ -72,35 +41,69 @@ class AIAnalyzer extends types_js_1.BaseAnalyzer {
72
41
  },
73
42
  ], startTime, { skipped: true, reason: 'no-api-key' });
74
43
  }
44
+ if (context.files.length === 0) {
45
+ logger.warn('No files to analyze');
46
+ return this.createResult([], startTime, {
47
+ skipped: true,
48
+ reason: 'no-files',
49
+ });
50
+ }
75
51
  try {
76
- // Load file contents
77
- const filesWithContent = await this.loadFileContents(context.files);
78
- if (filesWithContent.length === 0) {
79
- return this.createResult([], startTime, {
80
- skipped: true,
81
- reason: 'no-files',
82
- });
52
+ logger.phase('AI Analysis (Multi-Pass)');
53
+ logger.step(`Model: ${this.config.model}`);
54
+ logger.step(`Files in codebase: ${context.files.length}`);
55
+ // Get dependency graph from static phase results (if available)
56
+ const graph = this.getDependencyGraph(context) || (0, context_js_1.createEmptyGraph)(context.files);
57
+ // Log graph stats
58
+ const graphStats = {
59
+ entryPoints: graph.entryPoints.length,
60
+ configFiles: graph.configFiles.length,
61
+ apiFiles: graph.apiFiles.length,
62
+ };
63
+ logger.detail(`Dependency graph: ${graphStats.entryPoints} entry points, ${graphStats.configFiles} configs, ${graphStats.apiFiles} API routes`);
64
+ // Collect static findings for context
65
+ this.staticFindings = this.getStaticFindings(context);
66
+ if (this.staticFindings.length > 0) {
67
+ logger.detail(`Static findings to incorporate: ${this.staticFindings.length}`);
83
68
  }
84
- // Build the prompt
85
- const userPrompt = (0, prompts_js_1.buildUserPrompt)(filesWithContent, context.frameworks, this.config.customPrompt);
86
- // Call AI
87
- const apiKey = (0, index_js_1.getOpenRouterKey)();
88
- const response = await (0, openrouter_js_1.chat)(prompts_js_1.DEFAULT_SYSTEM_PROMPT, userPrompt, this.config, apiKey);
89
- // Parse response
90
- const parsed = (0, prompts_js_1.parseAIResponse)(response);
91
- // Convert to findings
92
- const findings = parsed.findings.map((f) => ({
93
- ruleId: f.ruleId,
94
- severity: f.severity,
95
- file: f.file,
96
- line: f.line,
97
- message: f.message,
98
- suggestion: f.suggestion,
99
- }));
100
- return this.createResult(findings, startTime, {
69
+ // Run all passes
70
+ const allPassResults = [];
71
+ const allFindings = [];
72
+ // Pass 1: Architecture
73
+ logger.step('Pass 1/3: Architecture Review');
74
+ const archResult = await this.runPass('architecture', context, graph, allFindings);
75
+ allPassResults.push(archResult);
76
+ allFindings.push(...archResult.findings);
77
+ logger.success(`Architecture: ${archResult.findings.length} findings`);
78
+ // Pass 2: Deep Dive
79
+ logger.step('Pass 2/3: Deep Dive Review');
80
+ const deepResult = await this.runPass('deep-dive', context, graph, allFindings);
81
+ allPassResults.push(deepResult);
82
+ allFindings.push(...deepResult.findings);
83
+ logger.success(`Deep-dive: ${deepResult.findings.length} findings`);
84
+ // Pass 3: Security
85
+ logger.step('Pass 3/3: Security Review');
86
+ const secResult = await this.runPass('security', context, graph, allFindings);
87
+ allPassResults.push(secResult);
88
+ allFindings.push(...secResult.findings);
89
+ logger.success(`Security: ${secResult.findings.length} findings`);
90
+ // Deduplicate findings
91
+ const dedupedFindings = this.deduplicateFindings(allFindings);
92
+ if (allFindings.length !== dedupedFindings.length) {
93
+ logger.detail(`Deduplicated: ${allFindings.length} → ${dedupedFindings.length} findings`);
94
+ }
95
+ // Combine summaries
96
+ const combinedSummary = allPassResults
97
+ .map((r) => `**${r.pass}**: ${r.summary}`)
98
+ .join('\n\n');
99
+ const duration = Date.now() - startTime;
100
+ logger.success(`AI analysis complete in ${(duration / 1000).toFixed(1)}s`);
101
+ return this.createResult(dedupedFindings, startTime, {
101
102
  model: this.config.model,
102
- summary: parsed.summary,
103
- filesAnalyzed: filesWithContent.length,
103
+ summary: combinedSummary,
104
+ passResults: allPassResults,
105
+ filesAnalyzed: context.files.length,
106
+ multiPass: true,
104
107
  });
105
108
  }
106
109
  catch (error) {
@@ -110,6 +113,7 @@ class AIAnalyzer extends types_js_1.BaseAnalyzer {
110
113
  : error instanceof Error
111
114
  ? error.message
112
115
  : 'Unknown error during AI analysis';
116
+ logger.warn(`AI analysis failed: ${errorMessage}`);
113
117
  return this.createResult([
114
118
  {
115
119
  ruleId: 'ai/error',
@@ -121,41 +125,131 @@ class AIAnalyzer extends types_js_1.BaseAnalyzer {
121
125
  }
122
126
  }
123
127
  /**
124
- * Load file contents for AI analysis
125
- * Respects size limits and filters appropriately
128
+ * Run a single AI pass
126
129
  */
127
- async loadFileContents(files) {
128
- const result = [];
129
- let totalSize = 0;
130
- // Sort by size (smaller files first) to maximize coverage
131
- const sortedFiles = [...files].sort((a, b) => a.size - b.size);
132
- for (const file of sortedFiles) {
133
- // Skip files that are too large
134
- if (file.size > MAX_FILE_SIZE_FOR_AI) {
135
- continue;
136
- }
137
- // Check total size limit
138
- if (totalSize + file.size > MAX_TOTAL_CONTENT_SIZE) {
130
+ async runPass(passType, context, graph, previousFindings) {
131
+ const logger = (0, logger_js_1.getGlobalLogger)();
132
+ // Build context for this pass
133
+ let reviewContext;
134
+ switch (passType) {
135
+ case 'architecture':
136
+ reviewContext = await (0, context_js_1.buildArchitectureContext)(context, graph);
139
137
  break;
138
+ case 'deep-dive':
139
+ reviewContext = await (0, context_js_1.buildDeepDiveContext)(context, graph, this.staticFindings, previousFindings.filter((f) => f.ruleId.startsWith('ai/arch')));
140
+ break;
141
+ case 'security':
142
+ reviewContext = await (0, context_js_1.buildSecurityContext)(context, graph);
143
+ break;
144
+ }
145
+ // Log context details
146
+ logger.detail(`Sending ${reviewContext.files.length} files (~${Math.round(reviewContext.metadata.totalTokenEstimate / 1000)}K tokens)`);
147
+ if (reviewContext.files.length > 0 && reviewContext.files.length <= 5) {
148
+ for (const file of reviewContext.files) {
149
+ logger.detail(` ${file.path} (${file.reason})`);
140
150
  }
141
- try {
142
- // Load content if not already loaded
143
- let content = file.content;
144
- if (content === undefined) {
145
- content = await fs.promises.readFile(file.path, 'utf-8');
146
- }
147
- result.push({
148
- ...file,
149
- content,
150
- });
151
- totalSize += file.size;
151
+ }
152
+ else if (reviewContext.files.length > 5) {
153
+ for (const file of reviewContext.files.slice(0, 3)) {
154
+ logger.detail(` ${file.path} (${file.reason})`);
155
+ }
156
+ logger.detail(` ... and ${reviewContext.files.length - 3} more files`);
157
+ }
158
+ // Skip if no files to review
159
+ if (reviewContext.files.length === 0) {
160
+ logger.warn(`No relevant files for ${passType} review`);
161
+ return {
162
+ pass: passType,
163
+ findings: [],
164
+ summary: `No relevant files for ${passType} review`,
165
+ };
166
+ }
167
+ // Build prompts
168
+ const systemPrompt = passes_js_1.PASS_SYSTEM_PROMPTS[passType];
169
+ const userPrompt = (0, passes_js_1.buildPassPrompt)(reviewContext, this.config.customPrompt);
170
+ // Call AI
171
+ logger.detail('Calling AI...');
172
+ const callStart = Date.now();
173
+ const apiKey = (0, index_js_1.getOpenRouterKey)();
174
+ const response = await (0, openrouter_js_1.chat)(systemPrompt, userPrompt, this.config, apiKey);
175
+ const callDuration = Date.now() - callStart;
176
+ logger.detail(`AI responded in ${(callDuration / 1000).toFixed(1)}s`);
177
+ // Parse response
178
+ const parsed = (0, prompts_js_1.parseAIResponse)(response);
179
+ // Convert to findings with proper severity types
180
+ const findings = parsed.findings.map((f) => ({
181
+ ruleId: f.ruleId,
182
+ severity: f.severity,
183
+ file: f.file,
184
+ line: f.line,
185
+ message: f.message,
186
+ suggestion: f.suggestion,
187
+ }));
188
+ return {
189
+ pass: passType,
190
+ findings,
191
+ summary: parsed.summary,
192
+ };
193
+ }
194
+ /**
195
+ * Get dependency graph from context or previous results
196
+ */
197
+ getDependencyGraph(context) {
198
+ // The dependency graph is stored in the context by the pipeline
199
+ // after the static phase runs
200
+ const metadata = context._previousResults;
201
+ if (metadata) {
202
+ return (0, context_js_1.getDependencyGraphFromResults)(metadata);
203
+ }
204
+ return null;
205
+ }
206
+ /**
207
+ * Get static findings from previous phase
208
+ */
209
+ getStaticFindings(context) {
210
+ const metadata = context._previousResults;
211
+ if (!metadata)
212
+ return [];
213
+ const staticResult = metadata.find((r) => r.analyzerName === 'static');
214
+ return staticResult?.findings || [];
215
+ }
216
+ /**
217
+ * Deduplicate findings from multiple passes
218
+ * Keeps the highest severity if duplicates found
219
+ */
220
+ deduplicateFindings(findings) {
221
+ const seen = new Map();
222
+ const severityOrder = {
223
+ error: 4,
224
+ warning: 3,
225
+ info: 2,
226
+ hint: 1,
227
+ };
228
+ for (const finding of findings) {
229
+ // Create a key based on file, line, and message similarity
230
+ const key = `${finding.file}:${finding.line || 0}:${this.normalizeMessage(finding.message)}`;
231
+ const existing = seen.get(key);
232
+ if (!existing) {
233
+ seen.set(key, finding);
152
234
  }
153
- catch {
154
- // Skip files that can't be read
155
- continue;
235
+ else {
236
+ // Keep the one with higher severity
237
+ if (severityOrder[finding.severity] > severityOrder[existing.severity]) {
238
+ seen.set(key, finding);
239
+ }
156
240
  }
157
241
  }
158
- return result;
242
+ return Array.from(seen.values());
243
+ }
244
+ /**
245
+ * Normalize message for deduplication comparison
246
+ */
247
+ normalizeMessage(message) {
248
+ return message
249
+ .toLowerCase()
250
+ .replace(/\s+/g, ' ')
251
+ .replace(/[^a-z0-9 ]/g, '')
252
+ .slice(0, 50);
159
253
  }
160
254
  }
161
255
  exports.AIAnalyzer = AIAnalyzer;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/analyzer/ai/index.ts"],"names":[],"mappings":"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"}
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