@vibecheckai/cli 3.5.0 → 3.5.2

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 (224) hide show
  1. package/bin/registry.js +214 -237
  2. package/bin/runners/cli-utils.js +33 -2
  3. package/bin/runners/context/analyzer.js +52 -1
  4. package/bin/runners/context/generators/cursor.js +2 -49
  5. package/bin/runners/context/git-context.js +3 -1
  6. package/bin/runners/context/team-conventions.js +33 -7
  7. package/bin/runners/lib/analysis-core.js +25 -5
  8. package/bin/runners/lib/analyzers.js +431 -481
  9. package/bin/runners/lib/default-config.js +127 -0
  10. package/bin/runners/lib/doctor/modules/security.js +3 -1
  11. package/bin/runners/lib/engine/ast-cache.js +210 -0
  12. package/bin/runners/lib/engine/auth-extractor.js +211 -0
  13. package/bin/runners/lib/engine/billing-extractor.js +112 -0
  14. package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
  15. package/bin/runners/lib/engine/env-extractor.js +207 -0
  16. package/bin/runners/lib/engine/express-extractor.js +208 -0
  17. package/bin/runners/lib/engine/extractors.js +849 -0
  18. package/bin/runners/lib/engine/index.js +207 -0
  19. package/bin/runners/lib/engine/repo-index.js +514 -0
  20. package/bin/runners/lib/engine/types.js +124 -0
  21. package/bin/runners/lib/engines/accessibility-engine.js +18 -218
  22. package/bin/runners/lib/engines/api-consistency-engine.js +30 -335
  23. package/bin/runners/lib/engines/cross-file-analysis-engine.js +27 -292
  24. package/bin/runners/lib/engines/empty-catch-engine.js +17 -127
  25. package/bin/runners/lib/engines/mock-data-engine.js +10 -53
  26. package/bin/runners/lib/engines/performance-issues-engine.js +36 -176
  27. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +54 -382
  28. package/bin/runners/lib/engines/type-aware-engine.js +39 -263
  29. package/bin/runners/lib/engines/vibecheck-engines/index.js +13 -122
  30. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
  31. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
  32. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
  33. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
  34. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
  35. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
  36. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
  37. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +73 -373
  38. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
  39. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
  40. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
  41. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
  42. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
  43. package/bin/runners/lib/entitlements-v2.js +73 -97
  44. package/bin/runners/lib/error-handler.js +44 -3
  45. package/bin/runners/lib/error-messages.js +289 -0
  46. package/bin/runners/lib/evidence-pack.js +7 -1
  47. package/bin/runners/lib/finding-id.js +69 -0
  48. package/bin/runners/lib/finding-sorter.js +89 -0
  49. package/bin/runners/lib/html-proof-report.js +700 -350
  50. package/bin/runners/lib/missions/plan.js +6 -46
  51. package/bin/runners/lib/missions/templates.js +0 -232
  52. package/bin/runners/lib/next-action.js +560 -0
  53. package/bin/runners/lib/prerequisites.js +149 -0
  54. package/bin/runners/lib/route-detection.js +137 -68
  55. package/bin/runners/lib/scan-output.js +91 -76
  56. package/bin/runners/lib/scan-runner.js +135 -0
  57. package/bin/runners/lib/schemas/ajv-validator.js +464 -0
  58. package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
  59. package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
  60. package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
  61. package/bin/runners/lib/schemas/run-request.schema.json +108 -0
  62. package/bin/runners/lib/schemas/validator.js +27 -0
  63. package/bin/runners/lib/schemas/verdict.schema.json +140 -0
  64. package/bin/runners/lib/ship-output-enterprise.js +23 -23
  65. package/bin/runners/lib/ship-output.js +75 -31
  66. package/bin/runners/lib/terminal-ui.js +6 -113
  67. package/bin/runners/lib/truth.js +351 -10
  68. package/bin/runners/lib/unified-cli-output.js +430 -603
  69. package/bin/runners/lib/unified-output.js +13 -9
  70. package/bin/runners/runAIAgent.js +10 -5
  71. package/bin/runners/runAgent.js +0 -3
  72. package/bin/runners/runAllowlist.js +389 -0
  73. package/bin/runners/runApprove.js +0 -33
  74. package/bin/runners/runAuth.js +73 -45
  75. package/bin/runners/runCheckpoint.js +51 -11
  76. package/bin/runners/runClassify.js +85 -21
  77. package/bin/runners/runContext.js +0 -3
  78. package/bin/runners/runDoctor.js +41 -28
  79. package/bin/runners/runEvidencePack.js +362 -0
  80. package/bin/runners/runFirewall.js +0 -3
  81. package/bin/runners/runFirewallHook.js +0 -3
  82. package/bin/runners/runFix.js +66 -76
  83. package/bin/runners/runGuard.js +18 -411
  84. package/bin/runners/runInit.js +113 -30
  85. package/bin/runners/runLabs.js +424 -0
  86. package/bin/runners/runMcp.js +19 -25
  87. package/bin/runners/runPolish.js +64 -240
  88. package/bin/runners/runPromptFirewall.js +12 -5
  89. package/bin/runners/runProve.js +57 -22
  90. package/bin/runners/runQuickstart.js +531 -0
  91. package/bin/runners/runReality.js +59 -68
  92. package/bin/runners/runReport.js +38 -33
  93. package/bin/runners/runRuntime.js +8 -5
  94. package/bin/runners/runScan.js +1413 -190
  95. package/bin/runners/runShip.js +113 -719
  96. package/bin/runners/runTruth.js +0 -3
  97. package/bin/runners/runValidate.js +13 -9
  98. package/bin/runners/runWatch.js +23 -14
  99. package/bin/scan.js +6 -1
  100. package/bin/vibecheck.js +204 -185
  101. package/mcp-server/deprecation-middleware.js +282 -0
  102. package/mcp-server/handlers/index.ts +15 -0
  103. package/mcp-server/handlers/tool-handler.ts +554 -0
  104. package/mcp-server/index-v1.js +698 -0
  105. package/mcp-server/index.js +210 -238
  106. package/mcp-server/lib/cache-wrapper.cjs +383 -0
  107. package/mcp-server/lib/error-envelope.js +138 -0
  108. package/mcp-server/lib/executor.ts +499 -0
  109. package/mcp-server/lib/index.ts +19 -0
  110. package/mcp-server/lib/rate-limiter.js +166 -0
  111. package/mcp-server/lib/sandbox.test.ts +519 -0
  112. package/mcp-server/lib/sandbox.ts +395 -0
  113. package/mcp-server/lib/types.ts +267 -0
  114. package/mcp-server/package.json +12 -3
  115. package/mcp-server/registry/tool-registry.js +794 -0
  116. package/mcp-server/registry/tools.json +605 -0
  117. package/mcp-server/registry.test.ts +334 -0
  118. package/mcp-server/tests/tier-gating.test.js +297 -0
  119. package/mcp-server/tier-auth.js +378 -45
  120. package/mcp-server/tools-v3.js +353 -442
  121. package/mcp-server/tsconfig.json +37 -0
  122. package/mcp-server/vibecheck-2.0-tools.js +14 -1
  123. package/package.json +1 -1
  124. package/bin/runners/lib/agent-firewall/learning/learning-engine.js +0 -849
  125. package/bin/runners/lib/audit-logger.js +0 -532
  126. package/bin/runners/lib/authority/authorities/architecture.js +0 -364
  127. package/bin/runners/lib/authority/authorities/compliance.js +0 -341
  128. package/bin/runners/lib/authority/authorities/human.js +0 -343
  129. package/bin/runners/lib/authority/authorities/quality.js +0 -420
  130. package/bin/runners/lib/authority/authorities/security.js +0 -228
  131. package/bin/runners/lib/authority/index.js +0 -293
  132. package/bin/runners/lib/bundle/bundle-intelligence.js +0 -846
  133. package/bin/runners/lib/cli-charts.js +0 -368
  134. package/bin/runners/lib/cli-config-display.js +0 -405
  135. package/bin/runners/lib/cli-demo.js +0 -275
  136. package/bin/runners/lib/cli-errors.js +0 -438
  137. package/bin/runners/lib/cli-help-formatter.js +0 -439
  138. package/bin/runners/lib/cli-interactive-menu.js +0 -509
  139. package/bin/runners/lib/cli-prompts.js +0 -441
  140. package/bin/runners/lib/cli-scan-cards.js +0 -362
  141. package/bin/runners/lib/compliance-reporter.js +0 -710
  142. package/bin/runners/lib/conductor/index.js +0 -671
  143. package/bin/runners/lib/easy/README.md +0 -123
  144. package/bin/runners/lib/easy/index.js +0 -140
  145. package/bin/runners/lib/easy/interactive-wizard.js +0 -788
  146. package/bin/runners/lib/easy/one-click-firewall.js +0 -564
  147. package/bin/runners/lib/easy/zero-config-reality.js +0 -714
  148. package/bin/runners/lib/engines/async-patterns-engine.js +0 -444
  149. package/bin/runners/lib/engines/bundle-size-engine.js +0 -433
  150. package/bin/runners/lib/engines/confidence-scoring.js +0 -276
  151. package/bin/runners/lib/engines/context-detection.js +0 -264
  152. package/bin/runners/lib/engines/database-patterns-engine.js +0 -429
  153. package/bin/runners/lib/engines/duplicate-code-engine.js +0 -354
  154. package/bin/runners/lib/engines/env-variables-engine.js +0 -458
  155. package/bin/runners/lib/engines/error-handling-engine.js +0 -437
  156. package/bin/runners/lib/engines/false-positive-prevention.js +0 -630
  157. package/bin/runners/lib/engines/framework-adapters/index.js +0 -607
  158. package/bin/runners/lib/engines/framework-detection.js +0 -508
  159. package/bin/runners/lib/engines/import-order-engine.js +0 -429
  160. package/bin/runners/lib/engines/naming-conventions-engine.js +0 -544
  161. package/bin/runners/lib/engines/noise-reduction-engine.js +0 -452
  162. package/bin/runners/lib/engines/orchestrator.js +0 -334
  163. package/bin/runners/lib/engines/react-patterns-engine.js +0 -457
  164. package/bin/runners/lib/engines/vibecheck-engines/lib/ai-hallucination-engine.js +0 -806
  165. package/bin/runners/lib/engines/vibecheck-engines/lib/smart-fix-engine.js +0 -577
  166. package/bin/runners/lib/engines/vibecheck-engines/lib/vibe-score-engine.js +0 -543
  167. package/bin/runners/lib/engines/vibecheck-engines.js +0 -514
  168. package/bin/runners/lib/enhanced-features/index.js +0 -305
  169. package/bin/runners/lib/enhanced-output.js +0 -631
  170. package/bin/runners/lib/enterprise.js +0 -300
  171. package/bin/runners/lib/firewall/command-validator.js +0 -351
  172. package/bin/runners/lib/firewall/config.js +0 -341
  173. package/bin/runners/lib/firewall/content-validator.js +0 -519
  174. package/bin/runners/lib/firewall/index.js +0 -101
  175. package/bin/runners/lib/firewall/path-validator.js +0 -256
  176. package/bin/runners/lib/intelligence/cross-repo-intelligence.js +0 -817
  177. package/bin/runners/lib/mcp-utils.js +0 -425
  178. package/bin/runners/lib/output/index.js +0 -1022
  179. package/bin/runners/lib/policy-engine.js +0 -652
  180. package/bin/runners/lib/polish/autofix/accessibility-fixes.js +0 -333
  181. package/bin/runners/lib/polish/autofix/async-handlers.js +0 -273
  182. package/bin/runners/lib/polish/autofix/dead-code.js +0 -280
  183. package/bin/runners/lib/polish/autofix/imports-optimizer.js +0 -344
  184. package/bin/runners/lib/polish/autofix/index.js +0 -200
  185. package/bin/runners/lib/polish/autofix/remove-consoles.js +0 -209
  186. package/bin/runners/lib/polish/autofix/strengthen-types.js +0 -245
  187. package/bin/runners/lib/polish/backend-checks.js +0 -148
  188. package/bin/runners/lib/polish/documentation-checks.js +0 -111
  189. package/bin/runners/lib/polish/frontend-checks.js +0 -168
  190. package/bin/runners/lib/polish/index.js +0 -71
  191. package/bin/runners/lib/polish/infrastructure-checks.js +0 -131
  192. package/bin/runners/lib/polish/library-detection.js +0 -175
  193. package/bin/runners/lib/polish/performance-checks.js +0 -100
  194. package/bin/runners/lib/polish/security-checks.js +0 -148
  195. package/bin/runners/lib/polish/utils.js +0 -203
  196. package/bin/runners/lib/prompt-builder.js +0 -540
  197. package/bin/runners/lib/proof-certificate.js +0 -634
  198. package/bin/runners/lib/reality/accessibility-audit.js +0 -946
  199. package/bin/runners/lib/reality/api-contract-validator.js +0 -1012
  200. package/bin/runners/lib/reality/chaos-engineering.js +0 -1084
  201. package/bin/runners/lib/reality/performance-tracker.js +0 -1077
  202. package/bin/runners/lib/reality/scenario-generator.js +0 -1404
  203. package/bin/runners/lib/reality/visual-regression.js +0 -852
  204. package/bin/runners/lib/reality-profiler.js +0 -717
  205. package/bin/runners/lib/replay/flight-recorder-viewer.js +0 -1160
  206. package/bin/runners/lib/review/ai-code-review.js +0 -832
  207. package/bin/runners/lib/rules/custom-rule-engine.js +0 -985
  208. package/bin/runners/lib/sbom-generator.js +0 -641
  209. package/bin/runners/lib/scan-output-enhanced.js +0 -512
  210. package/bin/runners/lib/security/owasp-scanner.js +0 -939
  211. package/bin/runners/lib/validators/contract-validator.js +0 -283
  212. package/bin/runners/lib/validators/dead-export-detector.js +0 -279
  213. package/bin/runners/lib/validators/dep-audit.js +0 -245
  214. package/bin/runners/lib/validators/env-validator.js +0 -319
  215. package/bin/runners/lib/validators/index.js +0 -120
  216. package/bin/runners/lib/validators/license-checker.js +0 -252
  217. package/bin/runners/lib/validators/route-validator.js +0 -290
  218. package/bin/runners/runAuthority.js +0 -528
  219. package/bin/runners/runConductor.js +0 -772
  220. package/bin/runners/runContainer.js +0 -366
  221. package/bin/runners/runEasy.js +0 -410
  222. package/bin/runners/runIaC.js +0 -372
  223. package/bin/runners/runVibe.js +0 -791
  224. package/mcp-server/tools.js +0 -495
@@ -1,788 +0,0 @@
1
- /**
2
- * Interactive Wizard
3
- *
4
- * ═══════════════════════════════════════════════════════════════════════════════
5
- * ZERO-FRICTION ONBOARDING - So Easy Your Mom Could Use It
6
- * ═══════════════════════════════════════════════════════════════════════════════
7
- *
8
- * This wizard guides users through Vibecheck with friendly prompts,
9
- * auto-detection, and clear explanations. No coding knowledge required.
10
- */
11
-
12
- "use strict";
13
-
14
- const readline = require("readline");
15
- const fs = require("fs");
16
- const path = require("path");
17
- const { spawn, exec } = require("child_process");
18
-
19
- // ═══════════════════════════════════════════════════════════════════════════════
20
- // BEAUTIFUL CONSOLE OUTPUT
21
- // ═══════════════════════════════════════════════════════════════════════════════
22
-
23
- const colors = {
24
- reset: "\x1b[0m",
25
- bright: "\x1b[1m",
26
- dim: "\x1b[2m",
27
- red: "\x1b[31m",
28
- green: "\x1b[32m",
29
- yellow: "\x1b[33m",
30
- blue: "\x1b[34m",
31
- magenta: "\x1b[35m",
32
- cyan: "\x1b[36m",
33
- white: "\x1b[37m",
34
- bgGreen: "\x1b[42m",
35
- bgBlue: "\x1b[44m",
36
- bgMagenta: "\x1b[45m"
37
- };
38
-
39
- const icons = {
40
- check: "✓",
41
- cross: "✗",
42
- arrow: "→",
43
- star: "★",
44
- heart: "♥",
45
- rocket: "🚀",
46
- shield: "🛡️",
47
- eye: "👁️",
48
- sparkle: "✨",
49
- fire: "🔥",
50
- warning: "⚠️",
51
- question: "❓",
52
- lightbulb: "💡",
53
- folder: "📁",
54
- globe: "🌐",
55
- lock: "🔒",
56
- clock: "⏱️",
57
- party: "🎉"
58
- };
59
-
60
- function print(text) {
61
- console.log(text);
62
- }
63
-
64
- function printBlank() {
65
- console.log("");
66
- }
67
-
68
- function printHeader(text) {
69
- printBlank();
70
- print(`${colors.bright}${colors.cyan}${text}${colors.reset}`);
71
- print(`${colors.dim}${"─".repeat(50)}${colors.reset}`);
72
- }
73
-
74
- function printSuccess(text) {
75
- print(` ${colors.green}${icons.check}${colors.reset} ${text}`);
76
- }
77
-
78
- function printInfo(text) {
79
- print(` ${colors.blue}${icons.arrow}${colors.reset} ${text}`);
80
- }
81
-
82
- function printWarning(text) {
83
- print(` ${colors.yellow}${icons.warning}${colors.reset} ${text}`);
84
- }
85
-
86
- function printStep(num, text) {
87
- print(` ${colors.magenta}${num}.${colors.reset} ${text}`);
88
- }
89
-
90
- function printOption(key, text, description = "") {
91
- const desc = description ? `${colors.dim} - ${description}${colors.reset}` : "";
92
- print(` ${colors.cyan}[${key}]${colors.reset} ${text}${desc}`);
93
- }
94
-
95
- function clearScreen() {
96
- console.clear();
97
- }
98
-
99
- // ═══════════════════════════════════════════════════════════════════════════════
100
- // ANIMATED WELCOME BANNER
101
- // ═══════════════════════════════════════════════════════════════════════════════
102
-
103
- function showWelcomeBanner() {
104
- clearScreen();
105
-
106
- const banner = `
107
- ${colors.cyan}${colors.bright}
108
- ╔═══════════════════════════════════════════════════════════════╗
109
- ║ ║
110
- ║ ${icons.sparkle} ${colors.white}V I B E C H E C K${colors.cyan} ${icons.sparkle} ║
111
- ║ ║
112
- ║ ${colors.dim}Find issues in your app before your users do${colors.cyan}${colors.bright} ║
113
- ║ ║
114
- ╚═══════════════════════════════════════════════════════════════╝
115
- ${colors.reset}`;
116
-
117
- print(banner);
118
- printBlank();
119
- print(` ${colors.dim}Welcome! Let's make sure your app is production-ready.${colors.reset}`);
120
- print(` ${colors.dim}Don't worry - I'll guide you through everything.${colors.reset}`);
121
- printBlank();
122
- }
123
-
124
- // ═══════════════════════════════════════════════════════════════════════════════
125
- // READLINE INTERFACE
126
- // ═══════════════════════════════════════════════════════════════════════════════
127
-
128
- class Wizard {
129
- constructor() {
130
- this.rl = null;
131
- this.projectRoot = process.cwd();
132
- this.detectedInfo = {};
133
- }
134
-
135
- async start() {
136
- this.rl = readline.createInterface({
137
- input: process.stdin,
138
- output: process.stdout
139
- });
140
-
141
- showWelcomeBanner();
142
-
143
- await this.sleep(500);
144
-
145
- // Detect project info
146
- await this.detectProject();
147
-
148
- // Show main menu
149
- await this.showMainMenu();
150
- }
151
-
152
- async prompt(question, defaultValue = "") {
153
- return new Promise((resolve) => {
154
- const defaultText = defaultValue ? ` ${colors.dim}(${defaultValue})${colors.reset}` : "";
155
- this.rl.question(` ${colors.cyan}?${colors.reset} ${question}${defaultText}: `, (answer) => {
156
- resolve(answer.trim() || defaultValue);
157
- });
158
- });
159
- }
160
-
161
- async confirm(question, defaultYes = true) {
162
- const hint = defaultYes ? "Y/n" : "y/N";
163
- const answer = await this.prompt(`${question} ${colors.dim}[${hint}]${colors.reset}`, "");
164
-
165
- if (answer === "") return defaultYes;
166
- return answer.toLowerCase().startsWith("y");
167
- }
168
-
169
- async choose(question, options) {
170
- printBlank();
171
- print(` ${colors.cyan}?${colors.reset} ${question}`);
172
- printBlank();
173
-
174
- for (const opt of options) {
175
- printOption(opt.key, opt.label, opt.description);
176
- }
177
-
178
- printBlank();
179
- const answer = await this.prompt("Your choice", options[0].key);
180
- return answer.toLowerCase();
181
- }
182
-
183
- sleep(ms) {
184
- return new Promise(resolve => setTimeout(resolve, ms));
185
- }
186
-
187
- // ─────────────────────────────────────────────────────────────────────────────
188
- // PROJECT DETECTION
189
- // ─────────────────────────────────────────────────────────────────────────────
190
-
191
- async detectProject() {
192
- printHeader(`${icons.folder} Checking Your Project`);
193
-
194
- await this.sleep(300);
195
-
196
- // Check for package.json
197
- const pkgPath = path.join(this.projectRoot, "package.json");
198
- if (fs.existsSync(pkgPath)) {
199
- const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
200
- this.detectedInfo.name = pkg.name;
201
- this.detectedInfo.hasPackageJson = true;
202
- printSuccess(`Found project: ${colors.bright}${pkg.name}${colors.reset}`);
203
-
204
- // Detect framework
205
- const deps = { ...pkg.dependencies, ...pkg.devDependencies };
206
-
207
- if (deps.next) {
208
- this.detectedInfo.framework = "Next.js";
209
- this.detectedInfo.devCommand = "npm run dev";
210
- this.detectedInfo.defaultUrl = "http://localhost:3000";
211
- } else if (deps.react) {
212
- this.detectedInfo.framework = "React";
213
- this.detectedInfo.devCommand = "npm start";
214
- this.detectedInfo.defaultUrl = "http://localhost:3000";
215
- } else if (deps.vue) {
216
- this.detectedInfo.framework = "Vue";
217
- this.detectedInfo.devCommand = "npm run serve";
218
- this.detectedInfo.defaultUrl = "http://localhost:8080";
219
- } else if (deps.express) {
220
- this.detectedInfo.framework = "Express";
221
- this.detectedInfo.devCommand = "npm start";
222
- this.detectedInfo.defaultUrl = "http://localhost:3000";
223
- } else if (deps.svelte || deps["@sveltejs/kit"]) {
224
- this.detectedInfo.framework = "Svelte";
225
- this.detectedInfo.devCommand = "npm run dev";
226
- this.detectedInfo.defaultUrl = "http://localhost:5173";
227
- } else {
228
- this.detectedInfo.framework = "Node.js";
229
- this.detectedInfo.devCommand = "npm start";
230
- this.detectedInfo.defaultUrl = "http://localhost:3000";
231
- }
232
-
233
- printSuccess(`Detected framework: ${colors.bright}${this.detectedInfo.framework}${colors.reset}`);
234
-
235
- // Check for scripts
236
- if (pkg.scripts?.dev || pkg.scripts?.start) {
237
- printSuccess(`Found dev server command`);
238
- }
239
- } else {
240
- this.detectedInfo.hasPackageJson = false;
241
- printWarning("No package.json found - that's okay!");
242
- }
243
-
244
- // Check for .env
245
- if (fs.existsSync(path.join(this.projectRoot, ".env"))) {
246
- printSuccess("Found environment file (.env)");
247
- }
248
-
249
- // Check for vibecheck config
250
- if (fs.existsSync(path.join(this.projectRoot, "vibecheck.config.js")) ||
251
- fs.existsSync(path.join(this.projectRoot, ".vibecheck"))) {
252
- printSuccess("Found existing Vibecheck configuration");
253
- this.detectedInfo.hasConfig = true;
254
- }
255
-
256
- printBlank();
257
- }
258
-
259
- // ─────────────────────────────────────────────────────────────────────────────
260
- // MAIN MENU
261
- // ─────────────────────────────────────────────────────────────────────────────
262
-
263
- async showMainMenu() {
264
- const choice = await this.choose("What would you like to do?", [
265
- {
266
- key: "1",
267
- label: `${icons.eye} Test My App (Reality Mode)`,
268
- description: "See your app like a real user would"
269
- },
270
- {
271
- key: "2",
272
- label: `${icons.shield} Protect My Code (Firewall)`,
273
- description: "Stop bad code from getting in"
274
- },
275
- {
276
- key: "3",
277
- label: `${icons.rocket} Scan Everything`,
278
- description: "Full check of your entire project"
279
- },
280
- {
281
- key: "4",
282
- label: `${icons.lightbulb} Explain What This Does`,
283
- description: "Learn more about Vibecheck"
284
- },
285
- {
286
- key: "q",
287
- label: "Exit",
288
- description: ""
289
- }
290
- ]);
291
-
292
- switch (choice) {
293
- case "1":
294
- await this.startRealityMode();
295
- break;
296
- case "2":
297
- await this.startFirewall();
298
- break;
299
- case "3":
300
- await this.startFullScan();
301
- break;
302
- case "4":
303
- await this.showExplanation();
304
- break;
305
- case "q":
306
- this.exit();
307
- break;
308
- default:
309
- await this.showMainMenu();
310
- }
311
- }
312
-
313
- // ─────────────────────────────────────────────────────────────────────────────
314
- // REALITY MODE (SUPER EASY)
315
- // ─────────────────────────────────────────────────────────────────────────────
316
-
317
- async startRealityMode() {
318
- clearScreen();
319
- printHeader(`${icons.eye} Reality Mode - Test Your App`);
320
-
321
- printBlank();
322
- print(` ${colors.dim}Reality Mode opens your app in a browser and tests it like${colors.reset}`);
323
- print(` ${colors.dim}a real person would - clicking buttons, filling forms, etc.${colors.reset}`);
324
- printBlank();
325
-
326
- // Get the URL
327
- let url = this.detectedInfo.defaultUrl || "http://localhost:3000";
328
-
329
- print(` ${icons.lightbulb} ${colors.dim}Tip: Make sure your app is running first!${colors.reset}`);
330
- printBlank();
331
-
332
- url = await this.prompt(
333
- "What's your app's URL?",
334
- url
335
- );
336
-
337
- // Validate URL
338
- if (!url.startsWith("http")) {
339
- url = "http://" + url;
340
- }
341
-
342
- printBlank();
343
-
344
- // Check if URL is reachable
345
- printInfo("Checking if your app is running...");
346
-
347
- const isRunning = await this.checkUrl(url);
348
-
349
- if (!isRunning) {
350
- printBlank();
351
- printWarning(`Couldn't reach ${url}`);
352
- printBlank();
353
-
354
- const startServer = await this.confirm(
355
- "Would you like me to help start your app?",
356
- true
357
- );
358
-
359
- if (startServer) {
360
- await this.helpStartServer();
361
- // Re-check
362
- await this.sleep(3000);
363
- const nowRunning = await this.checkUrl(url);
364
- if (!nowRunning) {
365
- printWarning("Still can't reach your app. Let's try again.");
366
- await this.startRealityMode();
367
- return;
368
- }
369
- } else {
370
- printInfo("No problem! Start your app and run this again.");
371
- await this.sleep(2000);
372
- await this.showMainMenu();
373
- return;
374
- }
375
- }
376
-
377
- printSuccess(`Found your app at ${url}`);
378
- printBlank();
379
-
380
- // Ask about options
381
- const options = await this.getRealityOptions();
382
-
383
- // Show what we're about to do
384
- printHeader(`${icons.rocket} Starting Reality Mode`);
385
- printBlank();
386
- printStep(1, "Opening a browser");
387
- printStep(2, "Visiting your app");
388
- printStep(3, "Testing all the pages and buttons");
389
- printStep(4, "Looking for problems");
390
- printStep(5, "Creating a report for you");
391
- printBlank();
392
-
393
- const proceed = await this.confirm("Ready to start?", true);
394
-
395
- if (!proceed) {
396
- await this.showMainMenu();
397
- return;
398
- }
399
-
400
- // Run Reality Mode
401
- await this.runRealityMode(url, options);
402
- }
403
-
404
- async getRealityOptions() {
405
- const options = {
406
- thorough: false,
407
- screenshots: true,
408
- loginFirst: false
409
- };
410
-
411
- printBlank();
412
-
413
- const mode = await this.choose("How thorough should the test be?", [
414
- {
415
- key: "q",
416
- label: "Quick Check",
417
- description: "~1 minute, finds obvious issues"
418
- },
419
- {
420
- key: "t",
421
- label: "Thorough Test",
422
- description: "~5 minutes, finds more issues"
423
- }
424
- ]);
425
-
426
- options.thorough = mode === "t";
427
-
428
- // Check if login is needed
429
- const needsLogin = await this.confirm(
430
- "Does your app require login to test?",
431
- false
432
- );
433
-
434
- if (needsLogin) {
435
- options.loginFirst = true;
436
- printBlank();
437
- printInfo("I'll pause at the login page so you can sign in.");
438
- }
439
-
440
- return options;
441
- }
442
-
443
- async runRealityMode(url, options) {
444
- clearScreen();
445
- printHeader(`${icons.eye} Running Reality Mode`);
446
- printBlank();
447
-
448
- // Show nice progress
449
- const steps = [
450
- { text: "Starting browser...", time: 1000 },
451
- { text: "Loading your app...", time: 1500 },
452
- { text: "Exploring pages...", time: 2000 },
453
- { text: "Testing interactions...", time: 2000 },
454
- { text: "Checking for issues...", time: 1500 },
455
- { text: "Generating report...", time: 1000 }
456
- ];
457
-
458
- for (const step of steps) {
459
- printInfo(step.text);
460
- await this.sleep(step.time);
461
- }
462
-
463
- // Actually run the command
464
- const args = ["reality", url];
465
- if (options.thorough) args.push("--thorough");
466
- if (options.screenshots) args.push("--screenshots");
467
- if (options.loginFirst) args.push("--pause-for-login");
468
-
469
- printBlank();
470
- printSuccess("Reality Mode complete!");
471
- printBlank();
472
-
473
- // Show results summary
474
- await this.showRealityResults();
475
- }
476
-
477
- async showRealityResults() {
478
- printHeader(`${icons.party} Results`);
479
- printBlank();
480
-
481
- // Simulated results - in real implementation, these come from the actual run
482
- print(` ${colors.bright}Pages Tested:${colors.reset} 12`);
483
- print(` ${colors.bright}Buttons Clicked:${colors.reset} 34`);
484
- print(` ${colors.bright}Forms Tested:${colors.reset} 5`);
485
- printBlank();
486
-
487
- print(` ${colors.green}${icons.check} No critical issues found${colors.reset}`);
488
- print(` ${colors.yellow}${icons.warning} 3 warnings to review${colors.reset}`);
489
- printBlank();
490
-
491
- printInfo(`Full report saved to: ${colors.bright}vibecheck-report.html${colors.reset}`);
492
- printBlank();
493
-
494
- const openReport = await this.confirm("Open the report in your browser?", true);
495
-
496
- if (openReport) {
497
- // Open report
498
- const reportPath = path.join(this.projectRoot, "vibecheck-report.html");
499
- this.openFile(reportPath);
500
- }
501
-
502
- printBlank();
503
- await this.prompt("Press Enter to continue...");
504
- await this.showMainMenu();
505
- }
506
-
507
- // ─────────────────────────────────────────────────────────────────────────────
508
- // FIREWALL (SUPER EASY)
509
- // ─────────────────────────────────────────────────────────────────────────────
510
-
511
- async startFirewall() {
512
- clearScreen();
513
- printHeader(`${icons.shield} Agent Firewall - Protect Your Code`);
514
-
515
- printBlank();
516
- print(` ${colors.dim}The Firewall watches your code and stops bad changes${colors.reset}`);
517
- print(` ${colors.dim}from AI tools (like Copilot) or other developers.${colors.reset}`);
518
- printBlank();
519
- print(` ${colors.dim}It catches things like:${colors.reset}`);
520
- printStep("", "Fake data being committed");
521
- printStep("", "Security vulnerabilities");
522
- printStep("", "Broken features");
523
- printStep("", "Missing error handling");
524
- printBlank();
525
-
526
- const enable = await this.confirm("Enable the Firewall?", true);
527
-
528
- if (!enable) {
529
- await this.showMainMenu();
530
- return;
531
- }
532
-
533
- await this.enableFirewall();
534
- }
535
-
536
- async enableFirewall() {
537
- clearScreen();
538
- printHeader(`${icons.shield} Setting Up Firewall`);
539
- printBlank();
540
-
541
- const steps = [
542
- { text: "Creating configuration...", time: 500 },
543
- { text: "Setting up Git hooks...", time: 800 },
544
- { text: "Configuring rules...", time: 600 },
545
- { text: "Enabling protection...", time: 400 }
546
- ];
547
-
548
- for (const step of steps) {
549
- printInfo(step.text);
550
- await this.sleep(step.time);
551
- printSuccess(step.text.replace("...", " - Done!"));
552
- }
553
-
554
- printBlank();
555
-
556
- // Create the config file
557
- const configPath = path.join(this.projectRoot, ".vibecheck", "firewall.json");
558
- const configDir = path.dirname(configPath);
559
-
560
- if (!fs.existsSync(configDir)) {
561
- fs.mkdirSync(configDir, { recursive: true });
562
- }
563
-
564
- const config = {
565
- enabled: true,
566
- mode: "protect",
567
- rules: {
568
- blockFakeData: true,
569
- blockSecurityIssues: true,
570
- blockConsoleLog: true,
571
- requireErrorHandling: true
572
- },
573
- notifications: {
574
- showInTerminal: true,
575
- showInVSCode: true
576
- }
577
- };
578
-
579
- fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
580
-
581
- printSuccess(`${icons.party} Firewall is now active!`);
582
- printBlank();
583
-
584
- print(` ${colors.dim}What happens now:${colors.reset}`);
585
- printStep(1, "The Firewall runs automatically when you save files");
586
- printStep(2, "If it finds a problem, it will warn you");
587
- printStep(3, "Critical issues will be blocked from being committed");
588
- printBlank();
589
-
590
- printInfo(`Config saved to: ${colors.bright}.vibecheck/firewall.json${colors.reset}`);
591
- printBlank();
592
-
593
- await this.prompt("Press Enter to continue...");
594
- await this.showMainMenu();
595
- }
596
-
597
- // ─────────────────────────────────────────────────────────────────────────────
598
- // FULL SCAN
599
- // ─────────────────────────────────────────────────────────────────────────────
600
-
601
- async startFullScan() {
602
- clearScreen();
603
- printHeader(`${icons.rocket} Full Project Scan`);
604
-
605
- printBlank();
606
- print(` ${colors.dim}This will check your entire codebase for:${colors.reset}`);
607
- printBlank();
608
- printStep("", "Security vulnerabilities");
609
- printStep("", "Performance issues");
610
- printStep("", "Code quality problems");
611
- printStep("", "Accessibility issues");
612
- printStep("", "Best practice violations");
613
- printBlank();
614
-
615
- const proceed = await this.confirm("Start the scan?", true);
616
-
617
- if (!proceed) {
618
- await this.showMainMenu();
619
- return;
620
- }
621
-
622
- await this.runFullScan();
623
- }
624
-
625
- async runFullScan() {
626
- clearScreen();
627
- printHeader(`${icons.rocket} Scanning Your Project`);
628
- printBlank();
629
-
630
- const categories = [
631
- { name: "Security", icon: icons.lock, time: 1500 },
632
- { name: "Performance", icon: icons.clock, time: 1200 },
633
- { name: "Code Quality", icon: icons.sparkle, time: 1000 },
634
- { name: "Accessibility", icon: icons.eye, time: 800 },
635
- { name: "Best Practices", icon: icons.star, time: 600 }
636
- ];
637
-
638
- for (const cat of categories) {
639
- print(` ${cat.icon} Checking ${cat.name}...`);
640
- await this.sleep(cat.time);
641
- printSuccess(`${cat.name} check complete`);
642
- }
643
-
644
- printBlank();
645
- printSuccess(`${icons.party} Scan complete!`);
646
- printBlank();
647
-
648
- // Show summary
649
- print(` ${colors.bright}Files Scanned:${colors.reset} 127`);
650
- print(` ${colors.bright}Issues Found:${colors.reset} 8`);
651
- print(` ${colors.bright}Auto-fixable:${colors.reset} 5`);
652
- printBlank();
653
-
654
- print(` ${colors.green}${icons.check} 2 Security${colors.reset}`);
655
- print(` ${colors.yellow}${icons.warning} 3 Performance${colors.reset}`);
656
- print(` ${colors.blue}${icons.lightbulb} 3 Suggestions${colors.reset}`);
657
- printBlank();
658
-
659
- const autoFix = await this.confirm("Would you like me to auto-fix the easy ones?", true);
660
-
661
- if (autoFix) {
662
- printBlank();
663
- printInfo("Fixing issues...");
664
- await this.sleep(1500);
665
- printSuccess("Fixed 5 issues automatically!");
666
- }
667
-
668
- printBlank();
669
- await this.prompt("Press Enter to continue...");
670
- await this.showMainMenu();
671
- }
672
-
673
- // ─────────────────────────────────────────────────────────────────────────────
674
- // EXPLANATION
675
- // ─────────────────────────────────────────────────────────────────────────────
676
-
677
- async showExplanation() {
678
- clearScreen();
679
- printHeader(`${icons.lightbulb} What is Vibecheck?`);
680
-
681
- printBlank();
682
- print(` ${colors.bright}Vibecheck helps you find problems in your app${colors.reset}`);
683
- print(` ${colors.bright}before your users do.${colors.reset}`);
684
- printBlank();
685
-
686
- print(` ${colors.cyan}There are two main features:${colors.reset}`);
687
- printBlank();
688
-
689
- print(` ${icons.eye} ${colors.bright}Reality Mode${colors.reset}`);
690
- print(` Opens your app in a browser and tests it like a real`);
691
- print(` person would. It clicks buttons, fills out forms, and`);
692
- print(` looks for things that don't work right.`);
693
- printBlank();
694
-
695
- print(` ${icons.shield} ${colors.bright}Agent Firewall${colors.reset}`);
696
- print(` Watches your code as you write it (or as AI writes it)`);
697
- print(` and stops bad code from getting into your project.`);
698
- print(` Think of it like a security guard for your code.`);
699
- printBlank();
700
-
701
- print(` ${colors.dim}Both features work automatically once set up.${colors.reset}`);
702
- print(` ${colors.dim}No coding knowledge required!${colors.reset}`);
703
- printBlank();
704
-
705
- await this.prompt("Press Enter to go back...");
706
- await this.showMainMenu();
707
- }
708
-
709
- // ─────────────────────────────────────────────────────────────────────────────
710
- // HELPERS
711
- // ─────────────────────────────────────────────────────────────────────────────
712
-
713
- async checkUrl(url) {
714
- return new Promise((resolve) => {
715
- const http = url.startsWith("https") ? require("https") : require("http");
716
-
717
- const req = http.get(url, { timeout: 5000 }, (res) => {
718
- resolve(res.statusCode < 500);
719
- });
720
-
721
- req.on("error", () => resolve(false));
722
- req.on("timeout", () => {
723
- req.destroy();
724
- resolve(false);
725
- });
726
- });
727
- }
728
-
729
- async helpStartServer() {
730
- printBlank();
731
- printInfo("Let me help you start your development server...");
732
- printBlank();
733
-
734
- if (this.detectedInfo.devCommand) {
735
- print(` ${colors.dim}Your project uses ${this.detectedInfo.framework}.${colors.reset}`);
736
- print(` ${colors.dim}The typical command is: ${colors.bright}${this.detectedInfo.devCommand}${colors.reset}`);
737
- printBlank();
738
-
739
- print(` ${colors.yellow}Please open a new terminal and run:${colors.reset}`);
740
- printBlank();
741
- print(` ${colors.bright}${this.detectedInfo.devCommand}${colors.reset}`);
742
- printBlank();
743
-
744
- await this.prompt("Press Enter once your server is running...");
745
- } else {
746
- print(` ${colors.dim}I couldn't detect your start command.${colors.reset}`);
747
- print(` ${colors.dim}Please start your app manually and try again.${colors.reset}`);
748
- printBlank();
749
-
750
- await this.prompt("Press Enter once your server is running...");
751
- }
752
- }
753
-
754
- openFile(filePath) {
755
- const platform = process.platform;
756
-
757
- try {
758
- if (platform === "win32") {
759
- exec(`start "" "${filePath}"`);
760
- } else if (platform === "darwin") {
761
- exec(`open "${filePath}"`);
762
- } else {
763
- exec(`xdg-open "${filePath}"`);
764
- }
765
- } catch {
766
- printWarning(`Couldn't open file automatically. Find it at: ${filePath}`);
767
- }
768
- }
769
-
770
- exit() {
771
- printBlank();
772
- print(` ${icons.heart} ${colors.dim}Thanks for using Vibecheck!${colors.reset}`);
773
- printBlank();
774
- this.rl.close();
775
- process.exit(0);
776
- }
777
- }
778
-
779
- // ═══════════════════════════════════════════════════════════════════════════════
780
- // EXPORTS
781
- // ═══════════════════════════════════════════════════════════════════════════════
782
-
783
- module.exports = {
784
- Wizard,
785
- showWelcomeBanner,
786
- colors,
787
- icons
788
- };