lamps-code-review 0.1.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.
Files changed (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +357 -0
  3. package/bin/lamps-review.js +7 -0
  4. package/dist/cli/commands/review.d.ts +9 -0
  5. package/dist/cli/commands/review.d.ts.map +1 -0
  6. package/dist/cli/commands/review.js +149 -0
  7. package/dist/cli/commands/review.js.map +1 -0
  8. package/dist/cli/index.d.ts +7 -0
  9. package/dist/cli/index.d.ts.map +1 -0
  10. package/dist/cli/index.js +41 -0
  11. package/dist/cli/index.js.map +1 -0
  12. package/dist/core/analyzer/ai/index.d.ts +28 -0
  13. package/dist/core/analyzer/ai/index.d.ts.map +1 -0
  14. package/dist/core/analyzer/ai/index.js +171 -0
  15. package/dist/core/analyzer/ai/index.js.map +1 -0
  16. package/dist/core/analyzer/ai/openrouter.d.ts +26 -0
  17. package/dist/core/analyzer/ai/openrouter.d.ts.map +1 -0
  18. package/dist/core/analyzer/ai/openrouter.js +77 -0
  19. package/dist/core/analyzer/ai/openrouter.js.map +1 -0
  20. package/dist/core/analyzer/ai/prompts.d.ts +32 -0
  21. package/dist/core/analyzer/ai/prompts.d.ts.map +1 -0
  22. package/dist/core/analyzer/ai/prompts.js +171 -0
  23. package/dist/core/analyzer/ai/prompts.js.map +1 -0
  24. package/dist/core/analyzer/index.d.ts +67 -0
  25. package/dist/core/analyzer/index.d.ts.map +1 -0
  26. package/dist/core/analyzer/index.js +224 -0
  27. package/dist/core/analyzer/index.js.map +1 -0
  28. package/dist/core/analyzer/static/index.d.ts +21 -0
  29. package/dist/core/analyzer/static/index.d.ts.map +1 -0
  30. package/dist/core/analyzer/static/index.js +69 -0
  31. package/dist/core/analyzer/static/index.js.map +1 -0
  32. package/dist/core/analyzer/types.d.ts +70 -0
  33. package/dist/core/analyzer/types.d.ts.map +1 -0
  34. package/dist/core/analyzer/types.js +27 -0
  35. package/dist/core/analyzer/types.js.map +1 -0
  36. package/dist/core/config/index.d.ts +28 -0
  37. package/dist/core/config/index.d.ts.map +1 -0
  38. package/dist/core/config/index.js +109 -0
  39. package/dist/core/config/index.js.map +1 -0
  40. package/dist/core/detector/index.d.ts +10 -0
  41. package/dist/core/detector/index.d.ts.map +1 -0
  42. package/dist/core/detector/index.js +306 -0
  43. package/dist/core/detector/index.js.map +1 -0
  44. package/dist/core/reporter/formats/json.d.ts +13 -0
  45. package/dist/core/reporter/formats/json.d.ts.map +1 -0
  46. package/dist/core/reporter/formats/json.js +23 -0
  47. package/dist/core/reporter/formats/json.js.map +1 -0
  48. package/dist/core/reporter/index.d.ts +15 -0
  49. package/dist/core/reporter/index.d.ts.map +1 -0
  50. package/dist/core/reporter/index.js +183 -0
  51. package/dist/core/reporter/index.js.map +1 -0
  52. package/dist/core/scanner/ignore-rules.d.ts +13 -0
  53. package/dist/core/scanner/ignore-rules.d.ts.map +1 -0
  54. package/dist/core/scanner/ignore-rules.js +162 -0
  55. package/dist/core/scanner/ignore-rules.js.map +1 -0
  56. package/dist/core/scanner/index.d.ts +16 -0
  57. package/dist/core/scanner/index.d.ts.map +1 -0
  58. package/dist/core/scanner/index.js +191 -0
  59. package/dist/core/scanner/index.js.map +1 -0
  60. package/dist/index.d.ts +51 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +126 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/types/index.d.ts +188 -0
  65. package/dist/types/index.d.ts.map +1 -0
  66. package/dist/types/index.js +13 -0
  67. package/dist/types/index.js.map +1 -0
  68. package/dist/utils/index.d.ts +54 -0
  69. package/dist/utils/index.d.ts.map +1 -0
  70. package/dist/utils/index.js +159 -0
  71. package/dist/utils/index.js.map +1 -0
  72. package/package.json +61 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Lamps (AppleLamps)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,357 @@
1
+ # LampsCodeReview
2
+
3
+ > AI-powered code review SDK and CLI for modern web codebases
4
+
5
+ [![GitHub](https://img.shields.io/badge/GitHub-AppleLamps-black?logo=github)](https://github.com/AppleLamps)
6
+ [![X (Twitter)](https://img.shields.io/badge/X-@lamps__apple-black?logo=x)](https://x.com/lamps_apple)
7
+
8
+ LampsCodeReview analyzes your codebase using AI to identify security vulnerabilities, performance issues, bugs, and code quality problems. It supports Next.js, React, TypeScript, JavaScript, and Python projects.
9
+
10
+ ## Features
11
+
12
+ - **AI-Powered Analysis** - Uses OpenRouter to access Claude, GPT-4, Gemini, and other models
13
+ - **Full Codebase Context** - Sends entire codebase to AI for holistic understanding of file interactions
14
+ - **Framework Detection** - Automatically detects Next.js, React, Express, FastAPI, Django, and more
15
+ - **Configurable Models** - Easily switch between AI models via config file or CLI flag
16
+ - **Multiple Output Formats** - JSON, Markdown, and HTML reports
17
+ - **Dual Interface** - Use as CLI tool or import as SDK
18
+ - **Extensible** - Add custom analyzers for project-specific rules
19
+
20
+ ## Quick Start
21
+
22
+ ```bash
23
+ # Install
24
+ npm install lamps-code-review
25
+
26
+ # Set API key
27
+ export OPENROUTER_API_KEY=your-key-here
28
+
29
+ # Run review
30
+ lamps-review ./my-project
31
+ ```
32
+
33
+ ## Installation
34
+
35
+ ```bash
36
+ npm install lamps-code-review
37
+ ```
38
+
39
+ Or install globally:
40
+
41
+ ```bash
42
+ npm install -g lamps-code-review
43
+ ```
44
+
45
+ ## Setup
46
+
47
+ Get an API key from [OpenRouter](https://openrouter.ai/) and set it as an environment variable:
48
+
49
+ ```bash
50
+ # Linux/macOS
51
+ export OPENROUTER_API_KEY=your-api-key-here
52
+
53
+ # Windows (PowerShell)
54
+ $env:OPENROUTER_API_KEY="your-api-key-here"
55
+
56
+ # Windows (CMD)
57
+ set OPENROUTER_API_KEY=your-api-key-here
58
+ ```
59
+
60
+ ## CLI Usage
61
+
62
+ ```bash
63
+ # Review current directory
64
+ lamps-review
65
+
66
+ # Review a specific path
67
+ lamps-review ./my-project
68
+
69
+ # Use a different AI model
70
+ lamps-review ./my-project --model openai/gpt-4o
71
+
72
+ # Save report to file
73
+ lamps-review ./my-project --output report.json
74
+
75
+ # Markdown report
76
+ lamps-review ./my-project --format markdown --output report.md
77
+
78
+ # Verbose mode (shows progress)
79
+ lamps-review ./my-project --verbose
80
+ ```
81
+
82
+ ### CLI Options
83
+
84
+ | Option | Description |
85
+ |--------|-------------|
86
+ | `-o, --output <file>` | Write report to file |
87
+ | `-f, --format <format>` | Output format: `json`, `markdown`, `html` |
88
+ | `-m, --model <model>` | Override AI model (e.g., `openai/gpt-4o`) |
89
+ | `-v, --verbose` | Enable verbose output |
90
+ | `-c, --config <file>` | Path to config file |
91
+
92
+ ### Example Output
93
+
94
+ ```
95
+ 🔍 LampsCodeReview - Analyzing: ./my-project
96
+
97
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
98
+ 📊 Review Summary
99
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
100
+
101
+ 🟢 Health Score: 85/100
102
+ 📁 Files Analyzed: 24
103
+
104
+ 🔧 Frameworks Detected:
105
+ • typescript (95%)
106
+ • react (90%)
107
+ • nextjs (85%)
108
+
109
+ 📋 Findings:
110
+ ⚠️ Warnings: 3
111
+ ℹ️ Info: 5
112
+
113
+ ⏱️ Completed in 18543ms
114
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
115
+ ```
116
+
117
+ ## Configuration
118
+
119
+ Create a `lamps.config.json` in your project root:
120
+
121
+ ```json
122
+ {
123
+ "ai": {
124
+ "model": "minimax/minimax-m2.1",
125
+ "customPrompt": "Focus on security and performance issues",
126
+ "maxTokens": 4096,
127
+ "temperature": 0.3
128
+ },
129
+ "scan": {
130
+ "ignorePatterns": ["*.test.ts", "*.spec.ts", "**/__mocks__/**"],
131
+ "maxFileSize": 102400,
132
+ "includeExtensions": [".ts", ".tsx", ".js", ".jsx", ".py"]
133
+ },
134
+ "format": "json"
135
+ }
136
+ ```
137
+
138
+ ### Configuration Reference
139
+
140
+ #### AI Options
141
+
142
+ | Option | Type | Default | Description |
143
+ |--------|------|---------|-------------|
144
+ | `model` | string | `minimax/minimax-m2.1` | OpenRouter model ID |
145
+ | `customPrompt` | string | - | Additional instructions for the AI reviewer |
146
+ | `maxTokens` | number | `150000` | Maximum tokens in AI response |
147
+ | `temperature` | number | `0.3` | AI temperature (0-1, lower = more focused) |
148
+
149
+ #### Scan Options
150
+
151
+ | Option | Type | Default | Description |
152
+ |--------|------|---------|-------------|
153
+ | `ignorePatterns` | string[] | `[]` | Glob patterns to ignore |
154
+ | `maxFileSize` | number | `1048576` | Max file size in bytes (default 1MB) |
155
+ | `includeExtensions` | string[] | - | Only include these extensions |
156
+ | `useGitignore` | boolean | `true` | Respect .gitignore files |
157
+
158
+ ### Available Models
159
+
160
+ Any model on [OpenRouter](https://openrouter.ai/models) works, including:
161
+
162
+ | Model | ID | Best For |
163
+ |-------|-----|----------|
164
+ | MiniMax M2.1 | `minimax/minimax-m2.1` | Large context, fast (default) |
165
+ | Claude Sonnet 4 | `anthropic/claude-sonnet-4` | Balanced quality/speed |
166
+ | Claude Opus 4 | `anthropic/claude-opus-4` | Highest quality |
167
+ | GPT-4o | `openai/gpt-4o` | Fast, good quality |
168
+ | Gemini 2.0 Flash | `google/gemini-2.0-flash-thinking-exp-1219` | Very fast |
169
+ | Llama 3.1 405B | `meta-llama/llama-3.1-405b-instruct` | Open source |
170
+
171
+ ## SDK Usage
172
+
173
+ ```typescript
174
+ import { LampsCodeReview } from 'lamps-code-review';
175
+
176
+ // Basic usage
177
+ const reviewer = new LampsCodeReview();
178
+ const report = await reviewer.review('./my-project');
179
+
180
+ console.log(`Health Score: ${report.summary.healthScore}/100`);
181
+ console.log(`Findings: ${report.summary.totalFindings}`);
182
+
183
+ // With configuration
184
+ const reviewer = new LampsCodeReview({
185
+ verbose: true,
186
+ ai: {
187
+ model: 'openai/gpt-4o',
188
+ customPrompt: 'Focus on security vulnerabilities',
189
+ },
190
+ scan: {
191
+ ignorePatterns: ['*.test.ts'],
192
+ maxFileSize: 500 * 1024,
193
+ },
194
+ });
195
+
196
+ const report = await reviewer.review('./my-project');
197
+
198
+ // Format report
199
+ const json = reviewer.formatReport(report, 'json');
200
+ const markdown = reviewer.formatReport(report, 'markdown');
201
+ ```
202
+
203
+ ### Custom Analyzers
204
+
205
+ Add your own analysis rules:
206
+
207
+ ```typescript
208
+ import { LampsCodeReview, BaseAnalyzer } from 'lamps-code-review';
209
+ import type { AnalysisContext, AnalysisResult } from 'lamps-code-review';
210
+
211
+ class MyCustomAnalyzer extends BaseAnalyzer {
212
+ readonly name = 'my-analyzer';
213
+ readonly phase = 'static'; // 'static' | 'ai' | 'post'
214
+ readonly description = 'My custom analysis rules';
215
+
216
+ async analyze(context: AnalysisContext): Promise<AnalysisResult> {
217
+ const startTime = Date.now();
218
+ const findings = [];
219
+
220
+ // Your analysis logic here
221
+ for (const file of context.files) {
222
+ if (file.relativePath.includes('TODO')) {
223
+ findings.push({
224
+ ruleId: 'my-analyzer/todo-file',
225
+ severity: 'warning',
226
+ file: file.relativePath,
227
+ message: 'File contains TODO in name',
228
+ });
229
+ }
230
+ }
231
+
232
+ return this.createResult(findings, startTime);
233
+ }
234
+ }
235
+
236
+ const reviewer = new LampsCodeReview();
237
+ reviewer.registerAnalyzer(new MyCustomAnalyzer());
238
+ ```
239
+
240
+ ## What Gets Analyzed
241
+
242
+ The AI reviewer checks for:
243
+
244
+ - **Security** - SQL injection, XSS, command injection, auth issues, secrets exposure
245
+ - **Bugs** - Logic errors, null handling, race conditions, off-by-one errors
246
+ - **Performance** - N+1 queries, memory leaks, unnecessary re-renders, inefficient algorithms
247
+ - **Code Quality** - Complexity, readability, maintainability, code smells
248
+ - **Best Practices** - Framework patterns, TypeScript/Python idioms, error handling
249
+ - **Architecture** - Coupling, cohesion, separation of concerns
250
+
251
+ ## Report Structure
252
+
253
+ ```typescript
254
+ interface ReviewReport {
255
+ version: string;
256
+ timestamp: string;
257
+ repository: {
258
+ path: string;
259
+ filesAnalyzed: number;
260
+ };
261
+ frameworks: {
262
+ frameworks: FrameworkDetection[];
263
+ primary: Framework | null;
264
+ languages: string[];
265
+ };
266
+ summary: {
267
+ totalFindings: number;
268
+ bySeverity: Record<Severity, number>;
269
+ byAnalyzer: Record<string, number>;
270
+ healthScore: number; // 0-100
271
+ };
272
+ findings: Finding[];
273
+ analyzerResults: AnalysisResult[];
274
+ }
275
+
276
+ interface Finding {
277
+ ruleId: string; // e.g., 'ai/security-sql-injection'
278
+ severity: 'error' | 'warning' | 'info' | 'hint';
279
+ file: string;
280
+ line?: number;
281
+ message: string;
282
+ suggestion?: string;
283
+ }
284
+ ```
285
+
286
+ ## Development
287
+
288
+ ```bash
289
+ # Clone the repo
290
+ git clone https://github.com/AppleLamps/lamps-code-review.git
291
+ cd lamps-code-review
292
+
293
+ # Install dependencies
294
+ npm install
295
+
296
+ # Build
297
+ npm run build
298
+
299
+ # Run tests
300
+ npm test
301
+
302
+ # Type check
303
+ npm run lint
304
+
305
+ # Run locally
306
+ node bin/lamps-review.js ./path/to/project
307
+ ```
308
+
309
+ ## Architecture
310
+
311
+ ```
312
+ src/
313
+ ├── index.ts # SDK entry point
314
+ ├── cli/ # CLI implementation
315
+ │ ├── index.ts # Command parsing
316
+ │ └── commands/
317
+ │ └── review.ts # Review command
318
+ ├── core/
319
+ │ ├── config/ # Configuration loading
320
+ │ ├── scanner/ # Repository scanning
321
+ │ ├── detector/ # Framework detection
322
+ │ ├── analyzer/
323
+ │ │ ├── static/ # Static analysis rules
324
+ │ │ └── ai/ # AI-powered analysis
325
+ │ │ ├── openrouter.ts # OpenRouter client
326
+ │ │ └── prompts.ts # Review prompts
327
+ │ └── reporter/ # Report generation
328
+ ├── types/ # TypeScript types
329
+ └── utils/ # Common utilities
330
+ ```
331
+
332
+ ## Troubleshooting
333
+
334
+ ### "OPENROUTER_API_KEY not set"
335
+
336
+ Make sure you've exported the environment variable in your current shell session.
337
+
338
+ ### AI analysis is slow
339
+
340
+ - Large codebases take longer (all files are sent for context)
341
+ - Try a faster model: `--model google/gemini-2.0-flash-thinking-exp-1219`
342
+ - Use `--verbose` to see progress
343
+
344
+ ### Files are being skipped
345
+
346
+ Check your `.gitignore` and `lamps.config.json` ignore patterns. Use `--verbose` to see which files are scanned.
347
+
348
+ ## Author
349
+
350
+ **Lamps** - [@lamps_apple](https://x.com/lamps_apple)
351
+
352
+ - GitHub: [AppleLamps](https://github.com/AppleLamps)
353
+ - X: [@lamps_apple](https://x.com/lamps_apple)
354
+
355
+ ## License
356
+
357
+ MIT
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI executable shim
4
+ * This file is the entry point for the `lamps-review` command
5
+ */
6
+
7
+ import('../dist/cli/index.js');
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Review command implementation
3
+ */
4
+ import type { CLIOptions } from '../../types/index.js';
5
+ /**
6
+ * Execute the review command
7
+ */
8
+ export declare function executeReview(targetPath: string, options: CLIOptions): Promise<void>;
9
+ //# sourceMappingURL=review.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/review.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAgB,MAAM,sBAAsB,CAAC;AAErE;;GAEG;AACH,wBAAsB,aAAa,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,IAAI,CAAC,CAoDf"}
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ /**
3
+ * Review command implementation
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.executeReview = executeReview;
40
+ const fs = __importStar(require("node:fs"));
41
+ const path = __importStar(require("node:path"));
42
+ const index_js_1 = require("../../index.js");
43
+ /**
44
+ * Execute the review command
45
+ */
46
+ async function executeReview(targetPath, options) {
47
+ const absolutePath = path.resolve(targetPath);
48
+ // Validate path exists
49
+ if (!fs.existsSync(absolutePath)) {
50
+ console.error(`Error: Path does not exist: ${absolutePath}`);
51
+ process.exit(1);
52
+ }
53
+ console.log(`\n🔍 LampsCodeReview - Analyzing: ${absolutePath}\n`);
54
+ // Show AI model info
55
+ if (options.model) {
56
+ console.log(`🤖 AI Model: ${options.model}\n`);
57
+ }
58
+ try {
59
+ // Create reviewer instance
60
+ const reviewer = new index_js_1.LampsCodeReview({
61
+ verbose: options.verbose,
62
+ format: options.format,
63
+ output: options.output,
64
+ ai: options.model ? { model: options.model } : undefined,
65
+ });
66
+ // Run the review
67
+ const startTime = Date.now();
68
+ const report = await reviewer.review(absolutePath);
69
+ const duration = Date.now() - startTime;
70
+ // Output results
71
+ if (options.output) {
72
+ // Write to file
73
+ const formatted = reviewer.formatReport(report, options.format || 'json');
74
+ fs.writeFileSync(options.output, formatted);
75
+ console.log(`📄 Report written to: ${options.output}`);
76
+ }
77
+ else {
78
+ // Print summary to console
79
+ printSummary(report, duration);
80
+ }
81
+ // Exit with error code if there are errors
82
+ if (report.summary.bySeverity.error > 0) {
83
+ process.exit(1);
84
+ }
85
+ }
86
+ catch (error) {
87
+ console.error('Error during review:', error);
88
+ process.exit(1);
89
+ }
90
+ }
91
+ /**
92
+ * Print a summary of the review to console
93
+ */
94
+ function printSummary(report, duration) {
95
+ console.log('━'.repeat(50));
96
+ console.log('📊 Review Summary');
97
+ console.log('━'.repeat(50));
98
+ // Health score with color
99
+ const score = report.summary.healthScore;
100
+ const scoreColor = score >= 80 ? '🟢' : score >= 50 ? '🟡' : '🔴';
101
+ console.log(`\n${scoreColor} Health Score: ${score}/100`);
102
+ // Files analyzed
103
+ console.log(`📁 Files Analyzed: ${report.repository.filesAnalyzed}`);
104
+ // Frameworks detected
105
+ if (report.frameworks.frameworks.length > 0) {
106
+ console.log('\n🔧 Frameworks Detected:');
107
+ for (const fw of report.frameworks.frameworks) {
108
+ const confidence = Math.round(fw.confidence * 100);
109
+ console.log(` • ${fw.framework} (${confidence}%)`);
110
+ }
111
+ }
112
+ // Findings summary
113
+ const { bySeverity } = report.summary;
114
+ console.log('\n📋 Findings:');
115
+ if (bySeverity.error > 0)
116
+ console.log(` ❌ Errors: ${bySeverity.error}`);
117
+ if (bySeverity.warning > 0)
118
+ console.log(` ⚠️ Warnings: ${bySeverity.warning}`);
119
+ if (bySeverity.info > 0)
120
+ console.log(` ℹ️ Info: ${bySeverity.info}`);
121
+ if (bySeverity.hint > 0)
122
+ console.log(` 💡 Hints: ${bySeverity.hint}`);
123
+ if (report.summary.totalFindings === 0) {
124
+ console.log(' ✨ No issues found!');
125
+ }
126
+ // Print individual findings
127
+ if (report.findings.length > 0 && report.findings.length <= 10) {
128
+ console.log('\n📝 Details:');
129
+ for (const finding of report.findings) {
130
+ const icon = finding.severity === 'error'
131
+ ? '❌'
132
+ : finding.severity === 'warning'
133
+ ? '⚠️'
134
+ : finding.severity === 'info'
135
+ ? 'ℹ️'
136
+ : '💡';
137
+ console.log(`\n ${icon} [${finding.ruleId}]`);
138
+ console.log(` ${finding.file}${finding.line ? `:${finding.line}` : ''}`);
139
+ console.log(` ${finding.message}`);
140
+ }
141
+ }
142
+ else if (report.findings.length > 10) {
143
+ console.log(`\n (${report.findings.length} findings - use --output to see all)`);
144
+ }
145
+ // Duration
146
+ console.log(`\n⏱️ Completed in ${duration}ms`);
147
+ console.log('━'.repeat(50));
148
+ }
149
+ //# sourceMappingURL=review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.js","sourceRoot":"","sources":["../../../src/cli/commands/review.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * LampsCodeReview CLI
4
+ * Command-line interface for running code reviews
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;GAGG"}
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * LampsCodeReview CLI
5
+ * Command-line interface for running code reviews
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ const commander_1 = require("commander");
9
+ const review_js_1 = require("./commands/review.js");
10
+ // Package version (will be replaced by actual version in production)
11
+ const VERSION = '0.1.0';
12
+ const program = new commander_1.Command();
13
+ program
14
+ .name('lamps-review')
15
+ .description('AI-powered code review for modern web codebases')
16
+ .version(VERSION);
17
+ program
18
+ .command('review')
19
+ .description('Run a code review on a repository or directory')
20
+ .argument('<path>', 'Path to the repository or directory to review')
21
+ .option('-o, --output <file>', 'Write report to file instead of stdout')
22
+ .option('-f, --format <format>', 'Output format: json, markdown, html', 'json')
23
+ .option('-m, --model <model>', 'Override AI model (e.g., openai/gpt-4o)')
24
+ .option('-v, --verbose', 'Enable verbose output', false)
25
+ .option('-c, --config <file>', 'Path to config file')
26
+ .action(async (targetPath, options) => {
27
+ await (0, review_js_1.executeReview)(targetPath, options);
28
+ });
29
+ // Default command: run review on current directory
30
+ program
31
+ .argument('[path]', 'Path to review (defaults to current directory)', '.')
32
+ .option('-o, --output <file>', 'Write report to file instead of stdout')
33
+ .option('-f, --format <format>', 'Output format: json, markdown, html', 'json')
34
+ .option('-m, --model <model>', 'Override AI model (e.g., openai/gpt-4o)')
35
+ .option('-v, --verbose', 'Enable verbose output', false)
36
+ .action(async (targetPath, options) => {
37
+ await (0, review_js_1.executeReview)(targetPath, options);
38
+ });
39
+ // Parse and execute
40
+ program.parse();
41
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;AACA;;;GAGG;;AAEH,yCAAoC;AACpC,oDAAqD;AAErD,qEAAqE;AACrE,MAAM,OAAO,GAAG,OAAO,CAAC;AAExB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,cAAc,CAAC;KACpB,WAAW,CAAC,iDAAiD,CAAC;KAC9D,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,gDAAgD,CAAC;KAC7D,QAAQ,CAAC,QAAQ,EAAE,+CAA+C,CAAC;KACnE,MAAM,CAAC,qBAAqB,EAAE,wCAAwC,CAAC;KACvE,MAAM,CACL,uBAAuB,EACvB,qCAAqC,EACrC,MAAM,CACP;KACA,MAAM,CAAC,qBAAqB,EAAE,yCAAyC,CAAC;KACxE,MAAM,CAAC,eAAe,EAAE,uBAAuB,EAAE,KAAK,CAAC;KACvD,MAAM,CAAC,qBAAqB,EAAE,qBAAqB,CAAC;KACpD,MAAM,CAAC,KAAK,EAAE,UAAkB,EAAE,OAAO,EAAE,EAAE;IAC5C,MAAM,IAAA,yBAAa,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEL,mDAAmD;AACnD,OAAO;KACJ,QAAQ,CAAC,QAAQ,EAAE,gDAAgD,EAAE,GAAG,CAAC;KACzE,MAAM,CAAC,qBAAqB,EAAE,wCAAwC,CAAC;KACvE,MAAM,CACL,uBAAuB,EACvB,qCAAqC,EACrC,MAAM,CACP;KACA,MAAM,CAAC,qBAAqB,EAAE,yCAAyC,CAAC;KACxE,MAAM,CAAC,eAAe,EAAE,uBAAuB,EAAE,KAAK,CAAC;KACvD,MAAM,CAAC,KAAK,EAAE,UAAkB,EAAE,OAAO,EAAE,EAAE;IAC5C,MAAM,IAAA,yBAAa,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEL,oBAAoB;AACpB,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * AI Analyzer module
3
+ * Uses OpenRouter to perform AI-powered code review
4
+ */
5
+ import type { AnalysisContext, AnalysisResult, AIConfig } from '../../../types/index.js';
6
+ import { BaseAnalyzer } from '../types.js';
7
+ /**
8
+ * AI-powered code analyzer using OpenRouter
9
+ */
10
+ export declare class AIAnalyzer extends BaseAnalyzer {
11
+ private config;
12
+ readonly name = "ai";
13
+ readonly phase: "ai";
14
+ readonly description = "AI-powered code review using OpenRouter";
15
+ constructor(config: AIConfig);
16
+ analyze(context: AnalysisContext): Promise<AnalysisResult>;
17
+ /**
18
+ * Load file contents for AI analysis
19
+ * Respects size limits and filters appropriately
20
+ */
21
+ private loadFileContents;
22
+ }
23
+ /**
24
+ * Create an AI analyzer with the given configuration
25
+ */
26
+ export declare function createAIAnalyzer(config: AIConfig): AIAnalyzer;
27
+ export { OpenRouterError } from './openrouter.js';
28
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/analyzer/ai/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,QAAQ,EAAqB,MAAM,yBAAyB,CAAC;AAC5G,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAW3C;;GAEG;AACH,qBAAa,UAAW,SAAQ,YAAY;IAK9B,OAAO,CAAC,MAAM;IAJ1B,QAAQ,CAAC,IAAI,QAAQ;IACrB,QAAQ,CAAC,KAAK,EAAG,IAAI,CAAU;IAC/B,QAAQ,CAAC,WAAW,6CAA6C;gBAE7C,MAAM,EAAE,QAAQ;IAI9B,OAAO,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAyFhE;;;OAGG;YACW,gBAAgB;CAyC/B;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,QAAQ,GAAG,UAAU,CAE7D;AAGD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}