@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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +58 -0
  3. package/dist/agent-report.d.ts +36 -0
  4. package/dist/agent-report.d.ts.map +1 -0
  5. package/dist/agent-report.js +329 -0
  6. package/dist/agent-report.js.map +1 -0
  7. package/dist/ai-summary.d.ts +55 -0
  8. package/dist/ai-summary.d.ts.map +1 -0
  9. package/dist/ai-summary.js +267 -0
  10. package/dist/ai-summary.js.map +1 -0
  11. package/dist/cli.d.ts +9 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +328 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/index.d.ts +23 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +27 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/orchestrator.d.ts +63 -0
  20. package/dist/orchestrator.d.ts.map +1 -0
  21. package/dist/orchestrator.js +331 -0
  22. package/dist/orchestrator.js.map +1 -0
  23. package/dist/scanners/complexity.d.ts +48 -0
  24. package/dist/scanners/complexity.d.ts.map +1 -0
  25. package/dist/scanners/complexity.js +512 -0
  26. package/dist/scanners/complexity.js.map +1 -0
  27. package/dist/scanners/eslint.d.ts +21 -0
  28. package/dist/scanners/eslint.d.ts.map +1 -0
  29. package/dist/scanners/eslint.js +196 -0
  30. package/dist/scanners/eslint.js.map +1 -0
  31. package/dist/scanners/gitleaks.d.ts +21 -0
  32. package/dist/scanners/gitleaks.d.ts.map +1 -0
  33. package/dist/scanners/gitleaks.js +158 -0
  34. package/dist/scanners/gitleaks.js.map +1 -0
  35. package/dist/scanners/index.d.ts +56 -0
  36. package/dist/scanners/index.d.ts.map +1 -0
  37. package/dist/scanners/index.js +71 -0
  38. package/dist/scanners/index.js.map +1 -0
  39. package/dist/scanners/npm-audit.d.ts +19 -0
  40. package/dist/scanners/npm-audit.d.ts.map +1 -0
  41. package/dist/scanners/npm-audit.js +176 -0
  42. package/dist/scanners/npm-audit.js.map +1 -0
  43. package/dist/scanners/semgrep.d.ts +22 -0
  44. package/dist/scanners/semgrep.d.ts.map +1 -0
  45. package/dist/scanners/semgrep.js +175 -0
  46. package/dist/scanners/semgrep.js.map +1 -0
  47. package/dist/types.d.ts +522 -0
  48. package/dist/types.d.ts.map +1 -0
  49. package/dist/types.js +194 -0
  50. package/dist/types.js.map +1 -0
  51. package/package.json +53 -0
@@ -0,0 +1,176 @@
1
+ /**
2
+ * NPM Audit Scanner
3
+ *
4
+ * Dependency vulnerability scanning for JavaScript/Node.js projects
5
+ * Covers: dependency category
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 NpmAuditScanner {
14
+ name = 'npm-audit';
15
+ categories = ['dependency'];
16
+ async isAvailable() {
17
+ try {
18
+ const { stdout } = await execAsync('npm --version', { timeout: 5000 });
19
+ return true;
20
+ }
21
+ catch {
22
+ return false;
23
+ }
24
+ }
25
+ async scan(target, config) {
26
+ const startTime = Date.now();
27
+ // Check if this is a Node.js project
28
+ const packageJsonPath = join(target.path, 'package.json');
29
+ if (!existsSync(packageJsonPath)) {
30
+ return {
31
+ scanner: this.name,
32
+ success: true,
33
+ findings: [],
34
+ metrics: { duration: Date.now() - startTime },
35
+ metadata: { skipped: true, reason: 'No package.json found' }
36
+ };
37
+ }
38
+ if (!await this.isAvailable()) {
39
+ return {
40
+ scanner: this.name,
41
+ success: false,
42
+ error: 'npm not available',
43
+ findings: [],
44
+ metrics: { duration: Date.now() - startTime }
45
+ };
46
+ }
47
+ try {
48
+ const findings = await this.runNpmAudit(target);
49
+ return {
50
+ scanner: this.name,
51
+ success: true,
52
+ findings,
53
+ metrics: {
54
+ duration: Date.now() - startTime
55
+ }
56
+ };
57
+ }
58
+ catch (error) {
59
+ return {
60
+ scanner: this.name,
61
+ success: false,
62
+ error: error instanceof Error ? error.message : String(error),
63
+ findings: [],
64
+ metrics: { duration: Date.now() - startTime }
65
+ };
66
+ }
67
+ }
68
+ async runNpmAudit(target) {
69
+ const cmd = `cd "${target.path}" && npm audit --json 2>/dev/null || true`;
70
+ try {
71
+ const { stdout } = await execAsync(cmd, {
72
+ timeout: 120000,
73
+ maxBuffer: 10 * 1024 * 1024
74
+ });
75
+ if (!stdout.trim()) {
76
+ return [];
77
+ }
78
+ const output = JSON.parse(stdout);
79
+ return this.transformFindings(output, target.path);
80
+ }
81
+ catch (error) {
82
+ // npm audit returns exit code 1 when vulnerabilities exist
83
+ if (error.stdout) {
84
+ try {
85
+ const output = JSON.parse(error.stdout);
86
+ return this.transformFindings(output, target.path);
87
+ }
88
+ catch {
89
+ return [];
90
+ }
91
+ }
92
+ throw error;
93
+ }
94
+ }
95
+ transformFindings(output, basePath) {
96
+ const findings = [];
97
+ for (const [pkgName, vuln] of Object.entries(output.vulnerabilities || {})) {
98
+ // Get the most specific vulnerability info
99
+ const viaDetails = vuln.via.filter(v => typeof v === 'object')[0];
100
+ if (!viaDetails)
101
+ continue;
102
+ const severity = this.mapSeverity(vuln.severity);
103
+ const fixInfo = this.getFixInfo(vuln.fixAvailable);
104
+ const finding = {
105
+ id: `npm-${pkgName}-${viaDetails.source || Date.now()}`,
106
+ source: this.name,
107
+ severity,
108
+ category: 'dependency',
109
+ file: 'package.json',
110
+ title: `Vulnerable dependency: ${pkgName}`,
111
+ description: `${viaDetails.title || 'Security vulnerability'}\n\n` +
112
+ `Package: ${pkgName}\n` +
113
+ `Vulnerable versions: ${vuln.range}\n` +
114
+ `Dependency path: ${vuln.isDirect ? 'Direct dependency' : 'Transitive dependency'}\n` +
115
+ (viaDetails.url ? `\nMore info: ${viaDetails.url}` : ''),
116
+ cwe: viaDetails.cwe?.[0] ? `CWE-${viaDetails.cwe[0]}` : undefined,
117
+ cvss: viaDetails.cvss?.score,
118
+ suggestion: fixInfo.suggestion,
119
+ fixAvailable: fixInfo.available,
120
+ autoFixable: fixInfo.autoFixable,
121
+ ruleId: `npm-advisory-${viaDetails.source}`,
122
+ ruleUrl: viaDetails.url,
123
+ confidence: 'high',
124
+ effort: fixInfo.effort,
125
+ fingerprint: ''
126
+ };
127
+ finding.fingerprint = generateFingerprint(finding);
128
+ findings.push(finding);
129
+ }
130
+ return findings;
131
+ }
132
+ mapSeverity(npmSeverity) {
133
+ const mapping = {
134
+ 'critical': 'critical',
135
+ 'high': 'high',
136
+ 'moderate': 'medium',
137
+ 'low': 'low',
138
+ 'info': 'info'
139
+ };
140
+ return mapping[npmSeverity.toLowerCase()] || 'medium';
141
+ }
142
+ getFixInfo(fixAvailable) {
143
+ if (fixAvailable === true) {
144
+ return {
145
+ available: true,
146
+ autoFixable: true,
147
+ suggestion: 'Run `npm audit fix` to automatically fix this vulnerability',
148
+ effort: 'trivial'
149
+ };
150
+ }
151
+ if (typeof fixAvailable === 'object' && fixAvailable !== null) {
152
+ if (fixAvailable.isSemVerMajor) {
153
+ return {
154
+ available: true,
155
+ autoFixable: false,
156
+ suggestion: `Update to ${fixAvailable.name}@${fixAvailable.version} (breaking change - review required). Run \`npm audit fix --force\` with caution`,
157
+ effort: 'medium'
158
+ };
159
+ }
160
+ return {
161
+ available: true,
162
+ autoFixable: true,
163
+ suggestion: `Update to ${fixAvailable.name}@${fixAvailable.version}. Run \`npm audit fix\``,
164
+ effort: 'easy'
165
+ };
166
+ }
167
+ return {
168
+ available: false,
169
+ autoFixable: false,
170
+ suggestion: 'No fix currently available. Consider using an alternative package or implementing mitigations',
171
+ effort: 'hard'
172
+ };
173
+ }
174
+ }
175
+ export default NpmAuditScanner;
176
+ //# sourceMappingURL=npm-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"npm-audit.js","sourceRoot":"","sources":["../../src/scanners/npm-audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Semgrep Scanner
3
+ *
4
+ * Provides SAST scanning using Semgrep CLI with fallback to MCP
5
+ * Covers: security, quality, style categories
6
+ */
7
+ import { Scanner, ScanTarget, ScannerConfig, ScannerResult, FindingCategory } from '../types.js';
8
+ export declare class SemgrepScanner implements Scanner {
9
+ name: string;
10
+ categories: FindingCategory[];
11
+ private rulesets;
12
+ constructor(rulesets?: string[]);
13
+ isAvailable(): Promise<boolean>;
14
+ scan(target: ScanTarget, config?: ScannerConfig): Promise<ScannerResult>;
15
+ private runSemgrep;
16
+ private transformFindings;
17
+ private mapSeverity;
18
+ private mapCategory;
19
+ private mapConfidence;
20
+ }
21
+ export default SemgrepScanner;
22
+ //# sourceMappingURL=semgrep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semgrep.d.ts","sourceRoot":"","sources":["../../src/scanners/semgrep.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EACL,OAAO,EACP,UAAU,EACV,aAAa,EACb,aAAa,EAEb,eAAe,EAGhB,MAAM,aAAa,CAAC;AAiCrB,qBAAa,cAAe,YAAW,OAAO;IAC5C,IAAI,SAAa;IACjB,UAAU,EAAE,eAAe,EAAE,CAAoC;IAEjE,OAAO,CAAC,QAAQ,CAAW;gBAEf,QAAQ,GAAE,MAAM,EAAa;IAYnC,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC;IAS/B,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;YAoChE,UAAU;IA0CxB,OAAO,CAAC,iBAAiB;IAkCzB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,WAAW;IAiBnB,OAAO,CAAC,aAAa;CAQtB;AAED,eAAe,cAAc,CAAC"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Semgrep Scanner
3
+ *
4
+ * Provides SAST scanning using Semgrep CLI with fallback to MCP
5
+ * Covers: security, quality, style categories
6
+ */
7
+ import { execSync, exec } from 'child_process';
8
+ import { promisify } from 'util';
9
+ import { generateFingerprint } from '../types.js';
10
+ const execAsync = promisify(exec);
11
+ export class SemgrepScanner {
12
+ name = 'semgrep';
13
+ categories = ['security', 'quality', 'style'];
14
+ rulesets;
15
+ constructor(rulesets = ['auto']) {
16
+ // Default rulesets for comprehensive scanning
17
+ this.rulesets = rulesets.length > 0 && rulesets[0] !== 'auto' ? rulesets : [
18
+ 'p/security-audit', // Security vulnerabilities
19
+ 'p/secrets', // Secret detection
20
+ 'p/javascript', // JS best practices
21
+ 'p/nodejs', // Node.js specific
22
+ 'p/typescript', // TypeScript specific
23
+ 'p/owasp-top-ten' // OWASP Top 10
24
+ ];
25
+ }
26
+ async isAvailable() {
27
+ try {
28
+ execSync('semgrep --version', { stdio: 'pipe' });
29
+ return true;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ async scan(target, config) {
36
+ const startTime = Date.now();
37
+ if (!await this.isAvailable()) {
38
+ return {
39
+ scanner: this.name,
40
+ success: false,
41
+ error: 'Semgrep CLI not installed. Install with: pip install semgrep',
42
+ findings: [],
43
+ metrics: { duration: Date.now() - startTime }
44
+ };
45
+ }
46
+ try {
47
+ const findings = await this.runSemgrep(target);
48
+ return {
49
+ scanner: this.name,
50
+ success: true,
51
+ findings,
52
+ metrics: {
53
+ duration: Date.now() - startTime,
54
+ filesScanned: findings.length > 0 ? new Set(findings.map(f => f.file)).size : 0
55
+ }
56
+ };
57
+ }
58
+ catch (error) {
59
+ return {
60
+ scanner: this.name,
61
+ success: false,
62
+ error: error instanceof Error ? error.message : String(error),
63
+ findings: [],
64
+ metrics: { duration: Date.now() - startTime }
65
+ };
66
+ }
67
+ }
68
+ async runSemgrep(target) {
69
+ const configArgs = this.rulesets.map(r => `--config ${r}`).join(' ');
70
+ // Build exclude patterns
71
+ const defaultExcludes = [
72
+ 'node_modules',
73
+ 'vendor',
74
+ '.git',
75
+ 'dist',
76
+ 'build',
77
+ '__pycache__',
78
+ '*.min.js',
79
+ '*.bundle.js'
80
+ ];
81
+ const excludes = [...defaultExcludes, ...(target.exclude || [])];
82
+ const excludeArgs = excludes.map(e => `--exclude '${e}'`).join(' ');
83
+ const cmd = `semgrep ${configArgs} ${excludeArgs} --json --quiet ${target.path}`;
84
+ try {
85
+ const { stdout } = await execAsync(cmd, {
86
+ timeout: 300000, // 5 minutes
87
+ maxBuffer: 50 * 1024 * 1024 // 50MB buffer for large outputs
88
+ });
89
+ const output = JSON.parse(stdout);
90
+ return this.transformFindings(output.results);
91
+ }
92
+ catch (error) {
93
+ // Semgrep returns exit code 1 when findings exist
94
+ if (error.stdout) {
95
+ try {
96
+ const output = JSON.parse(error.stdout);
97
+ return this.transformFindings(output.results);
98
+ }
99
+ catch {
100
+ throw new Error(`Failed to parse Semgrep output: ${error.message}`);
101
+ }
102
+ }
103
+ throw error;
104
+ }
105
+ }
106
+ transformFindings(semgrepFindings) {
107
+ return semgrepFindings.map(sf => {
108
+ const severity = this.mapSeverity(sf.extra.severity);
109
+ const category = this.mapCategory(sf.check_id, sf.extra.metadata);
110
+ const finding = {
111
+ id: `semgrep-${sf.check_id}-${sf.path}-${sf.start.line}`,
112
+ source: this.name,
113
+ severity,
114
+ category,
115
+ file: sf.path,
116
+ line: sf.start.line,
117
+ endLine: sf.end.line,
118
+ column: sf.start.col,
119
+ endColumn: sf.end.col,
120
+ title: sf.check_id.split('.').pop() || sf.check_id,
121
+ description: sf.extra.message,
122
+ snippet: sf.extra.lines,
123
+ cwe: sf.extra.metadata?.cwe?.[0],
124
+ owasp: sf.extra.metadata?.owasp?.[0],
125
+ suggestion: sf.extra.fix,
126
+ fixAvailable: !!sf.extra.fix,
127
+ autoFixable: !!sf.extra.fix,
128
+ ruleId: sf.check_id,
129
+ ruleUrl: sf.extra.metadata?.references?.[0],
130
+ confidence: this.mapConfidence(sf.extra.metadata?.confidence),
131
+ fingerprint: ''
132
+ };
133
+ finding.fingerprint = generateFingerprint(finding);
134
+ return finding;
135
+ });
136
+ }
137
+ mapSeverity(semgrepSeverity) {
138
+ const mapping = {
139
+ 'ERROR': 'high',
140
+ 'WARNING': 'medium',
141
+ 'INFO': 'low'
142
+ };
143
+ return mapping[semgrepSeverity.toUpperCase()] || 'medium';
144
+ }
145
+ mapCategory(ruleId, metadata) {
146
+ // Check rule ID patterns
147
+ if (ruleId.includes('secret') || ruleId.includes('password') || ruleId.includes('key')) {
148
+ return 'secret';
149
+ }
150
+ if (ruleId.includes('security') || ruleId.includes('injection') || ruleId.includes('xss')) {
151
+ return 'security';
152
+ }
153
+ // Check metadata category
154
+ const cat = metadata?.category?.toLowerCase();
155
+ if (cat?.includes('security'))
156
+ return 'security';
157
+ if (cat?.includes('best-practice'))
158
+ return 'quality';
159
+ return 'security'; // Default for Semgrep
160
+ }
161
+ mapConfidence(confidence) {
162
+ if (!confidence)
163
+ return undefined;
164
+ const c = confidence.toLowerCase();
165
+ if (c === 'high')
166
+ return 'high';
167
+ if (c === 'medium')
168
+ return 'medium';
169
+ if (c === 'low')
170
+ return 'low';
171
+ return undefined;
172
+ }
173
+ }
174
+ export default SemgrepScanner;
175
+ //# sourceMappingURL=semgrep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semgrep.js","sourceRoot":"","sources":["../../src/scanners/semgrep.ts"],"names":[],"mappings":"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"}