@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,239 @@
1
+ /**
2
+ * Enterprise Ship Output - Fixed Alignment
3
+ * * fixes: Table border misalignment and logo centering.
4
+ */
5
+
6
+ const path = require('path');
7
+ const os = require('os');
8
+
9
+ // ═══════════════════════════════════════════════════════════════════════════════
10
+ // ASCII ART LOGOS
11
+ // ═══════════════════════════════════════════════════════════════════════════════
12
+
13
+ const LOGO_VIBECHECK = `
14
+ █████████ █████ █████ █████ ███████████
15
+ ███░░░░░███░░███ ░░███ ░░███ ░░███░░░░░███
16
+ ░███ ░░░ ░███ ░███ ░███ ░███ ░███ VIBECHECK CLI
17
+ ░░█████████ ░███████████ ░███ ░██████████ ENTERPRISE SUITE
18
+ ░░░░░░░░███ ░███░░░░░███ ░███ ░███░░░░░░ v2.4.0-stable
19
+ ███ ░███ ░███ ░███ ░███ ░███
20
+ ░░█████████ █████ █████ █████ █████ © 2026 Vibecheck Inc.
21
+ ░░░░░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░
22
+ `;
23
+
24
+ const LOGO_NOT_SHIP_READY = `
25
+ ███ ███ █████████ █████████ █████ █████ █████ ███████
26
+ ████ ███ ███░░░░░███ ███░░░░░███░░███ ░░███ ░░███ ░░███░░█
27
+ ███░██ ██████ ███ ░███ ░░░ ░███ ░███ ░███ ░███ ░█
28
+ ███ ░██ ██████ ███ ░█████████ ░███████████ ░███ ░██████
29
+ ███ ░████████ ███ ░░░░░░░░███ ░███░░░░░███ ░███ ░███░░
30
+ ███ ░███████ ███ ███ ░███ ░███ ░███ ░███ ░███
31
+ ███ ░████░█████████ ░░█████████ █████ █████ █████ █████
32
+ ░░░ ░░░ ░░░░░░░░░ ░░░░░░░░░ ░░░░░ ░░░░░ ░░░░░ ░░░░░
33
+ `;
34
+
35
+ // ═══════════════════════════════════════════════════════════════════════════════
36
+ // CONFIGURATION
37
+ // ═══════════════════════════════════════════════════════════════════════════════
38
+
39
+ const BOX = {
40
+ topLeft: '╔', topRight: '╗', bottomLeft: '╚', bottomRight: '╝',
41
+ horizontal: '═', vertical: '║',
42
+ teeRight: '╠', teeLeft: '╣',
43
+
44
+ // Table Borders (Light)
45
+ tTopLeft: '┌', tTopRight: '┐', tBottomLeft: '└', tBottomRight: '┘',
46
+ tHorizontal: '─', tVertical: '│',
47
+ tTeeTop: '┬', tTeeBottom: '┴', tTee: '┼', tTeeLeft: '├', tTeeRight: '┤'
48
+ };
49
+
50
+ const WIDTH = 76;
51
+ // Column widths for the findings table (Must equal WIDTH - 4 when summed + separators)
52
+ // 10 + 13 + 47 + 2 borders + 2 internal separators = 76? Let's calibrate:
53
+ // Total internal width = WIDTH - 2 (borders) - 2 (padding) = 72
54
+ // Let's use: Col1: 10, Col2: 13, Col3: 45. 10+13+45 = 68. + 4 padding spaces + 2 internal bars = 74.
55
+ // We need exact pixel perfect match.
56
+ // Border: 76. Inner: 74.
57
+ // Row: "│ " + COL1 + " │ " + COL2 + " │ " + COL3 + " │"
58
+ // chars: 1+1+10 + 1+1+1 + 13 + 1+1+1 + 41 + 1+1 = 74.
59
+ // Let's stick to the previous column sizes but FIX the padding math.
60
+ const COL_1 = 10;
61
+ const COL_2 = 13;
62
+ const COL_3 = 41;
63
+
64
+ // ═══════════════════════════════════════════════════════════════════════════════
65
+ // UTILITIES
66
+ // ═══════════════════════════════════════════════════════════════════════════════
67
+
68
+ function padCenter(str, width) {
69
+ const visibleLen = str.length; // Simplified for no-ansi
70
+ const padding = Math.max(0, width - visibleLen);
71
+ const left = Math.floor(padding / 2);
72
+ const right = padding - left;
73
+ return ' '.repeat(left) + str + ' '.repeat(right);
74
+ }
75
+
76
+ function padRight(str, len) {
77
+ // Ensure we don't overflow if string is too long
78
+ const truncated = str.length > len ? str.substring(0, len - 3) + '...' : str;
79
+ return truncated + ' '.repeat(Math.max(0, len - truncated.length));
80
+ }
81
+
82
+ // Fixes the "Wobbly Logo" by padding lines to a block first
83
+ function padLogoBlock(ascii, width) {
84
+ const lines = ascii.trim().split('\n');
85
+ const maxContentWidth = Math.max(...lines.map(l => l.length));
86
+
87
+ return lines.map(line => {
88
+ // 1. Make the line itself consistent width
89
+ const solidLine = line + ' '.repeat(maxContentWidth - line.length);
90
+ // 2. Center that solid block
91
+ return padCenter(solidLine, width);
92
+ });
93
+ }
94
+
95
+ function renderProgressBar(score, width = 20) {
96
+ const filled = Math.round((score / 100) * width);
97
+ return '█'.repeat(filled) + '░'.repeat(width - filled);
98
+ }
99
+
100
+ function getMemoryUsage() {
101
+ const usage = process.memoryUsage();
102
+ return Math.round(usage.heapUsed / 1024 / 1024);
103
+ }
104
+
105
+ // ═══════════════════════════════════════════════════════════════════════════════
106
+ // MAIN OUTPUT FORMATTER
107
+ // ═══════════════════════════════════════════════════════════════════════════════
108
+
109
+ function formatShipOutput(result) {
110
+ const { verdict, score = 0, blockers = [], warnings = [], duration = 0 } = result;
111
+ const canShip = verdict === 'SHIP';
112
+ const heapMB = getMemoryUsage();
113
+
114
+ const lines = [];
115
+
116
+ // 1. OUTER FRAME TOP
117
+ lines.push(BOX.topLeft + BOX.horizontal.repeat(WIDTH - 2) + BOX.topRight);
118
+ lines.push(BOX.vertical + ' '.repeat(WIDTH - 2) + BOX.vertical);
119
+
120
+ // 2. LOGO
121
+ const logoSrc = canShip ? LOGO_VIBECHECK : LOGO_NOT_SHIP_READY;
122
+ padLogoBlock(logoSrc, WIDTH - 2).forEach(line => {
123
+ lines.push(BOX.vertical + line + BOX.vertical);
124
+ });
125
+ lines.push(BOX.vertical + ' '.repeat(WIDTH - 2) + BOX.vertical);
126
+
127
+ // 3. TELEMETRY
128
+ lines.push(BOX.teeRight + BOX.horizontal.repeat(WIDTH - 2) + BOX.teeLeft);
129
+ const exitTxt = canShip ? '✅ Exit: 0' : '❌ Exit: 1';
130
+ const abortTxt = canShip ? '' : ' 🛑 ABORTED';
131
+ const telemetry = `📡 TELEMETRY │ ⏱ Duration: ${duration}ms │ 📦 Heap: ${heapMB}MB │ ${exitTxt}${abortTxt}`;
132
+ lines.push(BOX.vertical + padCenter(telemetry, WIDTH - 2) + BOX.vertical);
133
+ lines.push(BOX.teeRight + BOX.horizontal.repeat(WIDTH - 2) + BOX.teeLeft);
134
+
135
+ // 4. STATUS & SCORES
136
+ if (canShip) {
137
+ lines.push(BOX.vertical + ' '.repeat(WIDTH - 2) + BOX.vertical);
138
+ lines.push(BOX.vertical + padCenter('✅ SHIPMENT CLEARED: INTEGRITY VERIFIED', WIDTH - 2) + BOX.vertical);
139
+ lines.push(BOX.vertical + ' '.repeat(WIDTH - 2) + BOX.vertical);
140
+ } else {
141
+ lines.push(BOX.vertical + ' '.repeat(WIDTH - 2) + BOX.vertical);
142
+ lines.push(BOX.vertical + padCenter('⛔ SHIPMENT ABORTED: INTEGRITY FAILURE', WIDTH - 2) + BOX.vertical);
143
+ lines.push(BOX.vertical + padCenter('────────────────────────────────────────────────────────────────────', WIDTH - 2) + BOX.vertical);
144
+
145
+ const scoreBar = renderProgressBar(score, 20);
146
+ lines.push(BOX.vertical + padCenter(`VIOLATION SCORE [${scoreBar}] ${score} / 100`, WIDTH - 2) + BOX.vertical);
147
+ lines.push(BOX.vertical + ' '.repeat(WIDTH - 2) + BOX.vertical);
148
+
149
+ // 5. THE TABLE (FIXED ALIGNMENT)
150
+ lines.push(BOX.vertical + padCenter('CRITICAL BLOCKERS (VISIBLE TIER)', WIDTH - 2) + BOX.vertical);
151
+
152
+ // Construct Table Borders
153
+ // We need to match: " │ COL1 │ COL2 │ COL3 │ "
154
+ // The padding inside the outer box is 2 spaces.
155
+ // Inner Width = WIDTH - 2 (borders) - 4 (padding) = 70.
156
+ // Our columns: 10 + 13 + 41 = 64.
157
+ // We have 3 separators (3 chars) + 2 outer table borders (2 chars) = 5 chars.
158
+ // Total table width = 69. We have 1 char slack. Let's adjust COL_3 to 42.
159
+
160
+ const C1 = 10, C2 = 13, C3 = 41;
161
+
162
+ const tTop = ` ${BOX.tTopLeft}${BOX.tHorizontal.repeat(C1)}${BOX.tTeeTop}${BOX.tHorizontal.repeat(C2)}${BOX.tTeeTop}${BOX.tHorizontal.repeat(C3)}${BOX.tTopRight} `;
163
+ const tMid = ` ${BOX.tTeeLeft}${BOX.tHorizontal.repeat(C1)}${BOX.tTee}${BOX.tHorizontal.repeat(C2)}${BOX.tTee}${BOX.tHorizontal.repeat(C3)}${BOX.tTeeRight} `;
164
+ const tBot = ` ${BOX.tBottomLeft}${BOX.tHorizontal.repeat(C1)}${BOX.tTeeBottom}${BOX.tHorizontal.repeat(C2)}${BOX.tTeeBottom}${BOX.tHorizontal.repeat(C3)}${BOX.tBottomRight} `;
165
+
166
+ lines.push(BOX.vertical + tTop + BOX.vertical);
167
+
168
+ // Table Header
169
+ const header = ` ${BOX.tVertical}${padRight(' SEVERITY', C1)}${BOX.tVertical}${padRight(' COMPONENT', C2)}${BOX.tVertical}${padRight(' FAILURE CONDITION', C3)}${BOX.tVertical} `;
170
+ lines.push(BOX.vertical + header + BOX.vertical);
171
+ lines.push(BOX.vertical + tMid + BOX.vertical);
172
+
173
+ // Table Rows
174
+ const items = [...blockers, ...warnings].slice(0, 5);
175
+ items.forEach(item => {
176
+ // Fix Emoji Length: '🛑 FATAL' is 8 chars.
177
+ // We manually construct the string to ensure it fits the 10 char column.
178
+ const severity = item.severity === 'block' ? '🛑 FATAL ' : '🟡 WARN '; // 9 visual chars?
179
+ // Note: 🛑 is 2 chars wide visually. " FATAL " is 7. Total 9.
180
+ // If column is 10, we add 1 space.
181
+
182
+ const comp = padRight(' ' + (getComponentName(item.category)), C2);
183
+ const desc = padRight(' ' + (item.title || item.message), C3);
184
+
185
+ // Manual row construction
186
+ const row = ` ${BOX.tVertical}${padRight(severity, C1)}${BOX.tVertical}${comp}${BOX.tVertical}${desc}${BOX.tVertical} `;
187
+ lines.push(BOX.vertical + row + BOX.vertical);
188
+ });
189
+
190
+ lines.push(BOX.vertical + tBot + BOX.vertical);
191
+ lines.push(BOX.vertical + ' '.repeat(WIDTH - 2) + BOX.vertical);
192
+
193
+ // 6. AUTO-FIX SECTION
194
+ lines.push(BOX.teeRight + BOX.horizontal.repeat(WIDTH - 2) + BOX.teeLeft);
195
+ lines.push(BOX.vertical + padCenter('⚡ AUTO-FIX AVAILABLE', WIDTH - 2) + BOX.vertical);
196
+ lines.push(BOX.vertical + padCenter('────────────────────────────────────────────────────────────────────', WIDTH - 2) + BOX.vertical);
197
+ lines.push(BOX.vertical + ' '.repeat(WIDTH - 2) + BOX.vertical);
198
+ lines.push(BOX.vertical + padCenter('Run `vibecheck ship --fix` to apply automatic fixes', WIDTH - 2) + BOX.vertical);
199
+ lines.push(BOX.vertical + padCenter('Run `vibecheck fix` to generate AI-powered fix missions', WIDTH - 2) + BOX.vertical);
200
+ lines.push(BOX.vertical + ' '.repeat(WIDTH - 2) + BOX.vertical);
201
+ }
202
+
203
+ // 7. BOTTOM FRAME
204
+ lines.push(BOX.vertical + ' '.repeat(WIDTH - 2) + BOX.vertical);
205
+ lines.push(BOX.bottomLeft + BOX.horizontal.repeat(WIDTH - 2) + BOX.bottomRight);
206
+
207
+ // DASHBOARD LINK (outside frame)
208
+ const runId = result.runId;
209
+ if (runId) {
210
+ lines.push('');
211
+ lines.push(` 🔗 Dashboard: https://app.vibecheckai.dev/runs/${runId}`);
212
+ }
213
+
214
+ // NEXT BEST ACTION (outside frame)
215
+ try {
216
+ const { formatNextActionOneLine, getNextActionForCommand } = require('./next-action');
217
+ const tier = result.tier || 'free';
218
+ const findings = [...(result.blockers || []), ...(result.warnings || [])];
219
+ const nextAction = getNextActionForCommand('ship', { verdict, runId, findings }, tier);
220
+ lines.push('');
221
+ lines.push(` ${formatNextActionOneLine(nextAction)}`);
222
+ } catch (e) {
223
+ // Next action module might not be available, skip gracefully
224
+ }
225
+
226
+ return lines.join('\n');
227
+ }
228
+
229
+ function getComponentName(category) {
230
+ const map = {
231
+ 'MissingRoute': 'routes',
232
+ 'EnvContract': 'env_sec',
233
+ 'FakeSuccess': 'ui_flow',
234
+ 'GhostAuth': 'auth',
235
+ };
236
+ return map[category] || 'unknown';
237
+ }
238
+
239
+ module.exports = { formatShipOutput };