vibecheck-ai 2.0.1 → 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,913 @@
1
+ /**
2
+ * HTML Proof Report Generator
3
+ *
4
+ * Creates a beautiful, self-contained HTML report that proves your app works.
5
+ * Includes embedded video, network evidence, and clear verdicts.
6
+ *
7
+ * Designed to be shareable: drop into a PR, CI artifact, or send to stakeholders.
8
+ */
9
+
10
+ "use strict";
11
+
12
+ const fs = require("fs");
13
+ const path = require("path");
14
+
15
+ // ═══════════════════════════════════════════════════════════════════════════════
16
+ // HTML TEMPLATE
17
+ // ═══════════════════════════════════════════════════════════════════════════════
18
+
19
+ function escapeHtml(str) {
20
+ if (!str) return '';
21
+ return String(str)
22
+ .replace(/&/g, '&')
23
+ .replace(/</g, '&lt;')
24
+ .replace(/>/g, '&gt;')
25
+ .replace(/"/g, '&quot;')
26
+ .replace(/'/g, '&#39;');
27
+ }
28
+
29
+ function formatDuration(ms) {
30
+ if (!ms) return '0s';
31
+ if (ms < 1000) return `${ms}ms`;
32
+ if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
33
+ const mins = Math.floor(ms / 60000);
34
+ const secs = Math.floor((ms % 60000) / 1000);
35
+ return `${mins}m ${secs}s`;
36
+ }
37
+
38
+ function generateHtmlProofReport(data) {
39
+ const {
40
+ verdict,
41
+ projectName,
42
+ url,
43
+ startedAt,
44
+ finishedAt,
45
+ durationMs,
46
+ findings = [],
47
+ coverage = null,
48
+ passes = {},
49
+ artifacts = {},
50
+ meta = {},
51
+ stabilityRuns = 1
52
+ } = data;
53
+
54
+ const blocks = findings.filter(f => f.severity === 'BLOCK').length;
55
+ const warns = findings.filter(f => f.severity === 'WARN').length;
56
+
57
+ const verdictConfig = {
58
+ SHIP: { emoji: '✅', color: '#10b981', bg: '#ecfdf5', label: 'PROVED REAL' },
59
+ CLEAN: { emoji: '✅', color: '#10b981', bg: '#ecfdf5', label: 'PROVED REAL' },
60
+ WARN: { emoji: '⚠️', color: '#f59e0b', bg: '#fffbeb', label: 'WARNINGS FOUND' },
61
+ BLOCK: { emoji: '🛑', color: '#ef4444', bg: '#fef2f2', label: 'NOT PROVED' }
62
+ };
63
+
64
+ const v = verdictConfig[verdict] || verdictConfig.BLOCK;
65
+
66
+ // Group findings by category
67
+ const findingsByCategory = {};
68
+ for (const f of findings) {
69
+ const cat = f.category || 'Other';
70
+ if (!findingsByCategory[cat]) findingsByCategory[cat] = [];
71
+ findingsByCategory[cat].push(f);
72
+ }
73
+
74
+ // Build HTML
75
+ return `<!DOCTYPE html>
76
+ <html lang="en">
77
+ <head>
78
+ <meta charset="UTF-8">
79
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
80
+ <title>Reality Proof: ${escapeHtml(projectName)}</title>
81
+ <style>
82
+ :root {
83
+ --verdict-color: ${v.color};
84
+ --verdict-bg: ${v.bg};
85
+ --primary: #6366f1;
86
+ --success: #10b981;
87
+ --warning: #f59e0b;
88
+ --danger: #ef4444;
89
+ --gray-50: #f9fafb;
90
+ --gray-100: #f3f4f6;
91
+ --gray-200: #e5e7eb;
92
+ --gray-300: #d1d5db;
93
+ --gray-400: #9ca3af;
94
+ --gray-500: #6b7280;
95
+ --gray-600: #4b5563;
96
+ --gray-700: #374151;
97
+ --gray-800: #1f2937;
98
+ --gray-900: #111827;
99
+ }
100
+
101
+ * {
102
+ margin: 0;
103
+ padding: 0;
104
+ box-sizing: border-box;
105
+ }
106
+
107
+ body {
108
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
109
+ background: var(--gray-50);
110
+ color: var(--gray-800);
111
+ line-height: 1.6;
112
+ }
113
+
114
+ .container {
115
+ max-width: 1200px;
116
+ margin: 0 auto;
117
+ padding: 2rem;
118
+ }
119
+
120
+ /* Header */
121
+ .header {
122
+ text-align: center;
123
+ margin-bottom: 3rem;
124
+ }
125
+
126
+ .logo {
127
+ font-size: 2rem;
128
+ font-weight: 700;
129
+ color: var(--primary);
130
+ margin-bottom: 0.5rem;
131
+ }
132
+
133
+ .logo span {
134
+ color: var(--gray-400);
135
+ font-weight: 400;
136
+ }
137
+
138
+ .subtitle {
139
+ color: var(--gray-500);
140
+ font-size: 1rem;
141
+ }
142
+
143
+ /* Verdict Card */
144
+ .verdict-card {
145
+ background: white;
146
+ border-radius: 16px;
147
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
148
+ padding: 2.5rem;
149
+ text-align: center;
150
+ margin-bottom: 2rem;
151
+ border: 2px solid var(--verdict-color);
152
+ }
153
+
154
+ .verdict-emoji {
155
+ font-size: 4rem;
156
+ margin-bottom: 1rem;
157
+ }
158
+
159
+ .verdict-label {
160
+ font-size: 1.75rem;
161
+ font-weight: 700;
162
+ color: var(--verdict-color);
163
+ margin-bottom: 0.5rem;
164
+ }
165
+
166
+ .verdict-desc {
167
+ color: var(--gray-500);
168
+ margin-bottom: 1.5rem;
169
+ }
170
+
171
+ .verdict-stats {
172
+ display: flex;
173
+ justify-content: center;
174
+ gap: 3rem;
175
+ flex-wrap: wrap;
176
+ }
177
+
178
+ .stat {
179
+ text-align: center;
180
+ }
181
+
182
+ .stat-value {
183
+ font-size: 2rem;
184
+ font-weight: 700;
185
+ color: var(--gray-800);
186
+ }
187
+
188
+ .stat-value.danger { color: var(--danger); }
189
+ .stat-value.warning { color: var(--warning); }
190
+ .stat-value.success { color: var(--success); }
191
+
192
+ .stat-label {
193
+ font-size: 0.875rem;
194
+ color: var(--gray-500);
195
+ text-transform: uppercase;
196
+ letter-spacing: 0.05em;
197
+ }
198
+
199
+ /* Meta Info */
200
+ .meta-grid {
201
+ display: grid;
202
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
203
+ gap: 1rem;
204
+ margin-bottom: 2rem;
205
+ }
206
+
207
+ .meta-item {
208
+ background: white;
209
+ border-radius: 8px;
210
+ padding: 1rem;
211
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
212
+ }
213
+
214
+ .meta-label {
215
+ font-size: 0.75rem;
216
+ color: var(--gray-500);
217
+ text-transform: uppercase;
218
+ letter-spacing: 0.05em;
219
+ margin-bottom: 0.25rem;
220
+ }
221
+
222
+ .meta-value {
223
+ font-weight: 600;
224
+ color: var(--gray-800);
225
+ word-break: break-all;
226
+ }
227
+
228
+ /* Sections */
229
+ .section {
230
+ background: white;
231
+ border-radius: 12px;
232
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
233
+ margin-bottom: 2rem;
234
+ overflow: hidden;
235
+ }
236
+
237
+ .section-header {
238
+ background: var(--gray-50);
239
+ padding: 1rem 1.5rem;
240
+ border-bottom: 1px solid var(--gray-200);
241
+ display: flex;
242
+ align-items: center;
243
+ gap: 0.75rem;
244
+ }
245
+
246
+ .section-icon {
247
+ font-size: 1.25rem;
248
+ }
249
+
250
+ .section-title {
251
+ font-weight: 600;
252
+ color: var(--gray-800);
253
+ }
254
+
255
+ .section-badge {
256
+ margin-left: auto;
257
+ background: var(--gray-200);
258
+ color: var(--gray-600);
259
+ padding: 0.25rem 0.75rem;
260
+ border-radius: 999px;
261
+ font-size: 0.75rem;
262
+ font-weight: 500;
263
+ }
264
+
265
+ .section-body {
266
+ padding: 1.5rem;
267
+ }
268
+
269
+ /* Evidence Section */
270
+ .evidence-grid {
271
+ display: grid;
272
+ gap: 1rem;
273
+ }
274
+
275
+ .evidence-row {
276
+ display: grid;
277
+ grid-template-columns: 1fr 1fr;
278
+ gap: 1rem;
279
+ }
280
+
281
+ @media (max-width: 768px) {
282
+ .evidence-row {
283
+ grid-template-columns: 1fr;
284
+ }
285
+ }
286
+
287
+ /* Video Player */
288
+ .video-container {
289
+ background: var(--gray-900);
290
+ border-radius: 8px;
291
+ overflow: hidden;
292
+ aspect-ratio: 16/9;
293
+ }
294
+
295
+ .video-container video {
296
+ width: 100%;
297
+ height: 100%;
298
+ object-fit: contain;
299
+ }
300
+
301
+ .video-label {
302
+ text-align: center;
303
+ padding: 0.75rem;
304
+ background: var(--gray-100);
305
+ font-size: 0.875rem;
306
+ color: var(--gray-600);
307
+ font-weight: 500;
308
+ }
309
+
310
+ .video-placeholder {
311
+ display: flex;
312
+ align-items: center;
313
+ justify-content: center;
314
+ height: 200px;
315
+ background: var(--gray-100);
316
+ color: var(--gray-400);
317
+ font-size: 0.875rem;
318
+ }
319
+
320
+ /* Network Evidence */
321
+ .network-table {
322
+ width: 100%;
323
+ border-collapse: collapse;
324
+ }
325
+
326
+ .network-table th,
327
+ .network-table td {
328
+ padding: 0.75rem;
329
+ text-align: left;
330
+ border-bottom: 1px solid var(--gray-200);
331
+ }
332
+
333
+ .network-table th {
334
+ background: var(--gray-50);
335
+ font-weight: 600;
336
+ font-size: 0.75rem;
337
+ text-transform: uppercase;
338
+ letter-spacing: 0.05em;
339
+ color: var(--gray-500);
340
+ }
341
+
342
+ .network-table td {
343
+ font-size: 0.875rem;
344
+ }
345
+
346
+ .status-badge {
347
+ display: inline-flex;
348
+ align-items: center;
349
+ gap: 0.25rem;
350
+ padding: 0.125rem 0.5rem;
351
+ border-radius: 4px;
352
+ font-size: 0.75rem;
353
+ font-weight: 500;
354
+ }
355
+
356
+ .status-badge.success { background: #dcfce7; color: #166534; }
357
+ .status-badge.warning { background: #fef3c7; color: #92400e; }
358
+ .status-badge.error { background: #fee2e2; color: #991b1b; }
359
+
360
+ /* Findings */
361
+ .finding-card {
362
+ border: 1px solid var(--gray-200);
363
+ border-radius: 8px;
364
+ margin-bottom: 1rem;
365
+ overflow: hidden;
366
+ }
367
+
368
+ .finding-card.block {
369
+ border-left: 4px solid var(--danger);
370
+ }
371
+
372
+ .finding-card.warn {
373
+ border-left: 4px solid var(--warning);
374
+ }
375
+
376
+ .finding-header {
377
+ padding: 1rem;
378
+ background: var(--gray-50);
379
+ display: flex;
380
+ align-items: flex-start;
381
+ gap: 0.75rem;
382
+ }
383
+
384
+ .finding-severity {
385
+ flex-shrink: 0;
386
+ padding: 0.25rem 0.5rem;
387
+ border-radius: 4px;
388
+ font-size: 0.75rem;
389
+ font-weight: 700;
390
+ text-transform: uppercase;
391
+ }
392
+
393
+ .finding-severity.block { background: #fee2e2; color: #991b1b; }
394
+ .finding-severity.warn { background: #fef3c7; color: #92400e; }
395
+
396
+ .finding-title {
397
+ font-weight: 600;
398
+ color: var(--gray-800);
399
+ flex: 1;
400
+ }
401
+
402
+ .finding-body {
403
+ padding: 1rem;
404
+ }
405
+
406
+ .finding-meta {
407
+ display: flex;
408
+ flex-wrap: wrap;
409
+ gap: 1rem;
410
+ font-size: 0.875rem;
411
+ color: var(--gray-500);
412
+ margin-bottom: 0.75rem;
413
+ }
414
+
415
+ .finding-reason {
416
+ color: var(--gray-600);
417
+ }
418
+
419
+ .finding-screenshot {
420
+ margin-top: 1rem;
421
+ border-radius: 8px;
422
+ overflow: hidden;
423
+ border: 1px solid var(--gray-200);
424
+ }
425
+
426
+ .finding-screenshot img {
427
+ width: 100%;
428
+ height: auto;
429
+ display: block;
430
+ }
431
+
432
+ /* Coverage */
433
+ .coverage-bar {
434
+ height: 12px;
435
+ background: var(--gray-200);
436
+ border-radius: 6px;
437
+ overflow: hidden;
438
+ margin-bottom: 0.5rem;
439
+ }
440
+
441
+ .coverage-fill {
442
+ height: 100%;
443
+ background: linear-gradient(90deg, var(--primary), #818cf8);
444
+ border-radius: 6px;
445
+ transition: width 0.3s ease;
446
+ }
447
+
448
+ .coverage-label {
449
+ display: flex;
450
+ justify-content: space-between;
451
+ font-size: 0.875rem;
452
+ color: var(--gray-600);
453
+ }
454
+
455
+ /* Trace Link */
456
+ .trace-link {
457
+ display: inline-flex;
458
+ align-items: center;
459
+ gap: 0.5rem;
460
+ padding: 0.75rem 1rem;
461
+ background: var(--gray-100);
462
+ border-radius: 8px;
463
+ color: var(--primary);
464
+ text-decoration: none;
465
+ font-weight: 500;
466
+ transition: background 0.2s;
467
+ }
468
+
469
+ .trace-link:hover {
470
+ background: var(--gray-200);
471
+ }
472
+
473
+ /* Footer */
474
+ .footer {
475
+ text-align: center;
476
+ padding: 2rem;
477
+ color: var(--gray-400);
478
+ font-size: 0.875rem;
479
+ }
480
+
481
+ .footer a {
482
+ color: var(--primary);
483
+ text-decoration: none;
484
+ }
485
+
486
+ /* Print styles */
487
+ @media print {
488
+ .video-container { display: none; }
489
+ .container { max-width: 100%; padding: 1rem; }
490
+ .section { break-inside: avoid; }
491
+ }
492
+
493
+ /* Collapsible */
494
+ .collapsible-header {
495
+ cursor: pointer;
496
+ user-select: none;
497
+ }
498
+
499
+ .collapsible-header::after {
500
+ content: '▼';
501
+ font-size: 0.75rem;
502
+ margin-left: 0.5rem;
503
+ transition: transform 0.2s;
504
+ }
505
+
506
+ .collapsible.collapsed .collapsible-header::after {
507
+ transform: rotate(-90deg);
508
+ }
509
+
510
+ .collapsible.collapsed .collapsible-body {
511
+ display: none;
512
+ }
513
+ </style>
514
+ </head>
515
+ <body>
516
+ <div class="container">
517
+ <!-- Header -->
518
+ <header class="header">
519
+ <div class="logo">vibecheck <span>prove</span></div>
520
+ <p class="subtitle">Reality Proof Report</p>
521
+ </header>
522
+
523
+ <!-- Verdict Card -->
524
+ <div class="verdict-card">
525
+ <div class="verdict-emoji">${v.emoji}</div>
526
+ <div class="verdict-label">${v.label}</div>
527
+ <p class="verdict-desc">
528
+ ${verdict === 'SHIP' || verdict === 'CLEAN'
529
+ ? 'Your app has been verified with real user flows hitting real APIs.'
530
+ : verdict === 'WARN'
531
+ ? 'Verification complete with warnings. Review before shipping.'
532
+ : 'Verification failed. Critical issues must be fixed.'}
533
+ </p>
534
+ <div class="verdict-stats">
535
+ <div class="stat">
536
+ <div class="stat-value ${blocks > 0 ? 'danger' : 'success'}">${blocks}</div>
537
+ <div class="stat-label">Blockers</div>
538
+ </div>
539
+ <div class="stat">
540
+ <div class="stat-value ${warns > 0 ? 'warning' : 'success'}">${warns}</div>
541
+ <div class="stat-label">Warnings</div>
542
+ </div>
543
+ <div class="stat">
544
+ <div class="stat-value">${coverage?.percent || 0}%</div>
545
+ <div class="stat-label">Coverage</div>
546
+ </div>
547
+ <div class="stat">
548
+ <div class="stat-value">${formatDuration(durationMs)}</div>
549
+ <div class="stat-label">Duration</div>
550
+ </div>
551
+ </div>
552
+ </div>
553
+
554
+ <!-- Meta Info -->
555
+ <div class="meta-grid">
556
+ <div class="meta-item">
557
+ <div class="meta-label">Project</div>
558
+ <div class="meta-value">${escapeHtml(projectName)}</div>
559
+ </div>
560
+ <div class="meta-item">
561
+ <div class="meta-label">URL Tested</div>
562
+ <div class="meta-value">${escapeHtml(url || 'N/A')}</div>
563
+ </div>
564
+ <div class="meta-item">
565
+ <div class="meta-label">Tested At</div>
566
+ <div class="meta-value">${new Date(startedAt).toLocaleString()}</div>
567
+ </div>
568
+ <div class="meta-item">
569
+ <div class="meta-label">Stability Runs</div>
570
+ <div class="meta-value">${stabilityRuns}</div>
571
+ </div>
572
+ </div>
573
+
574
+ ${generateVideoSection(artifacts, passes)}
575
+
576
+ ${generateNetworkSection(passes)}
577
+
578
+ ${generateCoverageSection(coverage)}
579
+
580
+ ${generateFindingsSection(findings, findingsByCategory)}
581
+
582
+ ${generateArtifactsSection(artifacts)}
583
+
584
+ <!-- Footer -->
585
+ <footer class="footer">
586
+ Generated by <a href="https://vibecheck.ai">vibecheck</a> &middot;
587
+ ${new Date().toISOString()}
588
+ </footer>
589
+ </div>
590
+
591
+ <script>
592
+ // Collapsible sections
593
+ document.querySelectorAll('.collapsible').forEach(el => {
594
+ const header = el.querySelector('.collapsible-header');
595
+ if (header) {
596
+ header.addEventListener('click', () => {
597
+ el.classList.toggle('collapsed');
598
+ });
599
+ }
600
+ });
601
+ </script>
602
+ </body>
603
+ </html>`;
604
+ }
605
+
606
+ function generateVideoSection(artifacts, passes) {
607
+ const hasVideos = artifacts?.videos?.anon || artifacts?.videos?.auth;
608
+ const hasTraces = artifacts?.traces?.anon || artifacts?.traces?.auth;
609
+
610
+ if (!hasVideos && !hasTraces) {
611
+ return '';
612
+ }
613
+
614
+ return `
615
+ <!-- Video Evidence -->
616
+ <div class="section">
617
+ <div class="section-header">
618
+ <span class="section-icon">🎬</span>
619
+ <span class="section-title">Video Evidence</span>
620
+ <span class="section-badge">Runtime Proof</span>
621
+ </div>
622
+ <div class="section-body">
623
+ <p style="color: var(--gray-500); margin-bottom: 1rem;">
624
+ These recordings show real browser sessions testing your application.
625
+ </p>
626
+ <div class="evidence-row">
627
+ ${artifacts?.videos?.anon ? `
628
+ <div>
629
+ <div class="video-container">
630
+ <video controls preload="metadata">
631
+ <source src="${escapeHtml(artifacts.videos.anon)}" type="video/webm">
632
+ Your browser does not support video playback.
633
+ </video>
634
+ </div>
635
+ <div class="video-label">👤 Anonymous Session</div>
636
+ </div>
637
+ ` : '<div class="video-placeholder">No anonymous session video</div>'}
638
+
639
+ ${artifacts?.videos?.auth ? `
640
+ <div>
641
+ <div class="video-container">
642
+ <video controls preload="metadata">
643
+ <source src="${escapeHtml(artifacts.videos.auth)}" type="video/webm">
644
+ Your browser does not support video playback.
645
+ </video>
646
+ </div>
647
+ <div class="video-label">🔑 Authenticated Session</div>
648
+ </div>
649
+ ` : ''}
650
+ </div>
651
+
652
+ ${hasTraces ? `
653
+ <div style="margin-top: 1.5rem;">
654
+ <p style="color: var(--gray-600); font-weight: 500; margin-bottom: 0.75rem;">
655
+ 📊 Full Traces (for detailed debugging)
656
+ </p>
657
+ <div style="display: flex; gap: 1rem; flex-wrap: wrap;">
658
+ ${artifacts?.traces?.anon ? `
659
+ <a href="https://trace.playwright.dev" class="trace-link" target="_blank">
660
+ View Anonymous Trace ↗
661
+ </a>
662
+ ` : ''}
663
+ ${artifacts?.traces?.auth ? `
664
+ <a href="https://trace.playwright.dev" class="trace-link" target="_blank">
665
+ View Authenticated Trace ↗
666
+ </a>
667
+ ` : ''}
668
+ </div>
669
+ <p style="color: var(--gray-400); font-size: 0.75rem; margin-top: 0.5rem;">
670
+ Download trace files and upload to trace.playwright.dev
671
+ </p>
672
+ </div>
673
+ ` : ''}
674
+ </div>
675
+ </div>
676
+ `;
677
+ }
678
+
679
+ function generateNetworkSection(passes) {
680
+ const anonErrors = passes?.anon?.networkErrors || [];
681
+ const authErrors = passes?.auth?.networkErrors || [];
682
+ const allErrors = [...anonErrors, ...authErrors].slice(0, 10);
683
+
684
+ const anonResponses = passes?.anon?.fakeDataDetections || [];
685
+ const fakeDetections = anonResponses.filter(d => d.confidence >= 0.7).slice(0, 5);
686
+
687
+ return `
688
+ <!-- Network Evidence -->
689
+ <div class="section">
690
+ <div class="section-header">
691
+ <span class="section-icon">📡</span>
692
+ <span class="section-title">Network Evidence</span>
693
+ <span class="section-badge">${allErrors.length} errors, ${fakeDetections.length} fakes detected</span>
694
+ </div>
695
+ <div class="section-body">
696
+ ${allErrors.length > 0 ? `
697
+ <h4 style="margin-bottom: 0.75rem; color: var(--gray-700);">Network Errors</h4>
698
+ <table class="network-table">
699
+ <thead>
700
+ <tr>
701
+ <th>URL</th>
702
+ <th>Error</th>
703
+ </tr>
704
+ </thead>
705
+ <tbody>
706
+ ${allErrors.map(e => `
707
+ <tr>
708
+ <td style="word-break: break-all; max-width: 400px;">${escapeHtml(e.url)}</td>
709
+ <td><span class="status-badge error">${escapeHtml(e.failure || 'Failed')}</span></td>
710
+ </tr>
711
+ `).join('')}
712
+ </tbody>
713
+ </table>
714
+ ` : `
715
+ <div style="text-align: center; padding: 2rem; color: var(--gray-400);">
716
+ ✅ No network errors detected
717
+ </div>
718
+ `}
719
+
720
+ ${fakeDetections.length > 0 ? `
721
+ <h4 style="margin: 1.5rem 0 0.75rem; color: var(--gray-700);">Fake Data Detections</h4>
722
+ <table class="network-table">
723
+ <thead>
724
+ <tr>
725
+ <th>Type</th>
726
+ <th>Evidence</th>
727
+ <th>Confidence</th>
728
+ </tr>
729
+ </thead>
730
+ <tbody>
731
+ ${fakeDetections.map(d => `
732
+ <tr>
733
+ <td>${escapeHtml(d.type)}</td>
734
+ <td>${escapeHtml(d.evidence)}</td>
735
+ <td><span class="status-badge ${d.confidence >= 0.9 ? 'error' : 'warning'}">${Math.round(d.confidence * 100)}%</span></td>
736
+ </tr>
737
+ `).join('')}
738
+ </tbody>
739
+ </table>
740
+ ` : ''}
741
+ </div>
742
+ </div>
743
+ `;
744
+ }
745
+
746
+ function generateCoverageSection(coverage) {
747
+ if (!coverage) return '';
748
+
749
+ return `
750
+ <!-- Coverage -->
751
+ <div class="section">
752
+ <div class="section-header">
753
+ <span class="section-icon">📊</span>
754
+ <span class="section-title">UI Path Coverage</span>
755
+ <span class="section-badge">${coverage.hit || 0}/${coverage.total || 0} paths</span>
756
+ </div>
757
+ <div class="section-body">
758
+ <div class="coverage-bar">
759
+ <div class="coverage-fill" style="width: ${coverage.percent || 0}%"></div>
760
+ </div>
761
+ <div class="coverage-label">
762
+ <span>${coverage.percent || 0}% covered</span>
763
+ <span>${coverage.hit || 0} of ${coverage.total || 0} paths visited</span>
764
+ </div>
765
+
766
+ ${coverage.missed && coverage.missed.length > 0 ? `
767
+ <div style="margin-top: 1rem;">
768
+ <p style="color: var(--gray-600); font-weight: 500; margin-bottom: 0.5rem;">
769
+ Missed Paths (${coverage.missed.length})
770
+ </p>
771
+ <ul style="color: var(--gray-500); font-size: 0.875rem; padding-left: 1.5rem;">
772
+ ${coverage.missed.slice(0, 5).map(p => `<li>${escapeHtml(p)}</li>`).join('')}
773
+ ${coverage.missed.length > 5 ? `<li>...and ${coverage.missed.length - 5} more</li>` : ''}
774
+ </ul>
775
+ </div>
776
+ ` : ''}
777
+ </div>
778
+ </div>
779
+ `;
780
+ }
781
+
782
+ function generateFindingsSection(findings, findingsByCategory) {
783
+ if (findings.length === 0) {
784
+ return `
785
+ <!-- Findings -->
786
+ <div class="section">
787
+ <div class="section-header">
788
+ <span class="section-icon">✅</span>
789
+ <span class="section-title">Findings</span>
790
+ <span class="section-badge">0 issues</span>
791
+ </div>
792
+ <div class="section-body">
793
+ <div style="text-align: center; padding: 2rem; color: var(--gray-400);">
794
+ ✨ No issues found! Your UI is responsive and real.
795
+ </div>
796
+ </div>
797
+ </div>
798
+ `;
799
+ }
800
+
801
+ const blocks = findings.filter(f => f.severity === 'BLOCK');
802
+ const warns = findings.filter(f => f.severity === 'WARN');
803
+
804
+ return `
805
+ <!-- Findings -->
806
+ <div class="section">
807
+ <div class="section-header">
808
+ <span class="section-icon">🔍</span>
809
+ <span class="section-title">Findings</span>
810
+ <span class="section-badge">${blocks.length} blockers, ${warns.length} warnings</span>
811
+ </div>
812
+ <div class="section-body">
813
+ ${Object.entries(findingsByCategory).map(([category, catFindings]) => `
814
+ <div class="collapsible" style="margin-bottom: 1.5rem;">
815
+ <h4 class="collapsible-header" style="color: var(--gray-700); margin-bottom: 0.75rem; cursor: pointer;">
816
+ ${getCategoryEmoji(category)} ${escapeHtml(category)}
817
+ <span style="color: var(--gray-400); font-weight: normal;">(${catFindings.length})</span>
818
+ </h4>
819
+ <div class="collapsible-body">
820
+ ${catFindings.slice(0, 10).map(f => `
821
+ <div class="finding-card ${f.severity.toLowerCase()}">
822
+ <div class="finding-header">
823
+ <span class="finding-severity ${f.severity.toLowerCase()}">${f.severity}</span>
824
+ <span class="finding-title">${escapeHtml(f.title)}</span>
825
+ </div>
826
+ <div class="finding-body">
827
+ <div class="finding-meta">
828
+ ${f.page ? `<span>📍 ${escapeHtml(truncateUrl(f.page))}</span>` : ''}
829
+ ${f.confidence ? `<span>🎯 ${Math.round(f.confidence * 100)}% confidence</span>` : ''}
830
+ </div>
831
+ ${f.reason ? `<p class="finding-reason">${escapeHtml(f.reason)}</p>` : ''}
832
+ ${f.screenshot ? `
833
+ <div class="finding-screenshot">
834
+ <img src="${escapeHtml(f.screenshot)}" alt="Screenshot" loading="lazy">
835
+ </div>
836
+ ` : ''}
837
+ </div>
838
+ </div>
839
+ `).join('')}
840
+ ${catFindings.length > 10 ? `
841
+ <p style="color: var(--gray-400); font-size: 0.875rem; text-align: center;">
842
+ ...and ${catFindings.length - 10} more in this category
843
+ </p>
844
+ ` : ''}
845
+ </div>
846
+ </div>
847
+ `).join('')}
848
+ </div>
849
+ </div>
850
+ `;
851
+ }
852
+
853
+ function generateArtifactsSection(artifacts) {
854
+ const hasArtifacts = artifacts?.screenshots || artifacts?.videos?.directory ||
855
+ artifacts?.traces?.directory || artifacts?.har?.directory;
856
+
857
+ if (!hasArtifacts) return '';
858
+
859
+ return `
860
+ <!-- Artifacts -->
861
+ <div class="section">
862
+ <div class="section-header">
863
+ <span class="section-icon">📁</span>
864
+ <span class="section-title">Artifacts</span>
865
+ </div>
866
+ <div class="section-body">
867
+ <p style="color: var(--gray-500); margin-bottom: 1rem;">
868
+ Full evidence files for CI/CD integration and audit trails.
869
+ </p>
870
+ <ul style="list-style: none; color: var(--gray-600);">
871
+ ${artifacts?.screenshots ? `<li style="margin-bottom: 0.5rem;">📸 Screenshots: <code style="background: var(--gray-100); padding: 0.25rem 0.5rem; border-radius: 4px;">${escapeHtml(artifacts.screenshots)}</code></li>` : ''}
872
+ ${artifacts?.videos?.directory ? `<li style="margin-bottom: 0.5rem;">🎬 Videos: <code style="background: var(--gray-100); padding: 0.25rem 0.5rem; border-radius: 4px;">${escapeHtml(artifacts.videos.directory)}</code></li>` : ''}
873
+ ${artifacts?.traces?.directory ? `<li style="margin-bottom: 0.5rem;">📊 Traces: <code style="background: var(--gray-100); padding: 0.25rem 0.5rem; border-radius: 4px;">${escapeHtml(artifacts.traces.directory)}</code></li>` : ''}
874
+ ${artifacts?.har?.directory ? `<li style="margin-bottom: 0.5rem;">📡 HAR Files: <code style="background: var(--gray-100); padding: 0.25rem 0.5rem; border-radius: 4px;">${escapeHtml(artifacts.har.directory)}</code></li>` : ''}
875
+ </ul>
876
+ </div>
877
+ </div>
878
+ `;
879
+ }
880
+
881
+ function getCategoryEmoji(category) {
882
+ const emojis = {
883
+ 'DeadUI': '💀',
884
+ 'AuthCoverage': '🔒',
885
+ 'HTTPError': '📡',
886
+ 'FakeDomain': '🔗',
887
+ 'FakeResponse': '🎭',
888
+ 'MockStatus': '📡',
889
+ 'StubCode': '📝',
890
+ 'TODOCode': '📋',
891
+ 'PlaceholderSecret': '🔐',
892
+ 'Other': '📌'
893
+ };
894
+ return emojis[category] || '📌';
895
+ }
896
+
897
+ function truncateUrl(url) {
898
+ if (!url) return '';
899
+ try {
900
+ const parsed = new URL(url);
901
+ return parsed.pathname + (parsed.search ? '?' + parsed.search.slice(1, 20) + '...' : '');
902
+ } catch {
903
+ return url.length > 60 ? url.slice(0, 60) + '...' : url;
904
+ }
905
+ }
906
+
907
+ // ═══════════════════════════════════════════════════════════════════════════════
908
+ // EXPORT
909
+ // ═══════════════════════════════════════════════════════════════════════════════
910
+
911
+ module.exports = {
912
+ generateHtmlProofReport
913
+ };