padrone 1.4.0 → 1.6.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.
- package/CHANGELOG.md +115 -0
- package/README.md +108 -283
- package/dist/args-Cnq0nwSM.mjs +272 -0
- package/dist/args-Cnq0nwSM.mjs.map +1 -0
- package/dist/codegen/index.d.mts +28 -3
- package/dist/codegen/index.d.mts.map +1 -1
- package/dist/codegen/index.mjs +169 -19
- package/dist/codegen/index.mjs.map +1 -1
- package/dist/commands-B_gufyR9.mjs +514 -0
- package/dist/commands-B_gufyR9.mjs.map +1 -0
- package/dist/{completion.mjs → completion-BEuflbDO.mjs} +86 -108
- package/dist/completion-BEuflbDO.mjs.map +1 -0
- package/dist/docs/index.d.mts +22 -2
- package/dist/docs/index.d.mts.map +1 -1
- package/dist/docs/index.mjs +92 -7
- package/dist/docs/index.mjs.map +1 -1
- package/dist/errors-CL63UOzt.mjs +137 -0
- package/dist/errors-CL63UOzt.mjs.map +1 -0
- package/dist/{formatter-ClUK5hcQ.d.mts → formatter-DrvhDMrq.d.mts} +35 -6
- package/dist/formatter-DrvhDMrq.d.mts.map +1 -0
- package/dist/help-B5Kk83of.mjs +849 -0
- package/dist/help-B5Kk83of.mjs.map +1 -0
- package/dist/index-BaU3X6dY.d.mts +1178 -0
- package/dist/index-BaU3X6dY.d.mts.map +1 -0
- package/dist/index.d.mts +763 -36
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +3608 -1534
- package/dist/index.mjs.map +1 -1
- package/dist/mcp-BM-d0nZi.mjs +377 -0
- package/dist/mcp-BM-d0nZi.mjs.map +1 -0
- package/dist/serve-Bk0JUlCj.mjs +402 -0
- package/dist/serve-Bk0JUlCj.mjs.map +1 -0
- package/dist/stream-DC4H8YTx.mjs +77 -0
- package/dist/stream-DC4H8YTx.mjs.map +1 -0
- package/dist/test.d.mts +5 -8
- package/dist/test.d.mts.map +1 -1
- package/dist/test.mjs +5 -27
- package/dist/test.mjs.map +1 -1
- package/dist/{update-check-EbNDkzyV.mjs → update-check-CZ2VqjnV.mjs} +16 -17
- package/dist/update-check-CZ2VqjnV.mjs.map +1 -0
- package/dist/zod.d.mts +32 -0
- package/dist/zod.d.mts.map +1 -0
- package/dist/zod.mjs +50 -0
- package/dist/zod.mjs.map +1 -0
- package/package.json +20 -9
- package/src/cli/completions.ts +14 -11
- package/src/cli/docs.ts +13 -16
- package/src/cli/doctor.ts +213 -24
- package/src/cli/index.ts +28 -82
- package/src/cli/init.ts +12 -10
- package/src/cli/link.ts +22 -18
- package/src/cli/wrap.ts +14 -11
- package/src/codegen/discovery.ts +80 -28
- package/src/codegen/index.ts +2 -1
- package/src/codegen/parsers/bash.ts +179 -0
- package/src/codegen/schema-to-code.ts +2 -1
- package/src/core/args.ts +296 -0
- package/src/core/commands.ts +373 -0
- package/src/core/create.ts +268 -0
- package/src/{runtime.ts → core/default-runtime.ts} +70 -135
- package/src/{errors.ts → core/errors.ts} +22 -0
- package/src/core/exec.ts +259 -0
- package/src/core/interceptors.ts +302 -0
- package/src/{parse.ts → core/parse.ts} +36 -89
- package/src/core/program-methods.ts +301 -0
- package/src/core/results.ts +229 -0
- package/src/core/runtime.ts +246 -0
- package/src/core/validate.ts +247 -0
- package/src/docs/index.ts +124 -11
- package/src/extension/auto-output.ts +95 -0
- package/src/extension/color.ts +38 -0
- package/src/extension/completion.ts +49 -0
- package/src/extension/config.ts +262 -0
- package/src/extension/env.ts +101 -0
- package/src/extension/help.ts +192 -0
- package/src/extension/index.ts +43 -0
- package/src/extension/ink.ts +93 -0
- package/src/extension/interactive.ts +106 -0
- package/src/extension/logger.ts +214 -0
- package/src/extension/man.ts +51 -0
- package/src/extension/mcp.ts +52 -0
- package/src/extension/progress-renderer.ts +338 -0
- package/src/extension/progress.ts +299 -0
- package/src/extension/repl.ts +94 -0
- package/src/extension/serve.ts +48 -0
- package/src/extension/signal.ts +87 -0
- package/src/extension/stdin.ts +62 -0
- package/src/extension/suggestions.ts +114 -0
- package/src/extension/timing.ts +81 -0
- package/src/extension/tracing.ts +175 -0
- package/src/extension/update-check.ts +77 -0
- package/src/extension/utils.ts +51 -0
- package/src/extension/version.ts +63 -0
- package/src/{completion.ts → feature/completion.ts} +130 -57
- package/src/{interactive.ts → feature/interactive.ts} +47 -6
- package/src/feature/mcp.ts +387 -0
- package/src/{repl-loop.ts → feature/repl-loop.ts} +26 -16
- package/src/feature/serve.ts +438 -0
- package/src/feature/test.ts +262 -0
- package/src/{update-check.ts → feature/update-check.ts} +16 -16
- package/src/{wrap.ts → feature/wrap.ts} +27 -27
- package/src/index.ts +120 -11
- package/src/output/colorizer.ts +154 -0
- package/src/{formatter.ts → output/formatter.ts} +281 -135
- package/src/{help.ts → output/help.ts} +62 -15
- package/src/{zod.d.ts → schema/zod.d.ts} +1 -1
- package/src/schema/zod.ts +50 -0
- package/src/test.ts +2 -285
- package/src/types/args-meta.ts +151 -0
- package/src/types/builder.ts +697 -0
- package/src/types/command.ts +157 -0
- package/src/types/index.ts +59 -0
- package/src/types/interceptor.ts +296 -0
- package/src/types/preferences.ts +83 -0
- package/src/types/result.ts +71 -0
- package/src/types/schema.ts +19 -0
- package/src/util/dotenv.ts +244 -0
- package/src/{shell-utils.ts → util/shell-utils.ts} +26 -9
- package/src/util/stream.ts +101 -0
- package/src/{type-helpers.ts → util/type-helpers.ts} +23 -16
- package/src/{type-utils.ts → util/type-utils.ts} +99 -37
- package/src/util/utils.ts +51 -0
- package/src/zod.ts +1 -0
- package/dist/args-CVDbyyzG.mjs +0 -199
- package/dist/args-CVDbyyzG.mjs.map +0 -1
- package/dist/chunk-y_GBKt04.mjs +0 -5
- package/dist/completion.d.mts +0 -64
- package/dist/completion.d.mts.map +0 -1
- package/dist/completion.mjs.map +0 -1
- package/dist/formatter-ClUK5hcQ.d.mts.map +0 -1
- package/dist/help-CcBe91bV.mjs +0 -1254
- package/dist/help-CcBe91bV.mjs.map +0 -1
- package/dist/types-DjIdJN5G.d.mts +0 -1059
- package/dist/types-DjIdJN5G.d.mts.map +0 -1
- package/dist/update-check-EbNDkzyV.mjs.map +0 -1
- package/src/args.ts +0 -461
- package/src/colorizer.ts +0 -41
- package/src/command-utils.ts +0 -532
- package/src/create.ts +0 -1477
- package/src/types.ts +0 -1109
- package/src/utils.ts +0 -140
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,120 @@
|
|
|
1
1
|
# padrone
|
|
2
2
|
|
|
3
|
+
## 1.6.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`75066f9`](https://github.com/KurtGokhan/padrone/commit/75066f9e12c33a1f64c502e248fce4d4e455d0da) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Improve "Did you mean?" suggestions for typos in commands and options. Return multiple matches (up to 3), add prefix/substring matching for inputs longer than 3 characters, and include `--` prefix in option suggestions. Suggestions are now included in soft-mode validation errors too.
|
|
8
|
+
|
|
9
|
+
- [`93ab85c`](https://github.com/KurtGokhan/padrone/commit/93ab85c88441e9062b2402f7d97f3d337293f2e7) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add typed context support. Define context with `.context<T>()` or `.context(transform)`, provide it via `cli()`, `eval()`, `run()`, and access it in action handlers as `ctx.context` and in all plugin phase contexts. Subcommands inherit context from parents. `.mount()` accepts an optional `{ context }` transform. New `InferContext` type helper.
|
|
10
|
+
|
|
11
|
+
- [`3b7fed0`](https://github.com/KurtGokhan/padrone/commit/3b7fed06d15cc2acad04df7d919ce0f6c9b66207) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add typed context injection for interceptors. Interceptors can declare provided context via `.provides<T>()` and required context via `.requires<T>()` on `defineInterceptor()`. Action handlers see the full merged context type. `.intercept()` rejects interceptors whose required context is not satisfied at compile time.
|
|
12
|
+
|
|
13
|
+
- [`067b9f7`](https://github.com/KurtGokhan/padrone/commit/067b9f7d695a838f0c39204c563029f8a2527675) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add extension system with `.extend()` for build-time composition. Rename plugins to interceptors (`.use()` → `.intercept()`, `PadronePlugin` → `PadroneInterceptor`). Move built-in commands to composable extensions. Default builtins (help, version, repl, color, config, interactive) are applied automatically via `createPadrone()`. Advanced features (completion, man, mcp, serve, update-check) are opt-in extensions. Individual builtins can be disabled via `createPadrone('name', { builtins: { help: false } })`.
|
|
14
|
+
|
|
15
|
+
- [`4e7f88b`](https://github.com/KurtGokhan/padrone/commit/4e7f88bdc68b7c97f36e3546142b6ebf5f87f76e) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Respect terminal width in help output. Default and choices metadata now appear inline with descriptions when space allows, and long descriptions wrap aligned to the description column.
|
|
16
|
+
|
|
17
|
+
- [`aa0b568`](https://github.com/KurtGokhan/padrone/commit/aa0b568f35c2fcb97a78abf077561a914606de6f) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add support for Ink apps. The `ink` interceptor renders an Ink app as part of a command's execution, and waits for it to unmount before proceeding.
|
|
18
|
+
|
|
19
|
+
- [`91fd814`](https://github.com/KurtGokhan/padrone/commit/91fd8146c0fff0eb8c4e5f46191d1a6bf8203ecf) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add `padroneLogger()` and `padroneTiming()` extensions for structured logging and command execution timing.
|
|
20
|
+
|
|
21
|
+
- [`99c8cfa`](https://github.com/KurtGokhan/padrone/commit/99c8cfa298194d9632b9c784858c1695e7782acf) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add `program.info` for read-only access to program metadata (name, version, description, commands, etc.). Add XDG config directory support via `xdg` option on `padroneConfig()`.
|
|
22
|
+
|
|
23
|
+
- [`88c45af`](https://github.com/KurtGokhan/padrone/commit/88c45afeef123d4a3e5d5e4d359e080ddf60a154) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add elapsed time (`time: true`) and ETA (`eta: true`) to progress indicators. ETA is calculated from numeric progress updates and counts down between updates. Move progress messages into a `message` field (string or `{ validation, progress, success, error }` object) with runtime-level defaults via context.
|
|
24
|
+
|
|
25
|
+
- [`8691694`](https://github.com/KurtGokhan/padrone/commit/86916947b189109e6647684d30dc06992a3909b5) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Improve runtime agnosticism. Add `terminal` and `exit` fields to `PadroneRuntime`. Replace `Buffer` usage with `Uint8Array`/`TextEncoder`. Route scattered `process.*` reads through runtime abstraction. Replace all `require()` calls with dynamic `import()`. Use `runtime.onSignal` in serve/MCP instead of direct `process.on`.
|
|
26
|
+
|
|
27
|
+
- [`4343f78`](https://github.com/KurtGokhan/padrone/commit/4343f7857b6685c8e1774b4d933846cd786fe828) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add signal handling support for graceful shutdown. Actions and plugins receive an `AbortSignal` via `ctx.signal` that aborts on SIGINT/SIGTERM/SIGHUP. Command results include `signal` and `exitCode` fields when interrupted. Double Ctrl+C within 2 seconds force-quits. Export new `SignalError` class and `PadroneSignal` type.
|
|
28
|
+
|
|
29
|
+
- [`7464026`](https://github.com/KurtGokhan/padrone/commit/746402615e11262a0ff7257f41a4840c3a54143e) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Reject unknown options for commands without `.arguments()`. Previously, commands without a schema accepted all options silently. Now they infer an empty object and error on unknown options.
|
|
30
|
+
|
|
31
|
+
- [`be62401`](https://github.com/KurtGokhan/padrone/commit/be624016ee6e4852ab043b15b4d525431319a168) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add experimental `padroneTracing()` extension for OpenTelemetry tracing. Logger automatically bridges log calls to span events when tracing is active.
|
|
32
|
+
|
|
33
|
+
### Patch Changes
|
|
34
|
+
|
|
35
|
+
- [`dbac7ec`](https://github.com/KurtGokhan/padrone/commit/dbac7ec56a9f0c320550eef2f6b188a3741d1d4e) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add `runtime` to interceptor contexts. Interceptors can now access and override the runtime via `ctx.runtime` instead of calling `getCommandRuntime()`. Support `next()` overrides for passing modified context to downstream interceptors.
|
|
36
|
+
|
|
37
|
+
- [`0dfae77`](https://github.com/KurtGokhan/padrone/commit/0dfae774d264d4cab092b90bb779dd3da46abaef) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Collect repeated non-array options into an array for the validator. Enables schemas like `z.union([z.string(), z.array(z.string())])` to receive all values when an option is passed multiple times.
|
|
38
|
+
|
|
39
|
+
## 1.5.0
|
|
40
|
+
|
|
41
|
+
### Minor Changes
|
|
42
|
+
|
|
43
|
+
- [`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.
|
|
44
|
+
|
|
45
|
+
- [`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.
|
|
46
|
+
|
|
47
|
+
- [`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".
|
|
48
|
+
|
|
49
|
+
- [`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.
|
|
50
|
+
|
|
51
|
+
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.
|
|
52
|
+
|
|
53
|
+
- [`3d7b282`](https://github.com/KurtGokhan/padrone/commit/3d7b28202890925e05357c9796218349b4a8410e) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add per-field validation during interactive prompts.
|
|
54
|
+
|
|
55
|
+
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.
|
|
56
|
+
|
|
57
|
+
- [`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.
|
|
58
|
+
|
|
59
|
+
- [`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.
|
|
60
|
+
|
|
61
|
+
- [`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:
|
|
62
|
+
|
|
63
|
+
- Success: `{ command, args, argsResult, result, drain() }`
|
|
64
|
+
- Error: `{ error, command?, args?, argsResult?, drain() }`
|
|
65
|
+
|
|
66
|
+
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:
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
const { value, error } = await program.cli().drain();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
New exported types: `PadroneDrainResult<T>`, `Drained<T>`.
|
|
73
|
+
|
|
74
|
+
- [`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.
|
|
75
|
+
|
|
76
|
+
**Auto-managed progress** via `.progress()` builder method:
|
|
77
|
+
|
|
78
|
+
- `true` or `string` for simple messages, or a full config object with per-state messages
|
|
79
|
+
- Starts before validation, auto-succeeds/fails after execution
|
|
80
|
+
- Validation-phase message transitions to execution-phase message
|
|
81
|
+
- `spinner` option: preset name (`dots`, `line`, `arc`, `bounce`), custom `{ frames, interval }`, or `false` to disable animation
|
|
82
|
+
- `success`/`error` fields accept static strings, `null` to suppress, callbacks `(result) => string | null`, or `{ message, indicator }` objects for per-call icon customization
|
|
83
|
+
|
|
84
|
+
**Manual progress** via `ctx.progress` in action handlers:
|
|
85
|
+
|
|
86
|
+
- Works even without `.progress()` config — lazily creates a real indicator on first use
|
|
87
|
+
- Auto-stopped when execution finishes (no leaked spinners)
|
|
88
|
+
- No-op when the runtime has no progress factory
|
|
89
|
+
|
|
90
|
+
**Built-in terminal spinner** (`createTerminalSpinner`):
|
|
91
|
+
|
|
92
|
+
- ANSI-based spinner with pause/resume for clean output interleaving
|
|
93
|
+
- Customizable success/error indicator icons via `PadroneProgressOptions`
|
|
94
|
+
- Empty string indicators hide the icon prefix entirely
|
|
95
|
+
- Graceful fallback in non-TTY/CI environments
|
|
96
|
+
|
|
97
|
+
**New types**: `PadroneProgressIndicator`, `PadroneProgressConfig`, `PadroneProgressMessage`, `PadroneProgressOptions`, `PadroneSpinnerConfig`, `PadroneSpinnerPreset`
|
|
98
|
+
|
|
99
|
+
- [`6851b48`](https://github.com/KurtGokhan/padrone/commit/6851b4878ab0fc8d48f40e93c2f8924236a40165) Thanks [@KurtGokhan](https://github.com/KurtGokhan)! - Add REST server (`program.serve()`) and `mutation` command config.
|
|
100
|
+
|
|
101
|
+
- New `serve()` program method: exposes commands as HTTP endpoints with automatic OpenAPI docs (Scalar).
|
|
102
|
+
- New `serve` built-in CLI command: `myapp serve --port 3000`.
|
|
103
|
+
- Built-in endpoints: `/_health`, `/_help`, `/_schema`, `/_docs` (Scalar), `/_openapi`.
|
|
104
|
+
- New `mutation` option in `.configure()`: mutation commands are POST-only in serve, set `destructiveHint` in MCP, and default `needsApproval` to true in `tool()`.
|
|
105
|
+
- MCP: rename `endpoint` to `basePath` for consistency with serve.
|
|
106
|
+
- Shared utilities extracted from MCP (`collectEndpoints`, `buildInputSchema`, `serializeArgsToFlags`).
|
|
107
|
+
|
|
108
|
+
### Patch Changes
|
|
109
|
+
|
|
110
|
+
- [`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).
|
|
111
|
+
|
|
112
|
+
- [`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.
|
|
113
|
+
|
|
114
|
+
- [`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()`
|
|
115
|
+
|
|
116
|
+
- [`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.
|
|
117
|
+
|
|
3
118
|
## 1.4.0
|
|
4
119
|
|
|
5
120
|
### 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>
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
##
|
|
21
|
+
## Install
|
|
30
22
|
|
|
31
23
|
```bash
|
|
32
|
-
# Using npm
|
|
33
24
|
npm install padrone zod
|
|
25
|
+
```
|
|
34
26
|
|
|
35
|
-
|
|
36
|
-
bun add padrone zod
|
|
27
|
+
## Scaffold a New Project
|
|
37
28
|
|
|
38
|
-
|
|
39
|
-
pnpm add padrone zod
|
|
29
|
+
The fastest way to get started is with `padrone init`:
|
|
40
30
|
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
```bash
|
|
32
|
+
npx padrone init my-cli
|
|
33
|
+
cd my-cli && bun i && bun dev
|
|
43
34
|
```
|
|
44
35
|
|
|
45
|
-
##
|
|
36
|
+
## Quick Start
|
|
46
37
|
|
|
47
38
|
```typescript
|
|
48
39
|
import { createPadrone } from 'padrone';
|
|
@@ -54,320 +45,154 @@ 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
|
|
67
|
-
|
|
68
|
-
|
|
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
|
-
|
|
88
|
-
```
|
|
89
|
-
Hello, Mr. John!
|
|
90
|
-
Hello, Mr. Jane!
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
## 📖 Usage Examples
|
|
94
|
-
|
|
95
|
-
### Programmatic Execution
|
|
96
|
-
|
|
97
|
-
```typescript
|
|
98
|
-
// Run a command directly with typed arguments
|
|
99
|
-
program.run('greet', { names: ['John', 'Jane'], prefix: 'Dr.' });
|
|
100
|
-
|
|
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
|
|
107
|
-
|
|
108
|
-
Generate a typed API from your CLI program:
|
|
109
|
-
|
|
110
|
-
```typescript
|
|
111
|
-
const api = program.api();
|
|
112
|
-
|
|
113
|
-
// Call commands as functions with full type safety
|
|
114
|
-
api.greet({ names: ['Alice', 'Bob'], prefix: 'Dr.' });
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
### Nested Commands
|
|
118
|
-
|
|
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
|
-
);
|
|
146
|
-
|
|
147
|
-
// Run nested command
|
|
148
|
-
program.eval('forecast extended London');
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### Option Aliases and Metadata
|
|
68
|
+
## What It Does
|
|
152
69
|
|
|
153
70
|
```typescript
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
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
|
-
```
|
|
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
|
|
181
76
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
Padrone supports loading arguments from environment variables and config files using dedicated schema methods:
|
|
185
|
-
|
|
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
|
-
```
|
|
77
|
+
// Parse without executing
|
|
78
|
+
const { args } = program.parse('greet John --prefix Mr.');
|
|
221
79
|
|
|
222
|
-
|
|
80
|
+
// Interactive REPL
|
|
81
|
+
for await (const result of program.repl()) { /* ... */ }
|
|
223
82
|
|
|
224
|
-
|
|
83
|
+
// AI tool for Vercel AI SDK
|
|
84
|
+
const tool = program.tool();
|
|
225
85
|
|
|
226
|
-
|
|
86
|
+
// MCP server for AI assistants (Claude, Cursor, etc.) [experimental]
|
|
87
|
+
await program.mcp(); // or: myapp mcp
|
|
227
88
|
|
|
228
|
-
|
|
229
|
-
|
|
89
|
+
// REST server with OpenAPI docs [experimental]
|
|
90
|
+
await program.serve(); // or: myapp serve
|
|
230
91
|
|
|
231
|
-
|
|
232
|
-
|
|
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
|
-
);
|
|
92
|
+
// Shell completions
|
|
93
|
+
const script = program.completion('zsh');
|
|
240
94
|
|
|
241
|
-
//
|
|
242
|
-
|
|
95
|
+
// Help in multiple formats
|
|
96
|
+
program.help('greet'); // text
|
|
97
|
+
program.help('greet', { format: 'json' }); // json, markdown, html, ansi
|
|
243
98
|
```
|
|
244
99
|
|
|
245
|
-
##
|
|
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
|
-
```
|
|
100
|
+
## Features at a Glance
|
|
277
101
|
|
|
278
|
-
|
|
102
|
+
**Arguments** — positional args, variadic args, short flags (`-v`), long aliases (`--dry-run`), auto kebab-case aliases, negatable booleans (`--no-verbose`).
|
|
279
103
|
|
|
280
|
-
|
|
104
|
+
**Env & Config** — load from environment variables with `.extend(padroneEnv(schema))` and config files with `.extend(padroneConfig({ files, schema }))`. Precedence: CLI > stdin > env > config > defaults.
|
|
281
105
|
|
|
282
|
-
|
|
283
|
-
console.log(program.help());
|
|
284
|
-
```
|
|
106
|
+
**Interactive prompts** — auto-prompt for missing fields. Booleans become confirm, enums become select, arrays become multi-select.
|
|
285
107
|
|
|
286
|
-
|
|
287
|
-
```
|
|
288
|
-
Usage: myapp greet [names...] [arguments]
|
|
108
|
+
**Progress indicators** — auto-managed spinners and progress bars with elapsed time and ETA. `.extend(padroneProgress({ message: 'Deploying...', bar: true, time: true, eta: true }))`.
|
|
289
109
|
|
|
290
|
-
|
|
291
|
-
names... Names to greet
|
|
110
|
+
**Extension-first architecture** — most built-in features (help, version, REPL, color, signal handling, auto-output, stdin, config, interactive, suggestions) are implemented as extensions composed via `.extend()`. Any built-in can be disabled or replaced.
|
|
292
111
|
|
|
293
|
-
|
|
294
|
-
-p, --prefix <string> Prefix to use in greeting
|
|
295
|
-
-h, --help Show help
|
|
296
|
-
```
|
|
112
|
+
**Interceptors** — middleware hooks for 6 phases (start, parse, validate, execute, error, shutdown). Onion model with `next()`. Extensions register interceptors under the hood. Create your own with `defineInterceptor()`.
|
|
297
113
|
|
|
298
|
-
|
|
114
|
+
**Composition** — mount programs as subcommands with `.mount()`, override commands with merge semantics.
|
|
299
115
|
|
|
300
|
-
|
|
116
|
+
**Wrapping** *(experimental)* — wrap external CLI tools with `.wrap({ command: 'git', args: ['commit'] })`.
|
|
301
117
|
|
|
302
|
-
|
|
118
|
+
## API
|
|
303
119
|
|
|
304
|
-
###
|
|
120
|
+
### Builder (define commands)
|
|
305
121
|
|
|
306
|
-
| Method |
|
|
122
|
+
| Method | What it does |
|
|
123
|
+
|--------|-------------|
|
|
124
|
+
| `.arguments(schema, meta?)` | Define args with Zod schema, positional config, field metadata |
|
|
125
|
+
| `.action(handler)` | Set handler `(args, ctx, base?) => result` |
|
|
126
|
+
| `.command(name, builder)` | Add subcommand (name or `[name, ...aliases]`) |
|
|
127
|
+
| `.context(transform?)` | Define typed context or transform inherited context |
|
|
128
|
+
| `.mount(name, program, options?)` | Mount another program as subcommand tree |
|
|
129
|
+
| `.configure(config)` | Set title, description, version, etc. |
|
|
130
|
+
| `.extend(padroneEnv(schema))` | Map env vars to args (composable extension) |
|
|
131
|
+
| `.extend(padroneConfig({ files, schema }))` | Load args from config files (composable extension) |
|
|
132
|
+
| `.wrap(config)` | Wrap an external CLI tool *(experimental)* |
|
|
133
|
+
| `.extend(padroneProgress(config?))` | Auto-managed progress indicator (extension) |
|
|
134
|
+
| `.intercept(interceptor)` | Register middleware interceptor (use `defineInterceptor()`) |
|
|
135
|
+
| `.extend(extension)` | Apply a build-time extension (bundle of config, commands, interceptors) |
|
|
136
|
+
| `.runtime(runtime)` | Custom I/O (for non-terminal use) |
|
|
137
|
+
| `.updateCheck(config?)` | Background version check |
|
|
138
|
+
| `.async()` | Mark as async validation |
|
|
139
|
+
|
|
140
|
+
### Program (run commands)
|
|
141
|
+
|
|
142
|
+
| Method | What it does |
|
|
307
143
|
|--------|-------------|
|
|
308
|
-
| `.
|
|
309
|
-
| `.
|
|
310
|
-
| `.
|
|
311
|
-
| `.
|
|
312
|
-
| `.
|
|
313
|
-
| `.
|
|
314
|
-
| `.
|
|
315
|
-
| `.
|
|
316
|
-
| `.
|
|
317
|
-
| `.
|
|
318
|
-
| `.
|
|
319
|
-
| `.
|
|
320
|
-
| `.
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
144
|
+
| `.cli(prefs?)` | Entry point — parses `process.argv`, throws on errors. Pass `context` in prefs. |
|
|
145
|
+
| `.eval(input, prefs?)` | Parse + validate + execute string, returns errors softly. Pass `context` in prefs. |
|
|
146
|
+
| `.run(command, args, prefs?)` | Run by name with typed args (no validation). Pass `context` in prefs. |
|
|
147
|
+
| `.parse(input?)` | Parse without executing |
|
|
148
|
+
| `.api()` | Generate typed function API |
|
|
149
|
+
| `.repl(options?)` | Interactive REPL session |
|
|
150
|
+
| `.help(command?, prefs?)` | Generate help (text, ansi, markdown, html, json) |
|
|
151
|
+
| `.tool()` | Vercel AI SDK tool definition |
|
|
152
|
+
| `.mcp(prefs?)` | Start MCP server (HTTP or stdio) *(experimental)* |
|
|
153
|
+
| `.serve(prefs?)` | Start REST server with OpenAPI docs *(experimental)* |
|
|
154
|
+
| `.completion(shell?)` | Shell completion script |
|
|
155
|
+
| `.find(command)` | Look up command by path |
|
|
156
|
+
| `.stringify(command?, args?)` | Convert back to CLI string |
|
|
157
|
+
|
|
158
|
+
### Zod `.meta()` fields
|
|
159
|
+
|
|
160
|
+
| Field | Example | Purpose |
|
|
161
|
+
|-------|---------|---------|
|
|
162
|
+
| `flags` | `'v'` | Single-char short flag (`-v`) |
|
|
163
|
+
| `alias` | `'dry-run'` | Multi-char long alias (`--dry-run`) |
|
|
164
|
+
| `examples` | `['8080']` | Example values in help |
|
|
165
|
+
| `deprecated` | `'Use --debug'` | Deprecation warning |
|
|
166
|
+
| `hidden` | `true` | Hide from help |
|
|
167
|
+
| `group` | `'Advanced'` | Group in help output |
|
|
168
|
+
|
|
169
|
+
### Arguments meta (second param of `.arguments()`)
|
|
327
170
|
|
|
328
171
|
```typescript
|
|
329
172
|
.arguments(schema, {
|
|
330
|
-
positional: ['source', '...files', 'dest'],
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
173
|
+
positional: ['source', '...files', 'dest'],
|
|
174
|
+
interactive: ['name', 'template'],
|
|
175
|
+
optionalInteractive: ['typescript'],
|
|
176
|
+
fields: { verbose: { flags: 'v' } },
|
|
177
|
+
stdin: 'data',
|
|
178
|
+
autoAlias: true, // default
|
|
335
179
|
})
|
|
336
180
|
```
|
|
337
181
|
|
|
338
|
-
|
|
182
|
+
## Agent Skill
|
|
339
183
|
|
|
340
|
-
|
|
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:
|
|
184
|
+
Give your AI coding agent knowledge of the Padrone API:
|
|
354
185
|
|
|
355
186
|
```bash
|
|
356
187
|
npx skills add KurtGokhan/padrone
|
|
357
188
|
```
|
|
358
189
|
|
|
359
|
-
##
|
|
190
|
+
## Requirements
|
|
360
191
|
|
|
361
192
|
- Node.js 18+ or Bun
|
|
362
193
|
- TypeScript 5.0+ (recommended)
|
|
363
|
-
- Zod
|
|
194
|
+
- Zod (or any Standard Schema-compatible library)
|
|
364
195
|
|
|
365
|
-
##
|
|
196
|
+
## License
|
|
366
197
|
|
|
367
|
-
[MIT](LICENSE)
|
|
368
|
-
|
|
369
|
-
---
|
|
370
|
-
|
|
371
|
-
<p align="center">
|
|
372
|
-
Made with ❤️ by <a href="https://gkurt.com">Gokhan Kurt</a>
|
|
373
|
-
</p>
|
|
198
|
+
[MIT](LICENSE)
|