vibecheck-ai 2.0.1 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (456) hide show
  1. package/bin/.generated +25 -0
  2. package/bin/_deprecations.js +463 -0
  3. package/bin/_router.js +46 -0
  4. package/bin/cli-hygiene.js +241 -0
  5. package/bin/dev/run-v2-torture.js +30 -0
  6. package/bin/registry.js +656 -0
  7. package/bin/runners/CLI_REFACTOR_SUMMARY.md +229 -0
  8. package/bin/runners/ENHANCEMENT_GUIDE.md +121 -0
  9. package/bin/runners/REPORT_AUDIT.md +64 -0
  10. package/bin/runners/cli-utils.js +1070 -0
  11. package/bin/runners/context/ai-task-decomposer.js +337 -0
  12. package/bin/runners/context/analyzer.js +513 -0
  13. package/bin/runners/context/api-contracts.js +427 -0
  14. package/bin/runners/context/context-diff.js +342 -0
  15. package/bin/runners/context/context-pruner.js +291 -0
  16. package/bin/runners/context/dependency-graph.js +414 -0
  17. package/bin/runners/context/generators/claude.js +107 -0
  18. package/bin/runners/context/generators/codex.js +108 -0
  19. package/bin/runners/context/generators/copilot.js +119 -0
  20. package/bin/runners/context/generators/cursor-enhanced.js +2525 -0
  21. package/bin/runners/context/generators/cursor.js +514 -0
  22. package/bin/runners/context/generators/mcp.js +169 -0
  23. package/bin/runners/context/generators/windsurf.js +180 -0
  24. package/bin/runners/context/git-context.js +304 -0
  25. package/bin/runners/context/index.js +1110 -0
  26. package/bin/runners/context/insights.js +173 -0
  27. package/bin/runners/context/mcp-server/generate-rules.js +337 -0
  28. package/bin/runners/context/mcp-server/index.js +1176 -0
  29. package/bin/runners/context/mcp-server/package.json +24 -0
  30. package/bin/runners/context/memory.js +200 -0
  31. package/bin/runners/context/monorepo.js +215 -0
  32. package/bin/runners/context/multi-repo-federation.js +404 -0
  33. package/bin/runners/context/patterns.js +253 -0
  34. package/bin/runners/context/proof-context.js +1264 -0
  35. package/bin/runners/context/security-scanner.js +541 -0
  36. package/bin/runners/context/semantic-search.js +350 -0
  37. package/bin/runners/context/shared.js +264 -0
  38. package/bin/runners/context/team-conventions.js +336 -0
  39. package/bin/runners/lib/__tests__/entitlements-v2.test.js +295 -0
  40. package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +474 -0
  41. package/bin/runners/lib/agent-firewall/change-packet/builder.js +488 -0
  42. package/bin/runners/lib/agent-firewall/change-packet/schema.json +228 -0
  43. package/bin/runners/lib/agent-firewall/change-packet/store.js +200 -0
  44. package/bin/runners/lib/agent-firewall/claims/claim-types.js +21 -0
  45. package/bin/runners/lib/agent-firewall/claims/extractor.js +303 -0
  46. package/bin/runners/lib/agent-firewall/claims/patterns.js +24 -0
  47. package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
  48. package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
  49. package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
  50. package/bin/runners/lib/agent-firewall/enforcement/gateway.js +1059 -0
  51. package/bin/runners/lib/agent-firewall/enforcement/index.js +98 -0
  52. package/bin/runners/lib/agent-firewall/enforcement/mode.js +318 -0
  53. package/bin/runners/lib/agent-firewall/enforcement/orchestrator.js +484 -0
  54. package/bin/runners/lib/agent-firewall/enforcement/proof-artifact.js +418 -0
  55. package/bin/runners/lib/agent-firewall/enforcement/schemas/change-event.schema.json +173 -0
  56. package/bin/runners/lib/agent-firewall/enforcement/schemas/intent.schema.json +181 -0
  57. package/bin/runners/lib/agent-firewall/enforcement/schemas/verdict.schema.json +222 -0
  58. package/bin/runners/lib/agent-firewall/enforcement/verdict-v2.js +333 -0
  59. package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +88 -0
  60. package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +75 -0
  61. package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +127 -0
  62. package/bin/runners/lib/agent-firewall/evidence/resolver.js +102 -0
  63. package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +213 -0
  64. package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +145 -0
  65. package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +19 -0
  66. package/bin/runners/lib/agent-firewall/fs-hook/installer.js +87 -0
  67. package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +184 -0
  68. package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +163 -0
  69. package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +107 -0
  70. package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +68 -0
  71. package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +66 -0
  72. package/bin/runners/lib/agent-firewall/index.js +200 -0
  73. package/bin/runners/lib/agent-firewall/integration/index.js +20 -0
  74. package/bin/runners/lib/agent-firewall/integration/ship-gate.js +437 -0
  75. package/bin/runners/lib/agent-firewall/intent/alignment-engine.js +634 -0
  76. package/bin/runners/lib/agent-firewall/intent/auto-detect.js +426 -0
  77. package/bin/runners/lib/agent-firewall/intent/index.js +102 -0
  78. package/bin/runners/lib/agent-firewall/intent/schema.js +352 -0
  79. package/bin/runners/lib/agent-firewall/intent/store.js +283 -0
  80. package/bin/runners/lib/agent-firewall/interception/fs-interceptor.js +502 -0
  81. package/bin/runners/lib/agent-firewall/interception/index.js +23 -0
  82. package/bin/runners/lib/agent-firewall/interceptor/base.js +308 -0
  83. package/bin/runners/lib/agent-firewall/interceptor/cursor.js +35 -0
  84. package/bin/runners/lib/agent-firewall/interceptor/vscode.js +35 -0
  85. package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +34 -0
  86. package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
  87. package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
  88. package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
  89. package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
  90. package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
  91. package/bin/runners/lib/agent-firewall/logger.js +141 -0
  92. package/bin/runners/lib/agent-firewall/policy/default-policy.json +90 -0
  93. package/bin/runners/lib/agent-firewall/policy/engine.js +103 -0
  94. package/bin/runners/lib/agent-firewall/policy/loader.js +451 -0
  95. package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +50 -0
  96. package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +50 -0
  97. package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +79 -0
  98. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +227 -0
  99. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +191 -0
  100. package/bin/runners/lib/agent-firewall/policy/rules/scope.js +93 -0
  101. package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +57 -0
  102. package/bin/runners/lib/agent-firewall/policy/schema.json +183 -0
  103. package/bin/runners/lib/agent-firewall/policy/verdict.js +54 -0
  104. package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
  105. package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
  106. package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
  107. package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
  108. package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
  109. package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
  110. package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
  111. package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
  112. package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
  113. package/bin/runners/lib/agent-firewall/risk/thresholds.js +322 -0
  114. package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
  115. package/bin/runners/lib/agent-firewall/session/collector.js +451 -0
  116. package/bin/runners/lib/agent-firewall/session/index.js +26 -0
  117. package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
  118. package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
  119. package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
  120. package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
  121. package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
  122. package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
  123. package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
  124. package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
  125. package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
  126. package/bin/runners/lib/agent-firewall/truthpack/index.js +67 -0
  127. package/bin/runners/lib/agent-firewall/truthpack/loader.js +137 -0
  128. package/bin/runners/lib/agent-firewall/unblock/planner.js +337 -0
  129. package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +118 -0
  130. package/bin/runners/lib/ai-bridge.js +416 -0
  131. package/bin/runners/lib/analysis-core.js +309 -0
  132. package/bin/runners/lib/analyzers.js +2500 -0
  133. package/bin/runners/lib/api-client.js +269 -0
  134. package/bin/runners/lib/approve-output.js +235 -0
  135. package/bin/runners/lib/artifact-envelope.js +540 -0
  136. package/bin/runners/lib/assets/vibecheck-logo.png +0 -0
  137. package/bin/runners/lib/audit-bridge.js +391 -0
  138. package/bin/runners/lib/auth-shared.js +977 -0
  139. package/bin/runners/lib/auth-truth.js +193 -0
  140. package/bin/runners/lib/auth.js +215 -0
  141. package/bin/runners/lib/authority-badge.js +425 -0
  142. package/bin/runners/lib/backup.js +62 -0
  143. package/bin/runners/lib/billing.js +107 -0
  144. package/bin/runners/lib/checkpoint.js +941 -0
  145. package/bin/runners/lib/claims.js +118 -0
  146. package/bin/runners/lib/classify-output.js +204 -0
  147. package/bin/runners/lib/cleanup/engine.js +571 -0
  148. package/bin/runners/lib/cleanup/index.js +53 -0
  149. package/bin/runners/lib/cleanup/output.js +375 -0
  150. package/bin/runners/lib/cleanup/rules.js +1060 -0
  151. package/bin/runners/lib/cli-output.js +400 -0
  152. package/bin/runners/lib/cli-ui.js +540 -0
  153. package/bin/runners/lib/compliance-bridge-new.js +0 -0
  154. package/bin/runners/lib/compliance-bridge.js +165 -0
  155. package/bin/runners/lib/contracts/auth-contract.js +202 -0
  156. package/bin/runners/lib/contracts/env-contract.js +181 -0
  157. package/bin/runners/lib/contracts/external-contract.js +206 -0
  158. package/bin/runners/lib/contracts/guard.js +168 -0
  159. package/bin/runners/lib/contracts/index.js +89 -0
  160. package/bin/runners/lib/contracts/plan-validator.js +311 -0
  161. package/bin/runners/lib/contracts/route-contract.js +199 -0
  162. package/bin/runners/lib/contracts.js +804 -0
  163. package/bin/runners/lib/default-config.js +127 -0
  164. package/bin/runners/lib/detect.js +89 -0
  165. package/bin/runners/lib/detectors-v2.js +622 -0
  166. package/bin/runners/lib/doctor/autofix.js +254 -0
  167. package/bin/runners/lib/doctor/diagnosis-receipt.js +454 -0
  168. package/bin/runners/lib/doctor/failure-signatures.js +526 -0
  169. package/bin/runners/lib/doctor/fix-script.js +336 -0
  170. package/bin/runners/lib/doctor/index.js +37 -0
  171. package/bin/runners/lib/doctor/modules/build-tools.js +453 -0
  172. package/bin/runners/lib/doctor/modules/dependencies.js +325 -0
  173. package/bin/runners/lib/doctor/modules/index.js +105 -0
  174. package/bin/runners/lib/doctor/modules/network.js +250 -0
  175. package/bin/runners/lib/doctor/modules/os-quirks.js +706 -0
  176. package/bin/runners/lib/doctor/modules/project.js +312 -0
  177. package/bin/runners/lib/doctor/modules/repo-integrity.js +485 -0
  178. package/bin/runners/lib/doctor/modules/runtime.js +224 -0
  179. package/bin/runners/lib/doctor/modules/security.js +350 -0
  180. package/bin/runners/lib/doctor/modules/system.js +213 -0
  181. package/bin/runners/lib/doctor/modules/vibecheck.js +394 -0
  182. package/bin/runners/lib/doctor/reporter.js +262 -0
  183. package/bin/runners/lib/doctor/safe-repair.js +384 -0
  184. package/bin/runners/lib/doctor/service.js +262 -0
  185. package/bin/runners/lib/doctor/types.js +113 -0
  186. package/bin/runners/lib/doctor/ui.js +263 -0
  187. package/bin/runners/lib/doctor-enhanced.js +233 -0
  188. package/bin/runners/lib/doctor-output.js +226 -0
  189. package/bin/runners/lib/doctor-v2.js +608 -0
  190. package/bin/runners/lib/drift.js +425 -0
  191. package/bin/runners/lib/enforcement.js +72 -0
  192. package/bin/runners/lib/engine/ast-cache.js +210 -0
  193. package/bin/runners/lib/engine/auth-extractor.js +211 -0
  194. package/bin/runners/lib/engine/billing-extractor.js +112 -0
  195. package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
  196. package/bin/runners/lib/engine/env-extractor.js +207 -0
  197. package/bin/runners/lib/engine/express-extractor.js +208 -0
  198. package/bin/runners/lib/engine/extractors.js +849 -0
  199. package/bin/runners/lib/engine/index.js +207 -0
  200. package/bin/runners/lib/engine/repo-index.js +514 -0
  201. package/bin/runners/lib/engine/types.js +124 -0
  202. package/bin/runners/lib/engines/accessibility-engine.js +190 -0
  203. package/bin/runners/lib/engines/api-consistency-engine.js +162 -0
  204. package/bin/runners/lib/engines/ast-cache.js +99 -0
  205. package/bin/runners/lib/engines/attack-detector.js +1192 -0
  206. package/bin/runners/lib/engines/code-quality-engine.js +255 -0
  207. package/bin/runners/lib/engines/console-logs-engine.js +115 -0
  208. package/bin/runners/lib/engines/cross-file-analysis-engine.js +268 -0
  209. package/bin/runners/lib/engines/dead-code-engine.js +198 -0
  210. package/bin/runners/lib/engines/deprecated-api-engine.js +226 -0
  211. package/bin/runners/lib/engines/empty-catch-engine.js +150 -0
  212. package/bin/runners/lib/engines/file-filter.js +131 -0
  213. package/bin/runners/lib/engines/hardcoded-secrets-engine.js +251 -0
  214. package/bin/runners/lib/engines/mock-data-engine.js +272 -0
  215. package/bin/runners/lib/engines/parallel-processor.js +71 -0
  216. package/bin/runners/lib/engines/performance-issues-engine.js +265 -0
  217. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +243 -0
  218. package/bin/runners/lib/engines/todo-fixme-engine.js +115 -0
  219. package/bin/runners/lib/engines/type-aware-engine.js +152 -0
  220. package/bin/runners/lib/engines/unsafe-regex-engine.js +225 -0
  221. package/bin/runners/lib/engines/vibecheck-engines/README.md +53 -0
  222. package/bin/runners/lib/engines/vibecheck-engines/index.js +15 -0
  223. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
  224. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
  225. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
  226. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
  227. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
  228. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
  229. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
  230. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +139 -0
  231. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
  232. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
  233. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
  234. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
  235. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
  236. package/bin/runners/lib/engines/vibecheck-engines/package.json +13 -0
  237. package/bin/runners/lib/enterprise-detect.js +603 -0
  238. package/bin/runners/lib/enterprise-init.js +942 -0
  239. package/bin/runners/lib/entitlements-v2.js +265 -0
  240. package/bin/runners/lib/entitlements.generated.js +0 -0
  241. package/bin/runners/lib/entitlements.js +340 -0
  242. package/bin/runners/lib/env-resolver.js +417 -0
  243. package/bin/runners/lib/env-template.js +66 -0
  244. package/bin/runners/lib/env.js +189 -0
  245. package/bin/runners/lib/error-handler.js +368 -0
  246. package/bin/runners/lib/error-messages.js +289 -0
  247. package/bin/runners/lib/evidence-pack.js +684 -0
  248. package/bin/runners/lib/exit-codes.js +275 -0
  249. package/bin/runners/lib/extractors/client-calls.js +990 -0
  250. package/bin/runners/lib/extractors/fastify-route-dump.js +573 -0
  251. package/bin/runners/lib/extractors/fastify-routes.js +426 -0
  252. package/bin/runners/lib/extractors/index.js +363 -0
  253. package/bin/runners/lib/extractors/next-routes.js +524 -0
  254. package/bin/runners/lib/extractors/proof-graph.js +431 -0
  255. package/bin/runners/lib/extractors/route-matcher.js +451 -0
  256. package/bin/runners/lib/extractors/truthpack-v2.js +377 -0
  257. package/bin/runners/lib/extractors/ui-bindings.js +547 -0
  258. package/bin/runners/lib/finding-id.js +69 -0
  259. package/bin/runners/lib/finding-sorter.js +89 -0
  260. package/bin/runners/lib/findings-schema.js +281 -0
  261. package/bin/runners/lib/fingerprint.js +377 -0
  262. package/bin/runners/lib/firewall-prompt.js +50 -0
  263. package/bin/runners/lib/fix-output.js +228 -0
  264. package/bin/runners/lib/global-flags.js +250 -0
  265. package/bin/runners/lib/graph/graph-builder.js +265 -0
  266. package/bin/runners/lib/graph/html-renderer.js +413 -0
  267. package/bin/runners/lib/graph/index.js +32 -0
  268. package/bin/runners/lib/graph/runtime-collector.js +215 -0
  269. package/bin/runners/lib/graph/static-extractor.js +518 -0
  270. package/bin/runners/lib/help-formatter.js +413 -0
  271. package/bin/runners/lib/html-proof-report.js +913 -0
  272. package/bin/runners/lib/html-report.js +650 -0
  273. package/bin/runners/lib/init-wizard.js +601 -0
  274. package/bin/runners/lib/interactive-menu.js +1496 -0
  275. package/bin/runners/lib/json-output.js +76 -0
  276. package/bin/runners/lib/llm.js +75 -0
  277. package/bin/runners/lib/logger.js +38 -0
  278. package/bin/runners/lib/meter.js +61 -0
  279. package/bin/runners/lib/missions/briefing.js +427 -0
  280. package/bin/runners/lib/missions/checkpoint.js +753 -0
  281. package/bin/runners/lib/missions/evidence.js +126 -0
  282. package/bin/runners/lib/missions/hardening.js +851 -0
  283. package/bin/runners/lib/missions/plan.js +648 -0
  284. package/bin/runners/lib/missions/safety-gates.js +645 -0
  285. package/bin/runners/lib/missions/schema.js +478 -0
  286. package/bin/runners/lib/missions/templates.js +317 -0
  287. package/bin/runners/lib/next-action.js +560 -0
  288. package/bin/runners/lib/packs/bundle.js +675 -0
  289. package/bin/runners/lib/packs/evidence-pack.js +671 -0
  290. package/bin/runners/lib/packs/pack-factory.js +837 -0
  291. package/bin/runners/lib/packs/permissions-pack.js +686 -0
  292. package/bin/runners/lib/packs/proof-graph-pack.js +779 -0
  293. package/bin/runners/lib/patch.js +40 -0
  294. package/bin/runners/lib/permissions/auth-model.js +213 -0
  295. package/bin/runners/lib/permissions/idor-prover.js +205 -0
  296. package/bin/runners/lib/permissions/index.js +45 -0
  297. package/bin/runners/lib/permissions/matrix-builder.js +198 -0
  298. package/bin/runners/lib/pkgjson.js +28 -0
  299. package/bin/runners/lib/policy.js +295 -0
  300. package/bin/runners/lib/polish/accessibility.js +62 -0
  301. package/bin/runners/lib/polish/analyzer.js +93 -0
  302. package/bin/runners/lib/polish/backend.js +87 -0
  303. package/bin/runners/lib/polish/configuration.js +83 -0
  304. package/bin/runners/lib/polish/documentation.js +83 -0
  305. package/bin/runners/lib/polish/frontend.js +817 -0
  306. package/bin/runners/lib/polish/index.js +27 -0
  307. package/bin/runners/lib/polish/infrastructure.js +80 -0
  308. package/bin/runners/lib/polish/internationalization.js +85 -0
  309. package/bin/runners/lib/polish/libraries.js +180 -0
  310. package/bin/runners/lib/polish/observability.js +75 -0
  311. package/bin/runners/lib/polish/performance.js +64 -0
  312. package/bin/runners/lib/polish/privacy.js +110 -0
  313. package/bin/runners/lib/polish/resilience.js +92 -0
  314. package/bin/runners/lib/polish/security.js +78 -0
  315. package/bin/runners/lib/polish/seo.js +71 -0
  316. package/bin/runners/lib/polish/styles.js +62 -0
  317. package/bin/runners/lib/polish/utils.js +104 -0
  318. package/bin/runners/lib/preflight.js +142 -0
  319. package/bin/runners/lib/prerequisites.js +149 -0
  320. package/bin/runners/lib/prove-output.js +220 -0
  321. package/bin/runners/lib/reality/correlation-detectors.js +359 -0
  322. package/bin/runners/lib/reality/index.js +318 -0
  323. package/bin/runners/lib/reality/request-hashing.js +416 -0
  324. package/bin/runners/lib/reality/request-mapper.js +453 -0
  325. package/bin/runners/lib/reality/safety-rails.js +463 -0
  326. package/bin/runners/lib/reality/semantic-snapshot.js +408 -0
  327. package/bin/runners/lib/reality/toast-detector.js +393 -0
  328. package/bin/runners/lib/reality-findings.js +84 -0
  329. package/bin/runners/lib/reality-output.js +231 -0
  330. package/bin/runners/lib/receipts.js +179 -0
  331. package/bin/runners/lib/redact.js +29 -0
  332. package/bin/runners/lib/replay/capsule-manager.js +154 -0
  333. package/bin/runners/lib/replay/index.js +263 -0
  334. package/bin/runners/lib/replay/player.js +348 -0
  335. package/bin/runners/lib/replay/recorder.js +331 -0
  336. package/bin/runners/lib/report-engine.js +626 -0
  337. package/bin/runners/lib/report-html.js +1233 -0
  338. package/bin/runners/lib/report-output.js +366 -0
  339. package/bin/runners/lib/report-templates.js +967 -0
  340. package/bin/runners/lib/report.js +135 -0
  341. package/bin/runners/lib/route-detection.js +1209 -0
  342. package/bin/runners/lib/route-truth.js +1322 -0
  343. package/bin/runners/lib/safelist/index.js +96 -0
  344. package/bin/runners/lib/safelist/integration.js +334 -0
  345. package/bin/runners/lib/safelist/matcher.js +696 -0
  346. package/bin/runners/lib/safelist/schema.js +948 -0
  347. package/bin/runners/lib/safelist/store.js +438 -0
  348. package/bin/runners/lib/sandbox/index.js +59 -0
  349. package/bin/runners/lib/sandbox/proof-chain.js +399 -0
  350. package/bin/runners/lib/sandbox/sandbox-runner.js +205 -0
  351. package/bin/runners/lib/sandbox/worktree.js +174 -0
  352. package/bin/runners/lib/scan-cache.js +330 -0
  353. package/bin/runners/lib/scan-output-schema.js +344 -0
  354. package/bin/runners/lib/scan-output.js +631 -0
  355. package/bin/runners/lib/scan-runner.js +135 -0
  356. package/bin/runners/lib/schema-validator.js +350 -0
  357. package/bin/runners/lib/schemas/ajv-validator.js +464 -0
  358. package/bin/runners/lib/schemas/contracts.schema.json +160 -0
  359. package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
  360. package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
  361. package/bin/runners/lib/schemas/finding.schema.json +100 -0
  362. package/bin/runners/lib/schemas/mission-pack.schema.json +206 -0
  363. package/bin/runners/lib/schemas/proof-graph.schema.json +176 -0
  364. package/bin/runners/lib/schemas/reality-report.schema.json +162 -0
  365. package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
  366. package/bin/runners/lib/schemas/run-request.schema.json +108 -0
  367. package/bin/runners/lib/schemas/share-pack.schema.json +180 -0
  368. package/bin/runners/lib/schemas/ship-manifest.schema.json +251 -0
  369. package/bin/runners/lib/schemas/ship-report.schema.json +117 -0
  370. package/bin/runners/lib/schemas/truthpack-v2.schema.json +303 -0
  371. package/bin/runners/lib/schemas/validator.js +465 -0
  372. package/bin/runners/lib/schemas/verdict.schema.json +140 -0
  373. package/bin/runners/lib/score-history.js +282 -0
  374. package/bin/runners/lib/security-bridge.js +249 -0
  375. package/bin/runners/lib/server-usage.js +513 -0
  376. package/bin/runners/lib/share-pack.js +239 -0
  377. package/bin/runners/lib/ship-gate.js +832 -0
  378. package/bin/runners/lib/ship-manifest.js +1153 -0
  379. package/bin/runners/lib/ship-output-enterprise.js +239 -0
  380. package/bin/runners/lib/ship-output.js +1128 -0
  381. package/bin/runners/lib/snippets.js +67 -0
  382. package/bin/runners/lib/status-output.js +340 -0
  383. package/bin/runners/lib/terminal-ui.js +356 -0
  384. package/bin/runners/lib/truth.js +1691 -0
  385. package/bin/runners/lib/ui.js +562 -0
  386. package/bin/runners/lib/unified-cli-output.js +947 -0
  387. package/bin/runners/lib/unified-output.js +197 -0
  388. package/bin/runners/lib/upsell.js +410 -0
  389. package/bin/runners/lib/usage.js +153 -0
  390. package/bin/runners/lib/validate-patch.js +156 -0
  391. package/bin/runners/lib/verdict-engine.js +628 -0
  392. package/bin/runners/lib/verification.js +345 -0
  393. package/bin/runners/lib/why-tree.js +650 -0
  394. package/bin/runners/reality/engine.js +917 -0
  395. package/bin/runners/reality/flows.js +122 -0
  396. package/bin/runners/reality/report.js +378 -0
  397. package/bin/runners/reality/session.js +193 -0
  398. package/bin/runners/runAIAgent.js +229 -0
  399. package/bin/runners/runAgent.d.ts +5 -0
  400. package/bin/runners/runAgent.js +161 -0
  401. package/bin/runners/runAllowlist.js +418 -0
  402. package/bin/runners/runApprove.js +320 -0
  403. package/bin/runners/runAudit.js +692 -0
  404. package/bin/runners/runAuth.js +731 -0
  405. package/bin/runners/runCI.js +353 -0
  406. package/bin/runners/runCheckpoint.js +530 -0
  407. package/bin/runners/runClassify.js +928 -0
  408. package/bin/runners/runCleanup.js +343 -0
  409. package/bin/runners/runContext.d.ts +4 -0
  410. package/bin/runners/runContext.js +175 -0
  411. package/bin/runners/runDoctor.js +877 -0
  412. package/bin/runners/runEvidencePack.js +362 -0
  413. package/bin/runners/runFirewall.d.ts +5 -0
  414. package/bin/runners/runFirewall.js +134 -0
  415. package/bin/runners/runFirewallHook.d.ts +5 -0
  416. package/bin/runners/runFirewallHook.js +56 -0
  417. package/bin/runners/runFix.js +1355 -0
  418. package/bin/runners/runForge.js +451 -0
  419. package/bin/runners/runGuard.js +262 -0
  420. package/bin/runners/runInit.js +1927 -0
  421. package/bin/runners/runIntent.js +906 -0
  422. package/bin/runners/runKickoff.js +878 -0
  423. package/bin/runners/runLabs.js +424 -0
  424. package/bin/runners/runLaunch.js +2000 -0
  425. package/bin/runners/runLink.js +785 -0
  426. package/bin/runners/runMcp.js +1875 -0
  427. package/bin/runners/runPacks.js +2089 -0
  428. package/bin/runners/runPolish.d.ts +4 -0
  429. package/bin/runners/runPolish.js +390 -0
  430. package/bin/runners/runPromptFirewall.js +211 -0
  431. package/bin/runners/runProve.js +1411 -0
  432. package/bin/runners/runQuickstart.js +531 -0
  433. package/bin/runners/runReality.js +2260 -0
  434. package/bin/runners/runReport.js +726 -0
  435. package/bin/runners/runRuntime.js +110 -0
  436. package/bin/runners/runSafelist.js +1190 -0
  437. package/bin/runners/runScan.js +688 -0
  438. package/bin/runners/runShield.js +1282 -0
  439. package/bin/runners/runShip.js +1660 -0
  440. package/bin/runners/runTruth.d.ts +5 -0
  441. package/bin/runners/runTruth.js +101 -0
  442. package/bin/runners/runValidate.js +179 -0
  443. package/bin/runners/runWatch.js +478 -0
  444. package/bin/runners/utils.js +360 -0
  445. package/bin/scan.js +617 -0
  446. package/bin/vibecheck.js +1617 -0
  447. package/dist/guardrail/index.d.ts +2405 -0
  448. package/dist/guardrail/index.js +9747 -0
  449. package/dist/guardrail/index.js.map +1 -0
  450. package/dist/scanner/index.d.ts +282 -0
  451. package/dist/scanner/index.js +3395 -0
  452. package/dist/scanner/index.js.map +1 -0
  453. package/package.json +123 -104
  454. package/README.md +0 -491
  455. package/dist/index.js +0 -99711
  456. package/dist/index.js.map +0 -1
@@ -0,0 +1,906 @@
1
+ /**
2
+ * vibecheck intent - Intent Declaration CLI
3
+ *
4
+ * ═══════════════════════════════════════════════════════════════════════════════
5
+ * AGENT FIREWALL™ - INTENT DECLARATION COMMAND
6
+ * ═══════════════════════════════════════════════════════════════════════════════
7
+ *
8
+ * Manage intent declarations for the Agent Firewall.
9
+ * Intent MUST be declared before AI code generation.
10
+ * If intent is missing → Agent Firewall defaults to BLOCK.
11
+ *
12
+ * Subcommands:
13
+ * set - Declare a new intent
14
+ * show - Show current intent
15
+ * clear - Clear current intent
16
+ * history - View intent history
17
+ * verify - Verify intent integrity
18
+ *
19
+ * @module runIntent
20
+ * @version 2.0.0
21
+ */
22
+
23
+ "use strict";
24
+
25
+ const path = require("path");
26
+ const fs = require("fs");
27
+
28
+ // Lazy imports
29
+ let _globalFlags = null;
30
+ let _exitCodes = null;
31
+ let _cliOutput = null;
32
+ let _intentModule = null;
33
+
34
+ function getGlobalFlags() {
35
+ if (!_globalFlags) {
36
+ _globalFlags = require("./lib/global-flags");
37
+ }
38
+ return _globalFlags;
39
+ }
40
+
41
+ function getExitCodes() {
42
+ if (!_exitCodes) {
43
+ _exitCodes = require("./lib/exit-codes");
44
+ }
45
+ return _exitCodes;
46
+ }
47
+
48
+ function getCliOutput() {
49
+ if (!_cliOutput) {
50
+ _cliOutput = require("./lib/unified-cli-output");
51
+ }
52
+ return _cliOutput;
53
+ }
54
+
55
+ function getIntentModule() {
56
+ if (!_intentModule) {
57
+ _intentModule = require("./lib/agent-firewall/intent");
58
+ }
59
+ return _intentModule;
60
+ }
61
+
62
+ // ═══════════════════════════════════════════════════════════════════════════════
63
+ // CONSTANTS
64
+ // ═══════════════════════════════════════════════════════════════════════════════
65
+
66
+ const INTENT_VERSION = "2.0.0";
67
+
68
+ const SUBCOMMANDS = {
69
+ set: { description: "Declare a new intent", pro: false },
70
+ show: { description: "Show current intent", pro: false },
71
+ clear: { description: "Clear current intent (archives to history)", pro: false },
72
+ history: { description: "View intent history", pro: false },
73
+ verify: { description: "Verify intent integrity", pro: false },
74
+ template: { description: "Show intent templates", pro: false },
75
+ };
76
+
77
+ // ═══════════════════════════════════════════════════════════════════════════════
78
+ // HELP
79
+ // ═══════════════════════════════════════════════════════════════════════════════
80
+
81
+ function printHelp() {
82
+ const { ansi } = getCliOutput();
83
+
84
+ console.log(`
85
+ ${ansi.bold}${ansi.cyan}╔═══════════════════════════════════════════════════════════════════════════════╗
86
+ ║ ║
87
+ ║ ${ansi.reset}${ansi.bold}INTENT DECLARATION${ansi.cyan} ║
88
+ ║ ${ansi.reset}${ansi.dim}Agent Firewall™ Intent System${ansi.cyan} ║
89
+ ║ ║
90
+ ╚═══════════════════════════════════════════════════════════════════════════════╝${ansi.reset}
91
+
92
+ ${ansi.bold}USAGE${ansi.reset}
93
+ ${ansi.cyan}vibecheck i${ansi.reset} "summary" ${ansi.dim}Quick intent (auto-infers everything)${ansi.reset}
94
+ ${ansi.cyan}vibecheck intent${ansi.reset} <subcommand> [options]
95
+
96
+ ${ansi.dim}Declare your intent BEFORE AI code generation.
97
+ In observe mode, changes are logged for later approval.${ansi.reset}
98
+
99
+ ${ansi.bold}SUBCOMMANDS${ansi.reset}
100
+ ${ansi.cyan}set${ansi.reset} Declare a new intent
101
+ ${ansi.cyan}show${ansi.reset} Show current intent
102
+ ${ansi.cyan}clear${ansi.reset} Clear current intent
103
+ ${ansi.cyan}history${ansi.reset} View intent history
104
+ ${ansi.cyan}verify${ansi.reset} Verify intent integrity
105
+ ${ansi.cyan}template${ansi.reset} Show intent templates
106
+
107
+ ${ansi.bold}SET OPTIONS${ansi.reset}
108
+ ${ansi.cyan}--summary, -s <text>${ansi.reset} Intent summary (required)
109
+ ${ansi.cyan}--constraint, -c <text>${ansi.reset} Add constraint (repeatable)
110
+ ${ansi.cyan}--allow-file <path>${ansi.reset} Allow file modification (repeatable)
111
+ ${ansi.cyan}--allow-route <route>${ansi.reset} Allow route addition (repeatable)
112
+ ${ansi.cyan}--allow-env <var>${ansi.reset} Allow env var (repeatable)
113
+ ${ansi.cyan}--scope-dir <dir>${ansi.reset} Restrict to directory (repeatable)
114
+ ${ansi.cyan}--scope-domain <domain>${ansi.reset} Restrict to domain (repeatable)
115
+ ${ansi.cyan}--expires <duration>${ansi.reset} Set expiration (e.g., "1h", "30m")
116
+ ${ansi.cyan}--from-file <path>${ansi.reset} Load intent from JSON file
117
+
118
+ ${ansi.bold}EXAMPLES${ansi.reset}
119
+ ${ansi.dim}# Simple intent${ansi.reset}
120
+ vibecheck intent set -s "Fix login button styling"
121
+
122
+ ${ansi.dim}# Intent with constraints${ansi.reset}
123
+ vibecheck intent set -s "Add user profile endpoint" \\
124
+ -c "No auth changes" \\
125
+ -c "Tests required" \\
126
+ --allow-file "src/routes/users.ts" \\
127
+ --allow-route "GET /api/users/:id"
128
+
129
+ ${ansi.dim}# Scoped intent${ansi.reset}
130
+ vibecheck intent set -s "Refactor auth module" \\
131
+ --scope-dir "src/auth/" \\
132
+ --scope-domain "auth"
133
+
134
+ ${ansi.dim}# From file${ansi.reset}
135
+ vibecheck intent set --from-file intent.json
136
+
137
+ ${ansi.dim}# Show current${ansi.reset}
138
+ vibecheck intent show
139
+
140
+ ${ansi.dim}# Clear${ansi.reset}
141
+ vibecheck intent clear
142
+
143
+ ${ansi.bold}DOMAINS${ansi.reset}
144
+ auth, payments, routes, contracts, ui, database, config, general
145
+
146
+ ${ansi.dim}────────────────────────────────────────────────────────────────────${ansi.reset}
147
+ ${ansi.dim}Documentation: https://docs.vibecheckai.dev/cli/intent${ansi.reset}
148
+ ${ansi.dim}Version: ${INTENT_VERSION}${ansi.reset}
149
+ `);
150
+ }
151
+
152
+ // ═══════════════════════════════════════════════════════════════════════════════
153
+ // MAIN ENTRY
154
+ // ═══════════════════════════════════════════════════════════════════════════════
155
+
156
+ /**
157
+ * Main intent command handler
158
+ * @param {string[]} args - Command arguments
159
+ * @param {Object} context - Execution context
160
+ * @returns {Promise<number>} Exit code
161
+ */
162
+ async function runIntent(args = [], context = {}) {
163
+ const { parseGlobalFlags, shouldSuppressOutput, isJsonMode } = getGlobalFlags();
164
+ const { EXIT } = getExitCodes();
165
+
166
+ const { flags: globalFlags, cleanArgs } = parseGlobalFlags(args);
167
+ const quiet = shouldSuppressOutput(globalFlags);
168
+ const json = isJsonMode(globalFlags) || args.includes("--json");
169
+ const projectRoot = context.repoRoot || globalFlags.path || process.cwd();
170
+
171
+ // Handle help
172
+ if (globalFlags.help || args.includes("--help") || args.includes("-h")) {
173
+ printHelp();
174
+ return EXIT.SUCCESS;
175
+ }
176
+
177
+ // Check for QUICK INTENT MODE: vibecheck i "summary text"
178
+ // If first arg is a quoted string (not a subcommand), treat as quick intent
179
+ const firstArg = cleanArgs[0];
180
+ const isQuickMode = firstArg &&
181
+ !SUBCOMMANDS[firstArg] &&
182
+ !firstArg.startsWith("-") &&
183
+ firstArg.length > 2;
184
+
185
+ if (isQuickMode) {
186
+ // Quick intent: vibecheck i "fix login bug"
187
+ const ctx = {
188
+ projectRoot,
189
+ json,
190
+ quiet,
191
+ args: cleanArgs,
192
+ originalArgs: args,
193
+ quickMode: true,
194
+ };
195
+ return await handleQuickSet(ctx);
196
+ }
197
+
198
+ // Parse subcommand
199
+ const subcommand = firstArg || "show";
200
+ const subArgs = cleanArgs.slice(1);
201
+
202
+ // Create context
203
+ const ctx = {
204
+ projectRoot,
205
+ json,
206
+ quiet,
207
+ args: subArgs,
208
+ originalArgs: args,
209
+ };
210
+
211
+ try {
212
+ switch (subcommand) {
213
+ case "set":
214
+ return await handleSet(ctx);
215
+ case "show":
216
+ return await handleShow(ctx);
217
+ case "clear":
218
+ return await handleClear(ctx);
219
+ case "history":
220
+ return await handleHistory(ctx);
221
+ case "verify":
222
+ return await handleVerify(ctx);
223
+ case "template":
224
+ return await handleTemplate(ctx);
225
+ default:
226
+ return handleUnknown(subcommand, ctx);
227
+ }
228
+ } catch (error) {
229
+ return handleError(error, ctx);
230
+ }
231
+ }
232
+
233
+ // ═══════════════════════════════════════════════════════════════════════════════
234
+ // HANDLERS
235
+ // ═══════════════════════════════════════════════════════════════════════════════
236
+
237
+ /**
238
+ * Handle QUICK set - vibecheck i "summary text"
239
+ * Auto-infers constraints, scope, and allowed files from context
240
+ */
241
+ async function handleQuickSet(ctx) {
242
+ const { EXIT } = getExitCodes();
243
+ const { ansi, renderSuccess, renderError } = getCliOutput();
244
+ const { createIntent, IntentStore } = getIntentModule();
245
+
246
+ // Import auto-detect module
247
+ let autoDetect;
248
+ try {
249
+ autoDetect = require("./lib/agent-firewall/intent/auto-detect");
250
+ } catch (e) {
251
+ if (ctx.json) {
252
+ console.log(JSON.stringify({ success: false, error: "Auto-detect module not available" }));
253
+ } else {
254
+ renderError("Auto-detect module not available");
255
+ }
256
+ return EXIT.INTERNAL_ERROR;
257
+ }
258
+
259
+ // Get the summary from args - join all non-flag args
260
+ const summaryParts = ctx.args.filter(a => !a.startsWith("-"));
261
+ const userSummary = summaryParts.join(" ").trim();
262
+
263
+ if (!userSummary) {
264
+ if (ctx.json) {
265
+ console.log(JSON.stringify({ success: false, error: "Summary required" }));
266
+ } else {
267
+ renderError("Summary required");
268
+ console.log(`\n ${ansi.dim}Example: ${ansi.cyan}vibecheck i "fix login bug"${ansi.reset}\n`);
269
+ }
270
+ return EXIT.USER_ERROR;
271
+ }
272
+
273
+ // Auto-detect context
274
+ const detected = autoDetect.autoDetectIntent(ctx.projectRoot, userSummary);
275
+
276
+ // Create and store intent
277
+ const intent = createIntent(detected);
278
+ const store = new IntentStore(ctx.projectRoot);
279
+ const result = store.store(intent);
280
+
281
+ if (ctx.json) {
282
+ console.log(JSON.stringify({
283
+ success: result.success,
284
+ quick_mode: true,
285
+ intent: {
286
+ hash: intent.hash,
287
+ summary: intent.summary,
288
+ constraints: intent.constraints,
289
+ allowed_changes: intent.allowed_changes?.length || 0,
290
+ scope: intent.scope,
291
+ created_at: intent.created_at,
292
+ },
293
+ auto_detected: detected._context,
294
+ error: result.error,
295
+ }, null, 2));
296
+ } else if (!ctx.quiet) {
297
+ if (result.success) {
298
+ console.log(`
299
+ ${ansi.green}${ansi.bold}╔═══════════════════════════════════════════════════════════════════╗
300
+ ║ ║
301
+ ║ ✓ QUICK INTENT SET ║
302
+ ║ ║
303
+ ╚═══════════════════════════════════════════════════════════════════╝${ansi.reset}
304
+
305
+ ${ansi.bold}Summary${ansi.reset}
306
+ ${intent.summary}`);
307
+
308
+ if (intent.constraints.length > 0) {
309
+ console.log(`\n ${ansi.bold}Auto-Inferred Constraints${ansi.reset}`);
310
+ for (const c of intent.constraints) {
311
+ console.log(` ${ansi.yellow}•${ansi.reset} ${c}`);
312
+ }
313
+ }
314
+
315
+ if (intent.allowed_changes && intent.allowed_changes.length > 0) {
316
+ console.log(`\n ${ansi.bold}Auto-Allowed Files${ansi.reset} ${ansi.dim}(from git status)${ansi.reset}`);
317
+ for (const ac of intent.allowed_changes.slice(0, 5)) {
318
+ console.log(` ${ansi.green}✓${ansi.reset} ${ac.target}`);
319
+ }
320
+ if (intent.allowed_changes.length > 5) {
321
+ console.log(` ${ansi.dim}... and ${intent.allowed_changes.length - 5} more${ansi.reset}`);
322
+ }
323
+ }
324
+
325
+ if (intent.scope) {
326
+ console.log(`\n ${ansi.bold}Auto-Detected Scope${ansi.reset}`);
327
+ if (intent.scope.directories) {
328
+ console.log(` ${ansi.dim}Directories:${ansi.reset} ${intent.scope.directories.join(", ")}`);
329
+ }
330
+ if (intent.scope.domains) {
331
+ console.log(` ${ansi.dim}Domains:${ansi.reset} ${intent.scope.domains.join(", ")}`);
332
+ }
333
+ }
334
+
335
+ // Show context used
336
+ const ctx_info = detected._context;
337
+ if (ctx_info) {
338
+ console.log(`\n ${ansi.dim}Context: ${ctx_info.branch ? `branch=${ctx_info.branch}` : ""}${ctx_info.stagedFiles ? ` staged=${ctx_info.stagedFiles}` : ""}${ctx_info.modifiedFiles ? ` modified=${ctx_info.modifiedFiles}` : ""} type=${ctx_info.inferredType}${ansi.reset}`);
339
+ }
340
+
341
+ console.log(`
342
+ ${ansi.dim}Hash: ${intent.hash.slice(0, 16)}...${ansi.reset}
343
+
344
+ ${ansi.bold}You're ready to vibe.${ansi.reset} ${ansi.dim}AI changes will be checked against this intent.${ansi.reset}
345
+ `);
346
+ } else {
347
+ renderError(result.error || "Failed to store intent");
348
+ }
349
+ }
350
+
351
+ return result.success ? EXIT.SUCCESS : EXIT.INTERNAL_ERROR;
352
+ }
353
+
354
+ /**
355
+ * Handle set subcommand
356
+ */
357
+ async function handleSet(ctx) {
358
+ const { EXIT } = getExitCodes();
359
+ const { ansi, renderSuccess, renderError } = getCliOutput();
360
+ const { createIntent, IntentStore, CONSTRAINT_TEMPLATES } = getIntentModule();
361
+
362
+ const args = ctx.originalArgs;
363
+
364
+ // Check for --from-file
365
+ const fromFile = getArgValue(args, "--from-file");
366
+
367
+ let intentData;
368
+
369
+ if (fromFile) {
370
+ // Load from file
371
+ const filePath = path.resolve(ctx.projectRoot, fromFile);
372
+ if (!fs.existsSync(filePath)) {
373
+ if (ctx.json) {
374
+ console.log(JSON.stringify({ success: false, error: `File not found: ${fromFile}` }));
375
+ } else {
376
+ renderError(`File not found: ${fromFile}`);
377
+ }
378
+ return EXIT.USER_ERROR;
379
+ }
380
+
381
+ try {
382
+ intentData = JSON.parse(fs.readFileSync(filePath, "utf-8"));
383
+ } catch (e) {
384
+ if (ctx.json) {
385
+ console.log(JSON.stringify({ success: false, error: `Invalid JSON: ${e.message}` }));
386
+ } else {
387
+ renderError(`Invalid JSON in ${fromFile}: ${e.message}`);
388
+ }
389
+ return EXIT.USER_ERROR;
390
+ }
391
+ } else {
392
+ // Build from CLI args
393
+ const summary = getArgValue(args, "--summary") || getArgValue(args, "-s");
394
+
395
+ if (!summary) {
396
+ if (ctx.json) {
397
+ console.log(JSON.stringify({ success: false, error: "Summary required. Use --summary or -s" }));
398
+ } else {
399
+ renderError("Summary required. Use --summary or -s");
400
+ console.log(`\n ${ansi.dim}Example: vibecheck intent set -s "Add user profile endpoint"${ansi.reset}\n`);
401
+ }
402
+ return EXIT.USER_ERROR;
403
+ }
404
+
405
+ const constraints = getAllArgValues(args, "--constraint", "-c");
406
+ const allowFiles = getAllArgValues(args, "--allow-file");
407
+ const allowRoutes = getAllArgValues(args, "--allow-route");
408
+ const allowEnvs = getAllArgValues(args, "--allow-env");
409
+ const scopeDirs = getAllArgValues(args, "--scope-dir");
410
+ const scopeDomains = getAllArgValues(args, "--scope-domain");
411
+ const expires = getArgValue(args, "--expires");
412
+
413
+ // Build allowed_changes
414
+ const allowed_changes = [];
415
+
416
+ for (const file of allowFiles) {
417
+ allowed_changes.push({ type: "file_modify", target: file });
418
+ }
419
+ for (const route of allowRoutes) {
420
+ allowed_changes.push({ type: "route_add", target: route });
421
+ }
422
+ for (const env of allowEnvs) {
423
+ allowed_changes.push({ type: "env_add", target: env });
424
+ }
425
+
426
+ // Build scope
427
+ let scope = null;
428
+ if (scopeDirs.length > 0 || scopeDomains.length > 0) {
429
+ scope = {};
430
+ if (scopeDirs.length > 0) scope.directories = scopeDirs;
431
+ if (scopeDomains.length > 0) scope.domains = scopeDomains;
432
+ }
433
+
434
+ intentData = {
435
+ summary,
436
+ constraints,
437
+ allowed_changes: allowed_changes.length > 0 ? allowed_changes : undefined,
438
+ scope,
439
+ };
440
+
441
+ // Handle expiration
442
+ if (expires) {
443
+ const ms = parseDuration(expires);
444
+ if (ms) {
445
+ intentData.expires_at = new Date(Date.now() + ms).toISOString();
446
+ }
447
+ }
448
+ }
449
+
450
+ // Create and store intent
451
+ const intent = createIntent(intentData);
452
+ const store = new IntentStore(ctx.projectRoot);
453
+ const result = store.store(intent);
454
+
455
+ if (ctx.json) {
456
+ console.log(JSON.stringify({
457
+ success: result.success,
458
+ intent: {
459
+ hash: intent.hash,
460
+ summary: intent.summary,
461
+ constraints: intent.constraints,
462
+ created_at: intent.created_at,
463
+ },
464
+ error: result.error,
465
+ }, null, 2));
466
+ } else if (!ctx.quiet) {
467
+ if (result.success) {
468
+ console.log(`
469
+ ${ansi.green}${ansi.bold}╔═══════════════════════════════════════════════════════════════════╗
470
+ ║ ║
471
+ ║ ✓ INTENT DECLARED ║
472
+ ║ ║
473
+ ╚═══════════════════════════════════════════════════════════════════╝${ansi.reset}
474
+
475
+ ${ansi.bold}Summary${ansi.reset}
476
+ ${intent.summary}
477
+
478
+ ${ansi.bold}Constraints${ansi.reset}`);
479
+
480
+ if (intent.constraints.length > 0) {
481
+ for (const c of intent.constraints) {
482
+ console.log(` ${ansi.yellow}•${ansi.reset} ${c}`);
483
+ }
484
+ } else {
485
+ console.log(` ${ansi.dim}(none)${ansi.reset}`);
486
+ }
487
+
488
+ if (intent.allowed_changes && intent.allowed_changes.length > 0) {
489
+ console.log(`\n ${ansi.bold}Allowed Changes${ansi.reset}`);
490
+ for (const ac of intent.allowed_changes) {
491
+ console.log(` ${ansi.green}✓${ansi.reset} [${ac.type}] ${ac.target || ac.pattern}`);
492
+ }
493
+ }
494
+
495
+ if (intent.scope) {
496
+ console.log(`\n ${ansi.bold}Scope${ansi.reset}`);
497
+ if (intent.scope.directories) {
498
+ console.log(` ${ansi.dim}Directories:${ansi.reset} ${intent.scope.directories.join(", ")}`);
499
+ }
500
+ if (intent.scope.domains) {
501
+ console.log(` ${ansi.dim}Domains:${ansi.reset} ${intent.scope.domains.join(", ")}`);
502
+ }
503
+ }
504
+
505
+ console.log(`
506
+ ${ansi.dim}Hash: ${intent.hash.slice(0, 16)}...${ansi.reset}
507
+ ${ansi.dim}Created: ${intent.created_at}${ansi.reset}
508
+
509
+ ${ansi.bold}The Agent Firewall will now enforce this intent.${ansi.reset}
510
+ ${ansi.dim}Changes outside this intent will be BLOCKED.${ansi.reset}
511
+ `);
512
+ } else {
513
+ renderError(result.error || "Failed to store intent");
514
+ }
515
+ }
516
+
517
+ return result.success ? EXIT.SUCCESS : EXIT.INTERNAL_ERROR;
518
+ }
519
+
520
+ /**
521
+ * Handle show subcommand
522
+ */
523
+ async function handleShow(ctx) {
524
+ const { EXIT } = getExitCodes();
525
+ const { ansi, renderWarning } = getCliOutput();
526
+ const { IntentStore, verifyIntentIntegrity, isIntentExpired } = getIntentModule();
527
+
528
+ const store = new IntentStore(ctx.projectRoot);
529
+ const intent = store.getCurrent({ allowMissing: true });
530
+
531
+ if (!intent) {
532
+ if (ctx.json) {
533
+ console.log(JSON.stringify({ intent: null, message: "No intent declared" }));
534
+ } else if (!ctx.quiet) {
535
+ renderWarning("No intent declared");
536
+ console.log(`
537
+ ${ansi.dim}The Agent Firewall will BLOCK all AI changes.${ansi.reset}
538
+ ${ansi.dim}Declare an intent: ${ansi.cyan}vibecheck intent set -s "Your intent"${ansi.reset}
539
+ `);
540
+ }
541
+ return EXIT.SUCCESS;
542
+ }
543
+
544
+ // Check if it's the blocking intent
545
+ const isBlocking = intent.summary?.includes("NO INTENT DECLARED");
546
+
547
+ // Verify integrity
548
+ const integrity = verifyIntentIntegrity(intent);
549
+ const expired = isIntentExpired(intent);
550
+
551
+ if (ctx.json) {
552
+ console.log(JSON.stringify({
553
+ intent,
554
+ status: {
555
+ valid: integrity.valid && !expired && !isBlocking,
556
+ integrity: integrity.valid,
557
+ expired,
558
+ isBlocking,
559
+ },
560
+ }, null, 2));
561
+ } else if (!ctx.quiet) {
562
+ if (isBlocking) {
563
+ console.log(`
564
+ ${ansi.yellow}${ansi.bold}╔═══════════════════════════════════════════════════════════════════╗
565
+ ║ ║
566
+ ║ ⚠ NO INTENT DECLARED ║
567
+ ║ ║
568
+ ╚═══════════════════════════════════════════════════════════════════╝${ansi.reset}
569
+
570
+ ${ansi.yellow}All AI changes are currently BLOCKED.${ansi.reset}
571
+ ${ansi.dim}Declare an intent to allow specific changes.${ansi.reset}
572
+
573
+ ${ansi.bold}Example:${ansi.reset}
574
+ ${ansi.cyan}vibecheck intent set -s "Fix login button" --allow-file "src/Login.tsx"${ansi.reset}
575
+ `);
576
+ } else {
577
+ const statusColor = integrity.valid && !expired ? ansi.green : ansi.red;
578
+ const statusText = integrity.valid && !expired ? "ACTIVE" : expired ? "EXPIRED" : "INVALID";
579
+
580
+ console.log(`
581
+ ${ansi.cyan}${ansi.bold}╔═══════════════════════════════════════════════════════════════════╗
582
+ ║ ║
583
+ ║ CURRENT INTENT ║
584
+ ║ ║
585
+ ╚═══════════════════════════════════════════════════════════════════╝${ansi.reset}
586
+
587
+ ${ansi.bold}Status${ansi.reset}
588
+ ${statusColor}${statusText}${ansi.reset}${expired ? ` ${ansi.dim}(expired at ${intent.expires_at})${ansi.reset}` : ""}
589
+
590
+ ${ansi.bold}Summary${ansi.reset}
591
+ ${intent.summary}
592
+
593
+ ${ansi.bold}Constraints${ansi.reset}`);
594
+
595
+ if (intent.constraints && intent.constraints.length > 0) {
596
+ for (const c of intent.constraints) {
597
+ console.log(` ${ansi.yellow}•${ansi.reset} ${c}`);
598
+ }
599
+ } else {
600
+ console.log(` ${ansi.dim}(none)${ansi.reset}`);
601
+ }
602
+
603
+ if (intent.allowed_changes && intent.allowed_changes.length > 0) {
604
+ console.log(`\n ${ansi.bold}Allowed Changes${ansi.reset}`);
605
+ for (const ac of intent.allowed_changes) {
606
+ console.log(` ${ansi.green}✓${ansi.reset} [${ac.type}] ${ac.target || ac.pattern}`);
607
+ }
608
+ }
609
+
610
+ if (intent.scope) {
611
+ console.log(`\n ${ansi.bold}Scope${ansi.reset}`);
612
+ if (intent.scope.directories) {
613
+ console.log(` ${ansi.dim}Directories:${ansi.reset} ${intent.scope.directories.join(", ")}`);
614
+ }
615
+ if (intent.scope.domains) {
616
+ console.log(` ${ansi.dim}Domains:${ansi.reset} ${intent.scope.domains.join(", ")}`);
617
+ }
618
+ if (intent.scope.excluded_paths) {
619
+ console.log(` ${ansi.dim}Excluded:${ansi.reset} ${intent.scope.excluded_paths.join(", ")}`);
620
+ }
621
+ }
622
+
623
+ console.log(`
624
+ ${ansi.dim}Hash: ${intent.hash.slice(0, 16)}...${ansi.reset}
625
+ ${ansi.dim}Version: ${intent.version || 1}${ansi.reset}
626
+ ${ansi.dim}Created: ${intent.created_at}${ansi.reset}
627
+ `);
628
+ }
629
+ }
630
+
631
+ return EXIT.SUCCESS;
632
+ }
633
+
634
+ /**
635
+ * Handle clear subcommand
636
+ */
637
+ async function handleClear(ctx) {
638
+ const { EXIT } = getExitCodes();
639
+ const { ansi, renderSuccess, renderWarning } = getCliOutput();
640
+ const { IntentStore } = getIntentModule();
641
+
642
+ const store = new IntentStore(ctx.projectRoot);
643
+
644
+ if (!store.hasIntent()) {
645
+ if (ctx.json) {
646
+ console.log(JSON.stringify({ success: true, message: "No intent to clear" }));
647
+ } else if (!ctx.quiet) {
648
+ renderWarning("No intent to clear");
649
+ }
650
+ return EXIT.SUCCESS;
651
+ }
652
+
653
+ store.clear();
654
+
655
+ if (ctx.json) {
656
+ console.log(JSON.stringify({ success: true, message: "Intent cleared and archived" }));
657
+ } else if (!ctx.quiet) {
658
+ renderSuccess("Intent cleared");
659
+ console.log(`
660
+ ${ansi.dim}The previous intent has been archived to history.${ansi.reset}
661
+ ${ansi.yellow}The Agent Firewall will now BLOCK all AI changes.${ansi.reset}
662
+
663
+ ${ansi.dim}View history: ${ansi.cyan}vibecheck intent history${ansi.reset}
664
+ `);
665
+ }
666
+
667
+ return EXIT.SUCCESS;
668
+ }
669
+
670
+ /**
671
+ * Handle history subcommand
672
+ */
673
+ async function handleHistory(ctx) {
674
+ const { EXIT } = getExitCodes();
675
+ const { ansi } = getCliOutput();
676
+ const { IntentStore } = getIntentModule();
677
+
678
+ const store = new IntentStore(ctx.projectRoot);
679
+ const history = store.getHistory(10);
680
+
681
+ if (ctx.json) {
682
+ console.log(JSON.stringify({ history }, null, 2));
683
+ } else if (!ctx.quiet) {
684
+ console.log(`
685
+ ${ansi.bold}Intent History${ansi.reset} ${ansi.dim}(last 10)${ansi.reset}
686
+ `);
687
+
688
+ if (history.length === 0) {
689
+ console.log(` ${ansi.dim}No history found${ansi.reset}\n`);
690
+ } else {
691
+ for (const intent of history) {
692
+ const date = new Date(intent.archived_at || intent.created_at).toLocaleString();
693
+ console.log(` ${ansi.dim}${date}${ansi.reset}`);
694
+ console.log(` ${intent.summary}`);
695
+ console.log(` ${ansi.dim}Hash: ${intent.hash.slice(0, 12)}... | v${intent.version || 1}${ansi.reset}`);
696
+ console.log();
697
+ }
698
+ }
699
+ }
700
+
701
+ return EXIT.SUCCESS;
702
+ }
703
+
704
+ /**
705
+ * Handle verify subcommand
706
+ */
707
+ async function handleVerify(ctx) {
708
+ const { EXIT } = getExitCodes();
709
+ const { ansi, renderSuccess, renderError } = getCliOutput();
710
+ const { IntentStore, verifyIntentIntegrity, isIntentExpired } = getIntentModule();
711
+
712
+ const store = new IntentStore(ctx.projectRoot);
713
+ const intent = store.getCurrent({ allowMissing: true });
714
+
715
+ if (!intent) {
716
+ if (ctx.json) {
717
+ console.log(JSON.stringify({ valid: false, reason: "NO_INTENT" }));
718
+ } else {
719
+ renderError("No intent to verify");
720
+ }
721
+ return EXIT.WARNINGS;
722
+ }
723
+
724
+ const integrity = verifyIntentIntegrity(intent);
725
+ const expired = isIntentExpired(intent);
726
+ const isBlocking = intent.summary?.includes("NO INTENT DECLARED");
727
+
728
+ const result = {
729
+ valid: integrity.valid && !expired && !isBlocking,
730
+ integrity: integrity.valid,
731
+ integrityReason: integrity.reason,
732
+ expired,
733
+ isBlocking,
734
+ hash: intent.hash,
735
+ computed_hash: integrity.computed_hash,
736
+ };
737
+
738
+ if (ctx.json) {
739
+ console.log(JSON.stringify(result, null, 2));
740
+ } else if (!ctx.quiet) {
741
+ if (result.valid) {
742
+ renderSuccess("Intent verified");
743
+ console.log(`
744
+ ${ansi.green}✓${ansi.reset} Integrity: ${integrity.reason}
745
+ ${ansi.green}✓${ansi.reset} Not expired
746
+ ${ansi.dim}Hash: ${intent.hash.slice(0, 16)}...${ansi.reset}
747
+ `);
748
+ } else {
749
+ renderError("Intent verification failed");
750
+ console.log(`
751
+ ${!integrity.valid ? `${ansi.red}✗${ansi.reset} Integrity: ${integrity.reason}` : `${ansi.green}✓${ansi.reset} Integrity: OK`}
752
+ ${expired ? `${ansi.red}✗${ansi.reset} Expired` : `${ansi.green}✓${ansi.reset} Not expired`}
753
+ ${isBlocking ? `${ansi.yellow}!${ansi.reset} Blocking intent (no user intent declared)` : ""}
754
+ `);
755
+ }
756
+ }
757
+
758
+ return result.valid ? EXIT.SUCCESS : EXIT.WARNINGS;
759
+ }
760
+
761
+ /**
762
+ * Handle template subcommand
763
+ */
764
+ async function handleTemplate(ctx) {
765
+ const { EXIT } = getExitCodes();
766
+ const { ansi } = getCliOutput();
767
+ const { CONSTRAINT_TEMPLATES } = getIntentModule();
768
+
769
+ const templates = {
770
+ STRICT_BUGFIX: {
771
+ description: "For minimal, focused bug fixes",
772
+ constraints: CONSTRAINT_TEMPLATES.STRICT_BUGFIX,
773
+ example: 'vibecheck intent set -s "Fix login button" -c "No new routes" -c "Changes limited to specified file(s)" --allow-file "src/Login.tsx"',
774
+ },
775
+ FEATURE_ADDITION: {
776
+ description: "For adding new features",
777
+ constraints: CONSTRAINT_TEMPLATES.FEATURE_ADDITION,
778
+ example: 'vibecheck intent set -s "Add user profile endpoint" -c "Tests required" --allow-route "GET /api/users/:id"',
779
+ },
780
+ REFACTOR: {
781
+ description: "For refactoring without behavior changes",
782
+ constraints: CONSTRAINT_TEMPLATES.REFACTOR,
783
+ example: 'vibecheck intent set -s "Refactor auth module" -c "No behavior changes" --scope-dir "src/auth/"',
784
+ },
785
+ SECURITY_PATCH: {
786
+ description: "For security-sensitive changes",
787
+ constraints: CONSTRAINT_TEMPLATES.SECURITY_PATCH,
788
+ example: 'vibecheck intent set -s "Fix XSS vulnerability" -c "No permission relaxation" -c "Review required"',
789
+ },
790
+ };
791
+
792
+ if (ctx.json) {
793
+ console.log(JSON.stringify(templates, null, 2));
794
+ } else if (!ctx.quiet) {
795
+ console.log(`
796
+ ${ansi.bold}Intent Templates${ansi.reset}
797
+ `);
798
+
799
+ for (const [name, template] of Object.entries(templates)) {
800
+ console.log(`${ansi.cyan}${ansi.bold}${name}${ansi.reset}`);
801
+ console.log(` ${ansi.dim}${template.description}${ansi.reset}`);
802
+ console.log(` ${ansi.bold}Constraints:${ansi.reset}`);
803
+ for (const c of template.constraints) {
804
+ console.log(` ${ansi.yellow}•${ansi.reset} ${c}`);
805
+ }
806
+ console.log(` ${ansi.bold}Example:${ansi.reset}`);
807
+ console.log(` ${ansi.dim}${template.example}${ansi.reset}`);
808
+ console.log();
809
+ }
810
+ }
811
+
812
+ return EXIT.SUCCESS;
813
+ }
814
+
815
+ /**
816
+ * Handle unknown subcommand
817
+ */
818
+ function handleUnknown(subcommand, ctx) {
819
+ const { EXIT } = getExitCodes();
820
+ const { ansi } = getCliOutput();
821
+
822
+ if (ctx.json) {
823
+ console.log(JSON.stringify({
824
+ success: false,
825
+ error: `Unknown subcommand: ${subcommand}`,
826
+ available: Object.keys(SUBCOMMANDS),
827
+ }));
828
+ } else {
829
+ console.log(`
830
+ ${ansi.red}Error: Unknown subcommand '${subcommand}'${ansi.reset}
831
+
832
+ ${ansi.dim}Available subcommands:${ansi.reset}
833
+ ${Object.keys(SUBCOMMANDS).map(s => ` ${ansi.cyan}${s}${ansi.reset}`).join("\n")}
834
+
835
+ Run ${ansi.cyan}vibecheck intent --help${ansi.reset} for usage.
836
+ `);
837
+ }
838
+
839
+ return EXIT.USER_ERROR;
840
+ }
841
+
842
+ /**
843
+ * Handle error
844
+ */
845
+ function handleError(error, ctx) {
846
+ const { EXIT } = getExitCodes();
847
+ const { renderError } = getCliOutput();
848
+
849
+ if (ctx.json) {
850
+ console.log(JSON.stringify({ success: false, error: error.message }));
851
+ } else {
852
+ renderError(`Intent error: ${error.message}`);
853
+ }
854
+
855
+ return EXIT.INTERNAL_ERROR;
856
+ }
857
+
858
+ // ═══════════════════════════════════════════════════════════════════════════════
859
+ // UTILITIES
860
+ // ═══════════════════════════════════════════════════════════════════════════════
861
+
862
+ function getArgValue(args, ...flags) {
863
+ for (const flag of flags) {
864
+ const index = args.indexOf(flag);
865
+ if (index !== -1 && args[index + 1] && !args[index + 1].startsWith("-")) {
866
+ return args[index + 1];
867
+ }
868
+ }
869
+ return null;
870
+ }
871
+
872
+ function getAllArgValues(args, ...flags) {
873
+ const values = [];
874
+ for (let i = 0; i < args.length; i++) {
875
+ if (flags.includes(args[i]) && args[i + 1] && !args[i + 1].startsWith("-")) {
876
+ values.push(args[i + 1]);
877
+ }
878
+ }
879
+ return values;
880
+ }
881
+
882
+ function parseDuration(str) {
883
+ const match = str.match(/^(\d+)(s|m|h|d)$/);
884
+ if (!match) return null;
885
+
886
+ const value = parseInt(match[1], 10);
887
+ const unit = match[2];
888
+
889
+ const multipliers = {
890
+ s: 1000,
891
+ m: 60 * 1000,
892
+ h: 60 * 60 * 1000,
893
+ d: 24 * 60 * 60 * 1000,
894
+ };
895
+
896
+ return value * multipliers[unit];
897
+ }
898
+
899
+ // ═══════════════════════════════════════════════════════════════════════════════
900
+ // EXPORTS
901
+ // ═══════════════════════════════════════════════════════════════════════════════
902
+
903
+ module.exports = {
904
+ runIntent,
905
+ SUBCOMMANDS,
906
+ };