padrone 1.4.0 → 1.5.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 (82) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/README.md +105 -284
  3. package/dist/{args-CVDbyyzG.mjs → args-D5PNDyNu.mjs} +41 -18
  4. package/dist/args-D5PNDyNu.mjs.map +1 -0
  5. package/dist/chunk-CjcI7cDX.mjs +15 -0
  6. package/dist/codegen/index.d.mts +28 -3
  7. package/dist/codegen/index.d.mts.map +1 -1
  8. package/dist/codegen/index.mjs +169 -19
  9. package/dist/codegen/index.mjs.map +1 -1
  10. package/dist/command-utils-B1D-HqCd.mjs +1117 -0
  11. package/dist/command-utils-B1D-HqCd.mjs.map +1 -0
  12. package/dist/completion.d.mts +1 -1
  13. package/dist/completion.d.mts.map +1 -1
  14. package/dist/completion.mjs +77 -29
  15. package/dist/completion.mjs.map +1 -1
  16. package/dist/docs/index.d.mts +22 -2
  17. package/dist/docs/index.d.mts.map +1 -1
  18. package/dist/docs/index.mjs +94 -7
  19. package/dist/docs/index.mjs.map +1 -1
  20. package/dist/errors-BiVrBgi6.mjs +114 -0
  21. package/dist/errors-BiVrBgi6.mjs.map +1 -0
  22. package/dist/{formatter-ClUK5hcQ.d.mts → formatter-DtHzbP22.d.mts} +34 -5
  23. package/dist/formatter-DtHzbP22.d.mts.map +1 -0
  24. package/dist/help-bbmu9-qd.mjs +735 -0
  25. package/dist/help-bbmu9-qd.mjs.map +1 -0
  26. package/dist/index.d.mts +32 -3
  27. package/dist/index.d.mts.map +1 -1
  28. package/dist/index.mjs +493 -265
  29. package/dist/index.mjs.map +1 -1
  30. package/dist/mcp-mLWIdUIu.mjs +379 -0
  31. package/dist/mcp-mLWIdUIu.mjs.map +1 -0
  32. package/dist/serve-B0u43DK7.mjs +404 -0
  33. package/dist/serve-B0u43DK7.mjs.map +1 -0
  34. package/dist/stream-BcC146Ud.mjs +56 -0
  35. package/dist/stream-BcC146Ud.mjs.map +1 -0
  36. package/dist/test.d.mts +1 -1
  37. package/dist/test.mjs +4 -15
  38. package/dist/test.mjs.map +1 -1
  39. package/dist/{types-DjIdJN5G.d.mts → types-Ch8Mk6Qb.d.mts} +310 -62
  40. package/dist/types-Ch8Mk6Qb.d.mts.map +1 -0
  41. package/dist/{update-check-EbNDkzyV.mjs → update-check-CFX1FV3v.mjs} +2 -2
  42. package/dist/{update-check-EbNDkzyV.mjs.map → update-check-CFX1FV3v.mjs.map} +1 -1
  43. package/dist/zod.d.mts +32 -0
  44. package/dist/zod.d.mts.map +1 -0
  45. package/dist/zod.mjs +50 -0
  46. package/dist/zod.mjs.map +1 -0
  47. package/package.json +10 -2
  48. package/src/args.ts +68 -40
  49. package/src/cli/docs.ts +1 -7
  50. package/src/cli/doctor.ts +195 -10
  51. package/src/cli/index.ts +1 -1
  52. package/src/cli/init.ts +2 -3
  53. package/src/cli/link.ts +2 -2
  54. package/src/codegen/discovery.ts +80 -28
  55. package/src/codegen/index.ts +2 -1
  56. package/src/codegen/parsers/bash.ts +179 -0
  57. package/src/codegen/schema-to-code.ts +2 -1
  58. package/src/colorizer.ts +126 -13
  59. package/src/command-utils.ts +380 -30
  60. package/src/completion.ts +120 -47
  61. package/src/create.ts +480 -128
  62. package/src/docs/index.ts +122 -8
  63. package/src/formatter.ts +171 -125
  64. package/src/help.ts +45 -12
  65. package/src/index.ts +29 -1
  66. package/src/interactive.ts +45 -4
  67. package/src/mcp.ts +390 -0
  68. package/src/repl-loop.ts +16 -3
  69. package/src/runtime.ts +195 -2
  70. package/src/serve.ts +442 -0
  71. package/src/stream.ts +75 -0
  72. package/src/test.ts +7 -16
  73. package/src/type-utils.ts +28 -4
  74. package/src/types.ts +212 -30
  75. package/src/wrap.ts +23 -25
  76. package/src/zod.ts +50 -0
  77. package/dist/args-CVDbyyzG.mjs.map +0 -1
  78. package/dist/chunk-y_GBKt04.mjs +0 -5
  79. package/dist/formatter-ClUK5hcQ.d.mts.map +0 -1
  80. package/dist/help-CcBe91bV.mjs +0 -1254
  81. package/dist/help-CcBe91bV.mjs.map +0 -1
  82. package/dist/types-DjIdJN5G.d.mts.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,84 @@
1
1
  # padrone
2
2
 
3
+ ## 1.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`ef5e829`](https://github.com/KurtGokhan/padrone/commit/ef5e82931c06bbce70b6cdf3e34c179a48d04c66) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add `asyncStream` for streaming stdin as `AsyncIterable`. New `padrone/zod` entrypoint exports `zodAsyncStream` and `jsonCodec` for typed streams with per-item validation. Extract shared `JSON_SCHEMA_OPTS` constant across all `jsonSchema.input()` calls.
8
+
9
+ - [`bbb05d9`](https://github.com/KurtGokhan/padrone/commit/bbb05d9dcf4b360d7f5ae85bdd4fa6e45b68b64d) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add `examples` configuration to options and commands for command-line usage examples.
10
+
11
+ - [`7ff2738`](https://github.com/KurtGokhan/padrone/commit/7ff2738c146c419f4f03315ec8182af5be31d1b0) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Collapse global commands in help output to a single summary line by default. Add `--all` flag to show full global commands section. Bare `--detail` flag now defaults to `full`. Rename "Built-in" section to "Global".
12
+
13
+ - [`369ebba`](https://github.com/KurtGokhan/padrone/commit/369ebbab4dc14c1d8acfd2af01a9322f5d964e23) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add `group` configuration to options and commands for organized help output.
14
+
15
+ Options can be grouped via `fields: { myField: { group: 'Group Name' } }` in argument metadata. Commands can be grouped via `configure({ group: 'Group Name' })`. Grouped items are rendered under labeled `${group}:` sections in help output, while ungrouped items remain under the default `Options:` / `Commands:` headers.
16
+
17
+ - [`3d7b282`](https://github.com/KurtGokhan/padrone/commit/3d7b28202890925e05357c9796218349b4a8410e) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add per-field validation during interactive prompts.
18
+
19
+ When a user provides an invalid value for an interactive field, the prompt now immediately validates it against the schema and re-prompts with a warning message instead of deferring all errors until after all prompts complete. This applies to both required and optional interactive fields.
20
+
21
+ - [`1843f1f`](https://github.com/KurtGokhan/padrone/commit/1843f1f3a00714d11570c245361ab73c4049aa91) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Lazily initialize commands defined with callbacks. Builder functions passed to `.command()` are now deferred until the command is routed to, avoiding upfront construction of unused commands. Features that need the full command tree (help, MCP, serve, docs, completion, REPL) resolve all commands eagerly. Added `getCommand()` and `isPadroneProgram()` helpers to replace direct `commandSymbol` usage.
22
+
23
+ - [`45ba002`](https://github.com/KurtGokhan/padrone/commit/45ba002db474e34808b64b15ebce59b289f9115b) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add built-in Model Context Protocol (MCP) server. Expose CLI commands as AI tools via `mcp` command or `.mcp()` method. Supports Streamable HTTP and stdio transports per the 2025-11-25 MCP spec.
24
+
25
+ - [`ab53491`](https://github.com/KurtGokhan/padrone/commit/ab534915e3bcb5cd1c3f563f4fde740d1b91fa50) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - **BREAKING:** `eval()`, `cli()`, and `run()` no longer throw errors. Instead, they return a discriminated union with an `error` field:
26
+
27
+ - Success: `{ command, args, argsResult, result, drain() }`
28
+ - Error: `{ error, command?, args?, argsResult?, drain() }`
29
+
30
+ Added `drain()` method to all command results. It flattens the result into a single `Promise<{ value } | { error }>` that never throws — resolving Promises, collecting iterables into arrays, and catching errors:
31
+
32
+ ```ts
33
+ const { value, error } = await program.cli().drain();
34
+ ```
35
+
36
+ New exported types: `PadroneDrainResult<T>`, `Drained<T>`.
37
+
38
+ - [`dffc5cd`](https://github.com/KurtGokhan/padrone/commit/dffc5cd36250f94cc82edae850aa34ae9916d43a) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add progress indicator system for commands with auto-managed spinners and manual control.
39
+
40
+ **Auto-managed progress** via `.progress()` builder method:
41
+
42
+ - `true` or `string` for simple messages, or a full config object with per-state messages
43
+ - Starts before validation, auto-succeeds/fails after execution
44
+ - Validation-phase message transitions to execution-phase message
45
+ - `spinner` option: preset name (`dots`, `line`, `arc`, `bounce`), custom `{ frames, interval }`, or `false` to disable animation
46
+ - `success`/`error` fields accept static strings, `null` to suppress, callbacks `(result) => string | null`, or `{ message, indicator }` objects for per-call icon customization
47
+
48
+ **Manual progress** via `ctx.progress` in action handlers:
49
+
50
+ - Works even without `.progress()` config — lazily creates a real indicator on first use
51
+ - Auto-stopped when execution finishes (no leaked spinners)
52
+ - No-op when the runtime has no progress factory
53
+
54
+ **Built-in terminal spinner** (`createTerminalSpinner`):
55
+
56
+ - ANSI-based spinner with pause/resume for clean output interleaving
57
+ - Customizable success/error indicator icons via `PadroneProgressOptions`
58
+ - Empty string indicators hide the icon prefix entirely
59
+ - Graceful fallback in non-TTY/CI environments
60
+
61
+ **New types**: `PadroneProgressIndicator`, `PadroneProgressConfig`, `PadroneProgressMessage`, `PadroneProgressOptions`, `PadroneSpinnerConfig`, `PadroneSpinnerPreset`
62
+
63
+ - [`6851b48`](https://github.com/KurtGokhan/padrone/commit/6851b4878ab0fc8d48f40e93c2f8924236a40165) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add REST server (`program.serve()`) and `mutation` command config.
64
+
65
+ - New `serve()` program method: exposes commands as HTTP endpoints with automatic OpenAPI docs (Scalar).
66
+ - New `serve` built-in CLI command: `myapp serve --port 3000`.
67
+ - Built-in endpoints: `/_health`, `/_help`, `/_schema`, `/_docs` (Scalar), `/_openapi`.
68
+ - New `mutation` option in `.configure()`: mutation commands are POST-only in serve, set `destructiveHint` in MCP, and default `needsApproval` to true in `tool()`.
69
+ - MCP: rename `endpoint` to `basePath` for consistency with serve.
70
+ - Shared utilities extracted from MCP (`collectEndpoints`, `buildInputSchema`, `serializeArgsToFlags`).
71
+
72
+ ### Patch Changes
73
+
74
+ - [`7e8f14d`](https://github.com/KurtGokhan/padrone/commit/7e8f14ddb628620f94a7c9f2e88f9417577f2b04) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Expand boolean auto-coercion to accept `yes`/`no`/`on`/`off` (case-insensitive).
75
+
76
+ - [`a1c7072`](https://github.com/KurtGokhan/padrone/commit/a1c70724829f8cd4fb1632098f352498c87cbf2e) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Improve help output formatting: options now display flags first, then names, type, and description in aligned columns. Metadata (deprecated, default, choices, examples, env, config) is shown on separate indented lines.
77
+
78
+ - [`befc82e`](https://github.com/KurtGokhan/padrone/commit/befc82e39b4a1663c3ace74305dd48f9aded1a09) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add `.catch()` and `.finally()` methods to thenable sync results from `eval()`, `parse()`, and `cli()`
79
+
80
+ - [`81f3bbc`](https://github.com/KurtGokhan/padrone/commit/81f3bbce54940953ff32d76c620eabd6cec7322f) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Use `node:child_process` in wrap handler instead of `Bun.spawn` for Node.js compatibility.
81
+
3
82
  ## 1.4.0
4
83
 
5
84
  ### Minor Changes
package/README.md CHANGED
@@ -2,10 +2,8 @@
2
2
  <img src="media/padrone.svg" alt="Padrone Logo" width="200" height="200" />
3
3
  </p>
4
4
 
5
- <!-- <h1 align="center">Padrone</h1> -->
6
-
7
5
  <p align="center">
8
- <strong>Create type-safe, interactive CLI apps with Zod schemas</strong>
6
+ <strong>Type-safe CLI framework powered by Zod schemas</strong>
9
7
  </p>
10
8
 
11
9
  <p align="center">
@@ -16,33 +14,26 @@
16
14
 
17
15
  ---
18
16
 
19
- ## Features
17
+ Define your CLI with Zod schemas. Get type safety, validation, help generation, interactive prompts, shell completions, AI tool integration, and more — all from a single source of truth.
20
18
 
21
- - 🔒 **Type-safe** - Full TypeScript support with Zod schema validation
22
- - 🎯 **Fluent API** - Chain commands and arguments with a clean builder pattern
23
- - 🤖 **AI-Ready** - First-class support for Vercel AI SDK tool integration
24
- - 📚 **Auto Help** - Automatic help generation from your schema definitions
25
- - 🧩 **Nested Commands** - Support for deeply nested subcommands
26
- - 🔄 **Standard Schema** - Built on [Standard Schema](https://github.com/standard-schema/standard-schema) for maximum compatibility
27
- - 🚀 **Zero Config** - Works out of the box with sensible defaults
19
+ Built on [Standard Schema](https://github.com/standard-schema/standard-schema), so it also works with Valibot, ArkType, and others.
28
20
 
29
- ## 📦 Installation
21
+ ## Install
30
22
 
31
23
  ```bash
32
- # Using npm
33
24
  npm install padrone zod
25
+ ```
34
26
 
35
- # Using bun
36
- bun add padrone zod
27
+ ## Scaffold a New Project
37
28
 
38
- # Using pnpm
39
- pnpm add padrone zod
29
+ The fastest way to get started is with `padrone init`:
40
30
 
41
- # Using yarn
42
- yarn add padrone zod
31
+ ```bash
32
+ npx padrone init my-cli
33
+ cd my-cli && bun i && bun dev
43
34
  ```
44
35
 
45
- ## 🚀 Quick Start
36
+ ## Quick Start
46
37
 
47
38
  ```typescript
48
39
  import { createPadrone } from 'padrone';
@@ -54,320 +45,150 @@ const program = createPadrone('myapp')
54
45
  .arguments(
55
46
  z.object({
56
47
  names: z.array(z.string()).describe('Names to greet'),
57
- prefix: z
58
- .string()
59
- .optional()
60
- .describe('Prefix to use in greeting')
61
- .meta({ alias: 'p' }),
48
+ prefix: z.string().optional().describe('Prefix').meta({ flags: 'p' }),
62
49
  }),
63
50
  { positional: ['...names'] },
64
51
  )
65
52
  .action((args) => {
66
- const prefix = args?.prefix ? `${args.prefix} ` : '';
67
- args.names.forEach((name) => {
68
- console.log(`Hello, ${prefix}${name}!`);
69
- });
53
+ for (const name of args.names) {
54
+ console.log(`Hello, ${args.prefix ?? ''} ${name}!`);
55
+ }
70
56
  }),
71
57
  );
72
58
 
73
- // Run from CLI arguments
74
59
  program.cli();
75
60
  ```
76
61
 
77
- ### Running your CLI
78
-
79
62
  ```bash
80
- # Run with arguments
81
- myapp greet John Jane --prefix Mr.
82
-
83
- # Or with alias
84
63
  myapp greet John Jane -p Mr.
64
+ # Hello, Mr. John!
65
+ # Hello, Mr. Jane!
85
66
  ```
86
67
 
87
- Output:
88
- ```
89
- Hello, Mr. John!
90
- Hello, Mr. Jane!
91
- ```
92
-
93
- ## 📖 Usage Examples
94
-
95
- ### Programmatic Execution
68
+ ## What It Does
96
69
 
97
70
  ```typescript
98
- // Run a command directly with typed arguments
99
- program.run('greet', { names: ['John', 'Jane'], prefix: 'Dr.' });
71
+ // Multiple ways to run commands
72
+ program.cli(); // from process.argv
73
+ program.eval('greet John --prefix Mr.'); // from a string
74
+ program.run('greet', { names: ['John'], prefix: 'Mr.' }); // typed args
75
+ program.api().greet({ names: ['John'], prefix: 'Mr.' }); // as a function
100
76
 
101
- // Parse CLI input without executing
102
- const parsed = program.parse('greet John --prefix Mr.');
103
- console.log(parsed.args); // { names: ['John'], prefix: 'Mr.' }
104
- ```
105
-
106
- ### API Mode
77
+ // Parse without executing
78
+ const { args } = program.parse('greet John --prefix Mr.');
107
79
 
108
- Generate a typed API from your CLI program:
80
+ // Interactive REPL
81
+ for await (const result of program.repl()) { /* ... */ }
109
82
 
110
- ```typescript
111
- const api = program.api();
83
+ // AI tool for Vercel AI SDK
84
+ const tool = program.tool();
112
85
 
113
- // Call commands as functions with full type safety
114
- api.greet({ names: ['Alice', 'Bob'], prefix: 'Dr.' });
115
- ```
86
+ // MCP server for AI assistants (Claude, Cursor, etc.) [experimental]
87
+ await program.mcp(); // or: myapp mcp
116
88
 
117
- ### Nested Commands
89
+ // REST server with OpenAPI docs [experimental]
90
+ await program.serve(); // or: myapp serve
118
91
 
119
- ```typescript
120
- const program = createPadrone('weather')
121
- .command('forecast', (c) =>
122
- c
123
- .arguments(
124
- z.object({
125
- city: z.string().describe('City name'),
126
- days: z.number().optional().default(3).describe('Number of days'),
127
- }),
128
- { positional: ['city'] },
129
- )
130
- .action((args) => {
131
- console.log(`Forecast for ${args.city}: ${args.days} days`);
132
- })
133
- .command('extended', (c) =>
134
- c
135
- .arguments(
136
- z.object({
137
- city: z.string().describe('City name'),
138
- }),
139
- { positional: ['city'] },
140
- )
141
- .action((args) => {
142
- console.log(`Extended forecast for ${args.city}`);
143
- }),
144
- ),
145
- );
92
+ // Shell completions
93
+ const script = program.completion('zsh');
146
94
 
147
- // Run nested command
148
- program.eval('forecast extended London');
95
+ // Help in multiple formats
96
+ program.help('greet'); // text
97
+ program.help('greet', { format: 'json' }); // json, markdown, html, ansi
149
98
  ```
150
99
 
151
- ### Option Aliases and Metadata
100
+ ## Features at a Glance
152
101
 
153
- ```typescript
154
- const program = createPadrone('app')
155
- .command('serve', (c) =>
156
- c
157
- .arguments(
158
- z.object({
159
- port: z
160
- .number()
161
- .default(3000)
162
- .describe('Port to listen on')
163
- .meta({ alias: 'p', examples: ['3000', '8080'] }),
164
- host: z
165
- .string()
166
- .default('localhost')
167
- .describe('Host to bind to')
168
- .meta({ alias: 'h' }),
169
- verbose: z
170
- .boolean()
171
- .optional()
172
- .describe('Enable verbose logging')
173
- .meta({ alias: 'v', deprecated: 'Use --debug instead' }),
174
- }),
175
- )
176
- .action((args) => {
177
- console.log(`Server running at ${args.host}:${args.port}`);
178
- }),
179
- );
180
- ```
102
+ **Arguments** — positional args, variadic args, short flags (`-v`), long aliases (`--dry-run`), auto kebab-case aliases, negatable booleans (`--no-verbose`).
181
103
 
182
- ### Environment Variables and Config Files
104
+ **Env & Config** — load from environment variables with `.env()` and config files with `.configFile()`. Precedence: CLI > stdin > env > config > defaults.
183
105
 
184
- Padrone supports loading arguments from environment variables and config files using dedicated schema methods:
106
+ **Interactive prompts** auto-prompt for missing fields. Booleans become confirm, enums become select, arrays become multi-select.
185
107
 
186
- ```typescript
187
- const program = createPadrone('app')
188
- .command('serve', (c) =>
189
- c
190
- .arguments(
191
- z.object({
192
- port: z.number().default(3000).describe('Port to listen on'),
193
- apiKey: z.string().describe('API key for authentication'),
194
- }),
195
- )
196
- // Map environment variables to arguments
197
- .env(
198
- z
199
- .object({
200
- APP_PORT: z.coerce.number().optional(),
201
- API_KEY: z.string().optional(),
202
- })
203
- .transform((env) => ({
204
- port: env.APP_PORT,
205
- apiKey: env.API_KEY,
206
- })),
207
- )
208
- // Load config from JSON file with matching schema
209
- .configFile(
210
- 'app.config.json',
211
- z.object({
212
- port: z.number().optional(),
213
- apiKey: z.string().optional(),
214
- }),
215
- )
216
- .action((args) => {
217
- console.log(`Server running on port ${args.port}`);
218
- }),
219
- );
220
- ```
108
+ **Progress indicators** — auto-managed spinners with dynamic messages. `.progress({ progress: 'Deploying...', success: (r) => \`v${r.version}\` })`.
221
109
 
222
- **Precedence order** (highest to lowest): CLI args > environment variables > config file
110
+ **Plugins** — middleware hooks for 6 phases (start, parse, validate, execute, error, shutdown). Onion model with `next()`.
223
111
 
224
- ### Async Validation
112
+ **Composition** mount programs as subcommands with `.mount()`, override commands with merge semantics.
225
113
 
226
- If your schema uses async refinements (e.g. `z.check(async ...)`), mark the command as async so that `parse()` and `cli()` return Promises:
114
+ **Wrapping** *(experimental)* wrap external CLI tools with `.wrap({ command: 'git', args: ['commit'] })`.
227
115
 
228
- ```typescript
229
- import { asyncSchema, createPadrone } from 'padrone';
116
+ ## API
230
117
 
231
- const program = createPadrone('app')
232
- .command('create', (c) =>
233
- c
234
- // Option 1: brand the schema with asyncSchema()
235
- .arguments(asyncSchema(z.object({ name: z.string() }).check(async (ctx) => { /* ... */ })))
236
- // Option 2: call .async() on the builder
237
- .async()
238
- .action((args) => args.name),
239
- );
240
-
241
- // parse() and cli() now return Promises
242
- const result = await program.parse('create --name test');
243
- ```
244
-
245
- ## 🤖 AI SDK Integration
246
-
247
- Padrone provides first-class support for the [Vercel AI SDK](https://ai-sdk.dev/), making it easy to expose your CLI as an AI tool:
248
-
249
- ```typescript
250
- import { streamText } from 'ai';
251
- import { createPadrone } from 'padrone';
252
- import * as z from 'zod/v4';
253
-
254
- const weatherCli = createPadrone('weather')
255
- .command('current', (c) =>
256
- c
257
- .arguments(
258
- z.object({
259
- city: z.string().describe('City name'),
260
- }),
261
- { positional: ['city'] },
262
- )
263
- .action((args) => {
264
- return { city: args.city, temperature: 72, condition: 'Sunny' };
265
- }),
266
- );
267
-
268
- // Convert your CLI to an AI tool
269
- const result = await streamText({
270
- model: yourModel,
271
- prompt: "What's the weather in London?",
272
- tools: {
273
- weather: weatherCli.tool(),
274
- },
275
- });
276
- ```
277
-
278
- ## 📋 Auto-Generated Help
279
-
280
- Padrone automatically generates help text from your Zod schemas:
281
-
282
- ```typescript
283
- console.log(program.help());
284
- ```
285
-
286
- Example output:
287
- ```
288
- Usage: myapp greet [names...] [arguments]
289
-
290
- Positionals:
291
- names... Names to greet
292
-
293
- Arguments:
294
- -p, --prefix <string> Prefix to use in greeting
295
- -h, --help Show help
296
- ```
297
-
298
- ## 🔧 API Reference
299
-
300
- ### `createPadrone(name)`
118
+ ### Builder (define commands)
301
119
 
302
- Creates a new CLI program with the given name.
303
-
304
- ### Program Methods
305
-
306
- | Method | Description |
120
+ | Method | What it does |
121
+ |--------|-------------|
122
+ | `.arguments(schema, meta?)` | Define args with Zod schema, positional config, field metadata |
123
+ | `.action(handler)` | Set handler `(args, ctx, base?) => result` |
124
+ | `.command(name, builder)` | Add subcommand (name or `[name, ...aliases]`) |
125
+ | `.mount(name, program)` | Mount another program as subcommand tree |
126
+ | `.configure(config)` | Set title, description, version, etc. |
127
+ | `.env(schema)` | Map env vars to args |
128
+ | `.configFile(file, schema?)` | Load args from config files |
129
+ | `.wrap(config)` | Wrap an external CLI tool *(experimental)* |
130
+ | `.progress(config?)` | Auto-managed spinner |
131
+ | `.use(plugin)` | Register middleware plugin |
132
+ | `.runtime(runtime)` | Custom I/O (for non-terminal use) |
133
+ | `.updateCheck(config?)` | Background version check |
134
+ | `.async()` | Mark as async validation |
135
+
136
+ ### Program (run commands)
137
+
138
+ | Method | What it does |
307
139
  |--------|-------------|
308
- | `.configure(config)` | Configure program properties (title, description, version) |
309
- | `.command(name, builder)` | Add a command to the program |
310
- | `.arguments(schema, meta?)` | Define arguments schema with optional positional args |
311
- | `.async()` | Mark command as async (for schemas with async validation) |
312
- | `.env(schema)` | Define schema for parsing environment variables into arguments |
313
- | `.configFile(file, schema?)` | Configure config file path(s) and schema |
314
- | `.action(handler)` | Set the command handler function |
315
- | `.cli(input?)` | Run as CLI (parses `process.argv` or input string) |
316
- | `.run(command, args?)` | Run a command programmatically |
317
- | `.parse(input?)` | Parse input without executing |
318
- | `.stringify(command?, args?)` | Convert command and arguments back to CLI string |
319
- | `.api()` | Generate a typed API object |
320
- | `.help(command?)` | Generate help text |
321
- | `.tool()` | Generate a Vercel AI SDK tool |
322
- | `.find(command)` | Find a command by name |
323
-
324
- ### Arguments Meta
325
-
326
- Use the second argument of `.arguments()` to configure positional arguments and per-argument metadata:
140
+ | `.cli(prefs?)` | Entry point parses `process.argv`, throws on errors |
141
+ | `.eval(input, prefs?)` | Parse + validate + execute string, returns errors softly |
142
+ | `.run(command, args)` | Run by name with typed args (no validation) |
143
+ | `.parse(input?)` | Parse without executing |
144
+ | `.api()` | Generate typed function API |
145
+ | `.repl(options?)` | Interactive REPL session |
146
+ | `.help(command?, prefs?)` | Generate help (text, ansi, markdown, html, json) |
147
+ | `.tool()` | Vercel AI SDK tool definition |
148
+ | `.mcp(prefs?)` | Start MCP server (HTTP or stdio) *(experimental)* |
149
+ | `.serve(prefs?)` | Start REST server with OpenAPI docs *(experimental)* |
150
+ | `.completion(shell?)` | Shell completion script |
151
+ | `.find(command)` | Look up command by path |
152
+ | `.stringify(command?, args?)` | Convert back to CLI string |
153
+
154
+ ### Zod `.meta()` fields
155
+
156
+ | Field | Example | Purpose |
157
+ |-------|---------|---------|
158
+ | `flags` | `'v'` | Single-char short flag (`-v`) |
159
+ | `alias` | `'dry-run'` | Multi-char long alias (`--dry-run`) |
160
+ | `examples` | `['8080']` | Example values in help |
161
+ | `deprecated` | `'Use --debug'` | Deprecation warning |
162
+ | `hidden` | `true` | Hide from help |
163
+ | `group` | `'Advanced'` | Group in help output |
164
+
165
+ ### Arguments meta (second param of `.arguments()`)
327
166
 
328
167
  ```typescript
329
168
  .arguments(schema, {
330
- positional: ['source', '...files', 'dest'], // '...files' is variadic
331
- fields: {
332
- verbose: { alias: 'v' },
333
- format: { deprecated: 'Use --output instead' },
334
- },
169
+ positional: ['source', '...files', 'dest'],
170
+ interactive: ['name', 'template'],
171
+ optionalInteractive: ['typescript'],
172
+ fields: { verbose: { flags: 'v' } },
173
+ stdin: 'data',
174
+ autoAlias: true, // default
335
175
  })
336
176
  ```
337
177
 
338
- ### Zod Metadata
178
+ ## Agent Skill
339
179
 
340
- Use `.meta()` on Zod schemas to provide additional CLI metadata:
341
-
342
- ```typescript
343
- z.string().meta({
344
- alias: 'p', // Short alias (-p)
345
- examples: ['value'], // Example values for help text
346
- deprecated: 'message', // Mark as deprecated
347
- hidden: true, // Hide from help output
348
- })
349
- ```
350
-
351
- ## 🤖 AI Coding Agent Skill
352
-
353
- Install the [Padrone skill](https://agentskills.io) to give your AI coding agent (Claude Code, etc.) knowledge of the Padrone API:
180
+ Give your AI coding agent knowledge of the Padrone API:
354
181
 
355
182
  ```bash
356
183
  npx skills add KurtGokhan/padrone
357
184
  ```
358
185
 
359
- ## 🛠️ Requirements
186
+ ## Requirements
360
187
 
361
188
  - Node.js 18+ or Bun
362
189
  - TypeScript 5.0+ (recommended)
363
- - Zod 3.25+ or 4.x
190
+ - Zod (or any Standard Schema-compatible library)
364
191
 
365
- ## 📄 License
192
+ ## License
366
193
 
367
- [MIT](LICENSE) © [Gokhan Kurt](https://gkurt.com)
368
-
369
- ---
370
-
371
- <p align="center">
372
- Made with ❤️ by <a href="https://gkurt.com">Gokhan Kurt</a>
373
- </p>
194
+ [MIT](LICENSE)