politty 0.7.0 → 0.9.0

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 (63) hide show
  1. package/dist/cli.js +1 -1
  2. package/dist/docs/index.d.ts +44 -2
  3. package/dist/docs/index.js +827 -43
  4. package/dist/index.js +1 -1
  5. package/dist/{runner-D43SkHt5.js → runner-APRZYXUS.js} +74 -3
  6. package/package.json +22 -67
  7. package/dist/arg-registry-DDJpsUea.d.cts +0 -942
  8. package/dist/arg-registry-DDJpsUea.d.cts.map +0 -1
  9. package/dist/arg-registry-DDJpsUea.d.ts.map +0 -1
  10. package/dist/augment.cjs +0 -0
  11. package/dist/augment.d.cts +0 -17
  12. package/dist/augment.d.cts.map +0 -1
  13. package/dist/augment.d.ts.map +0 -1
  14. package/dist/cli.cjs +0 -54
  15. package/dist/cli.cjs.map +0 -1
  16. package/dist/cli.d.cts +0 -1
  17. package/dist/cli.js.map +0 -1
  18. package/dist/completion/index.cjs +0 -23
  19. package/dist/completion/index.d.cts +0 -3
  20. package/dist/completion-CLHO3Xaz.cjs +0 -5769
  21. package/dist/completion-CLHO3Xaz.cjs.map +0 -1
  22. package/dist/completion-DHnVx9Zk.js.map +0 -1
  23. package/dist/docs/index.cjs +0 -2343
  24. package/dist/docs/index.cjs.map +0 -1
  25. package/dist/docs/index.d.cts +0 -710
  26. package/dist/docs/index.d.cts.map +0 -1
  27. package/dist/docs/index.d.ts.map +0 -1
  28. package/dist/docs/index.js.map +0 -1
  29. package/dist/index-DKGn3lIl.d.ts.map +0 -1
  30. package/dist/index-WyViqW59.d.cts +0 -663
  31. package/dist/index-WyViqW59.d.cts.map +0 -1
  32. package/dist/index.cjs +0 -45
  33. package/dist/index.d.cts +0 -685
  34. package/dist/index.d.cts.map +0 -1
  35. package/dist/index.d.ts.map +0 -1
  36. package/dist/log-collector-DK32-73m.js.map +0 -1
  37. package/dist/log-collector-DUqC427m.cjs +0 -185
  38. package/dist/log-collector-DUqC427m.cjs.map +0 -1
  39. package/dist/prompt/clack/index.cjs +0 -33
  40. package/dist/prompt/clack/index.cjs.map +0 -1
  41. package/dist/prompt/clack/index.d.cts +0 -18
  42. package/dist/prompt/clack/index.d.cts.map +0 -1
  43. package/dist/prompt/clack/index.d.ts.map +0 -1
  44. package/dist/prompt/clack/index.js.map +0 -1
  45. package/dist/prompt/index.cjs +0 -7
  46. package/dist/prompt/index.d.cts +0 -108
  47. package/dist/prompt/index.d.cts.map +0 -1
  48. package/dist/prompt/index.d.ts.map +0 -1
  49. package/dist/prompt/inquirer/index.cjs +0 -48
  50. package/dist/prompt/inquirer/index.cjs.map +0 -1
  51. package/dist/prompt/inquirer/index.d.cts +0 -18
  52. package/dist/prompt/inquirer/index.d.cts.map +0 -1
  53. package/dist/prompt/inquirer/index.d.ts.map +0 -1
  54. package/dist/prompt/inquirer/index.js.map +0 -1
  55. package/dist/prompt-Bs9e-Em3.cjs +0 -196
  56. package/dist/prompt-Bs9e-Em3.cjs.map +0 -1
  57. package/dist/prompt-Cc8Tfmdv.js.map +0 -1
  58. package/dist/runner-D43SkHt5.js.map +0 -1
  59. package/dist/runner-DvFvokV6.cjs +0 -2865
  60. package/dist/runner-DvFvokV6.cjs.map +0 -1
  61. package/dist/schema-extractor-BxSRwLrx.cjs +0 -710
  62. package/dist/schema-extractor-BxSRwLrx.cjs.map +0 -1
  63. package/dist/schema-extractor-Dqe7_kyQ.js.map +0 -1
@@ -1,942 +0,0 @@
1
- import { z } from "zod";
2
-
3
- //#region src/core/schema-extractor.d.ts
4
- /**
5
- * Resolved metadata for an argument field
6
- */
7
- interface ResolvedFieldMeta {
8
- /** Field name (camelCase, as defined in schema) */
9
- name: string;
10
- /** CLI option name (kebab-case, for command line usage) */
11
- cliName: string;
12
- /**
13
- * Aliases for this option, normalized to an array.
14
- * 1-char entries are short aliases (`-v`); multi-char entries are long
15
- * aliases (`--to-be`).
16
- */
17
- alias?: string[] | undefined;
18
- /**
19
- * Aliases that are accepted at parse time but hidden from help,
20
- * generated docs, and shell completion.
21
- */
22
- hiddenAlias?: string[] | undefined;
23
- /** Argument description */
24
- description?: string | undefined;
25
- /** Whether this is a positional argument */
26
- positional: boolean;
27
- /** Placeholder for help display */
28
- placeholder?: string | undefined;
29
- /**
30
- * Environment variable name(s) to read value from.
31
- * If an array, earlier entries take priority.
32
- */
33
- env?: string | string[] | undefined;
34
- /** Whether this argument is required */
35
- required: boolean;
36
- /** Default value if any */
37
- defaultValue?: unknown;
38
- /** Detected type from schema */
39
- type: "string" | "number" | "boolean" | "array" | "unknown";
40
- /** Original Zod schema */
41
- schema: z.ZodType;
42
- /** True if this overrides built-in aliases (-h, -H) */
43
- overrideBuiltinAlias?: true;
44
- /** Enum values if detected from schema (z.enum) */
45
- enumValues?: string[] | undefined;
46
- /** Completion metadata from arg() */
47
- completion?: CompletionMeta | undefined;
48
- /** Prompt metadata from arg() for interactive input */
49
- prompt?: PromptMeta | undefined;
50
- /**
51
- * Negation configuration for this boolean field.
52
- *
53
- * - String (e.g. `"disable-cache"`): the default `--no-<cliName>` form is
54
- * suppressed and only `--<negation>` (plus its camelCase variant) is
55
- * accepted as the negation flag.
56
- * - `true`: the default `--no-<cliName>` form is accepted **and** shown in
57
- * help, generated docs, and shell completions.
58
- * - `false`: neither the default `--no-<cliName>` nor any custom name is
59
- * accepted; the field only responds to the positive flag.
60
- * - `undefined`: the default `--no-<cliName>` is accepted by the parser
61
- * but hidden from help/docs/completions.
62
- *
63
- * Only applies to boolean fields; populated as `undefined` otherwise.
64
- */
65
- negation?: string | boolean | undefined;
66
- /**
67
- * Derived display name (no `--` prefix) for the negation flag in help,
68
- * generated docs, and shell completions. `undefined` means the negation
69
- * is hidden from those surfaces. Computed from `negation` + `cliName`.
70
- */
71
- negationDisplay?: string | undefined;
72
- /** Description shown for the negation option in help/docs. */
73
- negationDescription?: string | undefined;
74
- /** Side-effect callback from arg() metadata */
75
- effect?: ((value: unknown, context: EffectContext) => void | PromiseLike<void>) | undefined;
76
- }
77
- /**
78
- * Extracted fields from a schema
79
- */
80
- interface ExtractedFields {
81
- /** All field definitions */
82
- fields: ResolvedFieldMeta[];
83
- /** Original schema for validation */
84
- schema: ArgsSchema;
85
- /** Schema type */
86
- schemaType: "object" | "discriminatedUnion" | "union" | "xor" | "intersection";
87
- /** Discriminator key (for discriminatedUnion) */
88
- discriminator?: string;
89
- /** Variants (for discriminatedUnion) */
90
- variants?: Array<{
91
- discriminatorValue: string;
92
- fields: ResolvedFieldMeta[];
93
- description?: string;
94
- }>;
95
- /** Options (for union) */
96
- unionOptions?: ExtractedFields[];
97
- /** Schema description */
98
- description?: string;
99
- /**
100
- * Unknown keys handling mode
101
- * - "strict": Unknown keys cause validation errors (z.strictObject or z.object().strict())
102
- * - "strip": Unknown keys trigger warnings (default, z.object())
103
- * - "passthrough": Unknown keys are silently ignored (z.looseObject or z.object().passthrough())
104
- */
105
- unknownKeysMode: UnknownKeysMode;
106
- }
107
- /**
108
- * Unknown keys handling mode for object schemas
109
- * - "strict": Unknown keys cause validation errors
110
- * - "strip": Unknown keys are silently ignored (default)
111
- * - "passthrough": Unknown keys are passed through
112
- */
113
- type UnknownKeysMode = "strict" | "strip" | "passthrough";
114
- /**
115
- * Detect unknown keys handling mode from a Zod object schema
116
- *
117
- * In Zod v4:
118
- * - Default (strip): _def.catchall is undefined
119
- * - strict: _def.catchall is ZodNever (type = "never")
120
- * - passthrough: _def.catchall is ZodUnknown (type = "unknown")
121
- */
122
- declare function getUnknownKeysMode(schema: z.ZodType): UnknownKeysMode;
123
- /**
124
- * Convert camelCase to kebab-case
125
- * @example toKebabCase("dryRun") => "dry-run"
126
- * @example toKebabCase("outputDir") => "output-dir"
127
- * @example toKebabCase("XMLParser") => "xml-parser"
128
- */
129
- declare function toKebabCase(str: string): string;
130
- /**
131
- * Convert hyphen-separated sequences to camelCase.
132
- *
133
- * Replaces `-x` (hyphen followed by a lowercase letter) with the uppercase
134
- * variant. Non-hyphenated input (e.g., already camelCase) is returned as-is.
135
- *
136
- * @param str - A string that may contain hyphens
137
- * @example toCamelCase("dry-run") => "dryRun"
138
- * @example toCamelCase("output-dir") => "outputDir"
139
- * @example toCamelCase("dryRun") => "dryRun"
140
- */
141
- declare function toCamelCase(str: string): string;
142
- /**
143
- * Extract all fields from a schema
144
- *
145
- * @param schema - The args schema (ZodObject, ZodDiscriminatedUnion, etc.)
146
- * @returns Extracted field information
147
- */
148
- declare function extractFields(schema: ArgsSchema): ExtractedFields;
149
- //#endregion
150
- //#region src/lazy.d.ts
151
- /**
152
- * A lazily-loaded command that carries synchronous metadata for
153
- * static analysis (completion, help) while deferring full module
154
- * loading to execution time.
155
- */
156
- interface LazyCommand<T extends AnyCommand = AnyCommand> {
157
- readonly __politty_lazy__: true;
158
- readonly meta: T;
159
- readonly load: () => Promise<AnyCommand>;
160
- }
161
- /**
162
- * Type guard: check if a value is a LazyCommand
163
- */
164
- declare function isLazyCommand(value: unknown): value is LazyCommand;
165
- /**
166
- * Create a lazily-loaded subcommand with synchronous metadata.
167
- *
168
- * The `meta` command provides names, descriptions, and args schema
169
- * for static analysis (completion scripts, help text) without loading
170
- * the full command module.
171
- *
172
- * The `load` function is called only at execution time.
173
- *
174
- * @example
175
- * ```ts
176
- * import { lazy, defineCommand } from "politty";
177
- *
178
- * const cli = defineCommand({
179
- * name: "mycli",
180
- * subCommands: {
181
- * deploy: lazy(
182
- * defineCommand({
183
- * name: "deploy",
184
- * description: "Deploy the application",
185
- * args: z.object({ env: arg(z.string()) }),
186
- * }),
187
- * () => import("./deploy.js").then((m) => m.deployCommand),
188
- * ),
189
- * },
190
- * });
191
- * ```
192
- */
193
- declare function lazy<T extends AnyCommand>(meta: T, load: () => Promise<AnyCommand>): LazyCommand<T>;
194
- //#endregion
195
- //#region src/types.d.ts
196
- /**
197
- * Global args interface for declaration merging (Pattern 3).
198
- * Users can extend this interface to add global options to all commands:
199
- *
200
- * ```ts
201
- * declare module "politty" {
202
- * interface GlobalArgs { verbose: boolean; config?: string; }
203
- * }
204
- * ```
205
- */
206
- interface GlobalArgs {}
207
- /**
208
- * Detect empty interface (used for GlobalArgs declaration merging)
209
- */
210
- type IsEmpty<T> = keyof T extends never ? true : false;
211
- /**
212
- * Example definition for a command
213
- */
214
- interface Example {
215
- /** Command arguments to execute (e.g., "World" or "--loud Alice") */
216
- cmd: string;
217
- /** Description of the example */
218
- desc: string;
219
- /** Expected output (optional, for documentation) */
220
- output?: string;
221
- }
222
- /**
223
- * Logger interface for CLI output
224
- * Can be overridden by passing a custom logger to runMain or runCommand
225
- */
226
- interface Logger {
227
- /** Log informational message to stdout */
228
- log(message: string): void;
229
- /** Log error message to stderr */
230
- error(message: string): void;
231
- }
232
- /**
233
- * Supported schema types for args
234
- */
235
- type ArgsSchema = z.ZodType<Record<string, any>>;
236
- /**
237
- * Context provided to setup function
238
- */
239
- interface SetupContext<TArgs = unknown> {
240
- /** Parsed and validated arguments */
241
- args: TArgs;
242
- }
243
- /**
244
- * Context provided to cleanup function
245
- */
246
- interface CleanupContext<TArgs = unknown> {
247
- /** Parsed and validated arguments */
248
- args: TArgs;
249
- /** Error if command execution failed */
250
- error?: Error | undefined;
251
- }
252
- /**
253
- * Context provided to global setup function (runMain/runCommand level)
254
- */
255
- interface GlobalSetupContext {}
256
- /**
257
- * Context provided to global cleanup function (runMain/runCommand level)
258
- */
259
- interface GlobalCleanupContext {
260
- /** Error if command execution failed */
261
- error?: Error | undefined;
262
- }
263
- /**
264
- * Base command interface (shared properties)
265
- * @template TArgsSchema - The Zod schema type for arguments
266
- * @template TArgs - The inferred args type from the schema
267
- */
268
- interface CommandBase<TArgsSchema extends ArgsSchema | undefined = undefined, TArgs = unknown> {
269
- /** Command name (required) */
270
- name: string;
271
- /** Command description */
272
- description?: string | undefined;
273
- /** Alternative names for this command (used as subcommand aliases) */
274
- aliases?: string[] | undefined;
275
- /** Argument schema (preserves the original Zod schema type) */
276
- args: TArgsSchema;
277
- /** Subcommands */
278
- subCommands?: SubCommandsRecord | undefined;
279
- /** Setup hook */
280
- setup?: ((context: SetupContext<TArgs>) => void | Promise<void>) | undefined;
281
- /** Cleanup hook */
282
- cleanup?: ((context: CleanupContext<TArgs>) => void | Promise<void>) | undefined;
283
- /** Additional notes */
284
- notes?: string | undefined;
285
- /** Example usages for this command */
286
- examples?: Example[] | undefined;
287
- /**
288
- * @internal
289
- * Hook invoked once at the top of `runMain`, before any parsing. Used
290
- * by `withCompletionCommand` to fire its detached background-refresh
291
- * spawn. Best-effort; never throws.
292
- */
293
- runMainHook?: ((argv: readonly string[]) => void) | undefined;
294
- }
295
- /**
296
- * A command with a run function
297
- * @template TArgsSchema - The Zod schema type for arguments
298
- * @template TArgs - The inferred args type from the schema
299
- * @template TResult - The return type of the run function
300
- */
301
- interface RunnableCommand<TArgsSchema extends ArgsSchema | undefined = undefined, TArgs = unknown, TResult = unknown> extends CommandBase<TArgsSchema, TArgs> {
302
- /** Main run function */
303
- run: (args: TArgs) => TResult;
304
- }
305
- /**
306
- * A command without a run function (e.g., subcommand-only parent)
307
- * @template TArgsSchema - The Zod schema type for arguments
308
- * @template TArgs - The inferred args type from the schema
309
- */
310
- interface NonRunnableCommand<TArgsSchema extends ArgsSchema | undefined = undefined, TArgs = unknown> extends CommandBase<TArgsSchema, TArgs> {
311
- /** No run function */
312
- run?: undefined;
313
- }
314
- /**
315
- * A defined command (union of runnable and non-runnable)
316
- */
317
- type Command<TArgsSchema extends ArgsSchema | undefined = undefined, TArgs = unknown, TResult = unknown> = RunnableCommand<TArgsSchema, TArgs, TResult> | NonRunnableCommand<TArgsSchema, TArgs>;
318
- /**
319
- * Type alias for any args type.
320
- * Note: `any` is required here due to TypeScript's function parameter contravariance.
321
- * Using `unknown` would make it impossible to assign concrete command types to AnyCommand.
322
- * @internal
323
- */
324
- type AnyArgs = any;
325
- /**
326
- * Type alias for any result type.
327
- * @internal
328
- */
329
- type AnyResult = any;
330
- /**
331
- * Command type that accepts any args/result types
332
- * Used in internal functions that don't need specific type information
333
- */
334
- type AnyCommand = Command<ArgsSchema | undefined, AnyArgs, AnyResult>;
335
- /**
336
- * Subcommand value type (either a command or a lazy-loaded command)
337
- */
338
- type SubCommandValue = AnyCommand | (() => Promise<AnyCommand>) | LazyCommand;
339
- /**
340
- * Record of subcommands indexed by name
341
- */
342
- type SubCommandsRecord = Record<string, SubCommandValue>;
343
- /**
344
- * Async callback to resolve missing argument values interactively.
345
- * Called after env fallback, before Zod validation.
346
- * Provided by adapter subpath modules (e.g. `politty/prompt/clack`).
347
- */
348
- type PromptResolver = (rawArgs: Record<string, unknown>, extracted: ExtractedFields) => Promise<Record<string, unknown>>;
349
- /**
350
- * Options for runMain (CLI entry point)
351
- */
352
- interface MainOptions {
353
- /** Command version */
354
- version?: string;
355
- /** Enable debug mode (show stack traces on errors) */
356
- debug?: boolean;
357
- /** Capture console output during execution (default: false) */
358
- captureLogs?: boolean;
359
- /** Skip command definition validation (useful in production where tests already verified) */
360
- skipValidation?: boolean;
361
- /** Custom logger for output (default: console) */
362
- logger?: Logger;
363
- /** Global args schema (shared across all subcommands) */
364
- globalArgs?: ArgsSchema;
365
- /** Global setup hook (runs before command execution) */
366
- setup?: ((context: GlobalSetupContext) => void | Promise<void>) | undefined;
367
- /** Global cleanup hook (runs after command execution, always executes even on error) */
368
- cleanup?: ((context: GlobalCleanupContext) => void | Promise<void>) | undefined;
369
- /** Whether to display errors to stderr before process.exit (default: true) */
370
- displayErrors?: boolean;
371
- /** Prompt resolver for interactive missing-arg prompts (e.g. from `politty/prompt/clack`). */
372
- prompt?: PromptResolver | undefined;
373
- /**
374
- * Fallback hook for CLI plugin dispatch, invoked when a positional is not a
375
- * known subcommand at any level whose command exposes subcommands (e.g. exec
376
- * an external `<cli>-<path...>-<name>` binary).
377
- *
378
- * Return a number to treat it as handled and exit with that code; return
379
- * `undefined` (or omit) to fall back to the default unknown-subcommand/help
380
- * behavior. Not invoked for internal `__*` subcommands.
381
- */
382
- onUnknownSubcommand?: UnknownSubcommandHandler | undefined;
383
- }
384
- /**
385
- * Handler for an unrecognized subcommand. See {@link MainOptions.onUnknownSubcommand}.
386
- */
387
- type UnknownSubcommandHandler = (context: {
388
- /**
389
- * Known subcommand names traversed before the unknown name (excludes the
390
- * root command name). Empty at the root level.
391
- */
392
- commandPath: readonly string[]; /** The unrecognized subcommand name (first unmatched positional). */
393
- name: string; /** Args following the name, forwarded verbatim to the plugin. */
394
- args: readonly string[];
395
- }) => number | undefined | Promise<number | undefined>;
396
- /**
397
- * Options for runCommand (programmatic/test usage)
398
- */
399
- interface RunCommandOptions {
400
- /** Enable debug mode (show stack traces on errors) */
401
- debug?: boolean;
402
- /** Capture console output during execution (default: false) */
403
- captureLogs?: boolean;
404
- /** Skip command definition validation (useful in production where tests already verified) */
405
- skipValidation?: boolean;
406
- /** Custom logger for output (default: console) */
407
- logger?: Logger;
408
- /** Global args schema (shared across all subcommands) */
409
- globalArgs?: ArgsSchema;
410
- /** Global setup hook (runs before command execution) */
411
- setup?: ((context: GlobalSetupContext) => void | Promise<void>) | undefined;
412
- /** Global cleanup hook (runs after command execution, always executes even on error) */
413
- cleanup?: ((context: GlobalCleanupContext) => void | Promise<void>) | undefined;
414
- /** Prompt resolver for interactive missing-arg prompts (e.g. from `politty/prompt/clack`). */
415
- prompt?: PromptResolver | undefined;
416
- }
417
- /**
418
- * Log level type
419
- */
420
- type LogLevel = "log" | "info" | "debug" | "warn" | "error";
421
- /**
422
- * Output stream type
423
- */
424
- type LogStream = "stdout" | "stderr";
425
- /**
426
- * A single log entry collected during command execution
427
- */
428
- interface LogEntry {
429
- /** Log message */
430
- message: string;
431
- /** Timestamp when the log was recorded */
432
- timestamp: Date;
433
- /** Log level */
434
- level: LogLevel;
435
- /** Output stream (stdout or stderr) */
436
- stream: LogStream;
437
- }
438
- /**
439
- * Collected logs during command execution
440
- */
441
- interface CollectedLogs {
442
- /** All log entries in order */
443
- entries: LogEntry[];
444
- }
445
- /**
446
- * Successful command execution result
447
- */
448
- interface RunResultSuccess<T = unknown> {
449
- /** Indicates successful execution */
450
- success: true;
451
- /** Command return value */
452
- result: T | undefined;
453
- /** Error that occurred during execution */
454
- error?: never;
455
- /** Exit code (always 0 for success) */
456
- exitCode: 0;
457
- /** Collected logs during execution */
458
- logs: CollectedLogs;
459
- }
460
- /**
461
- * Failed command execution result
462
- */
463
- interface RunResultFailure {
464
- /** Indicates failed execution */
465
- success: false;
466
- /** Command return value */
467
- result?: never;
468
- /** Error that occurred during execution */
469
- error: Error;
470
- /** Exit code (non-zero for failure) */
471
- exitCode: number;
472
- /** Collected logs during execution */
473
- logs: CollectedLogs;
474
- }
475
- /**
476
- * Result of command execution (discriminated union)
477
- */
478
- type RunResult<T = unknown> = RunResultSuccess<T> | RunResultFailure;
479
- //#endregion
480
- //#region src/core/dynamic-completion-types.d.ts
481
- /**
482
- * Types for in-process dynamic value completion.
483
- *
484
- * A `resolve` callback registered on `arg(...)` receives parsed context
485
- * (other arg values typed so far, previous values supplied to the same
486
- * option, the current word being completed, target shell) and returns
487
- * candidates. The callback runs inside the `__complete` command. Dispatcher
488
- * shell scripts call `__complete` for every completion request; static shell
489
- * scripts delegate to it for any spec that uses `resolve`.
490
- *
491
- * Defined under `core/` (not `completion/`) so `arg-registry.ts` can
492
- * reference the resolver type without crossing the lint-enforced
493
- * `completion → core` boundary.
494
- */
495
- /** Bitmask combining `CompletionDirective` values. */
496
- type CompletionDirectiveMask = number;
497
- interface DynamicCompletionContext {
498
- /** Word being completed. `--field=` inline prefix is stripped before this is set. */
499
- currentWord: string;
500
- /** Target shell formatting requested by the caller. */
501
- shell: "bash" | "zsh" | "fish";
502
- /**
503
- * Best-effort parsed values of OTHER args on the same command, keyed by
504
- * camelCase name. Includes positionals and other options. Zod validation
505
- * is NOT applied; values are raw strings (or arrays of raw strings for
506
- * array-typed options/variadic positionals).
507
- */
508
- parsedArgs: Readonly<Record<string, unknown>>;
509
- /**
510
- * Values already supplied for the SAME option/positional being completed.
511
- * Useful for de-duplicating repeated array options.
512
- */
513
- previousValues: readonly string[];
514
- /**
515
- * Subcommand path from root (e.g. ["api"]). Reflects what the user
516
- * actually typed — aliases are NOT resolved to their canonical names, so
517
- * resolvers that branch on the path should accept every alias they care
518
- * about.
519
- */
520
- subcommandPath: readonly string[];
521
- }
522
- interface DynamicCompletionCandidate {
523
- value: string;
524
- description?: string;
525
- }
526
- interface DynamicCompletionResult {
527
- /** Candidates to surface. Strings or `{value, description}` objects. */
528
- candidates: Array<string | DynamicCompletionCandidate>;
529
- /**
530
- * Optional directive override. When omitted, defaults to
531
- * `FilterPrefix | NoFileCompletion` (matches `choices` behaviour).
532
- */
533
- directive?: CompletionDirectiveMask;
534
- }
535
- type DynamicCompletionResolver = (ctx: DynamicCompletionContext) => DynamicCompletionResult | Promise<DynamicCompletionResult>;
536
- //#endregion
537
- //#region src/core/expand-completion-types.d.ts
538
- /**
539
- * Types for "expand" completion — candidates that depend on sibling arg
540
- * values.
541
- *
542
- * The user provides `dependsOn` (sibling arg names that must have static
543
- * `choices` or an enum schema) and `enumerate(deps)`. Dispatcher scripts call
544
- * `enumerate` inside `__complete` for the dependency values already typed on
545
- * the command line. Static scripts walk the cartesian product of the
546
- * dependsOn values, call `enumerate` for each combination, and emit a shell
547
- * lookup table.
548
- *
549
- * Defined under `core/` (not `completion/`) so `arg-registry.ts` can
550
- * reference these types without crossing the lint-enforced
551
- * `completion → core` boundary.
552
- */
553
- /** Candidate returned by an `enumerate` callback. */
554
- interface ExpandCandidate {
555
- value: string;
556
- description?: string;
557
- }
558
- /** Resolved candidate stored on a {@link ValueCompletion} after enumeration. */
559
- interface ResolvedExpandCandidate {
560
- value: string;
561
- description?: string;
562
- }
563
- /**
564
- * User-facing spec attached to `completion.custom.expand`.
565
- *
566
- * `dependsOn` lists sibling args (camelCase names) whose values determine
567
- * which candidates apply. Each named arg must have a static set of values —
568
- * either an explicit `completion.custom.choices` or an enum schema. The
569
- * order of `dependsOn` is the order in which `deps` keys are exposed to
570
- * `enumerate`.
571
- *
572
- * In dispatcher mode, `enumerate` runs during `__complete` for the dependency
573
- * values already typed by the user. In static mode, it runs once per
574
- * cartesian-product combination at script-generation time (e.g. when the user
575
- * runs `<program> completion zsh --static`). It must be a pure function of
576
- * `deps`.
577
- */
578
- interface ExpandCompletion {
579
- dependsOn: readonly string[];
580
- enumerate: (deps: Readonly<Record<string, string>>) => ReadonlyArray<string | ExpandCandidate>;
581
- }
582
- //#endregion
583
- //#region src/core/arg-registry.d.ts
584
- /**
585
- * Built-in completion types
586
- */
587
- type CompletionType = "file" | "directory" | "none";
588
- /**
589
- * Custom completion specification.
590
- *
591
- * `choices`, `shellCommand`, `resolve`, and `expand` are mutually exclusive —
592
- * specifying more than one throws when the field metadata is resolved.
593
- */
594
- interface CustomCompletion {
595
- /** Static list of choices for completion */
596
- choices?: string[];
597
- /** Shell command to execute for dynamic completion */
598
- shellCommand?: string;
599
- /**
600
- * In-process JS callback for dynamic completion. Receives parsed context
601
- * (other arg values typed so far, previously supplied values for this same
602
- * option) and returns candidates. Dispatcher scripts call
603
- * `<program> __complete` for every completion request; static scripts
604
- * delegate to it whenever this is set.
605
- */
606
- resolve?: DynamicCompletionResolver;
607
- /**
608
- * Completion whose candidates depend on sibling arg values. Dispatcher
609
- * scripts call `enumerate` inside `__complete` for the dependency values
610
- * already typed on the command line. Static scripts pre-enumerate every
611
- * combination of `dependsOn` values at script-generation time and dispatch
612
- * via a shell lookup table.
613
- */
614
- expand?: ExpandCompletion;
615
- }
616
- /**
617
- * Completion metadata for an argument
618
- *
619
- * @example
620
- * ```ts
621
- * // File completion with extension filter
622
- * input: arg(z.string(), {
623
- * completion: { type: "file", extensions: ["json", "yaml"] }
624
- * })
625
- *
626
- * // Directory completion
627
- * outputDir: arg(z.string(), {
628
- * completion: { type: "directory" }
629
- * })
630
- *
631
- * // Custom static choices
632
- * logLevel: arg(z.string(), {
633
- * completion: { custom: { choices: ["debug", "info", "warn", "error"] } }
634
- * })
635
- *
636
- * // Dynamic completion from shell command
637
- * branch: arg(z.string(), {
638
- * completion: { custom: { shellCommand: "git branch --format='%(refname:short)'" } }
639
- * })
640
- *
641
- * // File completion with glob pattern matcher
642
- * envFile: arg(z.string(), {
643
- * completion: { type: "file", matcher: [".env.*"] }
644
- * })
645
- * ```
646
- */
647
- type CompletionMeta = {
648
- /** Built-in completion type */type?: CompletionType; /** Custom completion (takes precedence over type if both specified) */
649
- custom?: CustomCompletion;
650
- } & ({
651
- /** File extension filter (only applies when type is "file") */extensions?: string[];
652
- matcher?: never;
653
- } | {
654
- /** Glob patterns for file matching (only applies when type is "file") */matcher?: string[];
655
- extensions?: never;
656
- });
657
- /**
658
- * Prompt input type for interactive prompts
659
- *
660
- * - "text": free-form text input (default for string schemas)
661
- * - "password": masked text input
662
- * - "confirm": yes/no prompt (default for boolean schemas)
663
- * - "select": single selection from choices (default for enum schemas)
664
- * - "file": file path input (inherited from completion type)
665
- * - "directory": directory path input (inherited from completion type)
666
- */
667
- type PromptType = "text" | "password" | "confirm" | "select" | "file" | "directory";
668
- /**
669
- * Prompt metadata for interactive input when a value is missing.
670
- * Used by the `politty/prompt` module to request user input for unresolved arguments.
671
- *
672
- * @example
673
- * ```ts
674
- * // Custom prompt message
675
- * name: arg(z.string(), {
676
- * prompt: { message: "What is your name?" }
677
- * })
678
- *
679
- * // Password input (masked)
680
- * token: arg(z.string(), {
681
- * prompt: { type: "password", message: "Enter API token" }
682
- * })
683
- *
684
- * // Select with custom choices
685
- * region: arg(z.string(), {
686
- * prompt: { choices: ["us-east-1", "eu-west-1", "ap-northeast-1"] }
687
- * })
688
- * ```
689
- */
690
- interface PromptMeta {
691
- /** Prompt message shown to the user. Defaults to the field's description or name. */
692
- message?: string;
693
- /** Explicit prompt type. Overrides auto-detection from schema/completion. */
694
- type?: PromptType;
695
- /** Choices for select prompt. Overrides enum values from schema. */
696
- choices?: Array<string | {
697
- label: string;
698
- value: string;
699
- }>;
700
- /** Whether to enable prompting for this field (default: true when prompt is set) */
701
- enabled?: boolean;
702
- }
703
- /**
704
- * Context provided to effect callbacks.
705
- * When GlobalArgs is extended via declaration merging, `globalArgs` is typed accordingly.
706
- */
707
- type EffectContext = {
708
- /** Field name (camelCase) */name: string; /** Validated args for this schema (global args for global effects, command args for command effects) */
709
- args: Readonly<Record<string, unknown>>;
710
- } & (IsEmpty<GlobalArgs> extends true ? {
711
- globalArgs?: Readonly<Record<string, unknown>>;
712
- } : {
713
- globalArgs?: Readonly<GlobalArgs>;
714
- });
715
- /**
716
- * Base metadata shared by all argument types
717
- */
718
- interface BaseArgMeta<TValue = unknown> {
719
- /** Argument description */
720
- description?: string;
721
- /** Treat as positional argument */
722
- positional?: boolean;
723
- /** Placeholder for help display */
724
- placeholder?: string;
725
- /**
726
- * Environment variable name(s) to read value from.
727
- * If an array is provided, earlier entries take priority.
728
- * CLI arguments always take precedence over environment variables.
729
- *
730
- * @example
731
- * ```ts
732
- * // Single env var
733
- * port: arg(z.coerce.number(), { env: "PORT" })
734
- *
735
- * // Multiple env vars (PORT takes priority over SERVER_PORT)
736
- * port: arg(z.coerce.number(), { env: ["PORT", "SERVER_PORT"] })
737
- * ```
738
- */
739
- env?: string | string[];
740
- /** Completion configuration for shell tab-completion */
741
- completion?: CompletionMeta;
742
- /**
743
- * Interactive prompt configuration for missing values.
744
- * When set, the `politty/prompt` module will prompt the user interactively
745
- * if this argument is not provided via CLI args or environment variables.
746
- *
747
- * @example
748
- * ```ts
749
- * name: arg(z.string(), {
750
- * description: "User name",
751
- * prompt: { message: "What is your name?" },
752
- * })
753
- * ```
754
- */
755
- prompt?: PromptMeta;
756
- /**
757
- * Control the boolean negation option.
758
- *
759
- * Boolean fields automatically accept `--no-<cliName>` (and the camelCase
760
- * `--no<Name>` form) to set the value to `false`. By default this form is
761
- * accepted by the parser but hidden from help, generated docs, and shell
762
- * completions. This option lets you customize or expose that behavior:
763
- *
764
- * - `string` — replaces the auto-generated `--no-*` form with a custom
765
- * name. The default `--no-*` is no longer recognized.
766
- * - `true` — opt-in to advertising the default `--no-<cliName>` form in
767
- * help, generated docs, and shell completions. Parser behavior is
768
- * unchanged.
769
- * - `false` — disables negation entirely; neither the default `--no-*`
770
- * nor any custom name is accepted.
771
- *
772
- * String values follow the same naming conventions as `cliName`
773
- * (kebab-case is recommended). Only valid on boolean fields; setting
774
- * `negation` on a non-boolean field is a type error and raises a
775
- * runtime error during command parsing.
776
- *
777
- * @example
778
- * ```ts
779
- * // Custom negation name
780
- * cache: arg(z.boolean().default(true), {
781
- * description: "Enable caching",
782
- * negation: "disable-cache",
783
- * })
784
- * // Accepts: --cache (true), --disable-cache (false)
785
- * // No longer accepts: --no-cache
786
- *
787
- * // Expose default `--no-X` in help/docs/completion
788
- * verbose: arg(z.boolean().default(false), {
789
- * negation: true,
790
- * })
791
- * // Help shows `--verbose / --no-verbose`
792
- *
793
- * // Disable negation entirely
794
- * dryRun: arg(z.boolean().default(false), {
795
- * negation: false,
796
- * })
797
- * // Accepts: --dry-run (true)
798
- * // No longer accepts: --no-dry-run
799
- * ```
800
- */
801
- negation?: string | boolean;
802
- /**
803
- * Description shown for the negation option in help and generated docs.
804
- * Only meaningful when `negation` is set to a custom name string or `true`.
805
- * Disallowed when `negation` is `false`.
806
- */
807
- negationDescription?: string;
808
- /**
809
- * Side-effect callback executed after argument parsing and validation.
810
- * Runs before the command lifecycle (setup/run/cleanup).
811
- * Use Zod .transform() for value transformation instead.
812
- *
813
- * @example
814
- * ```ts
815
- * verbose: arg(z.boolean().default(false), {
816
- * alias: "v",
817
- * effect: (value) => {
818
- * if (value) logger.setLevel("debug");
819
- * },
820
- * })
821
- * ```
822
- */
823
- effect?: (value: TValue, context: EffectContext) => void | PromiseLike<void>;
824
- }
825
- /**
826
- * Metadata for regular arguments (non-builtin aliases)
827
- *
828
- * `alias` accepts either a single string or an array of strings.
829
- * Single-character entries become short options (e.g. `-v`); multi-character
830
- * entries become additional long options (e.g. `--to-be` for `--tobe`).
831
- */
832
- interface RegularArgMeta<TValue = unknown> extends BaseArgMeta<TValue> {
833
- /**
834
- * Alias name(s) for this option.
835
- * - 1-char string → short alias (`-v`)
836
- * - >1-char string → long alias (`--long-name`)
837
- * - array → multiple aliases of either kind
838
- */
839
- alias?: string | string[] | readonly string[];
840
- /**
841
- * Alias name(s) that are accepted by the parser but hidden from help,
842
- * generated docs, and shell completion. Useful for legacy or deprecated
843
- * names that should still work without being advertised.
844
- */
845
- hiddenAlias?: string | string[] | readonly string[];
846
- }
847
- /**
848
- * Metadata for overriding built-in aliases (-h, -H)
849
- */
850
- interface BuiltinOverrideArgMeta<TValue = unknown> extends BaseArgMeta<TValue> {
851
- /** Built-in alias to override ('h' or 'H'), optionally combined with extra aliases */
852
- alias: "h" | "H" | Array<"h" | "H" | string> | ReadonlyArray<"h" | "H" | string>;
853
- /** Hidden aliases (accepted but not surfaced in help/docs/completion) */
854
- hiddenAlias?: string | string[] | readonly string[];
855
- /** Must be true to override built-in aliases */
856
- overrideBuiltinAlias: true;
857
- }
858
- /**
859
- * Metadata options for argument definition
860
- */
861
- type ArgMeta<TValue = unknown> = RegularArgMeta<TValue> | BuiltinOverrideArgMeta<TValue>;
862
- /**
863
- * Register metadata for a Zod schema
864
- *
865
- * @param schema - The Zod schema
866
- * @param meta - Argument metadata
867
- * @returns The same schema (for chaining)
868
- *
869
- * @example
870
- * ```ts
871
- * import { z } from "zod";
872
- * import { arg, defineCommand } from "politty";
873
- *
874
- * const cmd = defineCommand({
875
- * args: z.object({
876
- * name: arg(z.string(), { description: "User name", positional: true }),
877
- * verbose: arg(z.boolean().default(false), { alias: "v" }),
878
- * }),
879
- * run: (args) => {
880
- * console.log(args.name, args.verbose);
881
- * },
882
- * });
883
- * ```
884
- */
885
- /**
886
- * Detect whether `A` contains a reserved alias ("h" or "H"), for either a
887
- * plain string or a tuple/array of strings. Uses `[A] extends [never]` to
888
- * prevent distribution returning `never` for missing fields.
889
- */
890
- type ContainsReservedAlias<A> = [A] extends [never] ? false : A extends "h" | "H" ? true : A extends readonly (infer E)[] ? [Extract<E, "h" | "H">] extends [never] ? false : true : false;
891
- type ReservedAliasTypeError<M> = { [K in keyof M]: M[K] } & {
892
- __typeError: "Alias 'h' or 'H' requires overrideBuiltinAlias: true";
893
- };
894
- type NegationTypeError<M> = { [K in keyof M]: M[K] } & {
895
- __typeError: "negation/negationDescription can only be used on boolean fields";
896
- };
897
- type AliasFieldOf<M> = M extends {
898
- alias: infer A;
899
- } ? A : never;
900
- type HiddenAliasFieldOf<M> = M extends {
901
- hiddenAlias: infer H;
902
- } ? H : never;
903
- /**
904
- * Check whether a Zod output type is a (possibly optional) boolean.
905
- * Strips `undefined` to allow `z.boolean().optional()`. Requires both
906
- * `boolean extends NonNullable<T>` (so `z.literal(true)` is rejected — the full
907
- * `boolean` domain is needed) and `NonNullable<T> extends boolean` (so unions
908
- * such as `z.union([z.boolean(), z.string()])` are rejected at the type level
909
- * to match the runtime check).
910
- */
911
- type IsBooleanField<T> = boolean extends NonNullable<T> ? ([NonNullable<T>] extends [boolean] ? true : false) : false;
912
- /**
913
- * Detect whether `M` has `K` set to a non-undefined value.
914
- *
915
- * When `M` is inferred from a literal such as `{ negation: "off" }`,
916
- * `M["negation"]` is `"off"` (without `undefined`), so this returns `true`.
917
- * When `M` is the wider `ArgMeta` type, `M["negation"]` is
918
- * `string | boolean | undefined`, so this returns `false` and avoids
919
- * false-positive type errors on broadly-typed meta values.
920
- */
921
- type HasExplicit<M, K extends string> = K extends keyof M ? undefined extends M[K] ? false : true : false;
922
- /**
923
- * Reject `negation` / `negationDescription` on non-boolean fields.
924
- * Uses {@link HasExplicit} so the error only fires when the user explicitly
925
- * sets the field on a narrowly-inferred meta literal.
926
- */
927
- type ValidateNegation<M, TValue> = HasExplicit<M, "negation"> extends true ? IsBooleanField<TValue> extends true ? M : NegationTypeError<M> : HasExplicit<M, "negationDescription"> extends true ? IsBooleanField<TValue> extends true ? M : NegationTypeError<M> : M;
928
- /**
929
- * Type helper to validate ArgMeta.
930
- * Forces a type error when a reserved alias ("h" / "H") is used without
931
- * `overrideBuiltinAlias: true`, whether the alias is provided as a string
932
- * or as part of an array, and whether it appears in `alias` or `hiddenAlias`.
933
- * Also rejects `negation` / `negationDescription` on non-boolean fields.
934
- */
935
- type ValidateArgMeta<M, TValue = unknown> = M extends {
936
- overrideBuiltinAlias: true;
937
- } ? ValidateNegation<M, TValue> : ContainsReservedAlias<AliasFieldOf<M>> extends true ? ReservedAliasTypeError<M> : ContainsReservedAlias<HiddenAliasFieldOf<M>> extends true ? ReservedAliasTypeError<M> : ValidateNegation<M, TValue>;
938
- declare function arg<T extends z.ZodType>(schema: T): T;
939
- declare function arg<T extends z.ZodType, M extends ArgMeta<z.output<T>>>(schema: T, meta: ValidateArgMeta<M, z.output<T>>): T;
940
- //#endregion
941
- export { toKebabCase as $, LogStream as A, SetupContext as B, Example as C, IsEmpty as D, GlobalSetupContext as E, RunCommandOptions as F, isLazyCommand as G, SubCommandsRecord as H, RunResult as I, ResolvedFieldMeta as J, lazy as K, RunResultFailure as L, MainOptions as M, NonRunnableCommand as N, LogEntry as O, PromptResolver as P, toCamelCase as Q, RunResultSuccess as R, CommandBase as S, GlobalCleanupContext as T, UnknownSubcommandHandler as U, SubCommandValue as V, LazyCommand as W, extractFields as X, UnknownKeysMode as Y, getUnknownKeysMode as Z, AnyCommand as _, EffectContext as a, CollectedLogs as b, arg as c, ResolvedExpandCandidate as d, CompletionDirectiveMask as f, DynamicCompletionResult as g, DynamicCompletionResolver as h, CustomCompletion as i, Logger as j, LogLevel as k, ExpandCandidate as l, DynamicCompletionContext as m, CompletionMeta as n, PromptMeta as o, DynamicCompletionCandidate as p, ExtractedFields as q, CompletionType as r, PromptType as s, ArgMeta as t, ExpandCompletion as u, ArgsSchema as v, GlobalArgs as w, Command as x, CleanupContext as y, RunnableCommand as z };
942
- //# sourceMappingURL=arg-registry-DDJpsUea.d.cts.map