@visulima/cerebro 3.0.0-alpha.9 → 3.0.1

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