@politty/zod 0.0.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 (41) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +561 -0
  3. package/bin/cli.mjs +3 -0
  4. package/dist/arg-registry-YaWTVu_x.d.ts +1025 -0
  5. package/dist/augment.d.ts +15 -0
  6. package/dist/augment.js +1 -0
  7. package/dist/cli-main-Dn88vIyn.js +84 -0
  8. package/dist/cli-run-eibUcgys.js +7 -0
  9. package/dist/cli.d.ts +1 -0
  10. package/dist/cli.js +16 -0
  11. package/dist/command-k-4yAz4J.js +42 -0
  12. package/dist/compile-cache-Ct41pWGL.js +100 -0
  13. package/dist/compile-cache.d.ts +78 -0
  14. package/dist/compile-cache.js +3 -0
  15. package/dist/completion-gtWX3mwP.js +5608 -0
  16. package/dist/completion.d.ts +242 -0
  17. package/dist/completion.js +4 -0
  18. package/dist/docs.d.ts +770 -0
  19. package/dist/docs.js +3044 -0
  20. package/dist/field-meta-DMy5BcRr.js +146 -0
  21. package/dist/index-CvhsecfS.d.ts +455 -0
  22. package/dist/index.d.ts +799 -0
  23. package/dist/index.js +17 -0
  24. package/dist/log-collector-CoUkLVJB.js +114 -0
  25. package/dist/logger-i_bb-Jhc.js +133 -0
  26. package/dist/prompt-CEIZ-7H1.js +171 -0
  27. package/dist/prompt-clack.d.ts +16 -0
  28. package/dist/prompt-clack.js +32 -0
  29. package/dist/prompt-inquirer.d.ts +16 -0
  30. package/dist/prompt-inquirer.js +47 -0
  31. package/dist/prompt.d.ts +106 -0
  32. package/dist/prompt.js +4 -0
  33. package/dist/register-Bk0K83W2.js +439 -0
  34. package/dist/runner-D72I7wvK.js +2956 -0
  35. package/dist/runner-FvUwOHyE.js +3 -0
  36. package/dist/schema-extractor-DMSozq40.js +250 -0
  37. package/dist/skill.d.ts +608 -0
  38. package/dist/skill.js +1832 -0
  39. package/dist/src-KzC0g5CS.js +191 -0
  40. package/dist/subcommand-router-Cskpofdk.js +134 -0
  41. package/package.json +103 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 toiroakr
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,561 @@
1
+ # politty
2
+
3
+ **politty** is a lightweight, type-safe CLI framework for Node.js built on **Zod v4**.
4
+
5
+ From simple scripts to complex CLI tools with subcommands, validation, and auto-generated help, you can build them all with a developer-friendly API.
6
+
7
+ ## Features
8
+
9
+ - **Zod Native**: Use Zod schemas directly for argument definition and validation
10
+ - **Type Safety**: Full TypeScript support with automatic type inference for parsed arguments
11
+ - **Flexible Argument Definition**: Support for positional arguments, flags, aliases, arrays, and environment variable fallbacks
12
+ - **Subcommands**: Build Git-style nested subcommands (with lazy loading and alias support)
13
+ - **Lifecycle Management**: Guaranteed `setup` → `run` → `cleanup` execution order
14
+ - **Signal Handling**: Proper SIGINT/SIGTERM handling with guaranteed cleanup execution
15
+ - **Auto Help Generation**: Automatically generate help text from definitions
16
+ - **Interactive Prompts**: Prompt for missing arguments with pluggable adapters (clack, inquirer)
17
+ - **Discriminated Union**: Support for mutually exclusive argument sets
18
+ - **Skill Management**: Manage agent skills (SKILL.md) with file-based install/uninstall
19
+ - **Fast Startup**: Automatic Node.js compile cache (V8 code cache) integration, with a `generate-shim` command to cache the whole CLI graph
20
+
21
+ ## Requirements
22
+
23
+ - Node.js >= 20.12.0 (excluding 21.0.0 - 21.6.x)
24
+ - Zod >= 4.2.1
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ npm install politty zod
30
+ # or
31
+ pnpm add politty zod
32
+ # or
33
+ yarn add politty zod
34
+ ```
35
+
36
+ ### Using valibot instead of zod
37
+
38
+ politty is also available as [`@politty/valibot`](https://www.npmjs.com/package/@politty/valibot), built on [valibot](https://valibot.dev/) schemas — same API (`defineCommand`, `arg`, `runMain`, and all subpath modules), and its published build never loads zod:
39
+
40
+ ```bash
41
+ npm install @politty/valibot valibot
42
+ ```
43
+
44
+ ```typescript
45
+ import * as v from "valibot";
46
+ import { defineCommand, runMain, arg } from "@politty/valibot";
47
+
48
+ const command = defineCommand({
49
+ name: "greet",
50
+ args: v.object({
51
+ name: arg(v.string(), { description: "Name to greet", positional: true }),
52
+ loud: arg(v.optional(v.boolean(), false), { alias: "l" }),
53
+ }),
54
+ run: (args) => {
55
+ const greeting = `Hello, ${args.name}!`;
56
+ console.log(args.loud ? greeting.toUpperCase() : greeting);
57
+ },
58
+ });
59
+
60
+ runMain(command);
61
+ ```
62
+
63
+ Field descriptions can also come from valibot's own metadata actions. They are actions, not schemas, so they belong inside `v.pipe(...)`: `v.pipe(v.string(), v.description("..."))` or `v.pipe(v.string(), v.metadata({ description: "..." }))`. The one zod-only feature without a valibot counterpart is the `politty/augment` module (zod `GlobalMeta` interface augmentation) — use `arg()` or `v.metadata()` instead. The `politty` package itself remains the zod flavor (an alias of `@politty/zod`).
64
+
65
+ ## Quick Start
66
+
67
+ ```typescript
68
+ import { z } from "zod";
69
+ import { defineCommand, runMain, arg } from "politty";
70
+
71
+ const command = defineCommand({
72
+ name: "greet",
73
+ description: "A CLI tool that displays greetings",
74
+ args: z.object({
75
+ name: arg(z.string(), {
76
+ positional: true,
77
+ description: "Name of the person to greet",
78
+ }),
79
+ greeting: arg(z.string().default("Hello"), {
80
+ alias: "g",
81
+ description: "Greeting phrase",
82
+ }),
83
+ loud: arg(z.boolean().default(false), {
84
+ alias: "l",
85
+ description: "Output in uppercase",
86
+ }),
87
+ }),
88
+ run: (args) => {
89
+ let message = `${args.greeting}, ${args.name}!`;
90
+ if (args.loud) {
91
+ message = message.toUpperCase();
92
+ }
93
+ console.log(message);
94
+ },
95
+ });
96
+
97
+ runMain(command);
98
+ ```
99
+
100
+ Example usage:
101
+
102
+ ```bash
103
+ $ my-cli World
104
+ Hello, World!
105
+
106
+ $ my-cli World -g "Hi" -l
107
+ HI, WORLD!
108
+
109
+ $ my-cli --help
110
+ Usage: greet <name> [options]
111
+
112
+ A CLI tool that displays greetings
113
+
114
+ Arguments:
115
+ name Name of the person to greet
116
+
117
+ Options:
118
+ -g, --greeting <value> Greeting phrase (default: "Hello")
119
+ -l, --loud Output in uppercase
120
+ -h, --help Show help
121
+ ```
122
+
123
+ ## Basic Usage
124
+
125
+ ### Defining Arguments
126
+
127
+ Use the `arg()` function to define argument metadata:
128
+
129
+ ```typescript
130
+ import { z } from "zod";
131
+ import { arg, defineCommand } from "politty";
132
+
133
+ const command = defineCommand({
134
+ name: "example",
135
+ args: z.object({
136
+ // Positional argument (required)
137
+ input: arg(z.string(), {
138
+ positional: true,
139
+ description: "Input file",
140
+ }),
141
+
142
+ // Optional positional argument
143
+ output: arg(z.string().optional(), {
144
+ positional: true,
145
+ description: "Output file",
146
+ }),
147
+
148
+ // Flag (with alias)
149
+ verbose: arg(z.boolean().default(false), {
150
+ alias: "v",
151
+ description: "Verbose output",
152
+ }),
153
+
154
+ // Environment variable fallback
155
+ apiKey: arg(z.string().optional(), {
156
+ env: "API_KEY",
157
+ description: "API key",
158
+ }),
159
+
160
+ // Array argument (--file a.txt --file b.txt)
161
+ files: arg(z.array(z.string()).default([]), {
162
+ alias: "f",
163
+ description: "Files to process",
164
+ }),
165
+ }),
166
+ run: (args) => {
167
+ console.log(args);
168
+ },
169
+ });
170
+ ```
171
+
172
+ Use `args.$source(name)` to check whether a value came from an explicit CLI token, an `env` fallback, or neither (e.g. a schema default). It's typed as optional since directly-constructed args objects (e.g. in unit tests) won't have it:
173
+
174
+ ```typescript
175
+ run: (args) => {
176
+ args.$source?.("apiKey"); // "cli" | "env" | "default"
177
+ },
178
+ ```
179
+
180
+ ### Subcommands
181
+
182
+ Define Git-style subcommands:
183
+
184
+ ```typescript
185
+ import { z } from "zod";
186
+ import { arg, defineCommand, runMain } from "politty";
187
+
188
+ const initCommand = defineCommand({
189
+ name: "init",
190
+ description: "Initialize a project",
191
+ aliases: ["i"],
192
+ args: z.object({
193
+ template: arg(z.string().default("default"), {
194
+ alias: "t",
195
+ description: "Template name",
196
+ }),
197
+ }),
198
+ run: (args) => {
199
+ console.log(`Initializing with template: ${args.template}`);
200
+ },
201
+ });
202
+
203
+ const buildCommand = defineCommand({
204
+ name: "build",
205
+ description: "Build the project",
206
+ aliases: ["b"],
207
+ args: z.object({
208
+ output: arg(z.string().default("dist"), {
209
+ alias: "o",
210
+ description: "Output directory",
211
+ }),
212
+ minify: arg(z.boolean().default(false), {
213
+ alias: "m",
214
+ description: "Minify output",
215
+ }),
216
+ }),
217
+ run: (args) => {
218
+ console.log(`Building to: ${args.output}`);
219
+ },
220
+ });
221
+
222
+ const cli = defineCommand({
223
+ name: "my-cli",
224
+ description: "Example CLI with subcommands",
225
+ subCommands: {
226
+ init: initCommand,
227
+ build: buildCommand,
228
+ },
229
+ });
230
+
231
+ runMain(cli, { version: "1.0.0" });
232
+ ```
233
+
234
+ Example usage:
235
+
236
+ ```bash
237
+ $ my-cli init -t react
238
+ $ my-cli i -t react # alias for init
239
+ $ my-cli build -o out -m
240
+ $ my-cli b -o out -m # alias for build
241
+ $ my-cli --help
242
+ ```
243
+
244
+ ### Lifecycle Hooks
245
+
246
+ Execute hooks in `setup` → `run` → `cleanup` order. The `cleanup` hook is always executed, even if an error occurs:
247
+
248
+ ```typescript
249
+ const command = defineCommand({
250
+ name: "db-query",
251
+ description: "Execute database queries",
252
+ args: z.object({
253
+ database: arg(z.string(), {
254
+ alias: "d",
255
+ description: "Database connection string",
256
+ }),
257
+ query: arg(z.string(), {
258
+ alias: "q",
259
+ description: "SQL query",
260
+ }),
261
+ }),
262
+ setup: async ({ args }) => {
263
+ console.log("[setup] Connecting to database...");
264
+ // Establish DB connection
265
+ },
266
+ run: async (args) => {
267
+ console.log("[run] Executing query...");
268
+ // Execute query
269
+ return { rowCount: 42 };
270
+ },
271
+ cleanup: async ({ args, error }) => {
272
+ console.log("[cleanup] Closing connection...");
273
+ if (error) {
274
+ console.error(`Error occurred: ${error.message}`);
275
+ }
276
+ // Close connection
277
+ },
278
+ });
279
+ ```
280
+
281
+ ## API
282
+
283
+ ### `defineCommand(options)`
284
+
285
+ Define a command.
286
+
287
+ | Option | Type | Description |
288
+ | ------------- | ----------------------------- | ------------------- |
289
+ | `name` | `string` | Command name |
290
+ | `description` | `string?` | Command description |
291
+ | `args` | `ZodSchema` | Argument schema |
292
+ | `aliases` | `string[]?` | Command aliases |
293
+ | `subCommands` | `Record<string, Command>?` | Subcommands |
294
+ | `setup` | `(context) => Promise<void>?` | Setup hook |
295
+ | `run` | `(args) => T?` | Run function |
296
+ | `cleanup` | `(context) => Promise<void>?` | Cleanup hook |
297
+
298
+ ### `runMain(command, options?)`
299
+
300
+ CLI entry point. Handles signals and calls `process.exit()`.
301
+
302
+ ```typescript
303
+ runMain(command, {
304
+ version: "1.0.0", // Displayed with --version flag
305
+ });
306
+ ```
307
+
308
+ ### `runCommand(command, argv, options?)`
309
+
310
+ Programmatic/testing entry point. Does not call `process.exit()` and returns a result object.
311
+
312
+ ```typescript
313
+ const result = await runCommand(command, ["arg1", "--flag"]);
314
+ if (result.success) {
315
+ console.log(result.result);
316
+ } else {
317
+ console.error(result.error);
318
+ }
319
+ ```
320
+
321
+ ### `arg(schema, meta)`
322
+
323
+ Attach metadata to an argument.
324
+
325
+ | Metadata | Type | Description |
326
+ | ------------- | ------------- | ------------------------------------------------------------------------ |
327
+ | `positional` | `boolean?` | Treat as positional argument |
328
+ | `alias` | `string?` | Short alias (e.g., `-v`) |
329
+ | `description` | `string?` | Argument description |
330
+ | `placeholder` | `string?` | Placeholder shown in help |
331
+ | `env` | `string?` | Environment variable name (fallback) |
332
+ | `completion` | `object?` | Shell completion configuration |
333
+ | `prompt` | `PromptMeta?` | Interactive prompt configuration ([docs](./docs/interactive-prompts.md)) |
334
+
335
+ ## Shell Completion
336
+
337
+ politty provides automatic shell completion generation for bash, zsh, and fish.
338
+ The default generated script is a small runtime dispatcher: when the user
339
+ presses TAB, it resolves the executable currently visible on `PATH` and uses a
340
+ bundled static worker from that executable's package when one is available. If
341
+ no package-relative bundled worker is found, it falls back to a per-binary
342
+ static worker cache and regenerates that cache from the hidden
343
+ `__refresh-completion` command when needed. Sourced workers are memoized for the
344
+ shell session, so warm completions call the worker function directly.
345
+ Completion fields that require runtime JavaScript still delegate to the
346
+ binary's hidden `__complete` command.
347
+ When `NODE_COMPILE_CACHE` is unset, the dispatcher sets it to a
348
+ program-specific cache directory before invoking `__complete`, letting Node.js
349
+ 22+ reuse V8 module compile cache across repeated completion requests.
350
+
351
+ ### Quick Setup
352
+
353
+ Use `withCompletionCommand` to add completion support to your CLI:
354
+
355
+ ```typescript
356
+ import { defineCommand, runMain, withCompletionCommand } from "politty";
357
+
358
+ const mainCommand = withCompletionCommand(
359
+ defineCommand({
360
+ name: "mycli",
361
+ subCommands: {
362
+ build: buildCommand,
363
+ test: testCommand,
364
+ },
365
+ }),
366
+ );
367
+
368
+ runMain(mainCommand);
369
+ ```
370
+
371
+ Then users can enable completions:
372
+
373
+ ```bash
374
+ # Bash
375
+ eval "$(mycli completion bash)"
376
+
377
+ # Zsh
378
+ eval "$(mycli completion zsh)"
379
+
380
+ # Fish
381
+ mycli completion fish | source
382
+ ```
383
+
384
+ For project-local CLIs, put the local binary directory in `PATH` with your
385
+ environment manager, for example:
386
+
387
+ ```sh
388
+ # .envrc
389
+ PATH_add node_modules/.bin
390
+ ```
391
+
392
+ Completion then follows the same executable the shell would run.
393
+
394
+ Published CLIs can ship a fast worker artifact:
395
+
396
+ ```bash
397
+ politty generate-worker --bin dist/cli/index.mjs --program mycli --shell zsh --verify
398
+ ```
399
+
400
+ or call `generateBundledCompletionWorker()` from `politty/completion` in your
401
+ own build script. The default output path is
402
+ `dist/completion/<shell>-worker.<ext>`.
403
+
404
+ The dispatcher looks for common package-relative worker paths such as
405
+ `dist/completion/zsh-worker.zsh` from the visible binary. Use
406
+ `withCompletionCommand({ bundledWorker: { relativePaths: { zsh: [...] } } })`
407
+ to customize the package-relative lookup. For package layouts that cannot be
408
+ expressed with relative paths, `bundledWorker.queryCommand: true` lets the
409
+ dispatcher ask the binary's hidden `__completion-worker-path` command on the
410
+ miss path.
411
+
412
+ To generate the older static script with command metadata baked in, use:
413
+
414
+ ```bash
415
+ eval "$(mycli completion bash --static)"
416
+ eval "$(mycli completion zsh --static)"
417
+ ```
418
+
419
+ ### Value Completion
420
+
421
+ Define completion hints for arguments:
422
+
423
+ ```typescript
424
+ const command = defineCommand({
425
+ name: "build",
426
+ args: z.object({
427
+ // Auto-detected from z.enum()
428
+ format: arg(z.enum(["json", "yaml", "xml"]), {
429
+ alias: "f",
430
+ description: "Output format",
431
+ }),
432
+
433
+ // File completion
434
+ config: arg(z.string(), {
435
+ completion: { type: "file", extensions: ["json", "yaml"] },
436
+ }),
437
+
438
+ // Directory completion
439
+ outputDir: arg(z.string(), {
440
+ completion: { type: "directory" },
441
+ }),
442
+
443
+ // Custom shell command
444
+ branch: arg(z.string().optional(), {
445
+ completion: {
446
+ custom: { shellCommand: "git branch --format='%(refname:short)'" },
447
+ },
448
+ }),
449
+
450
+ // Static choices
451
+ environment: arg(z.string(), {
452
+ completion: {
453
+ custom: { choices: ["development", "staging", "production"] },
454
+ },
455
+ }),
456
+ }),
457
+ run: (args) => {
458
+ /* ... */
459
+ },
460
+ });
461
+ ```
462
+
463
+ ## Faster Startup (Compile Cache)
464
+
465
+ politty integrates Node.js's on-disk compile cache (V8 code cache, Node >= 22.8.0) so warm starts skip recompilation; older runtimes are a silent no-op. `runMain` enables it automatically, which covers dynamically imported modules such as `lazy()` subcommands. To cache the whole CLI graph — politty, zod, and your command definitions — generate a bin shim as part of your build:
466
+
467
+ ```jsonc
468
+ // package.json
469
+ {
470
+ "bin": { "my-cli": "./dist/bin.js" },
471
+ "scripts": {
472
+ "build": "tsdown", // builds src/cli.ts -> dist/cli.js
473
+ "postbuild": "politty generate-shim --entry ./cli.js",
474
+ },
475
+ }
476
+ ```
477
+
478
+ `generate-shim` writes an executable shim that enables the cache and loads `--entry` (a specifier relative to the shim) with a dynamic import. The rest is derived from `package.json`: the output path from the `bin` path and the program name from the `bin` name; packages with multiple bins pass `--entry` once per bin, and `--entry` itself can be omitted when the entry sits next to the shim under a conventional name (`./cli.js`, `./index.js`, ...). See [Faster Startup (Compile Cache)](./docs/recipes.md#faster-startup-compile-cache) for the flags, the opt-out (`compileCache: false`), and the hand-written shim variant.
479
+
480
+ ## Skill Management
481
+
482
+ politty manages SKILL.md-based agent skills distributed via npm packages.
483
+
484
+ ### Quick Setup
485
+
486
+ Use `withSkillCommand` to add skill management to your CLI:
487
+
488
+ ```typescript
489
+ import { dirname, resolve } from "node:path";
490
+ import { fileURLToPath } from "node:url";
491
+ import { defineCommand, runMain } from "politty";
492
+ import { withSkillCommand } from "politty/skill";
493
+
494
+ // Resolves to ../skills from both src/ and dist/
495
+ const sourceDir = resolve(dirname(fileURLToPath(import.meta.url)), "../skills");
496
+
497
+ const cli = withSkillCommand(
498
+ defineCommand({
499
+ name: "my-agent",
500
+ subCommands: {/* ... */},
501
+ }),
502
+ { sourceDir, package: "@my-agent/skills" },
503
+ );
504
+
505
+ runMain(cli);
506
+ ```
507
+
508
+ `package` identifies who owns these skills. It is combined with the command name as `"{package}:{cliName}"` and must match the `metadata["politty-cli"]` stamp pre-declared in each source SKILL.md — `skills add`/`sync` refuse mismatches, and `remove`/`sync` refuse to delete skills belonging to another tool. The default install mode is `"symlink"` (`.agents/skills/<name>` -> source, `.claude/skills/<name>` -> canonical), so source updates propagate live; on filesystems without symlink support (e.g. Windows without Developer Mode) install throws with guidance to retry with `mode: "copy"`, which recursively copies instead (source updates then require re-running `sync`). See [Skill Management](./docs/skill-management.md) for details.
509
+
510
+ Skills are SKILL.md files with YAML frontmatter (spec-compliant: https://agentskills.io/specification). The `metadata["politty-cli"]` stamp is authored by the skill package:
511
+
512
+ ```markdown
513
+ ---
514
+ name: commit
515
+ description: Git commit message generation
516
+ license: MIT
517
+ metadata:
518
+ politty-cli: "@my-agent/skills:my-agent"
519
+ ---
520
+
521
+ # Instructions for the agent...
522
+ ```
523
+
524
+ Then users can manage skills:
525
+
526
+ ```bash
527
+ my-agent skills sync # Remove and reinstall all skills
528
+ my-agent skills add commit # Install a specific skill
529
+ my-agent skills remove commit # Remove a specific skill
530
+ my-agent skills list # List available skills
531
+ ```
532
+
533
+ ## Documentation
534
+
535
+ For detailed documentation, see the `docs/` directory:
536
+
537
+ - [Getting Started](./docs/getting-started.md) - Installation and creating your first command
538
+ - [Essentials](./docs/essentials.md) - Core concepts explained
539
+ - [Advanced Features](./docs/advanced-features.md) - Subcommands, Discriminated Union
540
+ - [Interactive Prompts](./docs/interactive-prompts.md) - Prompt for missing arguments interactively
541
+ - [Recipes](./docs/recipes.md) - Testing, configuration, error handling, faster startup (compile cache)
542
+ - [Skill Management](./docs/skill-management.md) - Agent skill management (SKILL.md-based)
543
+ - [API Reference](./docs/api-reference.md) - Detailed API reference
544
+ - [Doc Generation](./docs/doc-generation.md) - Automatic documentation generation
545
+
546
+ ## Examples
547
+
548
+ The `playground/` directory contains many examples:
549
+
550
+ - `01-hello-world` - Minimal command configuration
551
+ - `02-greet` - Positional arguments and flags
552
+ - `03-array-args` - Array arguments
553
+ - `05-lifecycle-hooks` - Lifecycle hooks
554
+ - `10-subcommands` - Subcommands
555
+ - `12-discriminated-union` - Discriminated Union
556
+ - `21-lazy-subcommands` - Lazy loading
557
+ - `26-command-alias` - Command aliases
558
+
559
+ ## License
560
+
561
+ MIT
package/bin/cli.mjs ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ // Committed launcher: pnpm only links a bin whose target exists at install time.
3
+ import "../dist/cli.js";