@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,69 @@
1
+ // bin/runners/lib/missions/plan.js
2
+ function scoreFinding(f) {
3
+ if (f.severity === "BLOCK") return 100;
4
+ if (f.severity === "WARN") return 50;
5
+ return 0;
6
+ }
7
+
8
+ function missionFromFinding(f) {
9
+ const typeByCategory = {
10
+ Security: "REMOVE_OWNER_MODE",
11
+ Billing: "FIX_STRIPE_WEBHOOKS",
12
+ Entitlements: "ENFORCE_PAID_SURFACE",
13
+ GhostAuth: "ADD_SERVER_AUTH",
14
+ MissingRoute: "FIX_MISSING_ROUTE",
15
+ EnvContract: "FIX_ENV_CONTRACT",
16
+ FakeSuccess: "FIX_FAKE_SUCCESS",
17
+ DeadUI: "FIX_DEAD_UI",
18
+ AuthCoverage: "ADD_SERVER_AUTH"
19
+ };
20
+
21
+ return {
22
+ id: `M_${f.id}`,
23
+ type: typeByCategory[f.category] || "GENERIC_FIX",
24
+ title: f.title,
25
+ severity: f.severity,
26
+ category: f.category,
27
+ successCriteria: [
28
+ `Finding ${f.id} no longer appears in ship results`
29
+ ],
30
+ targetFindingIds: [f.id]
31
+ };
32
+ }
33
+
34
+ function planMissions(findings, { maxMissions = 12, blocksOnlyFirst = true } = {}) {
35
+ const sorted = [...findings].sort((a,b) => scoreFinding(b) - scoreFinding(a));
36
+
37
+ // Cost control: if there are BLOCKs, only plan for BLOCKs first
38
+ const hasBlocks = sorted.some(f => f.severity === "BLOCK");
39
+ const scoped = (blocksOnlyFirst && hasBlocks)
40
+ ? sorted.filter(f => f.severity === "BLOCK")
41
+ : sorted;
42
+
43
+ const seen = new Set();
44
+ const filtered = [];
45
+ for (const f of scoped) {
46
+ const k = `${f.category}:${f.title}`;
47
+ if (f.severity === "WARN" && seen.has(k)) continue;
48
+ seen.add(k);
49
+ filtered.push(f);
50
+ }
51
+
52
+ const missions = filtered.slice(0, maxMissions).map(missionFromFinding);
53
+
54
+ const priority = {
55
+ REMOVE_OWNER_MODE: 1,
56
+ FIX_STRIPE_WEBHOOKS: 2,
57
+ ENFORCE_PAID_SURFACE: 3,
58
+ ADD_SERVER_AUTH: 4,
59
+ FIX_MISSING_ROUTE: 5,
60
+ FIX_FAKE_SUCCESS: 6,
61
+ FIX_ENV_CONTRACT: 7,
62
+ GENERIC_FIX: 99
63
+ };
64
+
65
+ missions.sort((a,b) => (priority[a.type] || 50) - (priority[b.type] || 50));
66
+ return missions;
67
+ }
68
+
69
+ module.exports = { planMissions };
@@ -0,0 +1,147 @@
1
+ // bin/runners/lib/missions/templates.js
2
+ function templateForMissionType(type) {
3
+ switch (type) {
4
+ case "REMOVE_OWNER_MODE":
5
+ return {
6
+ intent: "Remove any env-based entitlement bypass. Ship must not allow secretless unlocks.",
7
+ do: [
8
+ "Delete OWNER_MODE logic or gate it with signed admin token AND non-production check.",
9
+ "Ensure entitlement checks require real verification (API key / token / server-side).",
10
+ "Add/adjust tests if present (at minimum remove bypass path)."
11
+ ],
12
+ dont: [
13
+ "Do not replace with another env var.",
14
+ "Do not add 'temporary' backdoor."
15
+ ],
16
+ success: [
17
+ "Owner mode bypass finding disappears from ship results."
18
+ ]
19
+ };
20
+
21
+ case "FIX_STRIPE_WEBHOOKS":
22
+ return {
23
+ intent: "Make Stripe webhooks real: signature verified + raw body + idempotent event handling.",
24
+ do: [
25
+ "Use stripe.webhooks.constructEvent(rawBody, sigHeader, secret).",
26
+ "Ensure raw body is used (Next pages: bodyParser false; Next app: req.text()/arrayBuffer()).",
27
+ "Persist processed event.id and short-circuit on replays."
28
+ ],
29
+ dont: [
30
+ "Do not trust parsed JSON body for signature verification.",
31
+ "Do not mutate billing state without dedupe."
32
+ ],
33
+ success: [
34
+ "Webhook verification + idempotency findings disappear."
35
+ ]
36
+ };
37
+
38
+ case "ENFORCE_PAID_SURFACE":
39
+ return {
40
+ intent: "Move paid gating to the server handler BEFORE doing work.",
41
+ do: [
42
+ "Add enforceFeature/enforceLimit (or equivalent) at top of handler.",
43
+ "Return a structured 402/403 error code used by CLI/UI to upsell.",
44
+ "Keep logic minimal; don't refactor unrelated code."
45
+ ],
46
+ dont: [
47
+ "Do not rely on client/CLI-only gating.",
48
+ "Do not introduce new plans/tiers in this step."
49
+ ],
50
+ success: [
51
+ "Paid surface missing enforcement finding disappears."
52
+ ]
53
+ };
54
+
55
+ case "ADD_SERVER_AUTH":
56
+ return {
57
+ intent: "Ensure sensitive endpoints have real server-side auth enforcement.",
58
+ do: [
59
+ "Add session/JWT verification in handler or route hook.",
60
+ "If using Next middleware, ensure matcher covers the sensitive paths (but do not over-widen blindly).",
61
+ "Return 401/403 on missing/invalid auth."
62
+ ],
63
+ dont: [
64
+ "Do not only hide UI routes.",
65
+ "Do not add fake auth helpers without evidence."
66
+ ],
67
+ success: [
68
+ "GhostAuth findings disappear."
69
+ ]
70
+ };
71
+
72
+ case "FIX_MISSING_ROUTE":
73
+ return {
74
+ intent: "Make the referenced route real OR stop referencing it.",
75
+ do: [
76
+ "If the UI calls /api/x, ensure server route exists and matches method/path.",
77
+ "If the route should not exist, remove the client reference safely.",
78
+ "Prefer minimal handler that returns correct status and shape if needed."
79
+ ],
80
+ dont: [
81
+ "Do not invent new API surface unless required by evidence.",
82
+ "Do not add broad wildcard routes."
83
+ ],
84
+ success: [
85
+ "MissingRoute findings disappear."
86
+ ]
87
+ };
88
+
89
+ case "FIX_FAKE_SUCCESS":
90
+ return {
91
+ intent: "Remove success UI lies: success must be gated on awaited + verified network result.",
92
+ do: [
93
+ "Await the network call.",
94
+ "Gate toast.success / navigation behind res.ok/status checks.",
95
+ "Surface error toast on failure."
96
+ ],
97
+ dont: [
98
+ "Do not just delete success feedback.",
99
+ "Do not swallow errors silently."
100
+ ],
101
+ success: [
102
+ "FakeSuccess findings disappear."
103
+ ]
104
+ };
105
+
106
+ case "FIX_ENV_CONTRACT":
107
+ return {
108
+ intent: "Make env reality explicit: used env vars must be declared in .env.example/.env.template.",
109
+ do: [
110
+ "Add missing used vars to env template with safe defaults or comments.",
111
+ "If truly optional, ensure code has explicit fallback and document it."
112
+ ],
113
+ dont: [
114
+ "Do not introduce new env var usage unrelated to the finding."
115
+ ],
116
+ success: [
117
+ "EnvContract findings disappear."
118
+ ]
119
+ };
120
+
121
+ case "FIX_DEAD_UI":
122
+ return {
123
+ intent: "Make UI actions real: clicks must trigger real handler + real success criteria.",
124
+ do: [
125
+ "If click calls /api/*: ensure route exists server-side and returns success only on real ok.",
126
+ "If click should navigate: ensure href/router push is correct and target route exists.",
127
+ "If click should open modal: ensure state toggles and modal renders.",
128
+ "If action is disabled: remove click affordance or add aria-disabled + disabled styling consistently."
129
+ ],
130
+ dont: [
131
+ "Do not silence by removing UI without replacing the feature.",
132
+ "Do not show success toast before awaiting and verifying."
133
+ ],
134
+ success: ["Dead UI findings disappear from ship (after running reality again)."]
135
+ };
136
+
137
+ default:
138
+ return {
139
+ intent: "Fix the specific finding with smallest correct patch.",
140
+ do: ["Keep it minimal, evidence-based, and verifiable."],
141
+ dont: ["Do not refactor unrelated code."],
142
+ success: ["Target finding disappears."]
143
+ };
144
+ }
145
+ }
146
+
147
+ module.exports = { templateForMissionType };
@@ -0,0 +1,40 @@
1
+ // bin/runners/lib/patch.js
2
+ const fs = require("fs");
3
+ const path = require("path");
4
+ const { spawnSync } = require("child_process");
5
+
6
+ function ensureDir(p) {
7
+ fs.mkdirSync(p, { recursive: true });
8
+ }
9
+
10
+ function writeTempPatch(repoRoot, diffText) {
11
+ const dir = path.join(repoRoot, ".vibecheck", "tmp");
12
+ ensureDir(dir);
13
+ const p = path.join(dir, `patch_${Date.now()}.diff`);
14
+ fs.writeFileSync(p, diffText, "utf8");
15
+ return p;
16
+ }
17
+
18
+ function applyPatchWithGit(repoRoot, patchPath) {
19
+ const r = spawnSync("git", ["apply", "--reject", "--whitespace=fix", patchPath], {
20
+ cwd: repoRoot,
21
+ stdio: "pipe",
22
+ encoding: "utf8"
23
+ });
24
+
25
+ return { ok: r.status === 0, stdout: r.stdout, stderr: r.stderr, code: r.status };
26
+ }
27
+
28
+ function applyUnifiedDiff(repoRoot, diffText) {
29
+ const patchPath = writeTempPatch(repoRoot, diffText);
30
+
31
+ const check = spawnSync("git", ["--version"], { stdio: "ignore" });
32
+ if (check.status !== 0) {
33
+ return { ok: false, error: "git not found; cannot apply unified diff safely" };
34
+ }
35
+
36
+ const res = applyPatchWithGit(repoRoot, patchPath);
37
+ return res.ok ? { ok: true } : { ok: false, error: res.stderr || "git apply failed", details: res };
38
+ }
39
+
40
+ module.exports = { applyUnifiedDiff };
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Auth Model Extractor
3
+ * Extracts authorization model from code and contracts
4
+ */
5
+
6
+ "use strict";
7
+
8
+ const fs = require("fs");
9
+ const path = require("path");
10
+ const fg = require("fast-glob");
11
+ const parser = require("@babel/parser");
12
+ const traverse = require("@babel/traverse").default;
13
+ const t = require("@babel/types");
14
+
15
+ /**
16
+ * Extract auth model from codebase
17
+ */
18
+ async function extractAuthModel(repoRoot, truthpack) {
19
+ const model = {
20
+ version: "1.0.0",
21
+ generatedAt: new Date().toISOString(),
22
+ roles: [],
23
+ routes: [],
24
+ rbacPatterns: [],
25
+ evidence: []
26
+ };
27
+
28
+ // Extract from truthpack
29
+ if (truthpack?.auth) {
30
+ model.protectedPatterns = truthpack.auth.nextMatcherPatterns || [];
31
+
32
+ // Add middleware evidence
33
+ for (const mw of truthpack.auth.nextMiddleware || []) {
34
+ model.evidence.push({
35
+ type: "next_middleware",
36
+ file: mw.file,
37
+ signals: mw.signalTypes || []
38
+ });
39
+ }
40
+ }
41
+
42
+ // Extract role patterns from code
43
+ const rolePatterns = await extractRolePatterns(repoRoot);
44
+ model.rbacPatterns = rolePatterns;
45
+
46
+ // Infer roles from patterns
47
+ model.roles = inferRoles(rolePatterns, truthpack);
48
+
49
+ // Build route auth map
50
+ model.routes = buildRouteAuthMap(truthpack, model.roles);
51
+
52
+ return model;
53
+ }
54
+
55
+ /**
56
+ * Extract RBAC patterns from code
57
+ */
58
+ async function extractRolePatterns(repoRoot) {
59
+ const patterns = [];
60
+
61
+ const files = await fg(["**/*.{ts,tsx,js,jsx}"], {
62
+ cwd: repoRoot,
63
+ absolute: true,
64
+ ignore: ["**/node_modules/**", "**/.next/**", "**/dist/**", "**/build/**"]
65
+ });
66
+
67
+ for (const fileAbs of files) {
68
+ const fileRel = path.relative(repoRoot, fileAbs).replace(/\\/g, "/");
69
+ const code = fs.readFileSync(fileAbs, "utf8");
70
+
71
+ // Look for role-related patterns
72
+ const roleMatches = [
73
+ // role === 'admin'
74
+ /role\s*===?\s*['"](\w+)['"]/gi,
75
+ // isAdmin, isUser
76
+ /\b(is(?:Admin|User|Manager|Owner|Moderator))\b/gi,
77
+ // hasRole('admin')
78
+ /hasRole\s*\(\s*['"](\w+)['"]\s*\)/gi,
79
+ // checkPermission('edit')
80
+ /check(?:Permission|Auth)\s*\(\s*['"](\w+)['"]\s*\)/gi,
81
+ // [role: 'admin']
82
+ /role:\s*['"](\w+)['"]/gi
83
+ ];
84
+
85
+ for (const pattern of roleMatches) {
86
+ let match;
87
+ while ((match = pattern.exec(code)) !== null) {
88
+ patterns.push({
89
+ type: "role_check",
90
+ file: fileRel,
91
+ role: match[1],
92
+ line: code.substring(0, match.index).split("\n").length
93
+ });
94
+ }
95
+ }
96
+ }
97
+
98
+ return patterns;
99
+ }
100
+
101
+ /**
102
+ * Infer roles from patterns
103
+ */
104
+ function inferRoles(patterns, truthpack) {
105
+ const roleNames = new Set();
106
+
107
+ // Common roles
108
+ roleNames.add("user");
109
+ roleNames.add("admin");
110
+
111
+ // From patterns
112
+ for (const p of patterns) {
113
+ if (p.role) {
114
+ roleNames.add(p.role.toLowerCase());
115
+ }
116
+ // Extract from isAdmin -> admin
117
+ if (p.role?.startsWith("is")) {
118
+ roleNames.add(p.role.substring(2).toLowerCase());
119
+ }
120
+ }
121
+
122
+ // Build role objects
123
+ const roles = [];
124
+ for (const name of roleNames) {
125
+ const role = {
126
+ name,
127
+ routes: [],
128
+ evidence: patterns.filter(p =>
129
+ p.role?.toLowerCase() === name ||
130
+ p.role?.toLowerCase() === `is${name}`
131
+ )
132
+ };
133
+ roles.push(role);
134
+ }
135
+
136
+ return roles;
137
+ }
138
+
139
+ /**
140
+ * Build route auth map
141
+ */
142
+ function buildRouteAuthMap(truthpack, roles) {
143
+ const routes = [];
144
+ const serverRoutes = truthpack?.routes?.server || [];
145
+ const protectedPatterns = truthpack?.auth?.nextMatcherPatterns || [];
146
+
147
+ for (const route of serverRoutes) {
148
+ const isProtected = protectedPatterns.some(p => matchesPattern(route.path, p));
149
+
150
+ const routeAuth = {
151
+ path: route.path,
152
+ method: route.method,
153
+ handler: route.handler,
154
+ declared: {
155
+ protected: isProtected,
156
+ roles: inferRouteRoles(route, roles),
157
+ public: !isProtected && isPublicRoute(route.path)
158
+ },
159
+ actual: null // Filled by runtime verification
160
+ };
161
+
162
+ routes.push(routeAuth);
163
+ }
164
+
165
+ return routes;
166
+ }
167
+
168
+ /**
169
+ * Infer which roles can access a route
170
+ */
171
+ function inferRouteRoles(route, roles) {
172
+ const routeRoles = [];
173
+
174
+ // Admin routes
175
+ if (route.path.includes("/admin")) {
176
+ routeRoles.push("admin");
177
+ }
178
+
179
+ // User routes (most authenticated routes)
180
+ if (!route.path.includes("/admin") && !route.path.includes("/public")) {
181
+ routeRoles.push("user");
182
+ }
183
+
184
+ return routeRoles;
185
+ }
186
+
187
+ function isPublicRoute(path) {
188
+ const publicPatterns = [
189
+ /^\/api\/health/i,
190
+ /^\/api\/status/i,
191
+ /^\/api\/public\//i,
192
+ /^\/_next\//i,
193
+ /^\/favicon/i
194
+ ];
195
+ return publicPatterns.some(p => p.test(path));
196
+ }
197
+
198
+ function matchesPattern(path, pattern) {
199
+ const normPattern = pattern.replace(/\*/g, ".*").replace(/\//g, "\\/");
200
+ try {
201
+ const rx = new RegExp(`^${normPattern}`, "i");
202
+ return rx.test(path);
203
+ } catch {
204
+ return false;
205
+ }
206
+ }
207
+
208
+ module.exports = {
209
+ extractAuthModel,
210
+ extractRolePatterns,
211
+ inferRoles,
212
+ buildRouteAuthMap
213
+ };
@@ -0,0 +1,205 @@
1
+ /**
2
+ * IDOR Prover
3
+ * Detects Insecure Direct Object Reference vulnerabilities
4
+ * Tests if User A can access User B's resources
5
+ */
6
+
7
+ "use strict";
8
+
9
+ const crypto = require("crypto");
10
+
11
+ function sha256(text) {
12
+ return crypto.createHash("sha256").update(text).digest("hex").slice(0, 16);
13
+ }
14
+
15
+ /**
16
+ * Detect potential IDOR routes from auth model
17
+ */
18
+ function detectIDORCandidates(authModel) {
19
+ const candidates = [];
20
+
21
+ for (const route of authModel.routes) {
22
+ // Look for patterns like /users/:id, /invoices/:id, /orders/:id
23
+ const idorPatterns = [
24
+ /\/users\/:[^/]+/i,
25
+ /\/accounts\/:[^/]+/i,
26
+ /\/profiles\/:[^/]+/i,
27
+ /\/invoices\/:[^/]+/i,
28
+ /\/orders\/:[^/]+/i,
29
+ /\/documents\/:[^/]+/i,
30
+ /\/files\/:[^/]+/i,
31
+ /\/projects\/:[^/]+/i,
32
+ /\/teams\/:[^/]+/i,
33
+ /\/organizations\/:[^/]+/i
34
+ ];
35
+
36
+ for (const pattern of idorPatterns) {
37
+ if (pattern.test(route.path)) {
38
+ candidates.push({
39
+ path: route.path,
40
+ method: route.method,
41
+ handler: route.handler,
42
+ paramName: extractParamName(route.path),
43
+ resourceType: extractResourceType(route.path)
44
+ });
45
+ break;
46
+ }
47
+ }
48
+ }
49
+
50
+ return candidates;
51
+ }
52
+
53
+ function extractParamName(path) {
54
+ const match = path.match(/:([^/]+)/);
55
+ return match ? match[1] : "id";
56
+ }
57
+
58
+ function extractResourceType(path) {
59
+ const parts = path.split("/").filter(Boolean);
60
+ for (let i = 0; i < parts.length; i++) {
61
+ if (parts[i].startsWith(":") && i > 0) {
62
+ return parts[i - 1];
63
+ }
64
+ }
65
+ return "resource";
66
+ }
67
+
68
+ /**
69
+ * Build IDOR test plan
70
+ */
71
+ function buildIDORTestPlan(candidates, options = {}) {
72
+ const plan = {
73
+ version: "1.0.0",
74
+ generatedAt: new Date().toISOString(),
75
+ tests: [],
76
+ safeMode: options.safe !== false
77
+ };
78
+
79
+ for (const candidate of candidates) {
80
+ const test = {
81
+ id: `idor_${sha256(candidate.path)}`,
82
+ route: candidate.path,
83
+ method: candidate.method,
84
+ resourceType: candidate.resourceType,
85
+ paramName: candidate.paramName,
86
+ steps: [
87
+ {
88
+ description: `Login as User A`,
89
+ action: "auth",
90
+ role: "user_a"
91
+ },
92
+ {
93
+ description: `Access own resource: ${candidate.path.replace(`:${candidate.paramName}`, 'USER_A_ID')}`,
94
+ action: "request",
95
+ path: candidate.path,
96
+ param: "USER_A_ID",
97
+ expectStatus: [200, 201]
98
+ },
99
+ {
100
+ description: `Attempt to access User B's resource: ${candidate.path.replace(`:${candidate.paramName}`, 'USER_B_ID')}`,
101
+ action: "request",
102
+ path: candidate.path,
103
+ param: "USER_B_ID",
104
+ expectStatus: [403, 404]
105
+ }
106
+ ],
107
+ violation: {
108
+ condition: "step[2].status === 200",
109
+ severity: "BLOCK",
110
+ type: "idor",
111
+ message: `User A can access User B's ${candidate.resourceType}`
112
+ }
113
+ };
114
+
115
+ plan.tests.push(test);
116
+ }
117
+
118
+ return plan;
119
+ }
120
+
121
+ /**
122
+ * Execute IDOR test (requires browser context)
123
+ */
124
+ async function executeIDORTest(page, test, users) {
125
+ const result = {
126
+ testId: test.id,
127
+ route: test.route,
128
+ passed: true,
129
+ steps: [],
130
+ violation: null
131
+ };
132
+
133
+ // This is a placeholder - actual implementation requires:
134
+ // 1. Two test user accounts
135
+ // 2. Known resource IDs for each user
136
+ // 3. Ability to switch between sessions
137
+
138
+ if (!users?.userA || !users?.userB) {
139
+ result.skipped = true;
140
+ result.reason = "IDOR tests require two configured test users";
141
+ return result;
142
+ }
143
+
144
+ // Step 1: Login as User A
145
+ // Step 2: Access own resource - should succeed
146
+ // Step 3: Access User B's resource - should fail
147
+
148
+ // For now, return a template result
149
+ result.steps = test.steps.map((step, i) => ({
150
+ ...step,
151
+ executed: false,
152
+ reason: "IDOR testing requires explicit --idor --safe flag and user configuration"
153
+ }));
154
+
155
+ return result;
156
+ }
157
+
158
+ /**
159
+ * Format IDOR test plan for display
160
+ */
161
+ function formatIDORPlan(plan) {
162
+ const lines = [];
163
+
164
+ lines.push("# IDOR Test Plan\n");
165
+ lines.push(`Generated: ${plan.generatedAt}`);
166
+ lines.push(`Safe Mode: ${plan.safeMode ? "Yes" : "No"}`);
167
+ lines.push(`Tests: ${plan.tests.length}\n`);
168
+
169
+ if (plan.tests.length === 0) {
170
+ lines.push("No IDOR candidates detected.\n");
171
+ return lines.join("\n");
172
+ }
173
+
174
+ lines.push("## Candidates\n");
175
+
176
+ for (const test of plan.tests) {
177
+ lines.push(`### ${test.resourceType}: ${test.route}`);
178
+ lines.push(`Method: ${test.method}`);
179
+ lines.push(`Parameter: ${test.paramName}\n`);
180
+
181
+ lines.push("**Test Steps:**");
182
+ for (const step of test.steps) {
183
+ lines.push(`1. ${step.description}`);
184
+ }
185
+
186
+ lines.push("\n**Violation Condition:**");
187
+ lines.push(`If ${test.violation.condition}: ${test.violation.message}\n`);
188
+ }
189
+
190
+ lines.push("---\n");
191
+ lines.push("⚠️ **Safety Notice**");
192
+ lines.push("IDOR tests modify data access patterns. Only run on:");
193
+ lines.push("- Local development environments");
194
+ lines.push("- Staging with explicit consent");
195
+ lines.push("- With dedicated test accounts\n");
196
+
197
+ return lines.join("\n");
198
+ }
199
+
200
+ module.exports = {
201
+ detectIDORCandidates,
202
+ buildIDORTestPlan,
203
+ executeIDORTest,
204
+ formatIDORPlan
205
+ };