@vibecheckai/cli 3.1.5 → 3.1.6

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.
@@ -20,6 +20,7 @@ const {
20
20
  buildIDORTestPlan,
21
21
  formatIDORPlan
22
22
  } = require("./lib/permissions");
23
+ const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
23
24
 
24
25
  // Entitlements enforcement
25
26
  const entitlements = require("./lib/entitlements-v2");
@@ -43,7 +44,7 @@ async function runPermissions(args) {
43
44
  const opts = parseArgs(args);
44
45
 
45
46
  if (opts.help) {
46
- printHelp();
47
+ printHelp(shouldShowBanner(opts));
47
48
  return 0;
48
49
  }
49
50
 
@@ -225,8 +226,12 @@ async function runPermissions(args) {
225
226
  }
226
227
 
227
228
  function parseArgs(args) {
229
+ // Parse global flags first
230
+ const { flags: globalFlags, cleanArgs } = parseGlobalFlags(args);
231
+
228
232
  const opts = {
229
- path: process.cwd(),
233
+ ...globalFlags, // Merge global flags (json, verbose, noBanner, quiet, ci, etc.)
234
+ path: globalFlags.path || process.cwd(),
230
235
  url: null,
231
236
  learn: false,
232
237
  prove: false,
@@ -237,16 +242,17 @@ function parseArgs(args) {
237
242
  help: false,
238
243
  };
239
244
 
240
- for (let i = 0; i < args.length; i++) {
241
- const arg = args[i];
245
+ // Parse command-specific args from cleanArgs
246
+ for (let i = 0; i < cleanArgs.length; i++) {
247
+ const arg = cleanArgs[i];
242
248
  if (arg === "--learn") opts.learn = true;
243
249
  else if (arg === "--prove") opts.prove = true;
244
250
  else if (arg === "--matrix") opts.matrix = true;
245
251
  else if (arg === "--idor") opts.idor = true;
246
252
  else if (arg === "--safe") opts.safe = true;
247
- else if (arg === "--url") opts.url = args[++i];
248
- else if (arg === "--fastify-entry") opts.fastifyEntry = args[++i];
249
- else if (arg === "--path" || arg === "-p") opts.path = args[++i];
253
+ else if (arg === "--url") opts.url = cleanArgs[++i];
254
+ else if (arg === "--fastify-entry") opts.fastifyEntry = cleanArgs[++i];
255
+ else if (arg === "--path" || arg === "-p") opts.path = cleanArgs[++i];
250
256
  else if (arg === "--help" || arg === "-h") opts.help = true;
251
257
  }
252
258
 
@@ -30,6 +30,7 @@ const {
30
30
  verdictToExitCode,
31
31
  saveArtifact
32
32
  } = require("./lib/cli-output");
33
+ const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
33
34
 
34
35
  let runReality;
35
36
  try {
@@ -667,8 +668,10 @@ function printTimelineSummary(timeline) {
667
668
  // HELP DISPLAY
668
669
  // ═══════════════════════════════════════════════════════════════════════════════
669
670
 
670
- function printHelp() {
671
- console.log(BANNER_FULL);
671
+ function printHelp(showBanner = true) {
672
+ if (showBanner && shouldShowBanner({})) {
673
+ console.log(BANNER_FULL);
674
+ }
672
675
  console.log(`
673
676
  ${c.bold}Usage:${c.reset} vibecheck prove [options]
674
677
 
@@ -738,30 +741,33 @@ async function runProve(argsOrOpts = {}, context = {}) {
738
741
 
739
742
  // Handle array args from CLI
740
743
  if (Array.isArray(argsOrOpts)) {
741
- if (argsOrOpts.includes("--help") || argsOrOpts.includes("-h")) {
742
- printHelp();
744
+ // Parse global flags first
745
+ const { flags: globalFlags, cleanArgs } = parseGlobalFlags(argsOrOpts);
746
+
747
+ if (globalFlags.help) {
748
+ printHelp(shouldShowBanner(globalFlags));
743
749
  return 0;
744
750
  }
751
+
745
752
  const getArg = (flags) => {
746
753
  for (const f of flags) {
747
- const idx = argsOrOpts.indexOf(f);
748
- if (idx !== -1 && idx < argsOrOpts.length - 1) return argsOrOpts[idx + 1];
754
+ const idx = cleanArgs.indexOf(f);
755
+ if (idx !== -1 && idx < cleanArgs.length - 1) return cleanArgs[idx + 1];
749
756
  }
750
757
  return undefined;
751
758
  };
752
759
  argsOrOpts = {
760
+ ...globalFlags, // Merge global flags (json, verbose, noBanner, quiet, ci, etc.)
753
761
  url: getArg(["--url", "-u"]),
754
762
  auth: getArg(["--auth"]),
755
763
  storageState: getArg(["--storage-state"]),
756
764
  fastifyEntry: getArg(["--fastify-entry"]),
757
765
  maxFixRounds: parseInt(getArg(["--max-fix-rounds"]) || "3", 10),
758
- skipReality: argsOrOpts.includes("--skip-reality"),
759
- skipFix: argsOrOpts.includes("--skip-fix"),
760
- headed: argsOrOpts.includes("--headed"),
761
- danger: argsOrOpts.includes("--danger"),
762
- json: argsOrOpts.includes("--json"),
766
+ skipReality: cleanArgs.includes("--skip-reality"),
767
+ skipFix: cleanArgs.includes("--skip-fix"),
768
+ headed: cleanArgs.includes("--headed"),
769
+ danger: cleanArgs.includes("--danger"),
763
770
  output: getArg(["--output", "-o"]),
764
- ci: argsOrOpts.includes("--ci"),
765
771
  };
766
772
  }
767
773
 
@@ -17,6 +17,7 @@
17
17
 
18
18
  const path = require("path");
19
19
  const fs = require("fs");
20
+ const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
20
21
 
21
22
  // Entitlements enforcement
22
23
  let entitlements;
@@ -72,11 +73,14 @@ const {
72
73
  } = require("./lib/report-output");
73
74
 
74
75
  function parseArgs(args) {
76
+ // Parse global flags first
77
+ const { flags: globalFlags, cleanArgs } = parseGlobalFlags(args);
78
+
75
79
  const opts = {
76
80
  type: "technical",
77
81
  format: "html",
78
- path: ".",
79
- output: null,
82
+ path: globalFlags.path || ".",
83
+ output: globalFlags.output || null,
80
84
  logo: null,
81
85
  company: null,
82
86
  theme: "dark",
@@ -86,18 +90,23 @@ function parseArgs(args) {
86
90
  redactPaths: false,
87
91
  maxFindings: 50,
88
92
  open: false,
89
- help: false,
90
- quiet: false,
93
+ help: globalFlags.help || false,
94
+ quiet: globalFlags.quiet || false,
95
+ json: globalFlags.json || false,
96
+ noBanner: globalFlags.noBanner || false,
97
+ ci: globalFlags.ci || false,
98
+ verbose: globalFlags.verbose || false,
91
99
  };
92
100
 
93
- for (let i = 0; i < args.length; i++) {
94
- const a = args[i];
95
- if (a === "--type" || a === "-t") opts.type = args[++i];
96
- if (a === "--format" || a === "-f") opts.format = args[++i];
97
- if (a === "--output" || a === "-o") opts.output = args[++i];
98
- if (a === "--logo") opts.logo = args[++i];
99
- if (a === "--company") opts.company = args[++i];
100
- if (a === "--theme") opts.theme = args[++i];
101
+ // Parse command-specific args
102
+ for (let i = 0; i < cleanArgs.length; i++) {
103
+ const a = cleanArgs[i];
104
+ if (a === "--type" || a === "-t") opts.type = cleanArgs[++i];
105
+ if (a === "--format" || a === "-f") opts.format = cleanArgs[++i];
106
+ if (a === "--output" || a === "-o") opts.output = cleanArgs[++i];
107
+ if (a === "--logo") opts.logo = cleanArgs[++i];
108
+ if (a === "--company") opts.company = cleanArgs[++i];
109
+ if (a === "--theme") opts.theme = cleanArgs[++i];
101
110
  if (a === "--framework") opts.framework = args[++i];
102
111
  if (a === "--light") opts.theme = "light";
103
112
  if (a === "--dark") opts.theme = "dark";
@@ -115,8 +124,10 @@ function parseArgs(args) {
115
124
  return opts;
116
125
  }
117
126
 
118
- function printHelp() {
119
- console.log(BANNER);
127
+ function printHelp(showBanner = true) {
128
+ if (showBanner && shouldShowBanner({})) {
129
+ console.log(BANNER);
130
+ }
120
131
  console.log(formatHelp());
121
132
  }
122
133
 
@@ -124,7 +135,7 @@ async function runReport(args) {
124
135
  const opts = parseArgs(args);
125
136
 
126
137
  if (opts.help) {
127
- printHelp();
138
+ printHelp(shouldShowBanner(opts));
128
139
  return 0;
129
140
  }
130
141
 
@@ -179,9 +190,11 @@ async function runReport(args) {
179
190
 
180
191
  // Display banner and report info
181
192
  if (!opts.quiet) {
182
- console.log(BANNER);
183
- console.log(renderReportInfo(opts.type, opts.format, null));
184
- console.log('');
193
+ if (shouldShowBanner(opts)) {
194
+ console.log(BANNER);
195
+ console.log(renderReportInfo(opts.type, opts.format, null));
196
+ console.log('');
197
+ }
185
198
  }
186
199
 
187
200
  // Progress spinner
@@ -17,6 +17,7 @@ const fs = require("fs");
17
17
  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
+ const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
20
21
 
21
22
  // ═══════════════════════════════════════════════════════════════════════════════
22
23
  // ENHANCED TERMINAL UI & OUTPUT MODULES
@@ -84,34 +85,38 @@ function printLayers(layers) {
84
85
  // ═══════════════════════════════════════════════════════════════════════════════
85
86
 
86
87
  function parseArgs(args) {
88
+ // Parse global flags first
89
+ const { flags: globalFlags, cleanArgs } = parseGlobalFlags(args);
90
+
87
91
  const opts = {
88
- path: process.cwd(),
92
+ path: globalFlags.path || process.cwd(),
89
93
  truth: false,
90
94
  reality: false,
91
95
  realitySniff: false,
92
96
  baseUrl: null,
93
- json: false,
97
+ json: globalFlags.json || false,
94
98
  sarif: false,
95
- verbose: false,
96
- help: false,
99
+ verbose: globalFlags.verbose || false,
100
+ help: globalFlags.help || false,
97
101
  autofix: false,
98
102
  save: true, // Always save results by default
103
+ noBanner: globalFlags.noBanner || false,
104
+ ci: globalFlags.ci || false,
105
+ quiet: globalFlags.quiet || false,
99
106
  };
100
107
 
101
- for (let i = 0; i < args.length; i++) {
102
- const arg = args[i];
108
+ // Parse command-specific args from cleanArgs
109
+ for (let i = 0; i < cleanArgs.length; i++) {
110
+ const arg = cleanArgs[i];
103
111
 
104
112
  if (arg === '--truth' || arg === '-t') opts.truth = true;
105
113
  else if (arg === '--reality' || arg === '-r') { opts.reality = true; opts.truth = true; }
106
114
  else if (arg === '--reality-sniff' || arg === '--sniff') opts.realitySniff = true;
107
- else if (arg === '--url' || arg === '-u') { opts.baseUrl = args[++i]; opts.reality = true; opts.truth = true; }
108
- else if (arg === '--json') opts.json = true;
115
+ else if (arg === '--url' || arg === '-u') { opts.baseUrl = cleanArgs[++i]; opts.reality = true; opts.truth = true; }
109
116
  else if (arg === '--sarif') opts.sarif = true;
110
- else if (arg === '--verbose' || arg === '-v') opts.verbose = true;
111
- else if (arg === '--help' || arg === '-h') opts.help = true;
112
117
  else if (arg === '--autofix' || arg === '--fix' || arg === '-f') opts.autofix = true;
113
118
  else if (arg === '--no-save') opts.save = false;
114
- else if (arg === '--path' || arg === '-p') opts.path = args[++i];
119
+ else if (arg === '--path' || arg === '-p') opts.path = cleanArgs[++i] || process.cwd();
115
120
  else if (arg.startsWith('--path=')) opts.path = arg.split('=')[1];
116
121
  else if (!arg.startsWith('-')) opts.path = path.resolve(arg);
117
122
  }
@@ -119,10 +124,14 @@ function parseArgs(args) {
119
124
  return opts;
120
125
  }
121
126
 
122
- function printHelp() {
123
- console.log(BANNER);
127
+ function printHelp(showBanner = true) {
128
+ if (showBanner && shouldShowBanner({})) {
129
+ console.log(BANNER);
130
+ }
124
131
  console.log(`
125
- ${ansi.bold}Usage:${ansi.reset} vibecheck scan [path] [options]
132
+ ${ansi.bold}Usage:${ansi.reset} vibecheck scan ${ansi.dim}(s)${ansi.reset} [path] [options]
133
+
134
+ ${ansi.bold}Aliases:${ansi.reset} ${ansi.dim}s${ansi.reset}
126
135
 
127
136
  ${ansi.bold}Scan Modes:${ansi.reset}
128
137
  ${colors.accent}(default)${ansi.reset} Layer 1: AST static analysis ${ansi.dim}(fast)${ansi.reset}
@@ -440,7 +449,7 @@ async function runScan(args) {
440
449
 
441
450
  // Show help if requested
442
451
  if (opts.help) {
443
- printHelp();
452
+ printHelp(shouldShowBanner(opts));
444
453
  return 0;
445
454
  }
446
455
 
@@ -463,8 +472,10 @@ async function runScan(args) {
463
472
  }
464
473
  }
465
474
 
466
- // Print banner
467
- printBanner();
475
+ // Print banner (respects --no-banner, VIBECHECK_NO_BANNER, --ci, --quiet, --json)
476
+ if (shouldShowBanner(opts)) {
477
+ printBanner();
478
+ }
468
479
 
469
480
  const projectPath = path.resolve(opts.path);
470
481
  const startTime = Date.now();
@@ -13,6 +13,7 @@ const { withErrorHandling } = require("./lib/error-handler");
13
13
  const { ensureOutputDir, detectProjectFeatures } = require("./utils");
14
14
  const { enforceLimit, enforceFeature, trackUsage, getCurrentTier } = require("./lib/entitlements");
15
15
  const { emitShipCheck } = require("./lib/audit-bridge");
16
+ const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
16
17
  const {
17
18
  generateRunId,
18
19
  createJsonOutput,
@@ -607,10 +608,14 @@ function printFixResults(fixResults) {
607
608
  // HELP DISPLAY
608
609
  // ═══════════════════════════════════════════════════════════════════════════════
609
610
 
610
- function printHelp() {
611
- console.log(BANNER);
611
+ function printHelp(showBanner = true) {
612
+ if (showBanner && shouldShowBanner({})) {
613
+ console.log(BANNER);
614
+ }
612
615
  console.log(`
613
- ${ansi.bold}Usage:${ansi.reset} vibecheck ship [options]
616
+ ${ansi.bold}Usage:${ansi.reset} vibecheck ship ${ansi.dim}(go)${ansi.reset} [options]
617
+
618
+ ${ansi.bold}Aliases:${ansi.reset} ${ansi.dim}go${ansi.reset}
614
619
 
615
620
  ${ansi.bold}The One Command${ansi.reset} — Get a ship verdict: ${colors.success}SHIP${ansi.reset} | ${colors.warning}WARN${ansi.reset} | ${colors.error}BLOCK${ansi.reset}
616
621
 
@@ -754,35 +759,36 @@ function getGapType(category) {
754
759
  // ═══════════════════════════════════════════════════════════════════════════════
755
760
 
756
761
  function parseArgs(args) {
762
+ // Parse global flags first
763
+ const { flags: globalFlags, cleanArgs } = parseGlobalFlags(args);
764
+
757
765
  const opts = {
758
766
  fix: false,
759
- path: ".",
760
- verbose: false,
761
- json: false,
767
+ path: globalFlags.path || ".",
768
+ verbose: globalFlags.verbose || false,
769
+ json: globalFlags.json || false,
762
770
  badge: false,
763
771
  assist: false,
764
- strict: false,
765
- ci: false,
772
+ strict: globalFlags.strict || false,
773
+ ci: globalFlags.ci || false,
766
774
  mode: null, // "scan" for scan mode
767
775
  withRuntime: false, // merge runtime results
768
- help: false,
776
+ help: globalFlags.help || false,
777
+ noBanner: globalFlags.noBanner || false,
778
+ quiet: globalFlags.quiet || false,
769
779
  };
770
780
 
771
- for (let i = 0; i < args.length; i++) {
772
- const a = args[i];
781
+ // Parse command-specific args
782
+ for (let i = 0; i < cleanArgs.length; i++) {
783
+ const a = cleanArgs[i];
773
784
  if (a === "--fix" || a === "-f") opts.fix = true;
774
- else if (a === "--verbose" || a === "-v") opts.verbose = true;
775
- else if (a === "--json") opts.json = true;
776
785
  else if (a === "--badge" || a === "-b") opts.badge = true;
777
786
  else if (a === "--assist") opts.assist = true;
778
- else if (a === "--strict") opts.strict = true;
779
- else if (a === "--ci") opts.ci = true;
780
- else if (a === "--mode") opts.mode = args[++i];
787
+ else if (a === "--mode") opts.mode = cleanArgs[++i];
781
788
  else if (a === "--with") {
782
- const next = args[++i];
789
+ const next = cleanArgs[++i];
783
790
  if (next === "runtime") opts.withRuntime = true;
784
791
  }
785
- else if (a === "--help" || a === "-h") opts.help = true;
786
792
  else if (a.startsWith("--path=")) opts.path = a.split("=")[1];
787
793
  else if (a === "--path" || a === "-p") opts.path = args[++i];
788
794
  }
@@ -804,7 +810,7 @@ async function runShip(args, context = {}) {
804
810
 
805
811
  // Show help if requested
806
812
  if (opts.help) {
807
- printHelp();
813
+ printHelp(shouldShowBanner(opts));
808
814
  return 0;
809
815
  }
810
816
 
@@ -829,8 +835,8 @@ async function runShip(args, context = {}) {
829
835
  const outputDir = path.join(projectPath, ".vibecheck");
830
836
  const projectName = path.basename(projectPath);
831
837
 
832
- // Print banner (unless quiet/json/ci)
833
- if (!opts.json && !opts.ci) {
838
+ // Print banner (respects --no-banner, VIBECHECK_NO_BANNER, --ci, --quiet, --json)
839
+ if (shouldShowBanner(opts)) {
834
840
  printBanner();
835
841
  console.log(` ${ansi.dim}Project:${ansi.reset} ${ansi.bold}${projectName}${ansi.reset}`);
836
842
  console.log(` ${ansi.dim}Path:${ansi.reset} ${projectPath}`);
@@ -14,6 +14,7 @@
14
14
  const fs = require("fs");
15
15
  const path = require("path");
16
16
  const { formatStatusOutput } = require("./lib/status-output");
17
+ const { parseGlobalFlags } = require("./lib/global-flags");
17
18
 
18
19
  function readJsonSafe(p) {
19
20
  try {
@@ -24,7 +25,22 @@ function readJsonSafe(p) {
24
25
  }
25
26
  }
26
27
 
27
- async function runStatus({ repoRoot, json = false } = {}) {
28
+ async function runStatus(args = []) {
29
+ // Parse global flags
30
+ const { flags: globalFlags, cleanArgs } = parseGlobalFlags(args);
31
+
32
+ // Support both old API ({ repoRoot, json }) and new API (args array)
33
+ let repoRoot, json;
34
+ if (typeof args === 'object' && !Array.isArray(args) && args.repoRoot !== undefined) {
35
+ // Old API compatibility
36
+ repoRoot = args.repoRoot;
37
+ json = args.json || false;
38
+ } else {
39
+ // New API - parse from args
40
+ repoRoot = globalFlags.path || process.cwd();
41
+ json = globalFlags.json || false;
42
+ }
43
+
28
44
  const root = repoRoot || process.cwd();
29
45
 
30
46
  // Gather data