@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
@@ -0,0 +1,275 @@
1
+ /**
2
+ * Vibecheck CLI Exit Codes - Standardized for World-Class UX
3
+ *
4
+ * ═══════════════════════════════════════════════════════════════════════════════
5
+ * EXIT CODE REFERENCE
6
+ * ═══════════════════════════════════════════════════════════════════════════════
7
+ *
8
+ * Standard Unix conventions extended for CLI tooling:
9
+ *
10
+ * 0 SUCCESS Command completed successfully, no issues found
11
+ * 1 WARNINGS Command completed with warnings (non-blocking issues)
12
+ * 2 BLOCKING Command found blocking issues (critical/high severity)
13
+ * 3 USER_ERROR Invalid arguments, missing required flags, bad input
14
+ * 4 NOT_FOUND Command not found, file not found, resource missing
15
+ * 5 AUTH_REQUIRED Authentication required but not provided
16
+ * 6 AUTH_FAILED Authentication failed (invalid/expired credentials)
17
+ * 7 TIER_REQUIRED Feature requires higher subscription tier
18
+ * 8 RATE_LIMITED API rate limit exceeded
19
+ * 9 NETWORK_ERROR Network connectivity issue
20
+ * 10 INTERNAL_ERROR Unexpected internal error
21
+ *
22
+ * CI-Friendly: Exit codes 0-2 are "soft" (scan results), 3+ are "hard" (errors)
23
+ * ═══════════════════════════════════════════════════════════════════════════════
24
+ */
25
+
26
+ "use strict";
27
+
28
+ // ═══════════════════════════════════════════════════════════════════════════════
29
+ // EXIT CODE CONSTANTS
30
+ // ═══════════════════════════════════════════════════════════════════════════════
31
+
32
+ const EXIT = {
33
+ // Success states (0-2)
34
+ SUCCESS: 0, // All good, no issues
35
+ WARNINGS: 1, // Completed with warnings (medium/low severity)
36
+ BLOCKING: 2, // Blocking issues found (critical/high severity)
37
+
38
+ // User errors (3-4)
39
+ USER_ERROR: 3, // Bad args, invalid input, usage error
40
+ NOT_FOUND: 4, // Resource/command/file not found
41
+
42
+ // Auth errors (5-7)
43
+ AUTH_REQUIRED: 5, // Need to log in
44
+ AUTH_FAILED: 6, // Bad credentials
45
+ TIER_REQUIRED: 7, // Need higher plan
46
+
47
+ // Transient errors (8-9)
48
+ RATE_LIMITED: 8, // Try again later
49
+ NETWORK_ERROR: 9, // Connectivity issue
50
+
51
+ // Fatal errors (10+)
52
+ INTERNAL_ERROR: 10, // Bug, unexpected error
53
+
54
+ // Process signals (standard Unix)
55
+ SIGINT: 130, // Ctrl+C
56
+ SIGTERM: 143, // kill
57
+ };
58
+
59
+ // ═══════════════════════════════════════════════════════════════════════════════
60
+ // EXIT CODE METADATA
61
+ // ═══════════════════════════════════════════════════════════════════════════════
62
+
63
+ const EXIT_INFO = {
64
+ [EXIT.SUCCESS]: {
65
+ name: "SUCCESS",
66
+ description: "Command completed successfully",
67
+ ciStatus: "success",
68
+ recoverable: true,
69
+ },
70
+ [EXIT.WARNINGS]: {
71
+ name: "WARNINGS",
72
+ description: "Completed with warnings (non-blocking issues)",
73
+ ciStatus: "warning",
74
+ recoverable: true,
75
+ },
76
+ [EXIT.BLOCKING]: {
77
+ name: "BLOCKING",
78
+ description: "Blocking issues found (critical/high severity)",
79
+ ciStatus: "failure",
80
+ recoverable: true,
81
+ },
82
+ [EXIT.USER_ERROR]: {
83
+ name: "USER_ERROR",
84
+ description: "Invalid arguments or usage",
85
+ ciStatus: "failure",
86
+ recoverable: true,
87
+ hint: "Check command usage with --help",
88
+ },
89
+ [EXIT.NOT_FOUND]: {
90
+ name: "NOT_FOUND",
91
+ description: "Resource not found",
92
+ ciStatus: "failure",
93
+ recoverable: true,
94
+ hint: "Verify the path or resource exists",
95
+ },
96
+ [EXIT.AUTH_REQUIRED]: {
97
+ name: "AUTH_REQUIRED",
98
+ description: "Authentication required",
99
+ ciStatus: "failure",
100
+ recoverable: true,
101
+ hint: "Run 'vibecheck login' to authenticate",
102
+ },
103
+ [EXIT.AUTH_FAILED]: {
104
+ name: "AUTH_FAILED",
105
+ description: "Authentication failed",
106
+ ciStatus: "failure",
107
+ recoverable: true,
108
+ hint: "Check your API key or run 'vibecheck login' again",
109
+ },
110
+ [EXIT.TIER_REQUIRED]: {
111
+ name: "TIER_REQUIRED",
112
+ description: "Higher subscription tier required",
113
+ ciStatus: "failure",
114
+ recoverable: true,
115
+ hint: "Upgrade at https://vibecheckai.dev/pricing",
116
+ },
117
+ [EXIT.RATE_LIMITED]: {
118
+ name: "RATE_LIMITED",
119
+ description: "Rate limit exceeded",
120
+ ciStatus: "failure",
121
+ recoverable: true,
122
+ hint: "Wait a moment and try again",
123
+ },
124
+ [EXIT.NETWORK_ERROR]: {
125
+ name: "NETWORK_ERROR",
126
+ description: "Network connectivity issue",
127
+ ciStatus: "failure",
128
+ recoverable: true,
129
+ hint: "Check your internet connection or try --offline mode",
130
+ },
131
+ [EXIT.INTERNAL_ERROR]: {
132
+ name: "INTERNAL_ERROR",
133
+ description: "Unexpected internal error",
134
+ ciStatus: "failure",
135
+ recoverable: false,
136
+ hint: "Please report this issue at https://github.com/vibecheckai/vibecheck/issues",
137
+ },
138
+ };
139
+
140
+ // ═══════════════════════════════════════════════════════════════════════════════
141
+ // HELPER FUNCTIONS
142
+ // ═══════════════════════════════════════════════════════════════════════════════
143
+
144
+ /**
145
+ * Convert verdict string to exit code
146
+ * @param {string} verdict - SHIP, WARN, BLOCK, PASS, FAIL
147
+ * @returns {number} exit code
148
+ */
149
+ function verdictToExitCode(verdict) {
150
+ const v = String(verdict).toUpperCase();
151
+ if (v === "SHIP" || v === "PASS" || v === "SUCCESS" || v === "OK") {
152
+ return EXIT.SUCCESS;
153
+ }
154
+ if (v === "WARN" || v === "WARNING" || v === "WARNINGS") {
155
+ return EXIT.WARNINGS;
156
+ }
157
+ if (v === "BLOCK" || v === "FAIL" || v === "FAILURE" || v === "ERROR") {
158
+ return EXIT.BLOCKING;
159
+ }
160
+ return EXIT.WARNINGS; // Default to warnings for unknown
161
+ }
162
+
163
+ /**
164
+ * Convert exit code to verdict string
165
+ * @param {number} exitCode
166
+ * @returns {string} verdict
167
+ */
168
+ function exitCodeToVerdict(exitCode) {
169
+ switch (exitCode) {
170
+ case EXIT.SUCCESS: return "SHIP";
171
+ case EXIT.WARNINGS: return "WARN";
172
+ case EXIT.BLOCKING: return "BLOCK";
173
+ default: return "BLOCK";
174
+ }
175
+ }
176
+
177
+ /**
178
+ * Get exit info for an exit code
179
+ * @param {number} exitCode
180
+ * @returns {object} exit info
181
+ */
182
+ function getExitInfo(exitCode) {
183
+ return EXIT_INFO[exitCode] || EXIT_INFO[EXIT.INTERNAL_ERROR];
184
+ }
185
+
186
+ /**
187
+ * Check if exit code represents success (including warnings)
188
+ * @param {number} exitCode
189
+ * @returns {boolean}
190
+ */
191
+ function isSuccess(exitCode) {
192
+ return exitCode === EXIT.SUCCESS;
193
+ }
194
+
195
+ /**
196
+ * Check if exit code represents a "soft" failure (scan results, not errors)
197
+ * @param {number} exitCode
198
+ * @returns {boolean}
199
+ */
200
+ function isSoftFailure(exitCode) {
201
+ return exitCode === EXIT.WARNINGS || exitCode === EXIT.BLOCKING;
202
+ }
203
+
204
+ /**
205
+ * Check if exit code represents a "hard" failure (errors)
206
+ * @param {number} exitCode
207
+ * @returns {boolean}
208
+ */
209
+ function isHardFailure(exitCode) {
210
+ return exitCode >= EXIT.USER_ERROR;
211
+ }
212
+
213
+ /**
214
+ * Check if the error is recoverable (user can fix and retry)
215
+ * @param {number} exitCode
216
+ * @returns {boolean}
217
+ */
218
+ function isRecoverable(exitCode) {
219
+ const info = EXIT_INFO[exitCode];
220
+ return info ? info.recoverable : false;
221
+ }
222
+
223
+ /**
224
+ * Get hint message for exit code
225
+ * @param {number} exitCode
226
+ * @returns {string|null}
227
+ */
228
+ function getHint(exitCode) {
229
+ const info = EXIT_INFO[exitCode];
230
+ return info?.hint || null;
231
+ }
232
+
233
+ /**
234
+ * Get CI status for exit code
235
+ * @param {number} exitCode
236
+ * @returns {string} "success" | "warning" | "failure"
237
+ */
238
+ function getCIStatus(exitCode) {
239
+ const info = EXIT_INFO[exitCode];
240
+ return info?.ciStatus || "failure";
241
+ }
242
+
243
+ /**
244
+ * Create an error object with proper exit code
245
+ * @param {string} message
246
+ * @param {number} exitCode
247
+ * @param {object} details
248
+ * @returns {Error}
249
+ */
250
+ function createExitError(message, exitCode, details = {}) {
251
+ const error = new Error(message);
252
+ error.exitCode = exitCode;
253
+ error.exitInfo = getExitInfo(exitCode);
254
+ Object.assign(error, details);
255
+ return error;
256
+ }
257
+
258
+ // ═══════════════════════════════════════════════════════════════════════════════
259
+ // EXPORTS
260
+ // ═══════════════════════════════════════════════════════════════════════════════
261
+
262
+ module.exports = {
263
+ EXIT,
264
+ EXIT_INFO,
265
+ verdictToExitCode,
266
+ exitCodeToVerdict,
267
+ getExitInfo,
268
+ isSuccess,
269
+ isSoftFailure,
270
+ isHardFailure,
271
+ isRecoverable,
272
+ getHint,
273
+ getCIStatus,
274
+ createExitError,
275
+ };
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Finding ID Generation - Stable, Deterministic IDs
3
+ *
4
+ * Generates stable finding IDs that remain consistent across rescans.
5
+ * Same finding should get same ID for proper tracking and deduplication.
6
+ */
7
+
8
+ const crypto = require('crypto');
9
+
10
+ /**
11
+ * @typedef {Object} FindingInput
12
+ * @property {string} rule - Rule ID (e.g., 'SEC001')
13
+ * @property {string} file - File path
14
+ * @property {number} line - Line number
15
+ * @property {number} [column] - Column number (optional)
16
+ * @property {string} message - Finding message
17
+ */
18
+
19
+ /**
20
+ * Generate stable, deterministic finding ID.
21
+ * Same finding on rescan should get same ID.
22
+ *
23
+ * @param {FindingInput} finding - Finding input data
24
+ * @returns {string} Stable finding ID (format: vbc_<16-char-hex>)
25
+ */
26
+ function generateFindingId(finding) {
27
+ const components = [
28
+ finding.rule || 'UNKNOWN',
29
+ finding.file || '',
30
+ String(finding.line || 0),
31
+ String(finding.column || 0),
32
+ ];
33
+
34
+ const hash = crypto
35
+ .createHash('sha256')
36
+ .update(components.join(':'))
37
+ .digest('hex')
38
+ .slice(0, 16);
39
+
40
+ return `vbc_${hash}`;
41
+ }
42
+
43
+ /**
44
+ * Generate deduplication key for finding.
45
+ * Used to detect duplicate findings across scans.
46
+ *
47
+ * Note: Line number is excluded for fuzzy matching (same issue on different lines)
48
+ *
49
+ * @param {FindingInput} finding - Finding input data
50
+ * @returns {string} Deduplication key (64-char hex)
51
+ */
52
+ function generateDeduplicationKey(finding) {
53
+ const components = [
54
+ finding.rule || 'UNKNOWN',
55
+ finding.file || '',
56
+ // Line number excluded for fuzzy matching
57
+ (finding.message || '').slice(0, 100), // First 100 chars of message
58
+ ];
59
+
60
+ return crypto
61
+ .createHash('sha256')
62
+ .update(components.join(':'))
63
+ .digest('hex');
64
+ }
65
+
66
+ module.exports = {
67
+ generateFindingId,
68
+ generateDeduplicationKey,
69
+ };
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Finding Sorter - Deterministic Ordering
3
+ *
4
+ * Sorts findings deterministically for stable output across runs.
5
+ * Order: severity DESC, file ASC, line ASC, rule ASC
6
+ */
7
+
8
+ /**
9
+ * @typedef {Object} Finding
10
+ * @property {string} severity - critical, high, medium, low, info
11
+ * @property {string} file - File path
12
+ * @property {number} line - Line number
13
+ * @property {string} rule - Rule ID
14
+ * @property {string} [category] - Category
15
+ * @property {string} [title] - Title
16
+ */
17
+
18
+ /**
19
+ * Severity order mapping (lower number = higher priority)
20
+ */
21
+ const SEVERITY_ORDER = {
22
+ critical: 0,
23
+ high: 1,
24
+ medium: 2,
25
+ low: 3,
26
+ info: 4,
27
+ };
28
+
29
+ /**
30
+ * Sort findings deterministically for stable output.
31
+ * Order: severity DESC, file ASC, line ASC, rule ASC
32
+ *
33
+ * @param {Finding[]} findings - Array of findings to sort
34
+ * @returns {Finding[]} Sorted findings array
35
+ */
36
+ function sortFindings(findings) {
37
+ return [...findings].sort((a, b) => {
38
+ // 1. Severity (critical first)
39
+ const sevA = SEVERITY_ORDER[a.severity?.toLowerCase()] ?? 5;
40
+ const sevB = SEVERITY_ORDER[b.severity?.toLowerCase()] ?? 5;
41
+ if (sevA !== sevB) return sevA - sevB;
42
+
43
+ // 2. File path (alphabetical)
44
+ const fileA = (a.file || '').toLowerCase();
45
+ const fileB = (b.file || '').toLowerCase();
46
+ const fileCompare = fileA.localeCompare(fileB);
47
+ if (fileCompare !== 0) return fileCompare;
48
+
49
+ // 3. Line number
50
+ const lineA = a.line || 0;
51
+ const lineB = b.line || 0;
52
+ if (lineA !== lineB) return lineA - lineB;
53
+
54
+ // 4. Rule ID (alphabetical)
55
+ const ruleA = (a.rule || a.ruleId || '').toLowerCase();
56
+ const ruleB = (b.rule || b.ruleId || '').toLowerCase();
57
+ return ruleA.localeCompare(ruleB);
58
+ });
59
+ }
60
+
61
+ /**
62
+ * Generate stable JSON output (sorted keys, consistent spacing)
63
+ *
64
+ * @param {unknown} obj - Object to stringify
65
+ * @returns {string} Stable JSON string
66
+ */
67
+ function stableStringify(obj) {
68
+ if (typeof obj !== 'object' || obj === null) {
69
+ return JSON.stringify(obj);
70
+ }
71
+
72
+ if (Array.isArray(obj)) {
73
+ return '[' + obj.map(stableStringify).join(',') + ']';
74
+ }
75
+
76
+ // Sort keys for stable output
77
+ const sortedKeys = Object.keys(obj).sort();
78
+ const pairs = sortedKeys.map(key => {
79
+ const value = obj[key];
80
+ return JSON.stringify(key) + ':' + stableStringify(value);
81
+ });
82
+
83
+ return '{' + pairs.join(',') + '}';
84
+ }
85
+
86
+ module.exports = {
87
+ sortFindings,
88
+ stableStringify,
89
+ };