@vibecheckai/cli 3.4.0 → 3.5.1

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 (228) hide show
  1. package/bin/registry.js +154 -338
  2. package/bin/runners/context/generators/mcp.js +13 -15
  3. package/bin/runners/context/proof-context.js +1 -248
  4. package/bin/runners/lib/analysis-core.js +180 -198
  5. package/bin/runners/lib/analyzers.js +223 -1669
  6. package/bin/runners/lib/cli-output.js +210 -242
  7. package/bin/runners/lib/detectors-v2.js +785 -547
  8. package/bin/runners/lib/entitlements-v2.js +458 -96
  9. package/bin/runners/lib/error-handler.js +9 -16
  10. package/bin/runners/lib/global-flags.js +0 -37
  11. package/bin/runners/lib/route-truth.js +322 -1167
  12. package/bin/runners/lib/scan-output.js +469 -448
  13. package/bin/runners/lib/ship-output.js +27 -280
  14. package/bin/runners/lib/terminal-ui.js +733 -231
  15. package/bin/runners/lib/truth.js +321 -1004
  16. package/bin/runners/lib/unified-output.js +158 -162
  17. package/bin/runners/lib/upsell.js +204 -104
  18. package/bin/runners/runAllowlist.js +324 -0
  19. package/bin/runners/runAuth.js +95 -324
  20. package/bin/runners/runCheckpoint.js +21 -39
  21. package/bin/runners/runContext.js +24 -136
  22. package/bin/runners/runDoctor.js +67 -115
  23. package/bin/runners/runEvidencePack.js +219 -0
  24. package/bin/runners/runFix.js +5 -6
  25. package/bin/runners/runGuard.js +118 -212
  26. package/bin/runners/runInit.js +2 -14
  27. package/bin/runners/runInstall.js +281 -0
  28. package/bin/runners/runLabs.js +341 -0
  29. package/bin/runners/runMcp.js +52 -130
  30. package/bin/runners/runPolish.js +20 -43
  31. package/bin/runners/runProve.js +3 -13
  32. package/bin/runners/runReality.js +0 -14
  33. package/bin/runners/runReport.js +2 -3
  34. package/bin/runners/runScan.js +44 -511
  35. package/bin/runners/runShip.js +14 -28
  36. package/bin/runners/runValidate.js +2 -19
  37. package/bin/runners/runWatch.js +54 -118
  38. package/bin/vibecheck.js +41 -148
  39. package/mcp-server/ARCHITECTURE.md +339 -0
  40. package/mcp-server/__tests__/cache.test.ts +313 -0
  41. package/mcp-server/__tests__/executor.test.ts +239 -0
  42. package/mcp-server/__tests__/fixtures/exclusion-test/.cache/webpack/cache.pack +1 -0
  43. package/mcp-server/__tests__/fixtures/exclusion-test/.next/server/chunk.js +3 -0
  44. package/mcp-server/__tests__/fixtures/exclusion-test/.turbo/cache.json +3 -0
  45. package/mcp-server/__tests__/fixtures/exclusion-test/.venv/lib/env.py +3 -0
  46. package/mcp-server/__tests__/fixtures/exclusion-test/dist/bundle.js +3 -0
  47. package/mcp-server/__tests__/fixtures/exclusion-test/package.json +5 -0
  48. package/mcp-server/__tests__/fixtures/exclusion-test/src/app.ts +5 -0
  49. package/mcp-server/__tests__/fixtures/exclusion-test/venv/lib/config.py +4 -0
  50. package/mcp-server/__tests__/ids.test.ts +345 -0
  51. package/mcp-server/__tests__/integration/tools.test.ts +410 -0
  52. package/mcp-server/__tests__/registry.test.ts +365 -0
  53. package/mcp-server/__tests__/sandbox.test.ts +323 -0
  54. package/mcp-server/__tests__/schemas.test.ts +372 -0
  55. package/mcp-server/benchmarks/run-benchmarks.ts +304 -0
  56. package/mcp-server/examples/doctor.request.json +14 -0
  57. package/mcp-server/examples/doctor.response.json +53 -0
  58. package/mcp-server/examples/error.response.json +15 -0
  59. package/mcp-server/examples/scan.request.json +14 -0
  60. package/mcp-server/examples/scan.response.json +108 -0
  61. package/mcp-server/handlers/tool-handler.ts +671 -0
  62. package/mcp-server/index-v3.ts +293 -0
  63. package/mcp-server/index.js +1072 -1573
  64. package/mcp-server/index.old.js +4137 -0
  65. package/mcp-server/lib/cache.ts +341 -0
  66. package/mcp-server/lib/errors.ts +346 -0
  67. package/mcp-server/lib/executor.ts +792 -0
  68. package/mcp-server/lib/ids.ts +238 -0
  69. package/mcp-server/lib/logger.ts +368 -0
  70. package/mcp-server/lib/metrics.ts +365 -0
  71. package/mcp-server/lib/sandbox.ts +337 -0
  72. package/mcp-server/lib/validator.ts +229 -0
  73. package/mcp-server/package-lock.json +165 -0
  74. package/mcp-server/package.json +32 -7
  75. package/mcp-server/premium-tools.js +2 -2
  76. package/mcp-server/registry/tools.json +476 -0
  77. package/mcp-server/schemas/error-envelope.schema.json +125 -0
  78. package/mcp-server/schemas/finding.schema.json +167 -0
  79. package/mcp-server/schemas/report-artifact.schema.json +88 -0
  80. package/mcp-server/schemas/run-request.schema.json +75 -0
  81. package/mcp-server/schemas/verdict.schema.json +168 -0
  82. package/mcp-server/tier-auth.d.ts +71 -0
  83. package/mcp-server/tier-auth.js +371 -183
  84. package/mcp-server/truth-context.js +90 -131
  85. package/mcp-server/truth-firewall-tools.js +1000 -1611
  86. package/mcp-server/tsconfig.json +34 -0
  87. package/mcp-server/vibecheck-tools.js +2 -2
  88. package/mcp-server/vitest.config.ts +16 -0
  89. package/package.json +3 -4
  90. package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +0 -474
  91. package/bin/runners/lib/agent-firewall/change-packet/builder.js +0 -488
  92. package/bin/runners/lib/agent-firewall/change-packet/schema.json +0 -228
  93. package/bin/runners/lib/agent-firewall/change-packet/store.js +0 -200
  94. package/bin/runners/lib/agent-firewall/claims/claim-types.js +0 -21
  95. package/bin/runners/lib/agent-firewall/claims/extractor.js +0 -303
  96. package/bin/runners/lib/agent-firewall/claims/patterns.js +0 -24
  97. package/bin/runners/lib/agent-firewall/critic/index.js +0 -151
  98. package/bin/runners/lib/agent-firewall/critic/judge.js +0 -432
  99. package/bin/runners/lib/agent-firewall/critic/prompts.js +0 -305
  100. package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +0 -88
  101. package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +0 -75
  102. package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +0 -127
  103. package/bin/runners/lib/agent-firewall/evidence/resolver.js +0 -102
  104. package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +0 -213
  105. package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +0 -145
  106. package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +0 -19
  107. package/bin/runners/lib/agent-firewall/fs-hook/installer.js +0 -87
  108. package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +0 -184
  109. package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +0 -163
  110. package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +0 -107
  111. package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +0 -68
  112. package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +0 -66
  113. package/bin/runners/lib/agent-firewall/interceptor/base.js +0 -304
  114. package/bin/runners/lib/agent-firewall/interceptor/cursor.js +0 -35
  115. package/bin/runners/lib/agent-firewall/interceptor/vscode.js +0 -35
  116. package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +0 -34
  117. package/bin/runners/lib/agent-firewall/lawbook/distributor.js +0 -465
  118. package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +0 -604
  119. package/bin/runners/lib/agent-firewall/lawbook/index.js +0 -304
  120. package/bin/runners/lib/agent-firewall/lawbook/registry.js +0 -514
  121. package/bin/runners/lib/agent-firewall/lawbook/schema.js +0 -420
  122. package/bin/runners/lib/agent-firewall/logger.js +0 -141
  123. package/bin/runners/lib/agent-firewall/policy/default-policy.json +0 -90
  124. package/bin/runners/lib/agent-firewall/policy/engine.js +0 -103
  125. package/bin/runners/lib/agent-firewall/policy/loader.js +0 -451
  126. package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +0 -50
  127. package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +0 -50
  128. package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +0 -86
  129. package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +0 -162
  130. package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +0 -189
  131. package/bin/runners/lib/agent-firewall/policy/rules/scope.js +0 -93
  132. package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +0 -57
  133. package/bin/runners/lib/agent-firewall/policy/schema.json +0 -183
  134. package/bin/runners/lib/agent-firewall/policy/verdict.js +0 -54
  135. package/bin/runners/lib/agent-firewall/proposal/extractor.js +0 -394
  136. package/bin/runners/lib/agent-firewall/proposal/index.js +0 -212
  137. package/bin/runners/lib/agent-firewall/proposal/schema.js +0 -251
  138. package/bin/runners/lib/agent-firewall/proposal/validator.js +0 -386
  139. package/bin/runners/lib/agent-firewall/reality/index.js +0 -332
  140. package/bin/runners/lib/agent-firewall/reality/state.js +0 -625
  141. package/bin/runners/lib/agent-firewall/reality/watcher.js +0 -322
  142. package/bin/runners/lib/agent-firewall/risk/index.js +0 -173
  143. package/bin/runners/lib/agent-firewall/risk/scorer.js +0 -328
  144. package/bin/runners/lib/agent-firewall/risk/thresholds.js +0 -321
  145. package/bin/runners/lib/agent-firewall/risk/vectors.js +0 -421
  146. package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +0 -472
  147. package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +0 -346
  148. package/bin/runners/lib/agent-firewall/simulator/index.js +0 -181
  149. package/bin/runners/lib/agent-firewall/simulator/route-validator.js +0 -380
  150. package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +0 -661
  151. package/bin/runners/lib/agent-firewall/time-machine/index.js +0 -267
  152. package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +0 -436
  153. package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +0 -490
  154. package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +0 -530
  155. package/bin/runners/lib/agent-firewall/truthpack/index.js +0 -67
  156. package/bin/runners/lib/agent-firewall/truthpack/loader.js +0 -137
  157. package/bin/runners/lib/agent-firewall/unblock/planner.js +0 -337
  158. package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +0 -118
  159. package/bin/runners/lib/api-client.js +0 -269
  160. package/bin/runners/lib/authority-badge.js +0 -425
  161. package/bin/runners/lib/engines/accessibility-engine.js +0 -190
  162. package/bin/runners/lib/engines/api-consistency-engine.js +0 -162
  163. package/bin/runners/lib/engines/ast-cache.js +0 -99
  164. package/bin/runners/lib/engines/code-quality-engine.js +0 -255
  165. package/bin/runners/lib/engines/console-logs-engine.js +0 -115
  166. package/bin/runners/lib/engines/cross-file-analysis-engine.js +0 -268
  167. package/bin/runners/lib/engines/dead-code-engine.js +0 -198
  168. package/bin/runners/lib/engines/deprecated-api-engine.js +0 -226
  169. package/bin/runners/lib/engines/empty-catch-engine.js +0 -150
  170. package/bin/runners/lib/engines/file-filter.js +0 -131
  171. package/bin/runners/lib/engines/hardcoded-secrets-engine.js +0 -251
  172. package/bin/runners/lib/engines/mock-data-engine.js +0 -272
  173. package/bin/runners/lib/engines/parallel-processor.js +0 -71
  174. package/bin/runners/lib/engines/performance-issues-engine.js +0 -265
  175. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +0 -243
  176. package/bin/runners/lib/engines/todo-fixme-engine.js +0 -115
  177. package/bin/runners/lib/engines/type-aware-engine.js +0 -152
  178. package/bin/runners/lib/engines/unsafe-regex-engine.js +0 -225
  179. package/bin/runners/lib/engines/vibecheck-engines/README.md +0 -53
  180. package/bin/runners/lib/engines/vibecheck-engines/index.js +0 -15
  181. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +0 -164
  182. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +0 -291
  183. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +0 -83
  184. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +0 -198
  185. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +0 -275
  186. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +0 -167
  187. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +0 -217
  188. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +0 -139
  189. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +0 -140
  190. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +0 -164
  191. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +0 -234
  192. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +0 -217
  193. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +0 -78
  194. package/bin/runners/lib/engines/vibecheck-engines/package.json +0 -13
  195. package/bin/runners/lib/exit-codes.js +0 -275
  196. package/bin/runners/lib/fingerprint.js +0 -377
  197. package/bin/runners/lib/help-formatter.js +0 -413
  198. package/bin/runners/lib/logger.js +0 -38
  199. package/bin/runners/lib/ship-output-enterprise.js +0 -239
  200. package/bin/runners/lib/unified-cli-output.js +0 -604
  201. package/bin/runners/runAgent.d.ts +0 -5
  202. package/bin/runners/runAgent.js +0 -161
  203. package/bin/runners/runApprove.js +0 -1200
  204. package/bin/runners/runClassify.js +0 -859
  205. package/bin/runners/runContext.d.ts +0 -4
  206. package/bin/runners/runFirewall.d.ts +0 -5
  207. package/bin/runners/runFirewall.js +0 -134
  208. package/bin/runners/runFirewallHook.d.ts +0 -5
  209. package/bin/runners/runFirewallHook.js +0 -56
  210. package/bin/runners/runPolish.d.ts +0 -4
  211. package/bin/runners/runProof.zip +0 -0
  212. package/bin/runners/runTruth.d.ts +0 -5
  213. package/bin/runners/runTruth.js +0 -101
  214. package/mcp-server/HARDENING_SUMMARY.md +0 -299
  215. package/mcp-server/agent-firewall-interceptor.js +0 -500
  216. package/mcp-server/authority-tools.js +0 -569
  217. package/mcp-server/conductor/conflict-resolver.js +0 -588
  218. package/mcp-server/conductor/execution-planner.js +0 -544
  219. package/mcp-server/conductor/index.js +0 -377
  220. package/mcp-server/conductor/lock-manager.js +0 -615
  221. package/mcp-server/conductor/request-queue.js +0 -550
  222. package/mcp-server/conductor/session-manager.js +0 -500
  223. package/mcp-server/conductor/tools.js +0 -510
  224. package/mcp-server/lib/api-client.cjs +0 -13
  225. package/mcp-server/lib/logger.cjs +0 -30
  226. package/mcp-server/logger.js +0 -173
  227. package/mcp-server/tools-v3.js +0 -706
  228. package/mcp-server/vibecheck-mcp-server-3.2.0.tgz +0 -0
@@ -1,39 +1,22 @@
1
1
  /**
2
2
  * runContext.js - AI Rules Generator
3
3
  *
4
- * ═══════════════════════════════════════════════════════════════════════════════
5
- * World-Class AI Context Generation
6
- * ═══════════════════════════════════════════════════════════════════════════════
4
+ * Generates .cursorrules, .windsurf/rules, and other AI context files.
7
5
  */
8
6
 
9
7
  const path = require("path");
10
- const fs = require("fs");
11
8
  const { runContext: contextRunner } = require("./context");
12
- const { parseGlobalFlags, shouldShowBanner, shouldSuppressOutput, isJsonMode } = require("./lib/global-flags");
13
- const { EXIT } = require("./lib/exit-codes");
14
- const {
15
- ansi,
16
- sym,
17
- renderMinimalHeader,
18
- renderSectionHeader,
19
- renderSuccess,
20
- renderError,
21
- renderBullet,
22
- renderFooter,
23
- Spinner,
24
- getTierFromKey,
25
- } = require("./lib/unified-cli-output");
9
+ const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
26
10
 
27
11
  async function runContext(args) {
12
+ // Parse global flags first
28
13
  const { flags: globalFlags, cleanArgs } = parseGlobalFlags(args);
29
- const quiet = shouldSuppressOutput(globalFlags);
30
- const json = isJsonMode(globalFlags);
14
+
31
15
  const root = globalFlags.path || process.cwd();
32
- const startTime = Date.now();
33
16
 
34
17
  // Parse command-specific args
35
18
  const opts = {
36
- ...globalFlags,
19
+ ...globalFlags, // Merge global flags (includes help, json, noBanner, etc.)
37
20
  output: null,
38
21
  format: "all"
39
22
  };
@@ -46,129 +29,34 @@ async function runContext(args) {
46
29
  }
47
30
 
48
31
  if (opts.help) {
49
- console.log(`
50
- ${ansi.bold}USAGE${ansi.reset}
51
- ${ansi.cyan}vibecheck context${ansi.reset} [options]
52
-
53
- ${ansi.dim}Aliases: rules, ai-rules, mdc${ansi.reset}
54
-
55
- Generate project-aware AI coding rules for your IDE. These rules help
56
- AI assistants understand your codebase conventions, preventing common
57
- mistakes and enforcing patterns.
58
-
59
- ${ansi.bold}FORMATS${ansi.reset}
60
- ${ansi.cyan}cursor${ansi.reset} .cursorrules file for Cursor IDE
61
- ${ansi.cyan}mdc${ansi.reset} MDC format (.cursor/rules/*.mdc)
62
- ${ansi.cyan}windsurf${ansi.reset} Windsurf rules directory
63
- ${ansi.cyan}copilot${ansi.reset} GitHub Copilot instructions
64
- ${ansi.cyan}all${ansi.reset} Generate all formats (default)
65
-
66
- ${ansi.bold}OPTIONS${ansi.reset}
67
- ${ansi.cyan}-f, --format <fmt>${ansi.reset} Format to generate (default: all)
68
- ${ansi.cyan}-o, --output <dir>${ansi.reset} Output directory (default: project root)
69
- ${ansi.cyan}--json${ansi.reset} Output result as JSON
70
- ${ansi.cyan}--quiet, -q${ansi.reset} Suppress non-essential output
71
- ${ansi.cyan}--help, -h${ansi.reset} Show this help
72
-
73
- ${ansi.bold}EXAMPLES${ansi.reset}
74
- ${ansi.dim}# Generate all rule files${ansi.reset}
75
- vibecheck context
76
-
77
- ${ansi.dim}# Generate only Cursor rules${ansi.reset}
78
- vibecheck context --format cursor
79
-
80
- ${ansi.dim}# Custom output directory${ansi.reset}
81
- vibecheck context --output ./ai-rules
82
-
83
- ${ansi.bold}OUTPUT FILES${ansi.reset}
84
- .cursorrules Cursor IDE rules
85
- .cursor/rules/*.mdc MDC format rules
86
- .windsurf/rules/*.md Windsurf rules
87
- .github/copilot-instructions.md
88
-
89
- ${ansi.dim}────────────────────────────────────────────────────────────────────${ansi.reset}
90
- ${ansi.dim}Documentation: https://docs.vibecheckai.dev/cli/context${ansi.reset}
32
+ const banner = shouldShowBanner(opts) ? `
33
+ ${require('./lib/global-flags').BANNER || ''}
34
+ ` : '';
35
+ console.log(`${banner}
36
+ vibecheck context - Generate AI rules files
37
+
38
+ USAGE
39
+ vibecheck context Generate all AI rules files
40
+ vibecheck context --format X Generate specific format (cursor, windsurf, all)
41
+
42
+ OPTIONS
43
+ -o, --output <dir> Output directory (default: project root)
44
+ -f, --format <fmt> Format: cursor, windsurf, all (default: all)
45
+ -h, --help Show this help
91
46
  `);
92
- return EXIT.SUCCESS;
93
- }
94
-
95
- // Validate project path exists
96
- if (!fs.existsSync(root)) {
97
- if (json) {
98
- console.log(JSON.stringify({ success: false, error: `Project path does not exist: ${root}` }));
99
- } else {
100
- renderError(`Project path does not exist: ${root}`);
101
- console.log(` ${ansi.dim}Verify the path and try again.${ansi.reset}`);
102
- }
103
- return EXIT.NOT_FOUND;
104
- }
105
-
106
- // Validate format option
107
- const validFormats = ["all", "cursor", "mdc", "windsurf", "copilot"];
108
- if (!validFormats.includes(opts.format)) {
109
- if (json) {
110
- console.log(JSON.stringify({ success: false, error: `Unknown format: ${opts.format}`, validFormats }));
111
- } else {
112
- renderError(`Unknown format: ${opts.format}`);
113
- console.log(` ${ansi.dim}Valid formats: ${validFormats.join(", ")}${ansi.reset}`);
114
- }
115
- return EXIT.USER_ERROR;
47
+ return 0;
116
48
  }
117
49
 
118
50
  try {
119
- if (!quiet && !json) {
120
- renderMinimalHeader("context", "starter");
121
- renderSectionHeader("Generating AI Rules", sym.gear);
122
- }
123
-
124
- const spinner = !quiet && !json ? new Spinner(`Analyzing project and generating ${opts.format} rules`).start() : null;
125
-
126
- const result = await contextRunner({
51
+ await contextRunner({
127
52
  repoRoot: root,
128
53
  output: opts.output,
129
54
  format: opts.format
130
55
  });
131
-
132
- const duration = Date.now() - startTime;
133
-
134
- if (json) {
135
- console.log(JSON.stringify({
136
- success: true,
137
- format: opts.format,
138
- files: result?.files || [],
139
- path: root,
140
- duration,
141
- }));
142
- } else if (!quiet) {
143
- spinner?.succeed("AI rules generated successfully");
144
-
145
- // Show generated files
146
- if (result?.files && result.files.length > 0) {
147
- console.log();
148
- console.log(` ${ansi.bold}Generated files:${ansi.reset}`);
149
- result.files.forEach(f => {
150
- renderBullet(`${ansi.cyan}${f}${ansi.reset}`, 4);
151
- });
152
- }
153
-
154
- renderFooter({
155
- nextSteps: [
156
- { cmd: "vibecheck scan", desc: "analyze code quality" },
157
- { cmd: "vibecheck guard", desc: "validate AI outputs" },
158
- ],
159
- docsUrl: "https://docs.vibecheckai.dev/cli/context",
160
- });
161
- }
162
-
163
- return EXIT.SUCCESS;
56
+ return 0;
164
57
  } catch (error) {
165
- if (json) {
166
- console.log(JSON.stringify({ success: false, error: error.message }));
167
- } else {
168
- renderError(`Failed to generate context: ${error.message}`);
169
- console.log(` ${ansi.dim}Run "vibecheck doctor" to check your setup.${ansi.reset}`);
170
- }
171
- return EXIT.INTERNAL_ERROR;
58
+ console.error("Error generating context:", error.message);
59
+ return 1;
172
60
  }
173
61
  }
174
62
 
@@ -18,10 +18,7 @@ const {
18
18
  verdictToExitCode,
19
19
  saveArtifact
20
20
  } = require("./lib/cli-output");
21
- const { parseGlobalFlags, shouldShowBanner, shouldSuppressOutput, isJsonMode } = require("./lib/global-flags");
22
- const { EXIT } = require("./lib/exit-codes");
23
- const { formatWorkflowUpsell } = require("./lib/upsell");
24
- const { getApiKey } = require("./lib/auth");
21
+ const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
25
22
 
26
23
  // ═══════════════════════════════════════════════════════════════════════════════
27
24
  // ADVANCED TERMINAL - ANSI CODES & UTILITIES
@@ -301,110 +298,86 @@ async function runDoctor(args, context = {}) {
301
298
  const startTime = context.startTime || new Date().toISOString();
302
299
 
303
300
  const opts = parseArgs(args);
304
- const quiet = shouldSuppressOutput(opts);
305
- const json = isJsonMode(opts);
306
301
  const executionStart = Date.now();
307
302
 
308
303
  if (opts.help) {
309
304
  printHelp(shouldShowBanner(opts));
310
- return EXIT.SUCCESS;
305
+ return 0;
311
306
  }
312
307
 
313
308
  const projectPath = path.resolve(opts.path || process.cwd());
309
+ const projectName = path.basename(projectPath);
314
310
 
315
- // Validate project path exists
316
- if (!fs.existsSync(projectPath)) {
317
- if (json) {
318
- console.log(JSON.stringify({ success: false, error: `Project path does not exist: ${projectPath}` }));
319
- } else {
320
- console.error(` ❌ Project path does not exist: ${projectPath}`);
321
- }
322
- return EXIT.NOT_FOUND;
311
+ // Print banner conditionally
312
+ if (shouldShowBanner(opts)) {
313
+ printBanner();
314
+ console.log(` ${c.dim}Project:${c.reset} ${c.bold}${projectName}${c.reset}`);
315
+ console.log(` ${c.dim}Path:${c.reset} ${projectPath}`);
316
+ console.log();
323
317
  }
324
- const projectName = path.basename(projectPath);
325
318
 
326
- try {
327
- // Print banner conditionally
328
- if (shouldShowBanner(opts) && !quiet) {
329
- printBanner();
330
- console.log(` ${c.dim}Project:${c.reset} ${c.bold}${projectName}${c.reset}`);
331
- console.log(` ${c.dim}Path:${c.reset} ${projectPath}`);
332
- console.log();
333
- }
319
+ // Use new DoctorService if available
320
+ if (DoctorService.name === 'DoctorService') {
321
+ const doctor = new DoctorService(projectPath, {
322
+ json: opts.json,
323
+ fix: opts.fix,
324
+ fixDryRun: opts.dryRun,
325
+ quiet: opts.quiet,
326
+ verbose: opts.verbose,
327
+ categories: opts.categories,
328
+ skipNetwork: opts.skipNetwork,
329
+ saveReport: opts.saveReport,
330
+ failOnWarn: opts.failOnWarn,
331
+ runId,
332
+ });
334
333
 
335
- // Use new DoctorService if available
336
- if (DoctorService.name === 'DoctorService') {
337
- const doctor = new DoctorService(projectPath, {
338
- json: opts.json,
339
- fix: opts.fix,
340
- fixDryRun: opts.dryRun,
341
- quiet: opts.quiet || quiet,
342
- verbose: opts.verbose,
343
- categories: opts.categories,
344
- skipNetwork: opts.skipNetwork,
345
- saveReport: opts.saveReport,
346
- failOnWarn: opts.failOnWarn,
334
+ const results = await doctor.run();
335
+
336
+ // Apply CLI output conventions
337
+ if (opts.json) {
338
+ const output = createJsonOutput({
347
339
  runId,
340
+ command: "doctor",
341
+ startTime,
342
+ exitCode: results.exitCode || 0,
343
+ verdict: exitCodeToVerdict(results.exitCode || 0),
344
+ result: {
345
+ health: results.health || "unknown",
346
+ checks: results.checks || [],
347
+ fixes: results.fixes || [],
348
+ summary: {
349
+ total: results.totalChecks || 0,
350
+ passed: results.passedChecks || 0,
351
+ warnings: results.warnings || 0,
352
+ errors: results.errors || 0,
353
+ }
354
+ },
355
+ tier: "free",
356
+ version: require("../../package.json").version,
357
+ artifacts: results.reportPath ? [{
358
+ type: "report",
359
+ path: results.reportPath,
360
+ description: "Doctor report"
361
+ }] : []
348
362
  });
349
363
 
350
- const results = await doctor.run();
351
-
352
- // Apply CLI output conventions
353
- if (opts.json || json) {
354
- const output = createJsonOutput({
355
- runId,
356
- command: "doctor",
357
- startTime,
358
- exitCode: results.exitCode || EXIT.SUCCESS,
359
- verdict: exitCodeToVerdict(results.exitCode || EXIT.SUCCESS),
360
- result: {
361
- health: results.health || "unknown",
362
- checks: results.checks || [],
363
- fixes: results.fixes || [],
364
- summary: {
365
- total: results.totalChecks || 0,
366
- passed: results.passedChecks || 0,
367
- warnings: results.warnings || 0,
368
- errors: results.errors || 0,
369
- }
370
- },
371
- tier: "free",
372
- version: require("../../package.json").version,
373
- artifacts: results.reportPath ? [{
374
- type: "report",
375
- path: results.reportPath,
376
- description: "Doctor report"
377
- }] : []
378
- });
379
-
380
- writeJsonOutput(output, opts.output);
381
- }
382
-
383
- // Save artifacts
384
- if (results.checks) {
385
- saveArtifact(runId, "checks", results.checks);
386
- }
387
- if (results.fixes) {
388
- saveArtifact(runId, "fixes", results.fixes);
389
- }
390
-
391
- // Map results to proper exit codes
392
- if (results.errors > 0) return EXIT.BLOCKING;
393
- if (results.warnings > 0) return EXIT.WARNINGS;
394
- return EXIT.SUCCESS;
364
+ writeJsonOutput(output, opts.output);
395
365
  }
396
366
 
397
- // Legacy fallback
398
- const doctor = new DoctorService(projectPath, opts);
399
- return await doctor.diagnose();
400
- } catch (error) {
401
- if (json) {
402
- console.log(JSON.stringify({ success: false, error: error.message }));
403
- } else {
404
- console.error(` ❌ Doctor check failed: ${error.message}`);
367
+ // Save artifacts
368
+ if (results.checks) {
369
+ saveArtifact(runId, "checks", results.checks);
370
+ }
371
+ if (results.fixes) {
372
+ saveArtifact(runId, "fixes", results.fixes);
405
373
  }
406
- return EXIT.INTERNAL_ERROR;
374
+
375
+ return results.exitCode || 0;
407
376
  }
377
+
378
+ // Legacy fallback
379
+ const doctor = new DoctorService(projectPath, opts);
380
+ return await doctor.diagnose();
408
381
  }
409
382
 
410
383
  function parseArgs(args) {
@@ -600,33 +573,12 @@ function runDoctorLegacy() {
600
573
  }
601
574
 
602
575
  console.log("");
603
-
604
- // Get tier for upsell
605
- const { key } = getApiKey();
606
- const currentTier = key ? "starter" : "free";
607
-
608
576
  if (hasIssues) {
609
- console.log(" ❌ Issues found. Fix them and run doctor again.");
610
- console.log();
611
- console.log(` ${c.dim}Need help?${c.reset} ${colors.accent}vibecheck fix${c.reset} ${c.dim}can auto-repair many issues${c.reset}`);
612
- if (currentTier === "free") {
613
- console.log(` ${c.dim}Requires STARTER plan • vibecheckai.dev${c.reset}`);
614
- }
615
- console.log();
616
- return EXIT.BLOCKING;
577
+ console.log(" ❌ Issues found. Fix them and run doctor again.\n");
578
+ return 2;
617
579
  } else {
618
- console.log(" ✅ Environment healthy!");
619
- console.log();
620
-
621
- // Workflow upsell
622
- const workflow = formatWorkflowUpsell("doctor", currentTier);
623
- if (workflow) {
624
- console.log(` ${workflow}`);
625
- } else {
626
- console.log(` ${c.dim}Ready to scan?${c.reset} ${colors.accent}vibecheck scan${c.reset} ${c.dim}finds AI mistakes before they ship${c.reset}`);
627
- }
628
- console.log();
629
- return EXIT.SUCCESS;
580
+ console.log(" ✅ Environment healthy!\n");
581
+ return 0;
630
582
  }
631
583
  }
632
584
 
@@ -0,0 +1,219 @@
1
+ /**
2
+ * vibecheck evidence-pack - Bundle Proof Artifacts
3
+ *
4
+ * ═══════════════════════════════════════════════════════════════════════════════
5
+ * Creates shareable evidence packs from vibecheck proof runs.
6
+ * Bundles videos, traces, screenshots, and findings into a single artifact.
7
+ * ═══════════════════════════════════════════════════════════════════════════════
8
+ */
9
+
10
+ "use strict";
11
+
12
+ const fs = require("fs");
13
+ const path = require("path");
14
+ const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
15
+
16
+ // Colors
17
+ const c = {
18
+ reset: '\x1b[0m',
19
+ bold: '\x1b[1m',
20
+ dim: '\x1b[2m',
21
+ green: '\x1b[32m',
22
+ yellow: '\x1b[33m',
23
+ cyan: '\x1b[36m',
24
+ red: '\x1b[31m',
25
+ };
26
+
27
+ const rgb = (r, g, b) => `\x1b[38;2;${r};${g};${b}m`;
28
+
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),
34
+ };
35
+
36
+ const ICONS = {
37
+ pack: '📦',
38
+ check: '✓',
39
+ cross: '✗',
40
+ video: '🎥',
41
+ trace: '📊',
42
+ screenshot: '📸',
43
+ file: '📄',
44
+ };
45
+
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
+ console.log(`
59
+ ${c.bold}Usage:${c.reset} vibecheck evidence-pack [options]
60
+
61
+ ${c.bold}Bundle Proof Artifacts${c.reset} — Create shareable evidence packs.
62
+
63
+ ${c.bold}What It Bundles:${c.reset}
64
+ ${ICONS.video} ${c.dim}Videos${c.reset} Browser session recordings
65
+ ${ICONS.trace} ${c.dim}Traces${c.reset} Playwright traces (view at trace.playwright.dev)
66
+ ${ICONS.screenshot} ${c.dim}Screenshots${c.reset} Finding screenshots
67
+ ${ICONS.file} ${c.dim}Reports${c.reset} JSON reports with evidence
68
+
69
+ ${c.bold}Options:${c.reset}
70
+ ${colors.accent}--output, -o <path>${c.reset} Output zip path ${c.dim}(default: .vibecheck/evidence-packs/)${c.reset}
71
+ ${colors.accent}--no-videos${c.reset} Exclude video recordings
72
+ ${colors.accent}--no-traces${c.reset} Exclude Playwright traces
73
+ ${colors.accent}--no-screenshots${c.reset} Exclude screenshots
74
+ ${colors.accent}--no-allowlist${c.reset} Don't filter by allowlist
75
+ ${colors.accent}--markdown${c.reset} Generate markdown report
76
+ ${colors.accent}--json${c.reset} Output JSON manifest only
77
+ ${colors.accent}--help, -h${c.reset} Show this help
78
+
79
+ ${c.bold}Examples:${c.reset}
80
+ ${c.dim}# Create evidence pack${c.reset}
81
+ vibecheck evidence-pack
82
+
83
+ ${c.dim}# Custom output path${c.reset}
84
+ vibecheck evidence-pack --output ./artifacts/proof.zip
85
+
86
+ ${c.dim}# Generate markdown report${c.reset}
87
+ vibecheck evidence-pack --markdown > evidence-report.md
88
+
89
+ ${c.dim}# Exclude large files${c.reset}
90
+ vibecheck evidence-pack --no-videos --no-traces
91
+ `);
92
+ }
93
+
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;
104
+ }
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
+ }
125
+
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;
147
+ }
148
+
149
+ if (!quiet && !json) {
150
+ console.log(`\n ${ICONS.pack} ${c.bold}Building Evidence Pack${c.reset}\n`);
151
+ }
152
+
153
+ 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);
165
+ return pack.summary.verdict === 'SHIP' ? 0 : pack.summary.verdict === 'WARN' ? 1 : 2;
166
+ }
167
+
168
+ if (json) {
169
+ console.log(JSON.stringify(pack.manifest, null, 2));
170
+ return pack.summary.verdict === 'SHIP' ? 0 : pack.summary.verdict === 'WARN' ? 1 : 2;
171
+ }
172
+
173
+ // Print summary
174
+ const { summary, manifest } = pack;
175
+ const verdictColor = summary.verdict === 'SHIP' ? colors.success :
176
+ summary.verdict === 'WARN' ? colors.warning : colors.error;
177
+
178
+ console.log(` ${c.dim}Pack ID:${c.reset} ${pack.id}`);
179
+ 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)`);
181
+ console.log();
182
+
183
+ // Artifact summary
184
+ const artifacts = manifest.artifacts;
185
+ if (artifacts.screenshots.length > 0) {
186
+ console.log(` ${ICONS.screenshot} Screenshots: ${artifacts.screenshots.length}`);
187
+ }
188
+ if (artifacts.videos.length > 0) {
189
+ console.log(` ${ICONS.video} Videos: ${artifacts.videos.length}`);
190
+ }
191
+ if (artifacts.traces.length > 0) {
192
+ console.log(` ${ICONS.trace} Traces: ${artifacts.traces.length}`);
193
+ }
194
+
195
+ 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
+ }
200
+ console.log();
201
+
202
+ // Tips
203
+ if (artifacts.traces.length > 0) {
204
+ console.log(` ${c.dim}View traces at: ${c.cyan}https://trace.playwright.dev${c.reset}`);
205
+ }
206
+
207
+ return summary.verdict === 'SHIP' ? 0 : summary.verdict === 'WARN' ? 1 : 2;
208
+
209
+ } catch (error) {
210
+ if (json) {
211
+ console.log(JSON.stringify({ error: error.message }, null, 2));
212
+ } else {
213
+ console.error(`\n ${colors.error}${ICONS.cross}${c.reset} ${error.message}\n`);
214
+ }
215
+ return 1;
216
+ }
217
+ }
218
+
219
+ module.exports = { runEvidencePack };
@@ -33,7 +33,6 @@ 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');
37
36
 
38
37
  // Entitlements enforcement
39
38
  const entitlements = require('./lib/entitlements-v2');
@@ -697,7 +696,7 @@ async function runFix(args) {
697
696
  } catch (e) {
698
697
  stopSpinner('LLM failed', false);
699
698
  console.log(` ${colors.blockRed}${ICONS.cross}${c.reset} ${e.message}`);
700
- return EXIT.INTERNAL_ERROR;
699
+ return 1;
701
700
  }
702
701
 
703
702
  const respPath = path.join(outDir, `step_${String(step).padStart(2,"0")}_${mission.id}_response.json`);
@@ -723,7 +722,7 @@ async function runFix(args) {
723
722
  console.log(` ${colors.warnAmber}${ICONS.warning}${c.reset} ${w}`);
724
723
  }
725
724
  }
726
- return EXIT.BLOCKING;
725
+ return 1;
727
726
  }
728
727
 
729
728
  if (v.warnings.length) {
@@ -754,7 +753,7 @@ async function runFix(args) {
754
753
  console.log(` ${colors.blockRed}${ICONS.cross}${c.reset} Patch apply failed: ${res.error}`);
755
754
  restoreBackup(root, backupRoot);
756
755
  console.log(` ${colors.rollback}${ICONS.rollback}${c.reset} Restored from backup`);
757
- return EXIT.INTERNAL_ERROR;
756
+ return 1;
758
757
  }
759
758
  console.log(` ${colors.patch}${ICONS.patch}${c.reset} Applied: ${c.dim}${ed.path}${c.reset}`);
760
759
  }
@@ -790,7 +789,7 @@ async function runFix(args) {
790
789
  console.log();
791
790
  console.log(` ${colors.blockRed}${ICONS.stop}${c.reset} Stopping: stagnation limit reached (${stagnant}/${stagnationLimit})`);
792
791
  console.log();
793
- return EXIT.BLOCKING;
792
+ return 1;
794
793
  }
795
794
  continue;
796
795
  }
@@ -821,7 +820,7 @@ async function runFix(args) {
821
820
  }
822
821
  }
823
822
 
824
- return EXIT.WARNINGS; // Max steps reached, incomplete
823
+ return 1;
825
824
  }
826
825
 
827
826
  // ═══════════════════════════════════════════════════════════════════════════════