@vibecheckai/cli 3.4.0 → 3.5.1

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 (228) hide show
  1. package/bin/registry.js +154 -338
  2. package/bin/runners/context/generators/mcp.js +13 -15
  3. package/bin/runners/context/proof-context.js +1 -248
  4. package/bin/runners/lib/analysis-core.js +180 -198
  5. package/bin/runners/lib/analyzers.js +223 -1669
  6. package/bin/runners/lib/cli-output.js +210 -242
  7. package/bin/runners/lib/detectors-v2.js +785 -547
  8. package/bin/runners/lib/entitlements-v2.js +458 -96
  9. package/bin/runners/lib/error-handler.js +9 -16
  10. package/bin/runners/lib/global-flags.js +0 -37
  11. package/bin/runners/lib/route-truth.js +322 -1167
  12. package/bin/runners/lib/scan-output.js +469 -448
  13. package/bin/runners/lib/ship-output.js +27 -280
  14. package/bin/runners/lib/terminal-ui.js +733 -231
  15. package/bin/runners/lib/truth.js +321 -1004
  16. package/bin/runners/lib/unified-output.js +158 -162
  17. package/bin/runners/lib/upsell.js +204 -104
  18. package/bin/runners/runAllowlist.js +324 -0
  19. package/bin/runners/runAuth.js +95 -324
  20. package/bin/runners/runCheckpoint.js +21 -39
  21. package/bin/runners/runContext.js +24 -136
  22. package/bin/runners/runDoctor.js +67 -115
  23. package/bin/runners/runEvidencePack.js +219 -0
  24. package/bin/runners/runFix.js +5 -6
  25. package/bin/runners/runGuard.js +118 -212
  26. package/bin/runners/runInit.js +2 -14
  27. package/bin/runners/runInstall.js +281 -0
  28. package/bin/runners/runLabs.js +341 -0
  29. package/bin/runners/runMcp.js +52 -130
  30. package/bin/runners/runPolish.js +20 -43
  31. package/bin/runners/runProve.js +3 -13
  32. package/bin/runners/runReality.js +0 -14
  33. package/bin/runners/runReport.js +2 -3
  34. package/bin/runners/runScan.js +44 -511
  35. package/bin/runners/runShip.js +14 -28
  36. package/bin/runners/runValidate.js +2 -19
  37. package/bin/runners/runWatch.js +54 -118
  38. package/bin/vibecheck.js +41 -148
  39. package/mcp-server/ARCHITECTURE.md +339 -0
  40. package/mcp-server/__tests__/cache.test.ts +313 -0
  41. package/mcp-server/__tests__/executor.test.ts +239 -0
  42. package/mcp-server/__tests__/fixtures/exclusion-test/.cache/webpack/cache.pack +1 -0
  43. package/mcp-server/__tests__/fixtures/exclusion-test/.next/server/chunk.js +3 -0
  44. package/mcp-server/__tests__/fixtures/exclusion-test/.turbo/cache.json +3 -0
  45. package/mcp-server/__tests__/fixtures/exclusion-test/.venv/lib/env.py +3 -0
  46. package/mcp-server/__tests__/fixtures/exclusion-test/dist/bundle.js +3 -0
  47. package/mcp-server/__tests__/fixtures/exclusion-test/package.json +5 -0
  48. package/mcp-server/__tests__/fixtures/exclusion-test/src/app.ts +5 -0
  49. package/mcp-server/__tests__/fixtures/exclusion-test/venv/lib/config.py +4 -0
  50. package/mcp-server/__tests__/ids.test.ts +345 -0
  51. package/mcp-server/__tests__/integration/tools.test.ts +410 -0
  52. package/mcp-server/__tests__/registry.test.ts +365 -0
  53. package/mcp-server/__tests__/sandbox.test.ts +323 -0
  54. package/mcp-server/__tests__/schemas.test.ts +372 -0
  55. package/mcp-server/benchmarks/run-benchmarks.ts +304 -0
  56. package/mcp-server/examples/doctor.request.json +14 -0
  57. package/mcp-server/examples/doctor.response.json +53 -0
  58. package/mcp-server/examples/error.response.json +15 -0
  59. package/mcp-server/examples/scan.request.json +14 -0
  60. package/mcp-server/examples/scan.response.json +108 -0
  61. package/mcp-server/handlers/tool-handler.ts +671 -0
  62. package/mcp-server/index-v3.ts +293 -0
  63. package/mcp-server/index.js +1072 -1573
  64. package/mcp-server/index.old.js +4137 -0
  65. package/mcp-server/lib/cache.ts +341 -0
  66. package/mcp-server/lib/errors.ts +346 -0
  67. package/mcp-server/lib/executor.ts +792 -0
  68. package/mcp-server/lib/ids.ts +238 -0
  69. package/mcp-server/lib/logger.ts +368 -0
  70. package/mcp-server/lib/metrics.ts +365 -0
  71. package/mcp-server/lib/sandbox.ts +337 -0
  72. package/mcp-server/lib/validator.ts +229 -0
  73. package/mcp-server/package-lock.json +165 -0
  74. package/mcp-server/package.json +32 -7
  75. package/mcp-server/premium-tools.js +2 -2
  76. package/mcp-server/registry/tools.json +476 -0
  77. package/mcp-server/schemas/error-envelope.schema.json +125 -0
  78. package/mcp-server/schemas/finding.schema.json +167 -0
  79. package/mcp-server/schemas/report-artifact.schema.json +88 -0
  80. package/mcp-server/schemas/run-request.schema.json +75 -0
  81. package/mcp-server/schemas/verdict.schema.json +168 -0
  82. package/mcp-server/tier-auth.d.ts +71 -0
  83. package/mcp-server/tier-auth.js +371 -183
  84. package/mcp-server/truth-context.js +90 -131
  85. package/mcp-server/truth-firewall-tools.js +1000 -1611
  86. package/mcp-server/tsconfig.json +34 -0
  87. package/mcp-server/vibecheck-tools.js +2 -2
  88. package/mcp-server/vitest.config.ts +16 -0
  89. package/package.json +3 -4
  90. package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +0 -474
  91. package/bin/runners/lib/agent-firewall/change-packet/builder.js +0 -488
  92. package/bin/runners/lib/agent-firewall/change-packet/schema.json +0 -228
  93. package/bin/runners/lib/agent-firewall/change-packet/store.js +0 -200
  94. package/bin/runners/lib/agent-firewall/claims/claim-types.js +0 -21
  95. package/bin/runners/lib/agent-firewall/claims/extractor.js +0 -303
  96. package/bin/runners/lib/agent-firewall/claims/patterns.js +0 -24
  97. package/bin/runners/lib/agent-firewall/critic/index.js +0 -151
  98. package/bin/runners/lib/agent-firewall/critic/judge.js +0 -432
  99. package/bin/runners/lib/agent-firewall/critic/prompts.js +0 -305
  100. package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +0 -88
  101. package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +0 -75
  102. package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +0 -127
  103. package/bin/runners/lib/agent-firewall/evidence/resolver.js +0 -102
  104. package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +0 -213
  105. package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +0 -145
  106. package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +0 -19
  107. package/bin/runners/lib/agent-firewall/fs-hook/installer.js +0 -87
  108. package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +0 -184
  109. package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +0 -163
  110. package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +0 -107
  111. package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +0 -68
  112. package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +0 -66
  113. package/bin/runners/lib/agent-firewall/interceptor/base.js +0 -304
  114. package/bin/runners/lib/agent-firewall/interceptor/cursor.js +0 -35
  115. package/bin/runners/lib/agent-firewall/interceptor/vscode.js +0 -35
  116. package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +0 -34
  117. package/bin/runners/lib/agent-firewall/lawbook/distributor.js +0 -465
  118. package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +0 -604
  119. package/bin/runners/lib/agent-firewall/lawbook/index.js +0 -304
  120. package/bin/runners/lib/agent-firewall/lawbook/registry.js +0 -514
  121. package/bin/runners/lib/agent-firewall/lawbook/schema.js +0 -420
  122. package/bin/runners/lib/agent-firewall/logger.js +0 -141
  123. package/bin/runners/lib/agent-firewall/policy/default-policy.json +0 -90
  124. package/bin/runners/lib/agent-firewall/policy/engine.js +0 -103
  125. package/bin/runners/lib/agent-firewall/policy/loader.js +0 -451
  126. package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +0 -50
  127. package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +0 -50
  128. package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +0 -86
  129. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +0 -162
  130. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +0 -189
  131. package/bin/runners/lib/agent-firewall/policy/rules/scope.js +0 -93
  132. package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +0 -57
  133. package/bin/runners/lib/agent-firewall/policy/schema.json +0 -183
  134. package/bin/runners/lib/agent-firewall/policy/verdict.js +0 -54
  135. package/bin/runners/lib/agent-firewall/proposal/extractor.js +0 -394
  136. package/bin/runners/lib/agent-firewall/proposal/index.js +0 -212
  137. package/bin/runners/lib/agent-firewall/proposal/schema.js +0 -251
  138. package/bin/runners/lib/agent-firewall/proposal/validator.js +0 -386
  139. package/bin/runners/lib/agent-firewall/reality/index.js +0 -332
  140. package/bin/runners/lib/agent-firewall/reality/state.js +0 -625
  141. package/bin/runners/lib/agent-firewall/reality/watcher.js +0 -322
  142. package/bin/runners/lib/agent-firewall/risk/index.js +0 -173
  143. package/bin/runners/lib/agent-firewall/risk/scorer.js +0 -328
  144. package/bin/runners/lib/agent-firewall/risk/thresholds.js +0 -321
  145. package/bin/runners/lib/agent-firewall/risk/vectors.js +0 -421
  146. package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +0 -472
  147. package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +0 -346
  148. package/bin/runners/lib/agent-firewall/simulator/index.js +0 -181
  149. package/bin/runners/lib/agent-firewall/simulator/route-validator.js +0 -380
  150. package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +0 -661
  151. package/bin/runners/lib/agent-firewall/time-machine/index.js +0 -267
  152. package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +0 -436
  153. package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +0 -490
  154. package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +0 -530
  155. package/bin/runners/lib/agent-firewall/truthpack/index.js +0 -67
  156. package/bin/runners/lib/agent-firewall/truthpack/loader.js +0 -137
  157. package/bin/runners/lib/agent-firewall/unblock/planner.js +0 -337
  158. package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +0 -118
  159. package/bin/runners/lib/api-client.js +0 -269
  160. package/bin/runners/lib/authority-badge.js +0 -425
  161. package/bin/runners/lib/engines/accessibility-engine.js +0 -190
  162. package/bin/runners/lib/engines/api-consistency-engine.js +0 -162
  163. package/bin/runners/lib/engines/ast-cache.js +0 -99
  164. package/bin/runners/lib/engines/code-quality-engine.js +0 -255
  165. package/bin/runners/lib/engines/console-logs-engine.js +0 -115
  166. package/bin/runners/lib/engines/cross-file-analysis-engine.js +0 -268
  167. package/bin/runners/lib/engines/dead-code-engine.js +0 -198
  168. package/bin/runners/lib/engines/deprecated-api-engine.js +0 -226
  169. package/bin/runners/lib/engines/empty-catch-engine.js +0 -150
  170. package/bin/runners/lib/engines/file-filter.js +0 -131
  171. package/bin/runners/lib/engines/hardcoded-secrets-engine.js +0 -251
  172. package/bin/runners/lib/engines/mock-data-engine.js +0 -272
  173. package/bin/runners/lib/engines/parallel-processor.js +0 -71
  174. package/bin/runners/lib/engines/performance-issues-engine.js +0 -265
  175. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +0 -243
  176. package/bin/runners/lib/engines/todo-fixme-engine.js +0 -115
  177. package/bin/runners/lib/engines/type-aware-engine.js +0 -152
  178. package/bin/runners/lib/engines/unsafe-regex-engine.js +0 -225
  179. package/bin/runners/lib/engines/vibecheck-engines/README.md +0 -53
  180. package/bin/runners/lib/engines/vibecheck-engines/index.js +0 -15
  181. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +0 -164
  182. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +0 -291
  183. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +0 -83
  184. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +0 -198
  185. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +0 -275
  186. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +0 -167
  187. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +0 -217
  188. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +0 -139
  189. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +0 -140
  190. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +0 -164
  191. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +0 -234
  192. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +0 -217
  193. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +0 -78
  194. package/bin/runners/lib/engines/vibecheck-engines/package.json +0 -13
  195. package/bin/runners/lib/exit-codes.js +0 -275
  196. package/bin/runners/lib/fingerprint.js +0 -377
  197. package/bin/runners/lib/help-formatter.js +0 -413
  198. package/bin/runners/lib/logger.js +0 -38
  199. package/bin/runners/lib/ship-output-enterprise.js +0 -239
  200. package/bin/runners/lib/unified-cli-output.js +0 -604
  201. package/bin/runners/runAgent.d.ts +0 -5
  202. package/bin/runners/runAgent.js +0 -161
  203. package/bin/runners/runApprove.js +0 -1200
  204. package/bin/runners/runClassify.js +0 -859
  205. package/bin/runners/runContext.d.ts +0 -4
  206. package/bin/runners/runFirewall.d.ts +0 -5
  207. package/bin/runners/runFirewall.js +0 -134
  208. package/bin/runners/runFirewallHook.d.ts +0 -5
  209. package/bin/runners/runFirewallHook.js +0 -56
  210. package/bin/runners/runPolish.d.ts +0 -4
  211. package/bin/runners/runProof.zip +0 -0
  212. package/bin/runners/runTruth.d.ts +0 -5
  213. package/bin/runners/runTruth.js +0 -101
  214. package/mcp-server/HARDENING_SUMMARY.md +0 -299
  215. package/mcp-server/agent-firewall-interceptor.js +0 -500
  216. package/mcp-server/authority-tools.js +0 -569
  217. package/mcp-server/conductor/conflict-resolver.js +0 -588
  218. package/mcp-server/conductor/execution-planner.js +0 -544
  219. package/mcp-server/conductor/index.js +0 -377
  220. package/mcp-server/conductor/lock-manager.js +0 -615
  221. package/mcp-server/conductor/request-queue.js +0 -550
  222. package/mcp-server/conductor/session-manager.js +0 -500
  223. package/mcp-server/conductor/tools.js +0 -510
  224. package/mcp-server/lib/api-client.cjs +0 -13
  225. package/mcp-server/lib/logger.cjs +0 -30
  226. package/mcp-server/logger.js +0 -173
  227. package/mcp-server/tools-v3.js +0 -706
  228. package/mcp-server/vibecheck-mcp-server-3.2.0.tgz +0 -0
@@ -316,15 +316,11 @@ function renderFindingsBreakdown(findings) {
316
316
  // BLOCKER DETAILS
317
317
  // ═══════════════════════════════════════════════════════════════════════════════
318
318
 
319
- function renderBlockerDetails(findings, maxShow = 8, options = {}) {
320
- const { tier = 'free' } = options;
319
+ function renderBlockerDetails(findings, maxShow = 8) {
321
320
  const blockers = findings.filter(f => f.severity === 'BLOCK' || f.severity === 'critical');
322
321
 
323
322
  if (blockers.length === 0) return '';
324
323
 
325
- // Fix hints are PRO only (2-tier model)
326
- const canShowFixHints = tier === 'pro' || tier === 'compliance' || tier === 'starter'; // starter=legacy compatibility
327
-
328
324
  const lines = [];
329
325
  lines.push(renderSection(`BLOCKERS (${blockers.length})`, '🚨'));
330
326
  lines.push('');
@@ -333,22 +329,12 @@ function renderBlockerDetails(findings, maxShow = 8, options = {}) {
333
329
  const icon = getCategoryIcon(blocker.category);
334
330
  const severityBg = ansi.bgRgb(80, 20, 20);
335
331
 
336
- // Check if this is a common AI hallucination pattern
337
- const isAIPattern = AI_HALLUCINATION_CATEGORIES[blocker.category];
338
- const aiTag = isAIPattern ? `${ansi.bgRgb(60, 40, 80)}${ansi.bold} 🤖 AI ${ansi.reset} ` : '';
339
-
340
- // Severity badge + AI tag + title
341
- lines.push(` ${severityBg}${ansi.bold} BLOCKER ${ansi.reset} ${aiTag}${icon} ${ansi.bold}${truncate(blocker.title || blocker.message, 45)}${ansi.reset}`);
332
+ // Severity badge + title
333
+ lines.push(` ${severityBg}${ansi.bold} BLOCKER ${ansi.reset} ${icon} ${ansi.bold}${truncate(blocker.title || blocker.message, 50)}${ansi.reset}`);
342
334
 
343
- // Why/description - emphasize AI-specific messaging
335
+ // Why/description
344
336
  if (blocker.why || blocker.description) {
345
- const desc = blocker.why || blocker.description;
346
- lines.push(` ${ansi.dim}${truncate(desc, 55)}${ansi.reset}`);
347
- }
348
-
349
- // AI-specific warning for known patterns
350
- if (isAIPattern) {
351
- lines.push(` ${colors.warning}⚠ ${isAIPattern.desc}${ansi.reset}`);
337
+ lines.push(` ${ansi.dim}${truncate(blocker.why || blocker.description, 55)}${ansi.reset}`);
352
338
  }
353
339
 
354
340
  // File location
@@ -364,16 +350,11 @@ function renderBlockerDetails(findings, maxShow = 8, options = {}) {
364
350
  lines.push(` ${colors.accent}${shipIcons.doc} ${fileDisplay}${ansi.reset}`);
365
351
  }
366
352
 
367
- // Fix hint - STARTER+ only, show locked message for FREE
368
- if (canShowFixHints) {
369
- if (blocker.fixHints && blocker.fixHints.length > 0) {
370
- lines.push(` ${colors.success} ${truncate(blocker.fixHints[0], 50)}${ansi.reset}`);
371
- } else if (blocker.fix) {
372
- lines.push(` ${colors.success}→ ${truncate(blocker.fix, 50)}${ansi.reset}`);
373
- }
374
- } else {
375
- // Show locked fix hint for FREE tier
376
- lines.push(` ${ansi.dim}🔒 Fix hints available with PRO ($69/mo)${ansi.reset}`);
353
+ // Fix hint
354
+ if (blocker.fixHints && blocker.fixHints.length > 0) {
355
+ lines.push(` ${colors.success}→ ${truncate(blocker.fixHints[0], 50)}${ansi.reset}`);
356
+ } else if (blocker.fix) {
357
+ lines.push(` ${colors.success} ${truncate(blocker.fix, 50)}${ansi.reset}`);
377
358
  }
378
359
 
379
360
  lines.push('');
@@ -384,16 +365,6 @@ function renderBlockerDetails(findings, maxShow = 8, options = {}) {
384
365
  lines.push('');
385
366
  }
386
367
 
387
- // Show upsell for fix hints if FREE tier
388
- if (!canShowFixHints && blockers.length > 0) {
389
- lines.push(` ${ansi.dim}─────────────────────────────────────────${ansi.reset}`);
390
- lines.push(` ${colors.accent}💡${ansi.reset} ${ansi.bold}Unlock AI fix suggestions${ansi.reset}`);
391
- lines.push(` ${ansi.dim}PRO users get specific fix hints and${ansi.reset}`);
392
- lines.push(` ${ansi.dim}AI mission prompts for every issue.${ansi.reset}`);
393
- lines.push(` ${colors.accent}Upgrade to PRO ($69/mo)${ansi.reset} ${ansi.dim}→ vibecheckai.dev/pricing${ansi.reset}`);
394
- lines.push('');
395
- }
396
-
397
368
  return lines.join('\n');
398
369
  }
399
370
 
@@ -453,37 +424,22 @@ function renderFixResults(fixResults) {
453
424
  // BADGE OUTPUT
454
425
  // ═══════════════════════════════════════════════════════════════════════════════
455
426
 
456
- function renderBadgeOutput(projectPath, verdict, score, options = {}) {
457
- const { tier = 'free', isVerified = false } = options;
427
+ function renderBadgeOutput(projectPath, verdict, score) {
458
428
  const projectName = path.basename(projectPath);
459
429
  const projectId = projectName.toLowerCase().replace(/[^a-z0-9]/g, '-');
460
430
 
461
431
  const config = getVerdictConfig(verdict, score);
462
- const isPro = tier === 'pro' || tier === 'compliance';
463
432
 
464
433
  const lines = [];
465
-
466
- // Different header for verified vs basic badge
467
- if (isPro && isVerified) {
468
- lines.push(renderSection('VERIFIED BADGE', '✅'));
469
- lines.push('');
470
- lines.push(` ${ansi.bgRgb(40, 100, 60)}${ansi.bold} ✅ VERIFIED ${ansi.reset} ${ansi.dim}Reality-tested by AI${ansi.reset}`);
471
- lines.push('');
472
- } else {
473
- lines.push(renderSection('SHIP BADGE', '📛'));
474
- lines.push('');
475
- }
434
+ lines.push(renderSection('SHIP BADGE', '📛'));
435
+ lines.push('');
476
436
 
477
437
  // Badge preview
478
- const badgeText = isPro && isVerified
479
- ? `vibecheck | ✅ VERIFIED | ${score}`
480
- : `vibecheck | ${verdict} | ${score}`;
438
+ const badgeText = `vibecheck | ${verdict} | ${score}`;
481
439
  lines.push(` ${config.bgColor}${ansi.bold} ${badgeText} ${ansi.reset}`);
482
440
  lines.push('');
483
441
 
484
- // Different URLs for verified vs basic badge
485
- const badgeSuffix = (isPro && isVerified) ? '-verified' : '';
486
- const badgeUrl = `https://vibecheck.dev/badge/${projectId}${badgeSuffix}.svg`;
442
+ const badgeUrl = `https://vibecheck.dev/badge/${projectId}.svg`;
487
443
  const reportUrl = `https://vibecheck.dev/report/${projectId}`;
488
444
  const markdown = `[![Vibecheck](${badgeUrl})](${reportUrl})`;
489
445
 
@@ -496,19 +452,9 @@ function renderBadgeOutput(projectPath, verdict, score, options = {}) {
496
452
  lines.push(` ${ansi.dim}Add to README.md:${ansi.reset}`);
497
453
  lines.push(` ${colors.success}${markdown}${ansi.reset}`);
498
454
 
499
- // Show verified badge upsell if not PRO
500
- if (!isPro) {
501
- lines.push('');
502
- lines.push(` ${ansi.dim}─────────────────────────────────────────${ansi.reset}`);
503
- lines.push(` ${colors.accent}✨${ansi.reset} ${ansi.bold}Want a verified badge?${ansi.reset}`);
504
- lines.push(` ${ansi.dim}PRO users get a${ansi.reset} ${ansi.bgRgb(40, 100, 60)}${ansi.bold} ✅ VERIFIED ${ansi.reset} ${ansi.dim}badge${ansi.reset}`);
505
- lines.push(` ${ansi.dim}proving your app was reality-tested by AI.${ansi.reset}`);
506
- lines.push(` ${colors.accent}vibecheck login${ansi.reset} ${ansi.dim}to upgrade${ansi.reset}`);
507
- }
508
-
509
455
  return {
510
456
  output: lines.join('\n'),
511
- data: { projectId, badgeUrl, reportUrl, markdown, isVerified: isPro && isVerified },
457
+ data: { projectId, badgeUrl, reportUrl, markdown },
512
458
  };
513
459
  }
514
460
 
@@ -516,45 +462,10 @@ function renderBadgeOutput(projectPath, verdict, score, options = {}) {
516
462
  // NEXT STEPS
517
463
  // ═══════════════════════════════════════════════════════════════════════════════
518
464
 
519
- function renderNextSteps(canShip, hasFix = false, options = {}) {
520
- const { tier = 'free', showBadge = false } = options;
521
- const isPro = tier === 'pro' || tier === 'compliance';
465
+ function renderNextSteps(canShip, hasFix = false) {
466
+ if (canShip) return '';
522
467
 
523
468
  const lines = [];
524
-
525
- // If codebase PASSED - show celebration and PRO upsell for verified badge
526
- if (canShip) {
527
- lines.push('');
528
- lines.push(renderSection('WHAT\'S NEXT?', shipIcons.sparkle));
529
- lines.push('');
530
- lines.push(` ${colors.success}${icons.success}${ansi.reset} ${ansi.bold}Congratulations! Your code is ship-ready.${ansi.reset}`);
531
- lines.push('');
532
-
533
- if (!isPro) {
534
- // Upsell PRO for verified badge
535
- lines.push(` ${ansi.dim}─────────────────────────────────────────${ansi.reset}`);
536
- lines.push(` ${colors.accent}🏆${ansi.reset} ${ansi.bold}Prove it to the world!${ansi.reset}`);
537
- lines.push('');
538
- lines.push(` ${ansi.dim}Upgrade to${ansi.reset} ${colors.accent}PRO${ansi.reset} ${ansi.dim}for a${ansi.reset} ${ansi.bgRgb(40, 100, 60)}${ansi.bold} ✅ VERIFIED ${ansi.reset} ${ansi.dim}badge${ansi.reset}`);
539
- lines.push('');
540
- lines.push(` ${ansi.dim}The verified badge proves:${ansi.reset}`);
541
- lines.push(` ${colors.success}→${ansi.reset} AI reality-tested your app's actual behavior`);
542
- lines.push(` ${colors.success}→${ansi.reset} Video proof of working features`);
543
- lines.push(` ${colors.success}→${ansi.reset} Automated auth boundary verification`);
544
- lines.push('');
545
- lines.push(` ${colors.accent}vibecheck login${ansi.reset} ${ansi.dim}to start your PRO trial${ansi.reset}`);
546
- lines.push('');
547
- } else if (!showBadge) {
548
- // PRO user who passed - prompt them to generate badge
549
- lines.push(` ${colors.accent}vibecheck ship --badge${ansi.reset} ${ansi.dim}Generate your verified badge${ansi.reset}`);
550
- lines.push(` ${colors.accent}vibecheck prove${ansi.reset} ${ansi.dim}Create video proof of working features${ansi.reset}`);
551
- lines.push('');
552
- }
553
-
554
- return lines.join('\n');
555
- }
556
-
557
- // If codebase FAILED - show next steps to fix
558
469
  lines.push(renderSection('NEXT STEPS', shipIcons.lightning));
559
470
  lines.push('');
560
471
 
@@ -585,151 +496,12 @@ function renderReportLinks(outputDir, hasFix = false) {
585
496
  return lines.join('\n');
586
497
  }
587
498
 
588
- // ═══════════════════════════════════════════════════════════════════════════════
589
- // AI HALLUCINATION SCORE - Key metric for detecting AI-generated issues
590
- // ═══════════════════════════════════════════════════════════════════════════════
591
-
592
- // Categories that indicate common AI hallucination patterns
593
- const AI_HALLUCINATION_CATEGORIES = {
594
- 'MissingRoute': { weight: 25, label: 'Invented endpoints', desc: 'AI created API routes that don\'t exist' },
595
- 'FakeSuccess': { weight: 20, label: 'Fake success UI', desc: 'Shows success without verifying the operation' },
596
- 'GhostAuth': { weight: 15, label: 'Missing auth', desc: 'Sensitive endpoints without protection' },
597
- 'EnvGap': { weight: 10, label: 'Undefined env vars', desc: 'Uses environment variables that don\'t exist' },
598
- 'DeadUI': { weight: 10, label: 'Dead UI elements', desc: 'Buttons/forms that do nothing' },
599
- 'OwnerModeBypass': { weight: 15, label: 'Backdoor access', desc: 'Production security bypasses' },
600
- 'PaidSurface': { weight: 5, label: 'Billing bypass', desc: 'Paid features without enforcement' },
601
- };
602
-
603
- function calculateAIHallucinationScore(findings) {
604
- if (!findings || findings.length === 0) return { score: 100, breakdown: [], totalIssues: 0 };
605
-
606
- const breakdown = [];
607
- let deductions = 0;
608
-
609
- for (const [category, config] of Object.entries(AI_HALLUCINATION_CATEGORIES)) {
610
- const categoryFindings = findings.filter(f => f.category === category);
611
- const blockers = categoryFindings.filter(f => f.severity === 'BLOCK' || f.severity === 'critical');
612
- const warnings = categoryFindings.filter(f => f.severity === 'WARN' || f.severity === 'warning');
613
-
614
- if (categoryFindings.length > 0) {
615
- // Blockers count more than warnings
616
- const blockerDeduction = blockers.length * config.weight;
617
- const warningDeduction = warnings.length * Math.floor(config.weight / 2);
618
- const totalDeduction = blockerDeduction + warningDeduction;
619
-
620
- deductions += totalDeduction;
621
- breakdown.push({
622
- category,
623
- label: config.label,
624
- desc: config.desc,
625
- count: categoryFindings.length,
626
- blockers: blockers.length,
627
- warnings: warnings.length,
628
- deduction: totalDeduction,
629
- });
630
- }
631
- }
632
-
633
- // Cap at 0
634
- const score = Math.max(0, 100 - deductions);
635
-
636
- return {
637
- score,
638
- breakdown: breakdown.sort((a, b) => b.deduction - a.deduction),
639
- totalIssues: findings.length,
640
- };
641
- }
642
-
643
- function renderAIHallucinationScore(findings) {
644
- const { score, breakdown, totalIssues } = calculateAIHallucinationScore(findings);
645
-
646
- const lines = [];
647
- lines.push('');
648
- lines.push(renderSection('AI REALITY CHECK', '🤖'));
649
- lines.push('');
650
-
651
- // Score display with color coding
652
- const scoreColor = score >= 80 ? colors.success : score >= 50 ? colors.warning : colors.error;
653
- const scoreLabel = score >= 80 ? 'Low Risk' : score >= 50 ? 'Medium Risk' : 'High Risk';
654
-
655
- // Visual score bar
656
- lines.push(` ${ansi.bold}AI Hallucination Risk${ansi.reset}`);
657
- lines.push(` ${renderProgressBar(100 - score, 40, scoreColor)} ${scoreColor}${ansi.bold}${100 - score}%${ansi.reset} risk`);
658
- lines.push('');
659
-
660
- if (breakdown.length === 0) {
661
- lines.push(` ${colors.success}${icons.success}${ansi.reset} ${ansi.bold}No AI hallucination patterns detected!${ansi.reset}`);
662
- lines.push(` ${ansi.dim}Your code appears to be grounded in reality.${ansi.reset}`);
663
- } else {
664
- lines.push(` ${ansi.dim}Common AI mistakes found:${ansi.reset}`);
665
- lines.push('');
666
-
667
- for (const item of breakdown.slice(0, 5)) {
668
- const itemColor = item.blockers > 0 ? colors.error : colors.warning;
669
- const severityBadge = item.blockers > 0
670
- ? `${colors.error}${ansi.bold}${item.blockers} BLOCK${ansi.reset}`
671
- : `${colors.warning}${item.warnings} warn${ansi.reset}`;
672
-
673
- lines.push(` ${itemColor}•${ansi.reset} ${ansi.bold}${item.label}${ansi.reset} ${ansi.dim}(${item.count})${ansi.reset} ${severityBadge}`);
674
- lines.push(` ${ansi.dim}${item.desc}${ansi.reset}`);
675
- }
676
-
677
- if (breakdown.length > 5) {
678
- lines.push(` ${ansi.dim}... and ${breakdown.length - 5} more categories${ansi.reset}`);
679
- }
680
- }
681
-
682
- lines.push('');
683
- return lines.join('\n');
684
- }
685
-
686
- // ═══════════════════════════════════════════════════════════════════════════════
687
- // UPGRADE PROMPTS - Show FREE users what they're missing
688
- // ═══════════════════════════════════════════════════════════════════════════════
689
-
690
- function renderUpgradePrompts(findings, verdict) {
691
- const lines = [];
692
-
693
- // Only show if there are issues to fix
694
- if (!findings || findings.length === 0) return '';
695
-
696
- const blockers = findings.filter(f => f.severity === 'BLOCK' || f.severity === 'critical');
697
- const fixableCount = findings.length;
698
-
699
- lines.push('');
700
- lines.push(` ${ansi.dim}${'─'.repeat(60)}${ansi.reset}`);
701
- lines.push('');
702
- lines.push(` ${colors.accent}⚡${ansi.reset} ${ansi.bold}Want to fix these automatically?${ansi.reset}`);
703
- lines.push('');
704
-
705
- // PRO tier benefits (2-tier: FREE / PRO)
706
- lines.push(` ${colors.accent}PRO${ansi.reset} ${ansi.dim}($69/mo)${ansi.reset}`);
707
- lines.push(` ${colors.success}→${ansi.reset} ${ansi.bold}vibecheck fix${ansi.reset} - AI auto-fix for ${fixableCount} issues`);
708
- lines.push(` ${colors.success}→${ansi.reset} ${ansi.bold}vibecheck ship${ansi.reset} - GO/NO-GO verdicts with proof`);
709
- lines.push(` ${colors.success}→${ansi.reset} ${ansi.bold}vibecheck prove${ansi.reset} - Video proof your app actually works`);
710
- lines.push(` ${colors.success}→${ansi.reset} ${ansi.bold}vibecheck reality --agent${ansi.reset} - AI tests your app autonomously`);
711
- lines.push('');
712
-
713
- lines.push(` ${ansi.dim}Upgrade: ${colors.accent}vibecheckai.dev/pricing${ansi.reset}`);
714
- lines.push('');
715
-
716
- return lines.join('\n');
717
- }
718
-
719
499
  // ═══════════════════════════════════════════════════════════════════════════════
720
500
  // FULL SHIP OUTPUT
721
501
  // ═══════════════════════════════════════════════════════════════════════════════
722
502
 
723
503
  function formatShipOutput(result, options = {}) {
724
- const {
725
- verbose = false,
726
- showFix = false,
727
- showBadge = false,
728
- outputDir = '.vibecheck',
729
- projectPath = '.',
730
- tier = 'free', // User's current tier
731
- isVerified = false, // Whether reality testing was done (for verified badge)
732
- } = options;
504
+ const { verbose = false, showFix = false, showBadge = false, outputDir = '.vibecheck', projectPath = '.' } = options;
733
505
 
734
506
  const {
735
507
  verdict,
@@ -744,10 +516,6 @@ function formatShipOutput(result, options = {}) {
744
516
  cached = false,
745
517
  } = result;
746
518
 
747
- const isPro = tier === 'pro' || tier === 'compliance' || tier === 'starter'; // starter=legacy compat
748
- const isProTier = isPro; // 2-tier model: isPro covers all paid tiers
749
- const canShip = verdict === 'SHIP';
750
-
751
519
  const lines = [];
752
520
 
753
521
  // Verdict card (hero moment)
@@ -760,19 +528,11 @@ function formatShipOutput(result, options = {}) {
760
528
  cached,
761
529
  }));
762
530
 
763
- // AI Hallucination Score (always show - this is a key selling point)
764
- lines.push(renderAIHallucinationScore(findings));
765
-
766
531
  // Findings breakdown
767
532
  lines.push(renderFindingsBreakdown(findings));
768
533
 
769
- // Blocker details (with AI attribution, tier-gated fix hints)
770
- lines.push(renderBlockerDetails(findings, 8, { tier }));
771
-
772
- // Upgrade prompts for FREE tier users (if there are fixable issues)
773
- if (findings.length > 0 && !isProTier) {
774
- lines.push(renderUpgradePrompts(findings, verdict));
775
- }
534
+ // Blocker details
535
+ lines.push(renderBlockerDetails(findings));
776
536
 
777
537
  // Verbose: Route truth map
778
538
  if (verbose && truthpack) {
@@ -791,25 +551,18 @@ function formatShipOutput(result, options = {}) {
791
551
  lines.push(renderFixResults(fixResults));
792
552
  }
793
553
 
794
- // Badge (if requested and tier allows)
795
- if (showBadge && isProTier) {
796
- const badgeResult = renderBadgeOutput(projectPath, verdict, score, { tier, isVerified });
554
+ // Badge (if requested)
555
+ if (showBadge) {
556
+ const badgeResult = renderBadgeOutput(projectPath, verdict, score);
797
557
  lines.push(badgeResult.output);
798
- } else if (showBadge && !isProTier) {
799
- // Show badge upsell for FREE users
800
- lines.push('');
801
- lines.push(renderSection('BADGE', '📛'));
802
- lines.push('');
803
- lines.push(` ${ansi.dim}🔒 Ship badges require PRO ($69/mo)${ansi.reset}`);
804
- lines.push(` ${colors.accent}vibecheckai.dev/pricing${ansi.reset} ${ansi.dim}to upgrade${ansi.reset}`);
805
- lines.push('');
806
558
  }
807
559
 
808
560
  // Report links
809
561
  lines.push(renderReportLinks(outputDir, showFix));
810
562
 
811
- // Next steps (shows PRO upsell for verified badge if SHIP passed)
812
- lines.push(renderNextSteps(canShip, showFix, { tier, showBadge }));
563
+ // Next steps (if not shipping)
564
+ const canShip = verdict === 'SHIP';
565
+ lines.push(renderNextSteps(canShip, showFix));
813
566
 
814
567
  return lines.filter(Boolean).join('\n');
815
568
  }
@@ -875,12 +628,6 @@ module.exports = {
875
628
  renderBadgeOutput,
876
629
  renderNextSteps,
877
630
  renderReportLinks,
878
- renderAIHallucinationScore,
879
- renderUpgradePrompts,
880
-
881
- // AI Hallucination scoring
882
- calculateAIHallucinationScore,
883
- AI_HALLUCINATION_CATEGORIES,
884
631
 
885
632
  // Utilities
886
633
  getVerdictConfig,