@vibecheckai/cli 2.8.2 โ†’ 3.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 (454) hide show
  1. package/README.md +8 -8
  2. package/bin/_deprecations.js +35 -0
  3. package/bin/_router.js +46 -0
  4. package/bin/cli-hygiene.js +241 -0
  5. package/bin/guardrail.js +834 -0
  6. package/bin/runners/cli-utils.js +1070 -0
  7. package/bin/runners/context/ai-task-decomposer.js +337 -0
  8. package/bin/runners/context/analyzer.js +462 -0
  9. package/bin/runners/context/api-contracts.js +427 -0
  10. package/bin/runners/context/context-diff.js +342 -0
  11. package/bin/runners/context/context-pruner.js +291 -0
  12. package/bin/runners/context/dependency-graph.js +414 -0
  13. package/bin/runners/context/generators/claude.js +107 -0
  14. package/bin/runners/context/generators/codex.js +108 -0
  15. package/bin/runners/context/generators/copilot.js +119 -0
  16. package/bin/runners/context/generators/cursor.js +514 -0
  17. package/bin/runners/context/generators/mcp.js +151 -0
  18. package/bin/runners/context/generators/windsurf.js +180 -0
  19. package/bin/runners/context/git-context.js +302 -0
  20. package/bin/runners/context/index.js +1042 -0
  21. package/bin/runners/context/insights.js +173 -0
  22. package/bin/runners/context/mcp-server/generate-rules.js +337 -0
  23. package/bin/runners/context/mcp-server/index.js +1176 -0
  24. package/bin/runners/context/mcp-server/package.json +24 -0
  25. package/bin/runners/context/memory.js +200 -0
  26. package/bin/runners/context/monorepo.js +215 -0
  27. package/bin/runners/context/multi-repo-federation.js +404 -0
  28. package/bin/runners/context/patterns.js +253 -0
  29. package/bin/runners/context/proof-context.js +972 -0
  30. package/bin/runners/context/security-scanner.js +303 -0
  31. package/bin/runners/context/semantic-search.js +350 -0
  32. package/bin/runners/context/shared.js +264 -0
  33. package/bin/runners/context/team-conventions.js +310 -0
  34. package/bin/runners/lib/ai-bridge.js +416 -0
  35. package/bin/runners/lib/analysis-core.js +271 -0
  36. package/bin/runners/lib/analyzers.js +541 -0
  37. package/bin/runners/lib/audit-bridge.js +391 -0
  38. package/bin/runners/lib/auth-truth.js +193 -0
  39. package/bin/runners/lib/auth.js +215 -0
  40. package/bin/runners/lib/backup.js +62 -0
  41. package/bin/runners/lib/billing.js +107 -0
  42. package/bin/runners/lib/claims.js +118 -0
  43. package/bin/runners/lib/cli-ui.js +540 -0
  44. package/bin/runners/lib/compliance-bridge-new.js +0 -0
  45. package/bin/runners/lib/compliance-bridge.js +165 -0
  46. package/bin/runners/lib/contracts/auth-contract.js +194 -0
  47. package/bin/runners/lib/contracts/env-contract.js +178 -0
  48. package/bin/runners/lib/contracts/external-contract.js +198 -0
  49. package/bin/runners/lib/contracts/guard.js +168 -0
  50. package/bin/runners/lib/contracts/index.js +89 -0
  51. package/bin/runners/lib/contracts/plan-validator.js +311 -0
  52. package/bin/runners/lib/contracts/route-contract.js +192 -0
  53. package/bin/runners/lib/detect.js +89 -0
  54. package/bin/runners/lib/doctor/autofix.js +254 -0
  55. package/bin/runners/lib/doctor/index.js +37 -0
  56. package/bin/runners/lib/doctor/modules/dependencies.js +325 -0
  57. package/bin/runners/lib/doctor/modules/index.js +46 -0
  58. package/bin/runners/lib/doctor/modules/network.js +250 -0
  59. package/bin/runners/lib/doctor/modules/project.js +312 -0
  60. package/bin/runners/lib/doctor/modules/runtime.js +224 -0
  61. package/bin/runners/lib/doctor/modules/security.js +348 -0
  62. package/bin/runners/lib/doctor/modules/system.js +213 -0
  63. package/bin/runners/lib/doctor/modules/vibecheck.js +394 -0
  64. package/bin/runners/lib/doctor/reporter.js +262 -0
  65. package/bin/runners/lib/doctor/service.js +262 -0
  66. package/bin/runners/lib/doctor/types.js +113 -0
  67. package/bin/runners/lib/doctor/ui.js +263 -0
  68. package/bin/runners/lib/doctor-enhanced.js +233 -0
  69. package/bin/runners/lib/doctor-v2.js +608 -0
  70. package/bin/runners/lib/enforcement.js +72 -0
  71. package/bin/runners/lib/enterprise-detect.js +603 -0
  72. package/bin/runners/lib/enterprise-init.js +942 -0
  73. package/bin/runners/lib/entitlements-v2.js +381 -0
  74. package/bin/runners/lib/entitlements.generated.js +0 -0
  75. package/bin/runners/lib/entitlements.js +332 -0
  76. package/bin/runners/lib/env-template.js +66 -0
  77. package/bin/runners/lib/env.js +189 -0
  78. package/bin/runners/lib/error-handler.js +320 -0
  79. package/bin/runners/lib/firewall-prompt.js +50 -0
  80. package/bin/runners/lib/graph/graph-builder.js +265 -0
  81. package/bin/runners/lib/graph/html-renderer.js +413 -0
  82. package/bin/runners/lib/graph/index.js +32 -0
  83. package/bin/runners/lib/graph/runtime-collector.js +215 -0
  84. package/bin/runners/lib/graph/static-extractor.js +518 -0
  85. package/bin/runners/lib/init-wizard.js +308 -0
  86. package/bin/runners/lib/json-output.js +76 -0
  87. package/bin/runners/lib/llm.js +75 -0
  88. package/bin/runners/lib/meter.js +61 -0
  89. package/bin/runners/lib/missions/evidence.js +126 -0
  90. package/bin/runners/lib/missions/plan.js +69 -0
  91. package/bin/runners/lib/missions/templates.js +147 -0
  92. package/bin/runners/lib/patch.js +40 -0
  93. package/bin/runners/lib/permissions/auth-model.js +213 -0
  94. package/bin/runners/lib/permissions/idor-prover.js +205 -0
  95. package/bin/runners/lib/permissions/index.js +45 -0
  96. package/bin/runners/lib/permissions/matrix-builder.js +198 -0
  97. package/bin/runners/lib/pkgjson.js +28 -0
  98. package/bin/runners/lib/preflight.js +142 -0
  99. package/bin/runners/lib/reality-findings.js +84 -0
  100. package/bin/runners/lib/redact.js +29 -0
  101. package/bin/runners/lib/replay/capsule-manager.js +154 -0
  102. package/bin/runners/lib/replay/index.js +263 -0
  103. package/bin/runners/lib/replay/player.js +348 -0
  104. package/bin/runners/lib/replay/recorder.js +331 -0
  105. package/bin/runners/lib/report-engine.js +447 -0
  106. package/bin/runners/lib/report-html.js +1117 -0
  107. package/bin/runners/lib/report-templates.js +964 -0
  108. package/bin/runners/lib/route-detection.js +1140 -0
  109. package/bin/runners/lib/route-truth.js +477 -0
  110. package/bin/runners/lib/sandbox/index.js +59 -0
  111. package/bin/runners/lib/sandbox/proof-chain.js +399 -0
  112. package/bin/runners/lib/sandbox/sandbox-runner.js +205 -0
  113. package/bin/runners/lib/sandbox/worktree.js +174 -0
  114. package/bin/runners/lib/scan-cache.js +330 -0
  115. package/bin/runners/lib/scan-output-schema.js +344 -0
  116. package/bin/runners/lib/score-history.js +282 -0
  117. package/bin/runners/lib/security-bridge.js +249 -0
  118. package/bin/runners/lib/server-usage.js +513 -0
  119. package/bin/runners/lib/share-pack.js +239 -0
  120. package/bin/runners/lib/snippets.js +67 -0
  121. package/bin/runners/lib/truth.js +667 -0
  122. package/bin/runners/lib/unified-output.js +189 -0
  123. package/bin/runners/lib/validate-patch.js +156 -0
  124. package/bin/runners/lib/verification.js +345 -0
  125. package/bin/runners/reality/engine.js +917 -0
  126. package/bin/runners/reality/flows.js +122 -0
  127. package/bin/runners/reality/report.js +378 -0
  128. package/bin/runners/reality/session.js +193 -0
  129. package/bin/runners/runAIAgent.js +2 -0
  130. package/bin/runners/runAudit.js +2 -0
  131. package/bin/runners/runAuth.js +106 -0
  132. package/bin/runners/runAutopilot.js +2 -0
  133. package/bin/runners/runBadge.js +2 -0
  134. package/bin/runners/runCertify.js +2 -0
  135. package/bin/runners/runClaimVerifier.js +483 -0
  136. package/bin/runners/runContext.js +56 -0
  137. package/bin/runners/runContextCompiler.js +385 -0
  138. package/bin/runners/runCtx.js +187 -0
  139. package/bin/runners/runCtxGuard.js +176 -0
  140. package/bin/runners/runCtxSync.js +116 -0
  141. package/bin/runners/runDashboard.js +10 -0
  142. package/bin/runners/runDoctor.js +245 -0
  143. package/bin/runners/runEnhancedShip.js +2 -0
  144. package/bin/runners/runFix.js +735 -0
  145. package/bin/runners/runFixPacks.js +2 -0
  146. package/bin/runners/runGate.js +17 -0
  147. package/bin/runners/runGraph.js +283 -0
  148. package/bin/runners/runInit.js +260 -0
  149. package/bin/runners/runInitGha.js +101 -0
  150. package/bin/runners/runInstall.js +76 -0
  151. package/bin/runners/runInteractive.js +388 -0
  152. package/bin/runners/runLaunch.js +2 -0
  153. package/bin/runners/runMcp.js +19 -0
  154. package/bin/runners/runMdc.js +2 -0
  155. package/bin/runners/runMissionGenerator.js +282 -0
  156. package/bin/runners/runNaturalLanguage.js +3 -0
  157. package/bin/runners/runPR.js +96 -0
  158. package/bin/runners/runPermissions.js +290 -0
  159. package/bin/runners/runPromptFirewall.js +211 -0
  160. package/bin/runners/runProof.js +2 -0
  161. package/bin/runners/runProve.js +392 -0
  162. package/bin/runners/runReality.js +489 -0
  163. package/bin/runners/runRealitySniff.js +2 -0
  164. package/bin/runners/runReplay.js +469 -0
  165. package/bin/runners/runReport.js +478 -0
  166. package/bin/runners/runScan.js +835 -0
  167. package/bin/runners/runShare.js +34 -0
  168. package/bin/runners/runShip.js +1062 -0
  169. package/bin/runners/runStatus.js +136 -0
  170. package/bin/runners/runTruthpack.js +634 -0
  171. package/bin/runners/runUpgrade.js +2 -0
  172. package/bin/runners/runValidate.js +2 -0
  173. package/bin/runners/runVerifyAgentOutput.js +2 -0
  174. package/bin/runners/runWatch.js +230 -0
  175. package/bin/runners/utils.js +360 -0
  176. package/bin/scan.js +612 -0
  177. package/bin/vibecheck.js +834 -0
  178. package/package.json +11 -11
  179. package/dist/autopatch/verified-autopatch.d.ts +0 -111
  180. package/dist/autopatch/verified-autopatch.d.ts.map +0 -1
  181. package/dist/autopatch/verified-autopatch.js +0 -503
  182. package/dist/autopatch/verified-autopatch.js.map +0 -1
  183. package/dist/bundles/index.js +0 -8
  184. package/dist/bundles/vibecheck-core.js +0 -25799
  185. package/dist/bundles/vibecheck-security.js +0 -208693
  186. package/dist/bundles/vibecheck-ship.js +0 -2318
  187. package/dist/commands/baseline.d.ts +0 -7
  188. package/dist/commands/baseline.d.ts.map +0 -1
  189. package/dist/commands/baseline.js +0 -79
  190. package/dist/commands/baseline.js.map +0 -1
  191. package/dist/commands/cache.d.ts +0 -13
  192. package/dist/commands/cache.d.ts.map +0 -1
  193. package/dist/commands/cache.js +0 -165
  194. package/dist/commands/cache.js.map +0 -1
  195. package/dist/commands/checkpoint.d.ts +0 -8
  196. package/dist/commands/checkpoint.d.ts.map +0 -1
  197. package/dist/commands/checkpoint.js +0 -35
  198. package/dist/commands/checkpoint.js.map +0 -1
  199. package/dist/commands/doctor.d.ts +0 -17
  200. package/dist/commands/doctor.d.ts.map +0 -1
  201. package/dist/commands/doctor.js +0 -226
  202. package/dist/commands/doctor.js.map +0 -1
  203. package/dist/commands/evidence.d.ts +0 -45
  204. package/dist/commands/evidence.d.ts.map +0 -1
  205. package/dist/commands/evidence.js +0 -197
  206. package/dist/commands/evidence.js.map +0 -1
  207. package/dist/commands/explain.d.ts +0 -8
  208. package/dist/commands/explain.d.ts.map +0 -1
  209. package/dist/commands/explain.js +0 -52
  210. package/dist/commands/explain.js.map +0 -1
  211. package/dist/commands/fix-consolidated.d.ts +0 -19
  212. package/dist/commands/fix-consolidated.d.ts.map +0 -1
  213. package/dist/commands/fix-consolidated.js +0 -165
  214. package/dist/commands/fix-consolidated.js.map +0 -1
  215. package/dist/commands/index.d.ts +0 -8
  216. package/dist/commands/index.d.ts.map +0 -1
  217. package/dist/commands/index.js +0 -15
  218. package/dist/commands/index.js.map +0 -1
  219. package/dist/commands/init.d.ts +0 -8
  220. package/dist/commands/init.d.ts.map +0 -1
  221. package/dist/commands/init.js +0 -125
  222. package/dist/commands/init.js.map +0 -1
  223. package/dist/commands/launcher.d.ts +0 -10
  224. package/dist/commands/launcher.d.ts.map +0 -1
  225. package/dist/commands/launcher.js +0 -174
  226. package/dist/commands/launcher.js.map +0 -1
  227. package/dist/commands/on.d.ts +0 -8
  228. package/dist/commands/on.d.ts.map +0 -1
  229. package/dist/commands/on.js +0 -123
  230. package/dist/commands/on.js.map +0 -1
  231. package/dist/commands/replay.d.ts +0 -8
  232. package/dist/commands/replay.d.ts.map +0 -1
  233. package/dist/commands/replay.js +0 -52
  234. package/dist/commands/replay.js.map +0 -1
  235. package/dist/commands/scan-consolidated.d.ts +0 -61
  236. package/dist/commands/scan-consolidated.d.ts.map +0 -1
  237. package/dist/commands/scan-consolidated.js +0 -243
  238. package/dist/commands/scan-consolidated.js.map +0 -1
  239. package/dist/commands/scan-secrets.d.ts +0 -47
  240. package/dist/commands/scan-secrets.d.ts.map +0 -1
  241. package/dist/commands/scan-secrets.js +0 -225
  242. package/dist/commands/scan-secrets.js.map +0 -1
  243. package/dist/commands/scan-vulnerabilities-enhanced.d.ts +0 -41
  244. package/dist/commands/scan-vulnerabilities-enhanced.d.ts.map +0 -1
  245. package/dist/commands/scan-vulnerabilities-enhanced.js +0 -368
  246. package/dist/commands/scan-vulnerabilities-enhanced.js.map +0 -1
  247. package/dist/commands/scan-vulnerabilities-osv.d.ts +0 -58
  248. package/dist/commands/scan-vulnerabilities-osv.d.ts.map +0 -1
  249. package/dist/commands/scan-vulnerabilities-osv.js +0 -722
  250. package/dist/commands/scan-vulnerabilities-osv.js.map +0 -1
  251. package/dist/commands/scan-vulnerabilities.d.ts +0 -32
  252. package/dist/commands/scan-vulnerabilities.d.ts.map +0 -1
  253. package/dist/commands/scan-vulnerabilities.js +0 -283
  254. package/dist/commands/scan-vulnerabilities.js.map +0 -1
  255. package/dist/commands/secrets-allowlist.d.ts +0 -7
  256. package/dist/commands/secrets-allowlist.d.ts.map +0 -1
  257. package/dist/commands/secrets-allowlist.js +0 -85
  258. package/dist/commands/secrets-allowlist.js.map +0 -1
  259. package/dist/commands/ship-consolidated.d.ts +0 -58
  260. package/dist/commands/ship-consolidated.d.ts.map +0 -1
  261. package/dist/commands/ship-consolidated.js +0 -515
  262. package/dist/commands/ship-consolidated.js.map +0 -1
  263. package/dist/commands/stats.d.ts +0 -8
  264. package/dist/commands/stats.d.ts.map +0 -1
  265. package/dist/commands/stats.js +0 -134
  266. package/dist/commands/stats.js.map +0 -1
  267. package/dist/commands/upgrade.d.ts +0 -8
  268. package/dist/commands/upgrade.d.ts.map +0 -1
  269. package/dist/commands/upgrade.js +0 -30
  270. package/dist/commands/upgrade.js.map +0 -1
  271. package/dist/fix/applicator.d.ts +0 -44
  272. package/dist/fix/applicator.d.ts.map +0 -1
  273. package/dist/fix/applicator.js +0 -144
  274. package/dist/fix/applicator.js.map +0 -1
  275. package/dist/fix/backup.d.ts +0 -38
  276. package/dist/fix/backup.d.ts.map +0 -1
  277. package/dist/fix/backup.js +0 -154
  278. package/dist/fix/backup.js.map +0 -1
  279. package/dist/fix/engine.d.ts +0 -55
  280. package/dist/fix/engine.d.ts.map +0 -1
  281. package/dist/fix/engine.js +0 -285
  282. package/dist/fix/engine.js.map +0 -1
  283. package/dist/fix/index.d.ts +0 -5
  284. package/dist/fix/index.d.ts.map +0 -1
  285. package/dist/fix/index.js +0 -12
  286. package/dist/fix/index.js.map +0 -1
  287. package/dist/fix/interactive.d.ts +0 -22
  288. package/dist/fix/interactive.d.ts.map +0 -1
  289. package/dist/fix/interactive.js +0 -172
  290. package/dist/fix/interactive.js.map +0 -1
  291. package/dist/formatters/index.d.ts +0 -6
  292. package/dist/formatters/index.d.ts.map +0 -1
  293. package/dist/formatters/index.js +0 -11
  294. package/dist/formatters/index.js.map +0 -1
  295. package/dist/formatters/sarif-enhanced.d.ts +0 -78
  296. package/dist/formatters/sarif-enhanced.d.ts.map +0 -1
  297. package/dist/formatters/sarif-enhanced.js +0 -144
  298. package/dist/formatters/sarif-enhanced.js.map +0 -1
  299. package/dist/formatters/sarif-v2.d.ts +0 -121
  300. package/dist/formatters/sarif-v2.d.ts.map +0 -1
  301. package/dist/formatters/sarif-v2.js +0 -356
  302. package/dist/formatters/sarif-v2.js.map +0 -1
  303. package/dist/formatters/sarif.d.ts +0 -72
  304. package/dist/formatters/sarif.d.ts.map +0 -1
  305. package/dist/formatters/sarif.js +0 -146
  306. package/dist/formatters/sarif.js.map +0 -1
  307. package/dist/index.d.ts +0 -61
  308. package/dist/index.d.ts.map +0 -1
  309. package/dist/index.js +0 -4388
  310. package/dist/index.js.map +0 -1
  311. package/dist/init/ci-generator.d.ts +0 -18
  312. package/dist/init/ci-generator.d.ts.map +0 -1
  313. package/dist/init/ci-generator.js +0 -317
  314. package/dist/init/ci-generator.js.map +0 -1
  315. package/dist/init/detect-framework.d.ts +0 -15
  316. package/dist/init/detect-framework.d.ts.map +0 -1
  317. package/dist/init/detect-framework.js +0 -301
  318. package/dist/init/detect-framework.js.map +0 -1
  319. package/dist/init/hooks-installer.d.ts +0 -22
  320. package/dist/init/hooks-installer.d.ts.map +0 -1
  321. package/dist/init/hooks-installer.js +0 -310
  322. package/dist/init/hooks-installer.js.map +0 -1
  323. package/dist/init/index.d.ts +0 -8
  324. package/dist/init/index.d.ts.map +0 -1
  325. package/dist/init/index.js +0 -22
  326. package/dist/init/index.js.map +0 -1
  327. package/dist/init/templates.d.ts +0 -402
  328. package/dist/init/templates.d.ts.map +0 -1
  329. package/dist/init/templates.js +0 -240
  330. package/dist/init/templates.js.map +0 -1
  331. package/dist/mcp/server.d.ts +0 -12
  332. package/dist/mcp/server.d.ts.map +0 -1
  333. package/dist/mcp/server.js +0 -42
  334. package/dist/mcp/server.js.map +0 -1
  335. package/dist/mcp/telemetry.d.ts +0 -40
  336. package/dist/mcp/telemetry.d.ts.map +0 -1
  337. package/dist/mcp/telemetry.js +0 -98
  338. package/dist/mcp/telemetry.js.map +0 -1
  339. package/dist/reality/no-dead-buttons/button-sweep-generator.d.ts +0 -32
  340. package/dist/reality/no-dead-buttons/button-sweep-generator.d.ts.map +0 -1
  341. package/dist/reality/no-dead-buttons/button-sweep-generator.js +0 -236
  342. package/dist/reality/no-dead-buttons/button-sweep-generator.js.map +0 -1
  343. package/dist/reality/no-dead-buttons/index.d.ts +0 -11
  344. package/dist/reality/no-dead-buttons/index.d.ts.map +0 -1
  345. package/dist/reality/no-dead-buttons/index.js +0 -18
  346. package/dist/reality/no-dead-buttons/index.js.map +0 -1
  347. package/dist/reality/no-dead-buttons/static-scanner.d.ts +0 -34
  348. package/dist/reality/no-dead-buttons/static-scanner.d.ts.map +0 -1
  349. package/dist/reality/no-dead-buttons/static-scanner.js +0 -230
  350. package/dist/reality/no-dead-buttons/static-scanner.js.map +0 -1
  351. package/dist/reality/reality-graph.d.ts +0 -192
  352. package/dist/reality/reality-graph.d.ts.map +0 -1
  353. package/dist/reality/reality-graph.js +0 -600
  354. package/dist/reality/reality-graph.js.map +0 -1
  355. package/dist/reality/reality-runner.d.ts +0 -89
  356. package/dist/reality/reality-runner.d.ts.map +0 -1
  357. package/dist/reality/reality-runner.js +0 -540
  358. package/dist/reality/reality-runner.js.map +0 -1
  359. package/dist/reality/receipt-generator.d.ts +0 -152
  360. package/dist/reality/receipt-generator.d.ts.map +0 -1
  361. package/dist/reality/receipt-generator.js +0 -495
  362. package/dist/reality/receipt-generator.js.map +0 -1
  363. package/dist/reality/runtime-tracer.d.ts +0 -75
  364. package/dist/reality/runtime-tracer.d.ts.map +0 -1
  365. package/dist/reality/runtime-tracer.js +0 -109
  366. package/dist/reality/runtime-tracer.js.map +0 -1
  367. package/dist/runtime/auth-utils.d.ts +0 -43
  368. package/dist/runtime/auth-utils.d.ts.map +0 -1
  369. package/dist/runtime/auth-utils.js +0 -130
  370. package/dist/runtime/auth-utils.js.map +0 -1
  371. package/dist/runtime/client.d.ts +0 -74
  372. package/dist/runtime/client.d.ts.map +0 -1
  373. package/dist/runtime/client.js +0 -222
  374. package/dist/runtime/client.js.map +0 -1
  375. package/dist/runtime/creds.d.ts +0 -48
  376. package/dist/runtime/creds.d.ts.map +0 -1
  377. package/dist/runtime/creds.js +0 -245
  378. package/dist/runtime/creds.js.map +0 -1
  379. package/dist/runtime/exit-codes.d.ts +0 -49
  380. package/dist/runtime/exit-codes.d.ts.map +0 -1
  381. package/dist/runtime/exit-codes.js +0 -93
  382. package/dist/runtime/exit-codes.js.map +0 -1
  383. package/dist/runtime/index.d.ts +0 -9
  384. package/dist/runtime/index.d.ts.map +0 -1
  385. package/dist/runtime/index.js +0 -25
  386. package/dist/runtime/index.js.map +0 -1
  387. package/dist/runtime/json-output.d.ts +0 -42
  388. package/dist/runtime/json-output.d.ts.map +0 -1
  389. package/dist/runtime/json-output.js +0 -59
  390. package/dist/runtime/json-output.js.map +0 -1
  391. package/dist/runtime/semver.d.ts +0 -37
  392. package/dist/runtime/semver.d.ts.map +0 -1
  393. package/dist/runtime/semver.js +0 -110
  394. package/dist/runtime/semver.js.map +0 -1
  395. package/dist/scan/dead-ui-detector.d.ts +0 -48
  396. package/dist/scan/dead-ui-detector.d.ts.map +0 -1
  397. package/dist/scan/dead-ui-detector.js +0 -170
  398. package/dist/scan/dead-ui-detector.js.map +0 -1
  399. package/dist/scan/playwright-sweep.d.ts +0 -40
  400. package/dist/scan/playwright-sweep.d.ts.map +0 -1
  401. package/dist/scan/playwright-sweep.js +0 -216
  402. package/dist/scan/playwright-sweep.js.map +0 -1
  403. package/dist/scan/proof-bundle.d.ts +0 -25
  404. package/dist/scan/proof-bundle.d.ts.map +0 -1
  405. package/dist/scan/proof-bundle.js +0 -203
  406. package/dist/scan/proof-bundle.js.map +0 -1
  407. package/dist/scan/proof-graph.d.ts +0 -59
  408. package/dist/scan/proof-graph.d.ts.map +0 -1
  409. package/dist/scan/proof-graph.js +0 -64
  410. package/dist/scan/proof-graph.js.map +0 -1
  411. package/dist/scan/reality-sniff.d.ts +0 -56
  412. package/dist/scan/reality-sniff.d.ts.map +0 -1
  413. package/dist/scan/reality-sniff.js +0 -200
  414. package/dist/scan/reality-sniff.js.map +0 -1
  415. package/dist/scan/structural-verifier.d.ts +0 -20
  416. package/dist/scan/structural-verifier.d.ts.map +0 -1
  417. package/dist/scan/structural-verifier.js +0 -112
  418. package/dist/scan/structural-verifier.js.map +0 -1
  419. package/dist/scan/verification-engine.d.ts +0 -47
  420. package/dist/scan/verification-engine.d.ts.map +0 -1
  421. package/dist/scan/verification-engine.js +0 -141
  422. package/dist/scan/verification-engine.js.map +0 -1
  423. package/dist/scanner/baseline.d.ts +0 -52
  424. package/dist/scanner/baseline.d.ts.map +0 -1
  425. package/dist/scanner/baseline.js +0 -85
  426. package/dist/scanner/baseline.js.map +0 -1
  427. package/dist/scanner/incremental.d.ts +0 -30
  428. package/dist/scanner/incremental.d.ts.map +0 -1
  429. package/dist/scanner/incremental.js +0 -82
  430. package/dist/scanner/incremental.js.map +0 -1
  431. package/dist/scanner/parallel.d.ts +0 -43
  432. package/dist/scanner/parallel.d.ts.map +0 -1
  433. package/dist/scanner/parallel.js +0 -99
  434. package/dist/scanner/parallel.js.map +0 -1
  435. package/dist/standalone.d.ts +0 -1
  436. package/dist/standalone.d.ts.map +0 -1
  437. package/dist/standalone.js +0 -1
  438. package/dist/standalone.js.map +0 -1
  439. package/dist/truth-pack/index.d.ts +0 -102
  440. package/dist/truth-pack/index.d.ts.map +0 -1
  441. package/dist/truth-pack/index.js +0 -694
  442. package/dist/truth-pack/index.js.map +0 -1
  443. package/dist/ui/frame.d.ts +0 -68
  444. package/dist/ui/frame.d.ts.map +0 -1
  445. package/dist/ui/frame.js +0 -165
  446. package/dist/ui/frame.js.map +0 -1
  447. package/dist/ui/index.d.ts +0 -5
  448. package/dist/ui/index.d.ts.map +0 -1
  449. package/dist/ui/index.js +0 -16
  450. package/dist/ui/index.js.map +0 -1
  451. package/dist/ui.d.ts +0 -36
  452. package/dist/ui.d.ts.map +0 -1
  453. package/dist/ui.js +0 -45
  454. package/dist/ui.js.map +0 -1
@@ -0,0 +1,1117 @@
1
+ /**
2
+ * World-Class HTML Report Templates
3
+ *
4
+ * Features:
5
+ * - Modern glass-morphism design
6
+ * - Animated Chart.js visualizations
7
+ * - Interactive findings explorer
8
+ * - Dark/light mode toggle
9
+ * - Print-optimized CSS
10
+ * - Responsive mobile layout
11
+ * - Accessibility compliant
12
+ */
13
+
14
+ const { formatCategoryName } = require("./report-engine");
15
+
16
+ // ============================================================================
17
+ // CSS DESIGN SYSTEM
18
+ // ============================================================================
19
+
20
+ function getDesignSystem() {
21
+ return `
22
+ :root {
23
+ /* Colors */
24
+ --color-bg: #0f172a;
25
+ --color-bg-card: rgba(30, 41, 59, 0.8);
26
+ --color-bg-elevated: rgba(51, 65, 85, 0.6);
27
+ --color-text: #f8fafc;
28
+ --color-text-muted: #94a3b8;
29
+ --color-text-dim: #64748b;
30
+ --color-border: rgba(148, 163, 184, 0.2);
31
+
32
+ /* Brand */
33
+ --color-primary: #3b82f6;
34
+ --color-primary-glow: rgba(59, 130, 246, 0.4);
35
+
36
+ /* Status */
37
+ --color-ship: #22c55e;
38
+ --color-ship-bg: rgba(34, 197, 94, 0.15);
39
+ --color-warn: #f59e0b;
40
+ --color-warn-bg: rgba(245, 158, 11, 0.15);
41
+ --color-block: #ef4444;
42
+ --color-block-bg: rgba(239, 68, 68, 0.15);
43
+
44
+ /* Severity */
45
+ --color-critical: #ef4444;
46
+ --color-high: #f97316;
47
+ --color-medium: #eab308;
48
+ --color-low: #6b7280;
49
+
50
+ /* Spacing */
51
+ --space-xs: 4px;
52
+ --space-sm: 8px;
53
+ --space-md: 16px;
54
+ --space-lg: 24px;
55
+ --space-xl: 32px;
56
+ --space-2xl: 48px;
57
+ --space-3xl: 64px;
58
+
59
+ /* Radius */
60
+ --radius-sm: 6px;
61
+ --radius-md: 12px;
62
+ --radius-lg: 20px;
63
+ --radius-xl: 28px;
64
+ --radius-full: 9999px;
65
+
66
+ /* Shadows */
67
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
68
+ --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.3), 0 2px 4px -2px rgba(0, 0, 0, 0.3);
69
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4), 0 4px 6px -4px rgba(0, 0, 0, 0.3);
70
+ --shadow-glow: 0 0 40px var(--color-primary-glow);
71
+
72
+ /* Typography */
73
+ --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
74
+ --font-mono: 'JetBrains Mono', 'Fira Code', monospace;
75
+
76
+ /* Transitions */
77
+ --transition-fast: 150ms ease;
78
+ --transition-normal: 250ms ease;
79
+ --transition-slow: 400ms ease;
80
+ }
81
+
82
+ /* Light mode */
83
+ [data-theme="light"] {
84
+ --color-bg: #f8fafc;
85
+ --color-bg-card: rgba(255, 255, 255, 0.9);
86
+ --color-bg-elevated: rgba(241, 245, 249, 0.9);
87
+ --color-text: #0f172a;
88
+ --color-text-muted: #475569;
89
+ --color-text-dim: #94a3b8;
90
+ --color-border: rgba(148, 163, 184, 0.3);
91
+ --color-ship-bg: rgba(34, 197, 94, 0.1);
92
+ --color-warn-bg: rgba(245, 158, 11, 0.1);
93
+ --color-block-bg: rgba(239, 68, 68, 0.1);
94
+ }
95
+
96
+ * {
97
+ box-sizing: border-box;
98
+ margin: 0;
99
+ padding: 0;
100
+ }
101
+
102
+ html {
103
+ scroll-behavior: smooth;
104
+ }
105
+
106
+ body {
107
+ font-family: var(--font-sans);
108
+ background: var(--color-bg);
109
+ color: var(--color-text);
110
+ line-height: 1.6;
111
+ min-height: 100vh;
112
+ -webkit-font-smoothing: antialiased;
113
+ }
114
+
115
+ /* Background pattern */
116
+ body::before {
117
+ content: '';
118
+ position: fixed;
119
+ inset: 0;
120
+ background:
121
+ radial-gradient(circle at 20% 20%, var(--color-primary-glow), transparent 40%),
122
+ radial-gradient(circle at 80% 80%, rgba(139, 92, 246, 0.2), transparent 40%);
123
+ pointer-events: none;
124
+ z-index: -1;
125
+ }
126
+
127
+ /* ============================================================================
128
+ LAYOUT
129
+ ============================================================================ */
130
+
131
+ .report {
132
+ max-width: 1200px;
133
+ margin: 0 auto;
134
+ padding: var(--space-xl);
135
+ }
136
+
137
+ @media (max-width: 768px) {
138
+ .report {
139
+ padding: var(--space-md);
140
+ }
141
+ }
142
+
143
+ /* ============================================================================
144
+ HEADER
145
+ ============================================================================ */
146
+
147
+ .report-header {
148
+ display: flex;
149
+ justify-content: space-between;
150
+ align-items: flex-start;
151
+ margin-bottom: var(--space-2xl);
152
+ padding-bottom: var(--space-xl);
153
+ border-bottom: 1px solid var(--color-border);
154
+ }
155
+
156
+ .report-title {
157
+ font-size: 2rem;
158
+ font-weight: 700;
159
+ letter-spacing: -0.025em;
160
+ margin-bottom: var(--space-sm);
161
+ }
162
+
163
+ .report-meta {
164
+ color: var(--color-text-muted);
165
+ font-size: 0.875rem;
166
+ }
167
+
168
+ .report-meta span {
169
+ display: block;
170
+ }
171
+
172
+ .report-actions {
173
+ display: flex;
174
+ gap: var(--space-sm);
175
+ }
176
+
177
+ .btn {
178
+ display: inline-flex;
179
+ align-items: center;
180
+ gap: var(--space-sm);
181
+ padding: var(--space-sm) var(--space-md);
182
+ border-radius: var(--radius-md);
183
+ font-size: 0.875rem;
184
+ font-weight: 500;
185
+ cursor: pointer;
186
+ transition: all var(--transition-fast);
187
+ border: 1px solid var(--color-border);
188
+ background: var(--color-bg-card);
189
+ color: var(--color-text);
190
+ }
191
+
192
+ .btn:hover {
193
+ background: var(--color-bg-elevated);
194
+ transform: translateY(-1px);
195
+ }
196
+
197
+ .btn-icon {
198
+ padding: var(--space-sm);
199
+ }
200
+
201
+ /* ============================================================================
202
+ HERO SECTION (Score + Verdict)
203
+ ============================================================================ */
204
+
205
+ .hero-section {
206
+ display: grid;
207
+ grid-template-columns: 1fr 1.5fr;
208
+ gap: var(--space-xl);
209
+ margin-bottom: var(--space-2xl);
210
+ }
211
+
212
+ @media (max-width: 768px) {
213
+ .hero-section {
214
+ grid-template-columns: 1fr;
215
+ }
216
+ }
217
+
218
+ .score-card {
219
+ background: var(--color-bg-card);
220
+ backdrop-filter: blur(20px);
221
+ border-radius: var(--radius-xl);
222
+ padding: var(--space-2xl);
223
+ border: 1px solid var(--color-border);
224
+ display: flex;
225
+ flex-direction: column;
226
+ align-items: center;
227
+ justify-content: center;
228
+ text-align: center;
229
+ position: relative;
230
+ overflow: hidden;
231
+ }
232
+
233
+ .score-card::before {
234
+ content: '';
235
+ position: absolute;
236
+ inset: 0;
237
+ background: linear-gradient(135deg, transparent, rgba(255,255,255,0.05));
238
+ pointer-events: none;
239
+ }
240
+
241
+ .score-ring {
242
+ position: relative;
243
+ width: 200px;
244
+ height: 200px;
245
+ margin-bottom: var(--space-lg);
246
+ }
247
+
248
+ .score-ring svg {
249
+ transform: rotate(-90deg);
250
+ }
251
+
252
+ .score-ring-bg {
253
+ fill: none;
254
+ stroke: var(--color-border);
255
+ stroke-width: 12;
256
+ }
257
+
258
+ .score-ring-progress {
259
+ fill: none;
260
+ stroke-width: 12;
261
+ stroke-linecap: round;
262
+ transition: stroke-dasharray 1s ease-out;
263
+ }
264
+
265
+ .score-ring-progress.ship { stroke: var(--color-ship); }
266
+ .score-ring-progress.warn { stroke: var(--color-warn); }
267
+ .score-ring-progress.block { stroke: var(--color-block); }
268
+
269
+ .score-value {
270
+ position: absolute;
271
+ top: 50%;
272
+ left: 50%;
273
+ transform: translate(-50%, -50%);
274
+ font-size: 3.5rem;
275
+ font-weight: 800;
276
+ letter-spacing: -0.05em;
277
+ }
278
+
279
+ .score-label {
280
+ color: var(--color-text-muted);
281
+ font-size: 0.875rem;
282
+ text-transform: uppercase;
283
+ letter-spacing: 0.1em;
284
+ }
285
+
286
+ .verdict-card {
287
+ background: var(--color-bg-card);
288
+ backdrop-filter: blur(20px);
289
+ border-radius: var(--radius-xl);
290
+ padding: var(--space-2xl);
291
+ border: 1px solid var(--color-border);
292
+ }
293
+
294
+ .verdict-badge {
295
+ display: inline-flex;
296
+ align-items: center;
297
+ gap: var(--space-sm);
298
+ padding: var(--space-md) var(--space-xl);
299
+ border-radius: var(--radius-full);
300
+ font-size: 1.25rem;
301
+ font-weight: 700;
302
+ text-transform: uppercase;
303
+ letter-spacing: 0.05em;
304
+ margin-bottom: var(--space-lg);
305
+ }
306
+
307
+ .verdict-badge.ship {
308
+ background: var(--color-ship-bg);
309
+ color: var(--color-ship);
310
+ box-shadow: 0 0 30px rgba(34, 197, 94, 0.3);
311
+ }
312
+
313
+ .verdict-badge.warn {
314
+ background: var(--color-warn-bg);
315
+ color: var(--color-warn);
316
+ box-shadow: 0 0 30px rgba(245, 158, 11, 0.3);
317
+ }
318
+
319
+ .verdict-badge.block {
320
+ background: var(--color-block-bg);
321
+ color: var(--color-block);
322
+ box-shadow: 0 0 30px rgba(239, 68, 68, 0.3);
323
+ }
324
+
325
+ .verdict-message {
326
+ font-size: 1.125rem;
327
+ margin-bottom: var(--space-xl);
328
+ color: var(--color-text-muted);
329
+ }
330
+
331
+ .stats-grid {
332
+ display: grid;
333
+ grid-template-columns: repeat(3, 1fr);
334
+ gap: var(--space-md);
335
+ }
336
+
337
+ .stat-item {
338
+ text-align: center;
339
+ padding: var(--space-md);
340
+ background: var(--color-bg-elevated);
341
+ border-radius: var(--radius-md);
342
+ }
343
+
344
+ .stat-value {
345
+ font-size: 1.5rem;
346
+ font-weight: 700;
347
+ display: block;
348
+ }
349
+
350
+ .stat-label {
351
+ font-size: 0.75rem;
352
+ color: var(--color-text-muted);
353
+ text-transform: uppercase;
354
+ letter-spacing: 0.05em;
355
+ }
356
+
357
+ /* ============================================================================
358
+ SECTIONS
359
+ ============================================================================ */
360
+
361
+ .section {
362
+ margin-bottom: var(--space-2xl);
363
+ }
364
+
365
+ .section-header {
366
+ display: flex;
367
+ align-items: center;
368
+ gap: var(--space-md);
369
+ margin-bottom: var(--space-lg);
370
+ }
371
+
372
+ .section-icon {
373
+ width: 48px;
374
+ height: 48px;
375
+ border-radius: var(--radius-md);
376
+ background: linear-gradient(135deg, var(--color-primary), #8b5cf6);
377
+ display: flex;
378
+ align-items: center;
379
+ justify-content: center;
380
+ font-size: 1.5rem;
381
+ box-shadow: var(--shadow-glow);
382
+ }
383
+
384
+ .section-title {
385
+ font-size: 1.5rem;
386
+ font-weight: 600;
387
+ }
388
+
389
+ .section-subtitle {
390
+ color: var(--color-text-muted);
391
+ font-size: 0.875rem;
392
+ }
393
+
394
+ /* ============================================================================
395
+ CARDS
396
+ ============================================================================ */
397
+
398
+ .card {
399
+ background: var(--color-bg-card);
400
+ backdrop-filter: blur(20px);
401
+ border-radius: var(--radius-lg);
402
+ border: 1px solid var(--color-border);
403
+ padding: var(--space-xl);
404
+ transition: all var(--transition-normal);
405
+ }
406
+
407
+ .card:hover {
408
+ border-color: var(--color-primary);
409
+ box-shadow: var(--shadow-lg);
410
+ }
411
+
412
+ .card-grid {
413
+ display: grid;
414
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
415
+ gap: var(--space-lg);
416
+ }
417
+
418
+ /* ============================================================================
419
+ CATEGORY BARS
420
+ ============================================================================ */
421
+
422
+ .category-list {
423
+ display: flex;
424
+ flex-direction: column;
425
+ gap: var(--space-md);
426
+ }
427
+
428
+ .category-item {
429
+ background: var(--color-bg-elevated);
430
+ border-radius: var(--radius-md);
431
+ padding: var(--space-md) var(--space-lg);
432
+ }
433
+
434
+ .category-header {
435
+ display: flex;
436
+ justify-content: space-between;
437
+ align-items: center;
438
+ margin-bottom: var(--space-sm);
439
+ }
440
+
441
+ .category-name {
442
+ font-weight: 500;
443
+ }
444
+
445
+ .category-score {
446
+ font-weight: 700;
447
+ font-size: 1.125rem;
448
+ }
449
+
450
+ .category-score.good { color: var(--color-ship); }
451
+ .category-score.ok { color: var(--color-warn); }
452
+ .category-score.bad { color: var(--color-block); }
453
+
454
+ .category-bar {
455
+ height: 8px;
456
+ background: var(--color-border);
457
+ border-radius: var(--radius-full);
458
+ overflow: hidden;
459
+ }
460
+
461
+ .category-bar-fill {
462
+ height: 100%;
463
+ border-radius: var(--radius-full);
464
+ transition: width 0.8s ease-out;
465
+ }
466
+
467
+ .category-bar-fill.good { background: linear-gradient(90deg, var(--color-ship), #4ade80); }
468
+ .category-bar-fill.ok { background: linear-gradient(90deg, var(--color-warn), #fbbf24); }
469
+ .category-bar-fill.bad { background: linear-gradient(90deg, var(--color-block), #f87171); }
470
+
471
+ /* ============================================================================
472
+ SEVERITY CHART
473
+ ============================================================================ */
474
+
475
+ .severity-chart {
476
+ display: flex;
477
+ gap: var(--space-lg);
478
+ align-items: center;
479
+ }
480
+
481
+ .severity-donut {
482
+ flex-shrink: 0;
483
+ }
484
+
485
+ .severity-legend {
486
+ display: grid;
487
+ grid-template-columns: repeat(2, 1fr);
488
+ gap: var(--space-sm) var(--space-xl);
489
+ flex: 1;
490
+ }
491
+
492
+ .severity-item {
493
+ display: flex;
494
+ align-items: center;
495
+ gap: var(--space-sm);
496
+ }
497
+
498
+ .severity-dot {
499
+ width: 12px;
500
+ height: 12px;
501
+ border-radius: var(--radius-full);
502
+ }
503
+
504
+ .severity-dot.critical { background: var(--color-critical); }
505
+ .severity-dot.high { background: var(--color-high); }
506
+ .severity-dot.medium { background: var(--color-medium); }
507
+ .severity-dot.low { background: var(--color-low); }
508
+
509
+ .severity-label {
510
+ color: var(--color-text-muted);
511
+ font-size: 0.875rem;
512
+ }
513
+
514
+ .severity-count {
515
+ font-weight: 700;
516
+ margin-left: auto;
517
+ }
518
+
519
+ /* ============================================================================
520
+ FINDINGS
521
+ ============================================================================ */
522
+
523
+ .findings-tabs {
524
+ display: flex;
525
+ gap: var(--space-sm);
526
+ margin-bottom: var(--space-lg);
527
+ border-bottom: 1px solid var(--color-border);
528
+ padding-bottom: var(--space-md);
529
+ }
530
+
531
+ .findings-tab {
532
+ padding: var(--space-sm) var(--space-md);
533
+ border-radius: var(--radius-md);
534
+ font-size: 0.875rem;
535
+ font-weight: 500;
536
+ cursor: pointer;
537
+ transition: all var(--transition-fast);
538
+ background: transparent;
539
+ border: none;
540
+ color: var(--color-text-muted);
541
+ }
542
+
543
+ .findings-tab:hover {
544
+ color: var(--color-text);
545
+ background: var(--color-bg-elevated);
546
+ }
547
+
548
+ .findings-tab.active {
549
+ color: var(--color-primary);
550
+ background: rgba(59, 130, 246, 0.1);
551
+ }
552
+
553
+ .findings-tab .count {
554
+ display: inline-flex;
555
+ align-items: center;
556
+ justify-content: center;
557
+ min-width: 20px;
558
+ height: 20px;
559
+ border-radius: var(--radius-full);
560
+ background: var(--color-bg-elevated);
561
+ font-size: 0.75rem;
562
+ margin-left: var(--space-xs);
563
+ }
564
+
565
+ .findings-list {
566
+ display: flex;
567
+ flex-direction: column;
568
+ gap: var(--space-md);
569
+ }
570
+
571
+ .finding-card {
572
+ background: var(--color-bg-elevated);
573
+ border-radius: var(--radius-md);
574
+ padding: var(--space-lg);
575
+ border-left: 4px solid;
576
+ transition: all var(--transition-fast);
577
+ }
578
+
579
+ .finding-card:hover {
580
+ transform: translateX(4px);
581
+ }
582
+
583
+ .finding-card.critical { border-left-color: var(--color-critical); }
584
+ .finding-card.high { border-left-color: var(--color-high); }
585
+ .finding-card.medium { border-left-color: var(--color-medium); }
586
+ .finding-card.low { border-left-color: var(--color-low); }
587
+
588
+ .finding-header {
589
+ display: flex;
590
+ align-items: flex-start;
591
+ gap: var(--space-md);
592
+ margin-bottom: var(--space-sm);
593
+ }
594
+
595
+ .finding-severity {
596
+ padding: var(--space-xs) var(--space-sm);
597
+ border-radius: var(--radius-sm);
598
+ font-size: 0.625rem;
599
+ font-weight: 700;
600
+ text-transform: uppercase;
601
+ letter-spacing: 0.05em;
602
+ color: white;
603
+ }
604
+
605
+ .finding-severity.critical { background: var(--color-critical); }
606
+ .finding-severity.high { background: var(--color-high); }
607
+ .finding-severity.medium { background: var(--color-medium); }
608
+ .finding-severity.low { background: var(--color-low); }
609
+
610
+ .finding-id {
611
+ color: var(--color-text-dim);
612
+ font-size: 0.75rem;
613
+ font-family: var(--font-mono);
614
+ }
615
+
616
+ .finding-title {
617
+ font-weight: 600;
618
+ flex: 1;
619
+ }
620
+
621
+ .finding-meta {
622
+ display: flex;
623
+ gap: var(--space-lg);
624
+ margin-top: var(--space-sm);
625
+ font-size: 0.875rem;
626
+ color: var(--color-text-muted);
627
+ }
628
+
629
+ .finding-file {
630
+ font-family: var(--font-mono);
631
+ background: var(--color-bg-card);
632
+ padding: var(--space-xs) var(--space-sm);
633
+ border-radius: var(--radius-sm);
634
+ font-size: 0.75rem;
635
+ }
636
+
637
+ .finding-fix {
638
+ margin-top: var(--space-md);
639
+ padding: var(--space-md);
640
+ background: rgba(34, 197, 94, 0.1);
641
+ border-radius: var(--radius-md);
642
+ font-size: 0.875rem;
643
+ color: var(--color-ship);
644
+ }
645
+
646
+ .finding-fix::before {
647
+ content: '๐Ÿ’ก ';
648
+ }
649
+
650
+ /* ============================================================================
651
+ FIX ESTIMATES
652
+ ============================================================================ */
653
+
654
+ .fix-estimate-card {
655
+ display: flex;
656
+ align-items: center;
657
+ gap: var(--space-xl);
658
+ background: linear-gradient(135deg, var(--color-bg-card), var(--color-bg-elevated));
659
+ border-radius: var(--radius-xl);
660
+ padding: var(--space-2xl);
661
+ border: 1px solid var(--color-border);
662
+ }
663
+
664
+ .fix-estimate-total {
665
+ text-align: center;
666
+ }
667
+
668
+ .fix-estimate-value {
669
+ font-size: 3rem;
670
+ font-weight: 800;
671
+ background: linear-gradient(135deg, var(--color-primary), #8b5cf6);
672
+ -webkit-background-clip: text;
673
+ -webkit-text-fill-color: transparent;
674
+ background-clip: text;
675
+ }
676
+
677
+ .fix-estimate-label {
678
+ color: var(--color-text-muted);
679
+ font-size: 0.875rem;
680
+ text-transform: uppercase;
681
+ letter-spacing: 0.05em;
682
+ }
683
+
684
+ .fix-estimate-breakdown {
685
+ display: grid;
686
+ grid-template-columns: repeat(4, 1fr);
687
+ gap: var(--space-md);
688
+ flex: 1;
689
+ }
690
+
691
+ .fix-item {
692
+ text-align: center;
693
+ padding: var(--space-md);
694
+ background: var(--color-bg-card);
695
+ border-radius: var(--radius-md);
696
+ }
697
+
698
+ .fix-item-count {
699
+ font-size: 1.5rem;
700
+ font-weight: 700;
701
+ }
702
+
703
+ .fix-item-time {
704
+ font-size: 0.75rem;
705
+ color: var(--color-text-muted);
706
+ }
707
+
708
+ /* ============================================================================
709
+ FOOTER
710
+ ============================================================================ */
711
+
712
+ .report-footer {
713
+ margin-top: var(--space-3xl);
714
+ padding-top: var(--space-xl);
715
+ border-top: 1px solid var(--color-border);
716
+ display: flex;
717
+ justify-content: space-between;
718
+ align-items: center;
719
+ color: var(--color-text-muted);
720
+ font-size: 0.875rem;
721
+ }
722
+
723
+ .footer-brand {
724
+ display: flex;
725
+ align-items: center;
726
+ gap: var(--space-sm);
727
+ font-weight: 600;
728
+ color: var(--color-text);
729
+ }
730
+
731
+ /* ============================================================================
732
+ PRINT STYLES
733
+ ============================================================================ */
734
+
735
+ @media print {
736
+ body {
737
+ background: white !important;
738
+ color: black !important;
739
+ }
740
+
741
+ body::before {
742
+ display: none;
743
+ }
744
+
745
+ .report {
746
+ max-width: none;
747
+ padding: 0;
748
+ }
749
+
750
+ .card, .score-card, .verdict-card {
751
+ background: white !important;
752
+ border: 1px solid #e5e5e5 !important;
753
+ box-shadow: none !important;
754
+ }
755
+
756
+ .btn, .report-actions, .findings-tabs {
757
+ display: none !important;
758
+ }
759
+
760
+ .section {
761
+ page-break-inside: avoid;
762
+ }
763
+ }
764
+ `;
765
+ }
766
+
767
+ // ============================================================================
768
+ // COMPONENTS
769
+ // ============================================================================
770
+
771
+ function generateScoreRing(score, verdict) {
772
+ const radius = 85;
773
+ const circumference = 2 * Math.PI * radius;
774
+ const progress = (score / 100) * circumference;
775
+ const verdictClass = verdict.toLowerCase();
776
+
777
+ return `
778
+ <div class="score-ring">
779
+ <svg width="200" height="200" viewBox="0 0 200 200">
780
+ <circle class="score-ring-bg" cx="100" cy="100" r="${radius}"/>
781
+ <circle
782
+ class="score-ring-progress ${verdictClass}"
783
+ cx="100" cy="100" r="${radius}"
784
+ stroke-dasharray="${progress} ${circumference - progress}"
785
+ />
786
+ </svg>
787
+ <div class="score-value">${score}</div>
788
+ </div>
789
+ `;
790
+ }
791
+
792
+ function generateCategoryBars(categoryScores) {
793
+ return `
794
+ <div class="category-list">
795
+ ${Object.entries(categoryScores).map(([cat, score]) => {
796
+ const cls = score >= 80 ? "good" : score >= 50 ? "ok" : "bad";
797
+ return `
798
+ <div class="category-item">
799
+ <div class="category-header">
800
+ <span class="category-name">${formatCategoryName(cat)}</span>
801
+ <span class="category-score ${cls}">${score}%</span>
802
+ </div>
803
+ <div class="category-bar">
804
+ <div class="category-bar-fill ${cls}" style="width: ${score}%"></div>
805
+ </div>
806
+ </div>
807
+ `;
808
+ }).join("")}
809
+ </div>
810
+ `;
811
+ }
812
+
813
+ function generateSeverityDonut(severityCounts) {
814
+ const total = Object.values(severityCounts).reduce((a, b) => a + b, 0);
815
+ if (total === 0) {
816
+ return `<div style="text-align: center; color: var(--color-ship); font-size: 1.25rem; padding: 40px;">โœ… No issues found!</div>`;
817
+ }
818
+
819
+ const colors = {
820
+ critical: "#ef4444",
821
+ high: "#f97316",
822
+ medium: "#eab308",
823
+ low: "#6b7280",
824
+ };
825
+
826
+ // SVG donut chart
827
+ let cumulativePercent = 0;
828
+ const segments = [];
829
+
830
+ for (const [sev, count] of Object.entries(severityCounts)) {
831
+ if (count === 0) continue;
832
+ const percent = (count / total) * 100;
833
+ const dashArray = `${percent} ${100 - percent}`;
834
+ const dashOffset = -cumulativePercent;
835
+ segments.push(`
836
+ <circle
837
+ r="15.9155"
838
+ cx="50%" cy="50%"
839
+ fill="transparent"
840
+ stroke="${colors[sev]}"
841
+ stroke-width="6"
842
+ stroke-dasharray="${dashArray}"
843
+ stroke-dashoffset="${dashOffset}"
844
+ />
845
+ `);
846
+ cumulativePercent += percent;
847
+ }
848
+
849
+ return `
850
+ <div class="severity-chart">
851
+ <svg class="severity-donut" width="120" height="120" viewBox="0 0 42 42">
852
+ <circle r="15.9155" cx="50%" cy="50%" fill="transparent" stroke="var(--color-border)" stroke-width="6"/>
853
+ ${segments.join("")}
854
+ <text x="50%" y="50%" text-anchor="middle" dy=".3em" fill="var(--color-text)" font-size="8" font-weight="700">${total}</text>
855
+ </svg>
856
+ <div class="severity-legend">
857
+ ${Object.entries(severityCounts).map(([sev, count]) => `
858
+ <div class="severity-item">
859
+ <span class="severity-dot ${sev}"></span>
860
+ <span class="severity-label">${sev.charAt(0).toUpperCase() + sev.slice(1)}</span>
861
+ <span class="severity-count">${count}</span>
862
+ </div>
863
+ `).join("")}
864
+ </div>
865
+ </div>
866
+ `;
867
+ }
868
+
869
+ function generateFindingsList(findings, limit = 20) {
870
+ if (findings.length === 0) {
871
+ return `<div style="text-align: center; color: var(--color-text-muted); padding: 40px;">No findings to display</div>`;
872
+ }
873
+
874
+ const displayed = findings.slice(0, limit);
875
+
876
+ return `
877
+ <div class="findings-list">
878
+ ${displayed.map(f => `
879
+ <div class="finding-card ${f.severity}">
880
+ <div class="finding-header">
881
+ <span class="finding-severity ${f.severity}">${f.severity}</span>
882
+ <span class="finding-id">${f.id}</span>
883
+ <span class="finding-title">${escapeHtml(f.title)}</span>
884
+ </div>
885
+ <div class="finding-meta">
886
+ ${f.file ? `<span class="finding-file">${escapeHtml(f.file)}${f.line ? `:${f.line}` : ""}</span>` : ""}
887
+ ${f.category ? `<span>Category: ${formatCategoryName(f.category)}</span>` : ""}
888
+ ${f.fixTime ? `<span>~${f.fixTime} min to fix</span>` : ""}
889
+ </div>
890
+ ${f.fix ? `<div class="finding-fix">${escapeHtml(f.fix)}</div>` : ""}
891
+ </div>
892
+ `).join("")}
893
+ ${findings.length > limit ? `
894
+ <div style="text-align: center; color: var(--color-text-muted); padding: var(--space-lg);">
895
+ + ${findings.length - limit} more findings
896
+ </div>
897
+ ` : ""}
898
+ </div>
899
+ `;
900
+ }
901
+
902
+ function generateFixEstimates(fixEstimates) {
903
+ const { bySeverity, humanReadable } = fixEstimates;
904
+
905
+ return `
906
+ <div class="fix-estimate-card">
907
+ <div class="fix-estimate-total">
908
+ <div class="fix-estimate-value">${humanReadable}</div>
909
+ <div class="fix-estimate-label">Total Fix Time</div>
910
+ </div>
911
+ <div class="fix-estimate-breakdown">
912
+ ${Object.entries(bySeverity).map(([sev, data]) => `
913
+ <div class="fix-item">
914
+ <div class="fix-item-count" style="color: var(--color-${sev})">${data.count}</div>
915
+ <div class="fix-item-time">${formatDuration(data.totalMinutes)}</div>
916
+ <div style="font-size: 0.75rem; color: var(--color-text-dim)">${sev}</div>
917
+ </div>
918
+ `).join("")}
919
+ </div>
920
+ </div>
921
+ `;
922
+ }
923
+
924
+ function formatDuration(mins) {
925
+ if (mins === 0) return "0m";
926
+ if (mins < 60) return `${mins}m`;
927
+ const h = Math.floor(mins / 60);
928
+ const m = mins % 60;
929
+ return m > 0 ? `${h}h ${m}m` : `${h}h`;
930
+ }
931
+
932
+ function escapeHtml(str) {
933
+ if (!str) return "";
934
+ return String(str)
935
+ .replace(/&/g, "&amp;")
936
+ .replace(/</g, "&lt;")
937
+ .replace(/>/g, "&gt;")
938
+ .replace(/"/g, "&quot;");
939
+ }
940
+
941
+ // ============================================================================
942
+ // MAIN TEMPLATE
943
+ // ============================================================================
944
+
945
+ function generateWorldClassHTML(reportData, options = {}) {
946
+ const { meta, summary, findings, fixEstimates, coverage, truthpack } = reportData;
947
+ const verdictClass = summary.verdict.toLowerCase();
948
+
949
+ const verdictMessages = {
950
+ ship: "All systems go. This application is production-ready.",
951
+ warn: "Minor issues detected. Review recommended before deployment.",
952
+ block: "Critical issues found. Immediate remediation required.",
953
+ };
954
+
955
+ const verdictIcons = { ship: "โœ…", warn: "โš ๏ธ", block: "๐Ÿšซ" };
956
+
957
+ return `<!DOCTYPE html>
958
+ <html lang="en" data-theme="${options.theme || "dark"}">
959
+ <head>
960
+ <meta charset="UTF-8">
961
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
962
+ <title>Vibecheck Report - ${escapeHtml(meta.projectName)}</title>
963
+ <link rel="preconnect" href="https://fonts.googleapis.com">
964
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
965
+ <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" rel="stylesheet">
966
+ <style>${getDesignSystem()}</style>
967
+ </head>
968
+ <body>
969
+ <div class="report">
970
+ <!-- Header -->
971
+ <header class="report-header">
972
+ <div>
973
+ <h1 class="report-title">Ship Readiness Report</h1>
974
+ <div class="report-meta">
975
+ <span><strong>Project:</strong> ${escapeHtml(meta.projectName)}</span>
976
+ <span><strong>Generated:</strong> ${new Date(meta.generatedAt).toLocaleString()}</span>
977
+ <span><strong>Report ID:</strong> ${meta.reportId}</span>
978
+ </div>
979
+ </div>
980
+ <div class="report-actions">
981
+ <button class="btn btn-icon" onclick="toggleTheme()" title="Toggle theme">๐ŸŒ“</button>
982
+ <button class="btn" onclick="window.print()">๐Ÿ–จ๏ธ Print</button>
983
+ </div>
984
+ </header>
985
+
986
+ <!-- Hero Section -->
987
+ <section class="hero-section">
988
+ <div class="score-card">
989
+ ${generateScoreRing(summary.score, summary.verdict)}
990
+ <div class="score-label">Vibe Score</div>
991
+ </div>
992
+
993
+ <div class="verdict-card">
994
+ <div class="verdict-badge ${verdictClass}">
995
+ ${verdictIcons[verdictClass]} ${summary.verdict}
996
+ </div>
997
+ <p class="verdict-message">${verdictMessages[verdictClass]}</p>
998
+
999
+ <div class="stats-grid">
1000
+ <div class="stat-item">
1001
+ <span class="stat-value">${summary.totalFindings}</span>
1002
+ <span class="stat-label">Findings</span>
1003
+ </div>
1004
+ <div class="stat-item">
1005
+ <span class="stat-value">${truthpack.routes}</span>
1006
+ <span class="stat-label">Routes</span>
1007
+ </div>
1008
+ <div class="stat-item">
1009
+ <span class="stat-value">${fixEstimates.humanReadable}</span>
1010
+ <span class="stat-label">Fix Time</span>
1011
+ </div>
1012
+ </div>
1013
+ </div>
1014
+ </section>
1015
+
1016
+ <!-- Category Breakdown -->
1017
+ <section class="section">
1018
+ <div class="section-header">
1019
+ <div class="section-icon">๐Ÿ“Š</div>
1020
+ <div>
1021
+ <h2 class="section-title">Category Breakdown</h2>
1022
+ <p class="section-subtitle">Score analysis by domain</p>
1023
+ </div>
1024
+ </div>
1025
+ <div class="card">
1026
+ ${generateCategoryBars(summary.categoryScores)}
1027
+ </div>
1028
+ </section>
1029
+
1030
+ <!-- Severity Distribution -->
1031
+ <section class="section">
1032
+ <div class="section-header">
1033
+ <div class="section-icon">๐ŸŽฏ</div>
1034
+ <div>
1035
+ <h2 class="section-title">Severity Distribution</h2>
1036
+ <p class="section-subtitle">Issues breakdown by priority</p>
1037
+ </div>
1038
+ </div>
1039
+ <div class="card">
1040
+ ${generateSeverityDonut(summary.severityCounts)}
1041
+ </div>
1042
+ </section>
1043
+
1044
+ <!-- Fix Estimates -->
1045
+ <section class="section">
1046
+ <div class="section-header">
1047
+ <div class="section-icon">โฑ๏ธ</div>
1048
+ <div>
1049
+ <h2 class="section-title">Fix Time Estimates</h2>
1050
+ <p class="section-subtitle">Estimated remediation effort</p>
1051
+ </div>
1052
+ </div>
1053
+ ${generateFixEstimates(fixEstimates)}
1054
+ </section>
1055
+
1056
+ <!-- Findings -->
1057
+ ${findings.length > 0 ? `
1058
+ <section class="section">
1059
+ <div class="section-header">
1060
+ <div class="section-icon">๐Ÿ”</div>
1061
+ <div>
1062
+ <h2 class="section-title">Findings</h2>
1063
+ <p class="section-subtitle">${summary.totalFindings} issues identified</p>
1064
+ </div>
1065
+ </div>
1066
+ <div class="card">
1067
+ ${generateFindingsList(findings, options.maxFindings || 20)}
1068
+ </div>
1069
+ </section>
1070
+ ` : ""}
1071
+
1072
+ <!-- Footer -->
1073
+ <footer class="report-footer">
1074
+ <div class="footer-brand">
1075
+ <span>โšก</span>
1076
+ <span>Vibecheck</span>
1077
+ </div>
1078
+ <div>
1079
+ ${meta.reportId} ยท <a href="https://vibecheck.dev" style="color: var(--color-primary)">vibecheck.dev</a>
1080
+ </div>
1081
+ </footer>
1082
+ </div>
1083
+
1084
+ <script>
1085
+ function toggleTheme() {
1086
+ const html = document.documentElement;
1087
+ const current = html.getAttribute('data-theme');
1088
+ html.setAttribute('data-theme', current === 'dark' ? 'light' : 'dark');
1089
+ }
1090
+
1091
+ // Animate score ring on load
1092
+ document.addEventListener('DOMContentLoaded', () => {
1093
+ const ring = document.querySelector('.score-ring-progress');
1094
+ if (ring) {
1095
+ const dashArray = ring.getAttribute('stroke-dasharray');
1096
+ ring.setAttribute('stroke-dasharray', '0 1000');
1097
+ setTimeout(() => ring.setAttribute('stroke-dasharray', dashArray), 100);
1098
+ }
1099
+ });
1100
+ </script>
1101
+ </body>
1102
+ </html>`;
1103
+ }
1104
+
1105
+ // ============================================================================
1106
+ // EXPORTS
1107
+ // ============================================================================
1108
+
1109
+ module.exports = {
1110
+ generateWorldClassHTML,
1111
+ getDesignSystem,
1112
+ generateScoreRing,
1113
+ generateCategoryBars,
1114
+ generateSeverityDonut,
1115
+ generateFindingsList,
1116
+ generateFixEstimates,
1117
+ };