@visulima/cerebro 3.0.3 → 3.0.5

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 (41) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE.md +346 -0
  3. package/dist/commands/completion-command.d.ts +3 -3
  4. package/dist/commands/completion-command.js +1 -1
  5. package/dist/commands/help-command.d.ts +1 -1
  6. package/dist/commands/help-command.js +1 -1
  7. package/dist/commands/readme-command.d.ts +3 -3
  8. package/dist/commands/readme-command.js +17 -17
  9. package/dist/commands/version-command.d.ts +1 -1
  10. package/dist/index.d.ts +403 -433
  11. package/dist/index.js +1 -1
  12. package/dist/logger/create-pail-logger.d.ts +533 -555
  13. package/dist/logger/create-pail-logger.js +1 -1
  14. package/dist/packem_chunks/has-new-version.js +1 -1
  15. package/dist/packem_shared/Cerebro-58LHN3_T.js +4 -0
  16. package/dist/packem_shared/VisulimaError-k1qGkvab.js +76 -0
  17. package/dist/packem_shared/cerebro-error-DWpjBY_M.js +1 -0
  18. package/dist/packem_shared/command.d-B_G9vIYJ.d.ts +633 -0
  19. package/dist/packem_shared/{index-DvVGK4kr.js → index-Dpm7gUHe.js} +12 -12
  20. package/dist/packem_shared/index.d-CnnVYgSZ.d.ts +117 -0
  21. package/dist/packem_shared/renderError-BISXNU8L-B47ZikMV.js +27 -0
  22. package/dist/packem_shared/runtime-process-BEw54Ar-.js +1 -0
  23. package/dist/packem_shared/split-by-case-BZ6XOTIf.js +1 -0
  24. package/dist/plugins/error-handler-plugin.d.ts +18 -7
  25. package/dist/plugins/error-handler-plugin.js +1 -1
  26. package/dist/plugins/runtime-version-check-plugin.d.ts +5 -5
  27. package/dist/plugins/runtime-version-check-plugin.js +1 -1
  28. package/dist/plugins/update-notifier/update-notifier-plugin.d.ts +11 -10
  29. package/dist/plugins/update-notifier/update-notifier-plugin.js +1 -1
  30. package/dist/util/general/compile-cache.d.ts +37 -37
  31. package/dist/util/general/heap-tuning.d.ts +11 -11
  32. package/dist/util/general/heap-tuning.js +1 -1
  33. package/package.json +6 -6
  34. package/dist/packem_shared/Cerebro-Czc4t-75.js +0 -4
  35. package/dist/packem_shared/VisulimaError-C90oeIMu.js +0 -76
  36. package/dist/packem_shared/cerebro-error-BjBcYVRO.js +0 -1
  37. package/dist/packem_shared/command.d-DbhtfXF4.d.ts +0 -639
  38. package/dist/packem_shared/index.d-BL4NtVR3.d.ts +0 -127
  39. package/dist/packem_shared/renderError-B3ePOoBG-BmZlyMcr.js +0 -25
  40. package/dist/packem_shared/runtime-process-Dmz0vCJy.js +0 -1
  41. package/dist/packem_shared/split-by-case-Dbpgd7rf.js +0 -1
@@ -0,0 +1,633 @@
1
+ import { TableOptions } from '@visulima/tabular';
2
+ /**
3
+ * Definition for a command-line option.
4
+ *
5
+ * The optional `Name` and `Value` type parameters allow {@link CommandLineOptions}
6
+ * to be inferred from an `as const` array of definitions. They default to the
7
+ * loose runtime shape so plain `OptionDefinition` usage is unaffected.
8
+ */
9
+ interface OptionDefinition$1<Name extends string = string, Value = unknown> {
10
+ /**
11
+ * A getopt-style short option name. Can be any single character except a digit or hyphen.
12
+ */
13
+ alias?: string;
14
+ /**
15
+ * Any values unaccounted for by an option definition will be set on the `defaultOption`. This flag is typically set
16
+ * on the most commonly-used option to enable more concise usage.
17
+ */
18
+ defaultOption?: boolean;
19
+ /**
20
+ * An initial value for the option.
21
+ */
22
+ defaultValue?: Value;
23
+ /**
24
+ * One or more group names the option belongs to.
25
+ */
26
+ group?: string | string[];
27
+ /**
28
+ * Identical to `multiple` but with greedy parsing disabled.
29
+ */
30
+ lazyMultiple?: boolean;
31
+ /**
32
+ * Set this flag if the option accepts multiple values. In the output, you will receive an array of values each passed through the `type` function.
33
+ */
34
+ multiple?: boolean;
35
+ /**
36
+ * The long option name.
37
+ */
38
+ name: Name;
39
+ /**
40
+ * A setter function (you receive the output from this) enabling you to be specific about the type and value received. Typical values
41
+ * are `String` (the default), `Number` and `Boolean` but you can use a custom function. If no option value was set you will receive `null`.
42
+ */
43
+ type?: (input: string) => Value;
44
+ }
45
+ /** A Content section comprises a header and one or more lines of content. */
46
+ interface Content {
47
+ /**
48
+ * Overloaded property, accepting data in one of four formats.
49
+ * 1. A single string (one line of text).
50
+ * 2. An array of strings (multiple lines of text).
51
+ * 3. An array of arrays (recordset-style data). In this case, the data will be rendered in table format.
52
+ * 4. An object with two properties - data and options. In this case, the data and options will be passed directly to the underlying table module for rendering.
53
+ */
54
+ content?: string[] | string[][] | string | {
55
+ data: string[][];
56
+ options: TableOptions;
57
+ };
58
+ /** The section header, always bold and underlined. */
59
+ header?: string;
60
+ /** Set to true to avoid indentation and wrapping. Useful for banners. */
61
+ raw?: boolean;
62
+ }
63
+ /**
64
+ * Context provided to plugins during initialization
65
+ */
66
+ interface PluginContext<T extends Console = Console> {
67
+ /** The CLI instance */
68
+ cli: Cli<T>;
69
+ /** Current working directory */
70
+ cwd: string;
71
+ /** Logger instance */
72
+ logger: T;
73
+ }
74
+ /**
75
+ * Plugin interface with lifecycle hooks
76
+ */
77
+ interface Plugin<T extends Console = Console> {
78
+ /**
79
+ * Called after command execution completes successfully
80
+ * @param toolbox The command toolbox
81
+ * @param result The result returned by the command
82
+ */
83
+ afterCommand?: (toolbox: Toolbox<T>, result: unknown) => Promise<void> | void;
84
+ /**
85
+ * Called before command execution
86
+ * @param toolbox The command toolbox
87
+ */
88
+ beforeCommand?: (toolbox: Toolbox<T>) => Promise<void> | void;
89
+ /** Plugin dependencies (other plugin names that must be loaded first) */
90
+ dependencies?: string[];
91
+ /** Plugin description */
92
+ description?: string;
93
+ /**
94
+ * Called during command execution (for plugins that extend toolbox functionality)
95
+ * @param toolbox The command toolbox
96
+ */
97
+ execute?: (toolbox: Toolbox<T>) => Promise<void> | void;
98
+ /**
99
+ * Called once during plugin initialization
100
+ * @param context The plugin context
101
+ */
102
+ init?: (context: PluginContext<T>) => Promise<void> | void;
103
+ /** Plugin name (must be unique) */
104
+ name: string;
105
+ /**
106
+ * Called when an error occurs during command execution
107
+ * @param error The error that occurred
108
+ * @param toolbox The command toolbox
109
+ */
110
+ onError?: (error: Error, toolbox: Toolbox<T>) => Promise<void> | void;
111
+ /** Plugin version */
112
+ version?: string;
113
+ }
114
+ type Logger = Console;
115
+ /**
116
+ * Manages plugin lifecycle and execution
117
+ */
118
+ declare class PluginManager<T extends Logger = Logger> {
119
+ private readonly logger;
120
+ private readonly plugins;
121
+ private initialized;
122
+ private cachedDependencyOrder;
123
+ constructor(logger: T);
124
+ /**
125
+ * Checks if any plugins are registered.
126
+ * @returns True if at least one plugin is registered
127
+ */
128
+ hasPlugins(): boolean;
129
+ /**
130
+ * Registers a plugin.
131
+ * @param plugin The plugin to register
132
+ * @throws {Error} If plugin name is already registered or dependencies are invalid
133
+ */
134
+ register(plugin: Plugin<T>): void;
135
+ /**
136
+ * Initializes all registered plugins.
137
+ * @param context The plugin context for initialization
138
+ */
139
+ init(context: PluginContext<T>): Promise<void>;
140
+ /**
141
+ * Executes a specific lifecycle hook for all plugins.
142
+ * @param hook The lifecycle hook name
143
+ * @param toolbox The command toolbox (for command-specific hooks)
144
+ * @param result The command result (for afterCommand hook)
145
+ */
146
+ executeLifecycle(hook: "beforeCommand" | "afterCommand" | "execute", toolbox: Toolbox<T>, result?: unknown): Promise<void>;
147
+ /**
148
+ * Executes error handlers for all plugins.
149
+ * @param error The error that occurred
150
+ * @param toolbox The command toolbox
151
+ */
152
+ executeErrorHandlers(error: Error, toolbox: Toolbox<T>): Promise<void>;
153
+ /**
154
+ * Gets all registered plugins in dependency order.
155
+ * @returns Array of plugins sorted by dependencies
156
+ */
157
+ getDependencyOrder(): Plugin<T>[];
158
+ /**
159
+ * Validates that all plugin dependencies exist.
160
+ * @throws {Error} If any dependencies are missing
161
+ */
162
+ private validateDependencies;
163
+ }
164
+ type CommandSection = {
165
+ footer?: string;
166
+ header?: string;
167
+ };
168
+ type CliRunOptions = {
169
+ [key: string]: unknown;
170
+ /**
171
+ * Whether to automatically dispose/cleanup the CLI instance after execution
172
+ * @default true
173
+ */
174
+ autoDispose?: boolean;
175
+ shouldExitProcess?: boolean;
176
+ };
177
+ type RunCommandOptions = {
178
+ /**
179
+ * Extra options to merge into the command's options.
180
+ * These will be merged with the command's default options and parsed arguments.
181
+ * Use this to override or add additional options programmatically.
182
+ * @default Empty object
183
+ */
184
+ [key: string]: unknown;
185
+ /**
186
+ * Command-line arguments to pass to the command.
187
+ * If not provided, uses the default argv from the CLI instance.
188
+ * These arguments will be parsed and merged with the command's options.
189
+ * @default Empty array
190
+ */
191
+ argv?: string[];
192
+ };
193
+ interface Cli<T extends Console> {
194
+ /**
195
+ * Add an arbitrary command to the CLI.
196
+ * @param command The command to add.
197
+ * @returns self
198
+ */
199
+ addCommand: <OD extends OptionDefinition<unknown> = OptionDefinition<unknown>>(command: Command<OD, T>) => this;
200
+ /**
201
+ * Add a global option available to all commands.
202
+ * Global options are parsed alongside command options and shown in help output.
203
+ * @param option The option definition
204
+ * @returns self
205
+ */
206
+ addGlobalOption: <V = unknown>(option: OptionDefinition<V>) => this;
207
+ /**
208
+ * Add a plugin to extend the CLI functionality
209
+ * @param plugin The plugin to add.
210
+ * @returns self
211
+ */
212
+ addPlugin: (plugin: Plugin<T>) => this;
213
+ /**
214
+ * Disposes the CLI instance and cleans up resources
215
+ * @returns void
216
+ */
217
+ dispose: () => void;
218
+ getCliName: () => string;
219
+ getCommands: () => Map<string, Command<OptionDefinition<unknown>, T>>;
220
+ getCommandSection: () => CommandSection;
221
+ getCwd: () => string;
222
+ /**
223
+ * Gets all global options (built-in + custom).
224
+ */
225
+ getGlobalOptions: () => OptionDefinition<unknown>[];
226
+ getPackageName: () => string | undefined;
227
+ getPackageVersion: () => string | undefined;
228
+ /**
229
+ * Get the plugin manager instance
230
+ * @returns The plugin manager
231
+ */
232
+ getPluginManager: () => PluginManager<T>;
233
+ run: (extraOptions?: CliRunOptions) => Promise<void>;
234
+ /**
235
+ * Runs a command programmatically from within another command.
236
+ * This allows commands to call other commands during execution.
237
+ * @param commandName The name of the command to execute
238
+ * @param options Optional options including argv and other command options
239
+ * @returns A promise that resolves with the command's result (or void if command doesn't return a value)
240
+ * @throws {Error} If the specified command doesn't exist or command arguments are invalid
241
+ * @example
242
+ * ```typescript
243
+ * cli.addCommand({
244
+ * name: 'deploy',
245
+ * execute: async ({ runtime, logger }) => {
246
+ * logger.info('Building...');
247
+ * const buildResult = await runtime.runCommand('build', { argv: ['--production'] });
248
+ * // buildResult is the return value from the build command's execute function
249
+ *
250
+ * logger.info('Testing...');
251
+ * await runtime.runCommand('test', { argv: ['--coverage'] });
252
+ * }
253
+ * });
254
+ * ```
255
+ */
256
+ runCommand: (commandName: string, options?: RunCommandOptions) => Promise<unknown>;
257
+ setCommandSection: (commandSection: CommandSection) => this;
258
+ /**
259
+ * Set a default command, to display a different command if cli is call without command.
260
+ * @param commandName
261
+ * @returns self
262
+ */
263
+ setDefaultCommand: (commandName: string) => this;
264
+ }
265
+ /**
266
+ * Any of the output types [[OUTPUT_NORMAL]], [[OUTPUT_RAW]] and [[OUTPUT_PLAIN]].
267
+ */
268
+ type OutputType = 1 | 2 | 4;
269
+ /**
270
+ * Any of the verbosity types
271
+ * [[VERBOSITY_QUIET]], [[VERBOSITY_NORMAL]], [[VERBOSITY_VERBOSE]] and [[VERBOSITY_DEBUG]].
272
+ */
273
+ type VERBOSITY_LEVEL = 16 | 32 | 64 | 128 | 256;
274
+ /**
275
+ * A flexible object for the many "options" objects we throw around in cerebro.
276
+ */
277
+ type Options = Record<string | symbol, unknown>;
278
+ /**
279
+ * Runtime-injected filesystem adapter. A subset of `node:fs/promises` covering
280
+ * the operations commonly used by CLI commands (config files, credentials,
281
+ * cache paths). Defaults to `node:fs/promises` at runtime, but can be swapped
282
+ * for an in-memory adapter in tests or a sandbox in MCP/JustBash environments.
283
+ */
284
+ interface CerebroFs {
285
+ access: (path: string, mode?: number) => Promise<void>;
286
+ mkdir: (path: string, options?: {
287
+ recursive?: boolean;
288
+ }) => Promise<string | undefined>;
289
+ readdir: (path: string) => Promise<string[]>;
290
+ readFile: ((path: string) => Promise<Uint8Array>) & ((path: string, encoding: BufferEncoding) => Promise<string>);
291
+ rm: (path: string, options?: {
292
+ force?: boolean;
293
+ recursive?: boolean;
294
+ }) => Promise<void>;
295
+ stat: (path: string) => Promise<{
296
+ isDirectory: () => boolean;
297
+ isFile: () => boolean;
298
+ }>;
299
+ writeFile: (path: string, data: string | Uint8Array, encoding?: BufferEncoding) => Promise<void>;
300
+ }
301
+ /**
302
+ * Runtime-injected process info. Snapshot of cwd / env / argv / platform / arch
303
+ * captured at CLI construction time, plus an `exit` function and a `stdin`
304
+ * buffer for tests and sandbox runtimes.
305
+ *
306
+ * Prefer reading these from the toolbox over reaching for global `process` so
307
+ * commands stay portable across Node, Deno, Bun, and mocked test runtimes.
308
+ */
309
+ interface CerebroProcess {
310
+ /** CPU architecture, e.g. "x64", "arm64". */
311
+ arch: string;
312
+ /** The full command-line arguments array (same shape as `process.argv`). */
313
+ argv: ReadonlyArray<string>;
314
+ /** Working directory the CLI was constructed with. */
315
+ cwd: string;
316
+ /** Environment variables. May be the host `process.env` or an injected snapshot. */
317
+ env: Record<string, string | undefined>;
318
+ /**
319
+ * Terminate the process with the given exit code. Defaults to the
320
+ * runtime-agnostic exit helper, but can be overridden via `CliOptions.exit`
321
+ * to capture exit codes in tests instead of killing the runner.
322
+ */
323
+ exit: (code?: number) => void;
324
+ /** OS platform, e.g. "linux", "darwin", "win32". */
325
+ platform: string;
326
+ /**
327
+ * Buffered stdin content. Empty string when there is no piped input.
328
+ * Tests and sandbox runtimes can populate this without wiring real streams.
329
+ */
330
+ stdin: string;
331
+ }
332
+ /**
333
+ * Type-safe Toolbox interface with customizable options and environment variable types.
334
+ * @template TLogger - The logger type (defaults to Console)
335
+ * @template TOptions - The options type (defaults to Options/Record&lt;string, unknown>)
336
+ * @template TEnv - The environment variables type (defaults to Record&lt;string, unknown>)
337
+ */
338
+ interface Toolbox<TLogger extends Console = Console, TOptions extends Record<string, unknown> = Options, TEnv extends Record<string, unknown> = Record<string, unknown>> extends Cerebro.ExtensionOverrides {
339
+ /**
340
+ * The argument passed to the command.
341
+ * For example, if you run `cerebro foo bar baz`, then this will be `["foo", "bar", "baz"]`.
342
+ * @example
343
+ * ```typescript
344
+ * cli.addCommand({
345
+ * name: "copy",
346
+ * argument: {
347
+ * name: "files",
348
+ * type: String,
349
+ * description: "Files to copy"
350
+ * },
351
+ * execute: ({ argument }) => {
352
+ * // argument is an array of strings
353
+ * // argument[0] is the first file, argument[1] is the second, etc.
354
+ * argument.forEach((file) => console.log(`Copying ${file}...`));
355
+ * }
356
+ * });
357
+ * ```
358
+ */
359
+ argument: string[];
360
+ argv: ReadonlyArray<string>;
361
+ /**
362
+ * The command that is being executed.
363
+ */
364
+ command: Command;
365
+ /**
366
+ * The name of the command that is being executed.
367
+ */
368
+ commandName: string;
369
+ /**
370
+ * Alias for `logger`. Exposed under the `console` name so commands can
371
+ * write portable `({ console }) => console.log(...)` code without reaching
372
+ * for the global `console`. The injected value is the same object as
373
+ * `toolbox.logger`, so verbosity-aware methods (`debug`) keep working.
374
+ */
375
+ console: TLogger;
376
+ /**
377
+ * Environment variables processed from the command definition.
378
+ * Values are transformed according to their type definitions and default values.
379
+ * @example
380
+ * ```typescript
381
+ * // Define env types when creating command
382
+ * type MyEnv = { apiKey: string; debug: boolean };
383
+ *
384
+ * cli.addCommand({
385
+ * name: "build",
386
+ * env: [
387
+ * { name: "API_KEY", type: String },
388
+ * { name: "DEBUG", type: Boolean }
389
+ * ],
390
+ * execute: ({ env }) => {
391
+ * // env.apiKey and env.debug are now typed!
392
+ * console.log(env.apiKey, env.debug);
393
+ * }
394
+ * });
395
+ * ```
396
+ */
397
+ env: TEnv;
398
+ /**
399
+ * Filesystem adapter. Defaults to `node:fs/promises`, but can be swapped via
400
+ * `CliOptions.fs` for tests (in-memory adapter) or sandboxed runtimes
401
+ * (JustBash, MCP). Prefer `toolbox.fs` over a direct `node:fs/promises`
402
+ * import inside command actions to keep them portable and testable.
403
+ */
404
+ fs: CerebroFs;
405
+ /** The logger instance. */
406
+ logger: TLogger;
407
+ /**
408
+ * Any optional parameters. Typically coming from command-line
409
+ * argument like this: `--force -p tsconfig-mjson`.
410
+ * @example
411
+ * ```typescript
412
+ * // Define options type for better autocomplete
413
+ * type MyOptions = {
414
+ * output?: string;
415
+ * verbose?: boolean;
416
+ * port?: number;
417
+ * };
418
+ *
419
+ * cli.addCommand({
420
+ * name: "serve",
421
+ * options: [
422
+ * { name: "output", type: String },
423
+ * { name: "verbose", type: Boolean },
424
+ * { name: "port", type: Number }
425
+ * ],
426
+ * execute: ({ options }: { options: MyOptions }) => {
427
+ * // options.output, options.verbose, options.port are typed!
428
+ * console.log(options.output, options.verbose, options.port);
429
+ * }
430
+ * });
431
+ * ```
432
+ */
433
+ options: TOptions;
434
+ /**
435
+ * Runtime process info — cwd, env, argv, exit, platform, arch, stdin —
436
+ * captured at CLI construction. Prefer `toolbox.process` over reaching for
437
+ * the global `process` so commands stay portable across Node, Deno, Bun,
438
+ * and mocked test runtimes. `process.exit` honors the `CliOptions.exit`
439
+ * override, which lets tests assert exit codes without killing the runner.
440
+ */
441
+ process: CerebroProcess;
442
+ /**
443
+ * Raw tokens that command-line-args could not assign to a defined
444
+ * option — typically everything after a `--` separator, since
445
+ * cerebro runs the parser with `stopAtFirstUnknown: true`.
446
+ *
447
+ * Use this for passthrough patterns like
448
+ * `my-cmd foo bar -- --flag=value --other`, where everything after
449
+ * `--` is forwarded to an inner tool (`create-vite`, a template
450
+ * runner, etc.). Empty array when there was no `--` segment.
451
+ * @example
452
+ * ```typescript
453
+ * cli.addCommand({
454
+ * name: "create",
455
+ * argument: { name: "template", type: String },
456
+ * execute: ({ argument, rawUnknown }) => {
457
+ * // `vis create vite my-app -- --template react-ts`
458
+ * // → argument === ["vite", "my-app"]
459
+ * // → rawUnknown === ["--template", "react-ts"]
460
+ * spawnSync("npm", ["create", "vite", ...rawUnknown]);
461
+ * },
462
+ * });
463
+ * ```
464
+ */
465
+ rawUnknown: ReadonlyArray<string>;
466
+ /**
467
+ * This is the instance of the CLI that is running the command.
468
+ */
469
+ runtime: Cli<TLogger>;
470
+ }
471
+ type TypeConstructor<T> = (value: unknown) => T extends (infer R)[] ? R | undefined : T | undefined;
472
+ /**
473
+ * Type constructor for environment variables.
474
+ * Environment variables are always strings (or undefined), so the transform function receives string | undefined.
475
+ */
476
+ type EnvTypeConstructor<T> = (value: string | undefined) => T extends (infer R)[] ? R | undefined : T | undefined;
477
+ type MultiplePropertyOptions<T> = T extends ReadonlyArray<unknown> ? {
478
+ lazyMultiple: true;
479
+ } | {
480
+ multiple: true;
481
+ } : unknown;
482
+ type OptionDefinition<T> = MultiplePropertyOptions<T> & Omit<OptionDefinition$1, "type|defaultValue"> & {
483
+ /**
484
+ * Restricts the accepted values for this option to a fixed set, validated
485
+ * at parse time (like commander's `.choices()` / yargs `choices`). The
486
+ * provided value(s) are compared by string equality; for `multiple`
487
+ * options every provided value must be a member of the set.
488
+ * @example
489
+ * ```typescript
490
+ * { name: "format", type: String, choices: ["json", "yaml", "table"] }
491
+ * ```
492
+ */
493
+ choices?: ReadonlyArray<string>;
494
+ /**
495
+ * A string or array of strings indicating the conflicting option(s).
496
+ * Note: The default value for an option does not cause a conflict.
497
+ */
498
+ conflicts?: string[] | string;
499
+ /** An initial value for the option. */
500
+ defaultValue?: T;
501
+ /** A string describing the option. */
502
+ description?: string;
503
+ /** Option is hidden from help */
504
+ hidden?: boolean;
505
+ implies?: Record<string, unknown>;
506
+ /** Specifies whether the variable is required. */
507
+ required?: boolean;
508
+ /**
509
+ * A setter function (you receive the output from this) enabling you to be specific about the type and value received. Typical values
510
+ * are `String`, `Number` and `Boolean` but you can use a custom function.
511
+ */
512
+ type?: TypeConstructor<T>;
513
+ /** A string to replace the default type string (e.g. &lt;string>). It's often more useful to set a more descriptive type label, like &lt;ms>, &lt;files>, &lt;command>, etc.. */
514
+ typeLabel?: string;
515
+ };
516
+ type ArgumentDefinition<T = unknown> = Omit<OptionDefinition<T>, "multiple|lazyMultiple|defaultOption|alias|group|defaultValue">;
517
+ /**
518
+ * Environment variable definition for commands.
519
+ * Used to document and provide type-safe access to environment variables a command supports.
520
+ * @template T The type of the environment variable value
521
+ */
522
+ interface EnvDefinition<T = string> {
523
+ /** Default value if the environment variable is not set */
524
+ defaultValue?: T;
525
+ /** A description of what the environment variable does */
526
+ description?: string;
527
+ /** Environment variable is hidden from help */
528
+ hidden?: boolean;
529
+ /** The name of the environment variable */
530
+ name: string;
531
+ /**
532
+ * A transform function to convert the string environment variable value to the desired type.
533
+ * Typical values are `String`, `Number`, `Boolean` or custom functions.
534
+ * The function receives `string | undefined` and should return the transformed value.
535
+ */
536
+ type?: EnvTypeConstructor<T>;
537
+ /** A string to replace the default type string (e.g. &lt;string>). Useful for more descriptive type labels. */
538
+ typeLabel?: string;
539
+ }
540
+ /**
541
+ * Command interface with type-safe options and environment variables.
542
+ * @template O - The option definition type
543
+ * @template TContext - The toolbox context type (allows custom typing for better autocomplete)
544
+ * @example
545
+ * ```typescript
546
+ * // Define your options type for autocomplete
547
+ * type BuildOptions = {
548
+ * output?: string;
549
+ * production?: boolean;
550
+ * watch?: boolean;
551
+ * };
552
+ *
553
+ * type BuildEnv = {
554
+ * apiKey?: string;
555
+ * debug?: boolean;
556
+ * };
557
+ *
558
+ * cli.addCommand({
559
+ * name: "build",
560
+ * options: [
561
+ * { name: "output", type: String, alias: "o" },
562
+ * { name: "production", type: Boolean },
563
+ * { name: "watch", type: Boolean }
564
+ * ],
565
+ * env: [
566
+ * { name: "API_KEY", type: String },
567
+ * { name: "DEBUG", type: Boolean }
568
+ * ],
569
+ * execute: ({ options, env }: Toolbox<Console, BuildOptions, BuildEnv>) => {
570
+ * // Full autocomplete on options and env!
571
+ * console.log(options.output, options.production, env.apiKey);
572
+ * }
573
+ * });
574
+ * ```
575
+ */
576
+ /**
577
+ * Handler signature for commands. Used by both `execute` and the resolved default export of `loader`.
578
+ */
579
+ type CommandExecute<TContext> = ((toolbox: TContext) => Promise<void>) | ((toolbox: TContext) => void);
580
+ /**
581
+ * Module shape returned by a command `loader`. The default export is the command handler.
582
+ */
583
+ interface LazyCommandModule<TContext> {
584
+ default: CommandExecute<TContext>;
585
+ }
586
+ interface Command<O extends OptionDefinition<unknown> = OptionDefinition<unknown>, TLogger extends Console = Console, TContext extends Toolbox<TLogger> = Toolbox<TLogger>> {
587
+ /** Potential other names for this command */
588
+ alias?: string[] | string;
589
+ /** Positional argument */
590
+ argument?: ArgumentDefinition;
591
+ /** The command path, an array that describes how to get to this command */
592
+ commandPath?: string[];
593
+ /** A tweet-sized summary of your command */
594
+ description?: string;
595
+ /** Environment variables supported by this command */
596
+ env?: (EnvDefinition<boolean> | EnvDefinition<number> | EnvDefinition)[];
597
+ /** The full command examples, can be multiple lines */
598
+ examples?: string[] | string[][];
599
+ /**
600
+ * The function for running your command, can be async.
601
+ * Either `execute` or `loader` must be provided (but not both).
602
+ */
603
+ execute?: CommandExecute<TContext>;
604
+ /** The path to the file name for this command. */
605
+ file?: string;
606
+ /** Group commands together under a heading */
607
+ group?: string;
608
+ /** Should your command be shown in the listings */
609
+ hidden?: boolean;
610
+ /**
611
+ * Lazily loads the command handler on first execution. The module's default export is used as the handler.
612
+ * Either `execute` or `loader` must be provided (but not both).
613
+ * Help, completion, and validation work from the metadata declared on this object and never trigger the loader.
614
+ * @example
615
+ * ```typescript
616
+ * cli.addCommand({
617
+ * name: "build",
618
+ * description: "Build the project",
619
+ * options: [{ name: "output", type: String }],
620
+ * loader: () => import("./commands/build"),
621
+ * });
622
+ *
623
+ * // commands/build.ts
624
+ * export default ({ options }) => { ... };
625
+ * ```
626
+ */
627
+ loader?: () => Promise<LazyCommandModule<TContext>>;
628
+ /** The name of your command */
629
+ name: string;
630
+ options?: (O | OptionDefinition<boolean[]> | OptionDefinition<boolean> | OptionDefinition<number[]> | OptionDefinition<number> | OptionDefinition<string[]> | OptionDefinition<string>)[];
631
+ usage?: Content[];
632
+ }
633
+ export { ArgumentDefinition as A, Command as C, EnvDefinition as E, LazyCommandModule as L, OptionDefinition as O, Plugin as P, RunCommandOptions as R, Toolbox as T, VERBOSITY_LEVEL as V, CerebroFs as a, CommandSection as b, PluginManager as c, CliRunOptions as d, CommandExecute as e, Cli as f, CerebroProcess as g, OutputType as h, PluginContext as i };