vibecheck-ai 2.0.2 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (456) hide show
  1. package/bin/.generated +25 -0
  2. package/bin/_deprecations.js +463 -0
  3. package/bin/_router.js +46 -0
  4. package/bin/cli-hygiene.js +241 -0
  5. package/bin/dev/run-v2-torture.js +30 -0
  6. package/bin/registry.js +656 -0
  7. package/bin/runners/CLI_REFACTOR_SUMMARY.md +229 -0
  8. package/bin/runners/ENHANCEMENT_GUIDE.md +121 -0
  9. package/bin/runners/REPORT_AUDIT.md +64 -0
  10. package/bin/runners/cli-utils.js +1070 -0
  11. package/bin/runners/context/ai-task-decomposer.js +337 -0
  12. package/bin/runners/context/analyzer.js +513 -0
  13. package/bin/runners/context/api-contracts.js +427 -0
  14. package/bin/runners/context/context-diff.js +342 -0
  15. package/bin/runners/context/context-pruner.js +291 -0
  16. package/bin/runners/context/dependency-graph.js +414 -0
  17. package/bin/runners/context/generators/claude.js +107 -0
  18. package/bin/runners/context/generators/codex.js +108 -0
  19. package/bin/runners/context/generators/copilot.js +119 -0
  20. package/bin/runners/context/generators/cursor-enhanced.js +2525 -0
  21. package/bin/runners/context/generators/cursor.js +514 -0
  22. package/bin/runners/context/generators/mcp.js +169 -0
  23. package/bin/runners/context/generators/windsurf.js +180 -0
  24. package/bin/runners/context/git-context.js +304 -0
  25. package/bin/runners/context/index.js +1110 -0
  26. package/bin/runners/context/insights.js +173 -0
  27. package/bin/runners/context/mcp-server/generate-rules.js +337 -0
  28. package/bin/runners/context/mcp-server/index.js +1176 -0
  29. package/bin/runners/context/mcp-server/package.json +24 -0
  30. package/bin/runners/context/memory.js +200 -0
  31. package/bin/runners/context/monorepo.js +215 -0
  32. package/bin/runners/context/multi-repo-federation.js +404 -0
  33. package/bin/runners/context/patterns.js +253 -0
  34. package/bin/runners/context/proof-context.js +1264 -0
  35. package/bin/runners/context/security-scanner.js +541 -0
  36. package/bin/runners/context/semantic-search.js +350 -0
  37. package/bin/runners/context/shared.js +264 -0
  38. package/bin/runners/context/team-conventions.js +336 -0
  39. package/bin/runners/lib/__tests__/entitlements-v2.test.js +295 -0
  40. package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +474 -0
  41. package/bin/runners/lib/agent-firewall/change-packet/builder.js +488 -0
  42. package/bin/runners/lib/agent-firewall/change-packet/schema.json +228 -0
  43. package/bin/runners/lib/agent-firewall/change-packet/store.js +200 -0
  44. package/bin/runners/lib/agent-firewall/claims/claim-types.js +21 -0
  45. package/bin/runners/lib/agent-firewall/claims/extractor.js +303 -0
  46. package/bin/runners/lib/agent-firewall/claims/patterns.js +24 -0
  47. package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
  48. package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
  49. package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
  50. package/bin/runners/lib/agent-firewall/enforcement/gateway.js +1059 -0
  51. package/bin/runners/lib/agent-firewall/enforcement/index.js +98 -0
  52. package/bin/runners/lib/agent-firewall/enforcement/mode.js +318 -0
  53. package/bin/runners/lib/agent-firewall/enforcement/orchestrator.js +484 -0
  54. package/bin/runners/lib/agent-firewall/enforcement/proof-artifact.js +418 -0
  55. package/bin/runners/lib/agent-firewall/enforcement/schemas/change-event.schema.json +173 -0
  56. package/bin/runners/lib/agent-firewall/enforcement/schemas/intent.schema.json +181 -0
  57. package/bin/runners/lib/agent-firewall/enforcement/schemas/verdict.schema.json +222 -0
  58. package/bin/runners/lib/agent-firewall/enforcement/verdict-v2.js +333 -0
  59. package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +88 -0
  60. package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +75 -0
  61. package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +127 -0
  62. package/bin/runners/lib/agent-firewall/evidence/resolver.js +102 -0
  63. package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +213 -0
  64. package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +145 -0
  65. package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +19 -0
  66. package/bin/runners/lib/agent-firewall/fs-hook/installer.js +87 -0
  67. package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +184 -0
  68. package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +163 -0
  69. package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +107 -0
  70. package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +68 -0
  71. package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +66 -0
  72. package/bin/runners/lib/agent-firewall/index.js +200 -0
  73. package/bin/runners/lib/agent-firewall/integration/index.js +20 -0
  74. package/bin/runners/lib/agent-firewall/integration/ship-gate.js +437 -0
  75. package/bin/runners/lib/agent-firewall/intent/alignment-engine.js +634 -0
  76. package/bin/runners/lib/agent-firewall/intent/auto-detect.js +426 -0
  77. package/bin/runners/lib/agent-firewall/intent/index.js +102 -0
  78. package/bin/runners/lib/agent-firewall/intent/schema.js +352 -0
  79. package/bin/runners/lib/agent-firewall/intent/store.js +283 -0
  80. package/bin/runners/lib/agent-firewall/interception/fs-interceptor.js +502 -0
  81. package/bin/runners/lib/agent-firewall/interception/index.js +23 -0
  82. package/bin/runners/lib/agent-firewall/interceptor/base.js +308 -0
  83. package/bin/runners/lib/agent-firewall/interceptor/cursor.js +35 -0
  84. package/bin/runners/lib/agent-firewall/interceptor/vscode.js +35 -0
  85. package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +34 -0
  86. package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
  87. package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
  88. package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
  89. package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
  90. package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
  91. package/bin/runners/lib/agent-firewall/logger.js +141 -0
  92. package/bin/runners/lib/agent-firewall/policy/default-policy.json +90 -0
  93. package/bin/runners/lib/agent-firewall/policy/engine.js +103 -0
  94. package/bin/runners/lib/agent-firewall/policy/loader.js +451 -0
  95. package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +50 -0
  96. package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +50 -0
  97. package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +79 -0
  98. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +227 -0
  99. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +191 -0
  100. package/bin/runners/lib/agent-firewall/policy/rules/scope.js +93 -0
  101. package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +57 -0
  102. package/bin/runners/lib/agent-firewall/policy/schema.json +183 -0
  103. package/bin/runners/lib/agent-firewall/policy/verdict.js +54 -0
  104. package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
  105. package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
  106. package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
  107. package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
  108. package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
  109. package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
  110. package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
  111. package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
  112. package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
  113. package/bin/runners/lib/agent-firewall/risk/thresholds.js +322 -0
  114. package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
  115. package/bin/runners/lib/agent-firewall/session/collector.js +451 -0
  116. package/bin/runners/lib/agent-firewall/session/index.js +26 -0
  117. package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
  118. package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
  119. package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
  120. package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
  121. package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
  122. package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
  123. package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
  124. package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
  125. package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
  126. package/bin/runners/lib/agent-firewall/truthpack/index.js +67 -0
  127. package/bin/runners/lib/agent-firewall/truthpack/loader.js +137 -0
  128. package/bin/runners/lib/agent-firewall/unblock/planner.js +337 -0
  129. package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +118 -0
  130. package/bin/runners/lib/ai-bridge.js +416 -0
  131. package/bin/runners/lib/analysis-core.js +309 -0
  132. package/bin/runners/lib/analyzers.js +2500 -0
  133. package/bin/runners/lib/api-client.js +269 -0
  134. package/bin/runners/lib/approve-output.js +235 -0
  135. package/bin/runners/lib/artifact-envelope.js +540 -0
  136. package/bin/runners/lib/assets/vibecheck-logo.png +0 -0
  137. package/bin/runners/lib/audit-bridge.js +391 -0
  138. package/bin/runners/lib/auth-shared.js +977 -0
  139. package/bin/runners/lib/auth-truth.js +193 -0
  140. package/bin/runners/lib/auth.js +215 -0
  141. package/bin/runners/lib/authority-badge.js +425 -0
  142. package/bin/runners/lib/backup.js +62 -0
  143. package/bin/runners/lib/billing.js +107 -0
  144. package/bin/runners/lib/checkpoint.js +941 -0
  145. package/bin/runners/lib/claims.js +118 -0
  146. package/bin/runners/lib/classify-output.js +204 -0
  147. package/bin/runners/lib/cleanup/engine.js +571 -0
  148. package/bin/runners/lib/cleanup/index.js +53 -0
  149. package/bin/runners/lib/cleanup/output.js +375 -0
  150. package/bin/runners/lib/cleanup/rules.js +1060 -0
  151. package/bin/runners/lib/cli-output.js +400 -0
  152. package/bin/runners/lib/cli-ui.js +540 -0
  153. package/bin/runners/lib/compliance-bridge-new.js +0 -0
  154. package/bin/runners/lib/compliance-bridge.js +165 -0
  155. package/bin/runners/lib/contracts/auth-contract.js +202 -0
  156. package/bin/runners/lib/contracts/env-contract.js +181 -0
  157. package/bin/runners/lib/contracts/external-contract.js +206 -0
  158. package/bin/runners/lib/contracts/guard.js +168 -0
  159. package/bin/runners/lib/contracts/index.js +89 -0
  160. package/bin/runners/lib/contracts/plan-validator.js +311 -0
  161. package/bin/runners/lib/contracts/route-contract.js +199 -0
  162. package/bin/runners/lib/contracts.js +804 -0
  163. package/bin/runners/lib/default-config.js +127 -0
  164. package/bin/runners/lib/detect.js +89 -0
  165. package/bin/runners/lib/detectors-v2.js +622 -0
  166. package/bin/runners/lib/doctor/autofix.js +254 -0
  167. package/bin/runners/lib/doctor/diagnosis-receipt.js +454 -0
  168. package/bin/runners/lib/doctor/failure-signatures.js +526 -0
  169. package/bin/runners/lib/doctor/fix-script.js +336 -0
  170. package/bin/runners/lib/doctor/index.js +37 -0
  171. package/bin/runners/lib/doctor/modules/build-tools.js +453 -0
  172. package/bin/runners/lib/doctor/modules/dependencies.js +325 -0
  173. package/bin/runners/lib/doctor/modules/index.js +105 -0
  174. package/bin/runners/lib/doctor/modules/network.js +250 -0
  175. package/bin/runners/lib/doctor/modules/os-quirks.js +706 -0
  176. package/bin/runners/lib/doctor/modules/project.js +312 -0
  177. package/bin/runners/lib/doctor/modules/repo-integrity.js +485 -0
  178. package/bin/runners/lib/doctor/modules/runtime.js +224 -0
  179. package/bin/runners/lib/doctor/modules/security.js +350 -0
  180. package/bin/runners/lib/doctor/modules/system.js +213 -0
  181. package/bin/runners/lib/doctor/modules/vibecheck.js +394 -0
  182. package/bin/runners/lib/doctor/reporter.js +262 -0
  183. package/bin/runners/lib/doctor/safe-repair.js +384 -0
  184. package/bin/runners/lib/doctor/service.js +262 -0
  185. package/bin/runners/lib/doctor/types.js +113 -0
  186. package/bin/runners/lib/doctor/ui.js +263 -0
  187. package/bin/runners/lib/doctor-enhanced.js +233 -0
  188. package/bin/runners/lib/doctor-output.js +226 -0
  189. package/bin/runners/lib/doctor-v2.js +608 -0
  190. package/bin/runners/lib/drift.js +425 -0
  191. package/bin/runners/lib/enforcement.js +72 -0
  192. package/bin/runners/lib/engine/ast-cache.js +210 -0
  193. package/bin/runners/lib/engine/auth-extractor.js +211 -0
  194. package/bin/runners/lib/engine/billing-extractor.js +112 -0
  195. package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
  196. package/bin/runners/lib/engine/env-extractor.js +207 -0
  197. package/bin/runners/lib/engine/express-extractor.js +208 -0
  198. package/bin/runners/lib/engine/extractors.js +849 -0
  199. package/bin/runners/lib/engine/index.js +207 -0
  200. package/bin/runners/lib/engine/repo-index.js +514 -0
  201. package/bin/runners/lib/engine/types.js +124 -0
  202. package/bin/runners/lib/engines/accessibility-engine.js +190 -0
  203. package/bin/runners/lib/engines/api-consistency-engine.js +162 -0
  204. package/bin/runners/lib/engines/ast-cache.js +99 -0
  205. package/bin/runners/lib/engines/attack-detector.js +1192 -0
  206. package/bin/runners/lib/engines/code-quality-engine.js +255 -0
  207. package/bin/runners/lib/engines/console-logs-engine.js +115 -0
  208. package/bin/runners/lib/engines/cross-file-analysis-engine.js +268 -0
  209. package/bin/runners/lib/engines/dead-code-engine.js +198 -0
  210. package/bin/runners/lib/engines/deprecated-api-engine.js +226 -0
  211. package/bin/runners/lib/engines/empty-catch-engine.js +150 -0
  212. package/bin/runners/lib/engines/file-filter.js +131 -0
  213. package/bin/runners/lib/engines/hardcoded-secrets-engine.js +251 -0
  214. package/bin/runners/lib/engines/mock-data-engine.js +272 -0
  215. package/bin/runners/lib/engines/parallel-processor.js +71 -0
  216. package/bin/runners/lib/engines/performance-issues-engine.js +265 -0
  217. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +243 -0
  218. package/bin/runners/lib/engines/todo-fixme-engine.js +115 -0
  219. package/bin/runners/lib/engines/type-aware-engine.js +152 -0
  220. package/bin/runners/lib/engines/unsafe-regex-engine.js +225 -0
  221. package/bin/runners/lib/engines/vibecheck-engines/README.md +53 -0
  222. package/bin/runners/lib/engines/vibecheck-engines/index.js +15 -0
  223. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
  224. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
  225. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
  226. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
  227. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
  228. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
  229. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
  230. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +139 -0
  231. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
  232. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
  233. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
  234. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
  235. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
  236. package/bin/runners/lib/engines/vibecheck-engines/package.json +13 -0
  237. package/bin/runners/lib/enterprise-detect.js +603 -0
  238. package/bin/runners/lib/enterprise-init.js +942 -0
  239. package/bin/runners/lib/entitlements-v2.js +265 -0
  240. package/bin/runners/lib/entitlements.generated.js +0 -0
  241. package/bin/runners/lib/entitlements.js +340 -0
  242. package/bin/runners/lib/env-resolver.js +417 -0
  243. package/bin/runners/lib/env-template.js +66 -0
  244. package/bin/runners/lib/env.js +189 -0
  245. package/bin/runners/lib/error-handler.js +368 -0
  246. package/bin/runners/lib/error-messages.js +289 -0
  247. package/bin/runners/lib/evidence-pack.js +684 -0
  248. package/bin/runners/lib/exit-codes.js +275 -0
  249. package/bin/runners/lib/extractors/client-calls.js +990 -0
  250. package/bin/runners/lib/extractors/fastify-route-dump.js +573 -0
  251. package/bin/runners/lib/extractors/fastify-routes.js +426 -0
  252. package/bin/runners/lib/extractors/index.js +363 -0
  253. package/bin/runners/lib/extractors/next-routes.js +524 -0
  254. package/bin/runners/lib/extractors/proof-graph.js +431 -0
  255. package/bin/runners/lib/extractors/route-matcher.js +451 -0
  256. package/bin/runners/lib/extractors/truthpack-v2.js +377 -0
  257. package/bin/runners/lib/extractors/ui-bindings.js +547 -0
  258. package/bin/runners/lib/finding-id.js +69 -0
  259. package/bin/runners/lib/finding-sorter.js +89 -0
  260. package/bin/runners/lib/findings-schema.js +281 -0
  261. package/bin/runners/lib/fingerprint.js +377 -0
  262. package/bin/runners/lib/firewall-prompt.js +50 -0
  263. package/bin/runners/lib/fix-output.js +228 -0
  264. package/bin/runners/lib/global-flags.js +250 -0
  265. package/bin/runners/lib/graph/graph-builder.js +265 -0
  266. package/bin/runners/lib/graph/html-renderer.js +413 -0
  267. package/bin/runners/lib/graph/index.js +32 -0
  268. package/bin/runners/lib/graph/runtime-collector.js +215 -0
  269. package/bin/runners/lib/graph/static-extractor.js +518 -0
  270. package/bin/runners/lib/help-formatter.js +413 -0
  271. package/bin/runners/lib/html-proof-report.js +913 -0
  272. package/bin/runners/lib/html-report.js +650 -0
  273. package/bin/runners/lib/init-wizard.js +601 -0
  274. package/bin/runners/lib/interactive-menu.js +1496 -0
  275. package/bin/runners/lib/json-output.js +76 -0
  276. package/bin/runners/lib/llm.js +75 -0
  277. package/bin/runners/lib/logger.js +38 -0
  278. package/bin/runners/lib/meter.js +61 -0
  279. package/bin/runners/lib/missions/briefing.js +427 -0
  280. package/bin/runners/lib/missions/checkpoint.js +753 -0
  281. package/bin/runners/lib/missions/evidence.js +126 -0
  282. package/bin/runners/lib/missions/hardening.js +851 -0
  283. package/bin/runners/lib/missions/plan.js +648 -0
  284. package/bin/runners/lib/missions/safety-gates.js +645 -0
  285. package/bin/runners/lib/missions/schema.js +478 -0
  286. package/bin/runners/lib/missions/templates.js +317 -0
  287. package/bin/runners/lib/next-action.js +560 -0
  288. package/bin/runners/lib/packs/bundle.js +675 -0
  289. package/bin/runners/lib/packs/evidence-pack.js +671 -0
  290. package/bin/runners/lib/packs/pack-factory.js +837 -0
  291. package/bin/runners/lib/packs/permissions-pack.js +686 -0
  292. package/bin/runners/lib/packs/proof-graph-pack.js +779 -0
  293. package/bin/runners/lib/patch.js +40 -0
  294. package/bin/runners/lib/permissions/auth-model.js +213 -0
  295. package/bin/runners/lib/permissions/idor-prover.js +205 -0
  296. package/bin/runners/lib/permissions/index.js +45 -0
  297. package/bin/runners/lib/permissions/matrix-builder.js +198 -0
  298. package/bin/runners/lib/pkgjson.js +28 -0
  299. package/bin/runners/lib/policy.js +295 -0
  300. package/bin/runners/lib/polish/accessibility.js +62 -0
  301. package/bin/runners/lib/polish/analyzer.js +93 -0
  302. package/bin/runners/lib/polish/backend.js +87 -0
  303. package/bin/runners/lib/polish/configuration.js +83 -0
  304. package/bin/runners/lib/polish/documentation.js +83 -0
  305. package/bin/runners/lib/polish/frontend.js +817 -0
  306. package/bin/runners/lib/polish/index.js +27 -0
  307. package/bin/runners/lib/polish/infrastructure.js +80 -0
  308. package/bin/runners/lib/polish/internationalization.js +85 -0
  309. package/bin/runners/lib/polish/libraries.js +180 -0
  310. package/bin/runners/lib/polish/observability.js +75 -0
  311. package/bin/runners/lib/polish/performance.js +64 -0
  312. package/bin/runners/lib/polish/privacy.js +110 -0
  313. package/bin/runners/lib/polish/resilience.js +92 -0
  314. package/bin/runners/lib/polish/security.js +78 -0
  315. package/bin/runners/lib/polish/seo.js +71 -0
  316. package/bin/runners/lib/polish/styles.js +62 -0
  317. package/bin/runners/lib/polish/utils.js +104 -0
  318. package/bin/runners/lib/preflight.js +142 -0
  319. package/bin/runners/lib/prerequisites.js +149 -0
  320. package/bin/runners/lib/prove-output.js +220 -0
  321. package/bin/runners/lib/reality/correlation-detectors.js +359 -0
  322. package/bin/runners/lib/reality/index.js +318 -0
  323. package/bin/runners/lib/reality/request-hashing.js +416 -0
  324. package/bin/runners/lib/reality/request-mapper.js +453 -0
  325. package/bin/runners/lib/reality/safety-rails.js +463 -0
  326. package/bin/runners/lib/reality/semantic-snapshot.js +408 -0
  327. package/bin/runners/lib/reality/toast-detector.js +393 -0
  328. package/bin/runners/lib/reality-findings.js +84 -0
  329. package/bin/runners/lib/reality-output.js +231 -0
  330. package/bin/runners/lib/receipts.js +179 -0
  331. package/bin/runners/lib/redact.js +29 -0
  332. package/bin/runners/lib/replay/capsule-manager.js +154 -0
  333. package/bin/runners/lib/replay/index.js +263 -0
  334. package/bin/runners/lib/replay/player.js +348 -0
  335. package/bin/runners/lib/replay/recorder.js +331 -0
  336. package/bin/runners/lib/report-engine.js +626 -0
  337. package/bin/runners/lib/report-html.js +1233 -0
  338. package/bin/runners/lib/report-output.js +366 -0
  339. package/bin/runners/lib/report-templates.js +967 -0
  340. package/bin/runners/lib/report.js +135 -0
  341. package/bin/runners/lib/route-detection.js +1209 -0
  342. package/bin/runners/lib/route-truth.js +1322 -0
  343. package/bin/runners/lib/safelist/index.js +96 -0
  344. package/bin/runners/lib/safelist/integration.js +334 -0
  345. package/bin/runners/lib/safelist/matcher.js +696 -0
  346. package/bin/runners/lib/safelist/schema.js +948 -0
  347. package/bin/runners/lib/safelist/store.js +438 -0
  348. package/bin/runners/lib/sandbox/index.js +59 -0
  349. package/bin/runners/lib/sandbox/proof-chain.js +399 -0
  350. package/bin/runners/lib/sandbox/sandbox-runner.js +205 -0
  351. package/bin/runners/lib/sandbox/worktree.js +174 -0
  352. package/bin/runners/lib/scan-cache.js +330 -0
  353. package/bin/runners/lib/scan-output-schema.js +344 -0
  354. package/bin/runners/lib/scan-output.js +631 -0
  355. package/bin/runners/lib/scan-runner.js +135 -0
  356. package/bin/runners/lib/schema-validator.js +350 -0
  357. package/bin/runners/lib/schemas/ajv-validator.js +464 -0
  358. package/bin/runners/lib/schemas/contracts.schema.json +160 -0
  359. package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
  360. package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
  361. package/bin/runners/lib/schemas/finding.schema.json +100 -0
  362. package/bin/runners/lib/schemas/mission-pack.schema.json +206 -0
  363. package/bin/runners/lib/schemas/proof-graph.schema.json +176 -0
  364. package/bin/runners/lib/schemas/reality-report.schema.json +162 -0
  365. package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
  366. package/bin/runners/lib/schemas/run-request.schema.json +108 -0
  367. package/bin/runners/lib/schemas/share-pack.schema.json +180 -0
  368. package/bin/runners/lib/schemas/ship-manifest.schema.json +251 -0
  369. package/bin/runners/lib/schemas/ship-report.schema.json +117 -0
  370. package/bin/runners/lib/schemas/truthpack-v2.schema.json +303 -0
  371. package/bin/runners/lib/schemas/validator.js +465 -0
  372. package/bin/runners/lib/schemas/verdict.schema.json +140 -0
  373. package/bin/runners/lib/score-history.js +282 -0
  374. package/bin/runners/lib/security-bridge.js +249 -0
  375. package/bin/runners/lib/server-usage.js +513 -0
  376. package/bin/runners/lib/share-pack.js +239 -0
  377. package/bin/runners/lib/ship-gate.js +832 -0
  378. package/bin/runners/lib/ship-manifest.js +1153 -0
  379. package/bin/runners/lib/ship-output-enterprise.js +239 -0
  380. package/bin/runners/lib/ship-output.js +1128 -0
  381. package/bin/runners/lib/snippets.js +67 -0
  382. package/bin/runners/lib/status-output.js +340 -0
  383. package/bin/runners/lib/terminal-ui.js +356 -0
  384. package/bin/runners/lib/truth.js +1691 -0
  385. package/bin/runners/lib/ui.js +562 -0
  386. package/bin/runners/lib/unified-cli-output.js +947 -0
  387. package/bin/runners/lib/unified-output.js +197 -0
  388. package/bin/runners/lib/upsell.js +410 -0
  389. package/bin/runners/lib/usage.js +153 -0
  390. package/bin/runners/lib/validate-patch.js +156 -0
  391. package/bin/runners/lib/verdict-engine.js +628 -0
  392. package/bin/runners/lib/verification.js +345 -0
  393. package/bin/runners/lib/why-tree.js +650 -0
  394. package/bin/runners/reality/engine.js +917 -0
  395. package/bin/runners/reality/flows.js +122 -0
  396. package/bin/runners/reality/report.js +378 -0
  397. package/bin/runners/reality/session.js +193 -0
  398. package/bin/runners/runAIAgent.js +229 -0
  399. package/bin/runners/runAgent.d.ts +5 -0
  400. package/bin/runners/runAgent.js +161 -0
  401. package/bin/runners/runAllowlist.js +418 -0
  402. package/bin/runners/runApprove.js +320 -0
  403. package/bin/runners/runAudit.js +692 -0
  404. package/bin/runners/runAuth.js +731 -0
  405. package/bin/runners/runCI.js +353 -0
  406. package/bin/runners/runCheckpoint.js +530 -0
  407. package/bin/runners/runClassify.js +928 -0
  408. package/bin/runners/runCleanup.js +343 -0
  409. package/bin/runners/runContext.d.ts +4 -0
  410. package/bin/runners/runContext.js +175 -0
  411. package/bin/runners/runDoctor.js +877 -0
  412. package/bin/runners/runEvidencePack.js +362 -0
  413. package/bin/runners/runFirewall.d.ts +5 -0
  414. package/bin/runners/runFirewall.js +134 -0
  415. package/bin/runners/runFirewallHook.d.ts +5 -0
  416. package/bin/runners/runFirewallHook.js +56 -0
  417. package/bin/runners/runFix.js +1355 -0
  418. package/bin/runners/runForge.js +451 -0
  419. package/bin/runners/runGuard.js +262 -0
  420. package/bin/runners/runInit.js +1927 -0
  421. package/bin/runners/runIntent.js +906 -0
  422. package/bin/runners/runKickoff.js +878 -0
  423. package/bin/runners/runLabs.js +424 -0
  424. package/bin/runners/runLaunch.js +2000 -0
  425. package/bin/runners/runLink.js +785 -0
  426. package/bin/runners/runMcp.js +1875 -0
  427. package/bin/runners/runPacks.js +2089 -0
  428. package/bin/runners/runPolish.d.ts +4 -0
  429. package/bin/runners/runPolish.js +390 -0
  430. package/bin/runners/runPromptFirewall.js +211 -0
  431. package/bin/runners/runProve.js +1411 -0
  432. package/bin/runners/runQuickstart.js +531 -0
  433. package/bin/runners/runReality.js +2260 -0
  434. package/bin/runners/runReport.js +726 -0
  435. package/bin/runners/runRuntime.js +110 -0
  436. package/bin/runners/runSafelist.js +1190 -0
  437. package/bin/runners/runScan.js +688 -0
  438. package/bin/runners/runShield.js +1282 -0
  439. package/bin/runners/runShip.js +1660 -0
  440. package/bin/runners/runTruth.d.ts +5 -0
  441. package/bin/runners/runTruth.js +101 -0
  442. package/bin/runners/runValidate.js +179 -0
  443. package/bin/runners/runWatch.js +478 -0
  444. package/bin/runners/utils.js +360 -0
  445. package/bin/scan.js +617 -0
  446. package/bin/vibecheck.js +1617 -0
  447. package/dist/guardrail/index.d.ts +2405 -0
  448. package/dist/guardrail/index.js +9747 -0
  449. package/dist/guardrail/index.js.map +1 -0
  450. package/dist/scanner/index.d.ts +282 -0
  451. package/dist/scanner/index.js +3395 -0
  452. package/dist/scanner/index.js.map +1 -0
  453. package/package.json +123 -104
  454. package/README.md +0 -491
  455. package/dist/index.js +0 -99711
  456. package/dist/index.js.map +0 -1
@@ -0,0 +1,726 @@
1
+ /**
2
+ * vibecheck report - World-Class Enterprise Reports
3
+ *
4
+ * TIER ENFORCEMENT:
5
+ * - FREE: HTML, MD formats only
6
+ * - STARTER: + SARIF, CSV formats
7
+ * - PRO: + compliance packs, PDF export, redaction templates
8
+ *
9
+ * Enterprise-grade report generation with:
10
+ * - Beautiful interactive HTML with modern design
11
+ * - Multiple export formats (HTML, MD, JSON, SARIF, CSV, PDF)
12
+ * - Executive, Technical, Compliance report types
13
+ * - Historical trends and fix time estimates
14
+ * - Print-optimized layouts
15
+ * - White-label customization
16
+ */
17
+
18
+ const path = require("path");
19
+ const fs = require("fs");
20
+ const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
21
+ const { EXIT } = require("./lib/exit-codes");
22
+ const { ensureScanResults } = require("./lib/prerequisites");
23
+
24
+ // Entitlements enforcement
25
+ let entitlements;
26
+ try {
27
+ entitlements = require("./lib/entitlements-v2");
28
+ } catch {
29
+ // Fallback: allow all features if entitlements not available
30
+ entitlements = {
31
+ getLimits: () => ({ reportFormats: ["html", "md", "json", "sarif", "csv", "pdf"] }),
32
+ getTier: async () => "pro",
33
+ enforce: async () => ({ allowed: true }),
34
+ EXIT_FEATURE_NOT_ALLOWED: 1,
35
+ };
36
+ }
37
+
38
+ // Report modules
39
+ let reportEngine, reportHtml, reportTemplates;
40
+ try {
41
+ reportEngine = require("./lib/report-engine");
42
+ } catch (e) {
43
+ console.error("Warning: report-engine not found:", e.message);
44
+ }
45
+ try {
46
+ reportHtml = require("./lib/report-html");
47
+ } catch (e) {
48
+ console.error("Warning: report-html not found:", e.message);
49
+ }
50
+ try {
51
+ reportTemplates = require("./lib/report-templates");
52
+ } catch (e) {
53
+ console.error("Warning: report-templates not found:", e.message);
54
+ }
55
+
56
+ // ═══════════════════════════════════════════════════════════════════════════════
57
+ // ENHANCED TERMINAL UI & OUTPUT MODULES
58
+ // ═══════════════════════════════════════════════════════════════════════════════
59
+
60
+ const {
61
+ ansi,
62
+ colors,
63
+ icons,
64
+ Spinner,
65
+ renderSection,
66
+ formatDuration,
67
+ } = require("./lib/terminal-ui");
68
+
69
+ const {
70
+ BANNER,
71
+ formatHelp,
72
+ renderReportInfo,
73
+ renderSuccess,
74
+ renderError,
75
+ } = require("./lib/report-output");
76
+
77
+ function parseArgs(args) {
78
+ // Parse global flags first
79
+ const { flags: globalFlags, cleanArgs } = parseGlobalFlags(args);
80
+
81
+ const opts = {
82
+ type: "technical",
83
+ format: "html",
84
+ path: globalFlags.path || ".",
85
+ output: globalFlags.output || null,
86
+ logo: null,
87
+ company: null,
88
+ theme: "dark",
89
+ framework: "SOC2",
90
+ includeVerify: false,
91
+ includeTrends: false,
92
+ redactPaths: false,
93
+ maxFindings: 50,
94
+ open: false,
95
+ help: globalFlags.help || false,
96
+ quiet: globalFlags.quiet || false,
97
+ json: globalFlags.json || false,
98
+ noBanner: globalFlags.noBanner || false,
99
+ ci: globalFlags.ci || false,
100
+ verbose: globalFlags.verbose || false,
101
+ };
102
+
103
+ // Parse command-specific args
104
+ for (let i = 0; i < cleanArgs.length; i++) {
105
+ const a = cleanArgs[i];
106
+ if (a === "--type" || a === "-t") opts.type = cleanArgs[++i];
107
+ if (a === "--format" || a === "-f") opts.format = cleanArgs[++i];
108
+ if (a === "--output" || a === "-o") opts.output = cleanArgs[++i];
109
+ if (a === "--logo") opts.logo = cleanArgs[++i];
110
+ if (a === "--company") opts.company = cleanArgs[++i];
111
+ if (a === "--theme") opts.theme = cleanArgs[++i];
112
+ if (a === "--framework") opts.framework = args[++i];
113
+ if (a === "--light") opts.theme = "light";
114
+ if (a === "--dark") opts.theme = "dark";
115
+ if (a === "--include-verify") opts.includeVerify = true;
116
+ if (a === "--include-trends" || a === "--trends") opts.includeTrends = true;
117
+ if (a === "--redact-paths" || a === "--redact") opts.redactPaths = true;
118
+ if (a === "--max-findings") opts.maxFindings = parseInt(args[++i]) || 50;
119
+ if (a.startsWith("--path=")) opts.path = a.split("=")[1];
120
+ if (a === "--path" || a === "-p") opts.path = args[++i];
121
+ if (a === "--open") opts.open = true;
122
+ if (a === "--quiet" || a === "-q") opts.quiet = true;
123
+ if (a === "--help" || a === "-h") opts.help = true;
124
+ }
125
+
126
+ return opts;
127
+ }
128
+
129
+ function printHelp(showBanner = true) {
130
+ if (showBanner && shouldShowBanner({})) {
131
+ console.log(BANNER);
132
+ }
133
+ console.log(formatHelp());
134
+ }
135
+
136
+ async function runReport(args) {
137
+ const opts = parseArgs(args);
138
+
139
+ if (opts.help) {
140
+ printHelp(shouldShowBanner(opts));
141
+ return 0;
142
+ }
143
+
144
+ const projectPath = path.resolve(opts.path);
145
+ const outputDir = path.join(projectPath, ".vibecheck");
146
+ const projectName = path.basename(projectPath);
147
+
148
+ // TIER ENFORCEMENT
149
+ const format = opts.format.toLowerCase();
150
+ const tier = await entitlements.getTier({ projectPath });
151
+ const limits = entitlements.getLimits(tier);
152
+ const allowedFormats = limits.reportFormats || ["html", "md"];
153
+
154
+ // Check format access
155
+ if (!allowedFormats.includes(format) && format !== "json") {
156
+ if (format === "sarif" || format === "csv") {
157
+ const access = await entitlements.enforce("report.sarif_csv", {
158
+ projectPath,
159
+ silent: false,
160
+ });
161
+ if (!access.allowed) {
162
+ console.log(`\n ${colors.warning}${icons.warning}${ansi.reset} ${ansi.dim}HTML and MD formats are available on FREE tier${ansi.reset}`);
163
+ console.log(` ${ansi.dim}Upgrade to STARTER for SARIF/CSV export${ansi.reset}\n`);
164
+ return entitlements.EXIT_FEATURE_NOT_ALLOWED;
165
+ }
166
+ }
167
+
168
+ if (format === "pdf") {
169
+ const access = await entitlements.enforce("report.pdf_export", {
170
+ projectPath,
171
+ silent: false,
172
+ });
173
+ if (!access.allowed) {
174
+ console.log(`\n ${colors.warning}${icons.warning}${ansi.reset} ${ansi.dim}PDF export requires PRO tier${ansi.reset}`);
175
+ console.log(` ${ansi.dim}HTML reports can be printed to PDF from browser${ansi.reset}\n`);
176
+ return entitlements.EXIT_FEATURE_NOT_ALLOWED;
177
+ }
178
+ }
179
+ }
180
+
181
+ // Compliance reports require PRO
182
+ if (opts.type === "compliance") {
183
+ const access = await entitlements.enforce("report.compliance_packs", {
184
+ projectPath,
185
+ silent: false,
186
+ });
187
+ if (!access.allowed) {
188
+ console.log(`\n ${colors.warning}${icons.warning}${ansi.reset} ${ansi.dim}Executive and technical reports available on lower tiers${ansi.reset}`);
189
+ return entitlements.EXIT_FEATURE_NOT_ALLOWED;
190
+ }
191
+ }
192
+
193
+ // Display banner and report info
194
+ if (!opts.quiet) {
195
+ if (shouldShowBanner(opts)) {
196
+ console.log(BANNER);
197
+ console.log(renderReportInfo(opts.type, opts.format, null));
198
+ console.log('');
199
+ }
200
+ }
201
+
202
+ // Progress spinner
203
+ const spinner = new Spinner({ color: colors.accent });
204
+ spinner.start(`Generating ${opts.type} report`);
205
+
206
+ // Auto-run scan if results are missing (unless in CI or explicitly disabled)
207
+ const scanPrereq = await ensureScanResults(projectPath, {
208
+ quiet: opts.quiet,
209
+ json: opts.json,
210
+ ci: opts.ci,
211
+ colors,
212
+ icons,
213
+ ansi,
214
+ });
215
+
216
+ if (scanPrereq.ran && !scanPrereq.success && !opts.quiet) {
217
+ spinner.warn("Auto-run scan failed - continuing with available data");
218
+ }
219
+
220
+ // Load ship results (prefer ship results, fall back to scan results)
221
+ let shipResults = loadShipResults(projectPath, outputDir);
222
+
223
+ // If no ship results, try to load scan results
224
+ if (!shipResults) {
225
+ const scanResultsPath = path.join(projectPath, ".vibecheck", "results", "latest.json");
226
+ if (fs.existsSync(scanResultsPath)) {
227
+ try {
228
+ const scanData = JSON.parse(fs.readFileSync(scanResultsPath, "utf8"));
229
+ shipResults = {
230
+ score: scanData.result?.score || scanData.score || 0,
231
+ verdict: scanData.result?.verdict || scanData.verdict || "UNKNOWN",
232
+ findings: scanData.result?.findings || scanData.findings || [],
233
+ truthpack: scanData.truthpack || null,
234
+ };
235
+ } catch {}
236
+ }
237
+ }
238
+
239
+ if (!shipResults) {
240
+ spinner.warn("No scan results found - using demo data");
241
+ if (!opts.quiet) {
242
+ console.log(` ${ansi.dim}Tip: Run 'vibecheck scan' first for real results.${ansi.reset}\n`);
243
+ }
244
+ shipResults = getDemoData();
245
+ }
246
+
247
+ // Build comprehensive report data
248
+ spinner.update("Processing findings");
249
+ let reportData;
250
+ if (reportEngine) {
251
+ reportData = reportEngine.buildReportData(shipResults, {
252
+ projectName,
253
+ repoRoot: projectPath,
254
+ includeTrends: opts.includeTrends,
255
+ });
256
+ } else {
257
+ reportData = buildBasicReportData(shipResults, projectName);
258
+ }
259
+
260
+ // Generate report content
261
+ spinner.update(`Rendering ${format.toUpperCase()} output`);
262
+ let reportContent = "";
263
+ let fileExtension = format;
264
+
265
+ try {
266
+ switch (format) {
267
+ case "html":
268
+ // Debug: Log which HTML generator will be used
269
+ if (opts.verbose || opts.type === "technical") {
270
+ if (reportHtml && typeof reportHtml.generateWorldClassHTML === 'function') {
271
+ console.log(` ${ansi.dim}Using world-class HTML generator${ansi.reset}`);
272
+ } else {
273
+ console.log(` ${ansi.dim}Using basic HTML generator (report-html module not available)${ansi.reset}`);
274
+ }
275
+ }
276
+ reportContent = generateHTMLReport(reportData, opts);
277
+ break;
278
+ case "md":
279
+ case "markdown":
280
+ reportContent = generateMarkdownReport(reportData, opts);
281
+ fileExtension = "md";
282
+ break;
283
+ case "json":
284
+ reportContent = generateJSONReport(reportData, opts);
285
+ break;
286
+ case "sarif":
287
+ reportContent = generateSARIFReport(reportData, opts);
288
+ break;
289
+ case "csv":
290
+ reportContent = generateCSVReport(reportData, opts);
291
+ break;
292
+ case "pdf":
293
+ // PDF requires HTML first, then conversion
294
+ reportContent = await generatePDFReport(reportData, opts, outputDir);
295
+ break;
296
+ default:
297
+ spinner.fail(`Unknown format: ${format}`);
298
+ console.log(` ${ansi.dim}Supported: html, md, json, sarif, csv, pdf${ansi.reset}`);
299
+ return EXIT.USER_ERROR;
300
+ }
301
+ } catch (err) {
302
+ spinner.fail(`Failed to generate report: ${err.message}`);
303
+ return EXIT.INTERNAL_ERROR;
304
+ }
305
+
306
+ // Determine output path
307
+ const outputFileName = opts.output || path.join(outputDir, `report.${fileExtension}`);
308
+ const outputDirPath = path.dirname(outputFileName);
309
+
310
+ // Ensure output directory exists
311
+ if (!fs.existsSync(outputDirPath)) {
312
+ fs.mkdirSync(outputDirPath, { recursive: true });
313
+ }
314
+
315
+ // Write report (always overwrite to ensure fresh content)
316
+ spinner.update("Writing report");
317
+ fs.writeFileSync(outputFileName, reportContent, 'utf8');
318
+
319
+ // If this is the default report.html, also update the timestamp to help with cache busting
320
+ if (!opts.output && fileExtension === 'html') {
321
+ try {
322
+ // Touch the file to update its modification time
323
+ const now = new Date();
324
+ fs.utimesSync(outputFileName, now, now);
325
+ } catch {
326
+ // Ignore errors on utimes
327
+ }
328
+ }
329
+
330
+ // Save report history for trend analysis
331
+ saveReportHistory(outputDir, reportData);
332
+
333
+ spinner.succeed("Report generated");
334
+ console.log("");
335
+
336
+ // Print success message using design system
337
+ console.log(renderSuccess(outputFileName, opts.format));
338
+
339
+ // Open in browser if requested
340
+ if (opts.open && format === "html") {
341
+ openInBrowser(outputFileName);
342
+ }
343
+
344
+ return 0;
345
+ }
346
+
347
+ // ============================================================================
348
+ // DATA LOADING
349
+ // ============================================================================
350
+
351
+ function loadShipResults(projectPath, outputDir) {
352
+ const sources = [
353
+ path.join(outputDir, "ship_report.json"),
354
+ path.join(outputDir, "report.json"),
355
+ path.join(outputDir, "truth", "truthpack.json"),
356
+ ];
357
+
358
+ let results = null;
359
+ for (const src of sources) {
360
+ if (fs.existsSync(src)) {
361
+ try {
362
+ results = JSON.parse(fs.readFileSync(src, "utf8"));
363
+ break;
364
+ } catch {
365
+ continue;
366
+ }
367
+ }
368
+ }
369
+
370
+ // Also load reality report if available
371
+ const realitySources = [
372
+ path.join(outputDir, "reality", "last_reality.json"),
373
+ path.join(outputDir, "reality_report.json"),
374
+ ];
375
+
376
+ for (const src of realitySources) {
377
+ if (fs.existsSync(src)) {
378
+ try {
379
+ const realityData = JSON.parse(fs.readFileSync(src, "utf8"));
380
+ if (results) {
381
+ results.reality = realityData;
382
+ } else {
383
+ results = { reality: realityData };
384
+ }
385
+ break;
386
+ } catch {
387
+ continue;
388
+ }
389
+ }
390
+ }
391
+
392
+ return results;
393
+ }
394
+
395
+ function getDemoData() {
396
+ return {
397
+ score: 72,
398
+ verdict: "WARN",
399
+ findings: [
400
+ { id: "SEC001", severity: "BLOCK", type: "secret", message: "API key exposed in source code", title: "Exposed API Key", file: "src/config.ts", line: 42, fix: "Move to environment variable" },
401
+ { id: "AUTH001", severity: "BLOCK", type: "auth", message: "Authentication bypass in admin route", title: "Auth Bypass Vulnerability", file: "src/routes/admin.ts", line: 15, fix: "Add auth middleware" },
402
+ { id: "MOCK001", severity: "WARN", type: "mock", message: "Mock data used in production path", title: "Mock Data in Production", file: "src/api/users.ts", line: 88, fix: "Remove mock data fallback" },
403
+ { id: "ERR001", severity: "WARN", type: "error", message: "Empty catch block in payment flow", title: "Swallowed Exception", file: "src/billing/checkout.ts", line: 156, fix: "Add error handling" },
404
+ { id: "CFG001", severity: "INFO", type: "config", message: "Hardcoded timeout value", title: "Hardcoded Configuration", file: "src/utils/http.ts", line: 23, fix: "Move to config" },
405
+ { id: "DBG001", severity: "INFO", type: "quality", message: "Console.log statement", title: "Debug Statement", file: "src/debug.ts", line: 5, fix: "Remove or use logger" },
406
+ ],
407
+ categoryScores: { security: 65, auth: 50, billing: 90, quality: 75 },
408
+ truthpack: {
409
+ routes: { server: Array(12).fill({}) },
410
+ env: { vars: Array(8).fill("") },
411
+ },
412
+ reality: {
413
+ coverage: { clientCallsMapped: 87, uiActionsVerified: 95, authRoutes: 100 },
414
+ latencyP95: 412,
415
+ brokenFlows: [
416
+ {
417
+ title: "User cannot complete checkout flow",
418
+ severity: "BLOCK",
419
+ steps: [
420
+ { type: "ui", label: "Click 'Add to Cart'" },
421
+ { type: "api", label: "POST /api/cart" },
422
+ { type: "ui", label: "Click 'Checkout'" },
423
+ { type: "api", label: "POST /api/orders" },
424
+ { type: "error", label: "500 Internal Server Error" },
425
+ ],
426
+ },
427
+ ],
428
+ },
429
+ };
430
+ }
431
+
432
+ function buildBasicReportData(shipResults, projectName) {
433
+ const findings = shipResults?.findings || [];
434
+ const reality = shipResults?.reality || null;
435
+
436
+ return {
437
+ meta: {
438
+ projectName,
439
+ generatedAt: new Date().toISOString(),
440
+ version: "2.0.0",
441
+ reportId: `VC-${Date.now().toString(36).toUpperCase()}`,
442
+ },
443
+ summary: {
444
+ score: shipResults?.score || 0,
445
+ verdict: shipResults?.verdict || (shipResults?.canShip ? "SHIP" : "WARN"),
446
+ totalFindings: findings.length,
447
+ severityCounts: {
448
+ critical: findings.filter(f => f.severity === "BLOCK" || f.severity === "critical").length,
449
+ high: findings.filter(f => f.severity === "high").length,
450
+ medium: findings.filter(f => f.severity === "WARN" || f.severity === "medium").length,
451
+ low: findings.filter(f => f.severity === "low" || f.severity === "INFO").length,
452
+ },
453
+ categoryScores: shipResults?.categoryScores || {},
454
+ },
455
+ findings: findings.map((f, i) => ({ ...f, id: f.id || `F${String(i + 1).padStart(3, "0")}` })),
456
+ fixEstimates: { humanReadable: calculateFixTime(findings), totalMinutes: 120 },
457
+ truthpack: shipResults?.truthpack || null,
458
+ reality: reality,
459
+ };
460
+ }
461
+
462
+ // ============================================================================
463
+ // REPORT GENERATORS
464
+ // ============================================================================
465
+
466
+ function generateHTMLReport(reportData, opts) {
467
+ // Route to appropriate template based on type
468
+ switch (opts.type) {
469
+ case "executive":
470
+ if (reportTemplates?.generateEnhancedExecutiveReport) {
471
+ return reportTemplates.generateEnhancedExecutiveReport(
472
+ convertToLegacyFormat(reportData),
473
+ opts
474
+ );
475
+ }
476
+ // Fall through if template not available
477
+ break;
478
+ case "compliance":
479
+ if (reportTemplates?.generateEnhancedComplianceReport) {
480
+ return reportTemplates.generateEnhancedComplianceReport(
481
+ convertToLegacyFormat(reportData),
482
+ opts
483
+ );
484
+ }
485
+ // Fall through if template not available
486
+ break;
487
+ default:
488
+ // Technical report - ALWAYS use world-class HTML generator
489
+ if (reportHtml && typeof reportHtml.generateWorldClassHTML === 'function') {
490
+ try {
491
+ // Ensure reportData has required structure
492
+ if (!reportData.meta) {
493
+ reportData.meta = { projectName: 'Unknown', generatedAt: new Date().toISOString(), version: '2.0.0' };
494
+ }
495
+ if (!reportData.summary) {
496
+ reportData.summary = { score: 0, verdict: 'WARN', totalFindings: 0, severityCounts: {} };
497
+ }
498
+ if (!reportData.findings) {
499
+ reportData.findings = [];
500
+ }
501
+
502
+ return reportHtml.generateWorldClassHTML(reportData, opts);
503
+ } catch (err) {
504
+ console.error(`\n ${colors.error}${icons.error}${ansi.reset} Error generating world-class HTML: ${err.message}`);
505
+ if (opts.verbose) {
506
+ console.error(err.stack);
507
+ }
508
+ // Fall through to basic HTML only on error
509
+ }
510
+ } else {
511
+ console.warn(`\n ${colors.warning}${icons.warning}${ansi.reset} report-html module not available, using basic HTML template`);
512
+ }
513
+ break;
514
+ }
515
+
516
+ // Fallback to basic HTML only if world-class generator failed or not available
517
+ console.warn(` ${ansi.dim}Using basic HTML fallback${ansi.reset}`);
518
+ return generateBasicHTML(reportData, opts);
519
+ }
520
+
521
+ function generateMarkdownReport(reportData, opts) {
522
+ if (reportEngine?.exportToMarkdown) {
523
+ return reportEngine.exportToMarkdown(reportData, opts);
524
+ }
525
+ return generateBasicMarkdown(reportData, opts);
526
+ }
527
+
528
+ function generateJSONReport(reportData, opts) {
529
+ if (reportEngine?.exportToJSON) {
530
+ return reportEngine.exportToJSON(reportData);
531
+ }
532
+ return JSON.stringify(reportData, null, 2);
533
+ }
534
+
535
+ function generateSARIFReport(reportData, opts) {
536
+ if (reportEngine?.exportToSARIF) {
537
+ return JSON.stringify(reportEngine.exportToSARIF(reportData), null, 2);
538
+ }
539
+ // Basic SARIF fallback
540
+ return JSON.stringify({
541
+ $schema: "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
542
+ version: "2.1.0",
543
+ runs: [{
544
+ tool: { driver: { name: "vibecheck", version: "2.0.0" } },
545
+ results: reportData.findings.map(f => ({
546
+ ruleId: f.id,
547
+ level: f.severity === "critical" ? "error" : "warning",
548
+ message: { text: f.title || f.message },
549
+ })),
550
+ }],
551
+ }, null, 2);
552
+ }
553
+
554
+ function generateCSVReport(reportData, opts) {
555
+ if (reportEngine?.exportToCSV) {
556
+ return reportEngine.exportToCSV(reportData);
557
+ }
558
+ // Basic CSV fallback
559
+ const headers = ["ID", "Severity", "Title", "File", "Line", "Fix"];
560
+ const rows = reportData.findings.map(f => [
561
+ f.id || "",
562
+ f.severity || "",
563
+ `"${(f.title || f.message || "").replace(/"/g, '""')}"`,
564
+ f.file || "",
565
+ f.line || "",
566
+ `"${(f.fix || "").replace(/"/g, '""')}"`,
567
+ ]);
568
+ return [headers.join(","), ...rows.map(r => r.join(","))].join("\n");
569
+ }
570
+
571
+ async function generatePDFReport(reportData, opts, outputDir) {
572
+ // Generate HTML first
573
+ const htmlContent = generateHTMLReport(reportData, { ...opts, format: "html" });
574
+ const tempHtmlPath = path.join(outputDir, "temp_report.html");
575
+ fs.writeFileSync(tempHtmlPath, htmlContent);
576
+
577
+ // Try to use puppeteer for PDF generation
578
+ try {
579
+ const puppeteer = require("puppeteer");
580
+ const browser = await puppeteer.launch({ headless: "new" });
581
+ const page = await browser.newPage();
582
+ await page.setContent(htmlContent, { waitUntil: "networkidle0" });
583
+ const pdf = await page.pdf({
584
+ format: "Letter",
585
+ printBackground: true,
586
+ margin: { top: "0.5in", right: "0.5in", bottom: "0.5in", left: "0.5in" },
587
+ });
588
+ await browser.close();
589
+
590
+ // Clean up temp file
591
+ try { fs.unlinkSync(tempHtmlPath); } catch {}
592
+
593
+ return pdf;
594
+ } catch (e) {
595
+ // Clean up temp file
596
+ try { fs.unlinkSync(tempHtmlPath); } catch {}
597
+
598
+ throw new Error(
599
+ `PDF generation requires puppeteer. Install with: npm install puppeteer\n` +
600
+ `Or use --format=html and print to PDF from your browser.`
601
+ );
602
+ }
603
+ }
604
+
605
+ function convertToLegacyFormat(reportData) {
606
+ return {
607
+ projectName: reportData.meta.projectName,
608
+ generatedAt: reportData.meta.generatedAt,
609
+ reportId: reportData.meta.reportId,
610
+ score: reportData.summary.score,
611
+ verdict: reportData.summary.verdict,
612
+ findings: reportData.findings,
613
+ categoryScores: reportData.summary.categoryScores,
614
+ reality: reportData.reality,
615
+ };
616
+ }
617
+
618
+ // ============================================================================
619
+ // FALLBACK GENERATORS
620
+ // ============================================================================
621
+
622
+ function generateBasicHTML(reportData, opts) {
623
+ const { meta, summary } = reportData;
624
+ const verdictColor = summary.verdict === "SHIP" ? "#10b981" : summary.verdict === "WARN" ? "#f59e0b" : "#ef4444";
625
+
626
+ return `<!DOCTYPE html>
627
+ <html lang="en">
628
+ <head>
629
+ <meta charset="UTF-8">
630
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
631
+ <title>VibeCheck Report - ${meta.projectName}</title>
632
+ <style>
633
+ body { font-family: -apple-system, sans-serif; max-width: 800px; margin: 0 auto; padding: 40px; background: #0f172a; color: #f8fafc; }
634
+ .header { border-bottom: 2px solid #334155; padding-bottom: 20px; margin-bottom: 30px; }
635
+ .score { font-size: 4rem; font-weight: 800; text-align: center; margin: 40px 0; color: ${verdictColor}; }
636
+ .verdict { display: inline-block; padding: 12px 24px; border-radius: 50px; font-weight: 600; background: ${verdictColor}22; color: ${verdictColor}; }
637
+ .section { margin: 30px 0; }
638
+ h2 { color: #94a3b8; font-size: 0.875rem; text-transform: uppercase; letter-spacing: 0.1em; }
639
+ .finding { background: #1e293b; padding: 16px; border-radius: 8px; margin: 12px 0; border-left: 4px solid #3b82f6; }
640
+ .footer { margin-top: 60px; text-align: center; color: #64748b; }
641
+ </style>
642
+ </head>
643
+ <body>
644
+ <div class="header">
645
+ <h1>Ship Readiness Report</h1>
646
+ <p>Project: ${meta.projectName} · ${new Date(meta.generatedAt).toLocaleString()}</p>
647
+ </div>
648
+ <div class="score">${summary.score}</div>
649
+ <div style="text-align: center;"><span class="verdict">${summary.verdict}</span></div>
650
+ <div class="section">
651
+ <h2>Findings (${summary.totalFindings})</h2>
652
+ ${reportData.findings.slice(0, 10).map(f => `
653
+ <div class="finding">
654
+ <strong>${(f.severity || 'WARN').toUpperCase()}</strong>: ${f.title || f.message}
655
+ ${f.file ? `<br><code>${f.file}${f.line ? `:${f.line}` : ""}</code>` : ""}
656
+ </div>
657
+ `).join("")}
658
+ </div>
659
+ <div class="footer">Generated by VibeCheck · ${meta.reportId}</div>
660
+ </body>
661
+ </html>`;
662
+ }
663
+
664
+ function generateBasicMarkdown(reportData, opts) {
665
+ const { meta, summary, findings } = reportData;
666
+ return `# VibeCheck Report
667
+
668
+ **Project:** ${meta.projectName}
669
+ **Generated:** ${new Date(meta.generatedAt).toLocaleString()}
670
+ **Score:** ${summary.score}/100
671
+ **Verdict:** ${summary.verdict}
672
+
673
+ ## Findings (${summary.totalFindings})
674
+
675
+ ${findings.slice(0, 20).map(f => `- **${(f.severity || 'WARN').toUpperCase()}**: ${f.title || f.message}${f.file ? ` (\`${f.file}\`)` : ""}`).join("\n")}
676
+
677
+ ---
678
+ *Generated by VibeCheck · ${meta.reportId}*
679
+ `;
680
+ }
681
+
682
+ // ============================================================================
683
+ // UTILITIES
684
+ // ============================================================================
685
+
686
+ function calculateFixTime(findings) {
687
+ if (!findings || findings.length === 0) return "0h";
688
+
689
+ const minutes = findings.reduce((total, f) => {
690
+ const sev = (f.severity || "").toLowerCase();
691
+ const time = { block: 60, critical: 60, high: 45, warn: 20, medium: 20, info: 10, low: 10 };
692
+ return total + (time[sev] || 15);
693
+ }, 0);
694
+
695
+ if (minutes < 60) return `${minutes}m`;
696
+ const hours = Math.round(minutes / 60 * 10) / 10;
697
+ return hours > 8 ? `${Math.ceil(hours / 8)}d` : `${hours}h`;
698
+ }
699
+
700
+ function saveReportHistory(outputDir, reportData) {
701
+ try {
702
+ const historyDir = path.join(outputDir, "history");
703
+ if (!fs.existsSync(historyDir)) {
704
+ fs.mkdirSync(historyDir, { recursive: true });
705
+ }
706
+
707
+ const timestamp = new Date().toISOString().split("T")[0];
708
+ const historyFile = path.join(historyDir, `${timestamp}.json`);
709
+
710
+ fs.writeFileSync(historyFile, JSON.stringify({
711
+ meta: reportData.meta,
712
+ summary: reportData.summary,
713
+ }, null, 2));
714
+ } catch {
715
+ // Silently fail history saving
716
+ }
717
+ }
718
+
719
+ function openInBrowser(filePath) {
720
+ const { exec } = require("child_process");
721
+ const cmd = process.platform === "darwin" ? "open" :
722
+ process.platform === "win32" ? "start" : "xdg-open";
723
+ exec(`${cmd} "${filePath}"`);
724
+ }
725
+
726
+ module.exports = { runReport };