@darrenjcoxon/vibeguard 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 +58 -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 +328 -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 +48 -0
- package/dist/scanners/complexity.d.ts.map +1 -0
- package/dist/scanners/complexity.js +512 -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 +53 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CodeGuard - AI-Powered Code Security & Quality Scanner
|
|
3
|
+
*
|
|
4
|
+
* A pluggable orchestrator that combines multiple security and quality
|
|
5
|
+
* scanning tools with AI-powered analysis.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import { Orchestrator, ScanTarget } from 'codeguard';
|
|
10
|
+
*
|
|
11
|
+
* const orchestrator = new Orchestrator();
|
|
12
|
+
* const target: ScanTarget = { path: './my-project' };
|
|
13
|
+
* const report = await orchestrator.scan(target);
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
// Core exports
|
|
17
|
+
export { Orchestrator } from './orchestrator.js';
|
|
18
|
+
export { AISummaryGenerator } from './ai-summary.js';
|
|
19
|
+
export { AgentReportGenerator } from './agent-report.js';
|
|
20
|
+
// Types
|
|
21
|
+
export { DEFAULT_QUALITY_GATE, generateFingerprint, severityWeight } from './types.js';
|
|
22
|
+
// Scanners
|
|
23
|
+
export { SemgrepScanner, GitleaksScanner, NpmAuditScanner, ESLintScanner, ComplexityScanner, getAllScanners, getScannersByCategory, SCANNER_COVERAGE } from './scanners/index.js';
|
|
24
|
+
// Default export for convenience
|
|
25
|
+
import { Orchestrator } from './orchestrator.js';
|
|
26
|
+
export default Orchestrator;
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,eAAe;AACf,OAAO,EAAE,YAAY,EAA2B,MAAM,mBAAmB,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAwB,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAA2B,MAAM,mBAAmB,CAAC;AAElF,QAAQ;AACR,OAAO,EAWL,oBAAoB,EACpB,mBAAmB,EACnB,cAAc,EACf,MAAM,YAAY,CAAC;AAEpB,WAAW;AACX,OAAO,EACL,cAAc,EACd,eAAe,EACf,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,qBAAqB,CAAC;AAE7B,iCAAiC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vibeguard Orchestrator
|
|
3
|
+
*
|
|
4
|
+
* Coordinates multiple scanners, aggregates results, and generates reports
|
|
5
|
+
*/
|
|
6
|
+
import { Scanner, ScanTarget, ScanReport, QualityGate } from './types.js';
|
|
7
|
+
export interface OrchestratorConfig {
|
|
8
|
+
scanners?: Scanner[];
|
|
9
|
+
qualityGate?: QualityGate;
|
|
10
|
+
parallel?: boolean;
|
|
11
|
+
verbose?: boolean;
|
|
12
|
+
categories?: string[];
|
|
13
|
+
maxFindings?: number;
|
|
14
|
+
}
|
|
15
|
+
export declare class Orchestrator {
|
|
16
|
+
private scanners;
|
|
17
|
+
private qualityGate;
|
|
18
|
+
private parallel;
|
|
19
|
+
private verbose;
|
|
20
|
+
constructor(config?: OrchestratorConfig);
|
|
21
|
+
/**
|
|
22
|
+
* Check which scanners are available (for CLI check command)
|
|
23
|
+
*/
|
|
24
|
+
checkScanners(): Promise<Record<string, boolean>>;
|
|
25
|
+
/**
|
|
26
|
+
* Run all scanners against the target
|
|
27
|
+
*/
|
|
28
|
+
scan(target: ScanTarget): Promise<ScanReport>;
|
|
29
|
+
/**
|
|
30
|
+
* Check which scanners are available
|
|
31
|
+
*/
|
|
32
|
+
private checkScannerAvailability;
|
|
33
|
+
/**
|
|
34
|
+
* Run scanners in parallel
|
|
35
|
+
*/
|
|
36
|
+
private runScannersParallel;
|
|
37
|
+
/**
|
|
38
|
+
* Run scanners sequentially
|
|
39
|
+
*/
|
|
40
|
+
private runScannersSequential;
|
|
41
|
+
/**
|
|
42
|
+
* Aggregate findings from all scanners and deduplicate
|
|
43
|
+
*/
|
|
44
|
+
private aggregateFindings;
|
|
45
|
+
/**
|
|
46
|
+
* Evaluate quality gate rules
|
|
47
|
+
*/
|
|
48
|
+
private evaluateQualityGate;
|
|
49
|
+
/**
|
|
50
|
+
* Create summary statistics
|
|
51
|
+
*/
|
|
52
|
+
private createSummary;
|
|
53
|
+
/**
|
|
54
|
+
* Print summary to console
|
|
55
|
+
*/
|
|
56
|
+
private printSummary;
|
|
57
|
+
/**
|
|
58
|
+
* Create an empty report (when no scanners available)
|
|
59
|
+
*/
|
|
60
|
+
private createEmptyReport;
|
|
61
|
+
}
|
|
62
|
+
export default Orchestrator;
|
|
63
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EACL,OAAO,EACP,UAAU,EAEV,UAAU,EAEV,WAAW,EAIZ,MAAM,YAAY,CAAC;AAGpB,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAY;IAC5B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,QAAQ,CAAU;IAC1B,OAAO,CAAC,OAAO,CAAU;gBAEb,MAAM,GAAE,kBAAuB;IAc3C;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAQvD;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IA8CnD;;OAEG;YACW,wBAAwB;IA0BtC;;OAEG;YACW,mBAAmB;IAyCjC;;OAEG;YACW,qBAAqB;IAwCnC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA2BzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAsC3B;;OAEG;IACH,OAAO,CAAC,aAAa;IAwBrB;;OAEG;IACH,OAAO,CAAC,YAAY;IAwDpB;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAqB1B;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vibeguard Orchestrator
|
|
3
|
+
*
|
|
4
|
+
* Coordinates multiple scanners, aggregates results, and generates reports
|
|
5
|
+
*/
|
|
6
|
+
import { randomUUID } from 'crypto';
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import ora from 'ora';
|
|
9
|
+
import { DEFAULT_QUALITY_GATE, severityWeight } from './types.js';
|
|
10
|
+
import { getAllScanners } from './scanners/index.js';
|
|
11
|
+
export class Orchestrator {
|
|
12
|
+
scanners;
|
|
13
|
+
qualityGate;
|
|
14
|
+
parallel;
|
|
15
|
+
verbose;
|
|
16
|
+
constructor(config = {}) {
|
|
17
|
+
this.scanners = config.scanners || getAllScanners();
|
|
18
|
+
this.qualityGate = config.qualityGate || DEFAULT_QUALITY_GATE;
|
|
19
|
+
this.parallel = config.parallel ?? true;
|
|
20
|
+
this.verbose = config.verbose ?? false;
|
|
21
|
+
// Filter scanners by category if specified
|
|
22
|
+
if (config.categories?.length) {
|
|
23
|
+
this.scanners = this.scanners.filter(scanner => scanner.categories.some(cat => config.categories.includes(cat)));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Check which scanners are available (for CLI check command)
|
|
28
|
+
*/
|
|
29
|
+
async checkScanners() {
|
|
30
|
+
const results = {};
|
|
31
|
+
for (const scanner of this.scanners) {
|
|
32
|
+
results[scanner.name] = await scanner.isAvailable();
|
|
33
|
+
}
|
|
34
|
+
return results;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Run all scanners against the target
|
|
38
|
+
*/
|
|
39
|
+
async scan(target) {
|
|
40
|
+
const startTime = Date.now();
|
|
41
|
+
const reportId = randomUUID();
|
|
42
|
+
console.log(chalk.blue.bold('\nš Vibeguard Security & Quality Analysis\n'));
|
|
43
|
+
console.log(chalk.gray(`Target: ${target.path}`));
|
|
44
|
+
console.log(chalk.gray(`Scanners: ${this.scanners.map(s => s.name).join(', ')}\n`));
|
|
45
|
+
// Check scanner availability
|
|
46
|
+
const availableScanners = await this.checkScannerAvailability();
|
|
47
|
+
if (availableScanners.length === 0) {
|
|
48
|
+
console.log(chalk.yellow('ā ļø No scanners available. Install required tools.'));
|
|
49
|
+
return this.createEmptyReport(reportId, target, startTime);
|
|
50
|
+
}
|
|
51
|
+
// Run scanners
|
|
52
|
+
const results = this.parallel
|
|
53
|
+
? await this.runScannersParallel(availableScanners, target)
|
|
54
|
+
: await this.runScannersSequential(availableScanners, target);
|
|
55
|
+
// Aggregate and deduplicate findings
|
|
56
|
+
const aggregatedFindings = this.aggregateFindings(results);
|
|
57
|
+
// Apply quality gate
|
|
58
|
+
const qualityGateResult = this.evaluateQualityGate(aggregatedFindings);
|
|
59
|
+
// Create summary
|
|
60
|
+
const summary = this.createSummary(aggregatedFindings, qualityGateResult);
|
|
61
|
+
// Build report
|
|
62
|
+
const report = {
|
|
63
|
+
id: reportId,
|
|
64
|
+
timestamp: new Date().toISOString(),
|
|
65
|
+
target,
|
|
66
|
+
results,
|
|
67
|
+
findings: aggregatedFindings,
|
|
68
|
+
summary
|
|
69
|
+
};
|
|
70
|
+
// Print summary
|
|
71
|
+
this.printSummary(report);
|
|
72
|
+
return report;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Check which scanners are available
|
|
76
|
+
*/
|
|
77
|
+
async checkScannerAvailability() {
|
|
78
|
+
const available = [];
|
|
79
|
+
for (const scanner of this.scanners) {
|
|
80
|
+
const spinner = ora({
|
|
81
|
+
text: `Checking ${scanner.name}...`,
|
|
82
|
+
color: 'cyan'
|
|
83
|
+
}).start();
|
|
84
|
+
try {
|
|
85
|
+
const isAvailable = await scanner.isAvailable();
|
|
86
|
+
if (isAvailable) {
|
|
87
|
+
spinner.succeed(chalk.green(`${scanner.name} available`));
|
|
88
|
+
available.push(scanner);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
spinner.warn(chalk.yellow(`${scanner.name} not available`));
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
spinner.fail(chalk.red(`${scanner.name} error`));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
console.log('');
|
|
99
|
+
return available;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Run scanners in parallel
|
|
103
|
+
*/
|
|
104
|
+
async runScannersParallel(scanners, target) {
|
|
105
|
+
console.log(chalk.blue('Running scanners in parallel...\n'));
|
|
106
|
+
const promises = scanners.map(async (scanner) => {
|
|
107
|
+
const spinner = ora({
|
|
108
|
+
text: `${scanner.name}: scanning...`,
|
|
109
|
+
prefixText: ' '
|
|
110
|
+
}).start();
|
|
111
|
+
try {
|
|
112
|
+
const result = await scanner.scan(target);
|
|
113
|
+
if (result.success) {
|
|
114
|
+
spinner.succeed(`${scanner.name}: ${result.findings.length} findings (${result.metrics.duration}ms)`);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
spinner.fail(`${scanner.name}: ${result.error}`);
|
|
118
|
+
}
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
spinner.fail(`${scanner.name}: failed`);
|
|
123
|
+
return {
|
|
124
|
+
scanner: scanner.name,
|
|
125
|
+
success: false,
|
|
126
|
+
error: error instanceof Error ? error.message : String(error),
|
|
127
|
+
findings: [],
|
|
128
|
+
metrics: { duration: 0 }
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
const results = await Promise.all(promises);
|
|
133
|
+
console.log('');
|
|
134
|
+
return results;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Run scanners sequentially
|
|
138
|
+
*/
|
|
139
|
+
async runScannersSequential(scanners, target) {
|
|
140
|
+
const results = [];
|
|
141
|
+
for (const scanner of scanners) {
|
|
142
|
+
const spinner = ora({
|
|
143
|
+
text: `${scanner.name}: scanning...`,
|
|
144
|
+
prefixText: ' '
|
|
145
|
+
}).start();
|
|
146
|
+
try {
|
|
147
|
+
const result = await scanner.scan(target);
|
|
148
|
+
if (result.success) {
|
|
149
|
+
spinner.succeed(`${scanner.name}: ${result.findings.length} findings (${result.metrics.duration}ms)`);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
spinner.fail(`${scanner.name}: ${result.error}`);
|
|
153
|
+
}
|
|
154
|
+
results.push(result);
|
|
155
|
+
}
|
|
156
|
+
catch (error) {
|
|
157
|
+
spinner.fail(`${scanner.name}: failed`);
|
|
158
|
+
results.push({
|
|
159
|
+
scanner: scanner.name,
|
|
160
|
+
success: false,
|
|
161
|
+
error: error instanceof Error ? error.message : String(error),
|
|
162
|
+
findings: [],
|
|
163
|
+
metrics: { duration: 0 }
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
console.log('');
|
|
168
|
+
return results;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Aggregate findings from all scanners and deduplicate
|
|
172
|
+
*/
|
|
173
|
+
aggregateFindings(results) {
|
|
174
|
+
const allFindings = [];
|
|
175
|
+
const seen = new Set();
|
|
176
|
+
// Collect all findings
|
|
177
|
+
for (const result of results) {
|
|
178
|
+
allFindings.push(...result.findings);
|
|
179
|
+
}
|
|
180
|
+
// Deduplicate by fingerprint
|
|
181
|
+
const deduplicated = allFindings.filter(finding => {
|
|
182
|
+
const key = finding.fingerprint || `${finding.file}:${finding.line}:${finding.ruleId}`;
|
|
183
|
+
if (seen.has(key)) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
seen.add(key);
|
|
187
|
+
return true;
|
|
188
|
+
});
|
|
189
|
+
// Sort by severity (critical first) then by file
|
|
190
|
+
return deduplicated.sort((a, b) => {
|
|
191
|
+
const severityDiff = severityWeight(b.severity) - severityWeight(a.severity);
|
|
192
|
+
if (severityDiff !== 0)
|
|
193
|
+
return severityDiff;
|
|
194
|
+
return a.file.localeCompare(b.file);
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Evaluate quality gate rules
|
|
199
|
+
*/
|
|
200
|
+
evaluateQualityGate(findings) {
|
|
201
|
+
const details = [];
|
|
202
|
+
let passes = true;
|
|
203
|
+
const metrics = {
|
|
204
|
+
critical_findings: findings.filter(f => f.severity === 'critical').length,
|
|
205
|
+
high_findings: findings.filter(f => f.severity === 'high').length,
|
|
206
|
+
security_findings: findings.filter(f => f.category === 'security').length,
|
|
207
|
+
secret_findings: findings.filter(f => f.category === 'secret').length,
|
|
208
|
+
total_findings: findings.length,
|
|
209
|
+
new_findings: findings.length // For PR analysis, would filter by changed files
|
|
210
|
+
};
|
|
211
|
+
for (const rule of this.qualityGate.rules) {
|
|
212
|
+
const value = metrics[rule.metric] ?? 0;
|
|
213
|
+
let rulePass = true;
|
|
214
|
+
switch (rule.operator) {
|
|
215
|
+
case 'lt':
|
|
216
|
+
rulePass = value < rule.threshold;
|
|
217
|
+
break;
|
|
218
|
+
case 'lte':
|
|
219
|
+
rulePass = value <= rule.threshold;
|
|
220
|
+
break;
|
|
221
|
+
case 'gt':
|
|
222
|
+
rulePass = value > rule.threshold;
|
|
223
|
+
break;
|
|
224
|
+
case 'gte':
|
|
225
|
+
rulePass = value >= rule.threshold;
|
|
226
|
+
break;
|
|
227
|
+
case 'eq':
|
|
228
|
+
rulePass = value === rule.threshold;
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
const status = rulePass ? 'ā' : 'ā';
|
|
232
|
+
details.push(`${status} ${rule.metric}: ${value} (threshold: ${rule.operator} ${rule.threshold})`);
|
|
233
|
+
if (!rulePass && rule.failOnBreach) {
|
|
234
|
+
passes = false;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return { passes, details };
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Create summary statistics
|
|
241
|
+
*/
|
|
242
|
+
createSummary(findings, qualityGateResult) {
|
|
243
|
+
const bySeverity = {};
|
|
244
|
+
const byCategory = {};
|
|
245
|
+
const byScanner = {};
|
|
246
|
+
for (const finding of findings) {
|
|
247
|
+
bySeverity[finding.severity] = (bySeverity[finding.severity] || 0) + 1;
|
|
248
|
+
byCategory[finding.category] = (byCategory[finding.category] || 0) + 1;
|
|
249
|
+
byScanner[finding.source] = (byScanner[finding.source] || 0) + 1;
|
|
250
|
+
}
|
|
251
|
+
return {
|
|
252
|
+
totalFindings: findings.length,
|
|
253
|
+
bySeverity,
|
|
254
|
+
byCategory,
|
|
255
|
+
byScanner,
|
|
256
|
+
passesQualityGate: qualityGateResult.passes,
|
|
257
|
+
qualityGateDetails: qualityGateResult.details.join('\n')
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Print summary to console
|
|
262
|
+
*/
|
|
263
|
+
printSummary(report) {
|
|
264
|
+
const { summary, findings } = report;
|
|
265
|
+
console.log(chalk.bold('\nš Summary\n'));
|
|
266
|
+
// Severity breakdown
|
|
267
|
+
const severityColors = {
|
|
268
|
+
critical: chalk.red.bold,
|
|
269
|
+
high: chalk.red,
|
|
270
|
+
medium: chalk.yellow,
|
|
271
|
+
low: chalk.blue,
|
|
272
|
+
info: chalk.gray
|
|
273
|
+
};
|
|
274
|
+
const severities = ['critical', 'high', 'medium', 'low', 'info'];
|
|
275
|
+
for (const sev of severities) {
|
|
276
|
+
const count = summary.bySeverity[sev] || 0;
|
|
277
|
+
if (count > 0) {
|
|
278
|
+
console.log(` ${severityColors[sev](`${sev.toUpperCase()}: ${count}`)}`);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
console.log(chalk.gray(`\n Total: ${summary.totalFindings} findings\n`));
|
|
282
|
+
// Quality gate
|
|
283
|
+
console.log(chalk.bold('š¦ Quality Gate\n'));
|
|
284
|
+
const gateIcon = summary.passesQualityGate ? 'ā
' : 'ā';
|
|
285
|
+
const gateColor = summary.passesQualityGate ? chalk.green : chalk.red;
|
|
286
|
+
console.log(gateColor(` ${gateIcon} ${summary.passesQualityGate ? 'PASSED' : 'FAILED'}\n`));
|
|
287
|
+
if (summary.qualityGateDetails) {
|
|
288
|
+
for (const detail of summary.qualityGateDetails.split('\n')) {
|
|
289
|
+
const color = detail.startsWith('ā') ? chalk.green : chalk.red;
|
|
290
|
+
console.log(` ${color(detail)}`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// Top findings
|
|
294
|
+
if (findings.length > 0) {
|
|
295
|
+
console.log(chalk.bold('\nš“ Top Findings\n'));
|
|
296
|
+
const topFindings = findings.slice(0, 5);
|
|
297
|
+
for (const finding of topFindings) {
|
|
298
|
+
const sevColor = severityColors[finding.severity];
|
|
299
|
+
console.log(` ${sevColor(`[${finding.severity.toUpperCase()}]`)} ${finding.title}`);
|
|
300
|
+
console.log(chalk.gray(` ${finding.file}${finding.line ? `:${finding.line}` : ''}`));
|
|
301
|
+
console.log(chalk.gray(` Source: ${finding.source}`));
|
|
302
|
+
console.log('');
|
|
303
|
+
}
|
|
304
|
+
if (findings.length > 5) {
|
|
305
|
+
console.log(chalk.gray(` ... and ${findings.length - 5} more findings\n`));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Create an empty report (when no scanners available)
|
|
311
|
+
*/
|
|
312
|
+
createEmptyReport(reportId, target, startTime) {
|
|
313
|
+
return {
|
|
314
|
+
id: reportId,
|
|
315
|
+
timestamp: new Date().toISOString(),
|
|
316
|
+
target,
|
|
317
|
+
results: [],
|
|
318
|
+
findings: [],
|
|
319
|
+
summary: {
|
|
320
|
+
totalFindings: 0,
|
|
321
|
+
bySeverity: {},
|
|
322
|
+
byCategory: {},
|
|
323
|
+
byScanner: {},
|
|
324
|
+
passesQualityGate: true,
|
|
325
|
+
qualityGateDetails: 'No scanners ran'
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
export default Orchestrator;
|
|
331
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../src/orchestrator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAOL,oBAAoB,EACpB,cAAc,EAEf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAWrD,MAAM,OAAO,YAAY;IACf,QAAQ,CAAY;IACpB,WAAW,CAAc;IACzB,QAAQ,CAAU;IAClB,OAAO,CAAU;IAEzB,YAAY,SAA6B,EAAE;QACzC,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,cAAc,EAAE,CAAC;QACpD,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,oBAAoB,CAAC;QAC9D,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,IAAI,CAAC;QACxC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,KAAK,CAAC;QAEvC,2CAA2C;QAC3C,IAAI,MAAM,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;YAC9B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAC7C,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,UAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CACjE,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,aAAa;QACjB,MAAM,OAAO,GAA4B,EAAE,CAAC;QAC5C,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;QACtD,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CAAC,MAAkB;QAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,UAAU,EAAE,CAAC;QAE9B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC,CAAC;QAC7E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAEpF,6BAA6B;QAC7B,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAEhE,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,oDAAoD,CAAC,CAAC,CAAC;YAChF,OAAO,IAAI,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;QAC7D,CAAC;QAED,eAAe;QACf,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ;YAC3B,CAAC,CAAC,MAAM,IAAI,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,MAAM,CAAC;YAC3D,CAAC,CAAC,MAAM,IAAI,CAAC,qBAAqB,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;QAEhE,qCAAqC;QACrC,MAAM,kBAAkB,GAAG,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;QAE3D,qBAAqB;QACrB,MAAM,iBAAiB,GAAG,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,CAAC;QAEvE,iBAAiB;QACjB,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,kBAAkB,EAAE,iBAAiB,CAAC,CAAC;QAE1E,eAAe;QACf,MAAM,MAAM,GAAe;YACzB,EAAE,EAAE,QAAQ;YACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM;YACN,OAAO;YACP,QAAQ,EAAE,kBAAkB;YAC5B,OAAO;SACR,CAAC;QAEF,gBAAgB;QAChB,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QAE1B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,wBAAwB;QACpC,MAAM,SAAS,GAAc,EAAE,CAAC;QAEhC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACpC,MAAM,OAAO,GAAG,GAAG,CAAC;gBAClB,IAAI,EAAE,YAAY,OAAO,CAAC,IAAI,KAAK;gBACnC,KAAK,EAAE,MAAM;aACd,CAAC,CAAC,KAAK,EAAE,CAAC;YAEX,IAAI,CAAC;gBACH,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,WAAW,EAAE,CAAC;gBAChD,IAAI,WAAW,EAAE,CAAC;oBAChB,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,IAAI,YAAY,CAAC,CAAC,CAAC;oBAC1D,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC1B,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC;gBAC9D,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,IAAI,QAAQ,CAAC,CAAC,CAAC;YACnD,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,mBAAmB,CAC/B,QAAmB,EACnB,MAAkB;QAElB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC,CAAC;QAE7D,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAC,OAAO,EAAC,EAAE;YAC5C,MAAM,OAAO,GAAG,GAAG,CAAC;gBAClB,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,eAAe;gBACpC,UAAU,EAAE,IAAI;aACjB,CAAC,CAAC,KAAK,EAAE,CAAC;YAEX,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAE1C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACnB,OAAO,CAAC,OAAO,CACb,GAAG,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,QAAQ,CAAC,MAAM,cAAc,MAAM,CAAC,OAAO,CAAC,QAAQ,KAAK,CACrF,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;gBACnD,CAAC;gBAED,OAAO,MAAM,CAAC;YAChB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,UAAU,CAAC,CAAC;gBACxC,OAAO;oBACL,OAAO,EAAE,OAAO,CAAC,IAAI;oBACrB,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;oBAC7D,QAAQ,EAAE,EAAE;oBACZ,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE;iBACzB,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,qBAAqB,CACjC,QAAmB,EACnB,MAAkB;QAElB,MAAM,OAAO,GAAoB,EAAE,CAAC;QAEpC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,GAAG,CAAC;gBAClB,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,eAAe;gBACpC,UAAU,EAAE,IAAI;aACjB,CAAC,CAAC,KAAK,EAAE,CAAC;YAEX,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAE1C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;oBACnB,OAAO,CAAC,OAAO,CACb,GAAG,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,QAAQ,CAAC,MAAM,cAAc,MAAM,CAAC,OAAO,CAAC,QAAQ,KAAK,CACrF,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC;gBACnD,CAAC;gBAED,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACvB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,UAAU,CAAC,CAAC;gBACxC,OAAO,CAAC,IAAI,CAAC;oBACX,OAAO,EAAE,OAAO,CAAC,IAAI;oBACrB,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;oBAC7D,QAAQ,EAAE,EAAE;oBACZ,OAAO,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE;iBACzB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,OAAwB;QAChD,MAAM,WAAW,GAAc,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAE/B,uBAAuB;QACvB,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,WAAW,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvC,CAAC;QAED,6BAA6B;QAC7B,MAAM,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE;YAChD,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACvF,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAClB,OAAO,KAAK,CAAC;YACf,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACd,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CAAC;QAEH,iDAAiD;QACjD,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;YAChC,MAAM,YAAY,GAAG,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YAC7E,IAAI,YAAY,KAAK,CAAC;gBAAE,OAAO,YAAY,CAAC;YAC5C,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,mBAAmB,CAAC,QAAmB;QAC7C,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,MAAM,GAAG,IAAI,CAAC;QAElB,MAAM,OAAO,GAAG;YACd,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,MAAM;YACzE,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM;YACjE,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,MAAM;YACzE,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,MAAM;YACrE,cAAc,EAAE,QAAQ,CAAC,MAAM;YAC/B,YAAY,EAAE,QAAQ,CAAC,MAAM,CAAC,iDAAiD;SAChF,CAAC;QAEF,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;YAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,MAA8B,CAAC,IAAI,CAAC,CAAC;YAChE,IAAI,QAAQ,GAAG,IAAI,CAAC;YAEpB,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACtB,KAAK,IAAI;oBAAE,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC;oBAAC,MAAM;gBACpD,KAAK,KAAK;oBAAE,QAAQ,GAAG,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC;oBAAC,MAAM;gBACtD,KAAK,IAAI;oBAAE,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC;oBAAC,MAAM;gBACpD,KAAK,KAAK;oBAAE,QAAQ,GAAG,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC;oBAAC,MAAM;gBACtD,KAAK,IAAI;oBAAE,QAAQ,GAAG,KAAK,KAAK,IAAI,CAAC,SAAS,CAAC;oBAAC,MAAM;YACxD,CAAC;YAED,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YACpC,OAAO,CAAC,IAAI,CACV,GAAG,MAAM,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,gBAAgB,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,GAAG,CACrF,CAAC;YAEF,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;gBACnC,MAAM,GAAG,KAAK,CAAC;YACjB,CAAC;QACH,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED;;OAEG;IACK,aAAa,CACnB,QAAmB,EACnB,iBAAyD;QAEzD,MAAM,UAAU,GAA2B,EAAE,CAAC;QAC9C,MAAM,UAAU,GAA2B,EAAE,CAAC;QAC9C,MAAM,SAAS,GAA2B,EAAE,CAAC;QAE7C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC/B,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACvE,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;YACvE,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACnE,CAAC;QAED,OAAO;YACL,aAAa,EAAE,QAAQ,CAAC,MAAM;YAC9B,UAAU;YACV,UAAU;YACV,SAAS;YACT,iBAAiB,EAAE,iBAAiB,CAAC,MAAM;YAC3C,kBAAkB,EAAE,iBAAiB,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;SACzD,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,YAAY,CAAC,MAAkB;QACrC,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC;QAErC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAE1C,qBAAqB;QACrB,MAAM,cAAc,GAA4C;YAC9D,QAAQ,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI;YACxB,IAAI,EAAE,KAAK,CAAC,GAAG;YACf,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,GAAG,EAAE,KAAK,CAAC,IAAI;YACf,IAAI,EAAE,KAAK,CAAC,IAAI;SACjB,CAAC;QAEF,MAAM,UAAU,GAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAClF,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;gBACd,OAAO,CAAC,GAAG,CAAC,KAAK,cAAc,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,WAAW,EAAE,KAAK,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;YAC5E,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,OAAO,CAAC,aAAa,aAAa,CAAC,CAAC,CAAC;QAE1E,eAAe;QACf,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC7C,MAAM,QAAQ,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QACvD,MAAM,SAAS,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;QAE7F,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;YAC/B,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,kBAAkB,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5D,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;gBAC/D,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAED,eAAe;QACf,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,CAAC;YAE/C,MAAM,WAAW,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACzC,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;gBAClC,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;gBAClD,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;gBACrF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;gBACxF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBACzD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAClB,CAAC;YAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,QAAQ,CAAC,MAAM,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC;YAC9E,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,iBAAiB,CACvB,QAAgB,EAChB,MAAkB,EAClB,SAAiB;QAEjB,OAAO;YACL,EAAE,EAAE,QAAQ;YACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM;YACN,OAAO,EAAE,EAAE;YACX,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE;gBACP,aAAa,EAAE,CAAC;gBAChB,UAAU,EAAE,EAAE;gBACd,UAAU,EAAE,EAAE;gBACd,SAAS,EAAE,EAAE;gBACb,iBAAiB,EAAE,IAAI;gBACvB,kBAAkB,EAAE,iBAAiB;aACtC;SACF,CAAC;IACJ,CAAC;CACF;AAED,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Complexity Scanner
|
|
3
|
+
*
|
|
4
|
+
* Analyzes code complexity using various metrics
|
|
5
|
+
*
|
|
6
|
+
* Improvements based on expert feedback:
|
|
7
|
+
* - Excludes test files by default
|
|
8
|
+
* - Excludes type definition files (.d.ts)
|
|
9
|
+
* - Raised thresholds to industry standards (High: 25+, Medium: 20+)
|
|
10
|
+
* - Better remediation advice with specific function names
|
|
11
|
+
* - Smarter detection that avoids type-only files
|
|
12
|
+
*/
|
|
13
|
+
import { Scanner, ScanTarget, ScannerConfig, ScannerResult, FindingCategory } from '../types.js';
|
|
14
|
+
interface ComplexityConfig {
|
|
15
|
+
highComplexityThreshold: number;
|
|
16
|
+
mediumComplexityThreshold: number;
|
|
17
|
+
maxFileLines: number;
|
|
18
|
+
maxFunctionLines: number;
|
|
19
|
+
excludeTestFiles: boolean;
|
|
20
|
+
excludeTypeFiles: boolean;
|
|
21
|
+
excludePatterns: string[];
|
|
22
|
+
reportTodos: boolean;
|
|
23
|
+
reportDebugStatements: boolean;
|
|
24
|
+
}
|
|
25
|
+
export declare class ComplexityScanner implements Scanner {
|
|
26
|
+
name: string;
|
|
27
|
+
categories: FindingCategory[];
|
|
28
|
+
private config;
|
|
29
|
+
private supportedExtensions;
|
|
30
|
+
private testPatterns;
|
|
31
|
+
constructor(config?: Partial<ComplexityConfig>);
|
|
32
|
+
isAvailable(): Promise<boolean>;
|
|
33
|
+
scan(target: ScanTarget, config?: ScannerConfig): Promise<ScannerResult>;
|
|
34
|
+
private shouldExcludeFile;
|
|
35
|
+
private isTypeOnlyFile;
|
|
36
|
+
private collectFiles;
|
|
37
|
+
private analyzeFile;
|
|
38
|
+
private generateComplexitySuggestion;
|
|
39
|
+
private analyzeFunctions;
|
|
40
|
+
private extractFunctionBody;
|
|
41
|
+
private calculateFunctionComplexity;
|
|
42
|
+
private calculateLineMetrics;
|
|
43
|
+
private getCommentPatterns;
|
|
44
|
+
private detectCodeSmells;
|
|
45
|
+
private createFinding;
|
|
46
|
+
}
|
|
47
|
+
export default ComplexityScanner;
|
|
48
|
+
//# sourceMappingURL=complexity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"complexity.d.ts","sourceRoot":"","sources":["../../src/scanners/complexity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAIH,OAAO,EACL,OAAO,EACP,UAAU,EACV,aAAa,EACb,aAAa,EAEb,eAAe,EAGhB,MAAM,aAAa,CAAC;AASrB,UAAU,gBAAgB;IAExB,uBAAuB,EAAE,MAAM,CAAC;IAChC,yBAAyB,EAAE,MAAM,CAAC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IAGzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,eAAe,EAAE,MAAM,EAAE,CAAC;IAG1B,WAAW,EAAE,OAAO,CAAC;IACrB,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAcD,qBAAa,iBAAkB,YAAW,OAAO;IAC/C,IAAI,SAAgB;IACpB,UAAU,EAAE,eAAe,EAAE,CAA6B;IAE1D,OAAO,CAAC,MAAM,CAAmB;IAGjC,OAAO,CAAC,mBAAmB,CAA+E;IAG1G,OAAO,CAAC,YAAY,CASlB;gBAEU,MAAM,GAAE,OAAO,CAAC,gBAAgB,CAAM;IAI5C,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAI/B,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAgC9E,OAAO,CAAC,iBAAiB;IA2BzB,OAAO,CAAC,cAAc;IA0BtB,OAAO,CAAC,YAAY;YA+CN,WAAW;IAyFzB,OAAO,CAAC,4BAA4B;IAiBpC,OAAO,CAAC,gBAAgB;IAqDxB,OAAO,CAAC,mBAAmB;IA0C3B,OAAO,CAAC,2BAA2B;IAiCnC,OAAO,CAAC,oBAAoB;IAsC5B,OAAO,CAAC,kBAAkB;IAgB1B,OAAO,CAAC,gBAAgB;IAkFxB,OAAO,CAAC,aAAa;CA8BtB;AAED,eAAe,iBAAiB,CAAC"}
|