padrone 1.0.0 → 1.2.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 (80) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/LICENSE +1 -1
  3. package/README.md +92 -49
  4. package/dist/args-CKNh7Dm9.mjs +175 -0
  5. package/dist/args-CKNh7Dm9.mjs.map +1 -0
  6. package/dist/chunk-y_GBKt04.mjs +5 -0
  7. package/dist/codegen/index.d.mts +305 -0
  8. package/dist/codegen/index.d.mts.map +1 -0
  9. package/dist/codegen/index.mjs +1348 -0
  10. package/dist/codegen/index.mjs.map +1 -0
  11. package/dist/completion.d.mts +64 -0
  12. package/dist/completion.d.mts.map +1 -0
  13. package/dist/completion.mjs +417 -0
  14. package/dist/completion.mjs.map +1 -0
  15. package/dist/docs/index.d.mts +34 -0
  16. package/dist/docs/index.d.mts.map +1 -0
  17. package/dist/docs/index.mjs +404 -0
  18. package/dist/docs/index.mjs.map +1 -0
  19. package/dist/formatter-Dvx7jFXr.d.mts +82 -0
  20. package/dist/formatter-Dvx7jFXr.d.mts.map +1 -0
  21. package/dist/help-mUIX0T0V.mjs +1195 -0
  22. package/dist/help-mUIX0T0V.mjs.map +1 -0
  23. package/dist/index.d.mts +122 -438
  24. package/dist/index.d.mts.map +1 -1
  25. package/dist/index.mjs +1240 -1161
  26. package/dist/index.mjs.map +1 -1
  27. package/dist/test.d.mts +112 -0
  28. package/dist/test.d.mts.map +1 -0
  29. package/dist/test.mjs +138 -0
  30. package/dist/test.mjs.map +1 -0
  31. package/dist/types-qrtt0135.d.mts +1037 -0
  32. package/dist/types-qrtt0135.d.mts.map +1 -0
  33. package/dist/update-check-EbNDkzyV.mjs +146 -0
  34. package/dist/update-check-EbNDkzyV.mjs.map +1 -0
  35. package/package.json +61 -20
  36. package/src/args.ts +365 -0
  37. package/src/cli/completions.ts +29 -0
  38. package/src/cli/docs.ts +86 -0
  39. package/src/cli/doctor.ts +312 -0
  40. package/src/cli/index.ts +159 -0
  41. package/src/cli/init.ts +135 -0
  42. package/src/cli/link.ts +320 -0
  43. package/src/cli/wrap.ts +152 -0
  44. package/src/codegen/README.md +118 -0
  45. package/src/codegen/code-builder.ts +226 -0
  46. package/src/codegen/discovery.ts +232 -0
  47. package/src/codegen/file-emitter.ts +73 -0
  48. package/src/codegen/generators/barrel-file.ts +16 -0
  49. package/src/codegen/generators/command-file.ts +184 -0
  50. package/src/codegen/generators/command-tree.ts +124 -0
  51. package/src/codegen/index.ts +33 -0
  52. package/src/codegen/parsers/fish.ts +163 -0
  53. package/src/codegen/parsers/help.ts +378 -0
  54. package/src/codegen/parsers/merge.ts +158 -0
  55. package/src/codegen/parsers/zsh.ts +221 -0
  56. package/src/codegen/schema-to-code.ts +199 -0
  57. package/src/codegen/template.ts +69 -0
  58. package/src/codegen/types.ts +143 -0
  59. package/src/colorizer.ts +2 -2
  60. package/src/command-utils.ts +501 -0
  61. package/src/completion.ts +110 -97
  62. package/src/create.ts +1044 -284
  63. package/src/docs/index.ts +607 -0
  64. package/src/errors.ts +131 -0
  65. package/src/formatter.ts +149 -63
  66. package/src/help.ts +151 -55
  67. package/src/index.ts +13 -15
  68. package/src/interactive.ts +169 -0
  69. package/src/parse.ts +31 -16
  70. package/src/repl-loop.ts +317 -0
  71. package/src/runtime.ts +304 -0
  72. package/src/shell-utils.ts +83 -0
  73. package/src/test.ts +285 -0
  74. package/src/type-helpers.ts +12 -12
  75. package/src/type-utils.ts +124 -14
  76. package/src/types.ts +803 -144
  77. package/src/update-check.ts +244 -0
  78. package/src/wrap.ts +185 -0
  79. package/src/zod.d.ts +2 -2
  80. package/src/options.ts +0 -180
package/CHANGELOG.md ADDED
@@ -0,0 +1,51 @@
1
+ # padrone
2
+
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 66336e5: auto-output is now enabled by default: command return values are automatically written to output in eval, cli, and repl modes. The runtime `output` function now accepts `unknown` values instead of only strings, letting runtimes handle formatting natively. Use `autoOutput: false` in preferences or `configure({ autoOutput: false })` on individual commands to opt out.
8
+ - 02a171c: Add runtime adapter for I/O abstraction, enabling CLI framework usage outside of terminals (web UIs, chat interfaces, testing). New `.runtime()` builder method configures output, error, argv, env, format, config file loading, and file discovery. All fields are optional with Node.js/Bun defaults. Successive `.runtime()` calls merge with previous configuration.
9
+ - 93155ef: Add `padrone/codegen` entry point with a generic code generation toolkit including CodeBuilder (fluent TypeScript source builder), template engine, schemaToCode (Standard Schema to Zod source), FileEmitter (multi-file output), built-in generators (command files, command trees, barrel files), and parsers (help text, fish completions, zsh completions, multi-source merge). Also add `padrone init` CLI command that scaffolds a new Padrone project using the codegen utilities, and reorganize CLI files into `src/cli/` subfolder.
10
+ - 68508a7: Add command override/extension support. Re-registering a command with the same name now merges instead of duplicating: configuration is shallow-merged, the previous handler is passed as a `base` parameter to `.action()`, arguments can be overridden, and subcommands are recursively merged by name. Aliases are preserved from the original when the override doesn't specify new ones. All fully strongly typed.
11
+
12
+ Also fixes: REPL `.` command now works at any scope (including root) to execute the current command, `.help` always shows `.` and `.scope` entries, `cli()` and `repl()` return types now include all possible command results, and nested commands with default `''` subcommands route correctly.
13
+
14
+ - 7e83ebb: Improve command routing, help display, and `--` separator support.
15
+ - 583394b: Add `padrone/completion` subpath export and `padrone completions` CLI command. Shell completion generation is now lazy-loaded via dynamic import, and `setupCompletions()` writes eval snippets to shell config files with idempotent marker-based replacement. User programs get `--setup` on the built-in `completion` command (e.g. `myapp completion bash --setup`). The `.completion()` method is now async.
16
+ - 457f1f7: Add `padrone/docs` entry point with a `generateDocs()` utility that walks the command tree and generates structured documentation in four formats: markdown (with index page, frontmatter support for VitePress/Starlight), HTML (semantic with CSS classes), man pages (groff-formatted), and JSON. Each page includes command name, description, usage syntax, options with types/defaults/choices/aliases/env vars/config keys/examples, positional arguments, and subcommands table. Also add `padrone docs` CLI command that imports a Padrone program from any entry file and generates documentation to an output directory.
17
+ - 038d0aa: Add `padrone doctor <entry>` CLI command that lints and validates a Padrone program definition. Catches duplicate aliases, shadowed option/command names (help, version), commands without actions, schemas without descriptions, conflicting positional configs, and unused plugins.
18
+ - 262e2e6: Add `eval()` method and separate from `cli()`. `program.eval(input)` parses, validates, and executes a command string with soft error handling (returns result with issues instead of throwing). `program.cli()` is now exclusively the process entry point that reads from `process.argv` and throws on validation errors. The REPL and AI SDK tool integration now use `eval()` internally.
19
+ - fb86d5b: Add fuzzy matching for "Did you mean?" suggestions on unknown commands and options.
20
+ - 020cc21: Add interactive field prompting. Commands can now declare `interactive` and `optionalInteractive` in the arguments meta to prompt users for missing field values during `cli()`. Interactive prompts are auto-detected from the schema (boolean → confirm, enum → select, array enum → multiselect). The runtime controls whether interactivity is enabled via `runtime({ interactive: true })`, with a built-in Enquirer-powered terminal prompt as the default. Custom prompt implementations can be provided for non-terminal runtimes.
21
+ - cba6615: Add lifecycle hooks to the plugin system: `start`, `error`, and `shutdown` phases. `start` wraps the entire pipeline (before parse), `error` handles pipeline failures with the ability to suppress or transform errors, and `shutdown` always runs after completion for cleanup. All three use the same onion/middleware pattern as existing phases. Available in `eval()` and `cli()` only. Sync preservation is maintained.
22
+ - 727c6af: Add `padrone link` and `padrone unlink` CLI commands for linking programs during development. Creates shell shims in `~/.padrone/bin/` that invoke the entry file with the detected runtime. Auto-detects entry from `package.json` bin field and runtime from lockfiles. Use `--setup` to automatically add `~/.padrone/bin` to PATH in shell config. Shell utilities (`detectShell`, `getRcFile`, `writeToRcFile`) extracted to `shell-utils.ts` for reuse.
23
+ - fdca76f: Add `.mount(name, program)` method for composing Padrone programs together. Mounts an existing program as a subcommand, recursively re-pathing all nested commands and preserving arguments, handlers, plugins, and schemas. Supports aliases via array syntax. Mounted program's root-level `version` is dropped. Type-level paths are recursively updated for correct inference with `eval()`, `find()`, `run()`, etc.
24
+ - 4706462: Add plugin system with middleware pattern for intercepting command execution phases. Plugins use an onion model with `next()` to wrap parse, validate, and execute phases. Registered via `.use()` on both programs and subcommand builders. Program-level plugins apply as outermost wrappers; subcommand plugins compose as inner layers. Parse phase runs root plugins only. Supports explicit ordering via `order` parameter, shared mutable `state` across phases, sync preservation, and short-circuiting.
25
+ - 1a44f9d: Add REPL command history, tab completion, and output styling. The built-in terminal REPL now supports up/down arrow history navigation and tab completion for command names, subcommands, options, and aliases. New `repl()` preferences: `history` (initial entries), `completion` (toggle tab completion), `spacing` (separators before/after command output — supports blank lines, repeated characters, multi-line arrays, and independent before/after config), and `outputPrefix` (prefix each output line, e.g. `'│ '`). The default prompt is bold in ANSI-capable terminals.
26
+ - a73bf6a: Add REPL mode. `program.repl()` starts an interactive Read-Eval-Print Loop that returns an `AsyncIterable<PadroneCommandResult>`, yielding a result for each successfully executed command. Errors are caught and printed without crashing the session. Built-in REPL commands (`exit`, `quit`, `clear`) are provided but yield to user-defined commands of the same name. The runtime gains a new `readLine` field for abstracting line input, with a default Node.js/Bun `readline` implementation.
27
+ - 5437416: Add scoped/contextual REPLs, `--repl` CLI flag, and dot-prefixed built-in commands. All REPL built-ins now use dot-prefix notation (`.exit`, `.quit`, `.clear`, `.scope`, `.help`, `.history`) to avoid collisions with user commands. `.scope <subcommand>` scopes the REPL session to a command subtree, `.scope ..`/`..` goes back up, `.` executes the current scoped command. `.help` shows REPL-specific commands and keybindings. `.history` shows session command history. Default greeting displays program name and version; configurable `hint` text shown below. Double Ctrl+C to exit (first press shows hint). The prompt updates to reflect scope (e.g. `myapp/db ❯`). `options.scope` allows starting pre-scoped and is strongly typed to valid command paths. The `--repl` flag in `cli()` starts a REPL (optionally scoped to a command).
28
+ - b021824: Removed parse options. Custom runtimes can be used for the same behavior.
29
+ - 3ad9c6f: Add stdin piping support. Commands can declare a `stdin` field in their arguments meta to read piped input and inject it into a schema field. Supports `text` mode (read all as string) and `lines` mode (read as string array). Precedence: CLI flags > stdin > env vars > config file > schema defaults. Stdin is only read when piped (not a TTY) and the target field wasn't already provided via CLI. Runtime abstraction (`PadroneRuntime.stdin`) enables custom stdin sources for testing and non-terminal environments. Test harness gains `.stdin(data)` builder method. Help output shows `[stdin > field]` in usage line.
30
+ - a64f576: Add `padrone/test` entry point with testing utilities. The `testCli(program)` function provides a fluent builder for setting up CLI test scenarios with mock I/O capture. Supports mocking environment variables (`.env()`), interactive prompt answers (`.prompt()`), config files (`.config()`), and REPL sessions (`.repl()`). Works with any test framework.
31
+ - 6269637: add async validation support
32
+ - 6d15076: Add built-in opt-in update checking via `.updateCheck()`. When enabled, the program checks the npm registry (or a custom URL) for newer versions in the background and displays a notification after command output. Checks are cached to avoid hitting the registry on every invocation. Respects CI environments, non-TTY contexts, `--no-update-check` flag, and a configurable env var to disable.
33
+
34
+ ### Patch Changes
35
+
36
+ - 54de1b9: show built-in commands and flags (help, version, completion, --repl) in root help output
37
+ - 6fa2ac9: improve help output formatting: show actual positional argument names in usage line, use `[options]` instead of `[arguments]` for flags, and rename flags section from "Arguments" to "Options"
38
+ - bf6fe49: Add AI coding agent skill with API reference, examples, and installation instructions for Claude Code and other Agent Skills-compatible tools.
39
+
40
+ ## 1.0.0
41
+
42
+ Initial stable release of Padrone - a TypeScript CLI framework with Zod schema support.
43
+
44
+ ### Features
45
+
46
+ - Type-safe argument parsing with Zod schemas
47
+ - Interactive prompts with validation
48
+ - AI integration support via Vercel AI SDK
49
+ - Standard Schema compatibility
50
+ - Terminal UI components
51
+ - Command builder pattern
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2025 Gökhan Kurt
3
+ Copyright (c) 2026 Gökhan Kurt
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -19,7 +19,7 @@
19
19
  ## ✨ Features
20
20
 
21
21
  - 🔒 **Type-safe** - Full TypeScript support with Zod schema validation
22
- - 🎯 **Fluent API** - Chain commands, arguments, and options with a clean builder pattern
22
+ - 🎯 **Fluent API** - Chain commands and arguments with a clean builder pattern
23
23
  - 🤖 **AI-Ready** - First-class support for Vercel AI SDK tool integration
24
24
  - 📚 **Auto Help** - Automatic help generation from your schema definitions
25
25
  - 🧩 **Nested Commands** - Support for deeply nested subcommands
@@ -51,7 +51,7 @@ import * as z from 'zod/v4';
51
51
  const program = createPadrone('myapp')
52
52
  .command('greet', (c) =>
53
53
  c
54
- .options(
54
+ .arguments(
55
55
  z.object({
56
56
  names: z.array(z.string()).describe('Names to greet'),
57
57
  prefix: z
@@ -62,9 +62,9 @@ const program = createPadrone('myapp')
62
62
  }),
63
63
  { positional: ['...names'] },
64
64
  )
65
- .action((options) => {
66
- const prefix = options?.prefix ? `${options.prefix} ` : '';
67
- options.names.forEach((name) => {
65
+ .action((args) => {
66
+ const prefix = args?.prefix ? `${args.prefix} ` : '';
67
+ args.names.forEach((name) => {
68
68
  console.log(`Hello, ${prefix}${name}!`);
69
69
  });
70
70
  }),
@@ -95,12 +95,12 @@ Hello, Mr. Jane!
95
95
  ### Programmatic Execution
96
96
 
97
97
  ```typescript
98
- // Run a command directly with typed options
98
+ // Run a command directly with typed arguments
99
99
  program.run('greet', { names: ['John', 'Jane'], prefix: 'Dr.' });
100
100
 
101
101
  // Parse CLI input without executing
102
102
  const parsed = program.parse('greet John --prefix Mr.');
103
- console.log(parsed.options); // { names: ['John'], prefix: 'Mr.' }
103
+ console.log(parsed.args); // { names: ['John'], prefix: 'Mr.' }
104
104
  ```
105
105
 
106
106
  ### API Mode
@@ -120,32 +120,32 @@ api.greet({ names: ['Alice', 'Bob'], prefix: 'Dr.' });
120
120
  const program = createPadrone('weather')
121
121
  .command('forecast', (c) =>
122
122
  c
123
- .options(
123
+ .arguments(
124
124
  z.object({
125
125
  city: z.string().describe('City name'),
126
126
  days: z.number().optional().default(3).describe('Number of days'),
127
127
  }),
128
128
  { positional: ['city'] },
129
129
  )
130
- .action((options) => {
131
- console.log(`Forecast for ${options.city}: ${options.days} days`);
130
+ .action((args) => {
131
+ console.log(`Forecast for ${args.city}: ${args.days} days`);
132
132
  })
133
133
  .command('extended', (c) =>
134
134
  c
135
- .options(
135
+ .arguments(
136
136
  z.object({
137
137
  city: z.string().describe('City name'),
138
138
  }),
139
139
  { positional: ['city'] },
140
140
  )
141
- .action((options) => {
142
- console.log(`Extended forecast for ${options.city}`);
141
+ .action((args) => {
142
+ console.log(`Extended forecast for ${args.city}`);
143
143
  }),
144
144
  ),
145
145
  );
146
146
 
147
147
  // Run nested command
148
- program.cli('forecast extended London');
148
+ program.eval('forecast extended London');
149
149
  ```
150
150
 
151
151
  ### Option Aliases and Metadata
@@ -154,7 +154,7 @@ program.cli('forecast extended London');
154
154
  const program = createPadrone('app')
155
155
  .command('serve', (c) =>
156
156
  c
157
- .options(
157
+ .arguments(
158
158
  z.object({
159
159
  port: z
160
160
  .number()
@@ -173,41 +173,75 @@ const program = createPadrone('app')
173
173
  .meta({ alias: 'v', deprecated: 'Use --debug instead' }),
174
174
  }),
175
175
  )
176
- .action((options) => {
177
- console.log(`Server running at ${options.host}:${options.port}`);
176
+ .action((args) => {
177
+ console.log(`Server running at ${args.host}:${args.port}`);
178
178
  }),
179
179
  );
180
180
  ```
181
181
 
182
182
  ### Environment Variables and Config Files
183
183
 
184
- Padrone supports binding options to environment variables and config files:
184
+ Padrone supports loading arguments from environment variables and config files using dedicated schema methods:
185
185
 
186
186
  ```typescript
187
187
  const program = createPadrone('app')
188
- .configure({
189
- configFiles: ['app.config.json', '.apprc'],
190
- })
191
188
  .command('serve', (c) =>
192
189
  c
193
- .options(
190
+ .arguments(
194
191
  z.object({
195
192
  port: z.number().default(3000).describe('Port to listen on'),
196
193
  apiKey: z.string().describe('API key for authentication'),
197
194
  }),
198
- {
199
- options: {
200
- port: { env: 'APP_PORT', configKey: 'server.port' },
201
- apiKey: { env: ['API_KEY', 'APP_API_KEY'] },
202
- },
203
- },
204
195
  )
205
- .action((options) => {
206
- console.log(`Server running on port ${options.port}`);
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}`);
207
218
  }),
208
219
  );
209
220
  ```
210
221
 
222
+ **Precedence order** (highest to lowest): CLI args > environment variables > config file
223
+
224
+ ### Async Validation
225
+
226
+ If your schema uses async refinements (e.g. `z.check(async ...)`), mark the command as async so that `parse()` and `cli()` return Promises:
227
+
228
+ ```typescript
229
+ import { asyncSchema, createPadrone } from 'padrone';
230
+
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
+
211
245
  ## 🤖 AI SDK Integration
212
246
 
213
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:
@@ -220,14 +254,14 @@ import * as z from 'zod/v4';
220
254
  const weatherCli = createPadrone('weather')
221
255
  .command('current', (c) =>
222
256
  c
223
- .options(
257
+ .arguments(
224
258
  z.object({
225
259
  city: z.string().describe('City name'),
226
260
  }),
227
261
  { positional: ['city'] },
228
262
  )
229
- .action((options) => {
230
- return { city: options.city, temperature: 72, condition: 'Sunny' };
263
+ .action((args) => {
264
+ return { city: args.city, temperature: 72, condition: 'Sunny' };
231
265
  }),
232
266
  );
233
267
 
@@ -251,12 +285,12 @@ console.log(program.help());
251
285
 
252
286
  Example output:
253
287
  ```
254
- Usage: myapp greet [names...] [options]
288
+ Usage: myapp greet [names...] [arguments]
255
289
 
256
- Arguments:
290
+ Positionals:
257
291
  names... Names to greet
258
292
 
259
- Options:
293
+ Arguments:
260
294
  -p, --prefix <string> Prefix to use in greeting
261
295
  -h, --help Show help
262
296
  ```
@@ -271,34 +305,37 @@ Creates a new CLI program with the given name.
271
305
 
272
306
  | Method | Description |
273
307
  |--------|-------------|
274
- | `.configure(config)` | Configure program properties (title, description, version, configFiles) |
308
+ | `.configure(config)` | Configure program properties (title, description, version) |
275
309
  | `.command(name, builder)` | Add a command to the program |
276
- | `.options(schema, meta?)` | Define options schema with optional positional args |
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 |
277
314
  | `.action(handler)` | Set the command handler function |
278
315
  | `.cli(input?)` | Run as CLI (parses `process.argv` or input string) |
279
- | `.run(command, options)` | Run a command programmatically |
316
+ | `.run(command, args?)` | Run a command programmatically |
280
317
  | `.parse(input?)` | Parse input without executing |
281
- | `.stringify(command?, options?)` | Convert command and options back to CLI string |
318
+ | `.stringify(command?, args?)` | Convert command and arguments back to CLI string |
282
319
  | `.api()` | Generate a typed API object |
283
320
  | `.help(command?)` | Generate help text |
284
321
  | `.tool()` | Generate a Vercel AI SDK tool |
285
322
  | `.find(command)` | Find a command by name |
286
323
 
287
- ### Options Meta
324
+ ### Arguments Meta
288
325
 
289
- Use the second argument of `.options()` to configure positional arguments and per-option metadata:
326
+ Use the second argument of `.arguments()` to configure positional arguments and per-argument metadata:
290
327
 
291
328
  ```typescript
292
- .options(schema, {
329
+ .arguments(schema, {
293
330
  positional: ['source', '...files', 'dest'], // '...files' is variadic
294
- options: {
295
- verbose: { alias: 'v', env: 'VERBOSE' },
296
- config: { configKey: 'settings.config' },
331
+ fields: {
332
+ verbose: { alias: 'v' },
333
+ format: { deprecated: 'Use --output instead' },
297
334
  },
298
335
  })
299
336
  ```
300
337
 
301
- ### Zod Meta Options
338
+ ### Zod Metadata
302
339
 
303
340
  Use `.meta()` on Zod schemas to provide additional CLI metadata:
304
341
 
@@ -308,11 +345,17 @@ z.string().meta({
308
345
  examples: ['value'], // Example values for help text
309
346
  deprecated: 'message', // Mark as deprecated
310
347
  hidden: true, // Hide from help output
311
- env: 'MY_VAR', // Bind to environment variable
312
- configKey: 'path.key', // Bind to config file key
313
348
  })
314
349
  ```
315
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:
354
+
355
+ ```bash
356
+ npx skills add KurtGokhan/padrone
357
+ ```
358
+
316
359
  ## 🛠️ Requirements
317
360
 
318
361
  - Node.js 18+ or Bun
@@ -0,0 +1,175 @@
1
+ //#region src/args.ts
2
+ /**
3
+ * Normalizes stdin config into its explicit form.
4
+ */
5
+ function parseStdinConfig(stdin) {
6
+ if (typeof stdin === "string") return {
7
+ field: stdin,
8
+ as: "text"
9
+ };
10
+ return {
11
+ field: stdin.field,
12
+ as: stdin.as ?? "text"
13
+ };
14
+ }
15
+ /**
16
+ * Parse positional configuration to extract names and variadic info.
17
+ */
18
+ function parsePositionalConfig(positional) {
19
+ return positional.map((p) => {
20
+ const isVariadic = p.startsWith("...");
21
+ return {
22
+ name: isVariadic ? p.slice(3) : p,
23
+ variadic: isVariadic
24
+ };
25
+ });
26
+ }
27
+ /**
28
+ * Extract all arg metadata from schema and meta in a single pass.
29
+ * This consolidates aliases, env bindings, and config keys extraction.
30
+ */
31
+ function extractSchemaMetadata(schema, meta) {
32
+ const aliases = {};
33
+ if (meta) for (const [key, value] of Object.entries(meta)) {
34
+ if (!value) continue;
35
+ if (value.alias) {
36
+ const list = typeof value.alias === "string" ? [value.alias] : value.alias;
37
+ for (const aliasKey of list) if (typeof aliasKey === "string" && aliasKey && aliasKey !== key) aliases[aliasKey] = key;
38
+ }
39
+ }
40
+ try {
41
+ const jsonSchema = schema["~standard"].jsonSchema.input({ target: "draft-2020-12" });
42
+ if (jsonSchema.type === "object" && jsonSchema.properties) for (const [propertyName, propertySchema] of Object.entries(jsonSchema.properties)) {
43
+ if (!propertySchema) continue;
44
+ const propAlias = propertySchema.alias;
45
+ if (propAlias) {
46
+ const list = typeof propAlias === "string" ? [propAlias] : propAlias;
47
+ if (Array.isArray(list)) {
48
+ for (const aliasKey of list) if (typeof aliasKey === "string" && aliasKey && aliasKey !== propertyName && !(aliasKey in aliases)) aliases[aliasKey] = propertyName;
49
+ }
50
+ }
51
+ }
52
+ } catch {}
53
+ return { aliases };
54
+ }
55
+ function preprocessAliases(data, aliases) {
56
+ const result = { ...data };
57
+ for (const [aliasKey, fullArgName] of Object.entries(aliases)) if (aliasKey in data && aliasKey !== fullArgName) {
58
+ const aliasValue = data[aliasKey];
59
+ if (!(fullArgName in result)) result[fullArgName] = aliasValue;
60
+ delete result[aliasKey];
61
+ }
62
+ return result;
63
+ }
64
+ /**
65
+ * Apply values directly to arguments.
66
+ * CLI values take precedence over the provided values.
67
+ */
68
+ function applyValues(data, values) {
69
+ const result = { ...data };
70
+ for (const [key, value] of Object.entries(values)) {
71
+ if (key in result && result[key] !== void 0) continue;
72
+ if (value !== void 0) result[key] = value;
73
+ }
74
+ return result;
75
+ }
76
+ /**
77
+ * Combined preprocessing of arguments with all features.
78
+ * Precedence order (highest to lowest): CLI args > stdin > env vars > config file
79
+ */
80
+ function preprocessArgs(data, ctx) {
81
+ let result = { ...data };
82
+ if (ctx.aliases && Object.keys(ctx.aliases).length > 0) result = preprocessAliases(result, ctx.aliases);
83
+ if (ctx.stdinData) result = applyValues(result, ctx.stdinData);
84
+ if (ctx.envData) result = applyValues(result, ctx.envData);
85
+ if (ctx.configData) result = applyValues(result, ctx.configData);
86
+ return result;
87
+ }
88
+ /**
89
+ * Auto-coerce CLI string values to match the expected schema types.
90
+ * Handles: string → number, string → boolean for primitive schema fields.
91
+ * Arrays of primitives are also coerced element-wise.
92
+ */
93
+ function coerceArgs(data, schema) {
94
+ let properties;
95
+ try {
96
+ const jsonSchema = schema["~standard"].jsonSchema.input({ target: "draft-2020-12" });
97
+ if (jsonSchema.type !== "object" || !jsonSchema.properties) return data;
98
+ properties = jsonSchema.properties;
99
+ } catch {
100
+ return data;
101
+ }
102
+ const result = { ...data };
103
+ for (const [key, value] of Object.entries(result)) {
104
+ const prop = properties[key];
105
+ if (!prop) continue;
106
+ const targetType = prop.type;
107
+ if (targetType === "number" || targetType === "integer") {
108
+ if (typeof value === "string") {
109
+ const num = Number(value);
110
+ if (!Number.isNaN(num)) result[key] = num;
111
+ }
112
+ } else if (targetType === "boolean") {
113
+ if (typeof value === "string") {
114
+ if (value === "true" || value === "1") result[key] = true;
115
+ else if (value === "false" || value === "0") result[key] = false;
116
+ }
117
+ } else if (targetType === "array" && Array.isArray(value)) {
118
+ const itemType = prop.items?.type;
119
+ if (itemType === "number" || itemType === "integer") result[key] = value.map((v) => {
120
+ if (typeof v === "string") {
121
+ const num = Number(v);
122
+ return Number.isNaN(num) ? v : num;
123
+ }
124
+ return v;
125
+ });
126
+ else if (itemType === "boolean") result[key] = value.map((v) => {
127
+ if (typeof v === "string") {
128
+ if (v === "true" || v === "1") return true;
129
+ if (v === "false" || v === "0") return false;
130
+ }
131
+ return v;
132
+ });
133
+ }
134
+ }
135
+ return result;
136
+ }
137
+ /** Keys consumed by the CLI framework that are not user-defined args. */
138
+ const frameworkReservedKeys = new Set(["config", "c"]);
139
+ /**
140
+ * Detect unknown keys in the args that don't match any schema property.
141
+ * Returns an array of { key, suggestion? } for each unknown key.
142
+ * Framework-reserved keys (--config, -c) are always allowed.
143
+ */
144
+ function detectUnknownArgs(data, schema, aliases, suggestFn) {
145
+ let properties;
146
+ let isLoose = false;
147
+ try {
148
+ const jsonSchema = schema["~standard"].jsonSchema.input({ target: "draft-2020-12" });
149
+ if (jsonSchema.type !== "object" || !jsonSchema.properties) return [];
150
+ properties = jsonSchema.properties;
151
+ if (jsonSchema.additionalProperties !== void 0 && jsonSchema.additionalProperties !== false) isLoose = true;
152
+ } catch {
153
+ return [];
154
+ }
155
+ if (isLoose) return [];
156
+ const knownKeys = new Set([
157
+ ...Object.keys(properties),
158
+ ...Object.keys(aliases),
159
+ ...Object.values(aliases)
160
+ ]);
161
+ const propertyNames = Object.keys(properties);
162
+ const unknowns = [];
163
+ for (const key of Object.keys(data)) if (!knownKeys.has(key) && !frameworkReservedKeys.has(key)) {
164
+ const suggestion = suggestFn(key, propertyNames);
165
+ unknowns.push({
166
+ key,
167
+ suggestion
168
+ });
169
+ }
170
+ return unknowns;
171
+ }
172
+ //#endregion
173
+ export { parseStdinConfig as a, parsePositionalConfig as i, detectUnknownArgs as n, preprocessArgs as o, extractSchemaMetadata as r, coerceArgs as t };
174
+
175
+ //# sourceMappingURL=args-CKNh7Dm9.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args-CKNh7Dm9.mjs","names":[],"sources":["../src/args.ts"],"sourcesContent":["import type { StandardJSONSchemaV1 } from '@standard-schema/spec';\n\nexport interface PadroneFieldMeta {\n description?: string;\n alias?: string[] | string;\n deprecated?: boolean | string;\n hidden?: boolean;\n examples?: unknown[];\n}\n\ntype PositionalArgs<TObj> =\n TObj extends Record<string, any>\n ? {\n [K in keyof TObj]: TObj[K] extends Array<any> ? `...${K & string}` : K & string;\n }[keyof TObj]\n : string;\n\n/**\n * Meta configuration for arguments, including positional arguments.\n * The `positional` array defines which arguments are positional and their order.\n * Use '...name' prefix to indicate variadic (rest) arguments, matching JS/TS rest syntax.\n *\n * @example\n * ```ts\n * .arguments(schema, {\n * positional: ['source', '...files', 'dest'], // '...files' is variadic\n * })\n * ```\n */\n/**\n * Configuration for reading from stdin and mapping it to an argument field.\n */\nexport type StdinConfig<TObj = Record<string, any>> =\n | (keyof TObj & string)\n | {\n /** The argument field to populate with stdin data. */\n field: keyof TObj & string;\n /**\n * How to consume stdin:\n * - `'text'` (default): read all stdin as a single string.\n * - `'lines'`: read stdin as an array of lines (string[]).\n */\n as?: 'text' | 'lines';\n };\n\nexport interface PadroneArgsSchemaMeta<TObj = Record<string, any>> {\n /**\n * Array of argument names that should be treated as positional arguments.\n * Order in array determines position. Use '...name' prefix for variadic args.\n * @example ['source', '...files', 'dest'] - 'files' captures multiple values\n */\n positional?: PositionalArgs<TObj>[];\n /**\n * Per-argument metadata.\n */\n fields?: { [K in keyof TObj]?: PadroneFieldMeta };\n /**\n * Read from stdin and inject the data into the specified argument field.\n * Only reads when stdin is piped (not a TTY) and the field wasn't already provided via CLI flags.\n *\n * - `string`: shorthand for `{ field: name, as: 'text' }` — read all stdin as a string.\n * - `{ field, as }`: explicit form. `as: 'text'` reads all stdin as a string,\n * `as: 'lines'` reads stdin as an array of line strings.\n *\n * Precedence: CLI flags > stdin > env vars > config file > schema defaults.\n *\n * @example\n * ```ts\n * // Shorthand: read all stdin as text into 'data' field\n * .arguments(z.object({ data: z.string() }), { stdin: 'data' })\n *\n * // Explicit: read stdin lines into 'lines' field\n * .arguments(z.object({ lines: z.string().array() }), {\n * stdin: { field: 'lines', as: 'lines' },\n * })\n * ```\n */\n stdin?: StdinConfig<TObj>;\n /**\n * Fields to interactively prompt for when their values are missing after CLI/env/config resolution.\n * - `true`: prompt for all required fields that are missing.\n * - `string[]`: prompt for these specific fields if missing.\n *\n * Interactive prompting only occurs in `cli()` when the runtime has `interactive: true`.\n * Setting this makes `parse()` and `cli()` return Promises.\n *\n * @example\n * ```ts\n * .arguments(schema, {\n * interactive: true, // prompt all missing required fields\n * interactive: ['name', 'template'], // prompt only these fields\n * })\n * ```\n */\n interactive?: true | (keyof TObj & string)[];\n /**\n * Optional fields offered after required interactive prompts.\n * Users are shown a multi-select to choose which of these fields to configure.\n * - `true`: offer all optional fields that are missing.\n * - `string[]`: offer these specific fields.\n *\n * @example\n * ```ts\n * .arguments(schema, {\n * interactive: ['name'],\n * optionalInteractive: ['typescript', 'eslint', 'prettier'],\n * })\n * ```\n */\n optionalInteractive?: true | (keyof TObj & string)[];\n}\n\n/**\n * Normalizes stdin config into its explicit form.\n */\nexport function parseStdinConfig(stdin: StdinConfig): { field: string; as: 'text' | 'lines' } {\n if (typeof stdin === 'string') return { field: stdin, as: 'text' };\n return { field: stdin.field as string, as: stdin.as ?? 'text' };\n}\n\n/**\n * Parse positional configuration to extract names and variadic info.\n */\nexport function parsePositionalConfig(positional: string[]): { name: string; variadic: boolean }[] {\n return positional.map((p) => {\n const isVariadic = p.startsWith('...');\n const name = isVariadic ? p.slice(3) : p;\n return { name, variadic: isVariadic };\n });\n}\n\n/**\n * Result type for extractSchemaMetadata function.\n */\ninterface SchemaMetadataResult {\n aliases: Record<string, string>;\n}\n\n/**\n * Extract all arg metadata from schema and meta in a single pass.\n * This consolidates aliases, env bindings, and config keys extraction.\n */\nexport function extractSchemaMetadata(\n schema: StandardJSONSchemaV1,\n meta?: Record<string, PadroneFieldMeta | undefined>,\n): SchemaMetadataResult {\n const aliases: Record<string, string> = {};\n\n // Extract from meta object\n if (meta) {\n for (const [key, value] of Object.entries(meta)) {\n if (!value) continue;\n\n // Extract aliases\n if (value.alias) {\n const list = typeof value.alias === 'string' ? [value.alias] : value.alias;\n for (const aliasKey of list) {\n if (typeof aliasKey === 'string' && aliasKey && aliasKey !== key) {\n aliases[aliasKey] = key;\n }\n }\n }\n }\n }\n\n // Extract from JSON schema properties\n try {\n const jsonSchema = schema['~standard'].jsonSchema.input({ target: 'draft-2020-12' }) as Record<string, any>;\n if (jsonSchema.type === 'object' && jsonSchema.properties) {\n for (const [propertyName, propertySchema] of Object.entries(jsonSchema.properties as Record<string, any>)) {\n if (!propertySchema) continue;\n\n // Extract aliases from schema\n const propAlias = propertySchema.alias;\n if (propAlias) {\n const list = typeof propAlias === 'string' ? [propAlias] : propAlias;\n if (Array.isArray(list)) {\n for (const aliasKey of list) {\n if (typeof aliasKey === 'string' && aliasKey && aliasKey !== propertyName && !(aliasKey in aliases)) {\n aliases[aliasKey] = propertyName;\n }\n }\n }\n }\n }\n }\n } catch {\n // Ignore errors from JSON schema generation\n }\n\n return { aliases };\n}\n\nfunction preprocessAliases(data: Record<string, unknown>, aliases: Record<string, string>): Record<string, unknown> {\n const result = { ...data };\n\n for (const [aliasKey, fullArgName] of Object.entries(aliases)) {\n if (aliasKey in data && aliasKey !== fullArgName) {\n const aliasValue = data[aliasKey];\n // Prefer full arg name if it exists\n if (!(fullArgName in result)) result[fullArgName] = aliasValue;\n delete result[aliasKey];\n }\n }\n\n return result;\n}\n\ninterface ParseArgsContext {\n aliases?: Record<string, string>;\n stdinData?: Record<string, unknown>;\n envData?: Record<string, unknown>;\n configData?: Record<string, unknown>;\n}\n\n/**\n * Apply values directly to arguments.\n * CLI values take precedence over the provided values.\n */\nfunction applyValues(data: Record<string, unknown>, values: Record<string, unknown>): Record<string, unknown> {\n const result = { ...data };\n\n for (const [key, value] of Object.entries(values)) {\n // Only apply value if arg wasn't already set\n if (key in result && result[key] !== undefined) continue;\n if (value !== undefined) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * Combined preprocessing of arguments with all features.\n * Precedence order (highest to lowest): CLI args > stdin > env vars > config file\n */\nexport function preprocessArgs(data: Record<string, unknown>, ctx: ParseArgsContext): Record<string, unknown> {\n let result = { ...data };\n\n // 1. Apply aliases first\n if (ctx.aliases && Object.keys(ctx.aliases).length > 0) {\n result = preprocessAliases(result, ctx.aliases);\n }\n\n // 2. Apply stdin data (higher precedence than env)\n // Only applies if CLI didn't set the arg\n if (ctx.stdinData) {\n result = applyValues(result, ctx.stdinData);\n }\n\n // 3. Apply environment variables (higher precedence than config)\n // These only apply if CLI/stdin didn't set the arg\n if (ctx.envData) {\n result = applyValues(result, ctx.envData);\n }\n\n // 4. Apply config file values (lowest precedence)\n // These only apply if neither CLI, stdin, nor env set the arg\n if (ctx.configData) {\n result = applyValues(result, ctx.configData);\n }\n\n return result;\n}\n\n/**\n * Auto-coerce CLI string values to match the expected schema types.\n * Handles: string → number, string → boolean for primitive schema fields.\n * Arrays of primitives are also coerced element-wise.\n */\nexport function coerceArgs(data: Record<string, unknown>, schema: StandardJSONSchemaV1): Record<string, unknown> {\n let properties: Record<string, any>;\n try {\n const jsonSchema = schema['~standard'].jsonSchema.input({ target: 'draft-2020-12' }) as Record<string, any>;\n if (jsonSchema.type !== 'object' || !jsonSchema.properties) return data;\n properties = jsonSchema.properties;\n } catch {\n return data;\n }\n\n const result = { ...data };\n\n for (const [key, value] of Object.entries(result)) {\n const prop = properties[key];\n if (!prop) continue;\n\n const targetType = prop.type as string | undefined;\n\n if (targetType === 'number' || targetType === 'integer') {\n if (typeof value === 'string') {\n const num = Number(value);\n if (!Number.isNaN(num)) result[key] = num;\n }\n } else if (targetType === 'boolean') {\n if (typeof value === 'string') {\n if (value === 'true' || value === '1') result[key] = true;\n else if (value === 'false' || value === '0') result[key] = false;\n }\n } else if (targetType === 'array' && Array.isArray(value)) {\n const itemType = prop.items?.type as string | undefined;\n if (itemType === 'number' || itemType === 'integer') {\n result[key] = value.map((v) => {\n if (typeof v === 'string') {\n const num = Number(v);\n return Number.isNaN(num) ? v : num;\n }\n return v;\n });\n } else if (itemType === 'boolean') {\n result[key] = value.map((v) => {\n if (typeof v === 'string') {\n if (v === 'true' || v === '1') return true;\n if (v === 'false' || v === '0') return false;\n }\n return v;\n });\n }\n }\n }\n\n return result;\n}\n\n/** Keys consumed by the CLI framework that are not user-defined args. */\nconst frameworkReservedKeys = new Set(['config', 'c']);\n\n/**\n * Detect unknown keys in the args that don't match any schema property.\n * Returns an array of { key, suggestion? } for each unknown key.\n * Framework-reserved keys (--config, -c) are always allowed.\n */\nexport function detectUnknownArgs(\n data: Record<string, unknown>,\n schema: StandardJSONSchemaV1,\n aliases: Record<string, string>,\n suggestFn: (input: string, candidates: string[]) => string,\n): { key: string; suggestion: string }[] {\n let properties: Record<string, any>;\n let isLoose = false;\n try {\n const jsonSchema = schema['~standard'].jsonSchema.input({ target: 'draft-2020-12' }) as Record<string, any>;\n if (jsonSchema.type !== 'object' || !jsonSchema.properties) return [];\n properties = jsonSchema.properties;\n // If additionalProperties is set (true, {}, or a schema), the schema allows extra keys\n if (jsonSchema.additionalProperties !== undefined && jsonSchema.additionalProperties !== false) isLoose = true;\n } catch {\n return [];\n }\n\n if (isLoose) return [];\n\n const knownKeys = new Set<string>([...Object.keys(properties), ...Object.keys(aliases), ...Object.values(aliases)]);\n const propertyNames = Object.keys(properties);\n const unknowns: { key: string; suggestion: string }[] = [];\n\n for (const key of Object.keys(data)) {\n if (!knownKeys.has(key) && !frameworkReservedKeys.has(key)) {\n const suggestion = suggestFn(key, propertyNames);\n unknowns.push({ key, suggestion });\n }\n }\n\n return unknowns;\n}\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { createRequire } from "node:module";
2
+ //#region \0rolldown/runtime.js
3
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
4
+ //#endregion
5
+ export { __require as t };