@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,972 @@
1
+ /**
2
+ * Proof-Carrying Context System
3
+ * Every claim must have file:line evidence or it gets flagged as hypothesis
4
+ */
5
+
6
+ const fs = require("fs");
7
+ const path = require("path");
8
+
9
+ /**
10
+ * Extract proof-carrying facts with exact file:line references
11
+ */
12
+ function extractProofCarryingFacts(projectPath) {
13
+ const facts = {
14
+ verified: [], // Claims with proof
15
+ hypotheses: [], // Claims without proof (flagged)
16
+ proofMap: {}, // Quick lookup: claim -> proof
17
+ };
18
+
19
+ // 1. Extract verified route facts
20
+ const routeFacts = extractVerifiedRoutes(projectPath);
21
+ facts.verified.push(...routeFacts);
22
+
23
+ // 2. Extract verified schema facts
24
+ const schemaFacts = extractVerifiedSchema(projectPath);
25
+ facts.verified.push(...schemaFacts);
26
+
27
+ // 3. Extract verified export facts
28
+ const exportFacts = extractVerifiedExports(projectPath);
29
+ facts.verified.push(...exportFacts);
30
+
31
+ // 4. Extract verified middleware chain
32
+ const middlewareFacts = extractVerifiedMiddleware(projectPath);
33
+ facts.verified.push(...middlewareFacts);
34
+
35
+ // Build proof map
36
+ facts.verified.forEach(f => {
37
+ facts.proofMap[f.claim] = {
38
+ file: f.file,
39
+ line: f.line,
40
+ evidence: f.evidence
41
+ };
42
+ });
43
+
44
+ return facts;
45
+ }
46
+
47
+ /**
48
+ * Extract routes with exact line numbers as proof
49
+ */
50
+ function extractVerifiedRoutes(projectPath) {
51
+ const facts = [];
52
+ const routePatterns = [
53
+ /app\.(get|post|put|delete|patch)\s*\(\s*['"`]([^'"`]+)['"`]/g,
54
+ /router\.(get|post|put|delete|patch)\s*\(\s*['"`]([^'"`]+)['"`]/g,
55
+ ];
56
+
57
+ const files = findSourceFiles(projectPath, [".ts", ".js"], 5);
58
+
59
+ for (const file of files) {
60
+ if (!file.includes("route") && !file.includes("api")) continue;
61
+
62
+ try {
63
+ const content = fs.readFileSync(file, "utf-8");
64
+ const lines = content.split("\n");
65
+ const relativePath = path.relative(projectPath, file);
66
+
67
+ lines.forEach((line, idx) => {
68
+ for (const pattern of routePatterns) {
69
+ pattern.lastIndex = 0;
70
+ let match;
71
+ while ((match = pattern.exec(line)) !== null) {
72
+ facts.push({
73
+ type: "route",
74
+ claim: `Endpoint ${match[1].toUpperCase()} ${match[2]} exists`,
75
+ file: relativePath,
76
+ line: idx + 1,
77
+ evidence: line.trim().substring(0, 100),
78
+ method: match[1],
79
+ path: match[2]
80
+ });
81
+ }
82
+ }
83
+ });
84
+ } catch {}
85
+ }
86
+
87
+ return facts;
88
+ }
89
+
90
+ /**
91
+ * Extract schema tables with exact line numbers
92
+ */
93
+ function extractVerifiedSchema(projectPath) {
94
+ const facts = [];
95
+ const schemaFiles = findSourceFiles(projectPath, [".ts", ".js"], 5)
96
+ .filter(f => f.includes("schema"));
97
+
98
+ for (const file of schemaFiles) {
99
+ try {
100
+ const content = fs.readFileSync(file, "utf-8");
101
+ const lines = content.split("\n");
102
+ const relativePath = path.relative(projectPath, file);
103
+
104
+ // Drizzle tables
105
+ const tablePattern = /export\s+const\s+(\w+)\s*=\s*(?:pgTable|sqliteTable|mysqlTable)\s*\(\s*['"`](\w+)['"`]/;
106
+
107
+ lines.forEach((line, idx) => {
108
+ const match = line.match(tablePattern);
109
+ if (match) {
110
+ facts.push({
111
+ type: "schema_table",
112
+ claim: `Table "${match[2]}" exists (exported as ${match[1]})`,
113
+ file: relativePath,
114
+ line: idx + 1,
115
+ evidence: line.trim(),
116
+ tableName: match[2],
117
+ exportName: match[1]
118
+ });
119
+ }
120
+ });
121
+
122
+ // Extract columns for each table
123
+ let currentTable = null;
124
+ let tableStartLine = 0;
125
+
126
+ lines.forEach((line, idx) => {
127
+ const tableMatch = line.match(tablePattern);
128
+ if (tableMatch) {
129
+ currentTable = tableMatch[2];
130
+ tableStartLine = idx + 1;
131
+ }
132
+
133
+ if (currentTable) {
134
+ // Column patterns
135
+ const colPatterns = [
136
+ /(\w+):\s*(?:text|varchar|integer|boolean|timestamp|serial|uuid|json)/,
137
+ /\.(\w+)\s*\(/
138
+ ];
139
+
140
+ for (const colPattern of colPatterns) {
141
+ const colMatch = line.match(colPattern);
142
+ if (colMatch && !["pgTable", "sqliteTable", "mysqlTable", "export", "const"].includes(colMatch[1])) {
143
+ facts.push({
144
+ type: "schema_column",
145
+ claim: `Column "${colMatch[1]}" exists in table "${currentTable}"`,
146
+ file: relativePath,
147
+ line: idx + 1,
148
+ evidence: line.trim().substring(0, 80),
149
+ tableName: currentTable,
150
+ columnName: colMatch[1]
151
+ });
152
+ }
153
+ }
154
+ }
155
+
156
+ // Reset on closing brace at root level
157
+ if (line.match(/^\s*\}\s*\)/) && currentTable) {
158
+ currentTable = null;
159
+ }
160
+ });
161
+ } catch {}
162
+ }
163
+
164
+ return facts;
165
+ }
166
+
167
+ /**
168
+ * Extract verified exports with line numbers
169
+ */
170
+ function extractVerifiedExports(projectPath) {
171
+ const facts = [];
172
+ const files = findSourceFiles(projectPath, [".ts", ".tsx"], 4);
173
+
174
+ for (const file of files) {
175
+ try {
176
+ const content = fs.readFileSync(file, "utf-8");
177
+ const lines = content.split("\n");
178
+ const relativePath = path.relative(projectPath, file);
179
+
180
+ lines.forEach((line, idx) => {
181
+ // Named exports
182
+ const namedExport = line.match(/export\s+(?:const|function|class|type|interface)\s+(\w+)/);
183
+ if (namedExport) {
184
+ facts.push({
185
+ type: "export",
186
+ claim: `"${namedExport[1]}" is exported from ${relativePath}`,
187
+ file: relativePath,
188
+ line: idx + 1,
189
+ evidence: line.trim().substring(0, 80),
190
+ exportName: namedExport[1]
191
+ });
192
+ }
193
+
194
+ // Default exports
195
+ const defaultExport = line.match(/export\s+default\s+(?:function\s+)?(\w+)/);
196
+ if (defaultExport) {
197
+ facts.push({
198
+ type: "default_export",
199
+ claim: `"${defaultExport[1]}" is the default export from ${relativePath}`,
200
+ file: relativePath,
201
+ line: idx + 1,
202
+ evidence: line.trim().substring(0, 80),
203
+ exportName: defaultExport[1]
204
+ });
205
+ }
206
+ });
207
+ } catch {}
208
+ }
209
+
210
+ return facts;
211
+ }
212
+
213
+ /**
214
+ * Extract middleware chain with proof
215
+ */
216
+ function extractVerifiedMiddleware(projectPath) {
217
+ const facts = [];
218
+ const files = findSourceFiles(projectPath, [".ts", ".js"], 5);
219
+
220
+ for (const file of files) {
221
+ if (!file.includes("middleware") && !file.includes("server") && !file.includes("app")) continue;
222
+
223
+ try {
224
+ const content = fs.readFileSync(file, "utf-8");
225
+ const lines = content.split("\n");
226
+ const relativePath = path.relative(projectPath, file);
227
+
228
+ lines.forEach((line, idx) => {
229
+ // app.use() patterns
230
+ const useMatch = line.match(/app\.use\s*\(\s*(?:['"`]([^'"`]+)['"`]\s*,\s*)?(\w+)/);
231
+ if (useMatch) {
232
+ facts.push({
233
+ type: "middleware",
234
+ claim: `Middleware "${useMatch[2]}" is applied${useMatch[1] ? ` to path "${useMatch[1]}"` : " globally"}`,
235
+ file: relativePath,
236
+ line: idx + 1,
237
+ evidence: line.trim().substring(0, 100),
238
+ middlewareName: useMatch[2],
239
+ path: useMatch[1] || "/"
240
+ });
241
+ }
242
+ });
243
+ } catch {}
244
+ }
245
+
246
+ return facts;
247
+ }
248
+
249
+ /**
250
+ * Symbol Reality Check - detect hallucinated imports/functions
251
+ */
252
+ function symbolVibecheck(projectPath) {
253
+ const reality = {
254
+ availableSymbols: new Set(),
255
+ availableImports: new Map(),
256
+ installedPackages: new Set(),
257
+ missingSymbols: [],
258
+ };
259
+
260
+ // 1. Collect all exported symbols
261
+ const files = findSourceFiles(projectPath, [".ts", ".tsx", ".js", ".jsx"], 4);
262
+
263
+ for (const file of files) {
264
+ try {
265
+ const content = fs.readFileSync(file, "utf-8");
266
+ const relativePath = path.relative(projectPath, file);
267
+
268
+ // Named exports
269
+ const exports = content.matchAll(/export\s+(?:const|function|class|type|interface)\s+(\w+)/g);
270
+ for (const match of exports) {
271
+ reality.availableSymbols.add(match[1]);
272
+ if (!reality.availableImports.has(match[1])) {
273
+ reality.availableImports.set(match[1], []);
274
+ }
275
+ reality.availableImports.get(match[1]).push(relativePath);
276
+ }
277
+ } catch {}
278
+ }
279
+
280
+ // 2. Collect installed packages
281
+ const pkgPath = path.join(projectPath, "package.json");
282
+ if (fs.existsSync(pkgPath)) {
283
+ try {
284
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
285
+ Object.keys(pkg.dependencies || {}).forEach(d => reality.installedPackages.add(d));
286
+ Object.keys(pkg.devDependencies || {}).forEach(d => reality.installedPackages.add(d));
287
+ } catch {}
288
+ }
289
+
290
+ // 3. Check for potentially hallucinated imports in recent files
291
+ for (const file of files.slice(0, 50)) {
292
+ try {
293
+ const content = fs.readFileSync(file, "utf-8");
294
+ const relativePath = path.relative(projectPath, file);
295
+
296
+ // Check imports from packages
297
+ const packageImports = content.matchAll(/import\s+.*?\s+from\s+['"]([^./][^'"]+)['"]/g);
298
+ for (const match of packageImports) {
299
+ const pkgName = match[1].startsWith("@")
300
+ ? match[1].split("/").slice(0, 2).join("/")
301
+ : match[1].split("/")[0];
302
+
303
+ if (!reality.installedPackages.has(pkgName)) {
304
+ reality.missingSymbols.push({
305
+ type: "missing_package",
306
+ file: relativePath,
307
+ package: pkgName,
308
+ fullImport: match[0]
309
+ });
310
+ }
311
+ }
312
+ } catch {}
313
+ }
314
+
315
+ return reality;
316
+ }
317
+
318
+ /**
319
+ * Risk × Centrality × Churn scoring
320
+ */
321
+ function computeFileImportanceScore(projectPath) {
322
+ const scores = {};
323
+ const files = findSourceFiles(projectPath, [".ts", ".tsx", ".js", ".jsx"], 5);
324
+
325
+ // Risk tags
326
+ const riskPatterns = {
327
+ auth: ["auth", "login", "session", "token", "permission", "role"],
328
+ payments: ["payment", "stripe", "billing", "subscription", "checkout"],
329
+ migrations: ["migration", "schema", "database", "db"],
330
+ security: ["secret", "encrypt", "password", "credential", "key"],
331
+ infra: ["config", "env", "server", "deploy", "docker"]
332
+ };
333
+
334
+ // Compute import centrality
335
+ const importCounts = new Map();
336
+ const importedBy = new Map();
337
+
338
+ for (const file of files) {
339
+ try {
340
+ const content = fs.readFileSync(file, "utf-8");
341
+ const relativePath = path.relative(projectPath, file);
342
+
343
+ const imports = content.matchAll(/from\s+['"]([^'"]+)['"]/g);
344
+ for (const match of imports) {
345
+ const importPath = match[1];
346
+ if (importPath.startsWith(".") || importPath.startsWith("@/")) {
347
+ importCounts.set(importPath, (importCounts.get(importPath) || 0) + 1);
348
+ if (!importedBy.has(importPath)) {
349
+ importedBy.set(importPath, []);
350
+ }
351
+ importedBy.get(importPath).push(relativePath);
352
+ }
353
+ }
354
+ } catch {}
355
+ }
356
+
357
+ // Score each file
358
+ for (const file of files) {
359
+ const relativePath = path.relative(projectPath, file);
360
+ const fileName = path.basename(file).toLowerCase();
361
+ const filePath = relativePath.toLowerCase();
362
+
363
+ // Risk score (0-1)
364
+ let riskScore = 0;
365
+ for (const [category, patterns] of Object.entries(riskPatterns)) {
366
+ if (patterns.some(p => filePath.includes(p) || fileName.includes(p))) {
367
+ riskScore = Math.max(riskScore, 0.8);
368
+ if (category === "auth" || category === "payments") {
369
+ riskScore = 1.0;
370
+ }
371
+ }
372
+ }
373
+
374
+ // Centrality score (0-1)
375
+ let centralityScore = 0;
376
+ const maxImports = Math.max(...Array.from(importCounts.values()), 1);
377
+ for (const [importPath, count] of importCounts) {
378
+ if (relativePath.includes(importPath.replace(/^\.\/|@\//g, ""))) {
379
+ centralityScore = Math.max(centralityScore, count / maxImports);
380
+ }
381
+ }
382
+
383
+ // Entry point bonus
384
+ if (fileName.includes("index") || fileName.includes("main") || fileName.includes("app")) {
385
+ centralityScore = Math.max(centralityScore, 0.5);
386
+ }
387
+
388
+ // Schema/config files are always important
389
+ if (fileName.includes("schema") || fileName.includes("config")) {
390
+ centralityScore = Math.max(centralityScore, 0.7);
391
+ riskScore = Math.max(riskScore, 0.6);
392
+ }
393
+
394
+ // Final score: Risk dominates
395
+ const score = (3.0 * riskScore) + (1.5 * centralityScore);
396
+
397
+ scores[relativePath] = {
398
+ score: Math.round(score * 100) / 100,
399
+ risk: Math.round(riskScore * 100) / 100,
400
+ centrality: Math.round(centralityScore * 100) / 100,
401
+ importedBy: importedBy.get(relativePath)?.slice(0, 5) || []
402
+ };
403
+ }
404
+
405
+ // Sort and return top files
406
+ const sorted = Object.entries(scores)
407
+ .sort((a, b) => b[1].score - a[1].score)
408
+ .slice(0, 50);
409
+
410
+ return Object.fromEntries(sorted);
411
+ }
412
+
413
+ /**
414
+ * Anti-Pattern Museum - real examples from repo
415
+ */
416
+ function buildAntiPatternMuseum(projectPath) {
417
+ const museum = {
418
+ detected: [],
419
+ patterns: []
420
+ };
421
+
422
+ const files = findSourceFiles(projectPath, [".ts", ".tsx", ".js", ".jsx"], 4);
423
+
424
+ const antiPatterns = [
425
+ {
426
+ name: "any_type_usage",
427
+ pattern: /:\s*any\b/,
428
+ severity: "warning",
429
+ message: "Usage of 'any' type detected",
430
+ fix: "Use proper TypeScript type or 'unknown'"
431
+ },
432
+ {
433
+ name: "console_in_production",
434
+ pattern: /console\.(log|warn|error)\s*\(/,
435
+ severity: "info",
436
+ message: "Console statement in production code",
437
+ fix: "Use a proper logging service"
438
+ },
439
+ {
440
+ name: "hardcoded_secret",
441
+ pattern: /(?:password|secret|api_?key|token)\s*[:=]\s*['"][^'"]{8,}['"]/i,
442
+ severity: "critical",
443
+ message: "Potential hardcoded secret",
444
+ fix: "Use environment variables"
445
+ },
446
+ {
447
+ name: "todo_in_code",
448
+ pattern: /\/\/\s*TODO|\/\/\s*FIXME|\/\/\s*HACK/i,
449
+ severity: "info",
450
+ message: "TODO/FIXME comment found",
451
+ fix: "Track in issue tracker instead"
452
+ },
453
+ {
454
+ name: "empty_catch",
455
+ pattern: /catch\s*\([^)]*\)\s*\{\s*\}/,
456
+ severity: "warning",
457
+ message: "Empty catch block (swallowing errors)",
458
+ fix: "Log error or rethrow"
459
+ },
460
+ {
461
+ name: "sync_fs_operation",
462
+ pattern: /fs\.(?:readFileSync|writeFileSync|existsSync)/,
463
+ severity: "info",
464
+ message: "Synchronous file operation",
465
+ fix: "Use async fs operations in server code"
466
+ },
467
+ {
468
+ name: "raw_sql_injection_risk",
469
+ pattern: /query\s*\(\s*`[^`]*\$\{/,
470
+ severity: "critical",
471
+ message: "Potential SQL injection via template literal",
472
+ fix: "Use parameterized queries"
473
+ }
474
+ ];
475
+
476
+ for (const file of files.slice(0, 100)) {
477
+ try {
478
+ const content = fs.readFileSync(file, "utf-8");
479
+ const lines = content.split("\n");
480
+ const relativePath = path.relative(projectPath, file);
481
+
482
+ lines.forEach((line, idx) => {
483
+ for (const ap of antiPatterns) {
484
+ if (ap.pattern.test(line)) {
485
+ museum.detected.push({
486
+ antiPattern: ap.name,
487
+ severity: ap.severity,
488
+ message: ap.message,
489
+ file: relativePath,
490
+ line: idx + 1,
491
+ evidence: line.trim().substring(0, 100),
492
+ suggestedFix: ap.fix
493
+ });
494
+ }
495
+ }
496
+ });
497
+ } catch {}
498
+ }
499
+
500
+ // Group by pattern
501
+ museum.patterns = antiPatterns.map(ap => ({
502
+ name: ap.name,
503
+ severity: ap.severity,
504
+ message: ap.message,
505
+ fix: ap.fix,
506
+ instances: museum.detected.filter(d => d.antiPattern === ap.name).slice(0, 5)
507
+ })).filter(p => p.instances.length > 0);
508
+
509
+ return museum;
510
+ }
511
+
512
+ /**
513
+ * Context Spine - small, stable, always-included context
514
+ */
515
+ function generateContextSpine(projectPath, analysis) {
516
+ return {
517
+ architecture: {
518
+ framework: analysis.framework,
519
+ language: analysis.language,
520
+ stateManagement: analysis.antiHallucination?.stateManagement,
521
+ orm: analysis.antiHallucination?.ormType,
522
+ ui: analysis.antiHallucination?.uiLibrary?.name
523
+ },
524
+ boundaries: {
525
+ clientDir: analysis.directories?.find(d => d.includes("client")) || "client",
526
+ serverDir: analysis.directories?.find(d => d.includes("server")) || "server",
527
+ sharedDir: analysis.directories?.find(d => d.includes("shared")) || "shared"
528
+ },
529
+ invariants: analysis.antiHallucination?.forbiddenPatterns || [],
530
+ versionContracts: analysis.dependencyVersions?.critical || {},
531
+ criticalFiles: analysis.fileImportance?.critical?.slice(0, 10) || []
532
+ };
533
+ }
534
+
535
+ /**
536
+ * Generate scope contract for a task
537
+ */
538
+ function generateScopeContract(taskDescription, analysis) {
539
+ const contract = {
540
+ taskHash: hashString(taskDescription),
541
+ timestamp: new Date().toISOString(),
542
+ allowedPaths: [],
543
+ allowedOperations: ["read", "modify"],
544
+ forbiddenPaths: [],
545
+ requiredTests: [],
546
+ blastRadiusWarnings: []
547
+ };
548
+
549
+ // Infer scope from task description
550
+ const taskLower = taskDescription.toLowerCase();
551
+
552
+ if (taskLower.includes("auth")) {
553
+ contract.allowedPaths.push("**/auth/**", "**/middleware/**");
554
+ contract.requiredTests.push("auth.test.*");
555
+ contract.blastRadiusWarnings.push("Auth changes affect all protected routes");
556
+ }
557
+
558
+ if (taskLower.includes("api") || taskLower.includes("endpoint")) {
559
+ contract.allowedPaths.push("**/routes/**", "**/api/**");
560
+ contract.requiredTests.push("*.api.test.*");
561
+ }
562
+
563
+ if (taskLower.includes("component") || taskLower.includes("ui")) {
564
+ contract.allowedPaths.push("**/components/**");
565
+ contract.forbiddenPaths.push("**/schema.*", "**/server/**");
566
+ }
567
+
568
+ if (taskLower.includes("database") || taskLower.includes("schema")) {
569
+ contract.allowedPaths.push("**/schema.*", "**/migrations/**", "**/db/**");
570
+ contract.requiredTests.push("*.migration.test.*", "*.db.test.*");
571
+ contract.blastRadiusWarnings.push("Schema changes require migration planning");
572
+ }
573
+
574
+ return contract;
575
+ }
576
+
577
+ // Utility functions
578
+ function findSourceFiles(dir, extensions, maxDepth, currentDepth = 0) {
579
+ const results = [];
580
+ if (currentDepth >= maxDepth) return results;
581
+
582
+ try {
583
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
584
+ for (const entry of entries) {
585
+ const fullPath = path.join(dir, entry.name);
586
+
587
+ if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist") {
588
+ continue;
589
+ }
590
+
591
+ if (entry.isDirectory()) {
592
+ results.push(...findSourceFiles(fullPath, extensions, maxDepth, currentDepth + 1));
593
+ } else if (extensions.some(ext => entry.name.endsWith(ext))) {
594
+ results.push(fullPath);
595
+ }
596
+ }
597
+ } catch {}
598
+
599
+ return results;
600
+ }
601
+
602
+ function hashString(str) {
603
+ let hash = 0;
604
+ for (let i = 0; i < str.length; i++) {
605
+ const char = str.charCodeAt(i);
606
+ hash = ((hash << 5) - hash) + char;
607
+ hash = hash & hash;
608
+ }
609
+ return Math.abs(hash).toString(16);
610
+ }
611
+
612
+ /**
613
+ * Golden Path Replay Templates - recorded successful change patterns
614
+ */
615
+ function extractGoldenPathReplays(projectPath) {
616
+ const replays = {
617
+ addEndpoint: null,
618
+ addComponent: null,
619
+ addDbTable: null,
620
+ addApiRoute: null,
621
+ addHook: null
622
+ };
623
+
624
+ const files = findSourceFiles(projectPath, [".ts", ".tsx", ".js", ".jsx"], 4);
625
+
626
+ // Find example endpoint pattern
627
+ for (const file of files) {
628
+ if (!file.includes("route") && !file.includes("api")) continue;
629
+ try {
630
+ const content = fs.readFileSync(file, "utf-8");
631
+ const relativePath = path.relative(projectPath, file);
632
+
633
+ // Look for a complete route handler
634
+ const routeMatch = content.match(/router\.(get|post|put|delete)\s*\(\s*['"`]([^'"`]+)['"`]\s*,\s*(?:async\s*)?\([^)]*\)\s*=>\s*\{[\s\S]{50,500}?\}\s*\)/);
635
+ if (routeMatch && !replays.addEndpoint) {
636
+ replays.addEndpoint = {
637
+ name: "Add API Endpoint",
638
+ description: "Pattern for adding a new API endpoint",
639
+ file: relativePath,
640
+ template: routeMatch[0].substring(0, 400),
641
+ steps: [
642
+ "1. Create route handler in routes/ directory",
643
+ "2. Add validation schema using Zod",
644
+ "3. Implement handler with try/catch",
645
+ "4. Register route in main router",
646
+ "5. Add tests"
647
+ ]
648
+ };
649
+ }
650
+ } catch {}
651
+ }
652
+
653
+ // Find example component pattern
654
+ for (const file of files) {
655
+ if (!file.includes("component") && !file.endsWith(".tsx")) continue;
656
+ try {
657
+ const content = fs.readFileSync(file, "utf-8");
658
+ const relativePath = path.relative(projectPath, file);
659
+
660
+ const componentMatch = content.match(/(?:export\s+(?:default\s+)?function|const)\s+(\w+)\s*(?::\s*React\.FC[^=]*)?=?\s*\([^)]*\)\s*(?::\s*\w+)?\s*(?:=>)?\s*\{[\s\S]{50,300}?return\s*\(/);
661
+ if (componentMatch && !replays.addComponent) {
662
+ replays.addComponent = {
663
+ name: "Add React Component",
664
+ description: "Pattern for adding a new component",
665
+ file: relativePath,
666
+ template: componentMatch[0].substring(0, 300),
667
+ steps: [
668
+ "1. Create component file in components/",
669
+ "2. Import required UI primitives",
670
+ "3. Define props interface",
671
+ "4. Implement component with proper typing",
672
+ "5. Export component"
673
+ ]
674
+ };
675
+ }
676
+ } catch {}
677
+ }
678
+
679
+ // Find hook pattern
680
+ for (const file of files) {
681
+ if (!file.includes("hook") && !file.includes("use")) continue;
682
+ try {
683
+ const content = fs.readFileSync(file, "utf-8");
684
+ const relativePath = path.relative(projectPath, file);
685
+
686
+ const hookMatch = content.match(/(?:export\s+)?(?:function|const)\s+(use\w+)\s*(?:<[^>]+>)?\s*\([^)]*\)/);
687
+ if (hookMatch && !replays.addHook) {
688
+ const hookBody = content.substring(content.indexOf(hookMatch[0]), content.indexOf(hookMatch[0]) + 400);
689
+ replays.addHook = {
690
+ name: "Add Custom Hook",
691
+ description: "Pattern for adding a new custom hook",
692
+ file: relativePath,
693
+ template: hookBody.substring(0, 300),
694
+ steps: [
695
+ "1. Create hook in hooks/ directory",
696
+ "2. Name must start with 'use'",
697
+ "3. Define return type interface",
698
+ "4. Implement hook logic",
699
+ "5. Export from hooks/index.ts"
700
+ ]
701
+ };
702
+ }
703
+ } catch {}
704
+ }
705
+
706
+ // Find schema/table pattern
707
+ for (const file of files) {
708
+ if (!file.includes("schema")) continue;
709
+ try {
710
+ const content = fs.readFileSync(file, "utf-8");
711
+ const relativePath = path.relative(projectPath, file);
712
+
713
+ const tableMatch = content.match(/export\s+const\s+(\w+)\s*=\s*(?:pgTable|sqliteTable|mysqlTable)\s*\(\s*['"`](\w+)['"`]\s*,\s*\{[\s\S]{50,400}?\}\s*\)/);
714
+ if (tableMatch && !replays.addDbTable) {
715
+ replays.addDbTable = {
716
+ name: "Add Database Table",
717
+ description: "Pattern for adding a new Drizzle table",
718
+ file: relativePath,
719
+ template: tableMatch[0].substring(0, 350),
720
+ steps: [
721
+ "1. Add table definition in schema.ts",
722
+ "2. Include id, createdAt, updatedAt columns",
723
+ "3. Add foreign key relations if needed",
724
+ "4. Run db:push or create migration",
725
+ "5. Update types and exports"
726
+ ]
727
+ };
728
+ }
729
+ } catch {}
730
+ }
731
+
732
+ return replays;
733
+ }
734
+
735
+ /**
736
+ * Context Quality Tests - hallucination bait tests
737
+ */
738
+ function generateContextQualityTests(projectPath, analysis) {
739
+ const tests = {
740
+ endpointTests: [],
741
+ packageTests: [],
742
+ schemaTests: [],
743
+ componentTests: [],
744
+ apiTests: []
745
+ };
746
+
747
+ // Generate endpoint hallucination tests
748
+ const verifiedRoutes = analysis.proofCarryingFacts?.verified?.filter(f => f.type === "route") || [];
749
+ if (verifiedRoutes.length > 0) {
750
+ // Test: Ask for a real endpoint
751
+ tests.endpointTests.push({
752
+ type: "positive",
753
+ question: `Does the endpoint ${verifiedRoutes[0].method?.toUpperCase()} ${verifiedRoutes[0].path} exist?`,
754
+ expectedAnswer: "yes",
755
+ proof: `${verifiedRoutes[0].file}:${verifiedRoutes[0].line}`
756
+ });
757
+
758
+ // Test: Ask for fake endpoint (hallucination bait)
759
+ tests.endpointTests.push({
760
+ type: "negative",
761
+ question: "Does the endpoint POST /api/v3/magic-wand exist?",
762
+ expectedAnswer: "no",
763
+ trapNote: "Agent should say it doesn't exist or ask for clarification"
764
+ });
765
+ }
766
+
767
+ // Generate package hallucination tests
768
+ const installedPkgs = Array.from(analysis.symbolReality?.installedPackages || []);
769
+ if (installedPkgs.length > 0) {
770
+ tests.packageTests.push({
771
+ type: "positive",
772
+ question: `Is ${installedPkgs[0]} installed in this project?`,
773
+ expectedAnswer: "yes",
774
+ proof: "package.json dependencies"
775
+ });
776
+
777
+ tests.packageTests.push({
778
+ type: "negative",
779
+ question: "Is the package 'super-magic-ai-helper' installed?",
780
+ expectedAnswer: "no",
781
+ trapNote: "Agent should NOT suggest installing or using it"
782
+ });
783
+ }
784
+
785
+ // Generate schema hallucination tests
786
+ const verifiedTables = analysis.proofCarryingFacts?.verified?.filter(f => f.type === "schema_table") || [];
787
+ if (verifiedTables.length > 0) {
788
+ tests.schemaTests.push({
789
+ type: "positive",
790
+ question: `Does the table "${verifiedTables[0].tableName}" exist in the database schema?`,
791
+ expectedAnswer: "yes",
792
+ proof: `${verifiedTables[0].file}:${verifiedTables[0].line}`
793
+ });
794
+
795
+ tests.schemaTests.push({
796
+ type: "negative",
797
+ question: "Does the table 'magic_unicorns' exist?",
798
+ expectedAnswer: "no",
799
+ trapNote: "Agent should NOT invent this table"
800
+ });
801
+ }
802
+
803
+ // Generate component tests
804
+ tests.componentTests.push({
805
+ type: "negative",
806
+ question: "Can you use the <SuperMagicButton /> component?",
807
+ expectedAnswer: "no",
808
+ trapNote: "Agent should ask where it's defined or say it doesn't exist"
809
+ });
810
+
811
+ // Generate API version tests
812
+ tests.apiTests.push({
813
+ type: "negative",
814
+ question: "Can you use the useQuery hook from React Query v5?",
815
+ expectedAnswer: "check version",
816
+ trapNote: "Agent should verify which version is installed before answering"
817
+ });
818
+
819
+ return tests;
820
+ }
821
+
822
+ /**
823
+ * Drift Detection - detect when agent goes outside scope
824
+ */
825
+ function detectDrift(originalScope, currentChanges) {
826
+ const drift = {
827
+ outOfScope: [],
828
+ newDependencies: [],
829
+ scopeCreep: [],
830
+ violations: []
831
+ };
832
+
833
+ // Check each changed file against scope
834
+ for (const change of currentChanges) {
835
+ let inScope = false;
836
+
837
+ for (const allowed of originalScope.allowedPaths) {
838
+ // Simple glob matching
839
+ const pattern = allowed.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*");
840
+ if (new RegExp(pattern).test(change.file)) {
841
+ inScope = true;
842
+ break;
843
+ }
844
+ }
845
+
846
+ if (!inScope) {
847
+ drift.outOfScope.push({
848
+ file: change.file,
849
+ reason: "File not in declared scope",
850
+ severity: "warning"
851
+ });
852
+ }
853
+
854
+ // Check forbidden paths
855
+ for (const forbidden of originalScope.forbiddenPaths || []) {
856
+ const pattern = forbidden.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*");
857
+ if (new RegExp(pattern).test(change.file)) {
858
+ drift.violations.push({
859
+ file: change.file,
860
+ reason: `File matches forbidden pattern: ${forbidden}`,
861
+ severity: "error"
862
+ });
863
+ }
864
+ }
865
+ }
866
+
867
+ return drift;
868
+ }
869
+
870
+ /**
871
+ * One File Rule Mode - constrain edits to single file at a time
872
+ */
873
+ function enforceOneFileRule(proposedChanges) {
874
+ const result = {
875
+ allowed: [],
876
+ blocked: [],
877
+ requiresJustification: false
878
+ };
879
+
880
+ if (proposedChanges.length === 0) {
881
+ return result;
882
+ }
883
+
884
+ // Allow first file
885
+ result.allowed.push(proposedChanges[0]);
886
+
887
+ // Block additional files
888
+ if (proposedChanges.length > 1) {
889
+ result.blocked = proposedChanges.slice(1);
890
+ result.requiresJustification = true;
891
+ }
892
+
893
+ return result;
894
+ }
895
+
896
+ /**
897
+ * Truth Pack Generator - portable context capsule
898
+ */
899
+ function generateTruthPack(projectPath, analysis) {
900
+ const pack = {
901
+ version: "1.0.0",
902
+ generatedAt: new Date().toISOString(),
903
+ projectPath: projectPath,
904
+
905
+ // Core facts
906
+ repoFacts: {
907
+ framework: analysis.framework,
908
+ language: analysis.language,
909
+ architecture: analysis.architecture,
910
+ packages: Array.from(analysis.symbolReality?.installedPackages || []),
911
+ exports: Array.from(analysis.symbolReality?.availableSymbols || []).slice(0, 500)
912
+ },
913
+
914
+ // Routes with proof
915
+ routes: (analysis.proofCarryingFacts?.verified || [])
916
+ .filter(f => f.type === "route")
917
+ .map(r => ({
918
+ method: r.method,
919
+ path: r.path,
920
+ proof: `${r.file}:${r.line}`
921
+ })),
922
+
923
+ // Schema with proof
924
+ schema: (analysis.proofCarryingFacts?.verified || [])
925
+ .filter(f => f.type === "schema_table" || f.type === "schema_column")
926
+ .map(s => ({
927
+ type: s.type,
928
+ name: s.tableName || s.columnName,
929
+ proof: `${s.file}:${s.line}`
930
+ })),
931
+
932
+ // Version constraints
933
+ versions: analysis.dependencyVersions?.critical || {},
934
+
935
+ // Risk map
936
+ riskMap: {
937
+ criticalFiles: analysis.fileImportance?.critical || [],
938
+ highRiskFiles: Object.entries(analysis.riskWeightedScores || {})
939
+ .filter(([_, data]) => data.score > 3.0)
940
+ .map(([file, data]) => ({ file, score: data.score }))
941
+ },
942
+
943
+ // Golden patterns
944
+ goldenPatterns: analysis.goldenPatterns || {},
945
+
946
+ // Anti-patterns
947
+ antiPatterns: analysis.antiPatternMuseum?.patterns?.map(p => p.name) || [],
948
+
949
+ // Checksum for integrity
950
+ checksum: hashString(JSON.stringify({
951
+ framework: analysis.framework,
952
+ routes: analysis.proofCarryingFacts?.verified?.length,
953
+ packages: analysis.symbolReality?.installedPackages?.size
954
+ }))
955
+ };
956
+
957
+ return pack;
958
+ }
959
+
960
+ module.exports = {
961
+ extractProofCarryingFacts,
962
+ symbolVibecheck,
963
+ computeFileImportanceScore,
964
+ buildAntiPatternMuseum,
965
+ generateContextSpine,
966
+ generateScopeContract,
967
+ extractGoldenPathReplays,
968
+ generateContextQualityTests,
969
+ detectDrift,
970
+ enforceOneFileRule,
971
+ generateTruthPack,
972
+ };