@vibecheckai/cli 3.5.1 → 3.5.3

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
@@ -1,12 +1,20 @@
1
1
  /**
2
2
  * Standardized error handling for CLI runners
3
3
  *
4
+ * ═══════════════════════════════════════════════════════════════════════════════
5
+ * World-Class Error Handling
6
+ * ═══════════════════════════════════════════════════════════════════════════════
7
+ *
4
8
  * Design principles:
5
9
  * - Every error has a human-readable message
6
10
  * - Every error suggests a next step
7
11
  * - Exit codes are consistent and documented
12
+ * - Errors include "receipt" (file:line evidence) where possible
13
+ * - Debug mode shows stack traces
8
14
  */
9
15
 
16
+ const { EXIT, getExitInfo, getHint } = require("./exit-codes");
17
+
10
18
  const colors = {
11
19
  reset: "\x1b[0m",
12
20
  red: "\x1b[31m",
@@ -24,16 +32,15 @@ const c = {
24
32
  dim: (text) => `\x1b[2m${text}${colors.reset}`,
25
33
  };
26
34
 
27
- // Standard exit codes for CI/CD integration
28
- // Unified with packages/cli/src/runtime/exit-codes.ts
29
- // IMPORTANT: These codes are part of the CLI contract - do not change without migration guide
35
+ // Re-export EXIT for backward compatibility
36
+ // NOTE: Prefer importing from exit-codes.js directly
30
37
  const EXIT_CODES = {
31
- SUCCESS: 0, // Scan passed, no policy violations
32
- POLICY_FAIL: 1, // Findings above threshold (policy fail) - actionable by user
33
- USER_ERROR: 2, // User error: invalid args, bad config, missing required options
34
- SYSTEM_ERROR: 3, // System error: crash, filesystem issues, unexpected exceptions
35
- AUTH_FAILURE: 4, // Auth/entitlement failure: invalid key, expired token, insufficient tier
36
- NETWORK_FAILURE: 5, // Network/backend failure: API unreachable, timeout
38
+ SUCCESS: EXIT.SUCCESS,
39
+ POLICY_FAIL: EXIT.WARNINGS, // Findings above threshold (policy fail)
40
+ USER_ERROR: EXIT.USER_ERROR, // User error: invalid args, bad config
41
+ SYSTEM_ERROR: EXIT.INTERNAL_ERROR, // System error: crash, unexpected exceptions
42
+ AUTH_FAILURE: EXIT.AUTH_REQUIRED, // Auth/entitlement failure
43
+ NETWORK_FAILURE: EXIT.NETWORK_ERROR, // Network/backend failure
37
44
  };
38
45
 
39
46
  // Error-specific guidance
@@ -153,8 +160,26 @@ function handleError(error, context = "", metadata = {}) {
153
160
  // Get specific guidance
154
161
  const guidance = getErrorGuidance(err);
155
162
 
163
+ // Check for JSON mode (via NO_COLOR env var or explicit check)
164
+ const isJsonMode = process.env.NO_COLOR === '1' || process.env.VIBECHECK_JSON === '1';
165
+
156
166
  // Print error header
157
167
  if (guidance) {
168
+ if (isJsonMode) {
169
+ // JSON error output
170
+ const errorOutput = {
171
+ success: false,
172
+ error: {
173
+ code: err.code || err.name || 'ERROR',
174
+ message: message,
175
+ type: guidance.title,
176
+ nextSteps: guidance.nextSteps,
177
+ },
178
+ exitCode: err.exitCode || 1
179
+ };
180
+ console.error(JSON.stringify(errorOutput, null, 2));
181
+ return;
182
+ }
158
183
  console.error(`\n${c.error("✗")} ${c.error(guidance.title)}`);
159
184
  console.error(` ${message}`);
160
185
 
@@ -164,8 +189,20 @@ function handleError(error, context = "", metadata = {}) {
164
189
  console.error(` ${c.dim("•")} ${step}`);
165
190
  }
166
191
  } else {
192
+ // Check for JSON mode
193
+ const isJsonMode = process.env.NO_COLOR === '1' || process.env.VIBECHECK_JSON === '1';
194
+
167
195
  // Generic error handling with specific type detection
168
196
  if (err.code === "ENOENT") {
197
+ if (isJsonMode) {
198
+ const errorOutput = {
199
+ success: false,
200
+ error: { code: 'ENOENT', message: err.path || message, receipt },
201
+ exitCode: 4
202
+ };
203
+ console.error(JSON.stringify(errorOutput, null, 2));
204
+ return;
205
+ }
169
206
  console.error(`\n${c.error("✗")} File or directory not found`);
170
207
  console.error(` ${err.path || message}`);
171
208
  // Print receipt if available
@@ -206,6 +243,15 @@ function handleError(error, context = "", metadata = {}) {
206
243
  console.error(` ${c.dim("•")} Verify VIBECHECK_API_URL is correct`);
207
244
  } else {
208
245
  // Generic error
246
+ if (isJsonMode) {
247
+ const errorOutput = {
248
+ success: false,
249
+ error: { code: err.code || err.name || 'ERROR', message, receipt },
250
+ exitCode: err.exitCode || 1
251
+ };
252
+ console.error(JSON.stringify(errorOutput, null, 2));
253
+ return;
254
+ }
209
255
  console.error(`\n${c.error("✗")} Error`);
210
256
  console.error(` ${message}`);
211
257
  // Print receipt if available
@@ -222,13 +268,15 @@ function handleError(error, context = "", metadata = {}) {
222
268
  }
223
269
  }
224
270
 
225
- // Show stack trace in debug mode
226
- if (process.env.DEBUG || process.env.VIBECHECK_DEBUG) {
271
+ // Show stack trace in debug mode (skip in JSON mode)
272
+ if (!isJsonMode && (process.env.DEBUG || process.env.VIBECHECK_DEBUG)) {
227
273
  console.error(`\n${c.dim("Stack trace:")}`);
228
274
  console.error(c.dim(err.stack));
229
275
  }
230
276
 
231
- console.error(""); // Empty line for readability
277
+ if (!isJsonMode) {
278
+ console.error(""); // Empty line for readability
279
+ }
232
280
  }
233
281
 
234
282
  /**
@@ -0,0 +1,289 @@
1
+ /**
2
+ * Actionable Error Messages
3
+ *
4
+ * Provides standardized error messages with actionable next steps,
5
+ * documentation links, and clear guidance for users.
6
+ */
7
+
8
+ const { EXIT } = require('./exit-codes');
9
+
10
+ const DOCS_BASE_URL = 'https://docs.vibecheckai.dev';
11
+ const DASHBOARD_URL = 'https://app.vibecheckai.dev';
12
+
13
+ /**
14
+ * Format an actionable error message
15
+ */
16
+ function formatError(error, context = {}) {
17
+ const {
18
+ command = '',
19
+ suggestion = null,
20
+ docsLink = null,
21
+ nextSteps = [],
22
+ code = null,
23
+ } = context;
24
+
25
+ const lines = [];
26
+
27
+ // Main error message
28
+ lines.push(`\n ❌ ${error.message || error}`);
29
+
30
+ // Error code if provided
31
+ if (code) {
32
+ lines.push(`\n Code: ${code}`);
33
+ }
34
+
35
+ // Next steps
36
+ if (nextSteps.length > 0) {
37
+ lines.push(`\n Next steps:`);
38
+ nextSteps.forEach((step, i) => {
39
+ lines.push(` ${i + 1}. ${step}`);
40
+ });
41
+ } else if (suggestion) {
42
+ lines.push(`\n 💡 ${suggestion}`);
43
+ }
44
+
45
+ // Documentation link
46
+ if (docsLink) {
47
+ lines.push(`\n 📖 Docs: ${docsLink}`);
48
+ } else if (command) {
49
+ lines.push(`\n 📖 Docs: ${DOCS_BASE_URL}/commands/${command}`);
50
+ }
51
+
52
+ lines.push('');
53
+
54
+ return lines.join('\n');
55
+ }
56
+
57
+ /**
58
+ * Common error templates with actionable guidance
59
+ */
60
+ const ERROR_TEMPLATES = {
61
+ PROJECT_NOT_INITIALIZED: {
62
+ message: 'Project not initialized',
63
+ suggestion: 'Run `vibecheck init` to set up your project',
64
+ nextSteps: [
65
+ 'Run: vibecheck init',
66
+ 'This creates .vibecheckrc config file',
67
+ 'Then run: vibecheck scan',
68
+ ],
69
+ docsLink: `${DOCS_BASE_URL}/getting-started/init`,
70
+ },
71
+
72
+ NO_SCAN_RESULTS: {
73
+ message: 'No scan results found',
74
+ suggestion: 'Run `vibecheck scan` first to generate results',
75
+ nextSteps: [
76
+ 'Run: vibecheck scan',
77
+ 'This analyzes your codebase',
78
+ 'Then re-run this command',
79
+ ],
80
+ docsLink: `${DOCS_BASE_URL}/commands/scan`,
81
+ },
82
+
83
+ NO_TRUTHPACK: {
84
+ message: 'No truthpack found',
85
+ suggestion: 'Run `vibecheck context` to generate truthpack',
86
+ nextSteps: [
87
+ 'Run: vibecheck context',
88
+ 'This generates route/auth/env mapping',
89
+ 'Then re-run this command',
90
+ ],
91
+ docsLink: `${DOCS_BASE_URL}/commands/context`,
92
+ },
93
+
94
+ AUTH_REQUIRED: {
95
+ message: 'Authentication required',
96
+ suggestion: 'Run `vibecheck login` to authenticate',
97
+ nextSteps: [
98
+ 'Run: vibecheck login',
99
+ 'Enter your API key',
100
+ 'Get your key from: https://app.vibecheckai.dev/settings/api-keys',
101
+ ],
102
+ docsLink: `${DOCS_BASE_URL}/getting-started/authentication`,
103
+ },
104
+
105
+ INVALID_API_KEY: {
106
+ message: 'Invalid API key format',
107
+ suggestion: 'Check your API key format',
108
+ nextSteps: [
109
+ 'API keys should start with vc_',
110
+ 'Get a new key: https://app.vibecheckai.dev/settings/api-keys',
111
+ 'Run: vibecheck login --key YOUR_KEY',
112
+ ],
113
+ docsLink: `${DOCS_BASE_URL}/getting-started/authentication`,
114
+ },
115
+
116
+ TIER_REQUIRED: {
117
+ message: 'This feature requires PRO tier',
118
+ suggestion: 'Upgrade to PRO to access this feature',
119
+ nextSteps: [
120
+ 'Visit: https://app.vibecheckai.dev/pricing',
121
+ 'Upgrade your account',
122
+ 'Re-run this command',
123
+ ],
124
+ docsLink: `${DOCS_BASE_URL}/pricing`,
125
+ },
126
+
127
+ PROJECT_PATH_NOT_FOUND: {
128
+ message: 'Project path does not exist',
129
+ suggestion: 'Check the path and try again',
130
+ nextSteps: [
131
+ 'Verify the path exists: ls <path>',
132
+ 'Use absolute path if relative path fails',
133
+ 'Run: vibecheck init --path <path>',
134
+ ],
135
+ docsLink: `${DOCS_BASE_URL}/commands/init`,
136
+ },
137
+
138
+ CONFIG_INVALID: {
139
+ message: 'Invalid configuration file',
140
+ suggestion: 'Run `vibecheck doctor --fix` to repair config',
141
+ nextSteps: [
142
+ 'Run: vibecheck doctor --fix',
143
+ 'This auto-fixes common config issues',
144
+ 'Or manually edit .vibecheckrc',
145
+ ],
146
+ docsLink: `${DOCS_BASE_URL}/configuration`,
147
+ },
148
+
149
+ NETWORK_ERROR: {
150
+ message: 'Network connection failed',
151
+ suggestion: 'Check your internet connection or use --offline mode',
152
+ nextSteps: [
153
+ 'Check internet connection',
154
+ 'Or run with --offline flag for local-only mode',
155
+ 'Example: vibecheck scan --offline',
156
+ ],
157
+ docsLink: `${DOCS_BASE_URL}/commands/scan#offline-mode`,
158
+ },
159
+
160
+ MISSING_DEPENDENCY: {
161
+ message: 'Missing required dependency',
162
+ suggestion: 'Install missing dependencies',
163
+ nextSteps: [
164
+ 'Run: npm install',
165
+ 'Or: pnpm install',
166
+ 'Check package.json for required packages',
167
+ ],
168
+ docsLink: `${DOCS_BASE_URL}/troubleshooting/dependencies`,
169
+ },
170
+ };
171
+
172
+ /**
173
+ * Get error template by key
174
+ */
175
+ function getErrorTemplate(key, overrides = {}) {
176
+ const template = ERROR_TEMPLATES[key];
177
+ if (!template) {
178
+ return {
179
+ message: key,
180
+ suggestion: 'Check the documentation for help',
181
+ docsLink: DOCS_BASE_URL,
182
+ };
183
+ }
184
+
185
+ return { ...template, ...overrides };
186
+ }
187
+
188
+ /**
189
+ * Print actionable error and return exit code
190
+ */
191
+ function printActionableError(errorKey, context = {}) {
192
+ const template = getErrorTemplate(errorKey, context);
193
+ const error = {
194
+ message: template.message,
195
+ code: context.code || errorKey,
196
+ };
197
+
198
+ const formatted = formatError(error, {
199
+ ...context,
200
+ suggestion: template.suggestion,
201
+ nextSteps: template.nextSteps || [],
202
+ docsLink: template.docsLink,
203
+ });
204
+
205
+ console.error(formatted);
206
+
207
+ // Map error keys to exit codes
208
+ const exitCodeMap = {
209
+ AUTH_REQUIRED: EXIT.AUTH_REQUIRED,
210
+ INVALID_API_KEY: EXIT.AUTH_FAILED,
211
+ TIER_REQUIRED: EXIT.TIER_REQUIRED,
212
+ PROJECT_PATH_NOT_FOUND: EXIT.USER_ERROR,
213
+ CONFIG_INVALID: EXIT.USER_ERROR,
214
+ NETWORK_ERROR: EXIT.NETWORK_ERROR || 1,
215
+ MISSING_DEPENDENCY: EXIT.USER_ERROR,
216
+ PROJECT_NOT_INITIALIZED: EXIT.USER_ERROR,
217
+ NO_SCAN_RESULTS: EXIT.NOT_FOUND || 1,
218
+ NO_TRUTHPACK: EXIT.NOT_FOUND || 1,
219
+ };
220
+
221
+ return exitCodeMap[errorKey] || EXIT.USER_ERROR;
222
+ }
223
+
224
+ /**
225
+ * Enhance existing error with actionable guidance
226
+ */
227
+ function enhanceError(error, command = '', additionalContext = {}) {
228
+ const errorMessage = error.message || String(error);
229
+ const lowerMessage = errorMessage.toLowerCase();
230
+
231
+ // Detect error type from message
232
+ if (lowerMessage.includes('not initialized') || lowerMessage.includes('no config')) {
233
+ return printActionableError('PROJECT_NOT_INITIALIZED', { command, ...additionalContext });
234
+ }
235
+
236
+ if (lowerMessage.includes('scan result') || lowerMessage.includes('no results')) {
237
+ return printActionableError('NO_SCAN_RESULTS', { command, ...additionalContext });
238
+ }
239
+
240
+ if (lowerMessage.includes('truthpack') || lowerMessage.includes('context')) {
241
+ return printActionableError('NO_TRUTHPACK', { command, ...additionalContext });
242
+ }
243
+
244
+ if (lowerMessage.includes('auth') && (lowerMessage.includes('required') || lowerMessage.includes('unauthorized'))) {
245
+ return printActionableError('AUTH_REQUIRED', { command, ...additionalContext });
246
+ }
247
+
248
+ if (lowerMessage.includes('api key') && (lowerMessage.includes('invalid') || lowerMessage.includes('format'))) {
249
+ return printActionableError('INVALID_API_KEY', { command, ...additionalContext });
250
+ }
251
+
252
+ if (lowerMessage.includes('tier') || lowerMessage.includes('pro') || lowerMessage.includes('upgrade')) {
253
+ return printActionableError('TIER_REQUIRED', { command, ...additionalContext });
254
+ }
255
+
256
+ if (lowerMessage.includes('path') && (lowerMessage.includes('not found') || lowerMessage.includes('does not exist'))) {
257
+ return printActionableError('PROJECT_PATH_NOT_FOUND', { command, path: additionalContext.path });
258
+ }
259
+
260
+ if (lowerMessage.includes('config') && (lowerMessage.includes('invalid') || lowerMessage.includes('error'))) {
261
+ return printActionableError('CONFIG_INVALID', { command, ...additionalContext });
262
+ }
263
+
264
+ if (lowerMessage.includes('network') || lowerMessage.includes('connection') || lowerMessage.includes('fetch')) {
265
+ return printActionableError('NETWORK_ERROR', { command, ...additionalContext });
266
+ }
267
+
268
+ if (lowerMessage.includes('cannot find module') || lowerMessage.includes('missing')) {
269
+ return printActionableError('MISSING_DEPENDENCY', { command, dependency: additionalContext.dependency });
270
+ }
271
+
272
+ // Default: print enhanced error
273
+ console.error(formatError(error, {
274
+ command,
275
+ suggestion: additionalContext.suggestion || 'Check the documentation for help',
276
+ docsLink: additionalContext.docsLink || `${DOCS_BASE_URL}/commands/${command}`,
277
+ nextSteps: additionalContext.nextSteps || [],
278
+ }));
279
+
280
+ return EXIT.USER_ERROR;
281
+ }
282
+
283
+ module.exports = {
284
+ formatError,
285
+ getErrorTemplate,
286
+ printActionableError,
287
+ enhanceError,
288
+ ERROR_TEMPLATES,
289
+ };
@@ -14,7 +14,13 @@
14
14
  const fs = require("fs");
15
15
  const path = require("path");
16
16
  const crypto = require("crypto");
17
- const archiver = require("archiver");
17
+ // Make archiver optional - only required for zip creation
18
+ let archiver;
19
+ try {
20
+ archiver = require("archiver");
21
+ } catch {
22
+ archiver = null;
23
+ }
18
24
 
19
25
  // ═══════════════════════════════════════════════════════════════════════════════
20
26
  // EVIDENCE PACK SCHEMA