@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,667 @@
1
+ // bin/runners/lib/truth.js
2
+ const fg = require("fast-glob");
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const crypto = require("crypto");
6
+ const parser = require("@babel/parser");
7
+ const traverse = require("@babel/traverse").default;
8
+ const t = require("@babel/types");
9
+
10
+ // Env Truth v1
11
+ const { buildEnvTruth } = require("./env");
12
+ // Auth Truth v1
13
+ const { buildAuthTruth } = require("./auth-truth");
14
+ // Billing Truth v1
15
+ const { buildBillingTruth } = require("./billing");
16
+ // Enforcement Truth v1
17
+ const { buildEnforcementTruth } = require("./enforcement");
18
+ // Multi-framework route detection v2
19
+ const { resolveAllRoutes, detectFrameworks } = require("./route-detection");
20
+
21
+ // ---------- helpers ----------
22
+ function sha256(text) {
23
+ return "sha256:" + crypto.createHash("sha256").update(text).digest("hex");
24
+ }
25
+
26
+ function canonicalizeMethod(m) {
27
+ const u = String(m || "").toUpperCase();
28
+ if (u === "ALL" || u === "ANY" || u === "*") return "*";
29
+ return u;
30
+ }
31
+
32
+ function canonicalizePath(p) {
33
+ let s = String(p || "").trim();
34
+ if (!s.startsWith("/")) s = "/" + s;
35
+ s = s.replace(/\/+/g, "/");
36
+
37
+ // Next dynamic segments
38
+ s = s.replace(/\[\[\.{3}([^\]]+)\]\]/g, "*$1?"); // [[...slug]] -> *slug?
39
+ s = s.replace(/\[\.{3}([^\]]+)\]/g, "*$1"); // [...slug] -> *slug
40
+ s = s.replace(/\[([^\]]+)\]/g, ":$1"); // [id] -> :id
41
+
42
+ if (s.length > 1) s = s.replace(/\/$/, "");
43
+ return s;
44
+ }
45
+
46
+ function joinPaths(prefix, p) {
47
+ const a = canonicalizePath(prefix || "/");
48
+ const b = canonicalizePath(p || "/");
49
+ if (a === "/") return b;
50
+ if (b === "/") return a;
51
+ return canonicalizePath(a + "/" + b);
52
+ }
53
+
54
+ function parseFile(code) {
55
+ return parser.parse(code, { sourceType: "unambiguous", plugins: ["typescript", "jsx"] });
56
+ }
57
+
58
+ function safeRead(fileAbs) {
59
+ return fs.readFileSync(fileAbs, "utf8");
60
+ }
61
+
62
+ function ensureDir(p) {
63
+ fs.mkdirSync(p, { recursive: true });
64
+ }
65
+
66
+ function evidenceFromLoc({ fileAbs, fileRel, loc, reason }) {
67
+ if (!loc) return null;
68
+ const lines = fs.readFileSync(fileAbs, "utf8").split(/\r?\n/);
69
+ const start = Math.max(1, loc.start?.line || 1);
70
+ const end = Math.max(start, loc.end?.line || start);
71
+ const snippet = lines.slice(start - 1, end).join("\n");
72
+ return {
73
+ id: `ev_${crypto.randomBytes(4).toString("hex")}`,
74
+ file: fileRel,
75
+ lines: `${start}-${end}`,
76
+ snippetHash: sha256(snippet),
77
+ reason
78
+ };
79
+ }
80
+
81
+ // ---------- Next: app router API ----------
82
+ const HTTP_EXPORTS = new Set(["GET","POST","PUT","PATCH","DELETE","OPTIONS","HEAD"]);
83
+
84
+ async function resolveNextAppApiRoutes(repoRoot) {
85
+ const files = await fg(["**/app/api/**/route.@(ts|js)"], {
86
+ cwd: repoRoot,
87
+ absolute: true,
88
+ ignore: ["**/node_modules/**","**/.next/**","**/dist/**","**/build/**"]
89
+ });
90
+
91
+ const out = [];
92
+
93
+ for (const fileAbs of files) {
94
+ const fileRel = path.relative(repoRoot, fileAbs).replace(/\\/g, "/");
95
+ const idx = fileRel.indexOf("app/api/");
96
+ const sub = fileRel.slice(idx + "app/api/".length).replace(/\/route\.(ts|js)$/, "");
97
+ const routePath = canonicalizePath("/api/" + sub);
98
+
99
+ const code = safeRead(fileAbs);
100
+ let ast;
101
+ try { ast = parseFile(code); } catch { continue; }
102
+
103
+ const methods = [];
104
+ traverse(ast, {
105
+ ExportNamedDeclaration(p) {
106
+ const decl = p.node.declaration;
107
+ if (t.isFunctionDeclaration(decl) && decl.id?.name) {
108
+ const n = decl.id.name.toUpperCase();
109
+ if (HTTP_EXPORTS.has(n)) methods.push({ method: n, loc: decl.loc });
110
+ }
111
+ }
112
+ });
113
+
114
+ if (methods.length === 0) {
115
+ out.push({ method: "*", path: routePath, handler: fileRel, confidence: "low", evidence: [] });
116
+ continue;
117
+ }
118
+
119
+ for (const m of methods) {
120
+ const ev = evidenceFromLoc({
121
+ fileAbs, fileRel, loc: m.loc,
122
+ reason: `Next app router export ${m.method}`
123
+ });
124
+ out.push({
125
+ method: m.method,
126
+ path: routePath,
127
+ handler: fileRel,
128
+ confidence: "high",
129
+ evidence: ev ? [ev] : []
130
+ });
131
+ }
132
+ }
133
+
134
+ return out;
135
+ }
136
+
137
+ // ---------- Next: pages router API ----------
138
+ async function resolveNextPagesApiRoutes(repoRoot) {
139
+ const files = await fg(["**/pages/api/**/*.@(ts|js)"], {
140
+ cwd: repoRoot,
141
+ absolute: true,
142
+ ignore: ["**/node_modules/**","**/.next/**","**/dist/**","**/build/**"]
143
+ });
144
+
145
+ const out = [];
146
+ for (const fileAbs of files) {
147
+ const fileRel = path.relative(repoRoot, fileAbs).replace(/\\/g, "/");
148
+ const idx = fileRel.indexOf("pages/api/");
149
+ const sub = fileRel.slice(idx + "pages/api/".length).replace(/\.(ts|js)$/, "");
150
+ const routePath = canonicalizePath("/api/" + sub);
151
+
152
+ out.push({
153
+ method: "*",
154
+ path: routePath,
155
+ handler: fileRel,
156
+ confidence: "med",
157
+ evidence: []
158
+ });
159
+ }
160
+ return out;
161
+ }
162
+
163
+ // ---------- minimal relative module resolver ----------
164
+ function exists(p) {
165
+ try { return fs.statSync(p).isFile(); } catch { return false; }
166
+ }
167
+ function resolveRelativeModule(fromFileAbs, spec) {
168
+ if (!spec || (!spec.startsWith("./") && !spec.startsWith("../"))) return null;
169
+ const base = path.resolve(path.dirname(fromFileAbs), spec);
170
+ const candidates = [
171
+ base,
172
+ base + ".ts",
173
+ base + ".js",
174
+ path.join(base, "index.ts"),
175
+ path.join(base, "index.js")
176
+ ];
177
+ for (const c of candidates) if (exists(c)) return c;
178
+ return null;
179
+ }
180
+
181
+ // ---------- Fastify route extraction ----------
182
+ const FASTIFY_METHODS = new Set(["get","post","put","patch","delete","options","head","all"]);
183
+
184
+ function isFastifyMethod(name) {
185
+ return FASTIFY_METHODS.has(name);
186
+ }
187
+
188
+ function extractStringLiteral(node) {
189
+ return t.isStringLiteral(node) ? node.value : null;
190
+ }
191
+
192
+ function extractPrefixFromOpts(node) {
193
+ if (!t.isObjectExpression(node)) return null;
194
+ for (const p of node.properties) {
195
+ if (!t.isObjectProperty(p)) continue;
196
+ const key =
197
+ t.isIdentifier(p.key) ? p.key.name :
198
+ t.isStringLiteral(p.key) ? p.key.value :
199
+ null;
200
+ if (key === "prefix" && t.isStringLiteral(p.value)) return p.value.value;
201
+ }
202
+ return null;
203
+ }
204
+
205
+ function extractRouteObject(objExpr) {
206
+ let url = null;
207
+ let methods = [];
208
+ let hasHandler = false;
209
+ const hooks = [];
210
+
211
+ for (const p of objExpr.properties) {
212
+ if (!t.isObjectProperty(p)) continue;
213
+
214
+ const key =
215
+ t.isIdentifier(p.key) ? p.key.name :
216
+ t.isStringLiteral(p.key) ? p.key.value :
217
+ null;
218
+ if (!key) continue;
219
+
220
+ if (key === "url" && t.isStringLiteral(p.value)) url = p.value.value;
221
+
222
+ if (key === "method") {
223
+ if (t.isStringLiteral(p.value)) methods = [p.value.value];
224
+ if (t.isArrayExpression(p.value)) {
225
+ methods = p.value.elements.filter(e => t.isStringLiteral(e)).map(e => e.value);
226
+ }
227
+ }
228
+
229
+ if (key === "handler") hasHandler = true;
230
+ if (["preHandler","onRequest","preValidation","preSerialization"].includes(key)) hooks.push(key);
231
+ }
232
+
233
+ return { url, methods, hasHandler, hooks };
234
+ }
235
+
236
+ function resolveFastifyRoutes(repoRoot, entryAbs) {
237
+ const seen = new Set();
238
+ const routes = [];
239
+ const gaps = [];
240
+
241
+ function scanFile(fileAbs, prefix) {
242
+ if (!fileAbs || seen.has(fileAbs)) return;
243
+ seen.add(fileAbs);
244
+
245
+ const fileRel = path.relative(repoRoot, fileAbs).replace(/\\/g, "/");
246
+ const code = safeRead(fileAbs);
247
+
248
+ let ast;
249
+ try { ast = parseFile(code); } catch { return; }
250
+
251
+ // best-effort: fastify instance identifiers
252
+ const fastifyNames = new Set(["fastify"]);
253
+
254
+ traverse(ast, {
255
+ VariableDeclarator(p) {
256
+ if (!t.isIdentifier(p.node.id)) return;
257
+ const id = p.node.id.name;
258
+ const init = p.node.init;
259
+ if (!init) return;
260
+ if (t.isCallExpression(init) && t.isIdentifier(init.callee)) {
261
+ const cal = init.callee.name;
262
+ if (cal === "Fastify" || cal === "fastify") fastifyNames.add(id);
263
+ }
264
+ }
265
+ });
266
+
267
+ // helper: resolve imports for register(pluginIdent,...)
268
+ function resolveImportSpecForLocal(localName) {
269
+ let spec = null;
270
+
271
+ traverse(ast, {
272
+ ImportDeclaration(ip) {
273
+ for (const s of ip.node.specifiers) {
274
+ if ((t.isImportDefaultSpecifier(s) || t.isImportSpecifier(s)) && s.local.name === localName) {
275
+ spec = ip.node.source.value;
276
+ }
277
+ }
278
+ },
279
+ VariableDeclarator(vp) {
280
+ if (!t.isIdentifier(vp.node.id) || vp.node.id.name !== localName) return;
281
+ const init = vp.node.init;
282
+ if (!t.isCallExpression(init)) return;
283
+ if (!t.isIdentifier(init.callee) || init.callee.name !== "require") return;
284
+ const a0 = init.arguments[0];
285
+ if (t.isStringLiteral(a0)) spec = a0.value;
286
+ }
287
+ });
288
+
289
+ return spec;
290
+ }
291
+
292
+ traverse(ast, {
293
+ CallExpression(p) {
294
+ const callee = p.node.callee;
295
+ if (!t.isMemberExpression(callee)) return;
296
+ if (!t.isIdentifier(callee.object) || !t.isIdentifier(callee.property)) return;
297
+
298
+ const obj = callee.object.name;
299
+ const prop = callee.property.name;
300
+
301
+ if (!fastifyNames.has(obj)) return;
302
+
303
+ // fastify.get('/x', ...)
304
+ if (isFastifyMethod(prop)) {
305
+ const routeStr = extractStringLiteral(p.node.arguments[0]);
306
+ if (!routeStr) return;
307
+
308
+ const fullPath = joinPaths(prefix, routeStr);
309
+ const method = canonicalizeMethod(prop);
310
+
311
+ const ev = evidenceFromLoc({
312
+ fileAbs, fileRel, loc: p.node.loc,
313
+ reason: `Fastify ${prop.toUpperCase()}("${routeStr}")`
314
+ });
315
+
316
+ routes.push({
317
+ method,
318
+ path: fullPath,
319
+ handler: fileRel,
320
+ confidence: "med",
321
+ evidence: ev ? [ev] : []
322
+ });
323
+ return;
324
+ }
325
+
326
+ // fastify.route({ method, url, handler })
327
+ if (prop === "route") {
328
+ const arg0 = p.node.arguments[0];
329
+ if (!t.isObjectExpression(arg0)) return;
330
+
331
+ const r = extractRouteObject(arg0);
332
+ if (!r.url) return;
333
+
334
+ const fullPath = joinPaths(prefix, r.url);
335
+ const ms = (r.methods.length ? r.methods : ["*"]).map(canonicalizeMethod);
336
+
337
+ const ev = evidenceFromLoc({
338
+ fileAbs, fileRel, loc: p.node.loc,
339
+ reason: `Fastify.route({ url: "${r.url}" })`
340
+ });
341
+
342
+ for (const m of ms) {
343
+ routes.push({
344
+ method: m,
345
+ path: fullPath,
346
+ handler: fileRel,
347
+ hooks: r.hooks,
348
+ confidence: r.hasHandler ? "med" : "low",
349
+ evidence: ev ? [ev] : []
350
+ });
351
+ }
352
+ return;
353
+ }
354
+
355
+ // fastify.register(plugin, { prefix })
356
+ if (prop === "register") {
357
+ const pluginArg = p.node.arguments[0];
358
+ const optsArg = p.node.arguments[1];
359
+ const childPrefixRaw = extractPrefixFromOpts(optsArg);
360
+ const childPrefix = childPrefixRaw ? joinPaths(prefix, childPrefixRaw) : prefix;
361
+
362
+ // inline plugin
363
+ if (t.isFunctionExpression(pluginArg) || t.isArrowFunctionExpression(pluginArg)) {
364
+ const param0 = pluginArg.params[0];
365
+ const innerName = t.isIdentifier(param0) ? param0.name : "fastify";
366
+
367
+ // traverse just the plugin body (best effort)
368
+ traverse(pluginArg.body, {
369
+ CallExpression(pp) {
370
+ const c = pp.node.callee;
371
+ if (!t.isMemberExpression(c)) return;
372
+ if (!t.isIdentifier(c.object) || !t.isIdentifier(c.property)) return;
373
+ if (c.object.name !== innerName) return;
374
+
375
+ const pr = c.property.name;
376
+
377
+ if (isFastifyMethod(pr)) {
378
+ const rs = extractStringLiteral(pp.node.arguments[0]);
379
+ if (!rs) return;
380
+ const fullPath = joinPaths(childPrefix, rs);
381
+ const method = canonicalizeMethod(pr);
382
+
383
+ const ev = evidenceFromLoc({
384
+ fileAbs, fileRel, loc: pp.node.loc,
385
+ reason: `Fastify plugin ${pr.toUpperCase()}("${rs}") prefix="${childPrefixRaw || ""}"`
386
+ });
387
+
388
+ routes.push({ method, path: fullPath, handler: fileRel, confidence: "med", evidence: ev ? [ev] : [] });
389
+ }
390
+
391
+ if (pr === "route") {
392
+ const a0 = pp.node.arguments[0];
393
+ if (!t.isObjectExpression(a0)) return;
394
+ const r = extractRouteObject(a0);
395
+ if (!r.url) return;
396
+ const fullPath = joinPaths(childPrefix, r.url);
397
+ const ms = (r.methods.length ? r.methods : ["*"]).map(canonicalizeMethod);
398
+
399
+ const ev = evidenceFromLoc({
400
+ fileAbs, fileRel, loc: pp.node.loc,
401
+ reason: `Fastify plugin route("${r.url}") prefix="${childPrefixRaw || ""}"`
402
+ });
403
+
404
+ for (const m of ms) routes.push({ method: m, path: fullPath, handler: fileRel, confidence: "med", evidence: ev ? [ev] : [] });
405
+ }
406
+ }
407
+ }, p.scope, p);
408
+
409
+ return;
410
+ }
411
+
412
+ // imported plugin identifier
413
+ if (t.isIdentifier(pluginArg)) {
414
+ const localName = pluginArg.name;
415
+ const spec = resolveImportSpecForLocal(localName);
416
+
417
+ if (!spec) {
418
+ gaps.push({ kind: "fastify_plugin_unresolved", file: fileRel, name: localName });
419
+ return;
420
+ }
421
+
422
+ const resolved = resolveRelativeModule(fileAbs, spec);
423
+ if (!resolved) {
424
+ gaps.push({ kind: "fastify_plugin_unresolved", file: fileRel, spec });
425
+ return;
426
+ }
427
+
428
+ scanFile(resolved, childPrefix);
429
+ }
430
+ }
431
+ }
432
+ });
433
+ }
434
+
435
+ scanFile(entryAbs, "/");
436
+ return { routes, gaps };
437
+ }
438
+
439
+ // ---------- client refs (fetch + axios string literal only) ----------
440
+ function isAxiosMember(node) {
441
+ return t.isMemberExpression(node) &&
442
+ t.isIdentifier(node.object) &&
443
+ t.isIdentifier(node.property) &&
444
+ ["get","post","put","patch","delete"].includes(node.property.name);
445
+ }
446
+
447
+ async function resolveClientRouteRefs(repoRoot) {
448
+ const files = await fg(["**/*.{ts,tsx,js,jsx}"], {
449
+ cwd: repoRoot,
450
+ absolute: true,
451
+ ignore: [
452
+ "**/node_modules/**",
453
+ "**/.next/**",
454
+ "**/dist/**",
455
+ "**/build/**",
456
+ "**/test/**",
457
+ "**/tests/**",
458
+ "**/__tests__/**",
459
+ "**/*.test.*",
460
+ "**/*.spec.*",
461
+ "**/jest.setup.*",
462
+ "**/jest.config.*",
463
+ "**/*.mock.*",
464
+ "**/mocks/**",
465
+ "**/fixtures/**"
466
+ ]
467
+ });
468
+
469
+ const out = [];
470
+
471
+ for (const fileAbs of files) {
472
+ const fileRel = path.relative(repoRoot, fileAbs).replace(/\\/g, "/");
473
+ const code = safeRead(fileAbs);
474
+
475
+ let ast;
476
+ try { ast = parseFile(code); } catch { continue; }
477
+
478
+ traverse(ast, {
479
+ CallExpression(p) {
480
+ const callee = p.node.callee;
481
+
482
+ // fetch("/api/x", { method: "POST" })
483
+ if (t.isIdentifier(callee) && callee.name === "fetch") {
484
+ const a0 = p.node.arguments[0];
485
+ if (!t.isStringLiteral(a0)) return;
486
+
487
+ const url = a0.value;
488
+ if (!url.startsWith("/")) return;
489
+
490
+ let method = "*";
491
+ const a1 = p.node.arguments[1];
492
+ if (t.isObjectExpression(a1)) {
493
+ for (const prop of a1.properties) {
494
+ if (!t.isObjectProperty(prop)) continue;
495
+ const key =
496
+ t.isIdentifier(prop.key) ? prop.key.name :
497
+ t.isStringLiteral(prop.key) ? prop.key.value :
498
+ null;
499
+ if (key === "method" && t.isStringLiteral(prop.value)) {
500
+ method = canonicalizeMethod(prop.value.value);
501
+ }
502
+ }
503
+ }
504
+
505
+ const ev = evidenceFromLoc({
506
+ fileAbs, fileRel, loc: p.node.loc,
507
+ reason: `Client fetch("${url}")`
508
+ });
509
+
510
+ out.push({
511
+ method,
512
+ path: canonicalizePath(url),
513
+ source: fileRel,
514
+ confidence: "high",
515
+ evidence: ev ? [ev] : []
516
+ });
517
+ return;
518
+ }
519
+
520
+ // axios.get("/api/x")
521
+ if (isAxiosMember(callee)) {
522
+ const verb = callee.property.name.toUpperCase();
523
+ const a0 = p.node.arguments[0];
524
+ if (!t.isStringLiteral(a0)) return;
525
+
526
+ const url = a0.value;
527
+ if (!url.startsWith("/")) return;
528
+
529
+ const ev = evidenceFromLoc({
530
+ fileAbs, fileRel, loc: p.node.loc,
531
+ reason: `Client axios.${verb.toLowerCase()}("${url}")`
532
+ });
533
+
534
+ out.push({
535
+ method: canonicalizeMethod(verb),
536
+ path: canonicalizePath(url),
537
+ source: fileRel,
538
+ confidence: "high",
539
+ evidence: ev ? [ev] : []
540
+ });
541
+ }
542
+ }
543
+ });
544
+ }
545
+
546
+ return out;
547
+ }
548
+
549
+ // ---------- fastify entry detection ----------
550
+ function detectFastifyEntry(repoRoot) {
551
+ const candidates = [
552
+ "src/server.ts","src/server.js",
553
+ "server.ts","server.js",
554
+ "src/index.ts","src/index.js",
555
+ "index.ts","index.js"
556
+ ];
557
+ for (const rel of candidates) {
558
+ const abs = path.join(repoRoot, rel);
559
+ if (exists(abs)) return rel;
560
+ }
561
+ return null;
562
+ }
563
+
564
+ // ---------- truthpack build/write ----------
565
+ async function buildTruthpack({ repoRoot, fastifyEntry }) {
566
+ // Next.js routes (App Router + Pages Router)
567
+ const nextApp = await resolveNextAppApiRoutes(repoRoot);
568
+ const nextPages = await resolveNextPagesApiRoutes(repoRoot);
569
+
570
+ // Fastify routes (legacy detection)
571
+ const entryRel = fastifyEntry || detectFastifyEntry(repoRoot);
572
+ let fastify = { routes: [], gaps: [] };
573
+ if (entryRel) {
574
+ const entryAbs = path.isAbsolute(entryRel) ? entryRel : path.join(repoRoot, entryRel);
575
+ if (exists(entryAbs)) fastify = resolveFastifyRoutes(repoRoot, entryAbs);
576
+ }
577
+
578
+ // Multi-framework route detection v2 (Express, Flask, FastAPI, Django, Hono, Koa, etc.)
579
+ const multiFramework = await resolveAllRoutes(repoRoot);
580
+ const detectedFrameworks = await detectFrameworks(repoRoot);
581
+
582
+ // Client refs (JS/TS fetch/axios + Python requests/httpx)
583
+ const clientRefs = await resolveClientRouteRefs(repoRoot);
584
+ const allClientRefs = [...clientRefs, ...multiFramework.clientRefs];
585
+
586
+ // Merge all server routes (dedupe by method+path)
587
+ const serverRoutesRaw = [...nextApp, ...nextPages, ...fastify.routes, ...multiFramework.routes];
588
+ const seenRoutes = new Set();
589
+ const server = [];
590
+ for (const r of serverRoutesRaw) {
591
+ const key = `${r.method}:${r.path}`;
592
+ if (!seenRoutes.has(key)) {
593
+ seenRoutes.add(key);
594
+ server.push(r);
595
+ }
596
+ }
597
+
598
+ // Merge gaps
599
+ const allGaps = [...(fastify.gaps || []), ...(multiFramework.gaps || [])];
600
+
601
+ // Env Truth v1
602
+ const env = await buildEnvTruth(repoRoot);
603
+
604
+ // Auth Truth v1
605
+ const auth = await buildAuthTruth(repoRoot, server);
606
+
607
+ // Billing Truth v1
608
+ const billing = await buildBillingTruth(repoRoot);
609
+
610
+ // Enforcement Truth v1
611
+ const enforcement = buildEnforcementTruth(repoRoot, server);
612
+
613
+ // Determine frameworks
614
+ const frameworks = new Set(["next", "fastify"]);
615
+ detectedFrameworks.forEach(f => frameworks.add(f));
616
+ server.forEach(r => r.framework && frameworks.add(r.framework));
617
+
618
+ const truthpack = {
619
+ meta: {
620
+ version: "2.0.0",
621
+ generatedAt: new Date().toISOString(),
622
+ repoRoot,
623
+ commit: { sha: process.env.VIBECHECK_COMMIT_SHA || "unknown" }
624
+ },
625
+ project: { frameworks: Array.from(frameworks), workspaces: [], entrypoints: [] },
626
+ routes: { server, clientRefs: allClientRefs, gaps: allGaps },
627
+ env,
628
+ auth,
629
+ billing,
630
+ enforcement
631
+ };
632
+
633
+ const hash = sha256(JSON.stringify(truthpack));
634
+ truthpack.index = { hashes: { truthpackHash: hash }, evidenceRefs: [] };
635
+
636
+ return truthpack;
637
+ }
638
+
639
+ function writeTruthpack(repoRoot, truthpack) {
640
+ const dir = path.join(repoRoot, ".vibecheck");
641
+ ensureDir(dir);
642
+ // Spec: .vibecheck/truthpack.json (not .vibecheck/truth/truthpack.json)
643
+ fs.writeFileSync(path.join(dir, "truthpack.json"), JSON.stringify(truthpack, null, 2));
644
+ }
645
+
646
+ function loadTruthpack(repoRoot) {
647
+ // Spec path: .vibecheck/truthpack.json
648
+ const specPath = path.join(repoRoot, ".vibecheck", "truthpack.json");
649
+ // Legacy path: .vibecheck/truth/truthpack.json (backward compat)
650
+ const legacyPath = path.join(repoRoot, ".vibecheck", "truth", "truthpack.json");
651
+
652
+ try {
653
+ return JSON.parse(fs.readFileSync(specPath, "utf8"));
654
+ } catch {
655
+ // Try legacy path
656
+ try { return JSON.parse(fs.readFileSync(legacyPath, "utf8")); } catch { return null; }
657
+ }
658
+ }
659
+
660
+ module.exports = {
661
+ canonicalizeMethod,
662
+ canonicalizePath,
663
+ buildTruthpack,
664
+ writeTruthpack,
665
+ loadTruthpack,
666
+ detectFastifyEntry
667
+ };