@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.
Files changed (166) hide show
  1. package/bin/registry.js +243 -152
  2. package/bin/runners/cli-utils.js +2 -33
  3. package/bin/runners/context/generators/cursor.js +49 -2
  4. package/bin/runners/lib/agent-firewall/learning/learning-engine.js +849 -0
  5. package/bin/runners/lib/analyzers.js +544 -19
  6. package/bin/runners/lib/audit-logger.js +532 -0
  7. package/bin/runners/lib/authority/authorities/architecture.js +364 -0
  8. package/bin/runners/lib/authority/authorities/compliance.js +341 -0
  9. package/bin/runners/lib/authority/authorities/human.js +343 -0
  10. package/bin/runners/lib/authority/authorities/quality.js +420 -0
  11. package/bin/runners/lib/authority/authorities/security.js +228 -0
  12. package/bin/runners/lib/authority/index.js +293 -0
  13. package/bin/runners/lib/authority-badge.js +425 -425
  14. package/bin/runners/lib/bundle/bundle-intelligence.js +846 -0
  15. package/bin/runners/lib/cli-charts.js +368 -0
  16. package/bin/runners/lib/cli-config-display.js +405 -0
  17. package/bin/runners/lib/cli-demo.js +275 -0
  18. package/bin/runners/lib/cli-errors.js +438 -0
  19. package/bin/runners/lib/cli-help-formatter.js +439 -0
  20. package/bin/runners/lib/cli-interactive-menu.js +509 -0
  21. package/bin/runners/lib/cli-prompts.js +441 -0
  22. package/bin/runners/lib/cli-scan-cards.js +362 -0
  23. package/bin/runners/lib/compliance-reporter.js +710 -0
  24. package/bin/runners/lib/conductor/index.js +671 -0
  25. package/bin/runners/lib/easy/README.md +123 -0
  26. package/bin/runners/lib/easy/index.js +140 -0
  27. package/bin/runners/lib/easy/interactive-wizard.js +788 -0
  28. package/bin/runners/lib/easy/one-click-firewall.js +564 -0
  29. package/bin/runners/lib/easy/zero-config-reality.js +714 -0
  30. package/bin/runners/lib/engines/accessibility-engine.js +218 -18
  31. package/bin/runners/lib/engines/api-consistency-engine.js +335 -30
  32. package/bin/runners/lib/engines/async-patterns-engine.js +444 -0
  33. package/bin/runners/lib/engines/bundle-size-engine.js +433 -0
  34. package/bin/runners/lib/engines/confidence-scoring.js +276 -0
  35. package/bin/runners/lib/engines/context-detection.js +264 -0
  36. package/bin/runners/lib/engines/cross-file-analysis-engine.js +292 -27
  37. package/bin/runners/lib/engines/database-patterns-engine.js +429 -0
  38. package/bin/runners/lib/engines/duplicate-code-engine.js +354 -0
  39. package/bin/runners/lib/engines/empty-catch-engine.js +127 -17
  40. package/bin/runners/lib/engines/env-variables-engine.js +458 -0
  41. package/bin/runners/lib/engines/error-handling-engine.js +437 -0
  42. package/bin/runners/lib/engines/false-positive-prevention.js +630 -0
  43. package/bin/runners/lib/engines/framework-adapters/index.js +607 -0
  44. package/bin/runners/lib/engines/framework-detection.js +508 -0
  45. package/bin/runners/lib/engines/import-order-engine.js +429 -0
  46. package/bin/runners/lib/engines/mock-data-engine.js +53 -10
  47. package/bin/runners/lib/engines/naming-conventions-engine.js +544 -0
  48. package/bin/runners/lib/engines/noise-reduction-engine.js +452 -0
  49. package/bin/runners/lib/engines/orchestrator.js +334 -0
  50. package/bin/runners/lib/engines/performance-issues-engine.js +176 -36
  51. package/bin/runners/lib/engines/react-patterns-engine.js +457 -0
  52. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +382 -54
  53. package/bin/runners/lib/engines/type-aware-engine.js +263 -39
  54. package/bin/runners/lib/engines/vibecheck-engines/index.js +122 -13
  55. package/bin/runners/lib/engines/vibecheck-engines/lib/ai-hallucination-engine.js +806 -0
  56. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +373 -73
  57. package/bin/runners/lib/engines/vibecheck-engines/lib/smart-fix-engine.js +577 -0
  58. package/bin/runners/lib/engines/vibecheck-engines/lib/vibe-score-engine.js +543 -0
  59. package/bin/runners/lib/engines/vibecheck-engines.js +514 -0
  60. package/bin/runners/lib/enhanced-features/index.js +305 -0
  61. package/bin/runners/lib/enhanced-output.js +631 -0
  62. package/bin/runners/lib/enterprise.js +300 -0
  63. package/bin/runners/lib/entitlements-v2.js +103 -11
  64. package/bin/runners/lib/firewall/command-validator.js +351 -0
  65. package/bin/runners/lib/firewall/config.js +341 -0
  66. package/bin/runners/lib/firewall/content-validator.js +519 -0
  67. package/bin/runners/lib/firewall/index.js +101 -0
  68. package/bin/runners/lib/firewall/path-validator.js +256 -0
  69. package/bin/runners/lib/html-proof-report.js +350 -700
  70. package/bin/runners/lib/intelligence/cross-repo-intelligence.js +817 -0
  71. package/bin/runners/lib/mcp-utils.js +425 -0
  72. package/bin/runners/lib/missions/plan.js +46 -6
  73. package/bin/runners/lib/missions/templates.js +232 -0
  74. package/bin/runners/lib/output/index.js +1022 -0
  75. package/bin/runners/lib/policy-engine.js +652 -0
  76. package/bin/runners/lib/polish/autofix/accessibility-fixes.js +333 -0
  77. package/bin/runners/lib/polish/autofix/async-handlers.js +273 -0
  78. package/bin/runners/lib/polish/autofix/dead-code.js +280 -0
  79. package/bin/runners/lib/polish/autofix/imports-optimizer.js +344 -0
  80. package/bin/runners/lib/polish/autofix/index.js +200 -0
  81. package/bin/runners/lib/polish/autofix/remove-consoles.js +209 -0
  82. package/bin/runners/lib/polish/autofix/strengthen-types.js +245 -0
  83. package/bin/runners/lib/polish/backend-checks.js +148 -0
  84. package/bin/runners/lib/polish/documentation-checks.js +111 -0
  85. package/bin/runners/lib/polish/frontend-checks.js +168 -0
  86. package/bin/runners/lib/polish/index.js +71 -0
  87. package/bin/runners/lib/polish/infrastructure-checks.js +131 -0
  88. package/bin/runners/lib/polish/library-detection.js +175 -0
  89. package/bin/runners/lib/polish/performance-checks.js +100 -0
  90. package/bin/runners/lib/polish/security-checks.js +148 -0
  91. package/bin/runners/lib/polish/utils.js +203 -0
  92. package/bin/runners/lib/prompt-builder.js +540 -0
  93. package/bin/runners/lib/proof-certificate.js +634 -0
  94. package/bin/runners/lib/reality/accessibility-audit.js +946 -0
  95. package/bin/runners/lib/reality/api-contract-validator.js +1012 -0
  96. package/bin/runners/lib/reality/chaos-engineering.js +1084 -0
  97. package/bin/runners/lib/reality/performance-tracker.js +1077 -0
  98. package/bin/runners/lib/reality/scenario-generator.js +1404 -0
  99. package/bin/runners/lib/reality/visual-regression.js +852 -0
  100. package/bin/runners/lib/reality-profiler.js +717 -0
  101. package/bin/runners/lib/replay/flight-recorder-viewer.js +1160 -0
  102. package/bin/runners/lib/review/ai-code-review.js +832 -0
  103. package/bin/runners/lib/rules/custom-rule-engine.js +985 -0
  104. package/bin/runners/lib/sbom-generator.js +641 -0
  105. package/bin/runners/lib/scan-output-enhanced.js +512 -0
  106. package/bin/runners/lib/scan-output.js +47 -0
  107. package/bin/runners/lib/security/owasp-scanner.js +939 -0
  108. package/bin/runners/lib/terminal-ui.js +113 -1
  109. package/bin/runners/lib/unified-cli-output.js +603 -430
  110. package/bin/runners/lib/validators/contract-validator.js +283 -0
  111. package/bin/runners/lib/validators/dead-export-detector.js +279 -0
  112. package/bin/runners/lib/validators/dep-audit.js +245 -0
  113. package/bin/runners/lib/validators/env-validator.js +319 -0
  114. package/bin/runners/lib/validators/index.js +120 -0
  115. package/bin/runners/lib/validators/license-checker.js +252 -0
  116. package/bin/runners/lib/validators/route-validator.js +290 -0
  117. package/bin/runners/runAIAgent.js +5 -10
  118. package/bin/runners/runAgent.js +3 -0
  119. package/bin/runners/runApprove.js +1233 -1200
  120. package/bin/runners/runAuth.js +22 -1
  121. package/bin/runners/runAuthority.js +528 -0
  122. package/bin/runners/runCheckpoint.js +4 -24
  123. package/bin/runners/runClassify.js +862 -859
  124. package/bin/runners/runConductor.js +772 -0
  125. package/bin/runners/runContainer.js +366 -0
  126. package/bin/runners/runContext.js +3 -0
  127. package/bin/runners/runDoctor.js +28 -41
  128. package/bin/runners/runEasy.js +410 -0
  129. package/bin/runners/runFirewall.js +3 -0
  130. package/bin/runners/runFirewallHook.js +3 -0
  131. package/bin/runners/runFix.js +76 -66
  132. package/bin/runners/runGuard.js +411 -18
  133. package/bin/runners/runIaC.js +372 -0
  134. package/bin/runners/runInit.js +10 -60
  135. package/bin/runners/runMcp.js +11 -12
  136. package/bin/runners/runPolish.js +240 -64
  137. package/bin/runners/runPromptFirewall.js +5 -12
  138. package/bin/runners/runProve.js +20 -55
  139. package/bin/runners/runReality.js +68 -59
  140. package/bin/runners/runReport.js +31 -5
  141. package/bin/runners/runRuntime.js +5 -8
  142. package/bin/runners/runScan.js +194 -1286
  143. package/bin/runners/runShip.js +695 -47
  144. package/bin/runners/runTruth.js +3 -0
  145. package/bin/runners/runValidate.js +7 -11
  146. package/bin/runners/runVibe.js +791 -0
  147. package/bin/runners/runWatch.js +14 -23
  148. package/bin/vibecheck.js +175 -56
  149. package/mcp-server/index.js +190 -14
  150. package/mcp-server/package.json +1 -1
  151. package/mcp-server/tools-v3.js +397 -64
  152. package/mcp-server/tools.js +495 -0
  153. package/package.json +1 -1
  154. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +0 -164
  155. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +0 -291
  156. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +0 -83
  157. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +0 -198
  158. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +0 -275
  159. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +0 -167
  160. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +0 -217
  161. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +0 -140
  162. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +0 -164
  163. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +0 -234
  164. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +0 -217
  165. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +0 -78
  166. 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 };
@@ -1,8 +1,8 @@
1
1
  /**
2
- * vibecheck init - Enterprise Project Setup
2
+ * vibecheck init - Project Setup
3
3
  *
4
4
  * ═══════════════════════════════════════════════════════════════════════════════
5
- * ENTERPRISE EDITION - World-Class Terminal Experience
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
- // ADVANCED TERMINAL - ANSI CODES & UTILITIES
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
- // True color support
88
- const rgb = (r, g, b) => `\x1b[38;2;${r};${g};${b}m`;
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
- // Premium color palette (gold/amber theme for "init/setup")
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)}Enterprise Ready${c.reset} ${c.dim}│${c.reset}
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 [STARTER]' });
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} STARTER${c.reset} ${c.dim}•${c.reset} AI-powered fixes, GitHub CI, MCP tools ${c.dim}│${c.reset}`);
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}`);
@@ -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
- starter: { rpm: 30, burst: 60, daily: 500 },
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
- // Enterprise tier tools
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: "enterprise"
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", "starter", "pro", "enterprise"];
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 STARTER plan or higher" }));
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 STARTER plan or higher");
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: