@indicated/vibeguard 1.2.0 → 1.3.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/dist/cli/commands/scan.d.ts.map +1 -1
- package/dist/cli/commands/scan.js +44 -19
- package/dist/cli/commands/scan.js.map +1 -1
- package/dist/cli/output.d.ts +1 -0
- package/dist/cli/output.d.ts.map +1 -1
- package/dist/cli/output.js +28 -0
- package/dist/cli/output.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +88 -16
- package/dist/mcp/server.js.map +1 -1
- package/dist/scanner/index.d.ts.map +1 -1
- package/dist/scanner/index.js +34 -0
- package/dist/scanner/index.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/scan.ts +44 -19
- package/src/cli/output.ts +34 -0
- package/src/mcp/server.ts +91 -21
- package/src/scanner/index.ts +40 -0
- package/PROGRESS.md +0 -221
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/scan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBpC,wBAAgB,iBAAiB,IAAI,OAAO,CAwG3C"}
|
|
@@ -67,32 +67,57 @@ function createScanCommand() {
|
|
|
67
67
|
console.log((0, output_1.formatScanning)(result.files));
|
|
68
68
|
}
|
|
69
69
|
// Output results
|
|
70
|
+
const userTier = scanner.getUserTier();
|
|
70
71
|
if (options.json) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
72
|
+
// For free tier, only include counts in JSON, not individual findings
|
|
73
|
+
if (userTier === 'free') {
|
|
74
|
+
const counts = {
|
|
75
|
+
critical: result.findings.filter(f => f.rule.severity === 'critical').length,
|
|
76
|
+
high: result.findings.filter(f => f.rule.severity === 'high').length,
|
|
77
|
+
medium: result.findings.filter(f => f.rule.severity === 'medium').length,
|
|
78
|
+
low: result.findings.filter(f => f.rule.severity === 'low').length,
|
|
79
|
+
};
|
|
80
|
+
console.log(JSON.stringify({
|
|
81
|
+
version: packageJson.version,
|
|
82
|
+
tier: userTier,
|
|
83
|
+
files: result.files,
|
|
84
|
+
totalIssues: result.findings.length,
|
|
85
|
+
counts,
|
|
86
|
+
findings: [], // Empty for free tier
|
|
87
|
+
duration: result.duration,
|
|
88
|
+
upgradeMessage: 'Upgrade to Pro to see individual findings with file locations and fix suggestions',
|
|
89
|
+
}, null, 2));
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
console.log(JSON.stringify({
|
|
93
|
+
version: packageJson.version,
|
|
94
|
+
tier: userTier,
|
|
95
|
+
files: result.files,
|
|
96
|
+
findings: result.findings.map(f => ({
|
|
97
|
+
rule: f.rule.id,
|
|
98
|
+
severity: f.rule.severity,
|
|
99
|
+
tier: f.rule.tier,
|
|
100
|
+
file: path.relative(cwd, f.file),
|
|
101
|
+
line: f.line,
|
|
102
|
+
column: f.column,
|
|
103
|
+
message: f.rule.name,
|
|
104
|
+
fix: f.isRestricted ? null : f.rule.fix,
|
|
105
|
+
isRestricted: f.isRestricted,
|
|
106
|
+
})),
|
|
107
|
+
duration: result.duration,
|
|
108
|
+
}, null, 2));
|
|
109
|
+
}
|
|
89
110
|
}
|
|
90
111
|
else if (!options.quiet) {
|
|
91
112
|
if (result.findings.length === 0) {
|
|
92
113
|
console.log((0, output_1.formatCleanResult)());
|
|
93
114
|
}
|
|
115
|
+
else if (userTier === 'free') {
|
|
116
|
+
// Free tier: show counts only, no individual findings
|
|
117
|
+
console.log((0, output_1.formatFreeUserSummary)(result));
|
|
118
|
+
}
|
|
94
119
|
else {
|
|
95
|
-
|
|
120
|
+
// Pro tier: show full details
|
|
96
121
|
for (const finding of result.findings) {
|
|
97
122
|
console.log((0, output_1.formatFinding)(finding, cwd));
|
|
98
123
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/cli/commands/scan.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/cli/commands/scan.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/output.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export declare function formatSeverity(severity: Severity): string;
|
|
|
3
3
|
export declare function formatFinding(finding: Finding, cwd: string): string;
|
|
4
4
|
export declare function formatSummary(result: ScanResult, userTier?: Tier): string;
|
|
5
5
|
export declare function formatUpgradePrompt(restrictedCount: number): string;
|
|
6
|
+
export declare function formatFreeUserSummary(result: ScanResult): string;
|
|
6
7
|
export declare function formatHeader(version: string): string;
|
|
7
8
|
export declare function formatScanning(fileCount: number): string;
|
|
8
9
|
export declare function formatSuccess(message: string): string;
|
package/dist/cli/output.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAkC7E,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAIzD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAmBnE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,IAAI,GAAG,MAAM,CAmCzE;AAED,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAMnE;AA2BD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAUrD;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAG5C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAI7D"}
|
|
1
|
+
{"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAkC7E,wBAAgB,cAAc,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAIzD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAmBnE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,IAAI,GAAG,MAAM,CAmCzE;AAED,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAMnE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAgChE;AA2BD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAUrD;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAG5C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAI7D"}
|
package/dist/cli/output.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.formatSeverity = formatSeverity;
|
|
|
4
4
|
exports.formatFinding = formatFinding;
|
|
5
5
|
exports.formatSummary = formatSummary;
|
|
6
6
|
exports.formatUpgradePrompt = formatUpgradePrompt;
|
|
7
|
+
exports.formatFreeUserSummary = formatFreeUserSummary;
|
|
7
8
|
exports.formatHeader = formatHeader;
|
|
8
9
|
exports.formatScanning = formatScanning;
|
|
9
10
|
exports.formatSuccess = formatSuccess;
|
|
@@ -103,6 +104,33 @@ function formatUpgradePrompt(restrictedCount) {
|
|
|
103
104
|
output += `${colors.dim}Run ${colors.reset}${colors.cyan}vibeguard upgrade${colors.reset}${colors.dim} to unlock framework-specific security rules${colors.reset}\n`;
|
|
104
105
|
return output;
|
|
105
106
|
}
|
|
107
|
+
function formatFreeUserSummary(result) {
|
|
108
|
+
const counts = {
|
|
109
|
+
critical: 0,
|
|
110
|
+
high: 0,
|
|
111
|
+
medium: 0,
|
|
112
|
+
low: 0,
|
|
113
|
+
};
|
|
114
|
+
for (const finding of result.findings) {
|
|
115
|
+
counts[finding.rule.severity]++;
|
|
116
|
+
}
|
|
117
|
+
const total = result.findings.length;
|
|
118
|
+
const grade = calculateGrade(counts);
|
|
119
|
+
let output = '\n';
|
|
120
|
+
output += `${colors.dim}─────────────────────────────────────────${colors.reset}\n`;
|
|
121
|
+
output += `Found ${colors.bold}${total}${colors.reset} issue${total !== 1 ? 's' : ''} `;
|
|
122
|
+
output += `(${colors.red}${counts.critical} critical${colors.reset}, `;
|
|
123
|
+
output += `${colors.yellow}${counts.high} high${colors.reset}, `;
|
|
124
|
+
output += `${colors.blue}${counts.medium} medium${colors.reset}, `;
|
|
125
|
+
output += `${colors.dim}${counts.low} low${colors.reset})\n\n`;
|
|
126
|
+
output += `Grade: ${formatGrade(grade)}\n`;
|
|
127
|
+
// Upgrade prompt for free users
|
|
128
|
+
output += '\n';
|
|
129
|
+
output += `${colors.magenta}${colors.bold}[PRO]${colors.reset} `;
|
|
130
|
+
output += `Upgrade to see individual findings with file locations and fix suggestions\n`;
|
|
131
|
+
output += `${colors.dim}Run ${colors.reset}${colors.cyan}vibeguard upgrade${colors.reset}${colors.dim} to unlock full scan details${colors.reset}\n`;
|
|
132
|
+
return output;
|
|
133
|
+
}
|
|
106
134
|
function calculateGrade(counts) {
|
|
107
135
|
if (counts.critical > 0)
|
|
108
136
|
return 'F';
|
package/dist/cli/output.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":";;AAkCA,wCAIC;AAED,sCAmBC;AAED,sCAmCC;AAED,kDAMC;AA2BD,oCAEC;AAED,wCAEC;AAED,sCAEC;AAED,kCAEC;AAED,sCAEC;AAED,gCAEC;AAED,gCAUC;AAED,kDAGC;AAED,8CAGC;AAED,8CAIC;
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAoBA,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAoPpD"}
|
package/dist/mcp/server.js
CHANGED
|
@@ -40,6 +40,24 @@ const zod_1 = require("zod");
|
|
|
40
40
|
const path = __importStar(require("path"));
|
|
41
41
|
const scanner_1 = require("../scanner");
|
|
42
42
|
const definitions_1 = require("../scanner/rules/definitions");
|
|
43
|
+
const license_1 = require("../api/license");
|
|
44
|
+
function calculateGrade(counts) {
|
|
45
|
+
if (counts.critical > 0)
|
|
46
|
+
return 'F';
|
|
47
|
+
if (counts.high > 2)
|
|
48
|
+
return 'D';
|
|
49
|
+
if (counts.high > 0)
|
|
50
|
+
return 'C';
|
|
51
|
+
if (counts.medium > 3)
|
|
52
|
+
return 'C';
|
|
53
|
+
if (counts.medium > 0)
|
|
54
|
+
return 'B';
|
|
55
|
+
if (counts.low > 5)
|
|
56
|
+
return 'B';
|
|
57
|
+
if (counts.low > 0)
|
|
58
|
+
return 'A';
|
|
59
|
+
return 'A+';
|
|
60
|
+
}
|
|
43
61
|
async function startMcpServer() {
|
|
44
62
|
const server = new mcp_js_1.McpServer({
|
|
45
63
|
name: 'vibeguard',
|
|
@@ -51,24 +69,46 @@ async function startMcpServer() {
|
|
|
51
69
|
staged_only: zod_1.z.boolean().optional().describe('If true, only scan git staged files'),
|
|
52
70
|
}, async ({ paths, staged_only }) => {
|
|
53
71
|
try {
|
|
72
|
+
const licenseKey = (0, license_1.getLicenseKey)();
|
|
54
73
|
const scanner = new scanner_1.Scanner();
|
|
55
|
-
await scanner.initialize();
|
|
74
|
+
await scanner.initialize(licenseKey || undefined);
|
|
56
75
|
const cwd = process.cwd();
|
|
57
76
|
const targets = paths.map(p => path.resolve(cwd, p));
|
|
58
77
|
const result = staged_only
|
|
59
78
|
? await scanner.scanStaged()
|
|
60
79
|
: await scanner.scan(targets);
|
|
80
|
+
const userTier = scanner.getUserTier();
|
|
81
|
+
const tierLabel = userTier === 'pro' ? '🔓 Pro' : '🔒 Free';
|
|
61
82
|
if (result.findings.length === 0) {
|
|
62
83
|
return {
|
|
63
84
|
content: [
|
|
64
85
|
{
|
|
65
86
|
type: 'text',
|
|
66
|
-
text: `✅ No security issues found in ${result.files} file(s)
|
|
87
|
+
text: `✅ No security issues found in ${result.files} file(s).\n\nGrade: A+ | Tier: ${tierLabel}`,
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
const counts = {
|
|
93
|
+
critical: result.findings.filter(f => f.rule.severity === 'critical').length,
|
|
94
|
+
high: result.findings.filter(f => f.rule.severity === 'high').length,
|
|
95
|
+
medium: result.findings.filter(f => f.rule.severity === 'medium').length,
|
|
96
|
+
low: result.findings.filter(f => f.rule.severity === 'low').length,
|
|
97
|
+
};
|
|
98
|
+
const grade = calculateGrade(counts);
|
|
99
|
+
const summary = `Found ${result.findings.length} issue(s): ${counts.critical} critical, ${counts.high} high, ${counts.medium} medium, ${counts.low} low`;
|
|
100
|
+
// Free tier: show counts only, no individual findings
|
|
101
|
+
if (userTier === 'free') {
|
|
102
|
+
return {
|
|
103
|
+
content: [
|
|
104
|
+
{
|
|
105
|
+
type: 'text',
|
|
106
|
+
text: `${summary}\n\nGrade: ${grade} | Tier: ${tierLabel}\n\nUpgrade to Pro to see individual findings with file locations and fix suggestions.\nRun 'vibeguard upgrade' to unlock full scan details.`,
|
|
67
107
|
},
|
|
68
108
|
],
|
|
69
109
|
};
|
|
70
110
|
}
|
|
71
|
-
//
|
|
111
|
+
// Pro tier: show full details
|
|
72
112
|
const findings = result.findings.map(f => ({
|
|
73
113
|
severity: f.rule.severity,
|
|
74
114
|
rule: f.rule.id,
|
|
@@ -77,20 +117,21 @@ async function startMcpServer() {
|
|
|
77
117
|
line: f.line,
|
|
78
118
|
message: f.rule.description,
|
|
79
119
|
fix: f.rule.fix,
|
|
120
|
+
isRestricted: f.isRestricted,
|
|
80
121
|
}));
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
const
|
|
122
|
+
const formattedFindings = findings.map(f => {
|
|
123
|
+
const proTag = f.isRestricted ? ' [PRO]' : '';
|
|
124
|
+
const fixLine = f.isRestricted
|
|
125
|
+
? ' Fix: Upgrade to Pro to see fix details'
|
|
126
|
+
: ` Fix: ${f.fix}`;
|
|
127
|
+
return `[${f.severity.toUpperCase()}]${proTag} ${f.file}:${f.line}\n ${f.name}\n${fixLine}`;
|
|
128
|
+
}).join('\n\n');
|
|
129
|
+
const footer = `\nGrade: ${grade} | Tier: ${tierLabel}`;
|
|
89
130
|
return {
|
|
90
131
|
content: [
|
|
91
132
|
{
|
|
92
133
|
type: 'text',
|
|
93
|
-
text: `${summary}\n\n${formattedFindings}`,
|
|
134
|
+
text: `${summary}\n\n${formattedFindings}${footer}`,
|
|
94
135
|
},
|
|
95
136
|
],
|
|
96
137
|
};
|
|
@@ -137,9 +178,12 @@ async function startMcpServer() {
|
|
|
137
178
|
const ext = language === 'python' ? '.py' : language === 'typescript' ? '.ts' : '.js';
|
|
138
179
|
const tempFile = path.join(os.tmpdir(), `vibeguard-check-${Date.now()}${ext}`);
|
|
139
180
|
fs.writeFileSync(tempFile, code);
|
|
181
|
+
const licenseKey = (0, license_1.getLicenseKey)();
|
|
140
182
|
const scanner = new scanner_1.Scanner();
|
|
141
|
-
await scanner.initialize();
|
|
183
|
+
await scanner.initialize(licenseKey || undefined);
|
|
142
184
|
const result = await scanner.scan([tempFile]);
|
|
185
|
+
const userTier = scanner.getUserTier();
|
|
186
|
+
const tierLabel = userTier === 'pro' ? '🔓 Pro' : '🔒 Free';
|
|
143
187
|
// Clean up
|
|
144
188
|
fs.unlinkSync(tempFile);
|
|
145
189
|
if (result.findings.length === 0) {
|
|
@@ -147,24 +191,52 @@ async function startMcpServer() {
|
|
|
147
191
|
content: [
|
|
148
192
|
{
|
|
149
193
|
type: 'text',
|
|
150
|
-
text:
|
|
194
|
+
text: `✅ No security issues found in this code snippet.\n\nGrade: A+ | Tier: ${tierLabel}`,
|
|
195
|
+
},
|
|
196
|
+
],
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
const counts = {
|
|
200
|
+
critical: result.findings.filter(f => f.rule.severity === 'critical').length,
|
|
201
|
+
high: result.findings.filter(f => f.rule.severity === 'high').length,
|
|
202
|
+
medium: result.findings.filter(f => f.rule.severity === 'medium').length,
|
|
203
|
+
low: result.findings.filter(f => f.rule.severity === 'low').length,
|
|
204
|
+
};
|
|
205
|
+
const grade = calculateGrade(counts);
|
|
206
|
+
const summary = `Found ${result.findings.length} issue(s): ${counts.critical} critical, ${counts.high} high, ${counts.medium} medium, ${counts.low} low`;
|
|
207
|
+
// Free tier: show counts only, no individual findings
|
|
208
|
+
if (userTier === 'free') {
|
|
209
|
+
return {
|
|
210
|
+
content: [
|
|
211
|
+
{
|
|
212
|
+
type: 'text',
|
|
213
|
+
text: `${summary}\n\nGrade: ${grade} | Tier: ${tierLabel}\n\nUpgrade to Pro to see individual findings with line numbers and fix suggestions.`,
|
|
151
214
|
},
|
|
152
215
|
],
|
|
153
216
|
};
|
|
154
217
|
}
|
|
218
|
+
// Pro tier: show full details
|
|
155
219
|
const findings = result.findings.map(f => ({
|
|
156
220
|
severity: f.rule.severity,
|
|
157
221
|
rule: f.rule.id,
|
|
158
222
|
name: f.rule.name,
|
|
159
223
|
line: f.line,
|
|
160
224
|
fix: f.rule.fix,
|
|
225
|
+
isRestricted: f.isRestricted,
|
|
161
226
|
}));
|
|
162
|
-
const formatted = findings.map(f =>
|
|
227
|
+
const formatted = findings.map(f => {
|
|
228
|
+
const proTag = f.isRestricted ? ' [PRO]' : '';
|
|
229
|
+
const fixLine = f.isRestricted
|
|
230
|
+
? ' Fix: Upgrade to Pro to see fix details'
|
|
231
|
+
: ` Fix: ${f.fix}`;
|
|
232
|
+
return `[${f.severity.toUpperCase()}]${proTag} Line ${f.line}: ${f.name}\n${fixLine}`;
|
|
233
|
+
}).join('\n\n');
|
|
234
|
+
const footer = `\nGrade: ${grade} | Tier: ${tierLabel}`;
|
|
163
235
|
return {
|
|
164
236
|
content: [
|
|
165
237
|
{
|
|
166
238
|
type: 'text',
|
|
167
|
-
text: `Found ${findings.length} issue(s):\n\n${formatted}`,
|
|
239
|
+
text: `Found ${findings.length} issue(s):\n\n${formatted}${footer}`,
|
|
168
240
|
},
|
|
169
241
|
],
|
|
170
242
|
};
|
package/dist/mcp/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAW,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAW,UAAU,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAsE3E,qBAAa,OAAO;IAClB,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAgB;gBAEpB,MAAM,GAAE,MAAW;IAIzB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWpD,WAAW,IAAI,IAAI;IAIb,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;IAoC5C,UAAU,IAAI,OAAO,CAAC,UAAU,CAAC;YAuCzB,QAAQ;IA2CtB,OAAO,CAAC,eAAe;IAKvB,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,sBAAsB;IAO9B,QAAQ,IAAI,YAAY,EAAE;CAG3B"}
|
package/dist/scanner/index.js
CHANGED
|
@@ -62,6 +62,40 @@ const DEFAULT_EXCLUDE = [
|
|
|
62
62
|
'**/env/**',
|
|
63
63
|
'**/*.min.js',
|
|
64
64
|
'**/*.bundle.js',
|
|
65
|
+
// Test files
|
|
66
|
+
'**/*.test.js',
|
|
67
|
+
'**/*.test.ts',
|
|
68
|
+
'**/*.test.jsx',
|
|
69
|
+
'**/*.test.tsx',
|
|
70
|
+
'**/*.spec.js',
|
|
71
|
+
'**/*.spec.ts',
|
|
72
|
+
'**/*.spec.jsx',
|
|
73
|
+
'**/*.spec.tsx',
|
|
74
|
+
// Test directories
|
|
75
|
+
'**/__tests__/**',
|
|
76
|
+
'**/test/**',
|
|
77
|
+
'**/tests/**',
|
|
78
|
+
'**/spec/**',
|
|
79
|
+
// Fixtures and mocks
|
|
80
|
+
'**/fixtures/**',
|
|
81
|
+
'**/mocks/**',
|
|
82
|
+
'**/__mocks__/**',
|
|
83
|
+
'**/__fixtures__/**',
|
|
84
|
+
// Storybook
|
|
85
|
+
'**/*.stories.js',
|
|
86
|
+
'**/*.stories.ts',
|
|
87
|
+
'**/*.stories.jsx',
|
|
88
|
+
'**/*.stories.tsx',
|
|
89
|
+
'**/.storybook/**',
|
|
90
|
+
// E2E test tools
|
|
91
|
+
'**/cypress/**',
|
|
92
|
+
'**/playwright/**',
|
|
93
|
+
'**/*.e2e.js',
|
|
94
|
+
'**/*.e2e.ts',
|
|
95
|
+
// Dev configs (commonly have dummy values)
|
|
96
|
+
'**/jest.config.*',
|
|
97
|
+
'**/vitest.config.*',
|
|
98
|
+
'**/playwright.config.*',
|
|
65
99
|
];
|
|
66
100
|
class Scanner {
|
|
67
101
|
constructor(config = {}) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAC7B,+BAA4B;AAE5B,2CAAwD;AACxD,qDAAsF;AACtF,6CAA0D;AAC1D,4CAA6C;AAE7C,MAAM,oBAAoB,GAA2B;IACnD,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,QAAQ;CAChB,CAAC;AAEF,MAAM,eAAe,GAAG;IACtB,oBAAoB;IACpB,YAAY;IACZ,aAAa;IACb,YAAY;IACZ,gBAAgB;IAChB,mBAAmB;IACnB,YAAY;IACZ,aAAa;IACb,WAAW;IACX,aAAa;IACb,gBAAgB;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scanner/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/cli/commands/scan.ts
CHANGED
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
formatScanning,
|
|
9
9
|
formatFinding,
|
|
10
10
|
formatSummary,
|
|
11
|
+
formatFreeUserSummary,
|
|
11
12
|
formatBlockedCommit,
|
|
12
13
|
formatCleanResult,
|
|
13
14
|
formatError,
|
|
@@ -48,30 +49,54 @@ export function createScanCommand(): Command {
|
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
// Output results
|
|
52
|
+
const userTier: Tier = scanner.getUserTier();
|
|
53
|
+
|
|
51
54
|
if (options.json) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
55
|
+
// For free tier, only include counts in JSON, not individual findings
|
|
56
|
+
if (userTier === 'free') {
|
|
57
|
+
const counts = {
|
|
58
|
+
critical: result.findings.filter(f => f.rule.severity === 'critical').length,
|
|
59
|
+
high: result.findings.filter(f => f.rule.severity === 'high').length,
|
|
60
|
+
medium: result.findings.filter(f => f.rule.severity === 'medium').length,
|
|
61
|
+
low: result.findings.filter(f => f.rule.severity === 'low').length,
|
|
62
|
+
};
|
|
63
|
+
console.log(JSON.stringify({
|
|
64
|
+
version: packageJson.version,
|
|
65
|
+
tier: userTier,
|
|
66
|
+
files: result.files,
|
|
67
|
+
totalIssues: result.findings.length,
|
|
68
|
+
counts,
|
|
69
|
+
findings: [], // Empty for free tier
|
|
70
|
+
duration: result.duration,
|
|
71
|
+
upgradeMessage: 'Upgrade to Pro to see individual findings with file locations and fix suggestions',
|
|
72
|
+
}, null, 2));
|
|
73
|
+
} else {
|
|
74
|
+
console.log(JSON.stringify({
|
|
75
|
+
version: packageJson.version,
|
|
76
|
+
tier: userTier,
|
|
77
|
+
files: result.files,
|
|
78
|
+
findings: result.findings.map(f => ({
|
|
79
|
+
rule: f.rule.id,
|
|
80
|
+
severity: f.rule.severity,
|
|
81
|
+
tier: f.rule.tier,
|
|
82
|
+
file: path.relative(cwd, f.file),
|
|
83
|
+
line: f.line,
|
|
84
|
+
column: f.column,
|
|
85
|
+
message: f.rule.name,
|
|
86
|
+
fix: f.isRestricted ? null : f.rule.fix,
|
|
87
|
+
isRestricted: f.isRestricted,
|
|
88
|
+
})),
|
|
89
|
+
duration: result.duration,
|
|
90
|
+
}, null, 2));
|
|
91
|
+
}
|
|
70
92
|
} else if (!options.quiet) {
|
|
71
93
|
if (result.findings.length === 0) {
|
|
72
94
|
console.log(formatCleanResult());
|
|
95
|
+
} else if (userTier === 'free') {
|
|
96
|
+
// Free tier: show counts only, no individual findings
|
|
97
|
+
console.log(formatFreeUserSummary(result));
|
|
73
98
|
} else {
|
|
74
|
-
|
|
99
|
+
// Pro tier: show full details
|
|
75
100
|
for (const finding of result.findings) {
|
|
76
101
|
console.log(formatFinding(finding, cwd));
|
|
77
102
|
}
|
package/src/cli/output.ts
CHANGED
|
@@ -104,6 +104,40 @@ export function formatUpgradePrompt(restrictedCount: number): string {
|
|
|
104
104
|
return output;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
+
export function formatFreeUserSummary(result: ScanResult): string {
|
|
108
|
+
const counts = {
|
|
109
|
+
critical: 0,
|
|
110
|
+
high: 0,
|
|
111
|
+
medium: 0,
|
|
112
|
+
low: 0,
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
for (const finding of result.findings) {
|
|
116
|
+
counts[finding.rule.severity]++;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const total = result.findings.length;
|
|
120
|
+
const grade = calculateGrade(counts);
|
|
121
|
+
|
|
122
|
+
let output = '\n';
|
|
123
|
+
output += `${colors.dim}─────────────────────────────────────────${colors.reset}\n`;
|
|
124
|
+
output += `Found ${colors.bold}${total}${colors.reset} issue${total !== 1 ? 's' : ''} `;
|
|
125
|
+
output += `(${colors.red}${counts.critical} critical${colors.reset}, `;
|
|
126
|
+
output += `${colors.yellow}${counts.high} high${colors.reset}, `;
|
|
127
|
+
output += `${colors.blue}${counts.medium} medium${colors.reset}, `;
|
|
128
|
+
output += `${colors.dim}${counts.low} low${colors.reset})\n\n`;
|
|
129
|
+
|
|
130
|
+
output += `Grade: ${formatGrade(grade)}\n`;
|
|
131
|
+
|
|
132
|
+
// Upgrade prompt for free users
|
|
133
|
+
output += '\n';
|
|
134
|
+
output += `${colors.magenta}${colors.bold}[PRO]${colors.reset} `;
|
|
135
|
+
output += `Upgrade to see individual findings with file locations and fix suggestions\n`;
|
|
136
|
+
output += `${colors.dim}Run ${colors.reset}${colors.cyan}vibeguard upgrade${colors.reset}${colors.dim} to unlock full scan details${colors.reset}\n`;
|
|
137
|
+
|
|
138
|
+
return output;
|
|
139
|
+
}
|
|
140
|
+
|
|
107
141
|
function calculateGrade(counts: Record<Severity, number>): string {
|
|
108
142
|
if (counts.critical > 0) return 'F';
|
|
109
143
|
if (counts.high > 2) return 'D';
|
package/src/mcp/server.ts
CHANGED
|
@@ -4,6 +4,19 @@ import { z } from 'zod';
|
|
|
4
4
|
import * as path from 'path';
|
|
5
5
|
import { Scanner } from '../scanner';
|
|
6
6
|
import { securityRules } from '../scanner/rules/definitions';
|
|
7
|
+
import { getLicenseKey } from '../api/license';
|
|
8
|
+
import { Severity, Tier } from '../types';
|
|
9
|
+
|
|
10
|
+
function calculateGrade(counts: Record<Severity, number>): string {
|
|
11
|
+
if (counts.critical > 0) return 'F';
|
|
12
|
+
if (counts.high > 2) return 'D';
|
|
13
|
+
if (counts.high > 0) return 'C';
|
|
14
|
+
if (counts.medium > 3) return 'C';
|
|
15
|
+
if (counts.medium > 0) return 'B';
|
|
16
|
+
if (counts.low > 5) return 'B';
|
|
17
|
+
if (counts.low > 0) return 'A';
|
|
18
|
+
return 'A+';
|
|
19
|
+
}
|
|
7
20
|
|
|
8
21
|
export async function startMcpServer(): Promise<void> {
|
|
9
22
|
const server = new McpServer({
|
|
@@ -21,8 +34,9 @@ export async function startMcpServer(): Promise<void> {
|
|
|
21
34
|
},
|
|
22
35
|
async ({ paths, staged_only }) => {
|
|
23
36
|
try {
|
|
37
|
+
const licenseKey = getLicenseKey();
|
|
24
38
|
const scanner = new Scanner();
|
|
25
|
-
await scanner.initialize();
|
|
39
|
+
await scanner.initialize(licenseKey || undefined);
|
|
26
40
|
|
|
27
41
|
const cwd = process.cwd();
|
|
28
42
|
const targets = paths.map(p => path.resolve(cwd, p));
|
|
@@ -31,18 +45,43 @@ export async function startMcpServer(): Promise<void> {
|
|
|
31
45
|
? await scanner.scanStaged()
|
|
32
46
|
: await scanner.scan(targets);
|
|
33
47
|
|
|
48
|
+
const userTier: Tier = scanner.getUserTier();
|
|
49
|
+
const tierLabel = userTier === 'pro' ? '🔓 Pro' : '🔒 Free';
|
|
50
|
+
|
|
34
51
|
if (result.findings.length === 0) {
|
|
35
52
|
return {
|
|
36
53
|
content: [
|
|
37
54
|
{
|
|
38
55
|
type: 'text' as const,
|
|
39
|
-
text: `✅ No security issues found in ${result.files} file(s)
|
|
56
|
+
text: `✅ No security issues found in ${result.files} file(s).\n\nGrade: A+ | Tier: ${tierLabel}`,
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const counts: Record<Severity, number> = {
|
|
63
|
+
critical: result.findings.filter(f => f.rule.severity === 'critical').length,
|
|
64
|
+
high: result.findings.filter(f => f.rule.severity === 'high').length,
|
|
65
|
+
medium: result.findings.filter(f => f.rule.severity === 'medium').length,
|
|
66
|
+
low: result.findings.filter(f => f.rule.severity === 'low').length,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const grade = calculateGrade(counts);
|
|
70
|
+
const summary = `Found ${result.findings.length} issue(s): ${counts.critical} critical, ${counts.high} high, ${counts.medium} medium, ${counts.low} low`;
|
|
71
|
+
|
|
72
|
+
// Free tier: show counts only, no individual findings
|
|
73
|
+
if (userTier === 'free') {
|
|
74
|
+
return {
|
|
75
|
+
content: [
|
|
76
|
+
{
|
|
77
|
+
type: 'text' as const,
|
|
78
|
+
text: `${summary}\n\nGrade: ${grade} | Tier: ${tierLabel}\n\nUpgrade to Pro to see individual findings with file locations and fix suggestions.\nRun 'vibeguard upgrade' to unlock full scan details.`,
|
|
40
79
|
},
|
|
41
80
|
],
|
|
42
81
|
};
|
|
43
82
|
}
|
|
44
83
|
|
|
45
|
-
//
|
|
84
|
+
// Pro tier: show full details
|
|
46
85
|
const findings = result.findings.map(f => ({
|
|
47
86
|
severity: f.rule.severity,
|
|
48
87
|
rule: f.rule.id,
|
|
@@ -51,26 +90,24 @@ export async function startMcpServer(): Promise<void> {
|
|
|
51
90
|
line: f.line,
|
|
52
91
|
message: f.rule.description,
|
|
53
92
|
fix: f.rule.fix,
|
|
93
|
+
isRestricted: f.isRestricted,
|
|
54
94
|
}));
|
|
55
95
|
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const summary = `Found ${findings.length} issue(s): ${counts.critical} critical, ${counts.high} high, ${counts.medium} medium, ${counts.low} low`;
|
|
96
|
+
const formattedFindings = findings.map(f => {
|
|
97
|
+
const proTag = f.isRestricted ? ' [PRO]' : '';
|
|
98
|
+
const fixLine = f.isRestricted
|
|
99
|
+
? ' Fix: Upgrade to Pro to see fix details'
|
|
100
|
+
: ` Fix: ${f.fix}`;
|
|
101
|
+
return `[${f.severity.toUpperCase()}]${proTag} ${f.file}:${f.line}\n ${f.name}\n${fixLine}`;
|
|
102
|
+
}).join('\n\n');
|
|
64
103
|
|
|
65
|
-
const
|
|
66
|
-
`[${f.severity.toUpperCase()}] ${f.file}:${f.line}\n ${f.name}\n Fix: ${f.fix}`
|
|
67
|
-
).join('\n\n');
|
|
104
|
+
const footer = `\nGrade: ${grade} | Tier: ${tierLabel}`;
|
|
68
105
|
|
|
69
106
|
return {
|
|
70
107
|
content: [
|
|
71
108
|
{
|
|
72
109
|
type: 'text' as const,
|
|
73
|
-
text: `${summary}\n\n${formattedFindings}`,
|
|
110
|
+
text: `${summary}\n\n${formattedFindings}${footer}`,
|
|
74
111
|
},
|
|
75
112
|
],
|
|
76
113
|
};
|
|
@@ -136,10 +173,13 @@ export async function startMcpServer(): Promise<void> {
|
|
|
136
173
|
|
|
137
174
|
fs.writeFileSync(tempFile, code);
|
|
138
175
|
|
|
176
|
+
const licenseKey = getLicenseKey();
|
|
139
177
|
const scanner = new Scanner();
|
|
140
|
-
await scanner.initialize();
|
|
178
|
+
await scanner.initialize(licenseKey || undefined);
|
|
141
179
|
|
|
142
180
|
const result = await scanner.scan([tempFile]);
|
|
181
|
+
const userTier: Tier = scanner.getUserTier();
|
|
182
|
+
const tierLabel = userTier === 'pro' ? '🔓 Pro' : '🔒 Free';
|
|
143
183
|
|
|
144
184
|
// Clean up
|
|
145
185
|
fs.unlinkSync(tempFile);
|
|
@@ -149,29 +189,59 @@ export async function startMcpServer(): Promise<void> {
|
|
|
149
189
|
content: [
|
|
150
190
|
{
|
|
151
191
|
type: 'text' as const,
|
|
152
|
-
text:
|
|
192
|
+
text: `✅ No security issues found in this code snippet.\n\nGrade: A+ | Tier: ${tierLabel}`,
|
|
153
193
|
},
|
|
154
194
|
],
|
|
155
195
|
};
|
|
156
196
|
}
|
|
157
197
|
|
|
198
|
+
const counts: Record<Severity, number> = {
|
|
199
|
+
critical: result.findings.filter(f => f.rule.severity === 'critical').length,
|
|
200
|
+
high: result.findings.filter(f => f.rule.severity === 'high').length,
|
|
201
|
+
medium: result.findings.filter(f => f.rule.severity === 'medium').length,
|
|
202
|
+
low: result.findings.filter(f => f.rule.severity === 'low').length,
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const grade = calculateGrade(counts);
|
|
206
|
+
const summary = `Found ${result.findings.length} issue(s): ${counts.critical} critical, ${counts.high} high, ${counts.medium} medium, ${counts.low} low`;
|
|
207
|
+
|
|
208
|
+
// Free tier: show counts only, no individual findings
|
|
209
|
+
if (userTier === 'free') {
|
|
210
|
+
return {
|
|
211
|
+
content: [
|
|
212
|
+
{
|
|
213
|
+
type: 'text' as const,
|
|
214
|
+
text: `${summary}\n\nGrade: ${grade} | Tier: ${tierLabel}\n\nUpgrade to Pro to see individual findings with line numbers and fix suggestions.`,
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Pro tier: show full details
|
|
158
221
|
const findings = result.findings.map(f => ({
|
|
159
222
|
severity: f.rule.severity,
|
|
160
223
|
rule: f.rule.id,
|
|
161
224
|
name: f.rule.name,
|
|
162
225
|
line: f.line,
|
|
163
226
|
fix: f.rule.fix,
|
|
227
|
+
isRestricted: f.isRestricted,
|
|
164
228
|
}));
|
|
165
229
|
|
|
166
|
-
const formatted = findings.map(f =>
|
|
167
|
-
|
|
168
|
-
|
|
230
|
+
const formatted = findings.map(f => {
|
|
231
|
+
const proTag = f.isRestricted ? ' [PRO]' : '';
|
|
232
|
+
const fixLine = f.isRestricted
|
|
233
|
+
? ' Fix: Upgrade to Pro to see fix details'
|
|
234
|
+
: ` Fix: ${f.fix}`;
|
|
235
|
+
return `[${f.severity.toUpperCase()}]${proTag} Line ${f.line}: ${f.name}\n${fixLine}`;
|
|
236
|
+
}).join('\n\n');
|
|
237
|
+
|
|
238
|
+
const footer = `\nGrade: ${grade} | Tier: ${tierLabel}`;
|
|
169
239
|
|
|
170
240
|
return {
|
|
171
241
|
content: [
|
|
172
242
|
{
|
|
173
243
|
type: 'text' as const,
|
|
174
|
-
text: `Found ${findings.length} issue(s):\n\n${formatted}`,
|
|
244
|
+
text: `Found ${findings.length} issue(s):\n\n${formatted}${footer}`,
|
|
175
245
|
},
|
|
176
246
|
],
|
|
177
247
|
};
|
package/src/scanner/index.ts
CHANGED
|
@@ -29,6 +29,46 @@ const DEFAULT_EXCLUDE = [
|
|
|
29
29
|
'**/env/**',
|
|
30
30
|
'**/*.min.js',
|
|
31
31
|
'**/*.bundle.js',
|
|
32
|
+
|
|
33
|
+
// Test files
|
|
34
|
+
'**/*.test.js',
|
|
35
|
+
'**/*.test.ts',
|
|
36
|
+
'**/*.test.jsx',
|
|
37
|
+
'**/*.test.tsx',
|
|
38
|
+
'**/*.spec.js',
|
|
39
|
+
'**/*.spec.ts',
|
|
40
|
+
'**/*.spec.jsx',
|
|
41
|
+
'**/*.spec.tsx',
|
|
42
|
+
|
|
43
|
+
// Test directories
|
|
44
|
+
'**/__tests__/**',
|
|
45
|
+
'**/test/**',
|
|
46
|
+
'**/tests/**',
|
|
47
|
+
'**/spec/**',
|
|
48
|
+
|
|
49
|
+
// Fixtures and mocks
|
|
50
|
+
'**/fixtures/**',
|
|
51
|
+
'**/mocks/**',
|
|
52
|
+
'**/__mocks__/**',
|
|
53
|
+
'**/__fixtures__/**',
|
|
54
|
+
|
|
55
|
+
// Storybook
|
|
56
|
+
'**/*.stories.js',
|
|
57
|
+
'**/*.stories.ts',
|
|
58
|
+
'**/*.stories.jsx',
|
|
59
|
+
'**/*.stories.tsx',
|
|
60
|
+
'**/.storybook/**',
|
|
61
|
+
|
|
62
|
+
// E2E test tools
|
|
63
|
+
'**/cypress/**',
|
|
64
|
+
'**/playwright/**',
|
|
65
|
+
'**/*.e2e.js',
|
|
66
|
+
'**/*.e2e.ts',
|
|
67
|
+
|
|
68
|
+
// Dev configs (commonly have dummy values)
|
|
69
|
+
'**/jest.config.*',
|
|
70
|
+
'**/vitest.config.*',
|
|
71
|
+
'**/playwright.config.*',
|
|
32
72
|
];
|
|
33
73
|
|
|
34
74
|
export class Scanner {
|
package/PROGRESS.md
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
# VibeGuard Development Progress
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
VibeGuard is a local CLI security scanner for AI-generated code. This document tracks what has been implemented and what remains to be done.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## ✅ Completed
|
|
10
|
-
|
|
11
|
-
### Phase 1: Core Scanner
|
|
12
|
-
- [x] TypeScript project setup with npm package structure
|
|
13
|
-
- [x] Project structure following the planned architecture
|
|
14
|
-
- [x] JS/TS parser using @babel/parser for AST analysis
|
|
15
|
-
- [x] Pattern-based scanning with regex
|
|
16
|
-
- [x] Basic `scan` command with file/directory support
|
|
17
|
-
- [x] Finding output with file, line number, and severity
|
|
18
|
-
|
|
19
|
-
### Phase 2: Full Rule Set
|
|
20
|
-
- [x] 45 security rules implemented across all severity levels:
|
|
21
|
-
- **Critical (8):** hardcoded-secret, sql-injection, eval-usage, command-injection, insecure-deserialization, django-debug-true, django-secret-key-exposed, django-raw-sql
|
|
22
|
-
- **High (21):** missing-auth-route, xss-innerhtml, secrets-localstorage, supabase-no-rls, firebase-no-rules, idor-vulnerability, path-traversal, ssrf-vulnerability, open-redirect, insecure-cookie, missing-csrf, nextjs-exposed-server-action, nextjs-api-route-no-auth, nextjs-dangerouslySetInnerHTML, nextjs-exposed-env, django-no-csrf-exempt, fastapi-no-auth-dependency, nestjs-no-auth-guard, react-href-javascript, react-url-state-injection, express-session-insecure
|
|
23
|
-
- **Medium (10):** permissive-cors, http-not-https, weak-password, hardcoded-ip, xxe-vulnerability, jwt-none-algorithm, django-allowed-hosts-all, fastapi-cors-all-origins, express-helmet-missing, express-body-parser-limit
|
|
24
|
-
- **Low (6):** verbose-errors, missing-rate-limit, console-log-sensitive, debug-mode-enabled, prototype-pollution, nestjs-exposed-internal-exception
|
|
25
|
-
- [x] Python parser support (pattern-based)
|
|
26
|
-
- [x] Severity levels (critical, high, medium, low)
|
|
27
|
-
- [x] Letter grading system (A+ to F)
|
|
28
|
-
|
|
29
|
-
### Phase 3: CLI Polish
|
|
30
|
-
- [x] `vibeguard scan` - Main scan command
|
|
31
|
-
- [x] Directory scanning
|
|
32
|
-
- [x] File scanning
|
|
33
|
-
- [x] `--staged` flag for git staged files
|
|
34
|
-
- [x] `--json` output format
|
|
35
|
-
- [x] `--force` to ignore exit code
|
|
36
|
-
- [x] `--quiet` minimal output
|
|
37
|
-
- [x] `vibeguard init` - Pre-commit hook setup
|
|
38
|
-
- [x] Git hook creation
|
|
39
|
-
- [x] Husky detection and integration
|
|
40
|
-
- [x] `.vibeguardrc.json` config file creation
|
|
41
|
-
- [x] `vibeguard rules` - List security rules
|
|
42
|
-
- [x] `--severity` filter
|
|
43
|
-
- [x] `--language` filter
|
|
44
|
-
- [x] `--json` output
|
|
45
|
-
- [x] `vibeguard login` / `vibeguard logout` - License key management
|
|
46
|
-
- [x] `vibeguard upgrade` - Show Pro features and pricing
|
|
47
|
-
- [x] Pretty terminal output with colors
|
|
48
|
-
- [x] Config file support (`.vibeguardrc.json`)
|
|
49
|
-
|
|
50
|
-
### Phase 4: License System (CLI Side)
|
|
51
|
-
- [x] `login` command implemented
|
|
52
|
-
- [x] `logout` command implemented
|
|
53
|
-
- [x] License key storage in `~/.vibeguard/license.json`
|
|
54
|
-
- [x] Offline mode fallback (works without server)
|
|
55
|
-
- [x] API client stubs ready for server integration
|
|
56
|
-
|
|
57
|
-
### Phase 5: Free/Pro Tier System
|
|
58
|
-
- [x] `Tier` type added (`'free' | 'pro'`)
|
|
59
|
-
- [x] All 45 rules categorized by tier:
|
|
60
|
-
- **Free Tier (24 rules):** Basic vulnerabilities - hardcoded secrets, SQL injection, XSS, eval, command injection, CSRF, SSRF, path traversal, etc.
|
|
61
|
-
- **Pro Tier (21 rules):** Framework-specific - Next.js (4), Django (5), FastAPI (2), NestJS (2), React (2), Express (3), Supabase, Firebase, missing-auth-route
|
|
62
|
-
- [x] `isRestricted` field on findings for gated content
|
|
63
|
-
- [x] `[PRO]` badge display for restricted findings
|
|
64
|
-
- [x] Upgrade prompt showing count of restricted findings
|
|
65
|
-
- [x] `vibeguard upgrade` command with pricing and features
|
|
66
|
-
- [x] Tier info in JSON output (`tier`, `isRestricted` fields)
|
|
67
|
-
- [x] License tier caching for offline mode
|
|
68
|
-
- [x] `getUserTier()` and `getCachedTier()` functions
|
|
69
|
-
|
|
70
|
-
### Bonus: MCP Integration
|
|
71
|
-
- [x] `vibeguard mcp` command to start MCP server
|
|
72
|
-
- [x] `scan_code` tool - Scan files/directories
|
|
73
|
-
- [x] `list_security_rules` tool - List available rules
|
|
74
|
-
- [x] `check_code_snippet` tool - Validate code without saving
|
|
75
|
-
- [x] Documentation for Claude Code integration
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
## 🔲 Not Yet Implemented
|
|
80
|
-
|
|
81
|
-
### Server-Side: Website + Backend (Phase 2 - Future Session)
|
|
82
|
-
- [ ] Next.js 14+ website on Vercel
|
|
83
|
-
- [ ] Landing page with feature showcase
|
|
84
|
-
- [ ] Pricing page (Monthly $9, Annual $79)
|
|
85
|
-
- [ ] Documentation site
|
|
86
|
-
- [ ] User dashboard (license management, usage stats)
|
|
87
|
-
- [ ] License validation API (`POST /v1/license/validate`)
|
|
88
|
-
- [ ] License activation API (`POST /v1/license/activate`)
|
|
89
|
-
- [ ] Rules API (`GET /v1/rules`) for auto-updates
|
|
90
|
-
- [ ] Vercel Postgres database (users, licenses, activations tables)
|
|
91
|
-
- [ ] NextAuth.js or Clerk authentication
|
|
92
|
-
|
|
93
|
-
### Server-Side: Stripe Integration (Phase 3 - Future Session)
|
|
94
|
-
- [ ] Stripe product setup (Pro Monthly, Pro Annual)
|
|
95
|
-
- [ ] Checkout flow
|
|
96
|
-
- [ ] Webhook handlers for payment events
|
|
97
|
-
- [ ] License key email delivery
|
|
98
|
-
- [ ] Subscription management
|
|
99
|
-
|
|
100
|
-
### CLI Enhancements
|
|
101
|
-
- [ ] `vibeguard update` - Manual rule update command
|
|
102
|
-
- [ ] `vibeguard ignore` - Add inline ignore comments
|
|
103
|
-
- [ ] `vibeguard fix` - Auto-fix certain issues (where safe)
|
|
104
|
-
- [ ] Watch mode (`--watch`) for continuous scanning
|
|
105
|
-
- [ ] SARIF output format for GitHub Advanced Security
|
|
106
|
-
- [ ] GitLab CI/CD integration format
|
|
107
|
-
|
|
108
|
-
### Additional Rules
|
|
109
|
-
- [x] Command injection detection
|
|
110
|
-
- [x] Path traversal detection
|
|
111
|
-
- [x] Insecure deserialization
|
|
112
|
-
- [x] Hardcoded IP addresses
|
|
113
|
-
- [x] Missing CSRF protection
|
|
114
|
-
- [x] Insecure cookie settings
|
|
115
|
-
- [x] Open redirect vulnerabilities
|
|
116
|
-
- [x] XXE (XML External Entity) detection
|
|
117
|
-
- [x] SSRF (Server-Side Request Forgery) patterns
|
|
118
|
-
- [x] JWT none algorithm vulnerability
|
|
119
|
-
- [x] Console logging sensitive data
|
|
120
|
-
- [x] Debug mode enabled
|
|
121
|
-
- [x] Prototype pollution
|
|
122
|
-
|
|
123
|
-
### Parser Improvements
|
|
124
|
-
- [ ] Tree-sitter Python parser (currently regex-only)
|
|
125
|
-
- [ ] Better AST-based SQL injection detection for JS
|
|
126
|
-
- [x] Framework-specific rules (Next.js, Django, FastAPI, NestJS, Express, React)
|
|
127
|
-
- [ ] JSX/TSX component-level analysis
|
|
128
|
-
|
|
129
|
-
### Testing
|
|
130
|
-
- [x] Unit tests for scanner (13 tests)
|
|
131
|
-
- [x] Unit tests for rule matching (186 tests across all 45 rules)
|
|
132
|
-
- [x] Rule definitions tests (47 tests)
|
|
133
|
-
- [x] Test coverage reporting (Vitest + v8)
|
|
134
|
-
- [x] CI/CD pipeline (GitHub Actions)
|
|
135
|
-
- [x] CI workflow: tests on Node 18, 20, 22
|
|
136
|
-
- [x] Release workflow: auto-publish to npm on tags
|
|
137
|
-
- [ ] Integration tests for CLI commands
|
|
138
|
-
|
|
139
|
-
### Documentation
|
|
140
|
-
- [ ] API documentation for server endpoints
|
|
141
|
-
- [ ] Contributing guide
|
|
142
|
-
- [ ] Rule authoring guide
|
|
143
|
-
- [ ] Examples for each vulnerability type
|
|
144
|
-
|
|
145
|
-
### Distribution
|
|
146
|
-
- [ ] Publish to npm
|
|
147
|
-
- [ ] Homebrew formula
|
|
148
|
-
- [ ] Binary releases (pkg)
|
|
149
|
-
- [ ] Docker image
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
## 📁 Current Project Structure
|
|
154
|
-
|
|
155
|
-
```
|
|
156
|
-
vibeguard/
|
|
157
|
-
├── src/
|
|
158
|
-
│ ├── cli/
|
|
159
|
-
│ │ ├── index.ts # CLI entry point
|
|
160
|
-
│ │ ├── config.ts # Config file loading
|
|
161
|
-
│ │ ├── output.ts # Terminal formatting
|
|
162
|
-
│ │ └── commands/
|
|
163
|
-
│ │ ├── scan.ts # scan command
|
|
164
|
-
│ │ ├── init.ts # init command
|
|
165
|
-
│ │ ├── login.ts # login/logout commands
|
|
166
|
-
│ │ ├── rules.ts # rules command
|
|
167
|
-
│ │ ├── mcp.ts # mcp command
|
|
168
|
-
│ │ └── upgrade.ts # upgrade command (Pro features/pricing)
|
|
169
|
-
│ ├── scanner/
|
|
170
|
-
│ │ ├── index.ts # Main scanner logic
|
|
171
|
-
│ │ ├── parsers/
|
|
172
|
-
│ │ │ ├── javascript.ts # JS/TS AST + pattern scanning
|
|
173
|
-
│ │ │ └── python.ts # Python pattern scanning
|
|
174
|
-
│ │ └── rules/
|
|
175
|
-
│ │ ├── definitions.ts # 45 security rules (24 free, 21 pro)
|
|
176
|
-
│ │ ├── loader.ts # Rule loading (local + API)
|
|
177
|
-
│ │ └── matcher.ts # Pattern matching utilities
|
|
178
|
-
│ ├── mcp/
|
|
179
|
-
│ │ └── server.ts # MCP server for AI assistants
|
|
180
|
-
│ ├── api/
|
|
181
|
-
│ │ ├── license.ts # License management
|
|
182
|
-
│ │ └── rules.ts # Rules API client
|
|
183
|
-
│ └── types.ts # TypeScript types
|
|
184
|
-
├── dist/ # Compiled JavaScript
|
|
185
|
-
├── test-samples/ # Test files with vulnerabilities
|
|
186
|
-
├── package.json
|
|
187
|
-
├── tsconfig.json
|
|
188
|
-
├── README.md
|
|
189
|
-
└── PROGRESS.md # This file
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
---
|
|
193
|
-
|
|
194
|
-
## 🚀 Next Steps (Recommended Order)
|
|
195
|
-
|
|
196
|
-
1. **Website + Backend (Phase 2)** - Build vibeguard-web on Vercel with Next.js
|
|
197
|
-
- Landing page, pricing, docs
|
|
198
|
-
- License validation API
|
|
199
|
-
- Vercel Postgres database
|
|
200
|
-
2. **Stripe Integration (Phase 3)** - Payment flow and license delivery
|
|
201
|
-
3. **npm Publish** - Get it in users' hands
|
|
202
|
-
4. **CI Integration** - SARIF output for GitHub/GitLab
|
|
203
|
-
5. **More Rules** - Expand rule coverage based on user feedback
|
|
204
|
-
|
|
205
|
-
---
|
|
206
|
-
|
|
207
|
-
## 📊 Stats
|
|
208
|
-
|
|
209
|
-
| Metric | Count |
|
|
210
|
-
|--------|-------|
|
|
211
|
-
| Security Rules | 45 (24 free, 21 pro) |
|
|
212
|
-
| CLI Commands | 7 |
|
|
213
|
-
| MCP Tools | 3 |
|
|
214
|
-
| Supported Languages | 3 (JS, TS, Python) |
|
|
215
|
-
| Frameworks | 6 (Next.js, Django, FastAPI, NestJS, Express, React) |
|
|
216
|
-
| Unit Tests | 246 |
|
|
217
|
-
| Lines of TypeScript | ~2,200 |
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
*Last updated: January 30, 2026*
|