@vibecheckai/cli 3.5.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 (326) hide show
  1. package/bin/registry.js +174 -449
  2. package/bin/runners/cli-utils.js +33 -2
  3. package/bin/runners/context/generators/cursor.js +2 -49
  4. package/bin/runners/context/generators/mcp.js +13 -15
  5. package/bin/runners/context/proof-context.js +1 -248
  6. package/bin/runners/lib/analysis-core.js +180 -198
  7. package/bin/runners/lib/analyzers.js +241 -2212
  8. package/bin/runners/lib/cli-output.js +210 -242
  9. package/bin/runners/lib/detectors-v2.js +785 -547
  10. package/bin/runners/lib/entitlements-v2.js +431 -161
  11. package/bin/runners/lib/error-handler.js +9 -16
  12. package/bin/runners/lib/global-flags.js +0 -37
  13. package/bin/runners/lib/html-proof-report.js +700 -350
  14. package/bin/runners/lib/missions/plan.js +6 -46
  15. package/bin/runners/lib/missions/templates.js +0 -232
  16. package/bin/runners/lib/route-truth.js +322 -1167
  17. package/bin/runners/lib/scan-output.js +467 -493
  18. package/bin/runners/lib/ship-output.js +27 -280
  19. package/bin/runners/lib/terminal-ui.js +700 -310
  20. package/bin/runners/lib/truth.js +321 -1004
  21. package/bin/runners/lib/unified-output.js +158 -162
  22. package/bin/runners/lib/upsell.js +204 -104
  23. package/bin/runners/runAIAgent.js +10 -5
  24. package/bin/runners/runAllowlist.js +324 -0
  25. package/bin/runners/runAuth.js +94 -344
  26. package/bin/runners/runCheckpoint.js +45 -43
  27. package/bin/runners/runContext.js +24 -139
  28. package/bin/runners/runDoctor.js +101 -136
  29. package/bin/runners/runEvidencePack.js +219 -0
  30. package/bin/runners/runFix.js +71 -82
  31. package/bin/runners/runGuard.js +119 -606
  32. package/bin/runners/runInit.js +60 -22
  33. package/bin/runners/runInstall.js +281 -0
  34. package/bin/runners/runLabs.js +341 -0
  35. package/bin/runners/runMcp.js +62 -139
  36. package/bin/runners/runPolish.js +83 -282
  37. package/bin/runners/runPromptFirewall.js +12 -5
  38. package/bin/runners/runProve.js +58 -33
  39. package/bin/runners/runReality.js +58 -81
  40. package/bin/runners/runReport.js +7 -34
  41. package/bin/runners/runRuntime.js +8 -5
  42. package/bin/runners/runScan.js +844 -219
  43. package/bin/runners/runShip.js +59 -721
  44. package/bin/runners/runValidate.js +11 -24
  45. package/bin/runners/runWatch.js +76 -131
  46. package/bin/vibecheck.js +69 -295
  47. package/mcp-server/ARCHITECTURE.md +339 -0
  48. package/mcp-server/__tests__/cache.test.ts +313 -0
  49. package/mcp-server/__tests__/executor.test.ts +239 -0
  50. package/mcp-server/__tests__/fixtures/exclusion-test/.cache/webpack/cache.pack +1 -0
  51. package/mcp-server/__tests__/fixtures/exclusion-test/.next/server/chunk.js +3 -0
  52. package/mcp-server/__tests__/fixtures/exclusion-test/.turbo/cache.json +3 -0
  53. package/mcp-server/__tests__/fixtures/exclusion-test/.venv/lib/env.py +3 -0
  54. package/mcp-server/__tests__/fixtures/exclusion-test/dist/bundle.js +3 -0
  55. package/mcp-server/__tests__/fixtures/exclusion-test/package.json +5 -0
  56. package/mcp-server/__tests__/fixtures/exclusion-test/src/app.ts +5 -0
  57. package/mcp-server/__tests__/fixtures/exclusion-test/venv/lib/config.py +4 -0
  58. package/mcp-server/__tests__/ids.test.ts +345 -0
  59. package/mcp-server/__tests__/integration/tools.test.ts +410 -0
  60. package/mcp-server/__tests__/registry.test.ts +365 -0
  61. package/mcp-server/__tests__/sandbox.test.ts +323 -0
  62. package/mcp-server/__tests__/schemas.test.ts +372 -0
  63. package/mcp-server/benchmarks/run-benchmarks.ts +304 -0
  64. package/mcp-server/examples/doctor.request.json +14 -0
  65. package/mcp-server/examples/doctor.response.json +53 -0
  66. package/mcp-server/examples/error.response.json +15 -0
  67. package/mcp-server/examples/scan.request.json +14 -0
  68. package/mcp-server/examples/scan.response.json +108 -0
  69. package/mcp-server/handlers/tool-handler.ts +671 -0
  70. package/mcp-server/index-v1.js +698 -0
  71. package/mcp-server/index-v3.ts +293 -0
  72. package/mcp-server/index.js +1080 -1757
  73. package/mcp-server/index.old.js +4137 -0
  74. package/mcp-server/lib/cache.ts +341 -0
  75. package/mcp-server/lib/errors.ts +346 -0
  76. package/mcp-server/lib/executor.ts +792 -0
  77. package/mcp-server/lib/ids.ts +238 -0
  78. package/mcp-server/lib/logger.ts +368 -0
  79. package/mcp-server/lib/metrics.ts +365 -0
  80. package/mcp-server/lib/sandbox.ts +337 -0
  81. package/mcp-server/lib/validator.ts +229 -0
  82. package/mcp-server/package-lock.json +165 -0
  83. package/mcp-server/package.json +32 -7
  84. package/mcp-server/premium-tools.js +2 -2
  85. package/mcp-server/registry/tools.json +476 -0
  86. package/mcp-server/schemas/error-envelope.schema.json +125 -0
  87. package/mcp-server/schemas/finding.schema.json +167 -0
  88. package/mcp-server/schemas/report-artifact.schema.json +88 -0
  89. package/mcp-server/schemas/run-request.schema.json +75 -0
  90. package/mcp-server/schemas/verdict.schema.json +168 -0
  91. package/mcp-server/tier-auth.d.ts +71 -0
  92. package/mcp-server/tier-auth.js +371 -183
  93. package/mcp-server/truth-context.js +90 -131
  94. package/mcp-server/truth-firewall-tools.js +1000 -1611
  95. package/mcp-server/tsconfig.json +34 -0
  96. package/mcp-server/vibecheck-tools.js +2 -2
  97. package/mcp-server/vitest.config.ts +16 -0
  98. package/package.json +3 -4
  99. package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +0 -474
  100. package/bin/runners/lib/agent-firewall/change-packet/builder.js +0 -488
  101. package/bin/runners/lib/agent-firewall/change-packet/schema.json +0 -228
  102. package/bin/runners/lib/agent-firewall/change-packet/store.js +0 -200
  103. package/bin/runners/lib/agent-firewall/claims/claim-types.js +0 -21
  104. package/bin/runners/lib/agent-firewall/claims/extractor.js +0 -303
  105. package/bin/runners/lib/agent-firewall/claims/patterns.js +0 -24
  106. package/bin/runners/lib/agent-firewall/critic/index.js +0 -151
  107. package/bin/runners/lib/agent-firewall/critic/judge.js +0 -432
  108. package/bin/runners/lib/agent-firewall/critic/prompts.js +0 -305
  109. package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +0 -88
  110. package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +0 -75
  111. package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +0 -127
  112. package/bin/runners/lib/agent-firewall/evidence/resolver.js +0 -102
  113. package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +0 -213
  114. package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +0 -145
  115. package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +0 -19
  116. package/bin/runners/lib/agent-firewall/fs-hook/installer.js +0 -87
  117. package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +0 -184
  118. package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +0 -163
  119. package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +0 -107
  120. package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +0 -68
  121. package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +0 -66
  122. package/bin/runners/lib/agent-firewall/interceptor/base.js +0 -304
  123. package/bin/runners/lib/agent-firewall/interceptor/cursor.js +0 -35
  124. package/bin/runners/lib/agent-firewall/interceptor/vscode.js +0 -35
  125. package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +0 -34
  126. package/bin/runners/lib/agent-firewall/lawbook/distributor.js +0 -465
  127. package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +0 -604
  128. package/bin/runners/lib/agent-firewall/lawbook/index.js +0 -304
  129. package/bin/runners/lib/agent-firewall/lawbook/registry.js +0 -514
  130. package/bin/runners/lib/agent-firewall/lawbook/schema.js +0 -420
  131. package/bin/runners/lib/agent-firewall/learning/learning-engine.js +0 -849
  132. package/bin/runners/lib/agent-firewall/logger.js +0 -141
  133. package/bin/runners/lib/agent-firewall/policy/default-policy.json +0 -90
  134. package/bin/runners/lib/agent-firewall/policy/engine.js +0 -103
  135. package/bin/runners/lib/agent-firewall/policy/loader.js +0 -451
  136. package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +0 -50
  137. package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +0 -50
  138. package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +0 -86
  139. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +0 -162
  140. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +0 -189
  141. package/bin/runners/lib/agent-firewall/policy/rules/scope.js +0 -93
  142. package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +0 -57
  143. package/bin/runners/lib/agent-firewall/policy/schema.json +0 -183
  144. package/bin/runners/lib/agent-firewall/policy/verdict.js +0 -54
  145. package/bin/runners/lib/agent-firewall/proposal/extractor.js +0 -394
  146. package/bin/runners/lib/agent-firewall/proposal/index.js +0 -212
  147. package/bin/runners/lib/agent-firewall/proposal/schema.js +0 -251
  148. package/bin/runners/lib/agent-firewall/proposal/validator.js +0 -386
  149. package/bin/runners/lib/agent-firewall/reality/index.js +0 -332
  150. package/bin/runners/lib/agent-firewall/reality/state.js +0 -625
  151. package/bin/runners/lib/agent-firewall/reality/watcher.js +0 -322
  152. package/bin/runners/lib/agent-firewall/risk/index.js +0 -173
  153. package/bin/runners/lib/agent-firewall/risk/scorer.js +0 -328
  154. package/bin/runners/lib/agent-firewall/risk/thresholds.js +0 -321
  155. package/bin/runners/lib/agent-firewall/risk/vectors.js +0 -421
  156. package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +0 -472
  157. package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +0 -346
  158. package/bin/runners/lib/agent-firewall/simulator/index.js +0 -181
  159. package/bin/runners/lib/agent-firewall/simulator/route-validator.js +0 -380
  160. package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +0 -661
  161. package/bin/runners/lib/agent-firewall/time-machine/index.js +0 -267
  162. package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +0 -436
  163. package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +0 -490
  164. package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +0 -530
  165. package/bin/runners/lib/agent-firewall/truthpack/index.js +0 -67
  166. package/bin/runners/lib/agent-firewall/truthpack/loader.js +0 -137
  167. package/bin/runners/lib/agent-firewall/unblock/planner.js +0 -337
  168. package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +0 -118
  169. package/bin/runners/lib/api-client.js +0 -269
  170. package/bin/runners/lib/audit-logger.js +0 -532
  171. package/bin/runners/lib/authority/authorities/architecture.js +0 -364
  172. package/bin/runners/lib/authority/authorities/compliance.js +0 -341
  173. package/bin/runners/lib/authority/authorities/human.js +0 -343
  174. package/bin/runners/lib/authority/authorities/quality.js +0 -420
  175. package/bin/runners/lib/authority/authorities/security.js +0 -228
  176. package/bin/runners/lib/authority/index.js +0 -293
  177. package/bin/runners/lib/authority-badge.js +0 -425
  178. package/bin/runners/lib/bundle/bundle-intelligence.js +0 -846
  179. package/bin/runners/lib/cli-charts.js +0 -368
  180. package/bin/runners/lib/cli-config-display.js +0 -405
  181. package/bin/runners/lib/cli-demo.js +0 -275
  182. package/bin/runners/lib/cli-errors.js +0 -438
  183. package/bin/runners/lib/cli-help-formatter.js +0 -439
  184. package/bin/runners/lib/cli-interactive-menu.js +0 -509
  185. package/bin/runners/lib/cli-prompts.js +0 -441
  186. package/bin/runners/lib/cli-scan-cards.js +0 -362
  187. package/bin/runners/lib/compliance-reporter.js +0 -710
  188. package/bin/runners/lib/conductor/index.js +0 -671
  189. package/bin/runners/lib/easy/README.md +0 -123
  190. package/bin/runners/lib/easy/index.js +0 -140
  191. package/bin/runners/lib/easy/interactive-wizard.js +0 -788
  192. package/bin/runners/lib/easy/one-click-firewall.js +0 -564
  193. package/bin/runners/lib/easy/zero-config-reality.js +0 -714
  194. package/bin/runners/lib/engines/accessibility-engine.js +0 -390
  195. package/bin/runners/lib/engines/api-consistency-engine.js +0 -467
  196. package/bin/runners/lib/engines/ast-cache.js +0 -99
  197. package/bin/runners/lib/engines/async-patterns-engine.js +0 -444
  198. package/bin/runners/lib/engines/bundle-size-engine.js +0 -433
  199. package/bin/runners/lib/engines/code-quality-engine.js +0 -255
  200. package/bin/runners/lib/engines/confidence-scoring.js +0 -276
  201. package/bin/runners/lib/engines/console-logs-engine.js +0 -115
  202. package/bin/runners/lib/engines/context-detection.js +0 -264
  203. package/bin/runners/lib/engines/cross-file-analysis-engine.js +0 -533
  204. package/bin/runners/lib/engines/database-patterns-engine.js +0 -429
  205. package/bin/runners/lib/engines/dead-code-engine.js +0 -198
  206. package/bin/runners/lib/engines/deprecated-api-engine.js +0 -226
  207. package/bin/runners/lib/engines/duplicate-code-engine.js +0 -354
  208. package/bin/runners/lib/engines/empty-catch-engine.js +0 -260
  209. package/bin/runners/lib/engines/env-variables-engine.js +0 -458
  210. package/bin/runners/lib/engines/error-handling-engine.js +0 -437
  211. package/bin/runners/lib/engines/false-positive-prevention.js +0 -630
  212. package/bin/runners/lib/engines/file-filter.js +0 -131
  213. package/bin/runners/lib/engines/framework-adapters/index.js +0 -607
  214. package/bin/runners/lib/engines/framework-detection.js +0 -508
  215. package/bin/runners/lib/engines/hardcoded-secrets-engine.js +0 -251
  216. package/bin/runners/lib/engines/import-order-engine.js +0 -429
  217. package/bin/runners/lib/engines/mock-data-engine.js +0 -315
  218. package/bin/runners/lib/engines/naming-conventions-engine.js +0 -544
  219. package/bin/runners/lib/engines/noise-reduction-engine.js +0 -452
  220. package/bin/runners/lib/engines/orchestrator.js +0 -334
  221. package/bin/runners/lib/engines/parallel-processor.js +0 -71
  222. package/bin/runners/lib/engines/performance-issues-engine.js +0 -405
  223. package/bin/runners/lib/engines/react-patterns-engine.js +0 -457
  224. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +0 -571
  225. package/bin/runners/lib/engines/todo-fixme-engine.js +0 -115
  226. package/bin/runners/lib/engines/type-aware-engine.js +0 -376
  227. package/bin/runners/lib/engines/unsafe-regex-engine.js +0 -225
  228. package/bin/runners/lib/engines/vibecheck-engines/README.md +0 -53
  229. package/bin/runners/lib/engines/vibecheck-engines/index.js +0 -124
  230. package/bin/runners/lib/engines/vibecheck-engines/lib/ai-hallucination-engine.js +0 -806
  231. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +0 -439
  232. package/bin/runners/lib/engines/vibecheck-engines/lib/smart-fix-engine.js +0 -577
  233. package/bin/runners/lib/engines/vibecheck-engines/lib/vibe-score-engine.js +0 -543
  234. package/bin/runners/lib/engines/vibecheck-engines/package.json +0 -13
  235. package/bin/runners/lib/engines/vibecheck-engines.js +0 -514
  236. package/bin/runners/lib/enhanced-features/index.js +0 -305
  237. package/bin/runners/lib/enhanced-output.js +0 -631
  238. package/bin/runners/lib/enterprise.js +0 -300
  239. package/bin/runners/lib/exit-codes.js +0 -275
  240. package/bin/runners/lib/fingerprint.js +0 -377
  241. package/bin/runners/lib/firewall/command-validator.js +0 -351
  242. package/bin/runners/lib/firewall/config.js +0 -341
  243. package/bin/runners/lib/firewall/content-validator.js +0 -519
  244. package/bin/runners/lib/firewall/index.js +0 -101
  245. package/bin/runners/lib/firewall/path-validator.js +0 -256
  246. package/bin/runners/lib/help-formatter.js +0 -413
  247. package/bin/runners/lib/intelligence/cross-repo-intelligence.js +0 -817
  248. package/bin/runners/lib/logger.js +0 -38
  249. package/bin/runners/lib/mcp-utils.js +0 -425
  250. package/bin/runners/lib/output/index.js +0 -1022
  251. package/bin/runners/lib/policy-engine.js +0 -652
  252. package/bin/runners/lib/polish/autofix/accessibility-fixes.js +0 -333
  253. package/bin/runners/lib/polish/autofix/async-handlers.js +0 -273
  254. package/bin/runners/lib/polish/autofix/dead-code.js +0 -280
  255. package/bin/runners/lib/polish/autofix/imports-optimizer.js +0 -344
  256. package/bin/runners/lib/polish/autofix/index.js +0 -200
  257. package/bin/runners/lib/polish/autofix/remove-consoles.js +0 -209
  258. package/bin/runners/lib/polish/autofix/strengthen-types.js +0 -245
  259. package/bin/runners/lib/polish/backend-checks.js +0 -148
  260. package/bin/runners/lib/polish/documentation-checks.js +0 -111
  261. package/bin/runners/lib/polish/frontend-checks.js +0 -168
  262. package/bin/runners/lib/polish/index.js +0 -71
  263. package/bin/runners/lib/polish/infrastructure-checks.js +0 -131
  264. package/bin/runners/lib/polish/library-detection.js +0 -175
  265. package/bin/runners/lib/polish/performance-checks.js +0 -100
  266. package/bin/runners/lib/polish/security-checks.js +0 -148
  267. package/bin/runners/lib/polish/utils.js +0 -203
  268. package/bin/runners/lib/prompt-builder.js +0 -540
  269. package/bin/runners/lib/proof-certificate.js +0 -634
  270. package/bin/runners/lib/reality/accessibility-audit.js +0 -946
  271. package/bin/runners/lib/reality/api-contract-validator.js +0 -1012
  272. package/bin/runners/lib/reality/chaos-engineering.js +0 -1084
  273. package/bin/runners/lib/reality/performance-tracker.js +0 -1077
  274. package/bin/runners/lib/reality/scenario-generator.js +0 -1404
  275. package/bin/runners/lib/reality/visual-regression.js +0 -852
  276. package/bin/runners/lib/reality-profiler.js +0 -717
  277. package/bin/runners/lib/replay/flight-recorder-viewer.js +0 -1160
  278. package/bin/runners/lib/review/ai-code-review.js +0 -832
  279. package/bin/runners/lib/rules/custom-rule-engine.js +0 -985
  280. package/bin/runners/lib/sbom-generator.js +0 -641
  281. package/bin/runners/lib/scan-output-enhanced.js +0 -512
  282. package/bin/runners/lib/security/owasp-scanner.js +0 -939
  283. package/bin/runners/lib/ship-output-enterprise.js +0 -239
  284. package/bin/runners/lib/unified-cli-output.js +0 -777
  285. package/bin/runners/lib/validators/contract-validator.js +0 -283
  286. package/bin/runners/lib/validators/dead-export-detector.js +0 -279
  287. package/bin/runners/lib/validators/dep-audit.js +0 -245
  288. package/bin/runners/lib/validators/env-validator.js +0 -319
  289. package/bin/runners/lib/validators/index.js +0 -120
  290. package/bin/runners/lib/validators/license-checker.js +0 -252
  291. package/bin/runners/lib/validators/route-validator.js +0 -290
  292. package/bin/runners/runAgent.d.ts +0 -5
  293. package/bin/runners/runAgent.js +0 -164
  294. package/bin/runners/runApprove.js +0 -1233
  295. package/bin/runners/runAuthority.js +0 -528
  296. package/bin/runners/runClassify.js +0 -862
  297. package/bin/runners/runConductor.js +0 -772
  298. package/bin/runners/runContainer.js +0 -366
  299. package/bin/runners/runContext.d.ts +0 -4
  300. package/bin/runners/runEasy.js +0 -410
  301. package/bin/runners/runFirewall.d.ts +0 -5
  302. package/bin/runners/runFirewall.js +0 -137
  303. package/bin/runners/runFirewallHook.d.ts +0 -5
  304. package/bin/runners/runFirewallHook.js +0 -59
  305. package/bin/runners/runIaC.js +0 -372
  306. package/bin/runners/runPolish.d.ts +0 -4
  307. package/bin/runners/runProof.zip +0 -0
  308. package/bin/runners/runTruth.d.ts +0 -5
  309. package/bin/runners/runTruth.js +0 -104
  310. package/bin/runners/runVibe.js +0 -791
  311. package/mcp-server/HARDENING_SUMMARY.md +0 -299
  312. package/mcp-server/agent-firewall-interceptor.js +0 -500
  313. package/mcp-server/authority-tools.js +0 -569
  314. package/mcp-server/conductor/conflict-resolver.js +0 -588
  315. package/mcp-server/conductor/execution-planner.js +0 -544
  316. package/mcp-server/conductor/index.js +0 -377
  317. package/mcp-server/conductor/lock-manager.js +0 -615
  318. package/mcp-server/conductor/request-queue.js +0 -550
  319. package/mcp-server/conductor/session-manager.js +0 -500
  320. package/mcp-server/conductor/tools.js +0 -510
  321. package/mcp-server/lib/api-client.cjs +0 -13
  322. package/mcp-server/lib/logger.cjs +0 -30
  323. package/mcp-server/logger.js +0 -173
  324. package/mcp-server/tools-v3.js +0 -1039
  325. package/mcp-server/tools.js +0 -495
  326. package/mcp-server/vibecheck-mcp-server-3.2.0.tgz +0 -0
@@ -1,11 +1,6 @@
1
1
  /**
2
- * vibecheck ship - Comprehensive Production Readiness Analysis [PRO]
3
- *
4
- * The comprehensive analysis command running:
5
- * - ALL 17+ scan engines (vs 5 in quick scan)
6
- * - Ship-only validators (route integrity, contracts, deps, licenses, env, dead exports)
7
- * - Production Readiness Score calculation
8
- * - SHIP/WARN/BLOCK verdict with proof certificate
2
+ * vibecheck ship - The Vibe Coder's Best Friend
3
+ * Zero config. Plain English. One command to ship with confidence.
9
4
  *
10
5
  * ═══════════════════════════════════════════════════════════════════════════════
11
6
  * ENTERPRISE EDITION - World-Class Terminal Experience
@@ -16,73 +11,20 @@ const path = require("path");
16
11
  const fs = require("fs");
17
12
  const { withErrorHandling } = require("./lib/error-handler");
18
13
  const { ensureOutputDir, detectProjectFeatures } = require("./utils");
19
- const { enforceLimit, enforceFeature, trackUsage, getCurrentTier } = require("./lib/entitlements-v2");
14
+ const { enforceLimit, enforceFeature, trackUsage, getCurrentTier } = require("./lib/entitlements");
20
15
  const { emitShipCheck } = require("./lib/audit-bridge");
21
16
  const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
22
17
  const {
23
18
  generateRunId,
24
19
  createJsonOutput,
25
20
  writeJsonOutput,
21
+ exitCodeToVerdict,
22
+ verdictToExitCode,
26
23
  saveArtifact
27
24
  } = require("./lib/cli-output");
28
- const { EXIT, verdictToExitCode, exitCodeToVerdict } = require("./lib/exit-codes");
29
-
30
- // NEW: Import orchestrator and validators
31
- const { runShipEngines, ALL_ENGINES } = require("./lib/engines/orchestrator");
32
- const { runShipValidators } = require("./lib/validators");
33
25
 
34
26
  // Route Truth v1 - Fake endpoint detection
35
27
  const { buildTruthpack, writeTruthpack, detectFastifyEntry } = require("./lib/truth");
36
-
37
- // Helper to normalize severity for ship verdict
38
- function normalizeSeverityForShip(sev) {
39
- if (!sev) return 'WARN';
40
- const s = String(sev).toLowerCase();
41
- if (s === 'block' || s === 'critical' || s === 'high') return 'BLOCK';
42
- if (s === 'warn' || s === 'warning' || s === 'medium') return 'WARN';
43
- return 'INFO';
44
- }
45
-
46
- // Helper to categorize findings for score breakdown
47
- function categorizeFindings(finding) {
48
- const category = (finding.category || '').toLowerCase();
49
- const engine = (finding.engine || '').toLowerCase();
50
- const validator = (finding.validator || '').toLowerCase();
51
-
52
- // Security
53
- if (category.includes('secret') || category.includes('security') ||
54
- category.includes('auth') || category.includes('billing') ||
55
- engine.includes('secret') || engine.includes('security')) {
56
- return 'security';
57
- }
58
-
59
- // Hallucinations
60
- if (category.includes('hallucination') || category.includes('fake') ||
61
- category.includes('mock') || engine.includes('hallucination')) {
62
- return 'hallucination';
63
- }
64
-
65
- // Routes
66
- if (category.includes('route') || category.includes('missing') ||
67
- validator.includes('route')) {
68
- return 'routes';
69
- }
70
-
71
- // Contracts
72
- if (category.includes('contract') || category.includes('drift') ||
73
- validator.includes('contract')) {
74
- return 'contracts';
75
- }
76
-
77
- // Dependencies
78
- if (category.includes('dependency') || category.includes('license') ||
79
- validator.includes('dep') || validator.includes('license')) {
80
- return 'dependencies';
81
- }
82
-
83
- // Default to quality
84
- return 'quality';
85
- }
86
28
  const {
87
29
  findMissingRoutes,
88
30
  findEnvGaps,
@@ -97,213 +39,6 @@ const { findContractDrift, loadContracts, hasContracts, getDriftSummary } = requ
97
39
  const upsell = require("./lib/upsell");
98
40
  const entitlements = require("./lib/entitlements-v2");
99
41
 
100
- // V7: World-class proof certificate and risk radar
101
- let proofCertificate;
102
- try {
103
- proofCertificate = require("./lib/proof-certificate");
104
- } catch (e) {
105
- proofCertificate = null;
106
- }
107
-
108
- // Import vibecheck engines for enhanced analysis
109
- let vibeEngines;
110
- try {
111
- vibeEngines = require("./lib/engines/vibecheck-engines");
112
- } catch (e) {
113
- vibeEngines = null;
114
- }
115
-
116
- // ═══════════════════════════════════════════════════════════════════════════════
117
- // ENHANCED ANALYSIS WITH VIBECHECK ENGINES
118
- // ═══════════════════════════════════════════════════════════════════════════════
119
-
120
- const CODE_EXTENSIONS = ['.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs'];
121
- const IGNORE_PATTERNS = ['node_modules', '.git', 'dist', 'build', '.next', '.nuxt', 'coverage', '__pycache__', '.vibecheck'];
122
-
123
- function* walkFilesForShip(dir, depth = 0, maxDepth = 8) {
124
- if (depth > maxDepth) return;
125
-
126
- let entries;
127
- try {
128
- entries = fs.readdirSync(dir, { withFileTypes: true });
129
- } catch {
130
- return;
131
- }
132
-
133
- for (const entry of entries) {
134
- const fullPath = path.join(dir, entry.name);
135
-
136
- if (entry.isDirectory()) {
137
- if (IGNORE_PATTERNS.some(p => entry.name.includes(p))) continue;
138
- yield* walkFilesForShip(fullPath, depth + 1, maxDepth);
139
- } else if (entry.isFile()) {
140
- const ext = path.extname(entry.name);
141
- if (CODE_EXTENSIONS.includes(ext)) {
142
- yield fullPath;
143
- }
144
- }
145
- }
146
- }
147
-
148
- async function runVibeEngineAnalysis(projectPath, opts = {}) {
149
- if (!vibeEngines) return [];
150
-
151
- const findings = [];
152
- const files = Array.from(walkFilesForShip(projectPath));
153
-
154
- // Limit files to analyze in ship mode (performance)
155
- const filesToAnalyze = files.slice(0, 500);
156
-
157
- for (const filePath of filesToAnalyze) {
158
- try {
159
- const content = fs.readFileSync(filePath, 'utf-8');
160
-
161
- // Skip test files unless explicitly included
162
- if (!opts.includeTests && (
163
- filePath.includes('.test.') ||
164
- filePath.includes('.spec.') ||
165
- filePath.includes('__tests__')
166
- )) {
167
- continue;
168
- }
169
-
170
- // Run async patterns analysis - critical for production
171
- if (vibeEngines.analyzeAsyncPatterns) {
172
- try {
173
- const asyncFindings = vibeEngines.analyzeAsyncPatterns(content, filePath);
174
- findings.push(...asyncFindings.filter(f =>
175
- f.severity === 'BLOCK' || f.severity === 'WARN'
176
- ).map(f => ({
177
- ...f,
178
- category: f.category || 'AsyncPatterns',
179
- // Map to ship finding format
180
- title: f.title,
181
- why: f.message,
182
- severity: f.severity,
183
- evidence: [{ file: f.file, lines: String(f.line) }],
184
- fixHints: [f.fixHint].filter(Boolean),
185
- })));
186
- } catch {}
187
- }
188
-
189
- // Run env variable analysis - security critical
190
- if (vibeEngines.analyzeEnvVariables) {
191
- try {
192
- const envFindings = vibeEngines.analyzeEnvVariables(content, filePath);
193
- findings.push(...envFindings.filter(f =>
194
- f.severity === 'BLOCK' || f.severity === 'WARN'
195
- ).map(f => ({
196
- ...f,
197
- category: f.category || 'EnvVariable',
198
- title: f.title,
199
- why: f.message,
200
- severity: f.severity,
201
- evidence: [{ file: f.file, lines: String(f.line) }],
202
- fixHints: [f.fixHint].filter(Boolean),
203
- })));
204
- } catch {}
205
- }
206
-
207
- // Run AI hallucination detection - core vibecheck functionality
208
- if (vibeEngines.analyzeAIHallucinations) {
209
- try {
210
- const aiFindings = vibeEngines.analyzeAIHallucinations(content, filePath, {
211
- includeTests: opts.includeTests || false,
212
- });
213
- findings.push(...aiFindings.filter(f =>
214
- f.severity === 'BLOCK' || f.severity === 'WARN'
215
- ).map(f => ({
216
- ...f,
217
- category: f.category || 'AIHallucination',
218
- title: f.title || f.type,
219
- why: f.message,
220
- severity: f.severity,
221
- evidence: [{ file: f.file, lines: String(f.line) }],
222
- fixHints: [f.fixHint].filter(Boolean),
223
- })));
224
- } catch {}
225
- }
226
-
227
- // Run React patterns analysis (critical for React apps)
228
- if (vibeEngines.analyzeReactPatterns) {
229
- try {
230
- const reactFindings = vibeEngines.analyzeReactPatterns(content, filePath);
231
- findings.push(...reactFindings.filter(f =>
232
- f.severity === 'BLOCK' || f.severity === 'WARN'
233
- ).map(f => ({
234
- ...f,
235
- category: f.category || 'ReactPatterns',
236
- title: f.title,
237
- why: f.message,
238
- severity: f.severity,
239
- evidence: [{ file: f.file, lines: String(f.line) }],
240
- fixHints: [f.fixHint].filter(Boolean),
241
- })));
242
- } catch {}
243
- }
244
-
245
- // Run database patterns analysis (critical for production)
246
- if (vibeEngines.analyzeDatabasePatterns) {
247
- try {
248
- const dbFindings = vibeEngines.analyzeDatabasePatterns(content, filePath);
249
- findings.push(...dbFindings.filter(f =>
250
- f.severity === 'BLOCK' || f.severity === 'WARN'
251
- ).map(f => ({
252
- ...f,
253
- category: f.category || 'DatabasePatterns',
254
- title: f.title,
255
- why: f.message,
256
- severity: f.severity,
257
- evidence: [{ file: f.file, lines: String(f.line) }],
258
- fixHints: [f.fixHint].filter(Boolean),
259
- })));
260
- } catch {}
261
- }
262
-
263
- // Run error handling analysis
264
- if (vibeEngines.analyzeErrorHandling) {
265
- try {
266
- const errorFindings = vibeEngines.analyzeErrorHandling(content, filePath);
267
- findings.push(...errorFindings.filter(f =>
268
- f.severity === 'BLOCK' || f.severity === 'WARN'
269
- ).map(f => ({
270
- ...f,
271
- category: f.category || 'ErrorHandling',
272
- title: f.title,
273
- why: f.message,
274
- severity: f.severity,
275
- evidence: [{ file: f.file, lines: String(f.line) }],
276
- fixHints: [f.fixHint].filter(Boolean),
277
- })));
278
- } catch {}
279
- }
280
-
281
- } catch (e) {
282
- // Skip files that can't be read
283
- }
284
- }
285
-
286
- // Run env setup analysis at project level
287
- if (vibeEngines.analyzeEnvSetup) {
288
- try {
289
- const setupFindings = vibeEngines.analyzeEnvSetup(projectPath);
290
- findings.push(...setupFindings.filter(f =>
291
- f.severity === 'BLOCK' || f.severity === 'WARN'
292
- ).map(f => ({
293
- ...f,
294
- category: f.category || 'EnvSetup',
295
- title: f.title,
296
- why: f.message,
297
- severity: f.severity,
298
- evidence: [{ file: f.file, lines: String(f.line) }],
299
- fixHints: [f.fixHint].filter(Boolean),
300
- })));
301
- } catch {}
302
- }
303
-
304
- return findings;
305
- }
306
-
307
42
  // ═══════════════════════════════════════════════════════════════════════════════
308
43
  // ENHANCED TERMINAL UI & OUTPUT MODULES
309
44
  // ═══════════════════════════════════════════════════════════════════════════════
@@ -319,7 +54,7 @@ const {
319
54
  } = require("./lib/terminal-ui");
320
55
 
321
56
  const {
322
- formatShipOutput: formatShipOutputLegacy,
57
+ formatShipOutput,
323
58
  renderVerdictCard,
324
59
  renderFixModeHeader,
325
60
  renderFixResults,
@@ -329,13 +64,6 @@ const {
329
64
  shipIcons,
330
65
  } = require("./lib/ship-output");
331
66
 
332
- // Unified Output System
333
- const { output } = require("./lib/output/index.js");
334
-
335
- const {
336
- formatShipOutput,
337
- } = require("./lib/ship-output-enterprise");
338
-
339
67
  // ═══════════════════════════════════════════════════════════════════════════════
340
68
  // PREMIUM BANNER
341
69
  // ═══════════════════════════════════════════════════════════════════════════════
@@ -628,8 +356,6 @@ function getCategoryIcon(category) {
628
356
  'MissingRoute': ICONS.route,
629
357
  'EnvContract': ICONS.env,
630
358
  'EnvGap': ICONS.env,
631
- 'EnvVariable': ICONS.env,
632
- 'EnvSetup': ICONS.env,
633
359
  'FakeSuccess': ICONS.ghost,
634
360
  'GhostAuth': ICONS.auth,
635
361
  'StripeWebhook': ICONS.money,
@@ -640,33 +366,6 @@ function getCategoryIcon(category) {
640
366
  'Security': ICONS.shield,
641
367
  'Auth': ICONS.lock,
642
368
  'Fake Code': ICONS.ghost,
643
- // New engine categories
644
- 'AsyncPatterns': ICONS.lightning,
645
- 'AIHallucination': ICONS.ghost,
646
- 'NamingConventions': '📝',
647
- 'floating_promise': ICONS.lightning,
648
- 'empty_async_catch': ICONS.bug,
649
- 'exposed_secret': ICONS.key,
650
- 'insecure_default': ICONS.warning,
651
- // React patterns
652
- 'ReactPatterns': '⚛️',
653
- 'missing_key': '⚛️',
654
- 'conditional_hook': '⚛️',
655
- 'direct_state_mutation': '⚛️',
656
- 'stale_closure': '⚛️',
657
- // Database patterns
658
- 'DatabasePatterns': '🗃️',
659
- 'n_plus_1_query': '🗃️',
660
- 'query_in_loop': '🗃️',
661
- 'unbounded_query': '🗃️',
662
- 'missing_transaction': '🗃️',
663
- 'raw_query_interpolation': ICONS.key,
664
- // Error handling
665
- 'ErrorHandling': ICONS.bug,
666
- 'empty_catch': ICONS.bug,
667
- 'generic_error_message': ICONS.bug,
668
- // Import order
669
- 'ImportOrder': '📦',
670
369
  };
671
370
  return icons[category] || ICONS.bug;
672
371
  }
@@ -931,11 +630,6 @@ function printHelp(showBanner = true) {
931
630
  ${colors.accent}--verbose, -v${ansi.reset} Show detailed progress
932
631
  ${colors.accent}--help, -h${ansi.reset} Show this help
933
632
 
934
- ${ansi.bold}${colors.accent}Deploy Gate (CI/CD Integration):${ansi.reset}
935
- ${colors.accent}--gate, -g${ansi.reset} Enable deploy gate mode ${ansi.dim}(blocks deploys on failures)${ansi.reset}
936
- ${colors.accent}--fail-on${ansi.reset} What triggers failure: fake-features, warnings, any, blockers
937
- ${ansi.dim}(default: fake-features)${ansi.reset}
938
-
939
633
  ${ansi.bold}Exit Codes:${ansi.reset}
940
634
  ${colors.success}0${ansi.reset} SHIP — Ready to ship
941
635
  ${colors.warning}1${ansi.reset} WARN — Warnings found, review recommended
@@ -953,20 +647,6 @@ function printHelp(showBanner = true) {
953
647
 
954
648
  ${ansi.dim}# Strict CI mode (warnings = failure)${ansi.reset}
955
649
  vibecheck ship --strict --ci
956
-
957
- ${ansi.bold}${colors.accent}Deploy Gate Examples:${ansi.reset}
958
-
959
- ${ansi.dim}# Block deploy if fake features detected (default)${ansi.reset}
960
- vibecheck ship --gate
961
-
962
- ${ansi.dim}# Block deploy on any warning${ansi.reset}
963
- vibecheck ship --gate --fail-on=warnings
964
-
965
- ${ansi.dim}# Block deploy only on critical blockers${ansi.reset}
966
- vibecheck ship --gate --fail-on=blockers
967
-
968
- ${ansi.dim}# Use in GitHub Actions / Vercel / Netlify${ansi.reset}
969
- vibecheck ship --gate && npm run build
970
650
  `);
971
651
  }
972
652
 
@@ -1048,40 +728,13 @@ function getClaimType(category) {
1048
728
  const map = {
1049
729
  'MissingRoute': 'route_exists',
1050
730
  'EnvContract': 'env_declared',
1051
- 'EnvVariable': 'env_validated',
1052
- 'EnvSetup': 'env_secured',
1053
731
  'FakeSuccess': 'success_verified',
1054
732
  'GhostAuth': 'auth_protected',
1055
733
  'StripeWebhook': 'billing_enforced',
1056
734
  'PaidSurface': 'billing_enforced',
1057
735
  'OwnerModeBypass': 'billing_enforced',
1058
736
  'DeadUI': 'ui_wired',
1059
- 'ContractDrift': 'contract_satisfied',
1060
- // New engine claim types
1061
- 'AsyncPatterns': 'promises_handled',
1062
- 'AIHallucination': 'implementation_real',
1063
- 'NamingConventions': 'code_quality',
1064
- 'floating_promise': 'promises_handled',
1065
- 'empty_async_catch': 'errors_handled',
1066
- 'exposed_secret': 'secrets_secured',
1067
- 'insecure_default': 'config_secured',
1068
- // React patterns
1069
- 'ReactPatterns': 'react_patterns_valid',
1070
- 'missing_key': 'list_keys_present',
1071
- 'conditional_hook': 'hooks_order_valid',
1072
- 'direct_state_mutation': 'state_immutable',
1073
- 'stale_closure': 'deps_correct',
1074
- // Database patterns
1075
- 'DatabasePatterns': 'db_patterns_optimal',
1076
- 'n_plus_1_query': 'queries_optimized',
1077
- 'query_in_loop': 'queries_batched',
1078
- 'unbounded_query': 'queries_limited',
1079
- 'missing_transaction': 'transactions_used',
1080
- 'raw_query_interpolation': 'queries_parameterized',
1081
- // Error handling
1082
- 'ErrorHandling': 'errors_handled',
1083
- 'empty_catch': 'errors_logged',
1084
- 'generic_error_message': 'errors_descriptive',
737
+ 'ContractDrift': 'contract_satisfied'
1085
738
  };
1086
739
  return map[category] || 'ui_wired';
1087
740
  }
@@ -1090,40 +743,13 @@ function getGapType(category) {
1090
743
  const map = {
1091
744
  'MissingRoute': 'missing_handler',
1092
745
  'EnvContract': 'missing_verification',
1093
- 'EnvVariable': 'missing_validation',
1094
- 'EnvSetup': 'missing_security',
1095
746
  'FakeSuccess': 'missing_verification',
1096
747
  'GhostAuth': 'missing_gate',
1097
748
  'StripeWebhook': 'missing_verification',
1098
749
  'PaidSurface': 'missing_gate',
1099
750
  'OwnerModeBypass': 'missing_gate',
1100
751
  'DeadUI': 'missing_handler',
1101
- 'ContractDrift': 'contract_drift',
1102
- // New engine gap types
1103
- 'AsyncPatterns': 'unhandled_async',
1104
- 'AIHallucination': 'stub_implementation',
1105
- 'NamingConventions': 'naming_issue',
1106
- 'floating_promise': 'unhandled_promise',
1107
- 'empty_async_catch': 'swallowed_error',
1108
- 'exposed_secret': 'exposed_credential',
1109
- 'insecure_default': 'insecure_config',
1110
- // React patterns
1111
- 'ReactPatterns': 'react_antipattern',
1112
- 'missing_key': 'missing_list_key',
1113
- 'conditional_hook': 'invalid_hook_call',
1114
- 'direct_state_mutation': 'state_mutation',
1115
- 'stale_closure': 'stale_deps',
1116
- // Database patterns
1117
- 'DatabasePatterns': 'db_antipattern',
1118
- 'n_plus_1_query': 'n_plus_1',
1119
- 'query_in_loop': 'loop_query',
1120
- 'unbounded_query': 'no_limit',
1121
- 'missing_transaction': 'no_transaction',
1122
- 'raw_query_interpolation': 'sql_injection_risk',
1123
- // Error handling
1124
- 'ErrorHandling': 'poor_error_handling',
1125
- 'empty_catch': 'swallowed_error',
1126
- 'generic_error_message': 'generic_error',
752
+ 'ContractDrift': 'contract_drift'
1127
753
  };
1128
754
  return map[category] || 'untested_path';
1129
755
  }
@@ -1150,10 +776,6 @@ function parseArgs(args) {
1150
776
  help: globalFlags.help || false,
1151
777
  noBanner: globalFlags.noBanner || false,
1152
778
  quiet: globalFlags.quiet || false,
1153
- // Deploy Gate mode - for CI/CD integration (Vercel, Netlify, GitHub Actions)
1154
- gate: false,
1155
- // Deploy Gate options
1156
- failOn: "fake-features", // fake-features, warnings, any
1157
779
  };
1158
780
 
1159
781
  // Parse command-specific args
@@ -1169,21 +791,6 @@ function parseArgs(args) {
1169
791
  }
1170
792
  else if (a.startsWith("--path=")) opts.path = a.split("=")[1];
1171
793
  else if (a === "--path" || a === "-p") opts.path = args[++i];
1172
- // Deploy Gate flags for CI/CD integration
1173
- else if (a === "--gate" || a === "-g") {
1174
- opts.gate = true;
1175
- opts.ci = true; // Gate mode implies CI mode
1176
- opts.json = true; // Gate mode outputs JSON for parsing
1177
- }
1178
- else if (a === "--fail-on") {
1179
- const next = cleanArgs[++i];
1180
- if (["fake-features", "warnings", "any", "blockers"].includes(next)) {
1181
- opts.failOn = next;
1182
- }
1183
- }
1184
- else if (a.startsWith("--fail-on=")) {
1185
- opts.failOn = a.split("=")[1];
1186
- }
1187
794
  }
1188
795
 
1189
796
  return opts;
@@ -1201,13 +808,6 @@ async function runShip(args, context = {}) {
1201
808
  const opts = parseArgs(args);
1202
809
  const executionStart = Date.now();
1203
810
 
1204
- // Configure unified output mode
1205
- output.setMode({
1206
- json: opts.json,
1207
- quiet: opts.quiet,
1208
- ci: opts.ci
1209
- });
1210
-
1211
811
  // Show help if requested
1212
812
  if (opts.help) {
1213
813
  printHelp(shouldShowBanner(opts));
@@ -1224,7 +824,7 @@ async function runShip(args, context = {}) {
1224
824
  } catch (err) {
1225
825
  if (err.code === 'LIMIT_EXCEEDED' || err.code === 'FEATURE_NOT_AVAILABLE') {
1226
826
  console.error(`\n ${colors.error}${icons.error}${ansi.reset} ${err.upgradePrompt || err.message}\n`);
1227
- return EXIT.TIER_REQUIRED;
827
+ return EXIT_CODES.WARN;
1228
828
  }
1229
829
  throw err;
1230
830
  }
@@ -1262,36 +862,26 @@ async function runShip(args, context = {}) {
1262
862
  spinner = new Spinner({ color: colors.accent });
1263
863
  }
1264
864
 
1265
- // ═══════════════════════════════════════════════════════════════════════════
1266
- // PHASE 1: Run ALL 17+ Scan Engines (comprehensive analysis)
1267
- // ═══════════════════════════════════════════════════════════════════════════
1268
- if (spinner) spinner.start(`Running comprehensive analysis (${ALL_ENGINES.length} engines)...`);
1269
-
1270
- const engineResult = await runShipEngines(projectPath, {
1271
- maxFiles: 2000,
1272
- onProgress: opts.verbose ? (phase, pct) => {
1273
- if (spinner) spinner.text = `${phase}: ${pct}%`;
1274
- } : undefined,
1275
- });
865
+ // Phase 1: Production Integrity Check
866
+ if (spinner) spinner.start('Checking production integrity...');
1276
867
 
1277
- if (spinner) spinner.succeed(`Engines complete (${engineResult.findings.length} findings from ${ALL_ENGINES.length} engines)`);
1278
-
1279
- // ═══════════════════════════════════════════════════════════════════════════
1280
- // PHASE 2: Run Ship-Only Validators
1281
- // ═══════════════════════════════════════════════════════════════════════════
1282
- if (spinner) spinner.start('Running ship-only validators...');
1283
-
1284
- const validatorResult = await runShipValidators(projectPath, {
1285
- onProgress: opts.verbose ? (name, status) => {
1286
- if (spinner) spinner.text = `${name}: ${status}`;
1287
- } : undefined,
1288
- });
868
+ try {
869
+ const { auditProductionIntegrity } = require(
870
+ path.join(__dirname, "../../scripts/audit-production-integrity.js"),
871
+ );
872
+ const { results: integrityResults, integrity } = await auditProductionIntegrity(projectPath);
873
+ results.score = integrity.score;
874
+ results.grade = integrity.grade;
875
+ results.canShip = integrity.canShip;
876
+ results.deductions = integrity.deductions;
877
+ results.integrity = integrityResults;
878
+ } catch (err) {
879
+ if (opts.verbose) console.warn(` ${ansi.dim}Integrity check skipped: ${err.message}${ansi.reset}`);
880
+ }
1289
881
 
1290
- if (spinner) spinner.succeed(`Validators complete (${validatorResult.findings.length} findings from ${Object.keys(validatorResult.stats.findingsPerValidator).length} validators)`);
882
+ if (spinner) spinner.succeed('Production integrity checked');
1291
883
 
1292
- // ═══════════════════════════════════════════════════════════════════════════
1293
- // PHASE 3: Legacy analyzers (route truth, billing, etc.)
1294
- // ═══════════════════════════════════════════════════════════════════════════
884
+ // Phase 2: Route Truth Analysis
1295
885
  if (spinner) spinner.start('Building route truth map...');
1296
886
 
1297
887
  const fastifyEntry = detectFastifyEntry(projectPath);
@@ -1299,8 +889,8 @@ async function runShip(args, context = {}) {
1299
889
  writeTruthpack(projectPath, truthpack);
1300
890
  results.truthpack = truthpack;
1301
891
 
1302
- // Run legacy analyzers that aren't in the orchestrator
1303
- const legacyFindings = [
892
+ // Run all analyzers
893
+ const allFindings = [
1304
894
  ...findMissingRoutes(truthpack),
1305
895
  ...findEnvGaps(truthpack),
1306
896
  ...findFakeSuccess(projectPath),
@@ -1308,6 +898,7 @@ async function runShip(args, context = {}) {
1308
898
  ...findStripeWebhookViolations(truthpack),
1309
899
  ...findPaidSurfaceNotEnforced(truthpack),
1310
900
  ...findOwnerModeBypass(projectPath),
901
+ // Merge runtime findings if --with runtime is specified
1311
902
  ...(opts.withRuntime ? findingsFromReality(projectPath) : [])
1312
903
  ];
1313
904
 
@@ -1315,38 +906,12 @@ async function runShip(args, context = {}) {
1315
906
  if (hasContracts(projectPath)) {
1316
907
  const contracts = loadContracts(projectPath);
1317
908
  const driftFindings = findContractDrift(contracts, truthpack);
1318
- legacyFindings.push(...driftFindings);
909
+ allFindings.push(...driftFindings);
1319
910
  }
1320
911
 
1321
- if (spinner) spinner.succeed(`Route truth mapped (${truthpack.routes?.server?.length || 0} routes)`);
1322
-
1323
- // ═══════════════════════════════════════════════════════════════════════════
1324
- // Combine all findings
1325
- // ═══════════════════════════════════════════════════════════════════════════
1326
- const allFindings = [
1327
- // Engine findings (17+ engines)
1328
- ...engineResult.findings.map(f => ({
1329
- ...f,
1330
- source: 'engine',
1331
- severity: normalizeSeverityForShip(f.severity),
1332
- })),
1333
- // Validator findings (6 ship-only validators)
1334
- ...validatorResult.findings.map(f => ({
1335
- ...f,
1336
- source: 'validator',
1337
- severity: normalizeSeverityForShip(f.severity),
1338
- })),
1339
- // Legacy analyzer findings
1340
- ...legacyFindings.map(f => ({
1341
- ...f,
1342
- source: 'legacy',
1343
- severity: normalizeSeverityForShip(f.severity),
1344
- })),
1345
- ];
1346
-
1347
912
  results.findings = allFindings;
1348
- results.engineStats = engineResult.stats;
1349
- results.validatorStats = validatorResult.stats;
913
+
914
+ if (spinner) spinner.succeed(`Route truth mapped (${truthpack.routes?.server?.length || 0} routes)`);
1350
915
 
1351
916
  // Phase 3: Build Proof Graph
1352
917
  if (spinner) spinner.start('Building proof graph...');
@@ -1356,94 +921,33 @@ async function runShip(args, context = {}) {
1356
921
 
1357
922
  if (spinner) spinner.succeed(`Proof graph built (${proofGraph.summary.totalClaims} claims)`);
1358
923
 
1359
- // ═══════════════════════════════════════════════════════════════════════════
1360
- // Calculate Production Readiness Score and Verdict
1361
- // ═══════════════════════════════════════════════════════════════════════════
1362
- const blockers = allFindings.filter(f => f.severity === 'BLOCK');
1363
- const warnings = allFindings.filter(f => f.severity === 'WARN');
1364
- const infos = allFindings.filter(f => f.severity === 'INFO');
1365
-
1366
- // Check for hallucinations (critical for vibecheck)
1367
- const hallucinations = allFindings.filter(f =>
1368
- f.engine === 'ai-hallucination-engine' ||
1369
- f.category?.includes('AIHallucination') ||
1370
- f.category?.includes('Hallucination')
1371
- );
924
+ // Calculate final verdict
925
+ const blockers = allFindings.filter(f => f.severity === 'BLOCK' || f.severity === 'critical');
926
+ const warnings = allFindings.filter(f => f.severity === 'WARN' || f.severity === 'warning');
1372
927
 
1373
928
  results.blockers = blockers;
1374
929
  results.warnings = warnings;
1375
930
 
1376
- // Calculate Production Readiness Score (0-100)
1377
- // Start at 100 and deduct based on findings
1378
- let score = 100;
931
+ // Apply strict mode
932
+ if (opts.strict && warnings.length > 0) {
933
+ results.canShip = false;
934
+ }
1379
935
 
1380
- // Category-based deductions
1381
- const categoryDeductions = {
1382
- security: 0,
1383
- quality: 0,
1384
- hallucination: 0,
1385
- routes: 0,
1386
- contracts: 0,
1387
- dependencies: 0,
1388
- };
936
+ if (blockers.length > 0) {
937
+ results.canShip = false;
938
+ }
1389
939
 
940
+ // Deduct score for findings
1390
941
  for (const finding of allFindings) {
1391
- const category = categorizeFindings(finding);
1392
-
1393
942
  if (finding.severity === 'BLOCK') {
1394
- categoryDeductions[category] += 15;
943
+ results.score = Math.max(0, results.score - 15);
1395
944
  } else if (finding.severity === 'WARN') {
1396
- categoryDeductions[category] += 5;
1397
- } else {
1398
- categoryDeductions[category] += 1;
945
+ results.score = Math.max(0, results.score - 5);
1399
946
  }
1400
947
  }
1401
948
 
1402
- // Apply weighted deductions (max 100 points deducted)
1403
- const totalDeduction = Math.min(100,
1404
- categoryDeductions.security * 1.5 + // Security issues weighted higher
1405
- categoryDeductions.hallucination * 2.0 + // AI hallucinations weighted highest
1406
- categoryDeductions.quality * 0.8 +
1407
- categoryDeductions.routes * 1.0 +
1408
- categoryDeductions.contracts * 1.0 +
1409
- categoryDeductions.dependencies * 0.5
1410
- );
1411
-
1412
- score = Math.max(0, Math.round(100 - totalDeduction));
1413
- results.score = score;
1414
-
1415
- // Determine grade
1416
- results.grade = score >= 90 ? 'A' : score >= 80 ? 'B' : score >= 70 ? 'C' : score >= 50 ? 'D' : 'F';
1417
-
1418
- // Determine verdict using the specified rules
1419
- let verdict;
1420
- const hasCritical = blockers.length > 0;
1421
- const hasHallucinations = hallucinations.filter(f => f.severity !== 'INFO').length > 0;
1422
-
1423
- if (hasCritical || score < 50) {
1424
- verdict = 'BLOCK';
1425
- results.canShip = false;
1426
- } else if (hasHallucinations || score < 75 || (opts.strict && warnings.length > 0)) {
1427
- verdict = 'WARN';
1428
- results.canShip = false;
1429
- } else {
1430
- verdict = 'SHIP';
1431
- results.canShip = true;
1432
- }
1433
-
1434
- // Build breakdown by category
1435
- const breakdown = {
1436
- security: allFindings.filter(f => categorizeFindings(f) === 'security'),
1437
- quality: allFindings.filter(f => categorizeFindings(f) === 'quality'),
1438
- hallucination: hallucinations,
1439
- routes: allFindings.filter(f => categorizeFindings(f) === 'routes'),
1440
- contracts: allFindings.filter(f => categorizeFindings(f) === 'contracts'),
1441
- dependencies: allFindings.filter(f => categorizeFindings(f) === 'dependencies'),
1442
- };
1443
-
1444
- results.breakdown = breakdown;
1445
-
1446
- const duration = Date.now() - executionStart;
949
+ const verdict = results.canShip ? 'SHIP' : blockers.length > 0 ? 'BLOCK' : 'WARN';
950
+ const duration = Date.now() - startTime;
1447
951
 
1448
952
  // ═══════════════════════════════════════════════════════════════════════════
1449
953
  // OUTPUT
@@ -1527,7 +1031,7 @@ async function runShip(args, context = {}) {
1527
1031
  if (spinner) spinner.succeed('Safe fixes applied');
1528
1032
  }
1529
1033
 
1530
- // Human-readable output using enterprise ship-output module
1034
+ // Human-readable output using ship-output module
1531
1035
  const result = {
1532
1036
  verdict,
1533
1037
  score: results.score,
@@ -1540,109 +1044,30 @@ async function runShip(args, context = {}) {
1540
1044
  duration: Date.now() - executionStart,
1541
1045
  };
1542
1046
 
1543
- // Get current tier for output formatting
1544
- const currentTier = context?.authInfo?.access?.tier || getCurrentTier() || "free";
1545
-
1546
- // Use enterprise format
1547
1047
  console.log(formatShipOutput(result, {
1548
- tier: currentTier,
1048
+ verbose: opts.verbose,
1049
+ showFix: opts.fix,
1050
+ showBadge: opts.badge,
1051
+ outputDir,
1052
+ projectPath,
1549
1053
  }));
1550
1054
 
1551
- // V7: World-class Risk Radar and Pre-flight Checklist
1552
- if (proofCertificate && !opts.quiet && !opts.json && !opts.ci) {
1553
- // Risk Radar visualization
1554
- const riskRadar = proofCertificate.calculateRiskRadar(allFindings);
1555
- console.log();
1556
- console.log(proofCertificate.renderRiskRadar(riskRadar));
1557
-
1558
- // Pre-flight Checklist
1559
- const preflight = proofCertificate.runPreflightChecklist(allFindings, proofGraph);
1560
- console.log();
1561
- console.log(proofCertificate.renderPreflightChecklist(preflight));
1562
-
1563
- // Generate and save Proof Certificate
1564
- const certificate = proofCertificate.generateProofCertificate({
1565
- projectPath,
1566
- projectName: path.basename(projectPath),
1567
- verdict,
1568
- score: results.score,
1569
- findings: allFindings,
1570
- truthpack,
1571
- proofGraph,
1572
- duration: Date.now() - executionStart,
1573
- tier: currentTier,
1574
- version: require('../../package.json').version || '1.0.0',
1575
- });
1576
-
1577
- // Save certificate
1578
- fs.mkdirSync(outputDir, { recursive: true });
1579
- fs.writeFileSync(
1580
- path.join(outputDir, 'proof-certificate.json'),
1581
- JSON.stringify(certificate.certificate, null, 2)
1582
- );
1583
-
1584
- // Show certificate ID
1585
- console.log();
1586
- console.log(` ${ansi.dim}╭${'─'.repeat(58)}╮${ansi.reset}`);
1587
- console.log(` ${ansi.dim}│${ansi.reset} ${colors.accent}📜 PROOF CERTIFICATE${ansi.reset} ${ansi.dim}│${ansi.reset}`);
1588
- console.log(` ${ansi.dim}├${'─'.repeat(58)}┤${ansi.reset}`);
1589
- console.log(` ${ansi.dim}│${ansi.reset} ID: ${ansi.cyan}${certificate.certificate.certificateId}${ansi.reset} ${ansi.dim}│${ansi.reset}`);
1590
- console.log(` ${ansi.dim}│${ansi.reset} Short Code: ${ansi.bold}${certificate.shortCode}${ansi.reset} ${ansi.dim}│${ansi.reset}`);
1591
- console.log(` ${ansi.dim}│${ansi.reset} Confidence: ${ansi.bold}${certificate.certificate.verdict.confidence}%${ansi.reset} ${ansi.dim}│${ansi.reset}`);
1592
- console.log(` ${ansi.dim}│${ansi.reset} Expires: ${certificate.certificate.expires.slice(0, 10)} ${ansi.dim}│${ansi.reset}`);
1593
- console.log(` ${ansi.dim}├${'─'.repeat(58)}┤${ansi.reset}`);
1594
- console.log(` ${ansi.dim}│${ansi.reset} ${ansi.dim}Verify at:${ansi.reset} ${ansi.cyan}${certificate.certificate.verificationUrl.slice(0, 45)}${ansi.reset} ${ansi.dim}│${ansi.reset}`);
1595
- console.log(` ${ansi.dim}╰${'─'.repeat(58)}╯${ansi.reset}`);
1596
- }
1597
-
1598
- // Pro upsell for free users
1599
- if (currentTier === 'free' && !opts.quiet) {
1600
- console.log();
1601
- console.log(` ${ansi.gray}${BOX.dTopLeft}${BOX.dHorizontal.repeat(66)}${BOX.dTopRight}${ansi.reset}`);
1602
- console.log(` ${ansi.gray}${BOX.dVertical}${ansi.reset}${' '.repeat(66)}${ansi.gray}${BOX.dVertical}${ansi.reset}`);
1603
-
1604
- if (verdict === 'SHIP') {
1605
- console.log(` ${ansi.gray}${BOX.dVertical}${ansi.reset} ${ansi.magenta}★ PRO${ansi.reset} Generate a ${ansi.bold}status badge${ansi.reset} to show off your clean code! ${ansi.gray}${BOX.dVertical}${ansi.reset}`);
1606
- console.log(` ${ansi.gray}${BOX.dVertical}${ansi.reset} Run: ${ansi.cyan}vibecheck ship --badge${ansi.reset} ${ansi.gray}${BOX.dVertical}${ansi.reset}`);
1607
- } else if (allFindings.length > 0) {
1608
- console.log(` ${ansi.gray}${BOX.dVertical}${ansi.reset} ${ansi.magenta}★ PRO${ansi.reset} Auto-fix all ${ansi.bold}${allFindings.length} issues${ansi.reset} instantly with AI ${ansi.gray}${BOX.dVertical}${ansi.reset}`);
1609
- console.log(` ${ansi.gray}${BOX.dVertical}${ansi.reset} Run: ${ansi.cyan}vibecheck fix --apply${ansi.reset} ${ansi.gray}${BOX.dVertical}${ansi.reset}`);
1610
- }
1611
-
1612
- console.log(` ${ansi.gray}${BOX.dVertical}${ansi.reset}${' '.repeat(66)}${ansi.gray}${BOX.dVertical}${ansi.reset}`);
1613
- console.log(` ${ansi.gray}${BOX.dVertical}${ansi.reset} Upgrade: ${ansi.cyan}https://vibecheckai.dev/pricing${ansi.reset} ${ansi.gray}${BOX.dVertical}${ansi.reset}`);
1614
- console.log(` ${ansi.gray}${BOX.dVertical}${ansi.reset}${' '.repeat(66)}${ansi.gray}${BOX.dVertical}${ansi.reset}`);
1615
- console.log(` ${ansi.gray}${BOX.dBottomLeft}${BOX.dHorizontal.repeat(66)}${BOX.dBottomRight}${ansi.reset}`);
1616
- console.log();
1617
- }
1618
-
1619
- // Badge file generation (PRO only)
1055
+ // Badge file generation
1620
1056
  if (opts.badge) {
1621
- const isVerified = opts.withRuntime && currentTier === 'pro';
1622
- const { data: badgeData } = renderBadgeOutput(projectPath, verdict, results.score, {
1623
- tier: currentTier,
1624
- isVerified
1625
- });
1057
+ const { data: badgeData } = renderBadgeOutput(projectPath, verdict, results.score);
1626
1058
 
1627
1059
  // Save badge info
1628
1060
  fs.mkdirSync(outputDir, { recursive: true });
1629
1061
  fs.writeFileSync(
1630
1062
  path.join(outputDir, 'badge.json'),
1631
- JSON.stringify({
1632
- ...badgeData,
1633
- verdict,
1634
- score: results.score,
1635
- tier: currentTier,
1636
- isVerified,
1637
- generatedAt: new Date().toISOString()
1638
- }, null, 2)
1063
+ JSON.stringify({ ...badgeData, verdict, score: results.score, generatedAt: new Date().toISOString() }, null, 2)
1639
1064
  );
1640
1065
  }
1641
1066
 
1642
1067
  // Earned upsell: Badge withheld when verdict != SHIP
1643
1068
  if (!results.canShip) {
1644
1069
  const currentTier = context?.authInfo?.access?.tier || "free";
1645
- if (currentTier === "pro") {
1070
+ if (entitlements.tierMeetsMinimum(currentTier, "starter")) {
1646
1071
  // User has badge access but verdict prevents it
1647
1072
  console.log(upsell.formatEarnedUpsell({
1648
1073
  cmd: "ship",
@@ -1670,92 +1095,7 @@ async function runShip(args, context = {}) {
1670
1095
  } catch {}
1671
1096
 
1672
1097
  // Exit code: 0=SHIP, 1=WARN, 2=BLOCK
1673
- let exitCode = getExitCode(verdict);
1674
-
1675
- // Deploy Gate Mode: Stricter exit code logic for CI/CD integration
1676
- if (opts.gate) {
1677
- const hasFakeFeatures = allFindings.some(f =>
1678
- f.category?.toLowerCase().includes('fake') ||
1679
- f.category?.toLowerCase().includes('mock') ||
1680
- f.type?.toLowerCase().includes('fake') ||
1681
- f.title?.toLowerCase().includes('fake') ||
1682
- f.title?.toLowerCase().includes('mock data')
1683
- );
1684
-
1685
- const hasBlockers = allFindings.some(f =>
1686
- f.severity === 'BLOCK' || f.severity === 'critical' || f.severity === 'high'
1687
- );
1688
-
1689
- const hasWarnings = allFindings.some(f =>
1690
- f.severity === 'WARN' || f.severity === 'warning' || f.severity === 'medium'
1691
- );
1692
-
1693
- // Determine gate failure based on --fail-on option
1694
- let gateBlocked = false;
1695
- let gateReason = '';
1696
-
1697
- switch (opts.failOn) {
1698
- case 'fake-features':
1699
- gateBlocked = hasFakeFeatures;
1700
- gateReason = 'Fake features detected';
1701
- break;
1702
- case 'warnings':
1703
- gateBlocked = hasWarnings || hasBlockers || hasFakeFeatures;
1704
- gateReason = hasBlockers ? 'Blockers found' : hasFakeFeatures ? 'Fake features detected' : 'Warnings found';
1705
- break;
1706
- case 'any':
1707
- gateBlocked = allFindings.length > 0;
1708
- gateReason = 'Issues detected';
1709
- break;
1710
- case 'blockers':
1711
- default:
1712
- gateBlocked = hasBlockers || hasFakeFeatures;
1713
- gateReason = hasFakeFeatures ? 'Fake features detected' : 'Blockers found';
1714
- break;
1715
- }
1716
-
1717
- if (gateBlocked) {
1718
- exitCode = EXIT.BLOCKING;
1719
-
1720
- // Output gate-specific JSON for CI/CD parsing
1721
- if (opts.json) {
1722
- console.log(JSON.stringify({
1723
- gate: {
1724
- blocked: true,
1725
- reason: gateReason,
1726
- failOn: opts.failOn,
1727
- hasFakeFeatures,
1728
- hasBlockers,
1729
- hasWarnings,
1730
- issueCount: allFindings.length,
1731
- },
1732
- verdict,
1733
- score: results.score,
1734
- canShip: false,
1735
- exitCode,
1736
- findings: allFindings.slice(0, 20), // Top 20 findings
1737
- timestamp: new Date().toISOString(),
1738
- }, null, 2));
1739
- }
1740
- } else if (opts.json) {
1741
- console.log(JSON.stringify({
1742
- gate: {
1743
- blocked: false,
1744
- reason: 'All checks passed',
1745
- failOn: opts.failOn,
1746
- hasFakeFeatures: false,
1747
- hasBlockers: false,
1748
- hasWarnings,
1749
- issueCount: allFindings.length,
1750
- },
1751
- verdict,
1752
- score: results.score,
1753
- canShip: true,
1754
- exitCode,
1755
- timestamp: new Date().toISOString(),
1756
- }, null, 2));
1757
- }
1758
- }
1098
+ const exitCode = getExitCode(verdict);
1759
1099
 
1760
1100
  // Save final results
1761
1101
  saveArtifact(runId, "summary", {
@@ -1763,8 +1103,6 @@ async function runShip(args, context = {}) {
1763
1103
  score: results.score,
1764
1104
  canShip: results.canShip,
1765
1105
  exitCode,
1766
- gateMode: opts.gate,
1767
- failOn: opts.failOn,
1768
1106
  timestamp: new Date().toISOString()
1769
1107
  });
1770
1108
 
@@ -1778,7 +1116,7 @@ async function runShip(args, context = {}) {
1778
1116
  console.error(` ${ansi.dim}${error.stack}${ansi.reset}`);
1779
1117
  }
1780
1118
 
1781
- return EXIT.INTERNAL_ERROR;
1119
+ return EXIT_CODES.ERROR;
1782
1120
  }
1783
1121
  }
1784
1122