@vibecheckai/cli 3.5.1 → 3.5.2

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 (272) hide show
  1. package/bin/registry.js +406 -154
  2. package/bin/runners/context/analyzer.js +52 -1
  3. package/bin/runners/context/generators/mcp.js +15 -13
  4. package/bin/runners/context/git-context.js +3 -1
  5. package/bin/runners/context/proof-context.js +248 -1
  6. package/bin/runners/context/team-conventions.js +33 -7
  7. package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +474 -0
  8. package/bin/runners/lib/agent-firewall/change-packet/builder.js +488 -0
  9. package/bin/runners/lib/agent-firewall/change-packet/schema.json +228 -0
  10. package/bin/runners/lib/agent-firewall/change-packet/store.js +200 -0
  11. package/bin/runners/lib/agent-firewall/claims/claim-types.js +21 -0
  12. package/bin/runners/lib/agent-firewall/claims/extractor.js +303 -0
  13. package/bin/runners/lib/agent-firewall/claims/patterns.js +24 -0
  14. package/bin/runners/lib/agent-firewall/critic/index.js +151 -0
  15. package/bin/runners/lib/agent-firewall/critic/judge.js +432 -0
  16. package/bin/runners/lib/agent-firewall/critic/prompts.js +305 -0
  17. package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +88 -0
  18. package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +75 -0
  19. package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +127 -0
  20. package/bin/runners/lib/agent-firewall/evidence/resolver.js +102 -0
  21. package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +213 -0
  22. package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +145 -0
  23. package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +19 -0
  24. package/bin/runners/lib/agent-firewall/fs-hook/installer.js +87 -0
  25. package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +184 -0
  26. package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +163 -0
  27. package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +107 -0
  28. package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +68 -0
  29. package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +66 -0
  30. package/bin/runners/lib/agent-firewall/interceptor/base.js +304 -0
  31. package/bin/runners/lib/agent-firewall/interceptor/cursor.js +35 -0
  32. package/bin/runners/lib/agent-firewall/interceptor/vscode.js +35 -0
  33. package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +34 -0
  34. package/bin/runners/lib/agent-firewall/lawbook/distributor.js +465 -0
  35. package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +604 -0
  36. package/bin/runners/lib/agent-firewall/lawbook/index.js +304 -0
  37. package/bin/runners/lib/agent-firewall/lawbook/registry.js +514 -0
  38. package/bin/runners/lib/agent-firewall/lawbook/schema.js +420 -0
  39. package/bin/runners/lib/agent-firewall/logger.js +141 -0
  40. package/bin/runners/lib/agent-firewall/policy/default-policy.json +90 -0
  41. package/bin/runners/lib/agent-firewall/policy/engine.js +103 -0
  42. package/bin/runners/lib/agent-firewall/policy/loader.js +451 -0
  43. package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +50 -0
  44. package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +50 -0
  45. package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +86 -0
  46. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +162 -0
  47. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +189 -0
  48. package/bin/runners/lib/agent-firewall/policy/rules/scope.js +93 -0
  49. package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +57 -0
  50. package/bin/runners/lib/agent-firewall/policy/schema.json +183 -0
  51. package/bin/runners/lib/agent-firewall/policy/verdict.js +54 -0
  52. package/bin/runners/lib/agent-firewall/proposal/extractor.js +394 -0
  53. package/bin/runners/lib/agent-firewall/proposal/index.js +212 -0
  54. package/bin/runners/lib/agent-firewall/proposal/schema.js +251 -0
  55. package/bin/runners/lib/agent-firewall/proposal/validator.js +386 -0
  56. package/bin/runners/lib/agent-firewall/reality/index.js +332 -0
  57. package/bin/runners/lib/agent-firewall/reality/state.js +625 -0
  58. package/bin/runners/lib/agent-firewall/reality/watcher.js +322 -0
  59. package/bin/runners/lib/agent-firewall/risk/index.js +173 -0
  60. package/bin/runners/lib/agent-firewall/risk/scorer.js +328 -0
  61. package/bin/runners/lib/agent-firewall/risk/thresholds.js +321 -0
  62. package/bin/runners/lib/agent-firewall/risk/vectors.js +421 -0
  63. package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +472 -0
  64. package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +346 -0
  65. package/bin/runners/lib/agent-firewall/simulator/index.js +181 -0
  66. package/bin/runners/lib/agent-firewall/simulator/route-validator.js +380 -0
  67. package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +661 -0
  68. package/bin/runners/lib/agent-firewall/time-machine/index.js +267 -0
  69. package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +436 -0
  70. package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +490 -0
  71. package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +530 -0
  72. package/bin/runners/lib/agent-firewall/truthpack/index.js +67 -0
  73. package/bin/runners/lib/agent-firewall/truthpack/loader.js +137 -0
  74. package/bin/runners/lib/agent-firewall/unblock/planner.js +337 -0
  75. package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +118 -0
  76. package/bin/runners/lib/analysis-core.js +220 -182
  77. package/bin/runners/lib/analyzers.js +2145 -224
  78. package/bin/runners/lib/api-client.js +269 -0
  79. package/bin/runners/lib/authority-badge.js +425 -0
  80. package/bin/runners/lib/cli-output.js +242 -210
  81. package/bin/runners/lib/default-config.js +127 -0
  82. package/bin/runners/lib/detectors-v2.js +547 -785
  83. package/bin/runners/lib/doctor/modules/security.js +3 -1
  84. package/bin/runners/lib/engine/ast-cache.js +210 -0
  85. package/bin/runners/lib/engine/auth-extractor.js +211 -0
  86. package/bin/runners/lib/engine/billing-extractor.js +112 -0
  87. package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
  88. package/bin/runners/lib/engine/env-extractor.js +207 -0
  89. package/bin/runners/lib/engine/express-extractor.js +208 -0
  90. package/bin/runners/lib/engine/extractors.js +849 -0
  91. package/bin/runners/lib/engine/index.js +207 -0
  92. package/bin/runners/lib/engine/repo-index.js +514 -0
  93. package/bin/runners/lib/engine/types.js +124 -0
  94. package/bin/runners/lib/engines/accessibility-engine.js +190 -0
  95. package/bin/runners/lib/engines/api-consistency-engine.js +162 -0
  96. package/bin/runners/lib/engines/ast-cache.js +99 -0
  97. package/bin/runners/lib/engines/code-quality-engine.js +255 -0
  98. package/bin/runners/lib/engines/console-logs-engine.js +115 -0
  99. package/bin/runners/lib/engines/cross-file-analysis-engine.js +268 -0
  100. package/bin/runners/lib/engines/dead-code-engine.js +198 -0
  101. package/bin/runners/lib/engines/deprecated-api-engine.js +226 -0
  102. package/bin/runners/lib/engines/empty-catch-engine.js +150 -0
  103. package/bin/runners/lib/engines/file-filter.js +131 -0
  104. package/bin/runners/lib/engines/hardcoded-secrets-engine.js +251 -0
  105. package/bin/runners/lib/engines/mock-data-engine.js +272 -0
  106. package/bin/runners/lib/engines/parallel-processor.js +71 -0
  107. package/bin/runners/lib/engines/performance-issues-engine.js +265 -0
  108. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +243 -0
  109. package/bin/runners/lib/engines/todo-fixme-engine.js +115 -0
  110. package/bin/runners/lib/engines/type-aware-engine.js +152 -0
  111. package/bin/runners/lib/engines/unsafe-regex-engine.js +225 -0
  112. package/bin/runners/lib/engines/vibecheck-engines/README.md +53 -0
  113. package/bin/runners/lib/engines/vibecheck-engines/index.js +15 -0
  114. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
  115. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
  116. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
  117. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
  118. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
  119. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
  120. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
  121. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +139 -0
  122. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
  123. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
  124. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
  125. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
  126. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
  127. package/bin/runners/lib/engines/vibecheck-engines/package.json +13 -0
  128. package/bin/runners/lib/entitlements-v2.js +152 -446
  129. package/bin/runners/lib/error-handler.js +60 -12
  130. package/bin/runners/lib/error-messages.js +289 -0
  131. package/bin/runners/lib/evidence-pack.js +7 -1
  132. package/bin/runners/lib/exit-codes.js +275 -0
  133. package/bin/runners/lib/finding-id.js +69 -0
  134. package/bin/runners/lib/finding-sorter.js +89 -0
  135. package/bin/runners/lib/fingerprint.js +377 -0
  136. package/bin/runners/lib/global-flags.js +37 -0
  137. package/bin/runners/lib/help-formatter.js +413 -0
  138. package/bin/runners/lib/logger.js +38 -0
  139. package/bin/runners/lib/next-action.js +560 -0
  140. package/bin/runners/lib/prerequisites.js +149 -0
  141. package/bin/runners/lib/route-detection.js +137 -68
  142. package/bin/runners/lib/route-truth.js +1167 -322
  143. package/bin/runners/lib/scan-output.js +504 -463
  144. package/bin/runners/lib/scan-runner.js +135 -0
  145. package/bin/runners/lib/schemas/ajv-validator.js +464 -0
  146. package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
  147. package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
  148. package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
  149. package/bin/runners/lib/schemas/run-request.schema.json +108 -0
  150. package/bin/runners/lib/schemas/validator.js +27 -0
  151. package/bin/runners/lib/schemas/verdict.schema.json +140 -0
  152. package/bin/runners/lib/ship-output-enterprise.js +239 -0
  153. package/bin/runners/lib/ship-output.js +328 -31
  154. package/bin/runners/lib/terminal-ui.js +234 -731
  155. package/bin/runners/lib/truth.js +1332 -308
  156. package/bin/runners/lib/unified-cli-output.js +604 -0
  157. package/bin/runners/lib/unified-output.js +163 -155
  158. package/bin/runners/lib/upsell.js +104 -204
  159. package/bin/runners/runAgent.d.ts +5 -0
  160. package/bin/runners/runAgent.js +161 -0
  161. package/bin/runners/runAllowlist.js +166 -101
  162. package/bin/runners/runApprove.js +1200 -0
  163. package/bin/runners/runAuth.js +373 -95
  164. package/bin/runners/runCheckpoint.js +59 -21
  165. package/bin/runners/runClassify.js +926 -0
  166. package/bin/runners/runContext.d.ts +4 -0
  167. package/bin/runners/runContext.js +136 -24
  168. package/bin/runners/runDoctor.js +115 -67
  169. package/bin/runners/runEvidencePack.js +239 -96
  170. package/bin/runners/runFirewall.d.ts +5 -0
  171. package/bin/runners/runFirewall.js +134 -0
  172. package/bin/runners/runFirewallHook.d.ts +5 -0
  173. package/bin/runners/runFirewallHook.js +56 -0
  174. package/bin/runners/runFix.js +6 -5
  175. package/bin/runners/runGuard.js +212 -118
  176. package/bin/runners/runInit.js +66 -21
  177. package/bin/runners/runLabs.js +204 -121
  178. package/bin/runners/runMcp.js +131 -60
  179. package/bin/runners/runPolish.d.ts +4 -0
  180. package/bin/runners/runPolish.js +43 -20
  181. package/bin/runners/runProof.zip +0 -0
  182. package/bin/runners/runProve.js +15 -5
  183. package/bin/runners/runQuickstart.js +531 -0
  184. package/bin/runners/runReality.js +14 -0
  185. package/bin/runners/runReport.js +36 -4
  186. package/bin/runners/runScan.js +689 -91
  187. package/bin/runners/runShip.js +96 -40
  188. package/bin/runners/runTruth.d.ts +5 -0
  189. package/bin/runners/runTruth.js +101 -0
  190. package/bin/runners/runValidate.js +21 -4
  191. package/bin/runners/runWatch.js +118 -54
  192. package/bin/scan.js +6 -1
  193. package/bin/vibecheck.js +297 -52
  194. package/mcp-server/HARDENING_SUMMARY.md +299 -0
  195. package/mcp-server/agent-firewall-interceptor.js +500 -0
  196. package/mcp-server/authority-tools.js +569 -0
  197. package/mcp-server/conductor/conflict-resolver.js +588 -0
  198. package/mcp-server/conductor/execution-planner.js +544 -0
  199. package/mcp-server/conductor/index.js +377 -0
  200. package/mcp-server/conductor/lock-manager.js +615 -0
  201. package/mcp-server/conductor/request-queue.js +550 -0
  202. package/mcp-server/conductor/session-manager.js +500 -0
  203. package/mcp-server/conductor/tools.js +510 -0
  204. package/mcp-server/deprecation-middleware.js +282 -0
  205. package/mcp-server/handlers/index.ts +15 -0
  206. package/mcp-server/handlers/tool-handler.ts +474 -591
  207. package/mcp-server/index.js +1748 -1099
  208. package/mcp-server/lib/api-client.cjs +13 -0
  209. package/mcp-server/lib/cache-wrapper.cjs +383 -0
  210. package/mcp-server/lib/error-envelope.js +138 -0
  211. package/mcp-server/lib/executor.ts +428 -721
  212. package/mcp-server/lib/index.ts +19 -0
  213. package/mcp-server/lib/logger.cjs +30 -0
  214. package/mcp-server/lib/rate-limiter.js +166 -0
  215. package/mcp-server/lib/sandbox.test.ts +519 -0
  216. package/mcp-server/lib/sandbox.ts +342 -284
  217. package/mcp-server/lib/types.ts +267 -0
  218. package/mcp-server/logger.js +173 -0
  219. package/mcp-server/package.json +11 -27
  220. package/mcp-server/premium-tools.js +2 -2
  221. package/mcp-server/registry/tool-registry.js +794 -0
  222. package/mcp-server/registry/tools.json +507 -378
  223. package/mcp-server/registry.test.ts +334 -0
  224. package/mcp-server/tests/tier-gating.test.js +297 -0
  225. package/mcp-server/tier-auth.js +492 -347
  226. package/mcp-server/tools-v3.js +950 -0
  227. package/mcp-server/truth-context.js +131 -90
  228. package/mcp-server/truth-firewall-tools.js +1612 -1001
  229. package/mcp-server/tsconfig.json +8 -5
  230. package/mcp-server/vibecheck-2.0-tools.js +14 -1
  231. package/mcp-server/vibecheck-mcp-server-3.2.0.tgz +0 -0
  232. package/mcp-server/vibecheck-tools.js +2 -2
  233. package/package.json +4 -3
  234. package/bin/runners/runInstall.js +0 -281
  235. package/mcp-server/ARCHITECTURE.md +0 -339
  236. package/mcp-server/__tests__/cache.test.ts +0 -313
  237. package/mcp-server/__tests__/executor.test.ts +0 -239
  238. package/mcp-server/__tests__/fixtures/exclusion-test/.cache/webpack/cache.pack +0 -1
  239. package/mcp-server/__tests__/fixtures/exclusion-test/.next/server/chunk.js +0 -3
  240. package/mcp-server/__tests__/fixtures/exclusion-test/.turbo/cache.json +0 -3
  241. package/mcp-server/__tests__/fixtures/exclusion-test/.venv/lib/env.py +0 -3
  242. package/mcp-server/__tests__/fixtures/exclusion-test/dist/bundle.js +0 -3
  243. package/mcp-server/__tests__/fixtures/exclusion-test/package.json +0 -5
  244. package/mcp-server/__tests__/fixtures/exclusion-test/src/app.ts +0 -5
  245. package/mcp-server/__tests__/fixtures/exclusion-test/venv/lib/config.py +0 -4
  246. package/mcp-server/__tests__/ids.test.ts +0 -345
  247. package/mcp-server/__tests__/integration/tools.test.ts +0 -410
  248. package/mcp-server/__tests__/registry.test.ts +0 -365
  249. package/mcp-server/__tests__/sandbox.test.ts +0 -323
  250. package/mcp-server/__tests__/schemas.test.ts +0 -372
  251. package/mcp-server/benchmarks/run-benchmarks.ts +0 -304
  252. package/mcp-server/examples/doctor.request.json +0 -14
  253. package/mcp-server/examples/doctor.response.json +0 -53
  254. package/mcp-server/examples/error.response.json +0 -15
  255. package/mcp-server/examples/scan.request.json +0 -14
  256. package/mcp-server/examples/scan.response.json +0 -108
  257. package/mcp-server/index-v3.ts +0 -293
  258. package/mcp-server/index.old.js +0 -4137
  259. package/mcp-server/lib/cache.ts +0 -341
  260. package/mcp-server/lib/errors.ts +0 -346
  261. package/mcp-server/lib/ids.ts +0 -238
  262. package/mcp-server/lib/logger.ts +0 -368
  263. package/mcp-server/lib/metrics.ts +0 -365
  264. package/mcp-server/lib/validator.ts +0 -229
  265. package/mcp-server/package-lock.json +0 -165
  266. package/mcp-server/schemas/error-envelope.schema.json +0 -125
  267. package/mcp-server/schemas/finding.schema.json +0 -167
  268. package/mcp-server/schemas/report-artifact.schema.json +0 -88
  269. package/mcp-server/schemas/run-request.schema.json +0 -75
  270. package/mcp-server/schemas/verdict.schema.json +0 -168
  271. package/mcp-server/tier-auth.d.ts +0 -71
  272. package/mcp-server/vitest.config.ts +0 -16
@@ -11,7 +11,6 @@
11
11
 
12
12
  const fs = require("fs");
13
13
  const path = require("path");
14
- const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
15
14
 
16
15
  // Colors
17
16
  const c = {
@@ -22,15 +21,16 @@ const c = {
22
21
  yellow: '\x1b[33m',
23
22
  cyan: '\x1b[36m',
24
23
  red: '\x1b[31m',
24
+ magenta: '\x1b[35m',
25
25
  };
26
26
 
27
27
  const rgb = (r, g, b) => `\x1b[38;2;${r};${g};${b}m`;
28
28
 
29
29
  const colors = {
30
- accent: rgb(150, 100, 255),
31
- success: rgb(0, 255, 150),
32
- warning: rgb(255, 200, 0),
33
- error: rgb(255, 80, 80),
30
+ accent: rgb(0, 212, 255),
31
+ success: rgb(16, 185, 129),
32
+ warning: rgb(245, 158, 11),
33
+ error: rgb(239, 68, 68),
34
34
  };
35
35
 
36
36
  const ICONS = {
@@ -44,21 +44,10 @@ const ICONS = {
44
44
  };
45
45
 
46
46
  function printHelp(opts = {}) {
47
- if (shouldShowBanner(opts)) {
48
- console.log(`
49
- ${colors.accent} ██████╗ █████╗ ██████╗██╗ ██╗${c.reset}
50
- ${colors.accent} ██╔══██╗██╔══██╗██╔════╝██║ ██╔╝${c.reset}
51
- ${colors.accent} ██████╔╝███████║██║ █████╔╝ ${c.reset}
52
- ${colors.accent} ██╔═══╝ ██╔══██║██║ ██╔═██╗ ${c.reset}
53
- ${colors.accent} ██║ ██║ ██║╚██████╗██║ ██╗${c.reset}
54
- ${colors.accent} ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝${c.reset}
55
- `);
56
- }
57
-
58
47
  console.log(`
59
- ${c.bold}Usage:${c.reset} vibecheck evidence-pack [options]
48
+ ${c.bold}vibecheck evidence-pack${c.reset} - Bundle Proof Artifacts
60
49
 
61
- ${c.bold}Bundle Proof Artifacts${c.reset} Create shareable evidence packs.
50
+ ${c.bold}Usage:${c.reset} vibecheck evidence-pack [options]
62
51
 
63
52
  ${c.bold}What It Bundles:${c.reset}
64
53
  ${ICONS.video} ${c.dim}Videos${c.reset} Browser session recordings
@@ -67,21 +56,25 @@ ${colors.accent} ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═
67
56
  ${ICONS.file} ${c.dim}Reports${c.reset} JSON reports with evidence
68
57
 
69
58
  ${c.bold}Options:${c.reset}
70
- ${colors.accent}--output, -o <path>${c.reset} Output zip path ${c.dim}(default: .vibecheck/evidence-packs/)${c.reset}
59
+ ${colors.accent}--output, -o <path>${c.reset} Output directory ${c.dim}(default: .vibecheck/evidence-packs/)${c.reset}
60
+ ${colors.accent}--run-id <id>${c.reset} Bundle specific run by ID
61
+ ${colors.accent}--latest${c.reset} Bundle the most recent run ${c.dim}(default)${c.reset}
71
62
  ${colors.accent}--no-videos${c.reset} Exclude video recordings
72
63
  ${colors.accent}--no-traces${c.reset} Exclude Playwright traces
73
64
  ${colors.accent}--no-screenshots${c.reset} Exclude screenshots
74
- ${colors.accent}--no-allowlist${c.reset} Don't filter by allowlist
75
65
  ${colors.accent}--markdown${c.reset} Generate markdown report
76
66
  ${colors.accent}--json${c.reset} Output JSON manifest only
77
67
  ${colors.accent}--help, -h${c.reset} Show this help
78
68
 
79
69
  ${c.bold}Examples:${c.reset}
80
- ${c.dim}# Create evidence pack${c.reset}
70
+ ${c.dim}# Create evidence pack from latest run${c.reset}
81
71
  vibecheck evidence-pack
82
72
 
83
73
  ${c.dim}# Custom output path${c.reset}
84
- vibecheck evidence-pack --output ./artifacts/proof.zip
74
+ vibecheck evidence-pack --output ./artifacts/proof
75
+
76
+ ${c.dim}# Bundle specific run${c.reset}
77
+ vibecheck evidence-pack --run-id abc123
85
78
 
86
79
  ${c.dim}# Generate markdown report${c.reset}
87
80
  vibecheck evidence-pack --markdown > evidence-report.md
@@ -91,81 +84,92 @@ ${colors.accent} ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═
91
84
  `);
92
85
  }
93
86
 
94
- async function runEvidencePack(argsOrOpts = {}) {
95
- // Handle array args from CLI
96
- let globalOpts = { noBanner: false, json: false, quiet: false, ci: false };
97
- if (Array.isArray(argsOrOpts)) {
98
- const { flags } = parseGlobalFlags(argsOrOpts);
99
- globalOpts = { ...globalOpts, ...flags };
100
-
101
- if (globalOpts.help) {
102
- printHelp(globalOpts);
103
- return 0;
87
+ async function runEvidencePack(args = [], context = {}) {
88
+ // Parse arguments
89
+ const getArg = (flags) => {
90
+ for (const f of flags) {
91
+ const idx = args.indexOf(f);
92
+ if (idx !== -1 && idx < args.length - 1) return args[idx + 1];
104
93
  }
105
-
106
- const getArg = (flags) => {
107
- for (const f of flags) {
108
- const idx = argsOrOpts.indexOf(f);
109
- if (idx !== -1 && idx < argsOrOpts.length - 1) return argsOrOpts[idx + 1];
110
- }
111
- return undefined;
112
- };
113
-
114
- argsOrOpts = {
115
- repoRoot: process.cwd(),
116
- output: getArg(["--output", "-o"]),
117
- includeVideos: !argsOrOpts.includes("--no-videos"),
118
- includeTraces: !argsOrOpts.includes("--no-traces"),
119
- includeScreenshots: !argsOrOpts.includes("--no-screenshots"),
120
- applyAllowlist: !argsOrOpts.includes("--no-allowlist"),
121
- markdown: argsOrOpts.includes("--markdown"),
122
- ...globalOpts,
123
- };
124
- }
94
+ return undefined;
95
+ };
96
+
97
+ const hasFlag = (flags) => flags.some(f => args.includes(f));
125
98
 
126
- const {
127
- repoRoot = process.cwd(),
128
- output = null,
129
- includeVideos = true,
130
- includeTraces = true,
131
- includeScreenshots = true,
132
- applyAllowlist = true,
133
- markdown = false,
134
- json = false,
135
- quiet = false
136
- } = argsOrOpts;
137
-
138
- const root = repoRoot || process.cwd();
139
-
140
- // Import evidence-pack module
141
- let evidencePack;
142
- try {
143
- evidencePack = require("./lib/evidence-pack");
144
- } catch (e) {
145
- console.error(`${colors.error}${ICONS.cross}${c.reset} Failed to load evidence-pack module: ${e.message}`);
146
- return 1;
99
+ if (hasFlag(["--help", "-h"])) {
100
+ printHelp();
101
+ return 0;
147
102
  }
148
103
 
149
- if (!quiet && !json) {
104
+ const options = {
105
+ repoRoot: context.repoRoot || process.cwd(),
106
+ output: getArg(["--output", "-o"]),
107
+ runId: getArg(["--run-id"]),
108
+ latest: hasFlag(["--latest"]) || !getArg(["--run-id"]),
109
+ includeVideos: !hasFlag(["--no-videos"]),
110
+ includeTraces: !hasFlag(["--no-traces"]),
111
+ includeScreenshots: !hasFlag(["--no-screenshots"]),
112
+ markdown: hasFlag(["--markdown"]),
113
+ json: hasFlag(["--json"]),
114
+ quiet: hasFlag(["--quiet", "-q"]),
115
+ };
116
+
117
+ const root = options.repoRoot;
118
+ const vibecheckDir = path.join(root, ".vibecheck");
119
+ const runsDir = path.join(vibecheckDir, "runs");
120
+
121
+ if (!options.quiet && !options.json && !options.markdown) {
150
122
  console.log(`\n ${ICONS.pack} ${c.bold}Building Evidence Pack${c.reset}\n`);
151
123
  }
152
124
 
153
125
  try {
154
- const pack = await evidencePack.buildEvidencePack(root, {
155
- outputPath: output,
156
- includeVideos,
157
- includeTraces,
158
- includeScreenshots,
159
- applyAllowlist
160
- });
161
-
162
- if (markdown) {
163
- const mdReport = evidencePack.generateMarkdownReport(pack);
164
- console.log(mdReport);
126
+ // Find the run to bundle
127
+ let runId = options.runId;
128
+
129
+ if (options.latest || !runId) {
130
+ // Find the most recent run
131
+ if (!fs.existsSync(runsDir)) {
132
+ throw new Error("No runs found. Run 'vibecheck prove' first.");
133
+ }
134
+
135
+ const runs = fs.readdirSync(runsDir)
136
+ .filter(d => fs.statSync(path.join(runsDir, d)).isDirectory())
137
+ .map(d => {
138
+ const manifestPath = path.join(runsDir, d, "manifest.json");
139
+ if (fs.existsSync(manifestPath)) {
140
+ try {
141
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
142
+ return { id: d, timestamp: manifest.timestamp || 0 };
143
+ } catch {
144
+ return { id: d, timestamp: 0 };
145
+ }
146
+ }
147
+ return { id: d, timestamp: 0 };
148
+ })
149
+ .sort((a, b) => b.timestamp - a.timestamp);
150
+
151
+ if (runs.length === 0) {
152
+ throw new Error("No runs found. Run 'vibecheck prove' first.");
153
+ }
154
+
155
+ runId = runs[0].id;
156
+ }
157
+
158
+ const runDir = path.join(runsDir, runId);
159
+ if (!fs.existsSync(runDir)) {
160
+ throw new Error(`Run not found: ${runId}`);
161
+ }
162
+
163
+ // Build the evidence pack
164
+ const pack = await buildEvidencePack(runDir, runId, options);
165
+
166
+ // Output based on format
167
+ if (options.markdown) {
168
+ console.log(generateMarkdownReport(pack));
165
169
  return pack.summary.verdict === 'SHIP' ? 0 : pack.summary.verdict === 'WARN' ? 1 : 2;
166
170
  }
167
171
 
168
- if (json) {
172
+ if (options.json) {
169
173
  console.log(JSON.stringify(pack.manifest, null, 2));
170
174
  return pack.summary.verdict === 'SHIP' ? 0 : pack.summary.verdict === 'WARN' ? 1 : 2;
171
175
  }
@@ -176,38 +180,37 @@ async function runEvidencePack(argsOrOpts = {}) {
176
180
  summary.verdict === 'WARN' ? colors.warning : colors.error;
177
181
 
178
182
  console.log(` ${c.dim}Pack ID:${c.reset} ${pack.id}`);
183
+ console.log(` ${c.dim}Run ID:${c.reset} ${runId}`);
179
184
  console.log(` ${c.dim}Verdict:${c.reset} ${verdictColor}${c.bold}${summary.verdict}${c.reset}`);
180
- console.log(` ${c.dim}Findings:${c.reset} ${summary.filteredFindings} (${summary.allowlistedCount} allowlisted)`);
185
+ console.log(` ${c.dim}Score:${c.reset} ${summary.score}/100`);
186
+ console.log(` ${c.dim}Findings:${c.reset} ${summary.totalFindings}`);
181
187
  console.log();
182
188
 
183
189
  // Artifact summary
184
190
  const artifacts = manifest.artifacts;
185
- if (artifacts.screenshots.length > 0) {
191
+ if (artifacts.screenshots && artifacts.screenshots.length > 0) {
186
192
  console.log(` ${ICONS.screenshot} Screenshots: ${artifacts.screenshots.length}`);
187
193
  }
188
- if (artifacts.videos.length > 0) {
194
+ if (artifacts.videos && artifacts.videos.length > 0) {
189
195
  console.log(` ${ICONS.video} Videos: ${artifacts.videos.length}`);
190
196
  }
191
- if (artifacts.traces.length > 0) {
197
+ if (artifacts.traces && artifacts.traces.length > 0) {
192
198
  console.log(` ${ICONS.trace} Traces: ${artifacts.traces.length}`);
193
199
  }
194
200
 
195
201
  console.log();
196
- console.log(` ${colors.success}${ICONS.check}${c.reset} Manifest: ${path.relative(root, pack.manifestPath)}`);
197
- if (pack.zipPath) {
198
- console.log(` ${colors.success}${ICONS.check}${c.reset} Zip: ${path.relative(root, pack.zipPath)}`);
199
- }
202
+ console.log(` ${colors.success}${ICONS.check}${c.reset} Output: ${path.relative(root, pack.outputDir)}`);
200
203
  console.log();
201
204
 
202
205
  // Tips
203
- if (artifacts.traces.length > 0) {
206
+ if (artifacts.traces && artifacts.traces.length > 0) {
204
207
  console.log(` ${c.dim}View traces at: ${c.cyan}https://trace.playwright.dev${c.reset}`);
205
208
  }
206
209
 
207
210
  return summary.verdict === 'SHIP' ? 0 : summary.verdict === 'WARN' ? 1 : 2;
208
211
 
209
212
  } catch (error) {
210
- if (json) {
213
+ if (options.json) {
211
214
  console.log(JSON.stringify({ error: error.message }, null, 2));
212
215
  } else {
213
216
  console.error(`\n ${colors.error}${ICONS.cross}${c.reset} ${error.message}\n`);
@@ -216,4 +219,144 @@ async function runEvidencePack(argsOrOpts = {}) {
216
219
  }
217
220
  }
218
221
 
222
+ async function buildEvidencePack(runDir, runId, options) {
223
+ const packId = `pack_${Date.now().toString(36)}`;
224
+ const outputDir = options.output || path.join(path.dirname(path.dirname(runDir)), "evidence-packs", packId);
225
+
226
+ // Create output directory
227
+ fs.mkdirSync(outputDir, { recursive: true });
228
+
229
+ // Read run manifest
230
+ const manifestPath = path.join(runDir, "manifest.json");
231
+ let runManifest = {};
232
+ if (fs.existsSync(manifestPath)) {
233
+ runManifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
234
+ }
235
+
236
+ // Read summary
237
+ const summaryPath = path.join(runDir, "artifacts", "summary.json");
238
+ let summary = { verdict: 'UNKNOWN', score: 0, totalFindings: 0 };
239
+ if (fs.existsSync(summaryPath)) {
240
+ summary = JSON.parse(fs.readFileSync(summaryPath, "utf-8"));
241
+ }
242
+
243
+ // Collect artifacts
244
+ const artifacts = {
245
+ screenshots: [],
246
+ videos: [],
247
+ traces: [],
248
+ reports: [],
249
+ };
250
+
251
+ const artifactsDir = path.join(runDir, "artifacts");
252
+ if (fs.existsSync(artifactsDir)) {
253
+ const files = fs.readdirSync(artifactsDir);
254
+
255
+ for (const file of files) {
256
+ const filePath = path.join(artifactsDir, file);
257
+ const stat = fs.statSync(filePath);
258
+
259
+ if (stat.isFile()) {
260
+ const ext = path.extname(file).toLowerCase();
261
+ const destPath = path.join(outputDir, file);
262
+
263
+ if (['.png', '.jpg', '.jpeg'].includes(ext) && options.includeScreenshots) {
264
+ fs.copyFileSync(filePath, destPath);
265
+ artifacts.screenshots.push({ name: file, size: stat.size });
266
+ } else if (['.webm', '.mp4'].includes(ext) && options.includeVideos) {
267
+ fs.copyFileSync(filePath, destPath);
268
+ artifacts.videos.push({ name: file, size: stat.size });
269
+ } else if (ext === '.zip' && file.includes('trace') && options.includeTraces) {
270
+ fs.copyFileSync(filePath, destPath);
271
+ artifacts.traces.push({ name: file, size: stat.size });
272
+ } else if (ext === '.json') {
273
+ fs.copyFileSync(filePath, destPath);
274
+ artifacts.reports.push({ name: file, size: stat.size });
275
+ }
276
+ }
277
+ }
278
+ }
279
+
280
+ // Create pack manifest
281
+ const packManifest = {
282
+ id: packId,
283
+ runId,
284
+ createdAt: new Date().toISOString(),
285
+ summary,
286
+ artifacts,
287
+ source: runManifest,
288
+ };
289
+
290
+ const packManifestPath = path.join(outputDir, "manifest.json");
291
+ fs.writeFileSync(packManifestPath, JSON.stringify(packManifest, null, 2));
292
+
293
+ return {
294
+ id: packId,
295
+ runId,
296
+ outputDir,
297
+ manifestPath: packManifestPath,
298
+ manifest: packManifest,
299
+ summary,
300
+ };
301
+ }
302
+
303
+ function generateMarkdownReport(pack) {
304
+ const { manifest, summary } = pack;
305
+ const verdictEmoji = summary.verdict === 'SHIP' ? '✅' : summary.verdict === 'WARN' ? '⚠️' : '🚫';
306
+
307
+ let md = `# Evidence Pack Report
308
+
309
+ ## Summary
310
+
311
+ | Metric | Value |
312
+ |--------|-------|
313
+ | Pack ID | \`${pack.id}\` |
314
+ | Run ID | \`${pack.runId}\` |
315
+ | Verdict | ${verdictEmoji} **${summary.verdict}** |
316
+ | Score | ${summary.score}/100 |
317
+ | Findings | ${summary.totalFindings} |
318
+ | Created | ${manifest.createdAt} |
319
+
320
+ ## Artifacts
321
+
322
+ `;
323
+
324
+ if (manifest.artifacts.screenshots.length > 0) {
325
+ md += `### Screenshots (${manifest.artifacts.screenshots.length})\n\n`;
326
+ for (const s of manifest.artifacts.screenshots) {
327
+ md += `- \`${s.name}\` (${formatBytes(s.size)})\n`;
328
+ }
329
+ md += '\n';
330
+ }
331
+
332
+ if (manifest.artifacts.videos.length > 0) {
333
+ md += `### Videos (${manifest.artifacts.videos.length})\n\n`;
334
+ for (const v of manifest.artifacts.videos) {
335
+ md += `- \`${v.name}\` (${formatBytes(v.size)})\n`;
336
+ }
337
+ md += '\n';
338
+ }
339
+
340
+ if (manifest.artifacts.traces.length > 0) {
341
+ md += `### Traces (${manifest.artifacts.traces.length})\n\n`;
342
+ md += `View traces at [trace.playwright.dev](https://trace.playwright.dev)\n\n`;
343
+ for (const t of manifest.artifacts.traces) {
344
+ md += `- \`${t.name}\` (${formatBytes(t.size)})\n`;
345
+ }
346
+ md += '\n';
347
+ }
348
+
349
+ md += `---\n\n*Generated by vibecheck evidence-pack*\n`;
350
+
351
+ return md;
352
+ }
353
+
354
+ function formatBytes(bytes) {
355
+ if (bytes === 0) return '0 B';
356
+ const k = 1024;
357
+ const sizes = ['B', 'KB', 'MB', 'GB'];
358
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
359
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
360
+ }
361
+
219
362
  module.exports = { runEvidencePack };
@@ -0,0 +1,5 @@
1
+ export interface FirewallOptions {
2
+ action?: 'on' | 'off' | 'status' | 'lock';
3
+ projectRoot?: string;
4
+ }
5
+ export function runFirewall(options?: FirewallOptions): Promise<void>;
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Firewall Command Handler
3
+ *
4
+ * Main firewall command handler.
5
+ * Enable/disable firewall, set mode, show status and statistics.
6
+ */
7
+
8
+ "use strict";
9
+
10
+ const fs = require("fs");
11
+ const path = require("path");
12
+ const { loadPolicy, savePolicy, getDefaultPolicy } = require("./lib/agent-firewall/policy/loader");
13
+ const { getPacketStats, queryPackets } = require("./lib/agent-firewall/change-packet/store");
14
+ const { isTruthpackFresh } = require("./lib/agent-firewall/truthpack/loader");
15
+
16
+ /**
17
+ * Run firewall command
18
+ * @param {object} options - Command options
19
+ * @param {string} options.mode - Set mode: 'observe' or 'enforce'
20
+ * @param {boolean} options.status - Show firewall status
21
+ * @param {boolean} options.stats - Show statistics
22
+ * @param {string} options.projectRoot - Project root directory
23
+ */
24
+ async function runFirewall(options = {}) {
25
+ const projectRoot = options.projectRoot || process.cwd();
26
+
27
+ if (options.status) {
28
+ return showStatus(projectRoot);
29
+ }
30
+
31
+ if (options.stats) {
32
+ return showStats(projectRoot);
33
+ }
34
+
35
+ if (options.mode) {
36
+ return setMode(projectRoot, options.mode);
37
+ }
38
+
39
+ // Default: show status
40
+ return showStatus(projectRoot);
41
+ }
42
+
43
+ /**
44
+ * Show firewall status
45
+ */
46
+ function showStatus(projectRoot) {
47
+ try {
48
+ const policy = loadPolicy(projectRoot);
49
+ const truthpackFresh = isTruthpackFresh(projectRoot);
50
+
51
+ const output = {
52
+ mode: policy.mode || "observe",
53
+ profile: policy.profile || "default",
54
+ truthpackFresh,
55
+ rulesEnabled: Object.keys(policy.rules || {}).filter(
56
+ key => policy.rules[key]?.enabled !== false
57
+ ).length
58
+ };
59
+
60
+ return output;
61
+ } catch (error) {
62
+ return {
63
+ error: error.message,
64
+ mode: "unknown",
65
+ truthpackFresh: false
66
+ };
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Show firewall statistics
72
+ */
73
+ function showStats(projectRoot) {
74
+ try {
75
+ const stats = getPacketStats(projectRoot);
76
+ const recentPackets = queryPackets(projectRoot, { limit: 10 });
77
+
78
+ return {
79
+ total: stats.total,
80
+ byAgent: stats.byAgent,
81
+ byVerdict: stats.byVerdict,
82
+ byDate: stats.byDate,
83
+ recent: recentPackets.map(p => ({
84
+ id: p.id,
85
+ timestamp: p.timestamp,
86
+ agentId: p.agentId,
87
+ verdict: p.verdict?.decision,
88
+ files: p.files.length
89
+ }))
90
+ };
91
+ } catch (error) {
92
+ return {
93
+ error: error.message,
94
+ total: 0
95
+ };
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Set firewall mode
101
+ */
102
+ function setMode(projectRoot, mode) {
103
+ if (mode !== "observe" && mode !== "enforce") {
104
+ throw new Error(`Invalid mode: ${mode}. Must be 'observe' or 'enforce'`);
105
+ }
106
+
107
+ try {
108
+ let policy;
109
+ try {
110
+ policy = loadPolicy(projectRoot);
111
+ } catch {
112
+ // Policy doesn't exist, use default
113
+ policy = getDefaultPolicy();
114
+ }
115
+
116
+ policy.mode = mode;
117
+ savePolicy(projectRoot, policy);
118
+
119
+ return {
120
+ success: true,
121
+ mode,
122
+ message: `Firewall mode set to: ${mode}`
123
+ };
124
+ } catch (error) {
125
+ return {
126
+ success: false,
127
+ error: error.message
128
+ };
129
+ }
130
+ }
131
+
132
+ module.exports = {
133
+ runFirewall
134
+ };
@@ -0,0 +1,5 @@
1
+ export interface FirewallHookOptions {
2
+ action?: 'install' | 'start' | 'status';
3
+ projectRoot?: string;
4
+ }
5
+ export function runFirewallHook(options?: FirewallHookOptions): Promise<void>;
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Firewall Hook Manager
3
+ *
4
+ * Manages file system hook installation and control.
5
+ */
6
+
7
+ "use strict";
8
+
9
+ const { installFileSystemHook, startFileSystemHook, stopFileSystemHook } = require("./lib/agent-firewall/fs-hook/installer");
10
+ const fs = require("fs");
11
+ const path = require("path");
12
+
13
+ /**
14
+ * Run firewall hook command
15
+ * @param {object} options - Command options
16
+ * @param {string} options.action - Action: 'install', 'start', 'stop', 'status'
17
+ * @param {string} options.projectRoot - Project root directory
18
+ */
19
+ async function runFirewallHook(options = {}) {
20
+ const projectRoot = options.projectRoot || process.cwd();
21
+ const action = options.action || "status";
22
+
23
+ switch (action) {
24
+ case "install":
25
+ return installFileSystemHook(projectRoot);
26
+
27
+ case "start":
28
+ startFileSystemHook(projectRoot);
29
+ return {
30
+ success: true,
31
+ message: "File system hook started"
32
+ };
33
+
34
+ case "stop":
35
+ stopFileSystemHook();
36
+ return {
37
+ success: true,
38
+ message: "File system hook stopped"
39
+ };
40
+
41
+ case "status":
42
+ const markerFile = path.join(projectRoot, ".vibecheck", "fs-hook-enabled");
43
+ const installed = fs.existsSync(markerFile);
44
+ return {
45
+ installed,
46
+ running: false // Would need process management to check
47
+ };
48
+
49
+ default:
50
+ throw new Error(`Unknown action: ${action}`);
51
+ }
52
+ }
53
+
54
+ module.exports = {
55
+ runFirewallHook
56
+ };
@@ -33,6 +33,7 @@ const { backupFiles, restoreBackup } = require('./lib/backup');
33
33
  const { validatePatchResponse, parseDiffTouchedFiles } = require('./lib/validate-patch');
34
34
  const { buildSharePack } = require('./lib/share-pack');
35
35
  const { parseGlobalFlags, shouldShowBanner } = require('./lib/global-flags');
36
+ const { EXIT, verdictToExitCode } = require('./lib/exit-codes');
36
37
 
37
38
  // Entitlements enforcement
38
39
  const entitlements = require('./lib/entitlements-v2');
@@ -696,7 +697,7 @@ async function runFix(args) {
696
697
  } catch (e) {
697
698
  stopSpinner('LLM failed', false);
698
699
  console.log(` ${colors.blockRed}${ICONS.cross}${c.reset} ${e.message}`);
699
- return 1;
700
+ return EXIT.INTERNAL_ERROR;
700
701
  }
701
702
 
702
703
  const respPath = path.join(outDir, `step_${String(step).padStart(2,"0")}_${mission.id}_response.json`);
@@ -722,7 +723,7 @@ async function runFix(args) {
722
723
  console.log(` ${colors.warnAmber}${ICONS.warning}${c.reset} ${w}`);
723
724
  }
724
725
  }
725
- return 1;
726
+ return EXIT.BLOCKING;
726
727
  }
727
728
 
728
729
  if (v.warnings.length) {
@@ -753,7 +754,7 @@ async function runFix(args) {
753
754
  console.log(` ${colors.blockRed}${ICONS.cross}${c.reset} Patch apply failed: ${res.error}`);
754
755
  restoreBackup(root, backupRoot);
755
756
  console.log(` ${colors.rollback}${ICONS.rollback}${c.reset} Restored from backup`);
756
- return 1;
757
+ return EXIT.INTERNAL_ERROR;
757
758
  }
758
759
  console.log(` ${colors.patch}${ICONS.patch}${c.reset} Applied: ${c.dim}${ed.path}${c.reset}`);
759
760
  }
@@ -789,7 +790,7 @@ async function runFix(args) {
789
790
  console.log();
790
791
  console.log(` ${colors.blockRed}${ICONS.stop}${c.reset} Stopping: stagnation limit reached (${stagnant}/${stagnationLimit})`);
791
792
  console.log();
792
- return 1;
793
+ return EXIT.BLOCKING;
793
794
  }
794
795
  continue;
795
796
  }
@@ -820,7 +821,7 @@ async function runFix(args) {
820
821
  }
821
822
  }
822
823
 
823
- return 1;
824
+ return EXIT.WARNINGS; // Max steps reached, incomplete
824
825
  }
825
826
 
826
827
  // ═══════════════════════════════════════════════════════════════════════════════