@vibecheckai/cli 3.4.0 → 3.5.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/bin/registry.js +243 -152
- package/bin/runners/cli-utils.js +2 -33
- package/bin/runners/context/generators/cursor.js +49 -2
- package/bin/runners/lib/agent-firewall/learning/learning-engine.js +849 -0
- package/bin/runners/lib/analyzers.js +544 -19
- package/bin/runners/lib/audit-logger.js +532 -0
- package/bin/runners/lib/authority/authorities/architecture.js +364 -0
- package/bin/runners/lib/authority/authorities/compliance.js +341 -0
- package/bin/runners/lib/authority/authorities/human.js +343 -0
- package/bin/runners/lib/authority/authorities/quality.js +420 -0
- package/bin/runners/lib/authority/authorities/security.js +228 -0
- package/bin/runners/lib/authority/index.js +293 -0
- package/bin/runners/lib/authority-badge.js +425 -425
- package/bin/runners/lib/bundle/bundle-intelligence.js +846 -0
- package/bin/runners/lib/cli-charts.js +368 -0
- package/bin/runners/lib/cli-config-display.js +405 -0
- package/bin/runners/lib/cli-demo.js +275 -0
- package/bin/runners/lib/cli-errors.js +438 -0
- package/bin/runners/lib/cli-help-formatter.js +439 -0
- package/bin/runners/lib/cli-interactive-menu.js +509 -0
- package/bin/runners/lib/cli-prompts.js +441 -0
- package/bin/runners/lib/cli-scan-cards.js +362 -0
- package/bin/runners/lib/compliance-reporter.js +710 -0
- package/bin/runners/lib/conductor/index.js +671 -0
- package/bin/runners/lib/easy/README.md +123 -0
- package/bin/runners/lib/easy/index.js +140 -0
- package/bin/runners/lib/easy/interactive-wizard.js +788 -0
- package/bin/runners/lib/easy/one-click-firewall.js +564 -0
- package/bin/runners/lib/easy/zero-config-reality.js +714 -0
- package/bin/runners/lib/engines/accessibility-engine.js +218 -18
- package/bin/runners/lib/engines/api-consistency-engine.js +335 -30
- package/bin/runners/lib/engines/async-patterns-engine.js +444 -0
- package/bin/runners/lib/engines/bundle-size-engine.js +433 -0
- package/bin/runners/lib/engines/confidence-scoring.js +276 -0
- package/bin/runners/lib/engines/context-detection.js +264 -0
- package/bin/runners/lib/engines/cross-file-analysis-engine.js +292 -27
- package/bin/runners/lib/engines/database-patterns-engine.js +429 -0
- package/bin/runners/lib/engines/duplicate-code-engine.js +354 -0
- package/bin/runners/lib/engines/empty-catch-engine.js +127 -17
- package/bin/runners/lib/engines/env-variables-engine.js +458 -0
- package/bin/runners/lib/engines/error-handling-engine.js +437 -0
- package/bin/runners/lib/engines/false-positive-prevention.js +630 -0
- package/bin/runners/lib/engines/framework-adapters/index.js +607 -0
- package/bin/runners/lib/engines/framework-detection.js +508 -0
- package/bin/runners/lib/engines/import-order-engine.js +429 -0
- package/bin/runners/lib/engines/mock-data-engine.js +53 -10
- package/bin/runners/lib/engines/naming-conventions-engine.js +544 -0
- package/bin/runners/lib/engines/noise-reduction-engine.js +452 -0
- package/bin/runners/lib/engines/orchestrator.js +334 -0
- package/bin/runners/lib/engines/performance-issues-engine.js +176 -36
- package/bin/runners/lib/engines/react-patterns-engine.js +457 -0
- package/bin/runners/lib/engines/security-vulnerabilities-engine.js +382 -54
- package/bin/runners/lib/engines/type-aware-engine.js +263 -39
- package/bin/runners/lib/engines/vibecheck-engines/index.js +122 -13
- package/bin/runners/lib/engines/vibecheck-engines/lib/ai-hallucination-engine.js +806 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +373 -73
- package/bin/runners/lib/engines/vibecheck-engines/lib/smart-fix-engine.js +577 -0
- package/bin/runners/lib/engines/vibecheck-engines/lib/vibe-score-engine.js +543 -0
- package/bin/runners/lib/engines/vibecheck-engines.js +514 -0
- package/bin/runners/lib/enhanced-features/index.js +305 -0
- package/bin/runners/lib/enhanced-output.js +631 -0
- package/bin/runners/lib/enterprise.js +300 -0
- package/bin/runners/lib/entitlements-v2.js +103 -11
- package/bin/runners/lib/firewall/command-validator.js +351 -0
- package/bin/runners/lib/firewall/config.js +341 -0
- package/bin/runners/lib/firewall/content-validator.js +519 -0
- package/bin/runners/lib/firewall/index.js +101 -0
- package/bin/runners/lib/firewall/path-validator.js +256 -0
- package/bin/runners/lib/html-proof-report.js +350 -700
- package/bin/runners/lib/intelligence/cross-repo-intelligence.js +817 -0
- package/bin/runners/lib/mcp-utils.js +425 -0
- package/bin/runners/lib/missions/plan.js +46 -6
- package/bin/runners/lib/missions/templates.js +232 -0
- package/bin/runners/lib/output/index.js +1022 -0
- package/bin/runners/lib/policy-engine.js +652 -0
- package/bin/runners/lib/polish/autofix/accessibility-fixes.js +333 -0
- package/bin/runners/lib/polish/autofix/async-handlers.js +273 -0
- package/bin/runners/lib/polish/autofix/dead-code.js +280 -0
- package/bin/runners/lib/polish/autofix/imports-optimizer.js +344 -0
- package/bin/runners/lib/polish/autofix/index.js +200 -0
- package/bin/runners/lib/polish/autofix/remove-consoles.js +209 -0
- package/bin/runners/lib/polish/autofix/strengthen-types.js +245 -0
- package/bin/runners/lib/polish/backend-checks.js +148 -0
- package/bin/runners/lib/polish/documentation-checks.js +111 -0
- package/bin/runners/lib/polish/frontend-checks.js +168 -0
- package/bin/runners/lib/polish/index.js +71 -0
- package/bin/runners/lib/polish/infrastructure-checks.js +131 -0
- package/bin/runners/lib/polish/library-detection.js +175 -0
- package/bin/runners/lib/polish/performance-checks.js +100 -0
- package/bin/runners/lib/polish/security-checks.js +148 -0
- package/bin/runners/lib/polish/utils.js +203 -0
- package/bin/runners/lib/prompt-builder.js +540 -0
- package/bin/runners/lib/proof-certificate.js +634 -0
- package/bin/runners/lib/reality/accessibility-audit.js +946 -0
- package/bin/runners/lib/reality/api-contract-validator.js +1012 -0
- package/bin/runners/lib/reality/chaos-engineering.js +1084 -0
- package/bin/runners/lib/reality/performance-tracker.js +1077 -0
- package/bin/runners/lib/reality/scenario-generator.js +1404 -0
- package/bin/runners/lib/reality/visual-regression.js +852 -0
- package/bin/runners/lib/reality-profiler.js +717 -0
- package/bin/runners/lib/replay/flight-recorder-viewer.js +1160 -0
- package/bin/runners/lib/review/ai-code-review.js +832 -0
- package/bin/runners/lib/rules/custom-rule-engine.js +985 -0
- package/bin/runners/lib/sbom-generator.js +641 -0
- package/bin/runners/lib/scan-output-enhanced.js +512 -0
- package/bin/runners/lib/scan-output.js +47 -0
- package/bin/runners/lib/security/owasp-scanner.js +939 -0
- package/bin/runners/lib/terminal-ui.js +113 -1
- package/bin/runners/lib/unified-cli-output.js +603 -430
- package/bin/runners/lib/validators/contract-validator.js +283 -0
- package/bin/runners/lib/validators/dead-export-detector.js +279 -0
- package/bin/runners/lib/validators/dep-audit.js +245 -0
- package/bin/runners/lib/validators/env-validator.js +319 -0
- package/bin/runners/lib/validators/index.js +120 -0
- package/bin/runners/lib/validators/license-checker.js +252 -0
- package/bin/runners/lib/validators/route-validator.js +290 -0
- package/bin/runners/runAIAgent.js +5 -10
- package/bin/runners/runAgent.js +3 -0
- package/bin/runners/runApprove.js +1233 -1200
- package/bin/runners/runAuth.js +22 -1
- package/bin/runners/runAuthority.js +528 -0
- package/bin/runners/runCheckpoint.js +4 -24
- package/bin/runners/runClassify.js +862 -859
- package/bin/runners/runConductor.js +772 -0
- package/bin/runners/runContainer.js +366 -0
- package/bin/runners/runContext.js +3 -0
- package/bin/runners/runDoctor.js +28 -41
- package/bin/runners/runEasy.js +410 -0
- package/bin/runners/runFirewall.js +3 -0
- package/bin/runners/runFirewallHook.js +3 -0
- package/bin/runners/runFix.js +76 -66
- package/bin/runners/runGuard.js +411 -18
- package/bin/runners/runIaC.js +372 -0
- package/bin/runners/runInit.js +10 -60
- package/bin/runners/runMcp.js +11 -12
- package/bin/runners/runPolish.js +240 -64
- package/bin/runners/runPromptFirewall.js +5 -12
- package/bin/runners/runProve.js +20 -55
- package/bin/runners/runReality.js +68 -59
- package/bin/runners/runReport.js +31 -5
- package/bin/runners/runRuntime.js +5 -8
- package/bin/runners/runScan.js +194 -1286
- package/bin/runners/runShip.js +695 -47
- package/bin/runners/runTruth.js +3 -0
- package/bin/runners/runValidate.js +7 -11
- package/bin/runners/runVibe.js +791 -0
- package/bin/runners/runWatch.js +14 -23
- package/bin/vibecheck.js +175 -56
- package/mcp-server/index.js +190 -14
- package/mcp-server/package.json +1 -1
- package/mcp-server/tools-v3.js +397 -64
- package/mcp-server/tools.js +495 -0
- package/package.json +1 -1
- package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +0 -164
- package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +0 -291
- package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +0 -83
- package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +0 -198
- package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +0 -275
- package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +0 -167
- package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +0 -217
- package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +0 -140
- package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +0 -164
- package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +0 -234
- package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +0 -217
- package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +0 -78
- package/mcp-server/index-v1.js +0 -698
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Infrastructure as Code (IaC) Security Scanner CLI
|
|
3
|
+
*
|
|
4
|
+
* Scans Terraform and CloudFormation files for security issues
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
const path = require("path");
|
|
10
|
+
const fs = require("fs");
|
|
11
|
+
const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
|
|
12
|
+
const { EXIT } = require("./lib/exit-codes");
|
|
13
|
+
|
|
14
|
+
// Terminal UI
|
|
15
|
+
let terminalUI;
|
|
16
|
+
try {
|
|
17
|
+
terminalUI = require("./lib/terminal-ui");
|
|
18
|
+
} catch {
|
|
19
|
+
terminalUI = {
|
|
20
|
+
c: { reset: "", bold: "", dim: "", red: "", yellow: "", green: "", cyan: "" },
|
|
21
|
+
rgb: () => "",
|
|
22
|
+
icons: { check: "✓", cross: "✗", warning: "⚠", info: "ℹ" },
|
|
23
|
+
Spinner: class { start() {} succeed() {} fail() {} },
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const { c, rgb, icons, Spinner } = terminalUI;
|
|
28
|
+
|
|
29
|
+
// Unified Output System
|
|
30
|
+
const { output } = require("./lib/output/index.js");
|
|
31
|
+
|
|
32
|
+
// Colors
|
|
33
|
+
const colors = {
|
|
34
|
+
critical: rgb(255, 80, 80),
|
|
35
|
+
high: rgb(255, 150, 50),
|
|
36
|
+
medium: rgb(255, 200, 0),
|
|
37
|
+
low: rgb(100, 200, 255),
|
|
38
|
+
info: rgb(150, 150, 150),
|
|
39
|
+
success: rgb(0, 255, 150),
|
|
40
|
+
accent: rgb(0, 200, 255),
|
|
41
|
+
terraform: rgb(123, 66, 255),
|
|
42
|
+
cloudformation: rgb(255, 153, 0),
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const BANNER = `
|
|
46
|
+
${rgb(123, 66, 255)} ╔═══════════════════════════════════════════════════════════════╗${c.reset}
|
|
47
|
+
${rgb(123, 66, 255)} ║ ${c.bold}IAC SECURITY${c.reset}${rgb(123, 66, 255)} • Terraform / CloudFormation Scanning ║${c.reset}
|
|
48
|
+
${rgb(123, 66, 255)} ╚═══════════════════════════════════════════════════════════════╝${c.reset}
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
function printBanner() {
|
|
52
|
+
console.log(BANNER);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function printHelp() {
|
|
56
|
+
console.log(`
|
|
57
|
+
${c.bold}Usage:${c.reset} vibecheck iac [options] [path]
|
|
58
|
+
|
|
59
|
+
${c.bold}Description:${c.reset}
|
|
60
|
+
Scan Infrastructure as Code files for security misconfigurations.
|
|
61
|
+
Supports Terraform (.tf) and CloudFormation (YAML/JSON).
|
|
62
|
+
|
|
63
|
+
${c.bold}Options:${c.reset}
|
|
64
|
+
${colors.accent}--path, -p${c.reset} Path to IaC files or directory (default: .)
|
|
65
|
+
${colors.accent}--json${c.reset} Output as JSON
|
|
66
|
+
${colors.accent}--sarif${c.reset} Output as SARIF for GitHub
|
|
67
|
+
${colors.accent}--ignore${c.reset} Ignore specific rule IDs (comma-separated)
|
|
68
|
+
${colors.accent}--min-severity${c.reset} Minimum severity to report (critical/high/medium/low)
|
|
69
|
+
${colors.accent}--provider${c.reset} Scan only specific provider (terraform/cloudformation)
|
|
70
|
+
${colors.accent}--verbose, -v${c.reset} Show detailed output
|
|
71
|
+
${colors.accent}--help, -h${c.reset} Show this help
|
|
72
|
+
|
|
73
|
+
${c.bold}Examples:${c.reset}
|
|
74
|
+
${c.dim}# Scan current directory${c.reset}
|
|
75
|
+
vibecheck iac
|
|
76
|
+
|
|
77
|
+
${c.dim}# Scan Terraform files only${c.reset}
|
|
78
|
+
vibecheck iac --provider terraform
|
|
79
|
+
|
|
80
|
+
${c.dim}# JSON output for CI${c.reset}
|
|
81
|
+
vibecheck iac --json
|
|
82
|
+
|
|
83
|
+
${c.dim}# SARIF output for GitHub Security${c.reset}
|
|
84
|
+
vibecheck iac --sarif
|
|
85
|
+
|
|
86
|
+
${c.dim}# Ignore specific rules${c.reset}
|
|
87
|
+
vibecheck iac --ignore AWS-S3-001,AWS-IAM-001
|
|
88
|
+
`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function parseArgs(args) {
|
|
92
|
+
const { flags: globalFlags, cleanArgs } = parseGlobalFlags(args);
|
|
93
|
+
|
|
94
|
+
const opts = {
|
|
95
|
+
path: globalFlags.path || ".",
|
|
96
|
+
json: globalFlags.json || false,
|
|
97
|
+
sarif: false,
|
|
98
|
+
verbose: globalFlags.verbose || false,
|
|
99
|
+
help: globalFlags.help || false,
|
|
100
|
+
ignore: [],
|
|
101
|
+
minSeverity: null,
|
|
102
|
+
provider: null,
|
|
103
|
+
noBanner: globalFlags.noBanner || false,
|
|
104
|
+
ci: globalFlags.ci || false,
|
|
105
|
+
quiet: globalFlags.quiet || false,
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
for (let i = 0; i < cleanArgs.length; i++) {
|
|
109
|
+
const arg = cleanArgs[i];
|
|
110
|
+
|
|
111
|
+
if (arg === "--sarif") opts.sarif = true;
|
|
112
|
+
else if (arg === "--ignore") {
|
|
113
|
+
opts.ignore = (cleanArgs[++i] || "").split(",").filter(Boolean);
|
|
114
|
+
}
|
|
115
|
+
else if (arg.startsWith("--ignore=")) {
|
|
116
|
+
opts.ignore = arg.split("=")[1].split(",").filter(Boolean);
|
|
117
|
+
}
|
|
118
|
+
else if (arg === "--min-severity") {
|
|
119
|
+
opts.minSeverity = cleanArgs[++i];
|
|
120
|
+
}
|
|
121
|
+
else if (arg.startsWith("--min-severity=")) {
|
|
122
|
+
opts.minSeverity = arg.split("=")[1];
|
|
123
|
+
}
|
|
124
|
+
else if (arg === "--provider") {
|
|
125
|
+
opts.provider = cleanArgs[++i];
|
|
126
|
+
}
|
|
127
|
+
else if (arg.startsWith("--provider=")) {
|
|
128
|
+
opts.provider = arg.split("=")[1];
|
|
129
|
+
}
|
|
130
|
+
else if (!arg.startsWith("-")) {
|
|
131
|
+
opts.path = arg;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return opts;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function formatFinding(finding, verbose = false) {
|
|
139
|
+
const severityColors = {
|
|
140
|
+
critical: colors.critical,
|
|
141
|
+
high: colors.high,
|
|
142
|
+
medium: colors.medium,
|
|
143
|
+
low: colors.low,
|
|
144
|
+
info: colors.info,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const severityIcons = {
|
|
148
|
+
critical: "🔴",
|
|
149
|
+
high: "🟠",
|
|
150
|
+
medium: "🟡",
|
|
151
|
+
low: "🔵",
|
|
152
|
+
info: "⚪",
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const color = severityColors[finding.severity] || colors.info;
|
|
156
|
+
const icon = severityIcons[finding.severity] || "⚪";
|
|
157
|
+
|
|
158
|
+
let output = ` ${icon} ${color}${finding.severity.toUpperCase()}${c.reset} ${finding.title}\n`;
|
|
159
|
+
output += ` ${c.dim}${finding.id}${c.reset}`;
|
|
160
|
+
|
|
161
|
+
if (finding.resource) {
|
|
162
|
+
output += ` ${c.dim}• ${finding.resource}${c.reset}`;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
if (finding.line) {
|
|
166
|
+
output += ` ${c.dim}(line ${finding.line})${c.reset}`;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
output += "\n";
|
|
170
|
+
|
|
171
|
+
if (verbose) {
|
|
172
|
+
output += ` ${c.dim}${finding.description}${c.reset}\n`;
|
|
173
|
+
output += ` ${colors.accent}Fix:${c.reset} ${finding.recommendation}\n`;
|
|
174
|
+
if (finding.cwe) {
|
|
175
|
+
output += ` ${c.dim}CWE: ${finding.cwe}${c.reset}\n`;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return output;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
async function runIaC(args) {
|
|
183
|
+
const opts = parseArgs(args);
|
|
184
|
+
|
|
185
|
+
if (opts.help) {
|
|
186
|
+
printHelp();
|
|
187
|
+
return EXIT.SUCCESS;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (shouldShowBanner(opts)) {
|
|
191
|
+
printBanner();
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const spinner = new Spinner();
|
|
195
|
+
spinner.start("Scanning for IaC files...");
|
|
196
|
+
|
|
197
|
+
try {
|
|
198
|
+
// Dynamic import of the security package
|
|
199
|
+
let iacScanner;
|
|
200
|
+
try {
|
|
201
|
+
iacScanner = require("@vibecheck/security").scanIaC ||
|
|
202
|
+
require("@vibecheck/security").iac?.scanIaC;
|
|
203
|
+
|
|
204
|
+
if (!iacScanner) {
|
|
205
|
+
// Try direct import
|
|
206
|
+
const security = require("../../packages/security/src/iac/scanner");
|
|
207
|
+
iacScanner = security.scanIaC;
|
|
208
|
+
}
|
|
209
|
+
} catch (e) {
|
|
210
|
+
// Fallback: try relative path
|
|
211
|
+
try {
|
|
212
|
+
const security = require("../../packages/security/src/iac/scanner");
|
|
213
|
+
iacScanner = security.scanIaC;
|
|
214
|
+
} catch {
|
|
215
|
+
spinner.fail("IaC scanning module not available");
|
|
216
|
+
console.error(`\n ${colors.critical}${icons.cross}${c.reset} IaC scanning requires @vibecheck/security package\n`);
|
|
217
|
+
return EXIT.INTERNAL_ERROR;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const targetPath = path.resolve(opts.path);
|
|
222
|
+
|
|
223
|
+
// Determine providers to scan
|
|
224
|
+
const providers = opts.provider
|
|
225
|
+
? [opts.provider]
|
|
226
|
+
: ["terraform", "cloudformation"];
|
|
227
|
+
|
|
228
|
+
const results = await iacScanner({
|
|
229
|
+
paths: [targetPath],
|
|
230
|
+
providers,
|
|
231
|
+
ignoreRules: opts.ignore,
|
|
232
|
+
minSeverity: opts.minSeverity,
|
|
233
|
+
includeInfo: opts.verbose,
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
spinner.succeed(`Found ${results.length} provider(s) with IaC files`);
|
|
237
|
+
|
|
238
|
+
if (results.length === 0) {
|
|
239
|
+
console.log(`\n ${c.dim}No IaC files found in ${targetPath}${c.reset}\n`);
|
|
240
|
+
return EXIT.SUCCESS;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Aggregate findings
|
|
244
|
+
const totalFindings = results.flatMap(r => r.findings);
|
|
245
|
+
const totalScore = results.length > 0
|
|
246
|
+
? Math.round(results.reduce((sum, r) => sum + r.score, 0) / results.length)
|
|
247
|
+
: 100;
|
|
248
|
+
|
|
249
|
+
// JSON output
|
|
250
|
+
if (opts.json) {
|
|
251
|
+
console.log(JSON.stringify({
|
|
252
|
+
success: true,
|
|
253
|
+
results,
|
|
254
|
+
summary: {
|
|
255
|
+
providersScanned: results.length,
|
|
256
|
+
filesScanned: results.reduce((sum, r) => sum + r.files.length, 0),
|
|
257
|
+
resourcesScanned: results.reduce((sum, r) => sum + r.resourceCount, 0),
|
|
258
|
+
totalFindings: totalFindings.length,
|
|
259
|
+
score: totalScore,
|
|
260
|
+
critical: totalFindings.filter(f => f.severity === "critical").length,
|
|
261
|
+
high: totalFindings.filter(f => f.severity === "high").length,
|
|
262
|
+
medium: totalFindings.filter(f => f.severity === "medium").length,
|
|
263
|
+
low: totalFindings.filter(f => f.severity === "low").length,
|
|
264
|
+
},
|
|
265
|
+
}, null, 2));
|
|
266
|
+
|
|
267
|
+
return totalFindings.some(f => f.severity === "critical" || f.severity === "high")
|
|
268
|
+
? EXIT.BLOCKING
|
|
269
|
+
: totalFindings.length > 0 ? EXIT.WARNINGS : EXIT.SUCCESS;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// SARIF output
|
|
273
|
+
if (opts.sarif) {
|
|
274
|
+
let formatAsSARIF;
|
|
275
|
+
try {
|
|
276
|
+
formatAsSARIF = require("@vibecheck/security").formatAsSARIF ||
|
|
277
|
+
require("../../packages/security/src/iac/scanner").formatAsSARIF;
|
|
278
|
+
} catch {
|
|
279
|
+
// Manual SARIF format
|
|
280
|
+
formatAsSARIF = (results) => ({
|
|
281
|
+
$schema: "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
|
|
282
|
+
version: "2.1.0",
|
|
283
|
+
runs: results.map(result => ({
|
|
284
|
+
tool: {
|
|
285
|
+
driver: {
|
|
286
|
+
name: `vibecheck-${result.provider}`,
|
|
287
|
+
version: "1.0.0",
|
|
288
|
+
informationUri: "https://vibecheckai.dev",
|
|
289
|
+
},
|
|
290
|
+
},
|
|
291
|
+
results: result.findings.map(f => ({
|
|
292
|
+
ruleId: f.id,
|
|
293
|
+
level: f.severity === "critical" || f.severity === "high" ? "error" : "warning",
|
|
294
|
+
message: { text: f.description },
|
|
295
|
+
locations: [{
|
|
296
|
+
physicalLocation: {
|
|
297
|
+
artifactLocation: { uri: f.file },
|
|
298
|
+
region: f.line ? { startLine: f.line } : undefined,
|
|
299
|
+
},
|
|
300
|
+
}],
|
|
301
|
+
})),
|
|
302
|
+
})),
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
console.log(JSON.stringify(formatAsSARIF(results), null, 2));
|
|
307
|
+
return EXIT.SUCCESS;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Human-readable output
|
|
311
|
+
console.log("");
|
|
312
|
+
|
|
313
|
+
for (const result of results) {
|
|
314
|
+
const providerColor = result.provider === "terraform" ? colors.terraform : colors.cloudformation;
|
|
315
|
+
const providerIcon = result.provider === "terraform" ? "🏗️" : "☁️";
|
|
316
|
+
|
|
317
|
+
console.log(`${providerIcon} ${c.bold}${providerColor}${result.provider.toUpperCase()}${c.reset}`);
|
|
318
|
+
console.log(` Files: ${result.files.length} • Resources: ${result.resourceCount} • Score: ${result.score >= 80 ? colors.success : result.score >= 60 ? colors.medium : colors.critical}${result.score}/100${c.reset}`);
|
|
319
|
+
console.log("");
|
|
320
|
+
|
|
321
|
+
if (result.findings.length === 0) {
|
|
322
|
+
console.log(` ${colors.success}${icons.check}${c.reset} No issues found\n`);
|
|
323
|
+
} else {
|
|
324
|
+
// Group by severity
|
|
325
|
+
const bySeverity = {
|
|
326
|
+
critical: result.findings.filter(f => f.severity === "critical"),
|
|
327
|
+
high: result.findings.filter(f => f.severity === "high"),
|
|
328
|
+
medium: result.findings.filter(f => f.severity === "medium"),
|
|
329
|
+
low: result.findings.filter(f => f.severity === "low"),
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
for (const [severity, findings] of Object.entries(bySeverity)) {
|
|
333
|
+
if (findings.length > 0) {
|
|
334
|
+
for (const finding of findings) {
|
|
335
|
+
console.log(formatFinding(finding, opts.verbose));
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// Show scanned files
|
|
342
|
+
if (opts.verbose && result.files.length > 0) {
|
|
343
|
+
console.log(` ${c.dim}Files scanned:${c.reset}`);
|
|
344
|
+
for (const file of result.files.slice(0, 10)) {
|
|
345
|
+
console.log(` ${c.dim}• ${path.relative(process.cwd(), file)}${c.reset}`);
|
|
346
|
+
}
|
|
347
|
+
if (result.files.length > 10) {
|
|
348
|
+
console.log(` ${c.dim}... and ${result.files.length - 10} more${c.reset}`);
|
|
349
|
+
}
|
|
350
|
+
console.log("");
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
// Summary
|
|
355
|
+
console.log(`${c.dim}─────────────────────────────────────────────────────────────${c.reset}`);
|
|
356
|
+
const totalFiles = results.reduce((sum, r) => sum + r.files.length, 0);
|
|
357
|
+
const totalResources = results.reduce((sum, r) => sum + r.resourceCount, 0);
|
|
358
|
+
console.log(`${c.bold}Summary:${c.reset} ${totalFiles} file(s), ${totalResources} resource(s), ${totalFindings.length} finding(s), Score: ${totalScore}/100`);
|
|
359
|
+
console.log("");
|
|
360
|
+
|
|
361
|
+
return totalFindings.some(f => f.severity === "critical" || f.severity === "high")
|
|
362
|
+
? EXIT.BLOCKING
|
|
363
|
+
: totalFindings.length > 0 ? EXIT.WARNINGS : EXIT.SUCCESS;
|
|
364
|
+
|
|
365
|
+
} catch (error) {
|
|
366
|
+
spinner.fail("Scan failed");
|
|
367
|
+
console.error(`\n ${colors.critical}${icons.cross}${c.reset} ${error.message}\n`);
|
|
368
|
+
return EXIT.INTERNAL_ERROR;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
module.exports = { runIaC };
|
package/bin/runners/runInit.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* vibecheck init -
|
|
2
|
+
* vibecheck init - Project Setup
|
|
3
3
|
*
|
|
4
4
|
* ═══════════════════════════════════════════════════════════════════════════════
|
|
5
|
-
*
|
|
5
|
+
* Professional Terminal Experience
|
|
6
6
|
* ═══════════════════════════════════════════════════════════════════════════════
|
|
7
7
|
*
|
|
8
8
|
* Configure your project for production-grade verification.
|
|
@@ -31,64 +31,15 @@ try {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
34
|
-
//
|
|
34
|
+
// TERMINAL UI - Import from shared module
|
|
35
35
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
36
36
|
|
|
37
|
-
const c =
|
|
38
|
-
reset: '\x1b[0m',
|
|
39
|
-
bold: '\x1b[1m',
|
|
40
|
-
dim: '\x1b[2m',
|
|
41
|
-
italic: '\x1b[3m',
|
|
42
|
-
underline: '\x1b[4m',
|
|
43
|
-
blink: '\x1b[5m',
|
|
44
|
-
inverse: '\x1b[7m',
|
|
45
|
-
hidden: '\x1b[8m',
|
|
46
|
-
strike: '\x1b[9m',
|
|
47
|
-
// Colors
|
|
48
|
-
black: '\x1b[30m',
|
|
49
|
-
red: '\x1b[31m',
|
|
50
|
-
green: '\x1b[32m',
|
|
51
|
-
yellow: '\x1b[33m',
|
|
52
|
-
blue: '\x1b[34m',
|
|
53
|
-
magenta: '\x1b[35m',
|
|
54
|
-
cyan: '\x1b[36m',
|
|
55
|
-
white: '\x1b[37m',
|
|
56
|
-
// Bright colors
|
|
57
|
-
gray: '\x1b[90m',
|
|
58
|
-
brightRed: '\x1b[91m',
|
|
59
|
-
brightGreen: '\x1b[92m',
|
|
60
|
-
brightYellow: '\x1b[93m',
|
|
61
|
-
brightBlue: '\x1b[94m',
|
|
62
|
-
brightMagenta: '\x1b[95m',
|
|
63
|
-
brightCyan: '\x1b[96m',
|
|
64
|
-
brightWhite: '\x1b[97m',
|
|
65
|
-
// Background
|
|
66
|
-
bgBlack: '\x1b[40m',
|
|
67
|
-
bgRed: '\x1b[41m',
|
|
68
|
-
bgGreen: '\x1b[42m',
|
|
69
|
-
bgYellow: '\x1b[43m',
|
|
70
|
-
bgBlue: '\x1b[44m',
|
|
71
|
-
bgMagenta: '\x1b[45m',
|
|
72
|
-
bgCyan: '\x1b[46m',
|
|
73
|
-
bgWhite: '\x1b[47m',
|
|
74
|
-
// Cursor control
|
|
75
|
-
cursorUp: (n = 1) => `\x1b[${n}A`,
|
|
76
|
-
cursorDown: (n = 1) => `\x1b[${n}B`,
|
|
77
|
-
cursorRight: (n = 1) => `\x1b[${n}C`,
|
|
78
|
-
cursorLeft: (n = 1) => `\x1b[${n}D`,
|
|
79
|
-
clearLine: '\x1b[2K',
|
|
80
|
-
clearScreen: '\x1b[2J',
|
|
81
|
-
saveCursor: '\x1b[s',
|
|
82
|
-
restoreCursor: '\x1b[u',
|
|
83
|
-
hideCursor: '\x1b[?25l',
|
|
84
|
-
showCursor: '\x1b[?25h',
|
|
85
|
-
};
|
|
37
|
+
const { c, rgb, bgRgb, icons, Spinner } = require("./lib/terminal-ui");
|
|
86
38
|
|
|
87
|
-
//
|
|
88
|
-
const
|
|
89
|
-
const bgRgb = (r, g, b) => `\x1b[48;2;${r};${g};${b}m`;
|
|
39
|
+
// Unified Output System
|
|
40
|
+
const { output } = require("./lib/output/index.js");
|
|
90
41
|
|
|
91
|
-
//
|
|
42
|
+
// Extended color palette for init command (gold/amber theme)
|
|
92
43
|
const colors = {
|
|
93
44
|
// Gradient for banner
|
|
94
45
|
gradient1: rgb(255, 215, 100), // Gold
|
|
@@ -147,7 +98,7 @@ ${rgb(255, 140, 40)} ╚████╔╝ ██║██████╔╝
|
|
|
147
98
|
${rgb(255, 120, 20)} ╚═══╝ ╚═╝╚═════╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═════╝╚═╝ ╚═╝${c.reset}
|
|
148
99
|
|
|
149
100
|
${c.dim} ┌─────────────────────────────────────────────────────────────────────┐${c.reset}
|
|
150
|
-
${c.dim} │${c.reset} ${rgb(255, 200, 100)}⚡${c.reset} ${c.bold}INIT${c.reset} ${c.dim}•${c.reset} ${rgb(200, 200, 200)}Project Setup${c.reset} ${c.dim}•${c.reset} ${rgb(150, 150, 150)}
|
|
101
|
+
${c.dim} │${c.reset} ${rgb(255, 200, 100)}⚡${c.reset} ${c.bold}INIT${c.reset} ${c.dim}•${c.reset} ${rgb(200, 200, 200)}Project Setup${c.reset} ${c.dim}•${c.reset} ${rgb(150, 150, 150)}Production Ready${c.reset} ${c.dim}│${c.reset}
|
|
151
102
|
${c.dim} └─────────────────────────────────────────────────────────────────────┘${c.reset}
|
|
152
103
|
`;
|
|
153
104
|
|
|
@@ -1043,7 +994,7 @@ function printNextSteps(options = {}) {
|
|
|
1043
994
|
if (options.hasCI) {
|
|
1044
995
|
steps.push({ num: 3, cmd: 'git push', desc: 'CI will run automatically' });
|
|
1045
996
|
} else {
|
|
1046
|
-
steps.push({ num: 3, cmd: 'vibecheck init --connect', desc: 'Add GitHub integration [
|
|
997
|
+
steps.push({ num: 3, cmd: 'vibecheck init --connect', desc: 'Add GitHub integration [PRO]' });
|
|
1047
998
|
}
|
|
1048
999
|
}
|
|
1049
1000
|
|
|
@@ -1059,8 +1010,7 @@ function printNextSteps(options = {}) {
|
|
|
1059
1010
|
// Upsell box
|
|
1060
1011
|
console.log(` ${c.dim}╭────────────────────────────────────────────────────────────╮${c.reset}`);
|
|
1061
1012
|
console.log(` ${c.dim}│${c.reset} ${c.dim}│${c.reset}`);
|
|
1062
|
-
console.log(` ${c.dim}│${c.reset} ${colors.accent}
|
|
1063
|
-
console.log(` ${c.dim}│${c.reset} ${colors.accent}🏆 PRO${c.reset} ${c.dim}•${c.reset} Runtime proof, verified badges, AI testing ${c.dim}│${c.reset}`);
|
|
1013
|
+
console.log(` ${c.dim}│${c.reset} ${colors.accent}🏆 PRO${c.reset} ${c.dim}•${c.reset} AI fixes, CI, runtime proof, badges, MCP ${c.dim}│${c.reset}`);
|
|
1064
1014
|
console.log(` ${c.dim}│${c.reset} ${c.dim}│${c.reset}`);
|
|
1065
1015
|
console.log(` ${c.dim}│${c.reset} ${colors.info}vibecheck login${c.reset} ${c.dim}to upgrade • vibecheck.dev/pricing${c.reset} ${c.dim}│${c.reset}`);
|
|
1066
1016
|
console.log(` ${c.dim}│${c.reset} ${c.dim}│${c.reset}`);
|
package/bin/runners/runMcp.js
CHANGED
|
@@ -14,10 +14,13 @@ const { URL } = require("url");
|
|
|
14
14
|
const { buildTruthpack, writeTruthpack } = require("./lib/truth");
|
|
15
15
|
const { shipCore } = require("./runShip");
|
|
16
16
|
const { generateRunId } = require("./lib/cli-output");
|
|
17
|
-
const { enforceLimit, enforceFeature, trackUsage } = require("./lib/entitlements");
|
|
17
|
+
const { enforceLimit, enforceFeature, trackUsage } = require("./lib/entitlements-v2");
|
|
18
18
|
const { EXIT } = require("./lib/exit-codes");
|
|
19
19
|
const { parseGlobalFlags, shouldSuppressOutput, isJsonMode } = require("./lib/global-flags");
|
|
20
20
|
|
|
21
|
+
// Unified Output System
|
|
22
|
+
const { output } = require("./lib/output/index.js");
|
|
23
|
+
|
|
21
24
|
// MCP Server class
|
|
22
25
|
class VibecheckMCPServer {
|
|
23
26
|
constructor(options = {}) {
|
|
@@ -33,9 +36,7 @@ class VibecheckMCPServer {
|
|
|
33
36
|
this.rateLimits = new Map();
|
|
34
37
|
this.tiers = {
|
|
35
38
|
free: { rpm: 10, burst: 20, daily: 100 },
|
|
36
|
-
|
|
37
|
-
pro: { rpm: 100, burst: 200, daily: 2000 },
|
|
38
|
-
enterprise: { rpm: 500, burst: 1000, daily: Infinity }
|
|
39
|
+
pro: { rpm: 100, burst: 200, daily: Infinity }
|
|
39
40
|
};
|
|
40
41
|
|
|
41
42
|
// Tool definitions
|
|
@@ -110,7 +111,7 @@ class VibecheckMCPServer {
|
|
|
110
111
|
tier: "pro"
|
|
111
112
|
},
|
|
112
113
|
|
|
113
|
-
//
|
|
114
|
+
// Pro tier tools
|
|
114
115
|
policy_check: {
|
|
115
116
|
description: "Validate project against custom compliance policies",
|
|
116
117
|
inputSchema: {
|
|
@@ -121,7 +122,7 @@ class VibecheckMCPServer {
|
|
|
121
122
|
reportFormat: { type: "string", enum: ["json", "sarif", "markdown"], default: "json" }
|
|
122
123
|
}
|
|
123
124
|
},
|
|
124
|
-
tier: "
|
|
125
|
+
tier: "pro"
|
|
125
126
|
}
|
|
126
127
|
};
|
|
127
128
|
}
|
|
@@ -588,7 +589,7 @@ class VibecheckMCPServer {
|
|
|
588
589
|
}
|
|
589
590
|
|
|
590
591
|
checkTierAccess(requiredTier, userTier) {
|
|
591
|
-
const tierOrder = ["free", "
|
|
592
|
+
const tierOrder = ["free", "pro"];
|
|
592
593
|
const requiredIndex = tierOrder.indexOf(requiredTier);
|
|
593
594
|
const userIndex = tierOrder.indexOf(userTier);
|
|
594
595
|
|
|
@@ -677,9 +678,9 @@ async function runMcp(args) {
|
|
|
677
678
|
|
|
678
679
|
if (isFreeTier && !isHelpOrConfig) {
|
|
679
680
|
if (json) {
|
|
680
|
-
console.log(JSON.stringify({ success: false, error: "MCP Server requires
|
|
681
|
+
console.log(JSON.stringify({ success: false, error: "MCP Server requires PRO plan" }));
|
|
681
682
|
} else if (!quiet) {
|
|
682
|
-
console.log("\n🔌 MCP Server requires
|
|
683
|
+
console.log("\n🔌 MCP Server requires PRO plan");
|
|
683
684
|
console.log("Use --help to see available options or");
|
|
684
685
|
console.log("Upgrade: https://vibecheckai.dev/pricing\n");
|
|
685
686
|
}
|
|
@@ -909,9 +910,7 @@ ${c.bold}MCP TOOLS AVAILABLE${c.reset}
|
|
|
909
910
|
|
|
910
911
|
${c.dim}Pro Tier:${c.reset}
|
|
911
912
|
• run_ship Execute ship check
|
|
912
|
-
|
|
913
|
-
${c.dim}Enterprise Tier:${c.reset}
|
|
914
|
-
• policy_check Validate against policies
|
|
913
|
+
• policy_check Validate against policies [PRO]
|
|
915
914
|
|
|
916
915
|
${c.bold}CONFIGURATION${c.reset}
|
|
917
916
|
Add to your AI IDE's MCP config:
|