@vibecheckai/cli 3.5.0 → 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 (224) hide show
  1. package/bin/registry.js +214 -237
  2. package/bin/runners/cli-utils.js +33 -2
  3. package/bin/runners/context/analyzer.js +52 -1
  4. package/bin/runners/context/generators/cursor.js +2 -49
  5. package/bin/runners/context/git-context.js +3 -1
  6. package/bin/runners/context/team-conventions.js +33 -7
  7. package/bin/runners/lib/analysis-core.js +25 -5
  8. package/bin/runners/lib/analyzers.js +431 -481
  9. package/bin/runners/lib/default-config.js +127 -0
  10. package/bin/runners/lib/doctor/modules/security.js +3 -1
  11. package/bin/runners/lib/engine/ast-cache.js +210 -0
  12. package/bin/runners/lib/engine/auth-extractor.js +211 -0
  13. package/bin/runners/lib/engine/billing-extractor.js +112 -0
  14. package/bin/runners/lib/engine/enforcement-extractor.js +100 -0
  15. package/bin/runners/lib/engine/env-extractor.js +207 -0
  16. package/bin/runners/lib/engine/express-extractor.js +208 -0
  17. package/bin/runners/lib/engine/extractors.js +849 -0
  18. package/bin/runners/lib/engine/index.js +207 -0
  19. package/bin/runners/lib/engine/repo-index.js +514 -0
  20. package/bin/runners/lib/engine/types.js +124 -0
  21. package/bin/runners/lib/engines/accessibility-engine.js +18 -218
  22. package/bin/runners/lib/engines/api-consistency-engine.js +30 -335
  23. package/bin/runners/lib/engines/cross-file-analysis-engine.js +27 -292
  24. package/bin/runners/lib/engines/empty-catch-engine.js +17 -127
  25. package/bin/runners/lib/engines/mock-data-engine.js +10 -53
  26. package/bin/runners/lib/engines/performance-issues-engine.js +36 -176
  27. package/bin/runners/lib/engines/security-vulnerabilities-engine.js +54 -382
  28. package/bin/runners/lib/engines/type-aware-engine.js +39 -263
  29. package/bin/runners/lib/engines/vibecheck-engines/index.js +13 -122
  30. package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +164 -0
  31. package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +291 -0
  32. package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +83 -0
  33. package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +198 -0
  34. package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +275 -0
  35. package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +167 -0
  36. package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +217 -0
  37. package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +73 -373
  38. package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +140 -0
  39. package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +164 -0
  40. package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +234 -0
  41. package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +217 -0
  42. package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +78 -0
  43. package/bin/runners/lib/entitlements-v2.js +73 -97
  44. package/bin/runners/lib/error-handler.js +44 -3
  45. package/bin/runners/lib/error-messages.js +289 -0
  46. package/bin/runners/lib/evidence-pack.js +7 -1
  47. package/bin/runners/lib/finding-id.js +69 -0
  48. package/bin/runners/lib/finding-sorter.js +89 -0
  49. package/bin/runners/lib/html-proof-report.js +700 -350
  50. package/bin/runners/lib/missions/plan.js +6 -46
  51. package/bin/runners/lib/missions/templates.js +0 -232
  52. package/bin/runners/lib/next-action.js +560 -0
  53. package/bin/runners/lib/prerequisites.js +149 -0
  54. package/bin/runners/lib/route-detection.js +137 -68
  55. package/bin/runners/lib/scan-output.js +91 -76
  56. package/bin/runners/lib/scan-runner.js +135 -0
  57. package/bin/runners/lib/schemas/ajv-validator.js +464 -0
  58. package/bin/runners/lib/schemas/error-envelope.schema.json +105 -0
  59. package/bin/runners/lib/schemas/finding-v3.schema.json +151 -0
  60. package/bin/runners/lib/schemas/report-artifact.schema.json +120 -0
  61. package/bin/runners/lib/schemas/run-request.schema.json +108 -0
  62. package/bin/runners/lib/schemas/validator.js +27 -0
  63. package/bin/runners/lib/schemas/verdict.schema.json +140 -0
  64. package/bin/runners/lib/ship-output-enterprise.js +23 -23
  65. package/bin/runners/lib/ship-output.js +75 -31
  66. package/bin/runners/lib/terminal-ui.js +6 -113
  67. package/bin/runners/lib/truth.js +351 -10
  68. package/bin/runners/lib/unified-cli-output.js +430 -603
  69. package/bin/runners/lib/unified-output.js +13 -9
  70. package/bin/runners/runAIAgent.js +10 -5
  71. package/bin/runners/runAgent.js +0 -3
  72. package/bin/runners/runAllowlist.js +389 -0
  73. package/bin/runners/runApprove.js +0 -33
  74. package/bin/runners/runAuth.js +73 -45
  75. package/bin/runners/runCheckpoint.js +51 -11
  76. package/bin/runners/runClassify.js +85 -21
  77. package/bin/runners/runContext.js +0 -3
  78. package/bin/runners/runDoctor.js +41 -28
  79. package/bin/runners/runEvidencePack.js +362 -0
  80. package/bin/runners/runFirewall.js +0 -3
  81. package/bin/runners/runFirewallHook.js +0 -3
  82. package/bin/runners/runFix.js +66 -76
  83. package/bin/runners/runGuard.js +18 -411
  84. package/bin/runners/runInit.js +113 -30
  85. package/bin/runners/runLabs.js +424 -0
  86. package/bin/runners/runMcp.js +19 -25
  87. package/bin/runners/runPolish.js +64 -240
  88. package/bin/runners/runPromptFirewall.js +12 -5
  89. package/bin/runners/runProve.js +57 -22
  90. package/bin/runners/runQuickstart.js +531 -0
  91. package/bin/runners/runReality.js +59 -68
  92. package/bin/runners/runReport.js +38 -33
  93. package/bin/runners/runRuntime.js +8 -5
  94. package/bin/runners/runScan.js +1413 -190
  95. package/bin/runners/runShip.js +113 -719
  96. package/bin/runners/runTruth.js +0 -3
  97. package/bin/runners/runValidate.js +13 -9
  98. package/bin/runners/runWatch.js +23 -14
  99. package/bin/scan.js +6 -1
  100. package/bin/vibecheck.js +204 -185
  101. package/mcp-server/deprecation-middleware.js +282 -0
  102. package/mcp-server/handlers/index.ts +15 -0
  103. package/mcp-server/handlers/tool-handler.ts +554 -0
  104. package/mcp-server/index-v1.js +698 -0
  105. package/mcp-server/index.js +210 -238
  106. package/mcp-server/lib/cache-wrapper.cjs +383 -0
  107. package/mcp-server/lib/error-envelope.js +138 -0
  108. package/mcp-server/lib/executor.ts +499 -0
  109. package/mcp-server/lib/index.ts +19 -0
  110. package/mcp-server/lib/rate-limiter.js +166 -0
  111. package/mcp-server/lib/sandbox.test.ts +519 -0
  112. package/mcp-server/lib/sandbox.ts +395 -0
  113. package/mcp-server/lib/types.ts +267 -0
  114. package/mcp-server/package.json +12 -3
  115. package/mcp-server/registry/tool-registry.js +794 -0
  116. package/mcp-server/registry/tools.json +605 -0
  117. package/mcp-server/registry.test.ts +334 -0
  118. package/mcp-server/tests/tier-gating.test.js +297 -0
  119. package/mcp-server/tier-auth.js +378 -45
  120. package/mcp-server/tools-v3.js +353 -442
  121. package/mcp-server/tsconfig.json +37 -0
  122. package/mcp-server/vibecheck-2.0-tools.js +14 -1
  123. package/package.json +1 -1
  124. package/bin/runners/lib/agent-firewall/learning/learning-engine.js +0 -849
  125. package/bin/runners/lib/audit-logger.js +0 -532
  126. package/bin/runners/lib/authority/authorities/architecture.js +0 -364
  127. package/bin/runners/lib/authority/authorities/compliance.js +0 -341
  128. package/bin/runners/lib/authority/authorities/human.js +0 -343
  129. package/bin/runners/lib/authority/authorities/quality.js +0 -420
  130. package/bin/runners/lib/authority/authorities/security.js +0 -228
  131. package/bin/runners/lib/authority/index.js +0 -293
  132. package/bin/runners/lib/bundle/bundle-intelligence.js +0 -846
  133. package/bin/runners/lib/cli-charts.js +0 -368
  134. package/bin/runners/lib/cli-config-display.js +0 -405
  135. package/bin/runners/lib/cli-demo.js +0 -275
  136. package/bin/runners/lib/cli-errors.js +0 -438
  137. package/bin/runners/lib/cli-help-formatter.js +0 -439
  138. package/bin/runners/lib/cli-interactive-menu.js +0 -509
  139. package/bin/runners/lib/cli-prompts.js +0 -441
  140. package/bin/runners/lib/cli-scan-cards.js +0 -362
  141. package/bin/runners/lib/compliance-reporter.js +0 -710
  142. package/bin/runners/lib/conductor/index.js +0 -671
  143. package/bin/runners/lib/easy/README.md +0 -123
  144. package/bin/runners/lib/easy/index.js +0 -140
  145. package/bin/runners/lib/easy/interactive-wizard.js +0 -788
  146. package/bin/runners/lib/easy/one-click-firewall.js +0 -564
  147. package/bin/runners/lib/easy/zero-config-reality.js +0 -714
  148. package/bin/runners/lib/engines/async-patterns-engine.js +0 -444
  149. package/bin/runners/lib/engines/bundle-size-engine.js +0 -433
  150. package/bin/runners/lib/engines/confidence-scoring.js +0 -276
  151. package/bin/runners/lib/engines/context-detection.js +0 -264
  152. package/bin/runners/lib/engines/database-patterns-engine.js +0 -429
  153. package/bin/runners/lib/engines/duplicate-code-engine.js +0 -354
  154. package/bin/runners/lib/engines/env-variables-engine.js +0 -458
  155. package/bin/runners/lib/engines/error-handling-engine.js +0 -437
  156. package/bin/runners/lib/engines/false-positive-prevention.js +0 -630
  157. package/bin/runners/lib/engines/framework-adapters/index.js +0 -607
  158. package/bin/runners/lib/engines/framework-detection.js +0 -508
  159. package/bin/runners/lib/engines/import-order-engine.js +0 -429
  160. package/bin/runners/lib/engines/naming-conventions-engine.js +0 -544
  161. package/bin/runners/lib/engines/noise-reduction-engine.js +0 -452
  162. package/bin/runners/lib/engines/orchestrator.js +0 -334
  163. package/bin/runners/lib/engines/react-patterns-engine.js +0 -457
  164. package/bin/runners/lib/engines/vibecheck-engines/lib/ai-hallucination-engine.js +0 -806
  165. package/bin/runners/lib/engines/vibecheck-engines/lib/smart-fix-engine.js +0 -577
  166. package/bin/runners/lib/engines/vibecheck-engines/lib/vibe-score-engine.js +0 -543
  167. package/bin/runners/lib/engines/vibecheck-engines.js +0 -514
  168. package/bin/runners/lib/enhanced-features/index.js +0 -305
  169. package/bin/runners/lib/enhanced-output.js +0 -631
  170. package/bin/runners/lib/enterprise.js +0 -300
  171. package/bin/runners/lib/firewall/command-validator.js +0 -351
  172. package/bin/runners/lib/firewall/config.js +0 -341
  173. package/bin/runners/lib/firewall/content-validator.js +0 -519
  174. package/bin/runners/lib/firewall/index.js +0 -101
  175. package/bin/runners/lib/firewall/path-validator.js +0 -256
  176. package/bin/runners/lib/intelligence/cross-repo-intelligence.js +0 -817
  177. package/bin/runners/lib/mcp-utils.js +0 -425
  178. package/bin/runners/lib/output/index.js +0 -1022
  179. package/bin/runners/lib/policy-engine.js +0 -652
  180. package/bin/runners/lib/polish/autofix/accessibility-fixes.js +0 -333
  181. package/bin/runners/lib/polish/autofix/async-handlers.js +0 -273
  182. package/bin/runners/lib/polish/autofix/dead-code.js +0 -280
  183. package/bin/runners/lib/polish/autofix/imports-optimizer.js +0 -344
  184. package/bin/runners/lib/polish/autofix/index.js +0 -200
  185. package/bin/runners/lib/polish/autofix/remove-consoles.js +0 -209
  186. package/bin/runners/lib/polish/autofix/strengthen-types.js +0 -245
  187. package/bin/runners/lib/polish/backend-checks.js +0 -148
  188. package/bin/runners/lib/polish/documentation-checks.js +0 -111
  189. package/bin/runners/lib/polish/frontend-checks.js +0 -168
  190. package/bin/runners/lib/polish/index.js +0 -71
  191. package/bin/runners/lib/polish/infrastructure-checks.js +0 -131
  192. package/bin/runners/lib/polish/library-detection.js +0 -175
  193. package/bin/runners/lib/polish/performance-checks.js +0 -100
  194. package/bin/runners/lib/polish/security-checks.js +0 -148
  195. package/bin/runners/lib/polish/utils.js +0 -203
  196. package/bin/runners/lib/prompt-builder.js +0 -540
  197. package/bin/runners/lib/proof-certificate.js +0 -634
  198. package/bin/runners/lib/reality/accessibility-audit.js +0 -946
  199. package/bin/runners/lib/reality/api-contract-validator.js +0 -1012
  200. package/bin/runners/lib/reality/chaos-engineering.js +0 -1084
  201. package/bin/runners/lib/reality/performance-tracker.js +0 -1077
  202. package/bin/runners/lib/reality/scenario-generator.js +0 -1404
  203. package/bin/runners/lib/reality/visual-regression.js +0 -852
  204. package/bin/runners/lib/reality-profiler.js +0 -717
  205. package/bin/runners/lib/replay/flight-recorder-viewer.js +0 -1160
  206. package/bin/runners/lib/review/ai-code-review.js +0 -832
  207. package/bin/runners/lib/rules/custom-rule-engine.js +0 -985
  208. package/bin/runners/lib/sbom-generator.js +0 -641
  209. package/bin/runners/lib/scan-output-enhanced.js +0 -512
  210. package/bin/runners/lib/security/owasp-scanner.js +0 -939
  211. package/bin/runners/lib/validators/contract-validator.js +0 -283
  212. package/bin/runners/lib/validators/dead-export-detector.js +0 -279
  213. package/bin/runners/lib/validators/dep-audit.js +0 -245
  214. package/bin/runners/lib/validators/env-validator.js +0 -319
  215. package/bin/runners/lib/validators/index.js +0 -120
  216. package/bin/runners/lib/validators/license-checker.js +0 -252
  217. package/bin/runners/lib/validators/route-validator.js +0 -290
  218. package/bin/runners/runAuthority.js +0 -528
  219. package/bin/runners/runConductor.js +0 -772
  220. package/bin/runners/runContainer.js +0 -366
  221. package/bin/runners/runEasy.js +0 -410
  222. package/bin/runners/runIaC.js +0 -372
  223. package/bin/runners/runVibe.js +0 -791
  224. package/mcp-server/tools.js +0 -495
@@ -1,528 +0,0 @@
1
- /**
2
- * vibecheck authority - Authority System CLI
3
- *
4
- * List authorities and request approvals from human or automated reviewers.
5
- *
6
- * Usage:
7
- * vibecheck authority list - List available authorities
8
- * vibecheck authority approve --authority security - Request security approval
9
- * vibecheck authority approve --authority quality - Request quality approval
10
- *
11
- * Part of the Authority System - "The AI That Says No"
12
- */
13
-
14
- "use strict";
15
-
16
- const path = require("path");
17
- const fs = require("fs");
18
- const { withErrorHandling, createUserError } = require("./lib/error-handler");
19
- const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
20
- const { EXIT } = require("./lib/exit-codes");
21
-
22
- // Authority module
23
- const {
24
- listAuthorities,
25
- requestApproval,
26
- requestMultipleApprovals,
27
- getAggregatedVerdict,
28
- hasAuthority,
29
- } = require("./lib/authority");
30
-
31
- // ═══════════════════════════════════════════════════════════════════════════════
32
- // TERMINAL UI
33
- // ═══════════════════════════════════════════════════════════════════════════════
34
-
35
- const {
36
- ansi,
37
- colors,
38
- Spinner,
39
- } = require("./lib/terminal-ui");
40
-
41
- // Unified Output System
42
- const { output } = require("./lib/output/index.js");
43
-
44
- const BANNER = `
45
- ${ansi.rgb(0, 200, 255)} ██╗ ██╗██╗██████╗ ███████╗ ██████╗██╗ ██╗███████╗ ██████╗██╗ ██╗${ansi.reset}
46
- ${ansi.rgb(30, 180, 255)} ██║ ██║██║██╔══██╗██╔════╝██╔════╝██║ ██║██╔════╝██╔════╝██║ ██╔╝${ansi.reset}
47
- ${ansi.rgb(60, 160, 255)} ██║ ██║██║██████╔╝█████╗ ██║ ███████║█████╗ ██║ █████╔╝ ${ansi.reset}
48
- ${ansi.rgb(90, 140, 255)} ╚██╗ ██╔╝██║██╔══██╗██╔══╝ ██║ ██╔══██║██╔══╝ ██║ ██╔═██╗ ${ansi.reset}
49
- ${ansi.rgb(120, 120, 255)} ╚████╔╝ ██║██████╔╝███████╗╚██████╗██║ ██║███████╗╚██████╗██║ ██╗${ansi.reset}
50
- ${ansi.rgb(150, 100, 255)} ╚═══╝ ╚═╝╚═════╝ ╚══════╝ ╚═════╝╚═╝ ╚═╝╚══════╝ ╚═════╝╚═╝ ╚═╝${ansi.reset}
51
-
52
- ${ansi.dim} ┌─────────────────────────────────────────────────────────────────────┐${ansi.reset}
53
- ${ansi.dim} │${ansi.reset} ${ansi.rgb(255, 255, 255)}${ansi.bold}Authority System${ansi.reset} ${ansi.dim}•${ansi.reset} ${ansi.rgb(200, 200, 200)}The AI That Says No${ansi.reset} ${ansi.dim}│${ansi.reset}
54
- ${ansi.dim} └─────────────────────────────────────────────────────────────────────┘${ansi.reset}
55
- `;
56
-
57
- function printBanner() {
58
- console.log(BANNER);
59
- }
60
-
61
- // ═══════════════════════════════════════════════════════════════════════════════
62
- // ARGS PARSER
63
- // ═══════════════════════════════════════════════════════════════════════════════
64
-
65
- function parseArgs(args) {
66
- const { flags: globalFlags, cleanArgs } = parseGlobalFlags(args);
67
-
68
- const opts = {
69
- path: globalFlags.path || process.cwd(),
70
- json: globalFlags.json || false,
71
- verbose: globalFlags.verbose || false,
72
- help: globalFlags.help || false,
73
- noBanner: globalFlags.noBanner || false,
74
- ci: globalFlags.ci || false,
75
- quiet: globalFlags.quiet || false,
76
- // Subcommand
77
- subcommand: null, // 'list' or 'approve'
78
- // Authority options
79
- authority: null,
80
- authorities: [], // For multi-authority approval
81
- // File input
82
- files: [],
83
- diff: null,
84
- diffFile: null,
85
- // Output
86
- output: null,
87
- };
88
-
89
- for (let i = 0; i < cleanArgs.length; i++) {
90
- const arg = cleanArgs[i];
91
-
92
- // Subcommands
93
- if (arg === 'list' && !opts.subcommand) {
94
- opts.subcommand = 'list';
95
- } else if (arg === 'approve' && !opts.subcommand) {
96
- opts.subcommand = 'approve';
97
- }
98
- // Options
99
- else if (arg === '--authority' || arg === '-a') {
100
- const value = cleanArgs[++i];
101
- if (value) {
102
- opts.authority = value;
103
- if (!opts.authorities.includes(value)) {
104
- opts.authorities.push(value);
105
- }
106
- }
107
- }
108
- else if (arg.startsWith('--authority=')) {
109
- const value = arg.split('=')[1];
110
- opts.authority = value;
111
- if (!opts.authorities.includes(value)) {
112
- opts.authorities.push(value);
113
- }
114
- }
115
- else if (arg === '--file' || arg === '-f') {
116
- const value = cleanArgs[++i];
117
- if (value) opts.files.push(value);
118
- }
119
- else if (arg === '--diff') {
120
- opts.diff = cleanArgs[++i];
121
- }
122
- else if (arg === '--diff-file') {
123
- opts.diffFile = cleanArgs[++i];
124
- }
125
- else if (arg === '--output' || arg === '-o') {
126
- opts.output = cleanArgs[++i];
127
- }
128
- else if (arg === '--path' || arg === '-p') {
129
- opts.path = cleanArgs[++i] || process.cwd();
130
- }
131
- else if (arg.startsWith('--path=')) {
132
- opts.path = arg.split('=')[1];
133
- }
134
- }
135
-
136
- // Default subcommand
137
- if (!opts.subcommand) {
138
- opts.subcommand = 'list';
139
- }
140
-
141
- return opts;
142
- }
143
-
144
- function printHelp(showBanner = true) {
145
- if (showBanner && shouldShowBanner({})) {
146
- printBanner();
147
- }
148
- console.log(`
149
- ${ansi.bold}USAGE${ansi.reset}
150
- ${colors.accent}vibecheck authority${ansi.reset} <subcommand> [options]
151
-
152
- ${ansi.bold}SUBCOMMANDS${ansi.reset}
153
- ${colors.accent}list${ansi.reset} List all available authorities
154
- ${colors.accent}approve${ansi.reset} Request approval from an authority
155
-
156
- ${ansi.bold}AUTHORITY OPTIONS${ansi.reset}
157
- ${colors.accent}--authority, -a${ansi.reset} Authority to request approval from
158
- Can be specified multiple times for multi-approval
159
-
160
- ${ansi.bold}INPUT OPTIONS${ansi.reset}
161
- ${colors.accent}--file, -f${ansi.reset} File to include in review (can be repeated)
162
- ${colors.accent}--diff${ansi.reset} Git diff string to review
163
- ${colors.accent}--diff-file${ansi.reset} Read diff from file
164
-
165
- ${ansi.bold}OUTPUT OPTIONS${ansi.reset}
166
- ${colors.accent}--json${ansi.reset} Output as JSON
167
- ${colors.accent}--output, -o${ansi.reset} Save result to file
168
-
169
- ${ansi.bold}GLOBAL OPTIONS${ansi.reset}
170
- ${colors.accent}--path, -p <dir>${ansi.reset} Run in specified directory
171
- ${colors.accent}--verbose, -v${ansi.reset} Show detailed output
172
- ${colors.accent}--quiet, -q${ansi.reset} Suppress non-essential output
173
- ${colors.accent}--ci${ansi.reset} CI mode (quiet + exit codes)
174
- ${colors.accent}--help, -h${ansi.reset} Show this help
175
-
176
- ${ansi.bold}💡 EXAMPLES${ansi.reset}
177
-
178
- ${ansi.dim}# List available authorities${ansi.reset}
179
- vibecheck authority list
180
-
181
- ${ansi.dim}# Request security review${ansi.reset}
182
- vibecheck authority approve --authority security
183
-
184
- ${ansi.dim}# Review specific files${ansi.reset}
185
- vibecheck authority approve -a security -f src/auth.ts -f src/login.ts
186
-
187
- ${ansi.dim}# Review a diff${ansi.reset}
188
- git diff HEAD~1 | vibecheck authority approve -a security --diff-file -
189
-
190
- ${ansi.dim}# Multi-authority approval${ansi.reset}
191
- vibecheck authority approve -a security -a quality -a architecture
192
-
193
- ${ansi.dim}# JSON output for CI${ansi.reset}
194
- vibecheck authority approve -a security --json --ci
195
-
196
- ${ansi.bold}📊 VERDICTS${ansi.reset}
197
- ${colors.success}APPROVED${ansi.reset} Review passed (exit 0)
198
- ${colors.error}REJECTED${ansi.reset} Issues found (exit 1)
199
- ${colors.warning}PENDING${ansi.reset} Awaiting human approval (exit 2)
200
-
201
- ${ansi.bold}🔗 RELATED COMMANDS${ansi.reset}
202
- ${colors.accent}vibecheck approve${ansi.reset} Authority verdicts ${ansi.dim}(alias)${ansi.reset}
203
- ${colors.accent}vibecheck scan${ansi.reset} Full code analysis
204
- ${colors.accent}vibecheck ship${ansi.reset} SHIP/WARN/BLOCK verdict
205
-
206
- ${ansi.dim}─────────────────────────────────────────────────────────────${ansi.reset}
207
- ${ansi.dim}Documentation: https://docs.vibecheckai.dev/cli/authority${ansi.reset}
208
- `);
209
- }
210
-
211
- // ═══════════════════════════════════════════════════════════════════════════════
212
- // LIST COMMAND
213
- // ═══════════════════════════════════════════════════════════════════════════════
214
-
215
- async function runAuthorityList(opts) {
216
- const authorities = await listAuthorities();
217
-
218
- if (opts.json) {
219
- console.log(JSON.stringify(authorities, null, 2));
220
- return 0;
221
- }
222
-
223
- console.log(`\n ${ansi.bold}Available Authorities${ansi.reset}\n`);
224
- console.log(` ┌${"─".repeat(66)}┐`);
225
- console.log(` │ ${"Authority".padEnd(14)} │ ${"Description".padEnd(35)} │ ${"Type".padEnd(6)} │ ${"Tier".padEnd(4)} │`);
226
- console.log(` ├${"─".repeat(66)}┤`);
227
-
228
- for (const auth of authorities) {
229
- const typeLabel = auth.automated ? "Auto" : "Human";
230
- const typeColor = auth.automated ? colors.success : colors.warning;
231
- const tierColor = auth.tier === "free" ? colors.success : colors.accent;
232
-
233
- console.log(
234
- ` │ ${colors.accent}${auth.name.padEnd(14)}${ansi.reset} │ ${auth.description.slice(0, 35).padEnd(35)} │ ${typeColor}${typeLabel.padEnd(6)}${ansi.reset} │ ${tierColor}${auth.tier.padEnd(4)}${ansi.reset} │`
235
- );
236
- }
237
-
238
- console.log(` └${"─".repeat(66)}┘`);
239
- console.log();
240
- console.log(` ${ansi.dim}Usage: vibecheck authority approve --authority <name>${ansi.reset}`);
241
- console.log();
242
-
243
- return 0;
244
- }
245
-
246
- // ═══════════════════════════════════════════════════════════════════════════════
247
- // APPROVE COMMAND
248
- // ═══════════════════════════════════════════════════════════════════════════════
249
-
250
- async function runAuthorityApprove(opts) {
251
- const projectPath = path.resolve(opts.path);
252
-
253
- // Validate authority
254
- if (opts.authorities.length === 0) {
255
- if (!opts.authority) {
256
- console.error(`\n ${colors.error}✗${ansi.reset} Authority required\n`);
257
- console.log(` ${ansi.dim}Usage: vibecheck authority approve --authority <name>${ansi.reset}`);
258
- console.log(` ${ansi.dim}List: vibecheck authority list${ansi.reset}\n`);
259
- return EXIT.USER_ERROR;
260
- }
261
- opts.authorities = [opts.authority];
262
- }
263
-
264
- // Validate all authorities exist
265
- for (const auth of opts.authorities) {
266
- if (!hasAuthority(auth)) {
267
- const authorities = await listAuthorities();
268
- console.error(`\n ${colors.error}✗${ansi.reset} Unknown authority: ${auth}\n`);
269
- console.log(` ${ansi.dim}Available: ${authorities.map(a => a.name).join(", ")}${ansi.reset}\n`);
270
- return EXIT.USER_ERROR;
271
- }
272
- }
273
-
274
- // Build payload
275
- const payload = {
276
- files: [],
277
- diff: opts.diff || "",
278
- context: {
279
- projectPath,
280
- branch: process.env.GITHUB_HEAD_REF || process.env.BRANCH_NAME,
281
- commit: process.env.GITHUB_SHA || process.env.COMMIT_SHA,
282
- },
283
- };
284
-
285
- // Load files
286
- for (const filePath of opts.files) {
287
- const fullPath = path.resolve(projectPath, filePath);
288
- try {
289
- const content = fs.readFileSync(fullPath, "utf-8");
290
- payload.files.push({
291
- path: filePath,
292
- content,
293
- });
294
- } catch (err) {
295
- if (!opts.quiet) {
296
- console.warn(` ${colors.warning}⚠${ansi.reset} Could not read file: ${filePath}`);
297
- }
298
- }
299
- }
300
-
301
- // Load diff from file if specified
302
- if (opts.diffFile) {
303
- try {
304
- if (opts.diffFile === "-") {
305
- // Read from stdin
306
- payload.diff = fs.readFileSync(0, "utf-8");
307
- } else {
308
- payload.diff = fs.readFileSync(opts.diffFile, "utf-8");
309
- }
310
- } catch (err) {
311
- console.error(`\n ${colors.error}✗${ansi.reset} Could not read diff file: ${opts.diffFile}\n`);
312
- return EXIT.USER_ERROR;
313
- }
314
- }
315
-
316
- // If no files or diff provided, try to get staged diff
317
- if (payload.files.length === 0 && !payload.diff) {
318
- try {
319
- const { execSync } = require("child_process");
320
- payload.diff = execSync("git diff --staged", {
321
- cwd: projectPath,
322
- encoding: "utf-8",
323
- stdio: ["pipe", "pipe", "pipe"],
324
- });
325
-
326
- if (!payload.diff) {
327
- // Try unstaged diff
328
- payload.diff = execSync("git diff", {
329
- cwd: projectPath,
330
- encoding: "utf-8",
331
- stdio: ["pipe", "pipe", "pipe"],
332
- });
333
- }
334
- } catch (err) {
335
- // Not a git repo or no changes
336
- }
337
- }
338
-
339
- // Show info
340
- if (!opts.quiet && !opts.json) {
341
- console.log(`\n ${ansi.dim}Project:${ansi.reset} ${ansi.bold}${path.basename(projectPath)}${ansi.reset}`);
342
- console.log(` ${ansi.dim}Authorities:${ansi.reset} ${colors.accent}${opts.authorities.join(", ")}${ansi.reset}`);
343
- console.log(` ${ansi.dim}Files:${ansi.reset} ${payload.files.length}`);
344
- console.log(` ${ansi.dim}Diff lines:${ansi.reset} ${payload.diff.split("\n").length}`);
345
- console.log();
346
- }
347
-
348
- // Run approval
349
- const spinner = new Spinner({ color: colors.primary });
350
-
351
- if (!opts.quiet && !opts.json) {
352
- spinner.start(`Requesting approval from ${opts.authorities.length} ${opts.authorities.length === 1 ? "authority" : "authorities"}...`);
353
- }
354
-
355
- let results;
356
-
357
- try {
358
- if (opts.authorities.length === 1) {
359
- const result = await requestApproval(opts.authorities[0], payload);
360
- results = [result];
361
- } else {
362
- results = await requestMultipleApprovals(opts.authorities, payload);
363
- }
364
- } catch (error) {
365
- if (spinner) spinner.fail(`Authority review failed: ${error.message}`);
366
- throw error;
367
- }
368
-
369
- if (!opts.quiet && !opts.json) {
370
- spinner.succeed("Review complete");
371
- }
372
-
373
- // Get aggregated verdict for multi-authority
374
- const aggregated = getAggregatedVerdict(results);
375
-
376
- // JSON output
377
- if (opts.json) {
378
- const output = {
379
- verdict: aggregated.verdict,
380
- summary: aggregated.summary,
381
- blockers: aggregated.blockers,
382
- results,
383
- timestamp: new Date().toISOString(),
384
- };
385
- console.log(JSON.stringify(output, null, 2));
386
-
387
- // Save to file if requested
388
- if (opts.output) {
389
- fs.writeFileSync(opts.output, JSON.stringify(output, null, 2));
390
- }
391
-
392
- return aggregated.verdict === "APPROVED" ? 0 : aggregated.verdict === "PENDING" ? 2 : 1;
393
- }
394
-
395
- // Pretty output
396
- console.log();
397
- printVerdictSummary(aggregated, results);
398
-
399
- // Print detailed findings
400
- if (opts.verbose) {
401
- for (const result of results) {
402
- if (result.findings && result.findings.length > 0) {
403
- console.log(`\n ${ansi.bold}${result.authority} Findings:${ansi.reset}\n`);
404
-
405
- for (const finding of result.findings.slice(0, 10)) {
406
- const severityIcon = finding.severity === "critical" ? colors.error + "●" :
407
- finding.severity === "high" ? colors.warning + "●" :
408
- finding.severity === "medium" ? colors.accent + "●" :
409
- ansi.dim + "○";
410
-
411
- console.log(` ${severityIcon}${ansi.reset} ${finding.message}`);
412
- if (finding.file) {
413
- console.log(` ${ansi.dim}${finding.file}${finding.line ? `:${finding.line}` : ""}${ansi.reset}`);
414
- }
415
- if (finding.evidence) {
416
- console.log(` ${ansi.dim}${finding.evidence.slice(0, 60)}...${ansi.reset}`);
417
- }
418
- }
419
-
420
- if (result.findings.length > 10) {
421
- console.log(` ${ansi.dim}... and ${result.findings.length - 10} more findings${ansi.reset}`);
422
- }
423
- }
424
- }
425
- }
426
-
427
- // Save to file if requested
428
- if (opts.output) {
429
- const output = {
430
- verdict: aggregated.verdict,
431
- summary: aggregated.summary,
432
- blockers: aggregated.blockers,
433
- results,
434
- timestamp: new Date().toISOString(),
435
- };
436
- fs.writeFileSync(opts.output, JSON.stringify(output, null, 2));
437
- console.log(`\n ${colors.success}✓${ansi.reset} Results saved to: ${opts.output}`);
438
- }
439
-
440
- console.log();
441
-
442
- return aggregated.verdict === "APPROVED" ? 0 : aggregated.verdict === "PENDING" ? 2 : 1;
443
- }
444
-
445
- function printVerdictSummary(aggregated, results) {
446
- const verdictSymbol = aggregated.verdict === "APPROVED" ? colors.success + "✓" :
447
- aggregated.verdict === "PENDING" ? colors.warning + "○" :
448
- colors.error + "✗";
449
-
450
- const verdictColor = aggregated.verdict === "APPROVED" ? colors.success :
451
- aggregated.verdict === "PENDING" ? colors.warning :
452
- colors.error;
453
-
454
- console.log(" ┌────────────────────────────────────────────────────────────────────┐");
455
- console.log(` │ ${verdictSymbol}${ansi.reset} Verdict: ${verdictColor}${ansi.bold}${aggregated.verdict}${ansi.reset} │`);
456
- console.log(" ├────────────────────────────────────────────────────────────────────┤");
457
-
458
- // Summary line
459
- const { approved, rejected, pending, error } = aggregated.summary;
460
- const parts = [];
461
- if (approved > 0) parts.push(`${colors.success}${approved} approved${ansi.reset}`);
462
- if (rejected > 0) parts.push(`${colors.error}${rejected} rejected${ansi.reset}`);
463
- if (pending > 0) parts.push(`${colors.warning}${pending} pending${ansi.reset}`);
464
- if (error > 0) parts.push(`${colors.error}${error} error${ansi.reset}`);
465
-
466
- console.log(` │ ${parts.join(" ")}`.padEnd(75) + "│");
467
- console.log(" └────────────────────────────────────────────────────────────────────┘");
468
-
469
- // Individual results
470
- console.log(`\n ${ansi.bold}Authority Results:${ansi.reset}\n`);
471
-
472
- for (const result of results) {
473
- const resultSymbol = result.verdict === "APPROVED" ? colors.success + "✓" :
474
- result.verdict === "PENDING" ? colors.warning + "○" :
475
- colors.error + "✗";
476
-
477
- const findingsCount = result.findings ? result.findings.length : 0;
478
- const findingsStr = findingsCount > 0 ? `${ansi.dim}(${findingsCount} findings)${ansi.reset}` : "";
479
-
480
- console.log(` ${resultSymbol}${ansi.reset} ${colors.accent}${result.authority}${ansi.reset}: ${result.verdict} ${findingsStr}`);
481
- console.log(` ${ansi.dim}${result.reason}${ansi.reset}`);
482
-
483
- if (result.qualityScore !== undefined) {
484
- console.log(` ${ansi.dim}Quality Score: ${result.qualityScore}/100${ansi.reset}`);
485
- }
486
- }
487
-
488
- // Blockers
489
- if (aggregated.blockers.length > 0) {
490
- console.log(`\n ${ansi.bold}Blockers:${ansi.reset}\n`);
491
- for (const blocker of aggregated.blockers) {
492
- console.log(` ${colors.error}•${ansi.reset} ${blocker}`);
493
- }
494
- }
495
- }
496
-
497
- // ═══════════════════════════════════════════════════════════════════════════════
498
- // MAIN COMMAND
499
- // ═══════════════════════════════════════════════════════════════════════════════
500
-
501
- async function runAuthority(args) {
502
- const opts = parseArgs(args);
503
-
504
- // Show help
505
- if (opts.help) {
506
- printHelp(shouldShowBanner(opts));
507
- return 0;
508
- }
509
-
510
- // Print banner
511
- if (shouldShowBanner(opts) && !opts.json) {
512
- printBanner();
513
- }
514
-
515
- // Route to subcommand
516
- switch (opts.subcommand) {
517
- case "list":
518
- return await runAuthorityList(opts);
519
- case "approve":
520
- return await runAuthorityApprove(opts);
521
- default:
522
- return await runAuthorityList(opts);
523
- }
524
- }
525
-
526
- module.exports = {
527
- runAuthority: withErrorHandling(runAuthority, "Authority command failed"),
528
- };