padrone 1.5.0 → 1.7.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 (141) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +15 -11
  3. package/dist/{args-D5PNDyNu.mjs → args-Cnq0nwSM.mjs} +91 -41
  4. package/dist/args-Cnq0nwSM.mjs.map +1 -0
  5. package/dist/codegen/index.mjs +4 -4
  6. package/dist/codegen/index.mjs.map +1 -1
  7. package/dist/commands-B_gufyR9.mjs +514 -0
  8. package/dist/commands-B_gufyR9.mjs.map +1 -0
  9. package/dist/{completion.mjs → completion-BEuflbDO.mjs} +12 -82
  10. package/dist/completion-BEuflbDO.mjs.map +1 -0
  11. package/dist/docs/index.d.mts +4 -4
  12. package/dist/docs/index.d.mts.map +1 -1
  13. package/dist/docs/index.mjs +10 -12
  14. package/dist/docs/index.mjs.map +1 -1
  15. package/dist/{errors-BiVrBgi6.mjs → errors-DA4KzK1M.mjs} +26 -3
  16. package/dist/errors-DA4KzK1M.mjs.map +1 -0
  17. package/dist/{formatter-DtHzbP22.d.mts → formatter-DrvhDMrq.d.mts} +3 -3
  18. package/dist/formatter-DrvhDMrq.d.mts.map +1 -0
  19. package/dist/{help-bbmu9-qd.mjs → help-BtxLgrF_.mjs} +190 -43
  20. package/dist/help-BtxLgrF_.mjs.map +1 -0
  21. package/dist/{types-Ch8Mk6Qb.d.mts → index-D6-7dz0l.d.mts} +634 -745
  22. package/dist/index-D6-7dz0l.d.mts.map +1 -0
  23. package/dist/index.d.mts +869 -36
  24. package/dist/index.d.mts.map +1 -1
  25. package/dist/index.mjs +3884 -1699
  26. package/dist/index.mjs.map +1 -1
  27. package/dist/{mcp-mLWIdUIu.mjs → mcp-6-Jw4Bpq.mjs} +13 -15
  28. package/dist/mcp-6-Jw4Bpq.mjs.map +1 -0
  29. package/dist/{serve-B0u43DK7.mjs → serve-YVTPzBCl.mjs} +12 -14
  30. package/dist/serve-YVTPzBCl.mjs.map +1 -0
  31. package/dist/{stream-BcC146Ud.mjs → stream-DC4H8YTx.mjs} +24 -3
  32. package/dist/stream-DC4H8YTx.mjs.map +1 -0
  33. package/dist/test.d.mts +5 -8
  34. package/dist/test.d.mts.map +1 -1
  35. package/dist/test.mjs +2 -13
  36. package/dist/test.mjs.map +1 -1
  37. package/dist/{update-check-CFX1FV3v.mjs → update-check-CZ2VqjnV.mjs} +16 -17
  38. package/dist/update-check-CZ2VqjnV.mjs.map +1 -0
  39. package/dist/zod.d.mts +2 -2
  40. package/dist/zod.d.mts.map +1 -1
  41. package/dist/zod.mjs +2 -2
  42. package/dist/zod.mjs.map +1 -1
  43. package/package.json +15 -12
  44. package/src/cli/completions.ts +14 -11
  45. package/src/cli/docs.ts +13 -10
  46. package/src/cli/doctor.ts +22 -18
  47. package/src/cli/index.ts +28 -82
  48. package/src/cli/init.ts +10 -7
  49. package/src/cli/link.ts +20 -16
  50. package/src/cli/wrap.ts +14 -11
  51. package/src/codegen/schema-to-code.ts +2 -2
  52. package/src/{args.ts → core/args.ts} +32 -225
  53. package/src/core/commands.ts +373 -0
  54. package/src/core/create.ts +301 -0
  55. package/src/core/default-runtime.ts +239 -0
  56. package/src/{errors.ts → core/errors.ts} +22 -0
  57. package/src/core/exec.ts +259 -0
  58. package/src/core/interceptors.ts +302 -0
  59. package/src/{parse.ts → core/parse.ts} +36 -89
  60. package/src/core/program-methods.ts +301 -0
  61. package/src/core/results.ts +229 -0
  62. package/src/core/runtime.ts +246 -0
  63. package/src/core/validate.ts +247 -0
  64. package/src/docs/index.ts +12 -13
  65. package/src/extension/auto-output.ts +146 -0
  66. package/src/extension/color.ts +38 -0
  67. package/src/extension/completion.ts +49 -0
  68. package/src/extension/config.ts +262 -0
  69. package/src/extension/env.ts +101 -0
  70. package/src/extension/help.ts +192 -0
  71. package/src/extension/index.ts +44 -0
  72. package/src/extension/ink.ts +93 -0
  73. package/src/extension/interactive.ts +106 -0
  74. package/src/extension/logger.ts +262 -0
  75. package/src/extension/man.ts +51 -0
  76. package/src/extension/mcp.ts +52 -0
  77. package/src/extension/progress-renderer.ts +338 -0
  78. package/src/extension/progress.ts +299 -0
  79. package/src/extension/repl.ts +94 -0
  80. package/src/extension/serve.ts +48 -0
  81. package/src/extension/signal.ts +87 -0
  82. package/src/extension/stdin.ts +62 -0
  83. package/src/extension/suggestions.ts +114 -0
  84. package/src/extension/timing.ts +81 -0
  85. package/src/extension/tracing.ts +175 -0
  86. package/src/extension/update-check.ts +77 -0
  87. package/src/extension/utils.ts +51 -0
  88. package/src/extension/version.ts +63 -0
  89. package/src/{completion.ts → feature/completion.ts} +12 -12
  90. package/src/{interactive.ts → feature/interactive.ts} +4 -4
  91. package/src/{mcp.ts → feature/mcp.ts} +12 -15
  92. package/src/{repl-loop.ts → feature/repl-loop.ts} +10 -13
  93. package/src/{serve.ts → feature/serve.ts} +11 -15
  94. package/src/feature/test.ts +262 -0
  95. package/src/{update-check.ts → feature/update-check.ts} +16 -16
  96. package/src/{wrap.ts → feature/wrap.ts} +10 -8
  97. package/src/index.ts +115 -30
  98. package/src/{formatter.ts → output/formatter.ts} +124 -176
  99. package/src/{help.ts → output/help.ts} +22 -8
  100. package/src/output/output-indicator.ts +87 -0
  101. package/src/output/primitives.ts +335 -0
  102. package/src/output/styling.ts +221 -0
  103. package/src/{zod.d.ts → schema/zod.d.ts} +1 -1
  104. package/src/schema/zod.ts +50 -0
  105. package/src/test.ts +2 -276
  106. package/src/types/args-meta.ts +151 -0
  107. package/src/types/builder.ts +718 -0
  108. package/src/types/command.ts +157 -0
  109. package/src/types/index.ts +60 -0
  110. package/src/types/interceptor.ts +296 -0
  111. package/src/types/preferences.ts +83 -0
  112. package/src/types/result.ts +71 -0
  113. package/src/types/schema.ts +19 -0
  114. package/src/util/dotenv.ts +244 -0
  115. package/src/{shell-utils.ts → util/shell-utils.ts} +26 -9
  116. package/src/{stream.ts → util/stream.ts} +27 -1
  117. package/src/{type-helpers.ts → util/type-helpers.ts} +23 -16
  118. package/src/{type-utils.ts → util/type-utils.ts} +71 -33
  119. package/src/util/utils.ts +51 -0
  120. package/src/zod.ts +1 -50
  121. package/dist/args-D5PNDyNu.mjs.map +0 -1
  122. package/dist/chunk-CjcI7cDX.mjs +0 -15
  123. package/dist/command-utils-B1D-HqCd.mjs +0 -1117
  124. package/dist/command-utils-B1D-HqCd.mjs.map +0 -1
  125. package/dist/completion.d.mts +0 -64
  126. package/dist/completion.d.mts.map +0 -1
  127. package/dist/completion.mjs.map +0 -1
  128. package/dist/errors-BiVrBgi6.mjs.map +0 -1
  129. package/dist/formatter-DtHzbP22.d.mts.map +0 -1
  130. package/dist/help-bbmu9-qd.mjs.map +0 -1
  131. package/dist/mcp-mLWIdUIu.mjs.map +0 -1
  132. package/dist/serve-B0u43DK7.mjs.map +0 -1
  133. package/dist/stream-BcC146Ud.mjs.map +0 -1
  134. package/dist/types-Ch8Mk6Qb.d.mts.map +0 -1
  135. package/dist/update-check-CFX1FV3v.mjs.map +0 -1
  136. package/src/command-utils.ts +0 -882
  137. package/src/create.ts +0 -1829
  138. package/src/runtime.ts +0 -497
  139. package/src/types.ts +0 -1291
  140. package/src/utils.ts +0 -140
  141. /package/src/{colorizer.ts → output/colorizer.ts} +0 -0
package/src/types.ts DELETED
@@ -1,1291 +0,0 @@
1
- import type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';
2
- import type { Tool } from 'ai';
3
- import type { PadroneArgsSchemaMeta } from './args.ts';
4
- import type { HelpPreferences } from './help.ts';
5
- import type { PadroneMcpPreferences } from './mcp.ts';
6
- import type { PadroneProgressIndicator, PadroneRuntime, PadroneSpinnerConfig, ResolvedPadroneRuntime } from './runtime.ts';
7
- import type { PadroneServePreferences } from './serve.ts';
8
- import type {
9
- Drained,
10
- FindDirectChild,
11
- FlattenCommands,
12
- FullCommandName,
13
- IsGeneric,
14
- MaybePromise,
15
- OrAsync,
16
- OrAsyncMeta,
17
- PickCommandByName,
18
- PickCommandByPossibleCommands,
19
- PossibleCommands,
20
- RepathCommands,
21
- ReplaceOrAppendCommand,
22
- SafeString,
23
- } from './type-utils.ts';
24
- import type { UpdateCheckConfig } from './update-check.ts';
25
- import type { WrapConfig, WrapResult } from './wrap.ts';
26
-
27
- type UnknownRecord = Record<string, unknown>;
28
- type EmptyRecord = Record<string, never>;
29
- type DefaultArgs = UnknownRecord | void;
30
-
31
- /**
32
- * Context object passed as the second argument to command action handlers.
33
- * Contains the resolved runtime, the executing command, and the program instance.
34
- */
35
- export type PadroneActionContext = {
36
- /** The resolved runtime for this command (I/O, env, config, etc.). */
37
- runtime: ResolvedPadroneRuntime;
38
- /** The command being executed. */
39
- command: AnyPadroneCommand;
40
- /** The root program instance. */
41
- program: AnyPadroneProgram;
42
- /**
43
- * The active auto-managed progress indicator, or a no-op if none is configured.
44
- * Use `.update()` to change the in-progress message mid-execution.
45
- */
46
- progress: PadroneProgressIndicator;
47
- };
48
-
49
- /**
50
- * A schema that supports both validation (StandardSchemaV1) and JSON schema generation (StandardJSONSchemaV1).
51
- * This is the type required for command arguments in Padrone.
52
- */
53
- export type PadroneSchema<Input = unknown, Output = Input> = StandardSchemaV1<Input, Output> & StandardJSONSchemaV1<Input, Output>;
54
-
55
- /**
56
- * A schema branded as async. When passed to `.arguments()`, `.configFile()`, or `.env()`,
57
- * the command is automatically marked as async, causing `parse()` and `cli()` to return Promises.
58
- *
59
- * Use the `asyncSchema()` helper to brand an existing schema:
60
- * ```ts
61
- * import { asyncSchema } from 'padrone';
62
- * const schema = asyncSchema(z.object({ name: z.string() }).check(async (v) => { ... }));
63
- * ```
64
- */
65
- export type AsyncPadroneSchema<Input = unknown, Output = Input> = PadroneSchema<Input, Output> & { '~async': true };
66
-
67
- /**
68
- * Helper type to set aliases on a command type.
69
- * Uses intersection to override just the aliases while preserving all other type information.
70
- */
71
- type WithAliases<TCommand extends AnyPadroneCommand, TAliases extends string[]> = Omit<TCommand, 'aliases' | '~types'> & {
72
- aliases?: TAliases;
73
- '~types': Omit<TCommand['~types'], 'aliases'> & { aliases: TAliases };
74
- };
75
-
76
- /**
77
- * Resolves aliases for a command override: if new aliases are provided (non-empty), use them;
78
- * otherwise, preserve the existing command's aliases.
79
- */
80
- type ResolvedAliases<
81
- TCommands extends [...AnyPadroneCommand[]],
82
- TNameNested extends string,
83
- TAliases extends string[],
84
- > = TAliases extends []
85
- ? FindDirectChild<TCommands, TNameNested> extends infer E extends AnyPadroneCommand
86
- ? E['~types']['aliases']
87
- : []
88
- : TAliases;
89
-
90
- /**
91
- * Resolves the initial builder type for a `.command()` call.
92
- * If TNameNested already exists in TCommands, the builder starts pre-populated with that command's types.
93
- * Otherwise, a fresh builder with default types is used.
94
- */
95
- type InitialCommandBuilder<
96
- TProgramName extends string,
97
- TNameNested extends string,
98
- TParentPath extends string,
99
- TParentArgs extends PadroneSchema,
100
- TCommands extends [...AnyPadroneCommand[]],
101
- > = [FindDirectChild<TCommands, TNameNested>] extends [never]
102
- ? PadroneBuilder<
103
- TProgramName,
104
- TNameNested,
105
- TParentPath,
106
- PadroneSchema<void>,
107
- void,
108
- [],
109
- TParentArgs,
110
- PadroneSchema<void>,
111
- PadroneSchema<void>,
112
- false
113
- >
114
- : FindDirectChild<TCommands, TNameNested> extends infer E extends AnyPadroneCommand
115
- ? PadroneBuilder<
116
- TProgramName,
117
- TNameNested,
118
- TParentPath,
119
- E['~types']['argsSchema'],
120
- E['~types']['result'],
121
- E['~types']['commands'],
122
- TParentArgs,
123
- E['~types']['configSchema'],
124
- E['~types']['envSchema'],
125
- E['~types']['async']
126
- >
127
- : PadroneBuilder<
128
- TProgramName,
129
- TNameNested,
130
- TParentPath,
131
- PadroneSchema<void>,
132
- void,
133
- [],
134
- TParentArgs,
135
- PadroneSchema<void>,
136
- PadroneSchema<void>,
137
- false
138
- >;
139
-
140
- export type AnyPadroneBuilder = InitialCommandBuilder<string, string, string, any, [...AnyPadroneCommand[]]>;
141
-
142
- /**
143
- * Like InitialCommandBuilder but uses `any` for args/config/env in the fresh case.
144
- * Used as the default for TBuilder when no builderFn is provided.
145
- */
146
- type DefaultCommandBuilder<
147
- TProgramName extends string,
148
- TNameNested extends string,
149
- TParentPath extends string,
150
- TParentArgs extends PadroneSchema,
151
- TCommands extends [...AnyPadroneCommand[]],
152
- > = [FindDirectChild<TCommands, TNameNested>] extends [never]
153
- ? PadroneBuilder<TProgramName, TNameNested, TParentPath, any, void, [], TParentArgs, any, any, false>
154
- : FindDirectChild<TCommands, TNameNested> extends infer E extends AnyPadroneCommand
155
- ? PadroneBuilder<
156
- TProgramName,
157
- TNameNested,
158
- TParentPath,
159
- E['~types']['argsSchema'],
160
- E['~types']['result'],
161
- E['~types']['commands'],
162
- TParentArgs,
163
- E['~types']['configSchema'],
164
- E['~types']['envSchema'],
165
- E['~types']['async']
166
- >
167
- : PadroneBuilder<TProgramName, TNameNested, TParentPath, any, void, [], TParentArgs, any, any, false>;
168
-
169
- export type PadroneCommand<
170
- TName extends string = string,
171
- TParentName extends string = '',
172
- TArgs extends PadroneSchema = PadroneSchema<DefaultArgs>,
173
- TRes = void,
174
- TCommands extends [...AnyPadroneCommand[]] = [],
175
- TAliases extends string[] = string[],
176
- TConfig extends PadroneSchema<unknown, StandardSchemaV1.InferInput<TArgs>> = PadroneSchema<void>,
177
- TEnv extends PadroneSchema<unknown, StandardSchemaV1.InferInput<TArgs>> = PadroneSchema<void>,
178
- TAsync extends boolean = false,
179
- > = {
180
- name: TName;
181
- path: FullCommandName<TName, TParentName>;
182
- title?: string;
183
- description?: string;
184
- version?: string;
185
- /** Alternative names that can be used to invoke this command. Derived from the names passed to command(). */
186
- aliases?: TAliases;
187
- deprecated?: boolean | string;
188
- hidden?: boolean;
189
- /** Group name for organizing this command under a labeled section in help output. */
190
- group?: string;
191
- /** Whether this command performs a mutation (create, update, delete). Affects HTTP method in serve (POST-only) and MCP tool annotations (destructiveHint). */
192
- mutation?: boolean;
193
- needsApproval?: boolean | ((args: TArgs) => Promise<boolean> | boolean);
194
- autoOutput?: boolean;
195
- /** Usage examples shown in help output. Each entry is a command-line invocation string. */
196
- examples?: string[];
197
- /**
198
- * Auto-start a progress indicator when the command's execute phase begins.
199
- * - `true` — generic message based on command name.
200
- * - `string` — custom message for all states.
201
- * - `PadroneProgressConfig` — separate messages for progress, success, and error states.
202
- *
203
- * The indicator is automatically stopped on success (`.succeed()`) or failure (`.fail()`).
204
- * Requires a `progress` factory on the runtime — silently skipped if not available.
205
- */
206
- progress?: boolean | string | PadroneProgressPrefs;
207
- argsSchema?: TArgs;
208
- configSchema?: TConfig;
209
- envSchema?: TEnv;
210
- meta?: GetArgsMeta<TArgs>;
211
- action?: (args: StandardSchemaV1.InferOutput<TArgs>, ctx: PadroneActionContext) => TRes;
212
- /** List of possible config file names to search for. */
213
- configFiles?: string[];
214
- /** Runtime flag indicating this command uses async validation. Set by `.async()` or `asyncSchema()`. */
215
- isAsync?: boolean;
216
- /** Runtime configuration for I/O abstraction. */
217
- runtime?: PadroneRuntime;
218
-
219
- /** Plugins registered on this command. Collected from the parent chain at execution time. */
220
- plugins?: PadronePlugin<any, any>[];
221
-
222
- /** Update check configuration. Only used on the root program. */
223
- updateCheck?: UpdateCheckConfig;
224
-
225
- parent?: AnyPadroneCommand;
226
- commands?: TCommands;
227
-
228
- /** @deprecated Internal use only */
229
- '~types': {
230
- name: TName;
231
- parentName: TParentName;
232
- path: FullCommandName<TName, TParentName>;
233
- aliases: TAliases;
234
- argsSchema: TArgs;
235
- argsInput: StandardSchemaV1.InferInput<TArgs>;
236
- argsOutput: StandardSchemaV1.InferOutput<TArgs>;
237
- result: TRes;
238
- commands: TCommands;
239
- configSchema: TConfig;
240
- envSchema: TEnv;
241
- async: TAsync;
242
- };
243
- };
244
-
245
- export type AnyPadroneCommand = PadroneCommand<string, any, any, any, [...AnyPadroneCommand[]], string[], any, any, any>;
246
-
247
- /**
248
- * Base type for extracting command information from builder or program.
249
- * Both PadroneBuilder and PadroneProgram share this structure.
250
- */
251
- type CommandTypesBase = {
252
- '~types': {
253
- command: AnyPadroneCommand;
254
- };
255
- };
256
-
257
- /**
258
- * Configuration for a command.
259
- */
260
- /**
261
- * A progress message value: a plain string, `null` to suppress, or an object with a message and custom indicator icon.
262
- */
263
- export type PadroneProgressMessage = string | null | { message?: string | null; indicator?: string };
264
-
265
- /**
266
- * Progress indicator configuration with per-state messages and optional dynamic callbacks.
267
- *
268
- * The `success` and `error` fields accept either a static value or a callback function:
269
- * - `string` — static message.
270
- * - `null` — suppress the message entirely.
271
- * - `{ message, indicator }` — custom message with a per-call indicator icon override.
272
- * - `(result) => PadroneProgressMessage` / `(error) => PadroneProgressMessage` — dynamic from the actual result/error.
273
- */
274
- export type PadroneProgressPrefs<TRes = unknown> = {
275
- /** Message shown during async validation. Defaults to `''` (spinner only). */
276
- validation?: string;
277
- /** Message shown while the command's action is running. */
278
- progress?: string;
279
- /** Message shown when the command succeeds. `null` to suppress. Defaults to the `progress` message. */
280
- success?: PadroneProgressMessage | ((result: TRes) => PadroneProgressMessage);
281
- /** Message shown when the command fails. `null` to suppress. Defaults to the error message. */
282
- error?: PadroneProgressMessage | ((error: unknown) => PadroneProgressMessage);
283
- /** Spinner configuration: a preset name, custom frames/interval, or `false` to disable. */
284
- spinner?: PadroneSpinnerConfig;
285
- };
286
-
287
- export type PadroneCommandConfig = {
288
- /** A short title for the command, displayed in help. */
289
- title?: string;
290
- /** A longer description of what the command does. */
291
- description?: string;
292
- /** The version of the command. */
293
- version?: string;
294
- /** Whether the command is deprecated, or a message explaining the deprecation. */
295
- deprecated?: boolean | string;
296
- /** Whether the command should be hidden from help output. */
297
- hidden?: boolean;
298
- /** Group name for organizing this command under a labeled section in help output. */
299
- group?: string;
300
- /**
301
- * Automatically write this command's return value to output in CLI/eval/REPL mode.
302
- * Overrides the `autoOutput` setting in eval/cli preferences for this command.
303
- * See `PadroneEvalPreferences.autoOutput` for serialization details.
304
- */
305
- autoOutput?: boolean;
306
- /** Usage examples shown in help output. Each entry is a command-line invocation string. */
307
- examples?: string[];
308
- /**
309
- * Whether this command performs a mutation (create, update, delete).
310
- * - In `serve()`: mutation commands accept POST only; non-mutation commands accept GET and POST.
311
- * - In `mcp()`: sets `annotations.destructiveHint` on the tool definition.
312
- * - In `tool()`: defaults `needsApproval` to `true` when not explicitly set.
313
- */
314
- mutation?: boolean;
315
- };
316
-
317
- /**
318
- * Conditional type that returns either PadroneBuilder or PadroneProgram based on TReturn.
319
- * Used to avoid repetition in PadroneBuilderMethods return types.
320
- */
321
- type BuilderOrProgram<
322
- TReturn extends 'builder' | 'program',
323
- TProgramName extends string,
324
- TName extends string,
325
- TParentName extends string,
326
- TArgs extends PadroneSchema,
327
- TRes,
328
- TCommands extends [...AnyPadroneCommand[]],
329
- TParentArgs extends PadroneSchema,
330
- TConfig extends PadroneSchema<unknown, StandardSchemaV1.InferInput<TArgs>>,
331
- TEnv extends PadroneSchema<unknown, StandardSchemaV1.InferInput<TArgs>>,
332
- TAsync extends boolean,
333
- > = TReturn extends 'builder'
334
- ? PadroneBuilder<TProgramName, TName, TParentName, TArgs, TRes, TCommands, TParentArgs, TConfig, TEnv, TAsync>
335
- : PadroneProgram<TProgramName, TName, TParentName, TArgs, TRes, TCommands, TParentArgs, TConfig, TEnv, TAsync>;
336
-
337
- /**
338
- * Base builder methods shared between PadroneBuilder and PadroneProgram.
339
- * These methods are used for defining command structure (arguments, config, env, action, subcommands).
340
- */
341
- export type PadroneBuilderMethods<
342
- TProgramName extends string,
343
- TName extends string,
344
- TParentName extends string,
345
- TArgs extends PadroneSchema,
346
- TRes,
347
- TCommands extends [...AnyPadroneCommand[]],
348
- TParentArgs extends PadroneSchema,
349
- TConfig extends PadroneSchema<unknown, StandardSchemaV1.InferInput<TArgs>>,
350
- TEnv extends PadroneSchema<unknown, StandardSchemaV1.InferInput<TArgs>>,
351
- TAsync extends boolean,
352
- /** The return type for builder methods - either PadroneBuilder or PadroneProgram */
353
- TReturn extends 'builder' | 'program',
354
- > = {
355
- /**
356
- * Enables automatic update checking against a package registry.
357
- * When enabled, the program checks for a newer version in the background
358
- * and displays a notification after command output if an update is available.
359
- *
360
- * - Non-blocking: check runs in background, never delays command execution.
361
- * - Non-intrusive: shows a one-line notice after command output, not before.
362
- * - Respects CI: disabled when `CI=true` or non-TTY.
363
- * - Respects user preference: `--no-update-check` flag or env var.
364
- * - Caches last check timestamp to avoid hitting the registry on every invocation.
365
- *
366
- * @example
367
- * ```ts
368
- * createPadrone('myapp')
369
- * .version('1.2.3')
370
- * .updateCheck({
371
- * registry: 'npm', // or custom URL
372
- * interval: '1d', // check at most once per day
373
- * cache: '~/.myapp-update' // where to store last check
374
- * })
375
- * ```
376
- */
377
- updateCheck: (
378
- config?: UpdateCheckConfig,
379
- ) => BuilderOrProgram<TReturn, TProgramName, TName, TParentName, TArgs, TRes, TCommands, TParentArgs, TConfig, TEnv, TAsync>;
380
-
381
- /**
382
- * Registers a plugin that intercepts command execution phases (parse, validate, execute).
383
- * Plugins are applied in order: first registered = outermost wrapper (runs first before `next()`).
384
- * Use `plugin.order` for explicit ordering (lower = outermost).
385
- *
386
- * On the program, parse/validate/execute plugins all apply.
387
- * On subcommands, only validate and execute plugins apply (parse is handled by the root program).
388
- */
389
- use: (
390
- plugin: PadronePlugin<StandardSchemaV1.InferOutput<TArgs>, TRes>,
391
- ) => BuilderOrProgram<TReturn, TProgramName, TName, TParentName, TArgs, TRes, TCommands, TParentArgs, TConfig, TEnv, TAsync>;
392
-
393
- configure: (
394
- config: PadroneCommandConfig,
395
- ) => BuilderOrProgram<TReturn, TProgramName, TName, TParentName, TArgs, TRes, TCommands, TParentArgs, TConfig, TEnv, TAsync>;
396
-
397
- /**
398
- * Configures the runtime adapter for I/O abstraction.
399
- * Allows the CLI framework to work outside of a terminal (e.g., web UIs, chat interfaces, testing).
400
- * Unspecified fields fall back to the Node.js/Bun defaults.
401
- *
402
- * @example
403
- * ```ts
404
- * .runtime({
405
- * output: (text) => panel.append(text),
406
- * error: (text) => panel.appendError(text),
407
- * format: 'html',
408
- * })
409
- * ```
410
- */
411
- runtime: (
412
- runtime: PadroneRuntime,
413
- ) => BuilderOrProgram<TReturn, TProgramName, TName, TParentName, TArgs, TRes, TCommands, TParentArgs, TConfig, TEnv, TAsync>;
414
-
415
- /**
416
- * Explicitly marks this command as using async validation.
417
- * When a command is async, `parse()` and `cli()` return Promises.
418
- *
419
- * This is an alternative to using `asyncSchema()` on individual schemas.
420
- * Use this when your schema has async refinements but you don't want to
421
- * (or can't) brand the schema itself.
422
- *
423
- * @example
424
- * ```ts
425
- * .arguments(z.object({ name: z.string() }).check(async (v) => { ... }))
426
- * .async()
427
- * .action((args) => { ... })
428
- * ```
429
- */
430
- async: () => BuilderOrProgram<TReturn, TProgramName, TName, TParentName, TArgs, TRes, TCommands, TParentArgs, TConfig, TEnv, true>;
431
-
432
- /**
433
- * Defines the arguments schema for the command, including positional arguments.
434
- * Can accept either a schema directly or a function that takes parent args schema as a base and returns a schema.
435
- * Use the `positional` array in meta to specify which arguments are positional args.
436
- * Use '...name' prefix for variadic (rest) arguments, matching JS/TS rest syntax.
437
- *
438
- * @example
439
- * ```ts
440
- * // Direct schema
441
- * .arguments(z.object({
442
- * source: z.string(),
443
- * files: z.string().array(),
444
- * dest: z.string(),
445
- * recursive: z.boolean().default(false),
446
- * }), {
447
- * positional: ['source', '...files', 'dest'],
448
- * })
449
- * ```
450
- *
451
- * @example
452
- * ```ts
453
- * // Function-based schema extending parent arguments
454
- * .arguments((parentArgs) => {
455
- * return z.object({
456
- * ...parentArgs.shape,
457
- * verbose: z.boolean().default(false),
458
- * });
459
- * })
460
- * ```
461
- */
462
- arguments: <TNewArgs extends PadroneSchema = PadroneSchema<void>, TMeta extends GetArgsMeta<TNewArgs> = GetArgsMeta<TNewArgs>>(
463
- schema?: TNewArgs | ((parentSchema: TParentArgs) => TNewArgs),
464
- meta?: TMeta,
465
- ) => BuilderOrProgram<
466
- TReturn,
467
- TProgramName,
468
- TName,
469
- TParentName,
470
- TNewArgs,
471
- TRes,
472
- TCommands,
473
- TParentArgs,
474
- TConfig,
475
- TEnv,
476
- OrAsyncMeta<OrAsync<TAsync, TNewArgs>, TMeta>
477
- >;
478
-
479
- /**
480
- * Configures config file path(s) and schema for parsing config files.
481
- * @example
482
- * ```ts
483
- * .configFile('config.json', z.object({ port: z.number() }))
484
- * ```
485
- */
486
- configFile: <TNewConfig extends PadroneSchema<unknown, StandardSchemaV1.InferInput<TArgs>> = TArgs>(
487
- file: string | string[] | undefined,
488
- schema?: TNewConfig | ((argsSchema: TArgs) => TNewConfig),
489
- ) => BuilderOrProgram<
490
- TReturn,
491
- TProgramName,
492
- TName,
493
- TParentName,
494
- TArgs,
495
- TRes,
496
- TCommands,
497
- TParentArgs,
498
- TNewConfig,
499
- TEnv,
500
- OrAsync<TAsync, TNewConfig>
501
- >;
502
-
503
- /**
504
- * Configures environment variable schema for parsing env vars into arguments.
505
- * The schema should transform environment variables (typically SCREAMING_SNAKE_CASE)
506
- * into the argument names used by the command.
507
- * @example
508
- * ```ts
509
- * .env(z.object({ MY_APP_PORT: z.coerce.number() }).transform(e => ({ port: e.MY_APP_PORT })))
510
- * ```
511
- */
512
- env: <TNewEnv extends PadroneSchema<unknown, StandardSchemaV1.InferInput<TArgs>> = TArgs>(
513
- schema: TNewEnv | ((argsSchema: TArgs) => TNewEnv),
514
- ) => BuilderOrProgram<
515
- TReturn,
516
- TProgramName,
517
- TName,
518
- TParentName,
519
- TArgs,
520
- TRes,
521
- TCommands,
522
- TParentArgs,
523
- TConfig,
524
- TNewEnv,
525
- OrAsync<TAsync, TNewEnv>
526
- >;
527
-
528
- /**
529
- * Configures an auto-managed progress indicator for this command.
530
- * The indicator starts before validation and is automatically stopped on success or failure.
531
- *
532
- * - `true` — generic message based on command name.
533
- * - `string` — custom message for all states.
534
- * - `PadroneProgressConfig` — full control: per-state messages, dynamic callbacks, spinner config.
535
- *
536
- * Requires a `progress` factory on the runtime — silently skipped if not available.
537
- *
538
- * @example
539
- * ```ts
540
- * .progress('Deploying...')
541
- * .progress({
542
- * progress: 'Deploying...',
543
- * success: (result) => `Deployed ${result.version}`,
544
- * error: (err) => `Deploy failed: ${err.message}`,
545
- * spinner: 'line',
546
- * })
547
- * ```
548
- */
549
- progress: (
550
- config?: boolean | string | PadroneProgressPrefs<Awaited<TRes>>,
551
- ) => BuilderOrProgram<TReturn, TProgramName, TName, TParentName, TArgs, TRes, TCommands, TParentArgs, TConfig, TEnv, TAsync>;
552
-
553
- /**
554
- * Defines the handler function to be executed when the command is run.
555
- * When overriding an existing command, the previous handler is passed as the third `base` parameter.
556
- */
557
- action: <TNewRes>(
558
- handler?: (
559
- args: StandardSchemaV1.InferOutput<TArgs>,
560
- ctx: PadroneActionContext,
561
- base: (args: StandardSchemaV1.InferOutput<TArgs>, ctx: PadroneActionContext) => TRes,
562
- ) => TNewRes,
563
- ) => BuilderOrProgram<TReturn, TProgramName, TName, TParentName, TArgs, TNewRes, TCommands, TParentArgs, TConfig, TEnv, TAsync>;
564
-
565
- /**
566
- * Wraps an external CLI tool with optional schema transformation.
567
- * The config can include a schema that transforms command arguments to external CLI arguments.
568
- *
569
- * @experimental This API is experimental and may change in future releases.
570
- *
571
- * @example
572
- * ```ts
573
- * // No transformation - pass arguments as-is
574
- * .arguments(z.object({
575
- * message: z.string(),
576
- * }))
577
- * .wrap({
578
- * command: 'echo',
579
- * })
580
- * ```
581
- *
582
- * @example
583
- * ```ts
584
- * // With transformation schema
585
- * .arguments(z.object({
586
- * message: z.string(),
587
- * all: z.boolean().optional(),
588
- * }), {
589
- * positional: ['message'],
590
- * })
591
- * .wrap({
592
- * command: 'git',
593
- * args: ['commit'],
594
- * positional: ['m'],
595
- * schema: z.object({
596
- * message: z.string(),
597
- * all: z.boolean().optional(),
598
- * }).transform(args => ({
599
- * m: args.message,
600
- * a: args.all,
601
- * })),
602
- * })
603
- * ```
604
- *
605
- * @example
606
- * ```ts
607
- * // Using function-based schema for type inference
608
- * .arguments(z.object({
609
- * image: z.string(),
610
- * detach: z.boolean().optional(),
611
- * }))
612
- * .wrap({
613
- * command: 'docker',
614
- * args: ['run'],
615
- * positional: ['image'],
616
- * schema: (schema) => schema.transform(args => ({
617
- * d: args.detach,
618
- * image: args.image,
619
- * })),
620
- * })
621
- * ```
622
- */
623
- wrap: <TWrapArgs extends PadroneSchema = TArgs>(
624
- config: WrapConfig<TArgs, TWrapArgs>,
625
- ) => BuilderOrProgram<
626
- TReturn,
627
- TProgramName,
628
- TName,
629
- TParentName,
630
- TArgs,
631
- Promise<WrapResult>,
632
- TCommands,
633
- TParentArgs,
634
- TConfig,
635
- TEnv,
636
- TAsync
637
- >;
638
-
639
- /**
640
- * Creates or extends a nested command within the current command.
641
- * If a command with the same name already exists, it is extended:
642
- * - Configuration is merged (new values override old).
643
- * - The builder callback receives a builder pre-populated with the existing command's state.
644
- * - `.action()` receives the previous handler as the third `base` parameter.
645
- * - `.arguments()` callback receives the existing schema as its parameter.
646
- * - Subcommands are recursively merged by name.
647
- *
648
- * @example
649
- * ```ts
650
- * // Fresh command
651
- * .command('list', (c) => c.action(() => 'list'))
652
- *
653
- * // Override — extend an existing command
654
- * .command('list', (c) => c.action((args, ctx, base) => {
655
- * const original = base(args, ctx);
656
- * return `modified: ${original}`;
657
- * }))
658
- *
659
- * // Name with aliases
660
- * .command(['list', 'ls', 'l'], (c) => c.action(() => 'list'))
661
- * ```
662
- */
663
- command: <
664
- TNameNested extends string,
665
- TAliases extends string[] = [],
666
- TBuilder extends CommandTypesBase = DefaultCommandBuilder<
667
- TProgramName,
668
- TNameNested,
669
- FullCommandName<TName, TParentName>,
670
- TArgs,
671
- TCommands
672
- >,
673
- >(
674
- name: TNameNested | readonly [TNameNested, ...TAliases],
675
- builderFn?: (
676
- builder: InitialCommandBuilder<TProgramName, TNameNested, FullCommandName<TName, TParentName>, TArgs, TCommands>,
677
- ) => TBuilder,
678
- ) => BuilderOrProgram<
679
- TReturn,
680
- TProgramName,
681
- TName,
682
- TParentName,
683
- TArgs,
684
- TRes,
685
- TCommands extends []
686
- ? [WithAliases<TBuilder['~types']['command'], TAliases>]
687
- : AnyPadroneCommand[] extends TCommands
688
- ? [WithAliases<TBuilder['~types']['command'], TAliases>]
689
- : ReplaceOrAppendCommand<
690
- TCommands,
691
- TNameNested,
692
- WithAliases<TBuilder['~types']['command'], ResolvedAliases<TCommands, TNameNested, TAliases>>
693
- >,
694
- TParentArgs,
695
- TConfig,
696
- TEnv,
697
- TAsync
698
- >;
699
-
700
- /**
701
- * Mounts an existing Padrone program as a subcommand.
702
- * The program's root-level properties (name, path, parent) are replaced to fit the mount point.
703
- * All subcommands are recursively re-pathed. Root-level `version` is dropped.
704
- *
705
- * @example
706
- * ```ts
707
- * const admin = createPadrone('admin')
708
- * .command('users', (c) => c.action(() => 'users'))
709
- * .command('roles', (c) => c.action(() => 'roles'));
710
- *
711
- * const app = createPadrone('app')
712
- * .mount('admin', admin)
713
- * // Now: app admin users, app admin roles
714
- *
715
- * // With aliases
716
- * const app2 = createPadrone('app')
717
- * .mount(['admin', 'adm'], admin)
718
- * ```
719
- */
720
- mount: <TNameNested extends string, TAliases extends string[] = [], TProgram extends CommandTypesBase = CommandTypesBase>(
721
- name: TNameNested | readonly [TNameNested, ...TAliases],
722
- program: TProgram,
723
- ) => BuilderOrProgram<
724
- TReturn,
725
- TProgramName,
726
- TName,
727
- TParentName,
728
- TArgs,
729
- TRes,
730
- TCommands extends []
731
- ? [
732
- WithAliases<
733
- PadroneCommand<
734
- TNameNested,
735
- FullCommandName<TName, TParentName>,
736
- TProgram['~types']['command']['~types']['argsSchema'],
737
- TProgram['~types']['command']['~types']['result'],
738
- RepathCommands<
739
- TProgram['~types']['command']['~types']['commands'],
740
- FullCommandName<TNameNested, FullCommandName<TName, TParentName>>
741
- >,
742
- [],
743
- TProgram['~types']['command']['~types']['configSchema'],
744
- TProgram['~types']['command']['~types']['envSchema'],
745
- TProgram['~types']['command']['~types']['async']
746
- >,
747
- TAliases
748
- >,
749
- ]
750
- : AnyPadroneCommand[] extends TCommands
751
- ? [
752
- WithAliases<
753
- PadroneCommand<
754
- TNameNested,
755
- FullCommandName<TName, TParentName>,
756
- TProgram['~types']['command']['~types']['argsSchema'],
757
- TProgram['~types']['command']['~types']['result'],
758
- RepathCommands<
759
- TProgram['~types']['command']['~types']['commands'],
760
- FullCommandName<TNameNested, FullCommandName<TName, TParentName>>
761
- >,
762
- [],
763
- TProgram['~types']['command']['~types']['configSchema'],
764
- TProgram['~types']['command']['~types']['envSchema'],
765
- TProgram['~types']['command']['~types']['async']
766
- >,
767
- TAliases
768
- >,
769
- ]
770
- : ReplaceOrAppendCommand<
771
- TCommands,
772
- TNameNested,
773
- WithAliases<
774
- PadroneCommand<
775
- TNameNested,
776
- FullCommandName<TName, TParentName>,
777
- TProgram['~types']['command']['~types']['argsSchema'],
778
- TProgram['~types']['command']['~types']['result'],
779
- RepathCommands<
780
- TProgram['~types']['command']['~types']['commands'],
781
- FullCommandName<TNameNested, FullCommandName<TName, TParentName>>
782
- >,
783
- [],
784
- TProgram['~types']['command']['~types']['configSchema'],
785
- TProgram['~types']['command']['~types']['envSchema'],
786
- TProgram['~types']['command']['~types']['async']
787
- >,
788
- ResolvedAliases<TCommands, TNameNested, TAliases>
789
- >
790
- >,
791
- TParentArgs,
792
- TConfig,
793
- TEnv,
794
- TAsync
795
- >;
796
-
797
- /** @deprecated Internal use only */
798
- '~types': {
799
- programName: TProgramName;
800
- name: TName;
801
- parentName: TParentName;
802
- path: FullCommandName<TName, TParentName>;
803
- aliases: [];
804
- argsSchema: TArgs;
805
- result: TRes;
806
- commands: TCommands;
807
- async: TAsync;
808
- command: PadroneCommand<TName, TParentName, TArgs, TRes, TCommands, [], TConfig, TEnv, TAsync>;
809
- };
810
- };
811
-
812
- export type PadroneBuilder<
813
- TProgramName extends string = '',
814
- TName extends string = string,
815
- TParentName extends string = '',
816
- TArgs extends PadroneSchema = PadroneSchema<DefaultArgs>,
817
- TRes = void,
818
- TCommands extends [...AnyPadroneCommand[]] = [],
819
- TParentArgs extends PadroneSchema = PadroneSchema<void>,
820
- TConfig extends PadroneSchema<unknown, StandardSchemaV1.InferInput<TArgs>> = PadroneSchema<void>,
821
- TEnv extends PadroneSchema<unknown, StandardSchemaV1.InferInput<TArgs>> = PadroneSchema<void>,
822
- TAsync extends boolean = false,
823
- > = PadroneBuilderMethods<TProgramName, TName, TParentName, TArgs, TRes, TCommands, TParentArgs, TConfig, TEnv, TAsync, 'builder'>;
824
-
825
- export type PadroneProgram<
826
- TProgramName extends string = '',
827
- TName extends string = string,
828
- TParentName extends string = '',
829
- TArgs extends PadroneSchema = PadroneSchema<DefaultArgs>,
830
- TRes = void,
831
- TCommands extends [...AnyPadroneCommand[]] = [],
832
- TParentArgs extends PadroneSchema = PadroneSchema<void>,
833
- TConfig extends PadroneSchema<unknown, StandardSchemaV1.InferInput<TArgs>> = PadroneSchema<void>,
834
- TEnv extends PadroneSchema<unknown, StandardSchemaV1.InferInput<TArgs>> = PadroneSchema<void>,
835
- TAsync extends boolean = false,
836
- > = PadroneBuilderMethods<TProgramName, TName, TParentName, TArgs, TRes, TCommands, TParentArgs, TConfig, TEnv, TAsync, 'program'> & {
837
- /**
838
- * Runs a command programmatically by name with provided arguments (including positional args).
839
- */
840
- run: <const TCommand extends PossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], true, true>>(
841
- name: TCommand | SafeString,
842
- args: NoInfer<GetArguments<'in', PickCommandByName<[PadroneCommand<'', '', TArgs, TRes, TCommands>], TCommand>>>,
843
- ) => PadroneCommandResult<PickCommandByName<[PadroneCommand<'', '', TArgs, TRes, TCommands>], TCommand>>;
844
-
845
- /**
846
- * Evaluates a command string: parses, validates, and executes.
847
- * On validation errors, returns a result with issues instead of throwing.
848
- * This is the method used by `repl()` internally, and the right choice for
849
- * programmatic invocation, testing, chat interfaces, or any context where
850
- * you have a command string and want a result — not a process exit.
851
- *
852
- * @example
853
- * ```ts
854
- * const result = await program.eval('greet --name Alice');
855
- * if (result.argsResult?.issues) { /* handle validation errors *\/ }
856
- * ```
857
- */
858
- eval: <const TCommand extends PossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], true, true>>(
859
- input: TCommand | SafeString,
860
- prefs?: PadroneEvalPreferences,
861
- ) => MaybePromiseCommandResult<
862
- PickCommandByPossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], TCommand>,
863
- PickCommandByPossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], TCommand>['~types']['async']
864
- >;
865
-
866
- /**
867
- * Runs the program as a CLI entry point, parsing `process.argv`.
868
- * On validation errors, throws and prints help.
869
- * For programmatic invocation with a command string, use `eval()` instead.
870
- */
871
- cli: (
872
- prefs?: PadroneCliPreferences<PossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>]>>,
873
- ) => MaybePromiseCommandResult<FlattenCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>]>, TAsync>;
874
-
875
- /**
876
- * Parses CLI input (or the provided input string) into command and arguments without executing anything.
877
- */
878
- parse: <const TCommand extends PossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], true, false>>(
879
- input?: TCommand | SafeString,
880
- ) => MaybePromise<
881
- PadroneParseResult<PickCommandByPossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], TCommand>>,
882
- PickCommandByPossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], TCommand>['~types']['async']
883
- >;
884
-
885
- /**
886
- * Converts command and arguments back into a CLI string.
887
- */
888
- stringify: <const TCommand extends PossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], false, true>>(
889
- command?: TCommand | SafeString,
890
- args?: GetArguments<'out', PickCommandByPossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], TCommand>>,
891
- ) => string;
892
-
893
- /**
894
- * Finds a command by name, returning `undefined` if not found.
895
- */
896
- find: <const TFind extends PossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], false, true>>(
897
- command: TFind | SafeString,
898
- ) => PickCommandByPossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], TFind> | undefined;
899
-
900
- /**
901
- * Generates a type-safe API for invoking commands programmatically.
902
- */
903
- api: () => PadroneAPI<PadroneCommand<'', '', TArgs, TRes, TCommands>>;
904
-
905
- /**
906
- * Starts a REPL (Read-Eval-Print Loop) for running commands interactively.
907
- * Returns an AsyncIterable that yields a `PadroneCommandResult` for each successfully executed command.
908
- * Errors are printed via `runtime.error()` and the loop continues.
909
- * The loop ends when the user sends EOF (Ctrl+D), types `.exit`/`.quit`,
910
- * or presses Ctrl+C twice within 2 seconds.
911
- *
912
- * @example
913
- * ```ts
914
- * for await (const result of program.repl()) {
915
- * console.log(result.command.name, result.result);
916
- * }
917
- * ```
918
- *
919
- * TODO: REPL future enhancements:
920
- * - History persistence: save/load history across sessions (currently in-memory only)
921
- * - Middleware/hooks: onBeforeCommand, onAfterCommand, error interceptors (design alongside general middleware system)
922
- */
923
- repl: (options?: PadroneReplPreferences<PossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>]>>) => AsyncIterable<
924
- PadroneCommandResult<FlattenCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>]>>
925
- > & {
926
- drain: () => Promise<PadroneDrainResult<PadroneCommandResult<FlattenCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>]>>[]>>;
927
- };
928
-
929
- /**
930
- * Returns a tool definition that can be passed to AI SDK.
931
- */
932
- tool: () => Tool<{ command: string }>;
933
-
934
- /**
935
- * Returns the help information for the program or a specific command.
936
- */
937
- help: <const TCommand extends PossibleCommands<[PadroneCommand<'', '', TArgs, TRes, TCommands>], false, true>>(
938
- command?: TCommand,
939
- prefs?: HelpPreferences,
940
- ) => string;
941
-
942
- /**
943
- * Generates and returns a shell completion script.
944
- * If shell is not specified, automatically detects the current shell and provides instructions.
945
- * @param shell - The shell type (bash, zsh, fish, powershell). If not provided, auto-detects.
946
- * @returns The shell completion script as a string.
947
- * @example
948
- * ```ts
949
- * // Get bash completion script
950
- * const bashScript = program.completion('bash');
951
- *
952
- * // Auto-detect shell and get completion script with instructions
953
- * const script = program.completion();
954
- * ```
955
- */
956
- completion: (shell?: 'bash' | 'zsh' | 'fish' | 'powershell') => Promise<string>;
957
-
958
- /**
959
- * Starts a Model Context Protocol (MCP) server that exposes commands as tools for AI assistants.
960
- * Communicates over stdio using JSON-RPC with Content-Length framing.
961
- * Returns a Promise that resolves when the connection closes.
962
- *
963
- * @experimental This API is experimental and may change in future releases.
964
- *
965
- * @example
966
- * ```ts
967
- * await program.mcp();
968
- * ```
969
- */
970
- mcp: (prefs?: PadroneMcpPreferences) => Promise<void>;
971
-
972
- /**
973
- * Starts a REST HTTP server that exposes commands as endpoints.
974
- * Each command becomes a route: `users list` → `GET/POST /users/list`.
975
- * Commands with `mutation: true` only accept POST.
976
- *
977
- * @experimental This API is experimental and may change in future releases.
978
- *
979
- * @example
980
- * ```ts
981
- * await program.serve({ port: 3000 });
982
- * ```
983
- */
984
- serve: (prefs?: PadroneServePreferences) => Promise<void>;
985
- };
986
-
987
- export type AnyPadroneProgram = PadroneProgram<string, string, string, any, any, [...AnyPadroneCommand[]]>;
988
-
989
- /**
990
- * Options for `repl()` to customize the REPL session.
991
- */
992
- /** A single spacing value: blank line (`true`), separator string, or an array of these for multiple lines. */
993
- export type PadroneReplSpacing = boolean | string | (boolean | string)[];
994
-
995
- export type PadroneReplPreferences<TScope extends string = string> = {
996
- /** The prompt string displayed before each input, or a function returning it. Defaults to `"<programName>> "`. */
997
- prompt?: string | (() => string);
998
- /**
999
- * A greeting message displayed when the REPL starts.
1000
- * When not provided, defaults to `"Welcome to <name> v<version>"` (or just `"Welcome to <name>"` if no version).
1001
- * Set to `false` to suppress the default greeting entirely.
1002
- */
1003
- greeting?: string | false;
1004
- /**
1005
- * A hint message displayed below the greeting in dimmed text.
1006
- * When not provided, defaults to `'Type ".help" for more information, ".exit" to quit.'`.
1007
- * Set to `false` to suppress the hint.
1008
- */
1009
- hint?: string | false;
1010
- /** Initial history entries (most recent last). Arrow keys navigate history in the terminal. */
1011
- history?: string[];
1012
- /** Set to `false` to disable tab completion. Defaults to `true`. */
1013
- completion?: boolean;
1014
- /**
1015
- * Add spacing/separators around each command's output.
1016
- * A spacing value can be:
1017
- * - `true` — blank line
1018
- * - A string — separator line (single char like `'─'` repeats to terminal width, multi-char prints as-is)
1019
- * - An array of the above — multiple lines in order (e.g. `[true, '─']` for blank line then separator)
1020
- *
1021
- * Shorthand applies to both before and after. Use `{ before?, after? }` for independent control.
1022
- */
1023
- spacing?: PadroneReplSpacing | { before?: PadroneReplSpacing; after?: PadroneReplSpacing };
1024
- /** Prefix each line of command output/error with this string (e.g. `'│ '`, `' '`, `'▎ '`). */
1025
- outputPrefix?: string;
1026
- /**
1027
- * Start the REPL scoped to a command subtree. The scope path is a space-separated command path
1028
- * (e.g. `'db'` or `'db migrate'`). Commands are resolved relative to the scoped command.
1029
- * Users can change scope at runtime with `.scope <subcommand>` and `.scope ..`/`..`.
1030
- */
1031
- scope?: TScope;
1032
-
1033
- /**
1034
- * Automatically write each command's return value to output.
1035
- * See `PadroneEvalPreferences.autoOutput` for details on how values are serialized.
1036
- * Defaults to `true`.
1037
- */
1038
- autoOutput?: boolean;
1039
- };
1040
-
1041
- /**
1042
- * Options that can be passed to `eval()` to control execution behavior.
1043
- */
1044
- export type PadroneEvalPreferences = {
1045
- /**
1046
- * Controls interactive prompting for this execution.
1047
- * Overrides the runtime's `interactive` setting, but is itself overridden by `--interactive` / `-i` flags.
1048
- *
1049
- * - `undefined`: inherit from runtime (default).
1050
- * - `true`: force prompting for all configured interactive fields, even if values are already provided.
1051
- * - `false`: suppress all interactive prompts.
1052
- */
1053
- interactive?: boolean;
1054
-
1055
- /**
1056
- * Automatically write the command's return value to output.
1057
- *
1058
- * - Values are passed directly to the runtime's `output` function (no stringification).
1059
- * - Promises are awaited before output.
1060
- * - Iterators and async iterators are consumed, outputting each yielded value as it arrives.
1061
- * - `undefined` and `null` results produce no output.
1062
- *
1063
- * Defaults to `true`. Set to `false` to disable.
1064
- */
1065
- autoOutput?: boolean;
1066
-
1067
- /**
1068
- * Override the runtime for this execution.
1069
- * Partial — only the provided fields replace the command's resolved runtime.
1070
- * Useful for capturing output, injecting test doubles, or running in non-terminal contexts (e.g. AI tool calls).
1071
- */
1072
- runtime?: PadroneRuntime;
1073
- };
1074
-
1075
- /**
1076
- * Options that can be passed to `cli()` to control execution behavior.
1077
- */
1078
- export type PadroneCliPreferences<TScope extends string = string> = PadroneEvalPreferences & {
1079
- /** REPL preferences used when `--repl` flag is passed. Set to `false` to disable the `--repl` flag. */
1080
- repl?: PadroneReplPreferences<TScope> | false;
1081
- /** MCP server preferences used when `mcp` command is used. Set to `false` to disable. */
1082
- mcp?: PadroneMcpPreferences | false;
1083
- /** REST server preferences used when `serve` command is used. Set to `false` to disable. */
1084
- serve?: PadroneServePreferences | false;
1085
- };
1086
-
1087
- /**
1088
- * Result of `drain()` — a discriminated union that never throws.
1089
- * On success, `value` holds the fully resolved/collected result; on failure, `error` holds the error.
1090
- */
1091
- export type PadroneDrainResult<TResult> = { value: Drained<TResult>; error?: never } | { error: unknown; value?: never };
1092
-
1093
- /**
1094
- * Result returned by `eval()`, `cli()`, and `run()`. Never thrown — errors are captured in the `error` field.
1095
- * Discriminated union: check `error` to distinguish success from failure.
1096
- *
1097
- * On success: `command`, `args`, `argsResult`, `result` are populated; `error` is absent.
1098
- * On failure: `error` is populated; `command` may be present if routing succeeded.
1099
- */
1100
- export type PadroneCommandResult<TCommand extends AnyPadroneCommand = AnyPadroneCommand> =
1101
- | (PadroneParseResult<TCommand> & {
1102
- result: GetResults<TCommand>;
1103
- error?: never;
1104
- /** Flattens the result: awaits Promises, collects iterables, catches errors. Never throws. */
1105
- drain: () => Promise<PadroneDrainResult<GetResults<TCommand>>>;
1106
- })
1107
- | {
1108
- command?: TCommand;
1109
- args?: GetArguments<'out', TCommand>;
1110
- argsResult?: StandardSchemaV1.Result<GetArguments<'out', TCommand>>;
1111
- error: unknown;
1112
- result?: never;
1113
- /** Returns `{ error }` since there is no result to drain. */
1114
- drain: () => Promise<PadroneDrainResult<GetResults<TCommand>>>;
1115
- };
1116
-
1117
- /**
1118
- * Like `MaybePromise<PadroneCommandResult<TCommand>, TAsync>` but ensures `drain()` is available
1119
- * at the outer level in all cases — both sync (Thenable) and async (Promise).
1120
- */
1121
- type MaybePromiseCommandResult<TCommand extends AnyPadroneCommand, TAsync> = MaybePromise<PadroneCommandResult<TCommand>, TAsync> & {
1122
- drain: () => Promise<PadroneDrainResult<GetResults<TCommand>>>;
1123
- };
1124
-
1125
- export type PadroneParseResult<TCommand extends AnyPadroneCommand = AnyPadroneCommand> = {
1126
- command: TCommand;
1127
- args?: GetArguments<'out', TCommand>;
1128
- argsResult?: StandardSchemaV1.Result<GetArguments<'out', TCommand>>;
1129
- };
1130
-
1131
- export type PadroneAPI<TCommand extends AnyPadroneCommand> = PadroneAPICommand<TCommand> & {
1132
- [K in TCommand['~types']['commands'][number] as K['name']]: PadroneAPI<K>;
1133
- };
1134
-
1135
- type PadroneAPICommand<TCommand extends AnyPadroneCommand> = (args: GetArguments<'in', TCommand>) => GetResults<TCommand>;
1136
-
1137
- type NormalizeArguments<TArgs> = IsGeneric<TArgs> extends true ? void | EmptyRecord : TArgs;
1138
- type GetArguments<TDir extends 'in' | 'out', TCommand extends AnyPadroneCommand> = TDir extends 'in'
1139
- ? NormalizeArguments<TCommand['~types']['argsInput']>
1140
- : NormalizeArguments<TCommand['~types']['argsOutput']>;
1141
-
1142
- type GetResults<TCommand extends AnyPadroneCommand> = ReturnType<NonNullable<TCommand['action']>>;
1143
-
1144
- type GetArgsMeta<TArgs extends PadroneSchema> = PadroneArgsSchemaMeta<NonNullable<StandardSchemaV1.InferInput<TArgs>>>;
1145
-
1146
- // ---------------------------------------------------------------------------
1147
- // Plugin system
1148
- // ---------------------------------------------------------------------------
1149
-
1150
- /** Base context shared across all plugin phases within a single execution. */
1151
- export type PluginBaseContext = {
1152
- /** The resolved command for this execution. In the parse phase, this is the root program. */
1153
- command: AnyPadroneCommand;
1154
- /** Mutable state bag shared across phases for this execution. Plugins can store cross-phase data here. */
1155
- state: Record<string, unknown>;
1156
- };
1157
-
1158
- /** Context for the parse phase. */
1159
- export type PluginParseContext = PluginBaseContext & {
1160
- /** The raw CLI input string (undefined when invoked without input). */
1161
- input: string | undefined;
1162
- };
1163
-
1164
- /** Result returned by the parse phase's `next()`. */
1165
- export type PluginParseResult = {
1166
- command: AnyPadroneCommand;
1167
- rawArgs: Record<string, unknown>;
1168
- positionalArgs: string[];
1169
- };
1170
-
1171
- /** Context for the validate phase. */
1172
- export type PluginValidateContext = PluginBaseContext & {
1173
- /** Raw named arguments extracted by the parser. Mutable — modify before `next()` to inject/override values. */
1174
- rawArgs: Record<string, unknown>;
1175
- /** Positional argument strings extracted by the parser. */
1176
- positionalArgs: string[];
1177
- };
1178
-
1179
- /** Result returned by the validate phase's `next()`. */
1180
- export type PluginValidateResult<TArgs = unknown> = {
1181
- args: TArgs;
1182
- argsResult: StandardSchemaV1.Result<TArgs>;
1183
- };
1184
-
1185
- /** Context for the execute phase. */
1186
- export type PluginExecuteContext<TArgs = unknown> = PluginBaseContext & {
1187
- /** Validated arguments that will be passed to the action. Mutable — modify before `next()` to override. */
1188
- args: TArgs;
1189
- };
1190
-
1191
- /** Result returned by the execute phase's `next()`. */
1192
- export type PluginExecuteResult<TResult = unknown> = {
1193
- result: TResult;
1194
- };
1195
-
1196
- /** Context for the start phase. Runs before parsing, wraps the entire pipeline. */
1197
- export type PluginStartContext = PluginBaseContext & {
1198
- /** The raw CLI input string (undefined when invoked without input). */
1199
- input: string | undefined;
1200
- };
1201
-
1202
- /** Context for the error phase. Called when the pipeline throws. */
1203
- export type PluginErrorContext = PluginBaseContext & {
1204
- /** The error that was thrown. */
1205
- error: unknown;
1206
- };
1207
-
1208
- /** Result returned by the error phase's `next()`. */
1209
- export type PluginErrorResult<TResult = unknown> = {
1210
- /** The error (possibly transformed). Set to `undefined` to suppress the error. */
1211
- error?: unknown;
1212
- /** A replacement result when suppressing the error. */
1213
- result?: TResult;
1214
- };
1215
-
1216
- /** Context for the shutdown phase. Always runs after the pipeline (success or failure). */
1217
- export type PluginShutdownContext<TResult = unknown> = PluginBaseContext & {
1218
- /** The error, if the pipeline failed (after error phase processing). */
1219
- error?: unknown;
1220
- /** The pipeline result, if it succeeded. */
1221
- result?: TResult;
1222
- };
1223
-
1224
- /**
1225
- * A phase handler function for the plugin middleware chain.
1226
- *
1227
- * - `TCtx` — the context object available to the handler.
1228
- * - `TNextResult` — the typed result returned by `next()`, giving the handler type-safe access to downstream output.
1229
- * - `TReturn` — the type the handler itself returns. Defaults to `TNextResult` but can be wider,
1230
- * allowing plugins to transform or replace the result (e.g., error-recovery plugins returning a different type).
1231
- */
1232
- type PluginPhaseHandler<TCtx, TNextResult, TReturn = TNextResult> = (
1233
- ctx: TCtx,
1234
- next: () => TNextResult | Promise<TNextResult>,
1235
- ) => TReturn | Promise<TReturn>;
1236
-
1237
- /**
1238
- * A Padrone plugin that can intercept the parse, validate, and execute phases of command execution.
1239
- * Plugins are registered at the program or subcommand level with `.use()`.
1240
- *
1241
- * Type parameters:
1242
- * - `TArgs` — the validated arguments type (output of the args schema). Provides typed `ctx.args` in the execute phase
1243
- * and typed `args` in the validate result from `next()`.
1244
- * - `TResult` — the command's return type. Provides typed `result` in execute/error/shutdown phases.
1245
- *
1246
- * When registered inline on a builder, these are inferred from the command's types automatically.
1247
- * For reusable plugins that work with any command, use `PadronePlugin<any, any>`.
1248
- *
1249
- * Each phase handler receives a context and a `next()` function (onion/middleware pattern):
1250
- * - Call `next()` to proceed to the next plugin or the core operation.
1251
- * - Return without calling `next()` to short-circuit.
1252
- * - Wrap `next()` in try/catch for error handling.
1253
- * - Modify context fields before `next()` to alter inputs.
1254
- * - Transform the return value of `next()` to alter outputs.
1255
- */
1256
- export type PadronePlugin<TArgs = unknown, TResult = unknown> = {
1257
- /** Display name for this plugin. Used for identification in logs and debugging. */
1258
- name: string;
1259
- /**
1260
- * Optional unique identifier for deduplication. When multiple plugins share the same `id`,
1261
- * only the last one registered is kept. Useful for allowing downstream code to override
1262
- * a plugin without accumulating duplicates.
1263
- */
1264
- id?: string;
1265
- /**
1266
- * Ordering hint. Lower values run as outer layers (earlier before `next()`, later after).
1267
- * Plugins with the same order preserve registration order. Defaults to `0`.
1268
- */
1269
- order?: number;
1270
- /**
1271
- * Runs before the pipeline (parse → validate → execute). `next()` proceeds to the pipeline.
1272
- * Root plugins only. Use for startup tasks like telemetry, update checks, or global config loading.
1273
- */
1274
- start?: PluginPhaseHandler<PluginStartContext, unknown>;
1275
- /** Intercepts command routing and raw argument extraction. */
1276
- parse?: PluginPhaseHandler<PluginParseContext, PluginParseResult>;
1277
- /** Intercepts argument preprocessing, interactive prompting, and schema validation. */
1278
- validate?: PluginPhaseHandler<PluginValidateContext, PluginValidateResult<TArgs>, PluginValidateResult>;
1279
- /** Intercepts handler execution. */
1280
- execute?: PluginPhaseHandler<PluginExecuteContext<TArgs>, PluginExecuteResult<TResult>, PluginExecuteResult>;
1281
- /**
1282
- * Called when the pipeline throws an error. `next()` passes to the next error handler
1283
- * (innermost returns `{ error }` unchanged). Return `{ result }` without `error` to suppress.
1284
- */
1285
- error?: PluginPhaseHandler<PluginErrorContext, PluginErrorResult<TResult>, PluginErrorResult>;
1286
- /**
1287
- * Always runs after the pipeline completes (success or failure). `next()` calls the next shutdown handler.
1288
- * Use for cleanup: closing connections, flushing logs, etc.
1289
- */
1290
- shutdown?: PluginPhaseHandler<PluginShutdownContext<TResult>, void>;
1291
- };