@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
@@ -18,14 +18,6 @@ const { withErrorHandling, createUserError } = require("./lib/error-handler");
18
18
  const { enforceLimit, trackUsage } = require("./lib/entitlements");
19
19
  const { emitScanStart, emitScanComplete } = require("./lib/audit-bridge");
20
20
  const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
21
- const {
22
- createScan,
23
- updateScanProgress,
24
- submitScanResults,
25
- reportScanError,
26
- isApiAvailable
27
- } = require("./lib/api-client");
28
- const { EXIT, verdictToExitCode } = require("./lib/exit-codes");
29
21
 
30
22
  // ═══════════════════════════════════════════════════════════════════════════════
31
23
  // ENHANCED TERMINAL UI & OUTPUT MODULES
@@ -50,11 +42,6 @@ const {
50
42
  calculateScore,
51
43
  } = require("./lib/scan-output");
52
44
 
53
- const {
54
- enrichFindings,
55
- saveBaseline,
56
- } = require("./lib/fingerprint");
57
-
58
45
  const BANNER = `
59
46
  ${ansi.rgb(0, 200, 255)} ██╗ ██╗██╗██████╗ ███████╗ ██████╗██╗ ██╗███████╗ ██████╗██╗ ██╗${ansi.reset}
60
47
  ${ansi.rgb(30, 180, 255)} ██║ ██║██║██╔══██╗██╔════╝██╔════╝██║ ██║██╔════╝██╔════╝██║ ██╔╝${ansi.reset}
@@ -116,17 +103,6 @@ function parseArgs(args) {
116
103
  noBanner: globalFlags.noBanner || false,
117
104
  ci: globalFlags.ci || false,
118
105
  quiet: globalFlags.quiet || false,
119
- // Baseline tracking (fingerprints)
120
- baseline: true, // Compare against baseline by default
121
- updateBaseline: false, // --update-baseline to save current findings as baseline
122
- // Allowlist subcommand
123
- allowlist: null, // null = not using allowlist, or 'list' | 'add' | 'remove' | 'check'
124
- allowlistId: null,
125
- allowlistPattern: null,
126
- allowlistReason: null,
127
- allowlistScope: 'global',
128
- allowlistFile: null,
129
- allowlistExpires: null,
130
106
  };
131
107
 
132
108
  // Parse command-specific args from cleanArgs
@@ -140,26 +116,8 @@ function parseArgs(args) {
140
116
  else if (arg === '--sarif') opts.sarif = true;
141
117
  else if (arg === '--autofix' || arg === '--fix' || arg === '-f') opts.autofix = true;
142
118
  else if (arg === '--no-save') opts.save = false;
143
- else if (arg === '--no-baseline') opts.baseline = false;
144
- else if (arg === '--update-baseline' || arg === '--set-baseline') opts.updateBaseline = true;
145
119
  else if (arg === '--path' || arg === '-p') opts.path = cleanArgs[++i] || process.cwd();
146
120
  else if (arg.startsWith('--path=')) opts.path = arg.split('=')[1];
147
- // Allowlist subcommand support
148
- else if (arg === '--allowlist') {
149
- const nextArg = cleanArgs[i + 1];
150
- if (nextArg && !nextArg.startsWith('-')) {
151
- opts.allowlist = nextArg;
152
- i++;
153
- } else {
154
- opts.allowlist = 'list'; // Default to list
155
- }
156
- }
157
- else if (arg === '--id' && opts.allowlist) opts.allowlistId = cleanArgs[++i];
158
- else if (arg === '--pattern' && opts.allowlist) opts.allowlistPattern = cleanArgs[++i];
159
- else if (arg === '--reason' && opts.allowlist) opts.allowlistReason = cleanArgs[++i];
160
- else if (arg === '--scope' && opts.allowlist) opts.allowlistScope = cleanArgs[++i];
161
- else if (arg === '--file' && opts.allowlist) opts.allowlistFile = cleanArgs[++i];
162
- else if (arg === '--expires' && opts.allowlist) opts.allowlistExpires = cleanArgs[++i];
163
121
  else if (!arg.startsWith('-')) opts.path = path.resolve(arg);
164
122
  }
165
123
 
@@ -171,244 +129,46 @@ function printHelp(showBanner = true) {
171
129
  console.log(BANNER);
172
130
  }
173
131
  console.log(`
174
- ${ansi.bold}USAGE${ansi.reset}
175
- ${colors.accent}vibecheck scan${ansi.reset} [path] [options]
132
+ ${ansi.bold}Usage:${ansi.reset} vibecheck scan ${ansi.dim}(s)${ansi.reset} [path] [options]
176
133
 
177
- ${ansi.dim}Aliases: s, check${ansi.reset}
178
-
179
- The core analysis engine. Scans your codebase for route integrity issues,
180
- security vulnerabilities, code quality problems, and more.
181
-
182
- ${ansi.bold}SCAN LAYERS${ansi.reset}
183
- ${colors.accent}(default)${ansi.reset} Layer 1: AST static analysis ${ansi.dim}(fast, ~2s)${ansi.reset}
184
- ${colors.accent}--truth, -t${ansi.reset} Layer 1+2: + build manifest verification ${ansi.dim}(CI/ship)${ansi.reset}
185
- ${colors.accent}--reality, -r${ansi.reset} Layer 1+2+3: + Playwright runtime proof ${ansi.dim}[PRO]${ansi.reset}
186
- ${colors.accent}--reality-sniff${ansi.reset} Include Reality Sniff AI artifact detection
187
-
188
- ${ansi.bold}FIX MODE${ansi.reset} ${ansi.cyan}[STARTER]${ansi.reset}
189
- ${colors.accent}--autofix, -f${ansi.reset} Generate AI fix missions for detected issues
190
-
191
- ${ansi.bold}BASELINE TRACKING${ansi.reset}
192
- ${colors.accent}--baseline${ansi.reset} Compare against previous scan ${ansi.dim}(default: on)${ansi.reset}
193
- ${colors.accent}--no-baseline${ansi.reset} Skip baseline comparison
194
- ${colors.accent}--update-baseline${ansi.reset} Save current findings as new baseline
195
-
196
- ${ansi.bold}ALLOWLIST (suppress false positives)${ansi.reset}
197
- ${colors.accent}--allowlist list${ansi.reset} Show all suppressed findings
198
- ${colors.accent}--allowlist add --id <id> --reason "..."${ansi.reset}
199
- ${colors.accent}--allowlist remove --id <id>${ansi.reset} Remove suppression
200
- ${colors.accent}--allowlist check --id <id>${ansi.reset} Check if suppressed
201
-
202
- ${ansi.bold}OUTPUT OPTIONS${ansi.reset}
203
- ${colors.accent}--json${ansi.reset} Output as JSON ${ansi.dim}(machine-readable)${ansi.reset}
204
- ${colors.accent}--sarif${ansi.reset} SARIF format ${ansi.dim}(GitHub code scanning)${ansi.reset}
205
- ${colors.accent}--no-save${ansi.reset} Don't save results to .vibecheck/results/
206
- ${colors.accent}--verbose, -v${ansi.reset} Show detailed progress
207
-
208
- ${ansi.bold}GLOBAL OPTIONS${ansi.reset}
209
- ${colors.accent}--path, -p <dir>${ansi.reset} Run in specified directory
210
- ${colors.accent}--quiet, -q${ansi.reset} Suppress non-essential output
211
- ${colors.accent}--ci${ansi.reset} CI mode ${ansi.dim}(quiet + no-banner)${ansi.reset}
212
- ${colors.accent}--help, -h${ansi.reset} Show this help
213
-
214
- ${ansi.bold}💡 EXAMPLES${ansi.reset}
215
-
216
- ${ansi.dim}# Quick scan (most common)${ansi.reset}
134
+ ${ansi.bold}Aliases:${ansi.reset} ${ansi.dim}s${ansi.reset}
135
+
136
+ ${ansi.bold}Scan Modes:${ansi.reset}
137
+ ${colors.accent}(default)${ansi.reset} Layer 1: AST static analysis ${ansi.dim}(fast)${ansi.reset}
138
+ ${colors.accent}--truth, -t${ansi.reset} Layer 1+2: Include build manifest verification ${ansi.dim}(CI/ship)${ansi.reset}
139
+ ${colors.accent}--reality, -r${ansi.reset} Layer 1+2+3: Include Playwright runtime proof ${ansi.dim}(full)${ansi.reset}
140
+ ${colors.accent}--reality-sniff${ansi.reset} Include Reality Sniff AI artifact detection ${ansi.dim}(recommended)${ansi.reset}
141
+
142
+ ${ansi.bold}Fix Mode:${ansi.reset}
143
+ ${colors.accent}--autofix, -f${ansi.reset} Apply safe fixes + generate AI missions ${ansi.rgb(0, 200, 255)}[STARTER]${ansi.reset}
144
+
145
+ ${ansi.bold}Options:${ansi.reset}
146
+ ${colors.accent}--url, -u${ansi.reset} Base URL for reality testing (e.g., http://localhost:3000)
147
+ ${colors.accent}--verbose, -v${ansi.reset} Show detailed progress
148
+ ${colors.accent}--json${ansi.reset} Output results as JSON
149
+ ${colors.accent}--sarif${ansi.reset} Output in SARIF format (GitHub code scanning)
150
+ ${colors.accent}--no-save${ansi.reset} Don't save results to .vibecheck/results/
151
+ ${colors.accent}--help, -h${ansi.reset} Show this help
152
+
153
+ ${ansi.bold}Examples:${ansi.reset}
154
+ ${ansi.dim}# Quick scan (AST only)${ansi.reset}
217
155
  vibecheck scan
218
156
 
219
- ${ansi.dim}# Scan with AI fix missions${ansi.reset}
157
+ ${ansi.dim}# Scan + autofix with missions${ansi.reset}
220
158
  vibecheck scan --autofix
221
159
 
222
- ${ansi.dim}# Suppress a false positive${ansi.reset}
223
- vibecheck scan --allowlist add --id R_DEAD_abc123 --reason "Feature toggle"
224
-
225
- ${ansi.dim}# CI pipeline (JSON output, strict)${ansi.reset}
226
- vibecheck scan --ci --json > results.json
160
+ ${ansi.dim}# CI/CD scan with manifest verification${ansi.reset}
161
+ vibecheck scan --truth
227
162
 
228
- ${ansi.dim}# Full reality proof (requires running app)${ansi.reset}
163
+ ${ansi.dim}# Full proof with Playwright${ansi.reset}
229
164
  vibecheck scan --reality --url http://localhost:3000
230
165
 
231
- ${ansi.bold}📄 OUTPUT${ansi.reset}
232
- Results: .vibecheck/results/latest.json
233
- Missions: .vibecheck/missions/ ${ansi.dim}(with --autofix)${ansi.reset}
234
- History: .vibecheck/results/history/
235
-
236
- ${ansi.bold}🔗 RELATED COMMANDS${ansi.reset}
237
- ${colors.accent}vibecheck ship${ansi.reset} Get final SHIP/WARN/BLOCK verdict
238
- ${colors.accent}vibecheck fix${ansi.reset} Apply AI-generated fixes ${ansi.cyan}[STARTER]${ansi.reset}
239
- ${colors.accent}vibecheck prove${ansi.reset} Full proof pipeline with evidence ${ansi.magenta}[PRO]${ansi.reset}
240
-
241
- ${ansi.dim}─────────────────────────────────────────────────────────────${ansi.reset}
242
- ${ansi.dim}Documentation: https://docs.vibecheckai.dev/cli/scan${ansi.reset}
166
+ ${ansi.bold}Output:${ansi.reset}
167
+ Results saved to: .vibecheck/results/latest.json
168
+ Missions saved to: .vibecheck/missions/ ${ansi.dim}(with --autofix)${ansi.reset}
243
169
  `);
244
170
  }
245
171
 
246
- // ═══════════════════════════════════════════════════════════════════════════════
247
- // ALLOWLIST MANAGEMENT (integrated from runAllowlist)
248
- // ═══════════════════════════════════════════════════════════════════════════════
249
-
250
- async function handleAllowlistCommand(opts) {
251
- const root = opts.path || process.cwd();
252
-
253
- // Load evidence-pack module for allowlist functions
254
- let evidencePack;
255
- try {
256
- evidencePack = require("./lib/evidence-pack");
257
- } catch (e) {
258
- console.error(`${colors.error}✗${ansi.reset} Failed to load allowlist module: ${e.message}`);
259
- return 1;
260
- }
261
-
262
- const action = opts.allowlist;
263
-
264
- try {
265
- switch (action) {
266
- case "list": {
267
- const allowlist = evidencePack.loadAllowlist(root);
268
-
269
- if (opts.json) {
270
- console.log(JSON.stringify(allowlist, null, 2));
271
- return 0;
272
- }
273
-
274
- if (!opts.quiet) {
275
- console.log(`\n 📋 ${ansi.bold}Allowlist Entries${ansi.reset}\n`);
276
- }
277
-
278
- if (!allowlist.entries || allowlist.entries.length === 0) {
279
- console.log(` ${ansi.dim}No entries in allowlist.${ansi.reset}\n`);
280
- console.log(` ${ansi.dim}Add entries with: vibecheck scan --allowlist add --id <id> --reason "..."${ansi.reset}\n`);
281
- return 0;
282
- }
283
-
284
- for (const entry of allowlist.entries) {
285
- const expireStr = entry.expiresAt
286
- ? `${ansi.dim}expires ${new Date(entry.expiresAt).toLocaleDateString()}${ansi.reset}`
287
- : '';
288
- const scopeStr = entry.scope !== 'global'
289
- ? `${colors.accent}[${entry.scope}]${ansi.reset} `
290
- : '';
291
-
292
- console.log(` ${colors.success}✓${ansi.reset} ${ansi.bold}${entry.id}${ansi.reset} ${scopeStr}${expireStr}`);
293
-
294
- if (entry.findingId) {
295
- console.log(` ${ansi.dim}Finding:${ansi.reset} ${entry.findingId}`);
296
- }
297
- if (entry.pattern) {
298
- console.log(` ${ansi.dim}Pattern:${ansi.reset} ${entry.pattern}`);
299
- }
300
- console.log(` ${ansi.dim}Reason:${ansi.reset} ${entry.reason || 'No reason provided'}`);
301
- console.log(` ${ansi.dim}Added:${ansi.reset} ${entry.addedAt} by ${entry.addedBy || 'user'}`);
302
- console.log();
303
- }
304
-
305
- console.log(` ${ansi.dim}Total: ${allowlist.entries.length} entries${ansi.reset}\n`);
306
- return 0;
307
- }
308
-
309
- case "add": {
310
- if (!opts.allowlistId && !opts.allowlistPattern) {
311
- console.error(`\n ${colors.error}✗${ansi.reset} Either --id or --pattern is required\n`);
312
- return 1;
313
- }
314
-
315
- if (!opts.allowlistReason) {
316
- console.error(`\n ${colors.error}✗${ansi.reset} --reason is required\n`);
317
- return 1;
318
- }
319
-
320
- const entry = {
321
- findingId: opts.allowlistId,
322
- pattern: opts.allowlistPattern,
323
- reason: opts.allowlistReason,
324
- scope: opts.allowlistScope,
325
- addedBy: 'cli'
326
- };
327
-
328
- if (opts.allowlistFile) entry.file = opts.allowlistFile;
329
- if (opts.allowlistExpires) {
330
- const days = parseInt(opts.allowlistExpires, 10);
331
- entry.expiresAt = new Date(Date.now() + days * 24 * 60 * 60 * 1000).toISOString();
332
- }
333
-
334
- const added = evidencePack.addToAllowlist(root, entry);
335
-
336
- if (opts.json) {
337
- console.log(JSON.stringify({ added }, null, 2));
338
- return 0;
339
- }
340
-
341
- console.log(`\n ${colors.success}+${ansi.reset} Added allowlist entry: ${ansi.bold}${added.id}${ansi.reset}\n`);
342
- return 0;
343
- }
344
-
345
- case "remove": {
346
- if (!opts.allowlistId) {
347
- console.error(`\n ${colors.error}✗${ansi.reset} --id is required for remove\n`);
348
- return 1;
349
- }
350
-
351
- const allowlist = evidencePack.loadAllowlist(root);
352
- const before = allowlist.entries.length;
353
- allowlist.entries = allowlist.entries.filter(e => e.id !== opts.allowlistId && e.findingId !== opts.allowlistId);
354
- const removed = before - allowlist.entries.length;
355
-
356
- if (removed > 0) {
357
- evidencePack.saveAllowlist(root, allowlist);
358
- }
359
-
360
- if (opts.json) {
361
- console.log(JSON.stringify({ removed, remaining: allowlist.entries.length }, null, 2));
362
- return 0;
363
- }
364
-
365
- if (removed > 0) {
366
- console.log(`\n ${colors.success}-${ansi.reset} Removed ${removed} entry from allowlist\n`);
367
- } else {
368
- console.log(`\n ${colors.warning}⚠${ansi.reset} Entry not found: ${opts.allowlistId}\n`);
369
- }
370
- return 0;
371
- }
372
-
373
- case "check": {
374
- if (!opts.allowlistId) {
375
- console.error(`\n ${colors.error}✗${ansi.reset} --id is required for check\n`);
376
- return 1;
377
- }
378
-
379
- const allowlist = evidencePack.loadAllowlist(root);
380
- const result = evidencePack.isAllowlisted({ id: opts.allowlistId }, allowlist);
381
-
382
- if (opts.json) {
383
- console.log(JSON.stringify(result, null, 2));
384
- return result.allowed ? 0 : 1;
385
- }
386
-
387
- if (result.allowed) {
388
- console.log(`\n ${colors.success}✓${ansi.reset} ${ansi.bold}Allowlisted${ansi.reset}`);
389
- console.log(` ${ansi.dim}Reason:${ansi.reset} ${result.reason}`);
390
- console.log(` ${ansi.dim}Entry:${ansi.reset} ${result.entry?.id}\n`);
391
- } else {
392
- console.log(`\n ${colors.warning}⚠${ansi.reset} ${ansi.bold}Not allowlisted${ansi.reset}\n`);
393
- }
394
- return result.allowed ? 0 : 1;
395
- }
396
-
397
- default:
398
- console.error(`\n ${colors.error}✗${ansi.reset} Unknown allowlist action: ${action}\n`);
399
- console.log(` ${ansi.dim}Available: list, add, remove, check${ansi.reset}\n`);
400
- return 1;
401
- }
402
- } catch (error) {
403
- if (opts.json) {
404
- console.log(JSON.stringify({ error: error.message }, null, 2));
405
- } else {
406
- console.error(`\n ${colors.error}✗${ansi.reset} ${error.message}\n`);
407
- }
408
- return 1;
409
- }
410
- }
411
-
412
172
  // ═══════════════════════════════════════════════════════════════════════════════
413
173
  // AUTOFIX & MISSION GENERATION
414
174
  // ═══════════════════════════════════════════════════════════════════════════════
@@ -693,11 +453,6 @@ async function runScan(args) {
693
453
  return 0;
694
454
  }
695
455
 
696
- // Handle --allowlist subcommand
697
- if (opts.allowlist) {
698
- return await handleAllowlistCommand(opts);
699
- }
700
-
701
456
  // Entitlement check (graceful offline handling)
702
457
  try {
703
458
  await enforceLimit('scans');
@@ -729,27 +484,6 @@ async function runScan(args) {
729
484
  emitScanStart(projectPath, args);
730
485
  const projectName = path.basename(projectPath);
731
486
 
732
- // Initialize API integration
733
- let apiScan = null;
734
- let apiConnected = false;
735
-
736
- // Try to connect to API for dashboard integration
737
- try {
738
- apiConnected = await isApiAvailable();
739
- if (apiConnected) {
740
- // Create scan record in dashboard
741
- apiScan = await createScan({
742
- localPath: projectPath,
743
- branch: opts.branch || 'main',
744
- enableLLM: opts.llm || false,
745
- });
746
- console.log(`${colors.info}📡${ansi.reset} Connected to dashboard (Scan ID: ${apiScan.scanId})`);
747
- }
748
- } catch (err) {
749
- // API connection is optional, continue without it
750
- console.log(`${colors.dim}ℹ${ansi.reset} Dashboard integration unavailable`);
751
- }
752
-
753
487
  // Validate project path
754
488
  if (!fs.existsSync(projectPath)) {
755
489
  throw createUserError(`Project path does not exist: ${projectPath}`, "ValidationError");
@@ -780,7 +514,7 @@ async function runScan(args) {
780
514
  console.log(` ${colors.warning}⚠${ansi.reset} ${ansi.bold}Reality layer requires --url${ansi.reset}`);
781
515
  console.log(` ${ansi.dim}Example: vibecheck scan --reality --url http://localhost:3000${ansi.reset}`);
782
516
  console.log();
783
- return EXIT.USER_ERROR;
517
+ return 1;
784
518
  }
785
519
 
786
520
  // Initialize spinner outside try block for error handling
@@ -797,64 +531,19 @@ async function runScan(args) {
797
531
  // Fallback to JS-based scanner using truth.js and analyzers.js
798
532
  useFallbackScanner = true;
799
533
  const { buildTruthpack } = require('./lib/truth');
800
- const {
801
- findMissingRoutes,
802
- findEnvGaps,
803
- findFakeSuccess,
804
- findGhostAuth,
805
- findMockData,
806
- findTodoFixme,
807
- findConsoleLogs,
808
- findHardcodedSecrets,
809
- findDeadCode,
810
- findDeprecatedApis,
811
- findEmptyCatch,
812
- findUnsafeRegex,
813
- findSecurityVulnerabilities,
814
- findPerformanceIssues,
815
- findCodeQualityIssues,
816
- findCrossFileIssues,
817
- findTypeSafetyIssues,
818
- findAccessibilityIssues,
819
- findAPIConsistencyIssues,
820
- clearFileCache, // V3: Memory management
821
- } = require('./lib/analyzers');
534
+ const { findMissingRoutes, findEnvGaps, findFakeSuccess, findGhostAuth } = require('./lib/analyzers');
822
535
 
823
536
  scanRouteIntegrity = async function({ projectPath, layers, baseUrl, verbose }) {
824
537
  // Build truthpack for route analysis
825
538
  const truthpack = await buildTruthpack({ repoRoot: projectPath });
826
539
 
827
- // Run ALL analyzers for comprehensive scanning
540
+ // Run analyzers
828
541
  const findings = [];
829
-
830
- // Core analyzers (route integrity, env, auth)
831
542
  findings.push(...findMissingRoutes(truthpack));
832
543
  findings.push(...findEnvGaps(truthpack));
833
544
  findings.push(...findFakeSuccess(projectPath));
834
545
  findings.push(...findGhostAuth(truthpack, projectPath));
835
546
 
836
- // Code quality analyzers (MOCK, TODO, console.log, etc.)
837
- findings.push(...findMockData(projectPath));
838
- findings.push(...findTodoFixme(projectPath));
839
- findings.push(...findConsoleLogs(projectPath));
840
- findings.push(...findHardcodedSecrets(projectPath));
841
- findings.push(...findDeadCode(projectPath));
842
- findings.push(...findDeprecatedApis(projectPath));
843
- findings.push(...findEmptyCatch(projectPath));
844
- findings.push(...findUnsafeRegex(projectPath));
845
-
846
- // Enhanced analyzers (Security, Performance, Code Quality)
847
- findings.push(...findSecurityVulnerabilities(projectPath));
848
- findings.push(...findPerformanceIssues(projectPath));
849
- findings.push(...findCodeQualityIssues(projectPath));
850
-
851
- // V3: Clear file cache and AST cache to prevent memory leaks in large monorepos
852
- clearFileCache();
853
- const engines = require("./lib/engines/vibecheck-engines");
854
- if (engines.clearASTCache) {
855
- engines.clearASTCache();
856
- }
857
-
858
547
  // Convert to scan format matching TypeScript scanner output
859
548
  const shipBlockers = findings.map((f, i) => ({
860
549
  id: f.id || `finding-${i}`,
@@ -985,20 +674,7 @@ async function runScan(args) {
985
674
  const { BillingBypassDetector } = require('../../dist/engines/detection/billing-bypass-detector');
986
675
  const { FakeSuccessDetector } = require('../../dist/engines/detection/fake-success-detector');
987
676
 
988
- // Load ignore patterns from .vibecheckignore + defaults
989
- const { loadIgnorePatterns } = require('./lib/agent-firewall/utils/ignore-checker');
990
- const ignorePatterns = loadIgnorePatterns(projectPath);
991
- const exclude = [
992
- // Default excludes
993
- 'node_modules', '.git', 'dist', 'build', '.next', 'coverage', '_archive',
994
- // From .vibecheckignore
995
- 'mcp-server', 'bin', 'packages/cli', 'tests', '__tests__', 'examples',
996
- 'templates', 'docs', '.guardrail', '.cursor', '.vibecheck',
997
- // Test files
998
- '*.test.ts', '*.test.tsx', '*.spec.ts', '*.spec.tsx', '*.test.js', '*.spec.js',
999
- // Type definitions
1000
- '*.d.ts', '*.d.ts.map',
1001
- ];
677
+ const exclude = ['node_modules', '.git', 'dist', 'build', '.next', 'coverage', '_archive'];
1002
678
 
1003
679
  // Run detectors in parallel
1004
680
  const [deadUIResult, billingResult, fakeSuccessResult] = await Promise.all([
@@ -1146,48 +822,6 @@ async function runScan(args) {
1146
822
  return getExitCodeFromUnified ? getExitCodeFromUnified(verdict) : getExitCode(verdict);
1147
823
  }
1148
824
 
1149
- // ═══════════════════════════════════════════════════════════════════════════
1150
- // FINGERPRINTING & BASELINE COMPARISON
1151
- // ═══════════════════════════════════════════════════════════════════════════
1152
-
1153
- let diff = null;
1154
- if (opts.baseline) {
1155
- try {
1156
- const enrichResult = enrichFindings(normalizedFindings, projectPath, true);
1157
- diff = enrichResult.diff;
1158
-
1159
- // Update findings with fingerprints and status
1160
- for (let i = 0; i < normalizedFindings.length; i++) {
1161
- if (enrichResult.findings[i]) {
1162
- normalizedFindings[i].fingerprint = enrichResult.findings[i].fingerprint;
1163
- normalizedFindings[i].status = enrichResult.findings[i].status;
1164
- normalizedFindings[i].firstSeen = enrichResult.findings[i].firstSeen;
1165
- }
1166
- }
1167
- } catch (fpError) {
1168
- if (opts.verbose) {
1169
- console.warn(` ${ansi.dim}Fingerprinting skipped: ${fpError.message}${ansi.reset}`);
1170
- }
1171
- }
1172
- }
1173
-
1174
- // Update baseline if requested
1175
- if (opts.updateBaseline) {
1176
- try {
1177
- saveBaseline(projectPath, normalizedFindings, {
1178
- verdict: verdict?.verdict,
1179
- scanTime: new Date().toISOString(),
1180
- });
1181
- if (!opts.json && !opts.quiet) {
1182
- console.log(` ${colors.success}✓${ansi.reset} Baseline updated with ${normalizedFindings.length} findings`);
1183
- }
1184
- } catch (blError) {
1185
- if (opts.verbose) {
1186
- console.warn(` ${ansi.dim}Baseline save failed: ${blError.message}${ansi.reset}`);
1187
- }
1188
- }
1189
- }
1190
-
1191
825
  // ═══════════════════════════════════════════════════════════════════════════
1192
826
  // ENHANCED OUTPUT
1193
827
  // ═══════════════════════════════════════════════════════════════════════════
@@ -1201,7 +835,6 @@ async function runScan(args) {
1201
835
  breakdown: report.score?.breakdown,
1202
836
  timings,
1203
837
  cached,
1204
- diff, // Include diff for display
1205
838
  };
1206
839
  console.log(formatScanOutput(resultForOutput, { verbose: opts.verbose }));
1207
840
 
@@ -1288,28 +921,6 @@ async function runScan(args) {
1288
921
  durationMs: timings.total,
1289
922
  });
1290
923
 
1291
- // Submit results to dashboard if connected
1292
- if (apiConnected && apiScan) {
1293
- try {
1294
- await submitScanResults(apiScan.scanId, {
1295
- verdict: verdict.verdict,
1296
- score: report.score?.overall || 0,
1297
- findings: report.findings || [],
1298
- filesScanned: report.stats?.filesScanned || 0,
1299
- linesScanned: report.stats?.linesScanned || 0,
1300
- durationMs: timings.total,
1301
- metadata: {
1302
- layers,
1303
- profile: opts.profile,
1304
- version: require('../../package.json').version,
1305
- },
1306
- });
1307
- console.log(`${colors.success}✓${ansi.reset} Results sent to dashboard`);
1308
- } catch (err) {
1309
- console.log(`${colors.warning}⚠${ansi.reset} Failed to send results to dashboard: ${err.message}`);
1310
- }
1311
- }
1312
-
1313
924
  return getExitCodeFromUnified ? getExitCodeFromUnified(verdict) : getExitCode(verdict);
1314
925
  } else {
1315
926
  // Legacy fallback output when unified output system isn't available
@@ -1319,60 +930,6 @@ async function runScan(args) {
1319
930
 
1320
931
  const verdict = criticalCount > 0 ? 'BLOCK' : warningCount > 0 ? 'WARN' : 'SHIP';
1321
932
 
1322
- // ═══════════════════════════════════════════════════════════════════════════
1323
- // FINGERPRINTING & BASELINE COMPARISON (Legacy path)
1324
- // ═══════════════════════════════════════════════════════════════════════════
1325
-
1326
- const normalizedLegacyFindings = findings.map(f => ({
1327
- severity: f.severity === 'critical' || f.severity === 'BLOCK' ? 'critical' :
1328
- f.severity === 'warning' || f.severity === 'WARN' ? 'medium' : 'low',
1329
- category: f.category || 'ROUTE',
1330
- title: f.title || f.message,
1331
- message: f.message || f.title,
1332
- file: f.file || f.evidence?.[0]?.file,
1333
- line: f.line || parseInt(f.evidence?.[0]?.lines?.split('-')[0]) || 1,
1334
- evidence: f.evidence,
1335
- fix: f.fixSuggestion,
1336
- }));
1337
-
1338
- let diff = null;
1339
- if (opts.baseline) {
1340
- try {
1341
- const enrichResult = enrichFindings(normalizedLegacyFindings, projectPath, true);
1342
- diff = enrichResult.diff;
1343
-
1344
- // Update findings with fingerprints and status
1345
- for (let i = 0; i < normalizedLegacyFindings.length; i++) {
1346
- if (enrichResult.findings[i]) {
1347
- normalizedLegacyFindings[i].fingerprint = enrichResult.findings[i].fingerprint;
1348
- normalizedLegacyFindings[i].status = enrichResult.findings[i].status;
1349
- normalizedLegacyFindings[i].firstSeen = enrichResult.findings[i].firstSeen;
1350
- }
1351
- }
1352
- } catch (fpError) {
1353
- if (opts.verbose) {
1354
- console.warn(` ${ansi.dim}Fingerprinting skipped: ${fpError.message}${ansi.reset}`);
1355
- }
1356
- }
1357
- }
1358
-
1359
- // Update baseline if requested
1360
- if (opts.updateBaseline) {
1361
- try {
1362
- saveBaseline(projectPath, normalizedLegacyFindings, {
1363
- verdict,
1364
- scanTime: new Date().toISOString(),
1365
- });
1366
- if (!opts.json && !opts.quiet) {
1367
- console.log(` ${colors.success}✓${ansi.reset} Baseline updated with ${normalizedLegacyFindings.length} findings`);
1368
- }
1369
- } catch (blError) {
1370
- if (opts.verbose) {
1371
- console.warn(` ${ansi.dim}Baseline save failed: ${blError.message}${ansi.reset}`);
1372
- }
1373
- }
1374
- }
1375
-
1376
933
  // Use enhanced output formatter for legacy fallback
1377
934
  const severityCounts = {
1378
935
  critical: criticalCount,
@@ -1384,10 +941,18 @@ async function runScan(args) {
1384
941
 
1385
942
  const result = {
1386
943
  verdict: { verdict, score },
1387
- findings: normalizedLegacyFindings,
944
+ findings: findings.map(f => ({
945
+ severity: f.severity === 'critical' || f.severity === 'BLOCK' ? 'critical' :
946
+ f.severity === 'warning' || f.severity === 'WARN' ? 'medium' : 'low',
947
+ category: f.category || 'ROUTE',
948
+ title: f.title || f.message,
949
+ message: f.message || f.title,
950
+ file: f.file,
951
+ line: f.line,
952
+ fix: f.fixSuggestion,
953
+ })),
1388
954
  layers: [],
1389
955
  timings,
1390
- diff,
1391
956
  };
1392
957
 
1393
958
  console.log(formatScanOutput(result, { verbose: opts.verbose }));
@@ -1398,30 +963,8 @@ async function runScan(args) {
1398
963
  issueCount: criticalCount + warningCount,
1399
964
  durationMs: timings.total,
1400
965
  });
1401
-
1402
- // Submit results to dashboard if connected
1403
- if (apiConnected && apiScan) {
1404
- try {
1405
- await submitScanResults(apiScan.scanId, {
1406
- verdict,
1407
- score: verdict === 'SHIP' ? 100 : verdict === 'WARN' ? 70 : 40,
1408
- findings: normalizedLegacyFindings,
1409
- filesScanned: result.stats?.filesScanned || 0,
1410
- linesScanned: result.stats?.linesScanned || 0,
1411
- durationMs: timings.total,
1412
- metadata: {
1413
- layers,
1414
- profile: opts.profile,
1415
- version: require('../../package.json').version,
1416
- },
1417
- });
1418
- console.log(`${colors.success}✓${ansi.reset} Results sent to dashboard`);
1419
- } catch (err) {
1420
- console.log(`${colors.warning}⚠${ansi.reset} Failed to send results to dashboard: ${err.message}`);
1421
- }
1422
- }
1423
966
 
1424
- return verdictToExitCode(verdict);
967
+ return verdict === 'SHIP' ? 0 : verdict === 'WARN' ? 1 : 2;
1425
968
  }
1426
969
 
1427
970
  } catch (error) {
@@ -1438,16 +981,6 @@ async function runScan(args) {
1438
981
  errorMessage: error.message,
1439
982
  durationMs: Date.now() - startTime,
1440
983
  });
1441
-
1442
- // Report error to dashboard if connected
1443
- if (apiConnected && apiScan) {
1444
- try {
1445
- await reportScanError(apiScan.scanId, error);
1446
- console.log(`${colors.info}📡${ansi.reset} Error reported to dashboard`);
1447
- } catch (err) {
1448
- console.log(`${colors.warning}⚠${ansi.reset} Failed to report error to dashboard: ${err.message}`);
1449
- }
1450
- }
1451
984
 
1452
985
  return exitCode;
1453
986
  }