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,1176 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * vibecheck Context Engine - MCP Server
4
+ *
5
+ * A repo-installed Context OS that exposes verified repo facts + patterns + constraints
6
+ * as tool calls, so Cursor/Windsurf/Copilot can't "invent reality".
7
+ *
8
+ * Commands:
9
+ * index - Build truth pack (symbols/graphs/patterns)
10
+ * serve - Start MCP tool server
11
+ * verify - Run verification gates
12
+ */
13
+
14
+ const fs = require("fs");
15
+ const path = require("path");
16
+ const http = require("http");
17
+
18
+ // MCP Protocol version
19
+ const MCP_VERSION = "2024-11-05";
20
+
21
+ class ContextEngine {
22
+ constructor(projectPath) {
23
+ this.projectPath = projectPath;
24
+ this.truthPack = null;
25
+ this.indexed = false;
26
+ }
27
+
28
+ /**
29
+ * Index the project and build the truth pack
30
+ */
31
+ async index() {
32
+ console.log("📦 Building truth pack...");
33
+
34
+ const startTime = Date.now();
35
+
36
+ this.truthPack = {
37
+ version: "1.0.0",
38
+ indexedAt: new Date().toISOString(),
39
+ projectPath: this.projectPath,
40
+
41
+ // Symbol index
42
+ symbols: this.buildSymbolIndex(),
43
+
44
+ // Route map
45
+ routes: this.buildRouteMap(),
46
+
47
+ // Component graph
48
+ components: this.buildComponentGraph(),
49
+
50
+ // Dependency versions
51
+ versions: this.buildVersionTruth(),
52
+
53
+ // Security/auth map
54
+ security: this.buildSecurityMap(),
55
+
56
+ // Test obligations
57
+ tests: this.buildTestObligations(),
58
+
59
+ // Golden patterns
60
+ patterns: this.buildGoldenPatterns(),
61
+
62
+ // File importance/risk
63
+ riskMap: this.buildRiskMap(),
64
+ };
65
+
66
+ // Save truth pack
67
+ const vibecheckDir = path.join(this.projectPath, ".vibecheck");
68
+ if (!fs.existsSync(vibecheckDir)) {
69
+ fs.mkdirSync(vibecheckDir, { recursive: true });
70
+ }
71
+
72
+ fs.writeFileSync(
73
+ path.join(vibecheckDir, "truth-pack.json"),
74
+ JSON.stringify(this.truthPack, null, 2)
75
+ );
76
+
77
+ this.indexed = true;
78
+ const duration = Date.now() - startTime;
79
+
80
+ console.log(`✅ Truth pack built in ${duration}ms`);
81
+ console.log(` Symbols: ${Object.keys(this.truthPack.symbols.exports).length}`);
82
+ console.log(` Routes: ${this.truthPack.routes.endpoints.length}`);
83
+ console.log(` Packages: ${Object.keys(this.truthPack.versions.installed).length}`);
84
+
85
+ return this.truthPack;
86
+ }
87
+
88
+ /**
89
+ * Build symbol index (what exists in the codebase)
90
+ */
91
+ buildSymbolIndex() {
92
+ const symbols = {
93
+ exports: {}, // name -> { file, line, type }
94
+ imports: {}, // package -> [files using it]
95
+ functions: [], // all function names
96
+ components: [], // React components
97
+ types: [], // TypeScript types/interfaces
98
+ hooks: [], // Custom hooks
99
+ };
100
+
101
+ const files = this.findSourceFiles([".ts", ".tsx", ".js", ".jsx"]);
102
+
103
+ for (const file of files) {
104
+ try {
105
+ const content = fs.readFileSync(file, "utf-8");
106
+ const lines = content.split("\n");
107
+ const relativePath = path.relative(this.projectPath, file);
108
+
109
+ lines.forEach((line, idx) => {
110
+ // Exported functions/consts
111
+ const exportMatch = line.match(/export\s+(?:const|function|class|type|interface)\s+(\w+)/);
112
+ if (exportMatch) {
113
+ symbols.exports[exportMatch[1]] = {
114
+ file: relativePath,
115
+ line: idx + 1,
116
+ type: line.includes("function") ? "function" :
117
+ line.includes("class") ? "class" :
118
+ line.includes("type") ? "type" :
119
+ line.includes("interface") ? "interface" : "const"
120
+ };
121
+
122
+ if (exportMatch[1].startsWith("use")) {
123
+ symbols.hooks.push(exportMatch[1]);
124
+ }
125
+ if (/^[A-Z]/.test(exportMatch[1]) && file.endsWith(".tsx")) {
126
+ symbols.components.push(exportMatch[1]);
127
+ }
128
+ }
129
+
130
+ // Imports from packages
131
+ const importMatch = line.match(/import\s+.*?\s+from\s+['"]([^./][^'"]+)['"]/);
132
+ if (importMatch) {
133
+ const pkg = importMatch[1].startsWith("@")
134
+ ? importMatch[1].split("/").slice(0, 2).join("/")
135
+ : importMatch[1].split("/")[0];
136
+
137
+ if (!symbols.imports[pkg]) {
138
+ symbols.imports[pkg] = [];
139
+ }
140
+ if (!symbols.imports[pkg].includes(relativePath)) {
141
+ symbols.imports[pkg].push(relativePath);
142
+ }
143
+ }
144
+ });
145
+ } catch {}
146
+ }
147
+
148
+ return symbols;
149
+ }
150
+
151
+ /**
152
+ * Build route map (API endpoints)
153
+ */
154
+ buildRouteMap() {
155
+ const routes = {
156
+ endpoints: [],
157
+ files: [],
158
+ };
159
+
160
+ const routePatterns = [
161
+ /app\.(get|post|put|delete|patch)\s*\(\s*['"`]([^'"`]+)['"`]/g,
162
+ /router\.(get|post|put|delete|patch)\s*\(\s*['"`]([^'"`]+)['"`]/g,
163
+ ];
164
+
165
+ const files = this.findSourceFiles([".ts", ".js"]);
166
+
167
+ for (const file of files) {
168
+ if (!file.includes("route") && !file.includes("api")) continue;
169
+
170
+ try {
171
+ const content = fs.readFileSync(file, "utf-8");
172
+ const lines = content.split("\n");
173
+ const relativePath = path.relative(this.projectPath, file);
174
+ let hasRoutes = false;
175
+
176
+ lines.forEach((line, idx) => {
177
+ for (const pattern of routePatterns) {
178
+ pattern.lastIndex = 0;
179
+ let match;
180
+ while ((match = pattern.exec(line)) !== null) {
181
+ routes.endpoints.push({
182
+ method: match[1].toUpperCase(),
183
+ path: match[2],
184
+ file: relativePath,
185
+ line: idx + 1
186
+ });
187
+ hasRoutes = true;
188
+ }
189
+ }
190
+ });
191
+
192
+ if (hasRoutes) {
193
+ routes.files.push(relativePath);
194
+ }
195
+ } catch {}
196
+ }
197
+
198
+ return routes;
199
+ }
200
+
201
+ /**
202
+ * Build component graph
203
+ */
204
+ buildComponentGraph() {
205
+ const graph = {
206
+ components: {},
207
+ importedBy: {},
208
+ };
209
+
210
+ const files = this.findSourceFiles([".tsx"]);
211
+
212
+ for (const file of files) {
213
+ try {
214
+ const content = fs.readFileSync(file, "utf-8");
215
+ const relativePath = path.relative(this.projectPath, file);
216
+
217
+ // Find component definitions
218
+ const componentMatch = content.match(/(?:export\s+)?(?:default\s+)?function\s+([A-Z]\w+)/);
219
+ if (componentMatch) {
220
+ const name = componentMatch[1];
221
+ graph.components[name] = {
222
+ file: relativePath,
223
+ imports: [],
224
+ };
225
+
226
+ // Find what this component imports
227
+ const imports = content.matchAll(/import\s+\{([^}]+)\}\s+from\s+['"]([^'"]+)['"]/g);
228
+ for (const imp of imports) {
229
+ const names = imp[1].split(",").map(n => n.trim());
230
+ graph.components[name].imports.push(...names);
231
+
232
+ // Track reverse dependency
233
+ for (const importedName of names) {
234
+ if (!graph.importedBy[importedName]) {
235
+ graph.importedBy[importedName] = [];
236
+ }
237
+ graph.importedBy[importedName].push(name);
238
+ }
239
+ }
240
+ }
241
+ } catch {}
242
+ }
243
+
244
+ return graph;
245
+ }
246
+
247
+ /**
248
+ * Build version truth (installed packages)
249
+ */
250
+ buildVersionTruth() {
251
+ const versions = {
252
+ installed: {},
253
+ devDependencies: {},
254
+ peerDependencies: {},
255
+ };
256
+
257
+ // Check multiple possible package.json locations
258
+ const pkgPaths = [
259
+ path.join(this.projectPath, "package.json"),
260
+ path.join(this.projectPath, "client", "package.json"),
261
+ path.join(this.projectPath, "server", "package.json"),
262
+ ];
263
+
264
+ for (const pkgPath of pkgPaths) {
265
+ if (fs.existsSync(pkgPath)) {
266
+ try {
267
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
268
+ Object.assign(versions.installed, pkg.dependencies || {});
269
+ Object.assign(versions.devDependencies, pkg.devDependencies || {});
270
+ Object.assign(versions.peerDependencies, pkg.peerDependencies || {});
271
+ } catch {}
272
+ }
273
+ }
274
+
275
+ return versions;
276
+ }
277
+
278
+ /**
279
+ * Build security/auth map
280
+ */
281
+ buildSecurityMap() {
282
+ const security = {
283
+ authFiles: [],
284
+ middlewareFiles: [],
285
+ protectedRoutes: [],
286
+ envSecrets: [],
287
+ };
288
+
289
+ const files = this.findSourceFiles([".ts", ".js"]);
290
+
291
+ for (const file of files) {
292
+ const relativePath = path.relative(this.projectPath, file);
293
+ const lowerPath = relativePath.toLowerCase();
294
+
295
+ if (lowerPath.includes("auth") || lowerPath.includes("login") || lowerPath.includes("session")) {
296
+ security.authFiles.push(relativePath);
297
+ }
298
+ if (lowerPath.includes("middleware")) {
299
+ security.middlewareFiles.push(relativePath);
300
+ }
301
+
302
+ try {
303
+ const content = fs.readFileSync(file, "utf-8");
304
+
305
+ // Check for protected route patterns
306
+ if (content.includes("requireAuth") || content.includes("isAuthenticated") || content.includes("protect")) {
307
+ security.protectedRoutes.push(relativePath);
308
+ }
309
+ } catch {}
310
+ }
311
+
312
+ // Check for secret env vars
313
+ const envFiles = [".env", ".env.local", ".env.example"];
314
+ for (const envFile of envFiles) {
315
+ const envPath = path.join(this.projectPath, envFile);
316
+ if (fs.existsSync(envPath)) {
317
+ try {
318
+ const content = fs.readFileSync(envPath, "utf-8");
319
+ const secretPatterns = /^(.*(?:SECRET|KEY|TOKEN|PASSWORD|API_KEY).*)=/gim;
320
+ let match;
321
+ while ((match = secretPatterns.exec(content)) !== null) {
322
+ security.envSecrets.push(match[1].split("=")[0]);
323
+ }
324
+ } catch {}
325
+ }
326
+ }
327
+
328
+ return security;
329
+ }
330
+
331
+ /**
332
+ * Build test obligations
333
+ */
334
+ buildTestObligations() {
335
+ const tests = {
336
+ framework: null,
337
+ testFiles: [],
338
+ setupFiles: [],
339
+ coverageRequired: [],
340
+ };
341
+
342
+ // Detect test framework
343
+ const versions = this.truthPack?.versions?.installed || {};
344
+ if (versions["vitest"]) tests.framework = "vitest";
345
+ else if (versions["jest"]) tests.framework = "jest";
346
+ else if (versions["mocha"]) tests.framework = "mocha";
347
+
348
+ // Find test files
349
+ const files = this.findSourceFiles([".test.ts", ".test.tsx", ".spec.ts", ".spec.tsx", ".test.js", ".spec.js"]);
350
+ tests.testFiles = files.map(f => path.relative(this.projectPath, f));
351
+
352
+ // Find setup files
353
+ const setupPatterns = ["setup", "setupTests", "test-setup", "vitest.setup", "jest.setup"];
354
+ const allFiles = this.findSourceFiles([".ts", ".js"]);
355
+ for (const file of allFiles) {
356
+ const basename = path.basename(file, path.extname(file));
357
+ if (setupPatterns.some(p => basename.includes(p))) {
358
+ tests.setupFiles.push(path.relative(this.projectPath, file));
359
+ }
360
+ }
361
+
362
+ return tests;
363
+ }
364
+
365
+ /**
366
+ * Build golden patterns
367
+ */
368
+ buildGoldenPatterns() {
369
+ const patterns = {};
370
+ const files = this.findSourceFiles([".ts", ".tsx", ".js", ".jsx"]);
371
+
372
+ // Find API route pattern
373
+ for (const file of files) {
374
+ if (!file.includes("route")) continue;
375
+ try {
376
+ const content = fs.readFileSync(file, "utf-8");
377
+ const match = content.match(/router\.(get|post|put|delete)\s*\([^)]+\)\s*(?:async\s*)?\([^)]*\)\s*=>\s*\{[\s\S]{50,400}?\}/);
378
+ if (match && !patterns["api-route"]) {
379
+ patterns["api-route"] = {
380
+ file: path.relative(this.projectPath, file),
381
+ code: match[0].substring(0, 300),
382
+ description: "Standard API route handler pattern"
383
+ };
384
+ }
385
+ } catch {}
386
+ }
387
+
388
+ // Find component pattern
389
+ for (const file of files) {
390
+ if (!file.endsWith(".tsx")) continue;
391
+ try {
392
+ const content = fs.readFileSync(file, "utf-8");
393
+ const match = content.match(/export\s+(?:default\s+)?function\s+([A-Z]\w+)[^{]*\{[\s\S]{50,300}?return\s*\(/);
394
+ if (match && !patterns["component"]) {
395
+ patterns["component"] = {
396
+ file: path.relative(this.projectPath, file),
397
+ code: match[0].substring(0, 250),
398
+ description: "Standard React component pattern"
399
+ };
400
+ }
401
+ } catch {}
402
+ }
403
+
404
+ // Find hook pattern
405
+ for (const file of files) {
406
+ if (!file.includes("hook")) continue;
407
+ try {
408
+ const content = fs.readFileSync(file, "utf-8");
409
+ const match = content.match(/export\s+function\s+(use\w+)[^{]*\{[\s\S]{50,300}?\}/);
410
+ if (match && !patterns["hook"]) {
411
+ patterns["hook"] = {
412
+ file: path.relative(this.projectPath, file),
413
+ code: match[0].substring(0, 250),
414
+ description: "Standard custom hook pattern"
415
+ };
416
+ }
417
+ } catch {}
418
+ }
419
+
420
+ return patterns;
421
+ }
422
+
423
+ /**
424
+ * Build risk map
425
+ */
426
+ buildRiskMap() {
427
+ const riskMap = {
428
+ critical: [],
429
+ high: [],
430
+ medium: [],
431
+ };
432
+
433
+ const files = this.findSourceFiles([".ts", ".tsx", ".js", ".jsx"]);
434
+
435
+ for (const file of files) {
436
+ const relativePath = path.relative(this.projectPath, file);
437
+ const lowerPath = relativePath.toLowerCase();
438
+
439
+ // Critical: auth, schema, config
440
+ if (lowerPath.includes("schema") || lowerPath.includes("auth") ||
441
+ lowerPath.includes("config") || lowerPath.includes("middleware")) {
442
+ riskMap.critical.push(relativePath);
443
+ }
444
+ // High: routes, api, payments
445
+ else if (lowerPath.includes("route") || lowerPath.includes("api") ||
446
+ lowerPath.includes("payment") || lowerPath.includes("billing")) {
447
+ riskMap.high.push(relativePath);
448
+ }
449
+ // Medium: components, hooks
450
+ else if (lowerPath.includes("component") || lowerPath.includes("hook")) {
451
+ riskMap.medium.push(relativePath);
452
+ }
453
+ }
454
+
455
+ return riskMap;
456
+ }
457
+
458
+ /**
459
+ * Find source files
460
+ */
461
+ findSourceFiles(extensions, maxDepth = 5) {
462
+ const results = [];
463
+
464
+ const walk = (dir, depth = 0) => {
465
+ if (depth >= maxDepth) return;
466
+
467
+ try {
468
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
469
+ for (const entry of entries) {
470
+ if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist") {
471
+ continue;
472
+ }
473
+
474
+ const fullPath = path.join(dir, entry.name);
475
+ if (entry.isDirectory()) {
476
+ walk(fullPath, depth + 1);
477
+ } else if (extensions.some(ext => entry.name.endsWith(ext))) {
478
+ results.push(fullPath);
479
+ }
480
+ }
481
+ } catch {}
482
+ };
483
+
484
+ walk(this.projectPath);
485
+ return results;
486
+ }
487
+
488
+ /**
489
+ * Load existing truth pack
490
+ */
491
+ loadTruthPack() {
492
+ const packPath = path.join(this.projectPath, ".vibecheck", "truth-pack.json");
493
+ if (fs.existsSync(packPath)) {
494
+ try {
495
+ this.truthPack = JSON.parse(fs.readFileSync(packPath, "utf-8"));
496
+ this.indexed = true;
497
+ return true;
498
+ } catch {}
499
+ }
500
+ return false;
501
+ }
502
+
503
+ // ========== MCP TOOL IMPLEMENTATIONS ==========
504
+
505
+ /**
506
+ * repo.map() - Get project architecture and boundaries
507
+ */
508
+ repoMap() {
509
+ if (!this.truthPack) this.loadTruthPack();
510
+ if (!this.truthPack) return { error: "Not indexed. Run 'index' first." };
511
+
512
+ return {
513
+ projectPath: this.projectPath,
514
+ indexedAt: this.truthPack.indexedAt,
515
+ stats: {
516
+ symbols: Object.keys(this.truthPack.symbols.exports).length,
517
+ routes: this.truthPack.routes.endpoints.length,
518
+ components: this.truthPack.symbols.components.length,
519
+ packages: Object.keys(this.truthPack.versions.installed).length,
520
+ },
521
+ boundaries: {
522
+ routeFiles: this.truthPack.routes.files,
523
+ authFiles: this.truthPack.security.authFiles,
524
+ middlewareFiles: this.truthPack.security.middlewareFiles,
525
+ },
526
+ riskMap: this.truthPack.riskMap,
527
+ };
528
+ }
529
+
530
+ /**
531
+ * symbols.exists(name) - Check if a symbol exists
532
+ */
533
+ symbolsExists(name) {
534
+ if (!this.truthPack) this.loadTruthPack();
535
+ if (!this.truthPack) return { error: "Not indexed" };
536
+
537
+ const symbol = this.truthPack.symbols.exports[name];
538
+ if (symbol) {
539
+ return {
540
+ exists: true,
541
+ name,
542
+ file: symbol.file,
543
+ line: symbol.line,
544
+ type: symbol.type,
545
+ proof: `${symbol.file}:${symbol.line}`
546
+ };
547
+ }
548
+
549
+ return {
550
+ exists: false,
551
+ name,
552
+ suggestion: "Symbol not found. Do not invent it."
553
+ };
554
+ }
555
+
556
+ /**
557
+ * versions.allowed(package) - Check if package is installed
558
+ */
559
+ versionsAllowed(packageName) {
560
+ if (!this.truthPack) this.loadTruthPack();
561
+ if (!this.truthPack) return { error: "Not indexed" };
562
+
563
+ const version = this.truthPack.versions.installed[packageName] ||
564
+ this.truthPack.versions.devDependencies[packageName];
565
+
566
+ if (version) {
567
+ return {
568
+ allowed: true,
569
+ package: packageName,
570
+ version,
571
+ proof: "package.json"
572
+ };
573
+ }
574
+
575
+ return {
576
+ allowed: false,
577
+ package: packageName,
578
+ suggestion: "Package not installed. Do not suggest using it."
579
+ };
580
+ }
581
+
582
+ /**
583
+ * routes.exists(method, path) - Check if route exists
584
+ */
585
+ routesExists(method, routePath) {
586
+ if (!this.truthPack) this.loadTruthPack();
587
+ if (!this.truthPack) return { error: "Not indexed" };
588
+
589
+ const route = this.truthPack.routes.endpoints.find(
590
+ r => r.method === method.toUpperCase() && r.path === routePath
591
+ );
592
+
593
+ if (route) {
594
+ return {
595
+ exists: true,
596
+ method: route.method,
597
+ path: route.path,
598
+ file: route.file,
599
+ line: route.line,
600
+ proof: `${route.file}:${route.line}`
601
+ };
602
+ }
603
+
604
+ return {
605
+ exists: false,
606
+ method,
607
+ path: routePath,
608
+ suggestion: "Route not found. Do not invent it."
609
+ };
610
+ }
611
+
612
+ /**
613
+ * patterns.get(type) - Get golden pattern
614
+ */
615
+ patternsGet(type) {
616
+ if (!this.truthPack) this.loadTruthPack();
617
+ if (!this.truthPack) return { error: "Not indexed" };
618
+
619
+ const pattern = this.truthPack.patterns[type];
620
+ if (pattern) {
621
+ return {
622
+ found: true,
623
+ type,
624
+ file: pattern.file,
625
+ description: pattern.description,
626
+ code: pattern.code
627
+ };
628
+ }
629
+
630
+ return {
631
+ found: false,
632
+ type,
633
+ available: Object.keys(this.truthPack.patterns)
634
+ };
635
+ }
636
+
637
+ /**
638
+ * security.authFlow() - Get auth flow info
639
+ */
640
+ securityAuthFlow() {
641
+ if (!this.truthPack) this.loadTruthPack();
642
+ if (!this.truthPack) return { error: "Not indexed" };
643
+
644
+ return {
645
+ authFiles: this.truthPack.security.authFiles,
646
+ middlewareFiles: this.truthPack.security.middlewareFiles,
647
+ protectedRoutes: this.truthPack.security.protectedRoutes,
648
+ envSecrets: this.truthPack.security.envSecrets,
649
+ warning: "Do not bypass auth without explicit approval"
650
+ };
651
+ }
652
+
653
+ /**
654
+ * tests.required(files) - Get required tests for changed files
655
+ */
656
+ testsRequired(changedFiles) {
657
+ if (!this.truthPack) this.loadTruthPack();
658
+ if (!this.truthPack) return { error: "Not indexed" };
659
+
660
+ const required = [];
661
+
662
+ for (const file of changedFiles) {
663
+ // Find corresponding test file
664
+ const baseName = path.basename(file, path.extname(file));
665
+ const testFile = this.truthPack.tests.testFiles.find(
666
+ t => t.includes(baseName) && (t.includes(".test.") || t.includes(".spec."))
667
+ );
668
+
669
+ if (testFile) {
670
+ required.push({
671
+ sourceFile: file,
672
+ testFile,
673
+ mustRun: true
674
+ });
675
+ } else {
676
+ required.push({
677
+ sourceFile: file,
678
+ testFile: null,
679
+ mustRun: false,
680
+ warning: "No test file found - consider adding tests"
681
+ });
682
+ }
683
+ }
684
+
685
+ return {
686
+ framework: this.truthPack.tests.framework,
687
+ required,
688
+ setupFiles: this.truthPack.tests.setupFiles
689
+ };
690
+ }
691
+
692
+ /**
693
+ * risk.blastRadius(files) - Compute blast radius for changes
694
+ */
695
+ riskBlastRadius(files) {
696
+ if (!this.truthPack) this.loadTruthPack();
697
+ if (!this.truthPack) return { error: "Not indexed" };
698
+
699
+ const analysis = {
700
+ files: [],
701
+ overallRisk: "low",
702
+ warnings: [],
703
+ requiresApproval: false
704
+ };
705
+
706
+ for (const file of files) {
707
+ let risk = "low";
708
+
709
+ if (this.truthPack.riskMap.critical.some(f => file.includes(f) || f.includes(file))) {
710
+ risk = "critical";
711
+ analysis.warnings.push(`CRITICAL: ${file} is a critical file`);
712
+ analysis.requiresApproval = true;
713
+ } else if (this.truthPack.riskMap.high.some(f => file.includes(f) || f.includes(file))) {
714
+ risk = "high";
715
+ analysis.warnings.push(`HIGH: ${file} is a high-risk file`);
716
+ } else if (this.truthPack.riskMap.medium.some(f => file.includes(f) || f.includes(file))) {
717
+ risk = "medium";
718
+ }
719
+
720
+ // Check if file is imported by many others
721
+ const importedBy = this.truthPack.components.importedBy || {};
722
+ const baseName = path.basename(file, path.extname(file));
723
+ if (importedBy[baseName]?.length > 5) {
724
+ analysis.warnings.push(`HIGH IMPACT: ${file} is imported by ${importedBy[baseName].length} files`);
725
+ risk = risk === "low" ? "medium" : risk;
726
+ }
727
+
728
+ analysis.files.push({ file, risk });
729
+ }
730
+
731
+ // Overall risk
732
+ if (analysis.files.some(f => f.risk === "critical")) {
733
+ analysis.overallRisk = "critical";
734
+ } else if (analysis.files.some(f => f.risk === "high")) {
735
+ analysis.overallRisk = "high";
736
+ } else if (analysis.files.some(f => f.risk === "medium")) {
737
+ analysis.overallRisk = "medium";
738
+ }
739
+
740
+ return analysis;
741
+ }
742
+
743
+ /**
744
+ * graph.related(file) - Get related files
745
+ */
746
+ graphRelated(file) {
747
+ if (!this.truthPack) this.loadTruthPack();
748
+ if (!this.truthPack) return { error: "Not indexed" };
749
+
750
+ const related = {
751
+ imports: [],
752
+ importedBy: [],
753
+ sameDirectory: [],
754
+ };
755
+
756
+ const baseName = path.basename(file, path.extname(file));
757
+ const dirName = path.dirname(file);
758
+
759
+ // Find what this file imports (from component graph)
760
+ const component = Object.entries(this.truthPack.components.components || {})
761
+ .find(([name, data]) => data.file.includes(baseName));
762
+
763
+ if (component) {
764
+ related.imports = component[1].imports;
765
+ }
766
+
767
+ // Find what imports this file
768
+ related.importedBy = this.truthPack.components.importedBy[baseName] || [];
769
+
770
+ // Find files in same directory
771
+ const allExports = Object.values(this.truthPack.symbols.exports);
772
+ related.sameDirectory = allExports
773
+ .filter(exp => exp.file.includes(dirName) && !exp.file.includes(baseName))
774
+ .map(exp => exp.file)
775
+ .filter((v, i, a) => a.indexOf(v) === i)
776
+ .slice(0, 10);
777
+
778
+ return related;
779
+ }
780
+
781
+ // ========== VERIFICATION GATES ==========
782
+
783
+ /**
784
+ * Verify a proposed change
785
+ */
786
+ verify(changes) {
787
+ const results = {
788
+ passed: true,
789
+ checks: [],
790
+ };
791
+
792
+ // Symbol reality check
793
+ for (const change of changes.newSymbols || []) {
794
+ const exists = this.symbolsExists(change);
795
+ if (!exists.exists) {
796
+ results.passed = false;
797
+ results.checks.push({
798
+ type: "symbol_reality",
799
+ passed: false,
800
+ message: `Symbol "${change}" does not exist`
801
+ });
802
+ }
803
+ }
804
+
805
+ // Version check
806
+ for (const pkg of changes.newPackages || []) {
807
+ const allowed = this.versionsAllowed(pkg);
808
+ if (!allowed.allowed) {
809
+ results.passed = false;
810
+ results.checks.push({
811
+ type: "version_constraint",
812
+ passed: false,
813
+ message: `Package "${pkg}" is not installed`
814
+ });
815
+ }
816
+ }
817
+
818
+ // Blast radius check
819
+ if (changes.files?.length > 0) {
820
+ const blast = this.riskBlastRadius(changes.files);
821
+ if (blast.requiresApproval) {
822
+ results.checks.push({
823
+ type: "blast_radius",
824
+ passed: false,
825
+ message: "Changes touch critical files - requires approval",
826
+ warnings: blast.warnings
827
+ });
828
+ }
829
+ }
830
+
831
+ return results;
832
+ }
833
+ }
834
+
835
+ // ========== MCP SERVER ==========
836
+
837
+ class MCPServer {
838
+ constructor(engine) {
839
+ this.engine = engine;
840
+ this.tools = this.defineMCPTools();
841
+ }
842
+
843
+ defineMCPTools() {
844
+ return [
845
+ {
846
+ name: "repo_map",
847
+ description: "Get project architecture, boundaries, and risk map. Call this FIRST before planning any changes.",
848
+ inputSchema: {
849
+ type: "object",
850
+ properties: {},
851
+ required: []
852
+ }
853
+ },
854
+ {
855
+ name: "symbols_exists",
856
+ description: "Check if a symbol (function, class, component, hook) exists in the codebase. MUST call before using any symbol.",
857
+ inputSchema: {
858
+ type: "object",
859
+ properties: {
860
+ name: { type: "string", description: "The symbol name to check" }
861
+ },
862
+ required: ["name"]
863
+ }
864
+ },
865
+ {
866
+ name: "versions_allowed",
867
+ description: "Check if a package is installed and get its version. MUST call before suggesting any package usage.",
868
+ inputSchema: {
869
+ type: "object",
870
+ properties: {
871
+ package: { type: "string", description: "The package name to check" }
872
+ },
873
+ required: ["package"]
874
+ }
875
+ },
876
+ {
877
+ name: "routes_exists",
878
+ description: "Check if an API route exists. MUST call before claiming any endpoint exists.",
879
+ inputSchema: {
880
+ type: "object",
881
+ properties: {
882
+ method: { type: "string", description: "HTTP method (GET, POST, etc.)" },
883
+ path: { type: "string", description: "Route path" }
884
+ },
885
+ required: ["method", "path"]
886
+ }
887
+ },
888
+ {
889
+ name: "patterns_get",
890
+ description: "Get a golden pattern (verified code example) for a given type. Call when creating new code.",
891
+ inputSchema: {
892
+ type: "object",
893
+ properties: {
894
+ type: { type: "string", description: "Pattern type: api-route, component, hook" }
895
+ },
896
+ required: ["type"]
897
+ }
898
+ },
899
+ {
900
+ name: "security_auth_flow",
901
+ description: "Get authentication flow info: auth files, middleware, protected routes. Call before touching auth.",
902
+ inputSchema: {
903
+ type: "object",
904
+ properties: {},
905
+ required: []
906
+ }
907
+ },
908
+ {
909
+ name: "tests_required",
910
+ description: "Get required tests for a list of changed files.",
911
+ inputSchema: {
912
+ type: "object",
913
+ properties: {
914
+ files: { type: "array", items: { type: "string" }, description: "Files being changed" }
915
+ },
916
+ required: ["files"]
917
+ }
918
+ },
919
+ {
920
+ name: "risk_blast_radius",
921
+ description: "Compute blast radius and risk level for proposed changes. Call before making changes.",
922
+ inputSchema: {
923
+ type: "object",
924
+ properties: {
925
+ files: { type: "array", items: { type: "string" }, description: "Files to analyze" }
926
+ },
927
+ required: ["files"]
928
+ }
929
+ },
930
+ {
931
+ name: "graph_related",
932
+ description: "Get files related to a given file (imports, importers, same directory).",
933
+ inputSchema: {
934
+ type: "object",
935
+ properties: {
936
+ file: { type: "string", description: "File path to analyze" }
937
+ },
938
+ required: ["file"]
939
+ }
940
+ },
941
+ {
942
+ name: "verify_changes",
943
+ description: "Verify proposed changes against reality checks (symbols, versions, blast radius).",
944
+ inputSchema: {
945
+ type: "object",
946
+ properties: {
947
+ newSymbols: { type: "array", items: { type: "string" }, description: "New symbols being used" },
948
+ newPackages: { type: "array", items: { type: "string" }, description: "New packages being used" },
949
+ files: { type: "array", items: { type: "string" }, description: "Files being changed" }
950
+ },
951
+ required: []
952
+ }
953
+ }
954
+ ];
955
+ }
956
+
957
+ handleToolCall(toolName, args) {
958
+ switch (toolName) {
959
+ case "repo_map":
960
+ return this.engine.repoMap();
961
+ case "symbols_exists":
962
+ return this.engine.symbolsExists(args.name);
963
+ case "versions_allowed":
964
+ return this.engine.versionsAllowed(args.package);
965
+ case "routes_exists":
966
+ return this.engine.routesExists(args.method, args.path);
967
+ case "patterns_get":
968
+ return this.engine.patternsGet(args.type);
969
+ case "security_auth_flow":
970
+ return this.engine.securityAuthFlow();
971
+ case "tests_required":
972
+ return this.engine.testsRequired(args.files || []);
973
+ case "risk_blast_radius":
974
+ return this.engine.riskBlastRadius(args.files || []);
975
+ case "graph_related":
976
+ return this.engine.graphRelated(args.file);
977
+ case "verify_changes":
978
+ return this.engine.verify(args);
979
+ default:
980
+ return { error: `Unknown tool: ${toolName}` };
981
+ }
982
+ }
983
+
984
+ /**
985
+ * Start MCP server (stdio mode for Cursor)
986
+ */
987
+ startStdio() {
988
+ const readline = require("readline");
989
+ const rl = readline.createInterface({
990
+ input: process.stdin,
991
+ output: process.stdout,
992
+ terminal: false
993
+ });
994
+
995
+ rl.on("line", (line) => {
996
+ try {
997
+ const request = JSON.parse(line);
998
+ const response = this.handleMCPRequest(request);
999
+ console.log(JSON.stringify(response));
1000
+ } catch (err) {
1001
+ console.log(JSON.stringify({ error: err.message }));
1002
+ }
1003
+ });
1004
+
1005
+ // Send server info
1006
+ console.error("vibecheck Context Engine MCP Server started");
1007
+ }
1008
+
1009
+ /**
1010
+ * Start HTTP server (for debugging/testing)
1011
+ */
1012
+ startHttp(port = 3847) {
1013
+ const server = http.createServer((req, res) => {
1014
+ if (req.method === "POST") {
1015
+ let body = "";
1016
+ req.on("data", chunk => body += chunk);
1017
+ req.on("end", () => {
1018
+ try {
1019
+ const request = JSON.parse(body);
1020
+ const response = this.handleMCPRequest(request);
1021
+ res.writeHead(200, { "Content-Type": "application/json" });
1022
+ res.end(JSON.stringify(response, null, 2));
1023
+ } catch (err) {
1024
+ res.writeHead(400, { "Content-Type": "application/json" });
1025
+ res.end(JSON.stringify({ error: err.message }));
1026
+ }
1027
+ });
1028
+ } else if (req.method === "GET" && req.url === "/tools") {
1029
+ res.writeHead(200, { "Content-Type": "application/json" });
1030
+ res.end(JSON.stringify({ tools: this.tools }, null, 2));
1031
+ } else {
1032
+ res.writeHead(200, { "Content-Type": "application/json" });
1033
+ res.end(JSON.stringify({ status: "ok", tools: this.tools.map(t => t.name) }));
1034
+ }
1035
+ });
1036
+
1037
+ server.listen(port, () => {
1038
+ console.log(`🚀 Context Engine HTTP server running on http://localhost:${port}`);
1039
+ console.log(` Tools: ${this.tools.map(t => t.name).join(", ")}`);
1040
+ });
1041
+
1042
+ return server;
1043
+ }
1044
+
1045
+ handleMCPRequest(request) {
1046
+ const { method, params, id } = request;
1047
+
1048
+ switch (method) {
1049
+ case "initialize":
1050
+ return {
1051
+ jsonrpc: "2.0",
1052
+ id,
1053
+ result: {
1054
+ protocolVersion: MCP_VERSION,
1055
+ serverInfo: {
1056
+ name: "vibecheck-context",
1057
+ version: "1.0.0"
1058
+ },
1059
+ capabilities: {
1060
+ tools: {}
1061
+ }
1062
+ }
1063
+ };
1064
+
1065
+ case "tools/list":
1066
+ return {
1067
+ jsonrpc: "2.0",
1068
+ id,
1069
+ result: { tools: this.tools }
1070
+ };
1071
+
1072
+ case "tools/call":
1073
+ const { name, arguments: args } = params;
1074
+ const result = this.handleToolCall(name, args || {});
1075
+ return {
1076
+ jsonrpc: "2.0",
1077
+ id,
1078
+ result: { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] }
1079
+ };
1080
+
1081
+ default:
1082
+ return {
1083
+ jsonrpc: "2.0",
1084
+ id,
1085
+ error: { code: -32601, message: `Method not found: ${method}` }
1086
+ };
1087
+ }
1088
+ }
1089
+ }
1090
+
1091
+ // ========== CLI ==========
1092
+
1093
+ async function main() {
1094
+ const args = process.argv.slice(2);
1095
+ const command = args[0];
1096
+ const projectPath = args.find(a => a.startsWith("--path="))?.split("=")[1] || process.cwd();
1097
+
1098
+ const engine = new ContextEngine(projectPath);
1099
+
1100
+ switch (command) {
1101
+ case "index":
1102
+ await engine.index();
1103
+ break;
1104
+
1105
+ case "serve":
1106
+ const mode = args.includes("--http") ? "http" : "stdio";
1107
+ const port = parseInt(args.find(a => a.startsWith("--port="))?.split("=")[1] || "3847");
1108
+
1109
+ // Load or build index first
1110
+ if (!engine.loadTruthPack()) {
1111
+ console.log("No truth pack found, indexing first...");
1112
+ await engine.index();
1113
+ }
1114
+
1115
+ const server = new MCPServer(engine);
1116
+ if (mode === "http") {
1117
+ server.startHttp(port);
1118
+ } else {
1119
+ server.startStdio();
1120
+ }
1121
+ break;
1122
+
1123
+ case "verify":
1124
+ if (!engine.loadTruthPack()) {
1125
+ console.error("Not indexed. Run 'index' first.");
1126
+ process.exit(1);
1127
+ }
1128
+ // Read changes from stdin or args
1129
+ const changes = JSON.parse(args[1] || "{}");
1130
+ const result = engine.verify(changes);
1131
+ console.log(JSON.stringify(result, null, 2));
1132
+ break;
1133
+
1134
+ case "query":
1135
+ // Quick query mode for testing
1136
+ if (!engine.loadTruthPack()) {
1137
+ console.error("Not indexed. Run 'index' first.");
1138
+ process.exit(1);
1139
+ }
1140
+ const tool = args[1];
1141
+ const toolArgs = JSON.parse(args[2] || "{}");
1142
+ const mcpServer = new MCPServer(engine);
1143
+ const queryResult = mcpServer.handleToolCall(tool, toolArgs);
1144
+ console.log(JSON.stringify(queryResult, null, 2));
1145
+ break;
1146
+
1147
+ default:
1148
+ console.log(`
1149
+ vibecheck Context Engine - MCP Server
1150
+
1151
+ Usage:
1152
+ node index.js index [--path=<project>] Build truth pack
1153
+ node index.js serve [--http] [--port=3847] Start MCP server
1154
+ node index.js verify <changes-json> Verify proposed changes
1155
+ node index.js query <tool> [args-json] Query a tool directly
1156
+
1157
+ Tools:
1158
+ repo_map - Get project architecture
1159
+ symbols_exists - Check if symbol exists
1160
+ versions_allowed - Check if package is installed
1161
+ routes_exists - Check if route exists
1162
+ patterns_get - Get golden pattern
1163
+ security_auth_flow - Get auth flow info
1164
+ tests_required - Get required tests
1165
+ risk_blast_radius - Compute blast radius
1166
+ graph_related - Get related files
1167
+ verify_changes - Verify proposed changes
1168
+ `);
1169
+ }
1170
+ }
1171
+
1172
+ module.exports = { ContextEngine, MCPServer };
1173
+
1174
+ if (require.main === module) {
1175
+ main().catch(console.error);
1176
+ }