@vibecheckai/cli 3.1.4 → 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.
package/bin/registry.js CHANGED
@@ -86,7 +86,7 @@ const COMMANDS = {
86
86
  description: "Verdict engine - SHIP / WARN / BLOCK",
87
87
  tier: "free",
88
88
  category: "proof",
89
- aliases: ["verdict"],
89
+ aliases: ["verdict", "go"],
90
90
  caps: "static-only on FREE",
91
91
  runner: () => require("./runners/runShip").runShip
92
92
  },
@@ -0,0 +1,121 @@
1
+ # Command Enhancement Guide
2
+
3
+ This guide shows how to apply the enhancements from `vibecheck.js` to all command runners.
4
+
5
+ ## 1. Add Global Flags Support
6
+
7
+ ### Import the utilities:
8
+ ```javascript
9
+ const { parseGlobalFlags, shouldShowBanner } = require("./lib/global-flags");
10
+ ```
11
+
12
+ ### Update parseArgs function:
13
+ ```javascript
14
+ function parseArgs(args) {
15
+ // Parse global flags first
16
+ const { flags: globalFlags, cleanArgs } = parseGlobalFlags(args);
17
+
18
+ const opts = {
19
+ // ... existing options
20
+ path: globalFlags.path || process.cwd(),
21
+ json: globalFlags.json || false,
22
+ verbose: globalFlags.verbose || false,
23
+ help: globalFlags.help || false,
24
+ noBanner: globalFlags.noBanner || false,
25
+ ci: globalFlags.ci || false,
26
+ quiet: globalFlags.quiet || false,
27
+ };
28
+
29
+ // Parse command-specific args from cleanArgs
30
+ for (let i = 0; i < cleanArgs.length; i++) {
31
+ const a = cleanArgs[i];
32
+ // ... command-specific parsing
33
+ }
34
+
35
+ return opts;
36
+ }
37
+ ```
38
+
39
+ ## 2. Update Banner Printing
40
+
41
+ ### Update printHelp:
42
+ ```javascript
43
+ function printHelp(showBanner = true) {
44
+ if (showBanner && shouldShowBanner({})) {
45
+ console.log(BANNER);
46
+ }
47
+ // ... rest of help
48
+ }
49
+ ```
50
+
51
+ ### Update banner printing in main function:
52
+ ```javascript
53
+ async function runCommand(args) {
54
+ const opts = parseArgs(args);
55
+
56
+ if (opts.help) {
57
+ printHelp(shouldShowBanner(opts));
58
+ return 0;
59
+ }
60
+
61
+ // Print banner (respects --no-banner, VIBECHECK_NO_BANNER, --ci, --quiet, --json)
62
+ if (shouldShowBanner(opts)) {
63
+ printBanner();
64
+ }
65
+
66
+ // ... rest of command
67
+ }
68
+ ```
69
+
70
+ ## 3. Add Aliases to Help Text
71
+
72
+ Update help text to show aliases:
73
+ ```javascript
74
+ function printHelp(showBanner = true) {
75
+ // ...
76
+ console.log(`
77
+ ${ansi.bold}Usage:${ansi.reset} vibecheck command ${ansi.dim}(alias1, alias2)${ansi.reset} [options]
78
+
79
+ ${ansi.bold}Aliases:${ansi.reset} ${ansi.dim}alias1, alias2${ansi.reset}
80
+ `);
81
+ }
82
+ ```
83
+
84
+ ## 4. Lazy Loading (Optional)
85
+
86
+ For commands that load heavy modules, use lazy loading:
87
+ ```javascript
88
+ const { lazy } = require("./lib/global-flags");
89
+
90
+ const getHeavyModule = lazy("heavy-module", () => require("./lib/heavy-module"));
91
+
92
+ // Use later:
93
+ const heavyModule = getHeavyModule();
94
+ ```
95
+
96
+ ## Commands Updated
97
+
98
+ ✅ `runScan.js` - Full support for --no-banner, global flags, aliases in help
99
+ ✅ `runShip.js` - Full support for --no-banner, global flags, aliases in help
100
+ ✅ `runReport.js` - Full support for --no-banner, global flags
101
+ ✅ `runInit.js` - Already enhanced with all features
102
+
103
+ ## Commands Pending
104
+
105
+ - `runStatus.js` - No banner, but should support global flags
106
+ - `runFix.js` - Needs banner support
107
+ - `runProve.js` - Needs banner support
108
+ - `runContext.js` - Needs banner support
109
+ - `runCtx.js` - Needs banner support
110
+ - All other commands - Apply same pattern
111
+
112
+ ## Testing Checklist
113
+
114
+ For each command:
115
+ - [ ] `command --no-banner` suppresses banner
116
+ - [ ] `VIBECHECK_NO_BANNER=true command` suppresses banner
117
+ - [ ] `command --ci` suppresses banner
118
+ - [ ] `command --quiet` suppresses banner
119
+ - [ ] `command --json` suppresses banner
120
+ - [ ] `command --help` shows aliases (if any)
121
+ - [ ] Global flags (--path, --output, --verbose) work correctly
@@ -0,0 +1,213 @@
1
+ /**
2
+ * Global Flags Parser & Utilities
3
+ * Shared utilities for all commands to handle global flags consistently
4
+ */
5
+
6
+ // ═══════════════════════════════════════════════════════════════════════════════
7
+ // LAZY LOADING - Defer requires until needed
8
+ // ═══════════════════════════════════════════════════════════════════════════════
9
+ const lazyModules = {};
10
+
11
+ function lazy(name, loader) {
12
+ return () => {
13
+ if (!lazyModules[name]) {
14
+ lazyModules[name] = loader();
15
+ }
16
+ return lazyModules[name];
17
+ };
18
+ }
19
+
20
+ const getOs = lazy("os", () => require("os"));
21
+ const getPath = lazy("path", () => require("path"));
22
+ const getFs = lazy("fs", () => require("fs"));
23
+
24
+ // ═══════════════════════════════════════════════════════════════════════════════
25
+ // GLOBAL FLAGS PARSER
26
+ // ═══════════════════════════════════════════════════════════════════════════════
27
+
28
+ /**
29
+ * Parse global flags from command arguments
30
+ * Extracts global flags and returns clean args for command-specific parsing
31
+ */
32
+ function parseGlobalFlags(rawArgs) {
33
+ const flags = {
34
+ help: false,
35
+ version: false,
36
+ json: false,
37
+ ci: false,
38
+ quiet: false,
39
+ verbose: false,
40
+ debug: false,
41
+ strict: false,
42
+ noBanner: false,
43
+ path: process.cwd(),
44
+ output: null,
45
+ };
46
+
47
+ const cleanArgs = [];
48
+ let i = 0;
49
+
50
+ while (i < rawArgs.length) {
51
+ const arg = rawArgs[i];
52
+
53
+ switch (arg) {
54
+ case "--help":
55
+ case "-h":
56
+ flags.help = true;
57
+ break;
58
+ case "--version":
59
+ case "-v":
60
+ flags.version = true;
61
+ break;
62
+ case "--json":
63
+ flags.json = true;
64
+ break;
65
+ case "--ci":
66
+ flags.ci = true;
67
+ flags.noBanner = true; // CI mode automatically suppresses banner
68
+ break;
69
+ case "--quiet":
70
+ case "-q":
71
+ flags.quiet = true;
72
+ flags.noBanner = true; // Quiet mode also suppresses banner
73
+ break;
74
+ case "--verbose":
75
+ flags.verbose = true;
76
+ break;
77
+ case "--debug":
78
+ flags.debug = true;
79
+ break;
80
+ case "--strict":
81
+ flags.strict = true;
82
+ break;
83
+ case "--no-banner":
84
+ flags.noBanner = true;
85
+ break;
86
+ case "--path":
87
+ case "-p":
88
+ flags.path = rawArgs[++i] || process.cwd();
89
+ break;
90
+ case "--output":
91
+ case "-o":
92
+ flags.output = rawArgs[++i] || null;
93
+ break;
94
+ default:
95
+ if (arg.startsWith("--path=")) {
96
+ flags.path = arg.split("=")[1];
97
+ } else if (arg.startsWith("--output=")) {
98
+ flags.output = arg.split("=")[1];
99
+ } else {
100
+ cleanArgs.push(arg);
101
+ }
102
+ }
103
+ i++;
104
+ }
105
+
106
+ return { flags, cleanArgs };
107
+ }
108
+
109
+ // ═══════════════════════════════════════════════════════════════════════════════
110
+ // BANNER CHECKING
111
+ // ═══════════════════════════════════════════════════════════════════════════════
112
+
113
+ /**
114
+ * Check if banner should be shown
115
+ * Respects --no-banner flag, VIBECHECK_NO_BANNER env var, and VIBECHECK_QUIET
116
+ */
117
+ function shouldShowBanner(flags = {}) {
118
+ // Check environment variables first
119
+ if (process.env.VIBECHECK_NO_BANNER === "true") return false;
120
+ if (process.env.VIBECHECK_QUIET === "true") return false;
121
+
122
+ // Check flags
123
+ if (flags.noBanner === true) return false;
124
+ if (flags.ci === true) return false;
125
+ if (flags.quiet === true) return false;
126
+ if (flags.json === true) return false; // JSON output shouldn't have banners
127
+
128
+ return true;
129
+ }
130
+
131
+ // ═══════════════════════════════════════════════════════════════════════════════
132
+ // CI DETECTION
133
+ // ═══════════════════════════════════════════════════════════════════════════════
134
+
135
+ /**
136
+ * Check if running in CI environment
137
+ */
138
+ function isCI() {
139
+ return !!(
140
+ process.env.CI ||
141
+ process.env.CONTINUOUS_INTEGRATION ||
142
+ process.env.BUILD_NUMBER ||
143
+ process.env.TRAVIS ||
144
+ process.env.CIRCLECI ||
145
+ process.env.JENKINS_URL ||
146
+ process.env.GITLAB_CI ||
147
+ process.env.GITHUB_ACTIONS ||
148
+ process.env.BUILDKITE ||
149
+ process.env.TEAMCITY_VERSION ||
150
+ process.env.TF_BUILD
151
+ );
152
+ }
153
+
154
+ // ═══════════════════════════════════════════════════════════════════════════════
155
+ // CONFIG LOADING
156
+ // ═══════════════════════════════════════════════════════════════════════════════
157
+
158
+ /**
159
+ * Load config with environment variable support
160
+ */
161
+ function loadConfig(flags = {}) {
162
+ const path = getPath();
163
+ const fs = getFs();
164
+
165
+ const config = {
166
+ debug: false,
167
+ verbose: false,
168
+ quiet: false,
169
+ color: true,
170
+ analytics: true,
171
+ updateCheck: true,
172
+ timeout: 30000,
173
+ maxRetries: 3,
174
+ noBanner: false,
175
+ };
176
+
177
+ // Load project config if exists
178
+ const projectConfigPath = path.join(process.cwd(), ".vibecheckrc.json");
179
+ if (fs.existsSync(projectConfigPath)) {
180
+ try {
181
+ Object.assign(config, JSON.parse(fs.readFileSync(projectConfigPath, "utf-8")));
182
+ } catch {
183
+ // Ignore invalid config
184
+ }
185
+ }
186
+
187
+ // Environment overrides
188
+ if (process.env.VIBECHECK_DEBUG === "true") config.debug = true;
189
+ if (process.env.VIBECHECK_VERBOSE === "true") config.verbose = true;
190
+ if (process.env.VIBECHECK_QUIET === "true") config.quiet = true;
191
+ if (process.env.VIBECHECK_NO_BANNER === "true") config.noBanner = true;
192
+ if (process.env.NO_COLOR || process.env.VIBECHECK_NO_COLOR) config.color = false;
193
+
194
+ // Flag overrides (highest priority)
195
+ if (flags.debug) config.debug = true;
196
+ if (flags.verbose) config.verbose = true;
197
+ if (flags.quiet) config.quiet = true;
198
+ if (flags.noBanner) config.noBanner = true;
199
+ if (flags.ci) config.noBanner = true;
200
+
201
+ return config;
202
+ }
203
+
204
+ module.exports = {
205
+ parseGlobalFlags,
206
+ shouldShowBanner,
207
+ isCI,
208
+ loadConfig,
209
+ lazy,
210
+ getOs,
211
+ getPath,
212
+ getFs,
213
+ };