@darrenjcoxon/codeguard 1.0.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/LICENSE +21 -0
- package/README.md +61 -0
- package/dist/agent-report.d.ts +36 -0
- package/dist/agent-report.d.ts.map +1 -0
- package/dist/agent-report.js +329 -0
- package/dist/agent-report.js.map +1 -0
- package/dist/ai-summary.d.ts +55 -0
- package/dist/ai-summary.d.ts.map +1 -0
- package/dist/ai-summary.js +267 -0
- package/dist/ai-summary.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +199 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +27 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator.d.ts +63 -0
- package/dist/orchestrator.d.ts.map +1 -0
- package/dist/orchestrator.js +331 -0
- package/dist/orchestrator.js.map +1 -0
- package/dist/scanners/complexity.d.ts +29 -0
- package/dist/scanners/complexity.d.ts.map +1 -0
- package/dist/scanners/complexity.js +378 -0
- package/dist/scanners/complexity.js.map +1 -0
- package/dist/scanners/eslint.d.ts +21 -0
- package/dist/scanners/eslint.d.ts.map +1 -0
- package/dist/scanners/eslint.js +196 -0
- package/dist/scanners/eslint.js.map +1 -0
- package/dist/scanners/gitleaks.d.ts +21 -0
- package/dist/scanners/gitleaks.d.ts.map +1 -0
- package/dist/scanners/gitleaks.js +158 -0
- package/dist/scanners/gitleaks.js.map +1 -0
- package/dist/scanners/index.d.ts +56 -0
- package/dist/scanners/index.d.ts.map +1 -0
- package/dist/scanners/index.js +71 -0
- package/dist/scanners/index.js.map +1 -0
- package/dist/scanners/npm-audit.d.ts +19 -0
- package/dist/scanners/npm-audit.d.ts.map +1 -0
- package/dist/scanners/npm-audit.js +176 -0
- package/dist/scanners/npm-audit.js.map +1 -0
- package/dist/scanners/semgrep.d.ts +22 -0
- package/dist/scanners/semgrep.d.ts.map +1 -0
- package/dist/scanners/semgrep.js +175 -0
- package/dist/scanners/semgrep.js.map +1 -0
- package/dist/types.d.ts +522 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +194 -0
- package/dist/types.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Complexity Scanner
|
|
3
|
+
*
|
|
4
|
+
* Analyzes code complexity using various metrics
|
|
5
|
+
* Covers: complexity, dead-code, duplication categories
|
|
6
|
+
*/
|
|
7
|
+
import { exec } from 'child_process';
|
|
8
|
+
import { promisify } from 'util';
|
|
9
|
+
import { readFileSync, readdirSync, statSync } from 'fs';
|
|
10
|
+
import { join, extname, relative } from 'path';
|
|
11
|
+
import { generateFingerprint } from '../types.js';
|
|
12
|
+
const execAsync = promisify(exec);
|
|
13
|
+
export class ComplexityScanner {
|
|
14
|
+
name = 'complexity';
|
|
15
|
+
categories = ['complexity', 'quality'];
|
|
16
|
+
// Thresholds
|
|
17
|
+
maxFileLines = 500;
|
|
18
|
+
maxFunctionLines = 50;
|
|
19
|
+
maxCyclomaticComplexity = 15;
|
|
20
|
+
maxCognitiveComplexity = 20;
|
|
21
|
+
// Supported extensions
|
|
22
|
+
supportedExtensions = ['.js', '.jsx', '.ts', '.tsx', '.py', '.rb', '.php', '.java', '.cs', '.go'];
|
|
23
|
+
async isAvailable() {
|
|
24
|
+
return true; // Built-in analysis, always available
|
|
25
|
+
}
|
|
26
|
+
async scan(target, config) {
|
|
27
|
+
const startTime = Date.now();
|
|
28
|
+
try {
|
|
29
|
+
const files = this.collectFiles(target.path, target);
|
|
30
|
+
const findings = [];
|
|
31
|
+
for (const file of files) {
|
|
32
|
+
const fileFindings = await this.analyzeFile(file, target.path);
|
|
33
|
+
findings.push(...fileFindings);
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
scanner: this.name,
|
|
37
|
+
success: true,
|
|
38
|
+
findings,
|
|
39
|
+
metrics: {
|
|
40
|
+
duration: Date.now() - startTime,
|
|
41
|
+
filesScanned: files.length
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
return {
|
|
47
|
+
scanner: this.name,
|
|
48
|
+
success: false,
|
|
49
|
+
error: error instanceof Error ? error.message : String(error),
|
|
50
|
+
findings: [],
|
|
51
|
+
metrics: { duration: Date.now() - startTime }
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
collectFiles(dir, target) {
|
|
56
|
+
const files = [];
|
|
57
|
+
const excludePatterns = [
|
|
58
|
+
'node_modules', 'vendor', '.git', 'dist', 'build',
|
|
59
|
+
'__pycache__', '.venv', 'venv', 'coverage', '.next',
|
|
60
|
+
...(target.exclude || [])
|
|
61
|
+
];
|
|
62
|
+
const walk = (currentDir) => {
|
|
63
|
+
try {
|
|
64
|
+
const entries = readdirSync(currentDir);
|
|
65
|
+
for (const entry of entries) {
|
|
66
|
+
const fullPath = join(currentDir, entry);
|
|
67
|
+
// Skip excluded patterns
|
|
68
|
+
if (excludePatterns.some(p => entry === p || fullPath.includes(`/${p}/`))) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
const stat = statSync(fullPath);
|
|
73
|
+
if (stat.isDirectory()) {
|
|
74
|
+
walk(fullPath);
|
|
75
|
+
}
|
|
76
|
+
else if (stat.isFile()) {
|
|
77
|
+
const ext = extname(entry).toLowerCase();
|
|
78
|
+
if (this.supportedExtensions.includes(ext)) {
|
|
79
|
+
files.push(fullPath);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// Skip files we can't stat
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Skip directories we can't read
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
walk(dir);
|
|
93
|
+
return files;
|
|
94
|
+
}
|
|
95
|
+
async analyzeFile(filePath, basePath) {
|
|
96
|
+
const findings = [];
|
|
97
|
+
const relativePath = relative(basePath, filePath);
|
|
98
|
+
try {
|
|
99
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
100
|
+
const lines = content.split('\n');
|
|
101
|
+
const ext = extname(filePath).toLowerCase();
|
|
102
|
+
// Basic line metrics
|
|
103
|
+
const metrics = this.calculateLineMetrics(lines, ext);
|
|
104
|
+
// File too long
|
|
105
|
+
if (metrics.codeLines > this.maxFileLines) {
|
|
106
|
+
findings.push(this.createFinding({
|
|
107
|
+
file: relativePath,
|
|
108
|
+
title: 'File exceeds maximum length',
|
|
109
|
+
description: `This file has ${metrics.codeLines} lines of code (threshold: ${this.maxFileLines}). Consider splitting it into smaller modules.`,
|
|
110
|
+
severity: metrics.codeLines > this.maxFileLines * 2 ? 'medium' : 'low',
|
|
111
|
+
category: 'complexity',
|
|
112
|
+
suggestion: 'Break down into smaller, focused modules. Each module should have a single responsibility.',
|
|
113
|
+
effort: 'medium'
|
|
114
|
+
}));
|
|
115
|
+
}
|
|
116
|
+
// Calculate complexity
|
|
117
|
+
const complexity = this.estimateCyclomaticComplexity(content, ext);
|
|
118
|
+
if (complexity > this.maxCyclomaticComplexity) {
|
|
119
|
+
findings.push(this.createFinding({
|
|
120
|
+
file: relativePath,
|
|
121
|
+
title: 'High cyclomatic complexity',
|
|
122
|
+
description: `Estimated cyclomatic complexity: ${complexity} (threshold: ${this.maxCyclomaticComplexity}). High complexity makes code harder to test and maintain.`,
|
|
123
|
+
severity: complexity > this.maxCyclomaticComplexity * 2 ? 'high' : 'medium',
|
|
124
|
+
category: 'complexity',
|
|
125
|
+
suggestion: 'Reduce complexity by extracting methods, using early returns, and simplifying conditionals.',
|
|
126
|
+
effort: 'medium'
|
|
127
|
+
}));
|
|
128
|
+
}
|
|
129
|
+
// Find long functions
|
|
130
|
+
const longFunctions = this.findLongFunctions(content, ext, relativePath);
|
|
131
|
+
findings.push(...longFunctions);
|
|
132
|
+
// Check for potential issues
|
|
133
|
+
const codeSmells = this.detectCodeSmells(content, ext, relativePath);
|
|
134
|
+
findings.push(...codeSmells);
|
|
135
|
+
}
|
|
136
|
+
catch {
|
|
137
|
+
// Skip files we can't read
|
|
138
|
+
}
|
|
139
|
+
return findings;
|
|
140
|
+
}
|
|
141
|
+
calculateLineMetrics(lines, ext) {
|
|
142
|
+
let codeLines = 0;
|
|
143
|
+
let commentLines = 0;
|
|
144
|
+
let blankLines = 0;
|
|
145
|
+
const commentPatterns = this.getCommentPatterns(ext);
|
|
146
|
+
let inBlockComment = false;
|
|
147
|
+
for (const line of lines) {
|
|
148
|
+
const trimmed = line.trim();
|
|
149
|
+
if (!trimmed) {
|
|
150
|
+
blankLines++;
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
// Simple block comment detection
|
|
154
|
+
if (commentPatterns.blockStart && trimmed.includes(commentPatterns.blockStart)) {
|
|
155
|
+
inBlockComment = true;
|
|
156
|
+
}
|
|
157
|
+
if (inBlockComment) {
|
|
158
|
+
commentLines++;
|
|
159
|
+
if (commentPatterns.blockEnd && trimmed.includes(commentPatterns.blockEnd)) {
|
|
160
|
+
inBlockComment = false;
|
|
161
|
+
}
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
// Line comment
|
|
165
|
+
if (commentPatterns.line && trimmed.startsWith(commentPatterns.line)) {
|
|
166
|
+
commentLines++;
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
codeLines++;
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
path: '',
|
|
173
|
+
lines: lines.length,
|
|
174
|
+
codeLines,
|
|
175
|
+
commentLines,
|
|
176
|
+
blankLines,
|
|
177
|
+
complexity: 0,
|
|
178
|
+
functions: 0,
|
|
179
|
+
avgFunctionLength: 0,
|
|
180
|
+
maxFunctionLength: 0,
|
|
181
|
+
longFunctions: []
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
getCommentPatterns(ext) {
|
|
185
|
+
const patterns = {
|
|
186
|
+
'.js': { line: '//', blockStart: '/*', blockEnd: '*/' },
|
|
187
|
+
'.jsx': { line: '//', blockStart: '/*', blockEnd: '*/' },
|
|
188
|
+
'.ts': { line: '//', blockStart: '/*', blockEnd: '*/' },
|
|
189
|
+
'.tsx': { line: '//', blockStart: '/*', blockEnd: '*/' },
|
|
190
|
+
'.py': { line: '#', blockStart: '"""', blockEnd: '"""' },
|
|
191
|
+
'.rb': { line: '#', blockStart: '=begin', blockEnd: '=end' },
|
|
192
|
+
'.php': { line: '//', blockStart: '/*', blockEnd: '*/' },
|
|
193
|
+
'.java': { line: '//', blockStart: '/*', blockEnd: '*/' },
|
|
194
|
+
'.cs': { line: '//', blockStart: '/*', blockEnd: '*/' },
|
|
195
|
+
'.go': { line: '//', blockStart: '/*', blockEnd: '*/' }
|
|
196
|
+
};
|
|
197
|
+
return patterns[ext] || { line: '//' };
|
|
198
|
+
}
|
|
199
|
+
estimateCyclomaticComplexity(content, ext) {
|
|
200
|
+
// Simple estimation based on control flow keywords
|
|
201
|
+
let complexity = 1; // Base complexity
|
|
202
|
+
const patterns = [
|
|
203
|
+
/\bif\b/g,
|
|
204
|
+
/\belse\s+if\b/g,
|
|
205
|
+
/\bwhile\b/g,
|
|
206
|
+
/\bfor\b/g,
|
|
207
|
+
/\bforeach\b/gi,
|
|
208
|
+
/\bcase\b/g,
|
|
209
|
+
/\bcatch\b/g,
|
|
210
|
+
/\&\&/g,
|
|
211
|
+
/\|\|/g,
|
|
212
|
+
/\?\s*[^:]+\s*:/g // Ternary
|
|
213
|
+
];
|
|
214
|
+
for (const pattern of patterns) {
|
|
215
|
+
const matches = content.match(pattern);
|
|
216
|
+
if (matches) {
|
|
217
|
+
complexity += matches.length;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return complexity;
|
|
221
|
+
}
|
|
222
|
+
findLongFunctions(content, ext, filePath) {
|
|
223
|
+
const findings = [];
|
|
224
|
+
// Simple regex-based function detection
|
|
225
|
+
const functionPatterns = {
|
|
226
|
+
'.js': [
|
|
227
|
+
/function\s+(\w+)\s*\([^)]*\)\s*\{/g,
|
|
228
|
+
/(\w+)\s*[:=]\s*(?:async\s+)?function\s*\([^)]*\)\s*\{/g,
|
|
229
|
+
/(\w+)\s*[:=]\s*(?:async\s+)?\([^)]*\)\s*=>\s*\{/g
|
|
230
|
+
],
|
|
231
|
+
'.ts': [
|
|
232
|
+
/function\s+(\w+)\s*\([^)]*\)[^{]*\{/g,
|
|
233
|
+
/(\w+)\s*[:=]\s*(?:async\s+)?function\s*\([^)]*\)[^{]*\{/g,
|
|
234
|
+
/(\w+)\s*[:=]\s*(?:async\s+)?\([^)]*\)[^=]*=>\s*\{/g,
|
|
235
|
+
/(?:public|private|protected)?\s*(?:async\s+)?(\w+)\s*\([^)]*\)[^{]*\{/g
|
|
236
|
+
],
|
|
237
|
+
'.py': [
|
|
238
|
+
/def\s+(\w+)\s*\([^)]*\)\s*(?:->.*)?:/g
|
|
239
|
+
]
|
|
240
|
+
};
|
|
241
|
+
const patterns = functionPatterns[ext] || functionPatterns['.js'];
|
|
242
|
+
const lines = content.split('\n');
|
|
243
|
+
for (const pattern of patterns) {
|
|
244
|
+
let match;
|
|
245
|
+
while ((match = pattern.exec(content)) !== null) {
|
|
246
|
+
const startIndex = match.index;
|
|
247
|
+
const startLine = content.slice(0, startIndex).split('\n').length;
|
|
248
|
+
// Estimate function length by finding matching brace/indent
|
|
249
|
+
const functionLength = this.estimateFunctionLength(content.slice(startIndex), ext);
|
|
250
|
+
if (functionLength > this.maxFunctionLines) {
|
|
251
|
+
findings.push(this.createFinding({
|
|
252
|
+
file: filePath,
|
|
253
|
+
line: startLine,
|
|
254
|
+
title: `Function too long: ${match[1] || 'anonymous'}`,
|
|
255
|
+
description: `This function is approximately ${functionLength} lines long (threshold: ${this.maxFunctionLines}).`,
|
|
256
|
+
severity: functionLength > this.maxFunctionLines * 2 ? 'medium' : 'low',
|
|
257
|
+
category: 'complexity',
|
|
258
|
+
suggestion: 'Extract smaller helper functions. Each function should do one thing well.',
|
|
259
|
+
effort: 'easy'
|
|
260
|
+
}));
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
pattern.lastIndex = 0; // Reset regex
|
|
264
|
+
}
|
|
265
|
+
return findings;
|
|
266
|
+
}
|
|
267
|
+
estimateFunctionLength(content, ext) {
|
|
268
|
+
if (['.py', '.rb'].includes(ext)) {
|
|
269
|
+
// Indentation-based languages - count until dedent
|
|
270
|
+
const lines = content.split('\n');
|
|
271
|
+
if (lines.length < 2)
|
|
272
|
+
return 1;
|
|
273
|
+
const firstLine = lines[0];
|
|
274
|
+
const baseIndent = firstLine.match(/^\s*/)?.[0].length || 0;
|
|
275
|
+
let count = 1;
|
|
276
|
+
for (let i = 1; i < lines.length; i++) {
|
|
277
|
+
const line = lines[i];
|
|
278
|
+
if (!line.trim()) {
|
|
279
|
+
count++;
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
const indent = line.match(/^\s*/)?.[0].length || 0;
|
|
283
|
+
if (indent <= baseIndent && line.trim())
|
|
284
|
+
break;
|
|
285
|
+
count++;
|
|
286
|
+
}
|
|
287
|
+
return count;
|
|
288
|
+
}
|
|
289
|
+
// Brace-based languages
|
|
290
|
+
let braceCount = 0;
|
|
291
|
+
let started = false;
|
|
292
|
+
let lineCount = 0;
|
|
293
|
+
for (const char of content) {
|
|
294
|
+
if (char === '{') {
|
|
295
|
+
braceCount++;
|
|
296
|
+
started = true;
|
|
297
|
+
}
|
|
298
|
+
else if (char === '}') {
|
|
299
|
+
braceCount--;
|
|
300
|
+
if (started && braceCount === 0)
|
|
301
|
+
break;
|
|
302
|
+
}
|
|
303
|
+
else if (char === '\n') {
|
|
304
|
+
lineCount++;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return lineCount;
|
|
308
|
+
}
|
|
309
|
+
detectCodeSmells(content, ext, filePath) {
|
|
310
|
+
const findings = [];
|
|
311
|
+
const lines = content.split('\n');
|
|
312
|
+
// TODO comments
|
|
313
|
+
const todoPattern = /\b(TODO|FIXME|HACK|XXX|BUG)\b/gi;
|
|
314
|
+
lines.forEach((line, index) => {
|
|
315
|
+
const match = line.match(todoPattern);
|
|
316
|
+
if (match) {
|
|
317
|
+
findings.push(this.createFinding({
|
|
318
|
+
file: filePath,
|
|
319
|
+
line: index + 1,
|
|
320
|
+
title: `${match[0].toUpperCase()} comment found`,
|
|
321
|
+
description: `Code contains a ${match[0].toUpperCase()} marker: "${line.trim().slice(0, 80)}..."`,
|
|
322
|
+
severity: 'info',
|
|
323
|
+
category: 'quality',
|
|
324
|
+
suggestion: 'Address or create a tracking issue for this TODO item.',
|
|
325
|
+
effort: 'easy'
|
|
326
|
+
}));
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
// Console.log / print statements (potential debug code)
|
|
330
|
+
const debugPatterns = {
|
|
331
|
+
'.js': /console\.(log|debug|info)\(/g,
|
|
332
|
+
'.ts': /console\.(log|debug|info)\(/g,
|
|
333
|
+
'.py': /print\s*\(/g,
|
|
334
|
+
'.php': /var_dump\(|print_r\(/g
|
|
335
|
+
};
|
|
336
|
+
const debugPattern = debugPatterns[ext];
|
|
337
|
+
if (debugPattern) {
|
|
338
|
+
lines.forEach((line, index) => {
|
|
339
|
+
if (debugPattern.test(line) && !line.trim().startsWith('//') && !line.trim().startsWith('#')) {
|
|
340
|
+
findings.push(this.createFinding({
|
|
341
|
+
file: filePath,
|
|
342
|
+
line: index + 1,
|
|
343
|
+
title: 'Debug statement detected',
|
|
344
|
+
description: 'Debug/logging statement found that may need to be removed before production.',
|
|
345
|
+
severity: 'info',
|
|
346
|
+
category: 'quality',
|
|
347
|
+
suggestion: 'Remove or replace with proper logging framework.',
|
|
348
|
+
effort: 'trivial'
|
|
349
|
+
}));
|
|
350
|
+
debugPattern.lastIndex = 0;
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
return findings;
|
|
355
|
+
}
|
|
356
|
+
createFinding(params) {
|
|
357
|
+
const finding = {
|
|
358
|
+
id: `complexity-${params.file}-${params.line || 0}-${Date.now()}`,
|
|
359
|
+
source: this.name,
|
|
360
|
+
severity: params.severity,
|
|
361
|
+
category: params.category,
|
|
362
|
+
file: params.file,
|
|
363
|
+
line: params.line,
|
|
364
|
+
title: params.title,
|
|
365
|
+
description: params.description,
|
|
366
|
+
suggestion: params.suggestion,
|
|
367
|
+
fixAvailable: false,
|
|
368
|
+
autoFixable: false,
|
|
369
|
+
confidence: 'medium',
|
|
370
|
+
effort: params.effort,
|
|
371
|
+
fingerprint: ''
|
|
372
|
+
};
|
|
373
|
+
finding.fingerprint = generateFingerprint(finding);
|
|
374
|
+
return finding;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
export default ComplexityScanner;
|
|
378
|
+
//# sourceMappingURL=complexity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complexity.js","sourceRoot":"","sources":["../../src/scanners/complexity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESLint Scanner
|
|
3
|
+
*
|
|
4
|
+
* Code quality and style scanning for JavaScript/TypeScript projects
|
|
5
|
+
* Covers: quality, style, security (with security plugins)
|
|
6
|
+
*/
|
|
7
|
+
import { Scanner, ScanTarget, ScannerConfig, ScannerResult, FindingCategory } from '../types.js';
|
|
8
|
+
export declare class ESLintScanner implements Scanner {
|
|
9
|
+
name: string;
|
|
10
|
+
categories: FindingCategory[];
|
|
11
|
+
private securityRulePrefixes;
|
|
12
|
+
isAvailable(): Promise<boolean>;
|
|
13
|
+
scan(target: ScanTarget, config?: ScannerConfig): Promise<ScannerResult>;
|
|
14
|
+
private hasESLintConfig;
|
|
15
|
+
private runESLint;
|
|
16
|
+
private transformFindings;
|
|
17
|
+
private categorizeRule;
|
|
18
|
+
private mapSeverity;
|
|
19
|
+
}
|
|
20
|
+
export default ESLintScanner;
|
|
21
|
+
//# sourceMappingURL=eslint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eslint.d.ts","sourceRoot":"","sources":["../../src/scanners/eslint.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,EACL,OAAO,EACP,UAAU,EACV,aAAa,EACb,aAAa,EAEb,eAAe,EAGhB,MAAM,aAAa,CAAC;AAgCrB,qBAAa,aAAc,YAAW,OAAO;IAC3C,IAAI,SAAY;IAChB,UAAU,EAAE,eAAe,EAAE,CAAoC;IAGjE,OAAO,CAAC,oBAAoB,CAO1B;IAEI,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAS/B,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAkD9E,OAAO,CAAC,eAAe;YAgBT,SAAS;IAkCvB,OAAO,CAAC,iBAAiB;IA6CzB,OAAO,CAAC,cAAc;IAwBtB,OAAO,CAAC,WAAW;CAcpB;AAED,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ESLint Scanner
|
|
3
|
+
*
|
|
4
|
+
* Code quality and style scanning for JavaScript/TypeScript projects
|
|
5
|
+
* Covers: quality, style, security (with security plugins)
|
|
6
|
+
*/
|
|
7
|
+
import { exec } from 'child_process';
|
|
8
|
+
import { promisify } from 'util';
|
|
9
|
+
import { existsSync } from 'fs';
|
|
10
|
+
import { join } from 'path';
|
|
11
|
+
import { generateFingerprint } from '../types.js';
|
|
12
|
+
const execAsync = promisify(exec);
|
|
13
|
+
export class ESLintScanner {
|
|
14
|
+
name = 'eslint';
|
|
15
|
+
categories = ['quality', 'style', 'security'];
|
|
16
|
+
// Security-related ESLint rule prefixes
|
|
17
|
+
securityRulePrefixes = [
|
|
18
|
+
'security/',
|
|
19
|
+
'@typescript-eslint/no-unsafe',
|
|
20
|
+
'no-eval',
|
|
21
|
+
'no-implied-eval',
|
|
22
|
+
'no-new-func',
|
|
23
|
+
'no-script-url'
|
|
24
|
+
];
|
|
25
|
+
async isAvailable() {
|
|
26
|
+
try {
|
|
27
|
+
await execAsync('npx eslint --version', { timeout: 10000 });
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async scan(target, config) {
|
|
35
|
+
const startTime = Date.now();
|
|
36
|
+
// Check for ESLint config or package.json
|
|
37
|
+
const hasESLintConfig = this.hasESLintConfig(target.path);
|
|
38
|
+
const hasPackageJson = existsSync(join(target.path, 'package.json'));
|
|
39
|
+
if (!hasESLintConfig && !hasPackageJson) {
|
|
40
|
+
return {
|
|
41
|
+
scanner: this.name,
|
|
42
|
+
success: true,
|
|
43
|
+
findings: [],
|
|
44
|
+
metrics: { duration: Date.now() - startTime },
|
|
45
|
+
metadata: { skipped: true, reason: 'No ESLint config or package.json found' }
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (!await this.isAvailable()) {
|
|
49
|
+
return {
|
|
50
|
+
scanner: this.name,
|
|
51
|
+
success: false,
|
|
52
|
+
error: 'ESLint not available. Run `npm install eslint` in your project',
|
|
53
|
+
findings: [],
|
|
54
|
+
metrics: { duration: Date.now() - startTime }
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const findings = await this.runESLint(target);
|
|
59
|
+
return {
|
|
60
|
+
scanner: this.name,
|
|
61
|
+
success: true,
|
|
62
|
+
findings,
|
|
63
|
+
metrics: {
|
|
64
|
+
duration: Date.now() - startTime,
|
|
65
|
+
filesScanned: findings.length > 0 ? new Set(findings.map(f => f.file)).size : 0
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
return {
|
|
71
|
+
scanner: this.name,
|
|
72
|
+
success: false,
|
|
73
|
+
error: error instanceof Error ? error.message : String(error),
|
|
74
|
+
findings: [],
|
|
75
|
+
metrics: { duration: Date.now() - startTime }
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
hasESLintConfig(path) {
|
|
80
|
+
const configFiles = [
|
|
81
|
+
'.eslintrc',
|
|
82
|
+
'.eslintrc.js',
|
|
83
|
+
'.eslintrc.cjs',
|
|
84
|
+
'.eslintrc.json',
|
|
85
|
+
'.eslintrc.yml',
|
|
86
|
+
'.eslintrc.yaml',
|
|
87
|
+
'eslint.config.js',
|
|
88
|
+
'eslint.config.mjs',
|
|
89
|
+
'eslint.config.cjs'
|
|
90
|
+
];
|
|
91
|
+
return configFiles.some(f => existsSync(join(path, f)));
|
|
92
|
+
}
|
|
93
|
+
async runESLint(target) {
|
|
94
|
+
const extensions = '--ext .js,.jsx,.ts,.tsx,.mjs,.cjs';
|
|
95
|
+
const ignorePattern = '--ignore-pattern "node_modules/**" --ignore-pattern "dist/**" --ignore-pattern "build/**"';
|
|
96
|
+
const cmd = `cd "${target.path}" && npx eslint . ${extensions} ${ignorePattern} --format json --no-error-on-unmatched-pattern 2>/dev/null || true`;
|
|
97
|
+
try {
|
|
98
|
+
const { stdout, stderr } = await execAsync(cmd, {
|
|
99
|
+
timeout: 180000, // 3 minutes
|
|
100
|
+
maxBuffer: 20 * 1024 * 1024
|
|
101
|
+
});
|
|
102
|
+
if (!stdout.trim() || stdout.trim() === '[]') {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
const results = JSON.parse(stdout);
|
|
106
|
+
return this.transformFindings(results, target.path);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
// ESLint exits with 1 when there are linting errors
|
|
110
|
+
if (error.stdout) {
|
|
111
|
+
try {
|
|
112
|
+
const results = JSON.parse(error.stdout);
|
|
113
|
+
return this.transformFindings(results, target.path);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Config errors etc. - just return empty
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
transformFindings(results, basePath) {
|
|
124
|
+
const findings = [];
|
|
125
|
+
for (const result of results) {
|
|
126
|
+
for (const msg of result.messages) {
|
|
127
|
+
if (!msg.ruleId)
|
|
128
|
+
continue; // Skip parsing errors without rule IDs
|
|
129
|
+
const category = this.categorizeRule(msg.ruleId);
|
|
130
|
+
const severity = this.mapSeverity(msg.severity, category);
|
|
131
|
+
// Make path relative
|
|
132
|
+
const relativePath = result.filePath.startsWith(basePath)
|
|
133
|
+
? result.filePath.slice(basePath.length + 1)
|
|
134
|
+
: result.filePath;
|
|
135
|
+
const finding = {
|
|
136
|
+
id: `eslint-${msg.ruleId}-${relativePath}-${msg.line}`,
|
|
137
|
+
source: this.name,
|
|
138
|
+
severity,
|
|
139
|
+
category,
|
|
140
|
+
file: relativePath,
|
|
141
|
+
line: msg.line,
|
|
142
|
+
endLine: msg.endLine,
|
|
143
|
+
column: msg.column,
|
|
144
|
+
endColumn: msg.endColumn,
|
|
145
|
+
title: msg.ruleId,
|
|
146
|
+
description: msg.message,
|
|
147
|
+
suggestion: msg.suggestions?.[0]?.desc || (msg.fix ? 'Auto-fix available' : undefined),
|
|
148
|
+
fixAvailable: !!(msg.fix || msg.suggestions?.length),
|
|
149
|
+
autoFixable: !!msg.fix,
|
|
150
|
+
ruleId: msg.ruleId,
|
|
151
|
+
ruleUrl: `https://eslint.org/docs/rules/${msg.ruleId}`,
|
|
152
|
+
confidence: 'high',
|
|
153
|
+
effort: msg.fix ? 'trivial' : 'easy',
|
|
154
|
+
fingerprint: ''
|
|
155
|
+
};
|
|
156
|
+
finding.fingerprint = generateFingerprint(finding);
|
|
157
|
+
findings.push(finding);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return findings;
|
|
161
|
+
}
|
|
162
|
+
categorizeRule(ruleId) {
|
|
163
|
+
// Check if it's a security rule
|
|
164
|
+
if (this.securityRulePrefixes.some(prefix => ruleId.startsWith(prefix) || ruleId.includes(prefix))) {
|
|
165
|
+
return 'security';
|
|
166
|
+
}
|
|
167
|
+
// Style rules
|
|
168
|
+
const stylePatterns = [
|
|
169
|
+
'indent', 'quotes', 'semi', 'comma', 'spacing', 'newline',
|
|
170
|
+
'brace', 'curly', 'padding', 'wrap', 'linebreak'
|
|
171
|
+
];
|
|
172
|
+
if (stylePatterns.some(p => ruleId.toLowerCase().includes(p))) {
|
|
173
|
+
return 'style';
|
|
174
|
+
}
|
|
175
|
+
// Complexity rules
|
|
176
|
+
if (ruleId.includes('complexity') || ruleId.includes('max-')) {
|
|
177
|
+
return 'complexity';
|
|
178
|
+
}
|
|
179
|
+
// Default to quality
|
|
180
|
+
return 'quality';
|
|
181
|
+
}
|
|
182
|
+
mapSeverity(eslintSeverity, category) {
|
|
183
|
+
// Security issues get elevated severity
|
|
184
|
+
if (category === 'security') {
|
|
185
|
+
return eslintSeverity === 2 ? 'high' : 'medium';
|
|
186
|
+
}
|
|
187
|
+
// Style issues are low priority
|
|
188
|
+
if (category === 'style') {
|
|
189
|
+
return 'low';
|
|
190
|
+
}
|
|
191
|
+
// Quality issues
|
|
192
|
+
return eslintSeverity === 2 ? 'medium' : 'low';
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
export default ESLintScanner;
|
|
196
|
+
//# sourceMappingURL=eslint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eslint.js","sourceRoot":"","sources":["../../src/scanners/eslint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gitleaks Scanner
|
|
3
|
+
*
|
|
4
|
+
* Secret detection scanner using Gitleaks CLI
|
|
5
|
+
* Covers: secret category
|
|
6
|
+
*/
|
|
7
|
+
import { Scanner, ScanTarget, ScannerConfig, ScannerResult, FindingCategory } from '../types.js';
|
|
8
|
+
export declare class GitleaksScanner implements Scanner {
|
|
9
|
+
name: string;
|
|
10
|
+
categories: FindingCategory[];
|
|
11
|
+
isAvailable(): Promise<boolean>;
|
|
12
|
+
scan(target: ScanTarget, config?: ScannerConfig): Promise<ScannerResult>;
|
|
13
|
+
private runGitleaks;
|
|
14
|
+
private transformFindings;
|
|
15
|
+
private determineSeverity;
|
|
16
|
+
private redactSecret;
|
|
17
|
+
private redactSnippet;
|
|
18
|
+
private getSuggestion;
|
|
19
|
+
}
|
|
20
|
+
export default GitleaksScanner;
|
|
21
|
+
//# sourceMappingURL=gitleaks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitleaks.d.ts","sourceRoot":"","sources":["../../src/scanners/gitleaks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EACL,OAAO,EACP,UAAU,EACV,aAAa,EACb,aAAa,EAEb,eAAe,EAGhB,MAAM,aAAa,CAAC;AAyBrB,qBAAa,eAAgB,YAAW,OAAO;IAC7C,IAAI,SAAc;IAClB,UAAU,EAAE,eAAe,EAAE,CAAc;IAErC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAS/B,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;YAoChE,WAAW;IAkCzB,OAAO,CAAC,iBAAiB;IAgCzB,OAAO,CAAC,iBAAiB;IA4BzB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,aAAa;IAKrB,OAAO,CAAC,aAAa;CAYtB;AAED,eAAe,eAAe,CAAC"}
|