@andrei.fyi/picocli 0.1.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/README.md +357 -0
- package/dist/create-eQnnIhZu.d.cts +87 -0
- package/dist/create-eQnnIhZu.d.ts +87 -0
- package/dist/index.cjs +1175 -0
- package/dist/index.d.cts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +1166 -0
- package/dist/mcp/index.cjs +507 -0
- package/dist/mcp/index.d.cts +30 -0
- package/dist/mcp/index.d.ts +30 -0
- package/dist/mcp/index.js +502 -0
- package/dist/testing/testkit.cjs +115 -0
- package/dist/testing/testkit.d.cts +23 -0
- package/dist/testing/testkit.d.ts +23 -0
- package/dist/testing/testkit.js +112 -0
- package/package.json +94 -0
package/README.md
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
# picocli
|
|
2
|
+
|
|
3
|
+
Tiny CLI framework for Node and Bun.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pnpm add @andrei.fyi/picocli zod
|
|
7
|
+
# or
|
|
8
|
+
bun add @andrei.fyi/picocli zod
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Requires Node.js ≥ 22 or Bun, and `zod@^4`.
|
|
12
|
+
|
|
13
|
+
## Quickstart
|
|
14
|
+
|
|
15
|
+
Sample code:
|
|
16
|
+
|
|
17
|
+
```ts
|
|
18
|
+
import cli from "@andrei.fyi/picocli";
|
|
19
|
+
import { z } from "zod";
|
|
20
|
+
|
|
21
|
+
// create app
|
|
22
|
+
const app = cli.create("gh", {
|
|
23
|
+
version: "1.0.0",
|
|
24
|
+
description: "Tiny GitHub-style CLI",
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// create and add a command directly
|
|
28
|
+
app.command("status", {
|
|
29
|
+
description: "Show repository status",
|
|
30
|
+
run: () => {
|
|
31
|
+
const result = { clean: true, branch: "main" };
|
|
32
|
+
console.log(`clean (branch: ${result.branch})`);
|
|
33
|
+
},
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// create a command and then add it
|
|
37
|
+
// if it has no run() handler it will just print the help for its subcommands
|
|
38
|
+
const pr = cli.command("pr", {
|
|
39
|
+
description: "Manage pull requests",
|
|
40
|
+
});
|
|
41
|
+
// create and add a subcommand
|
|
42
|
+
pr.command("list", {
|
|
43
|
+
alias: "ls", // alternate command name
|
|
44
|
+
description: "List pull requests", // help & MCP tool description
|
|
45
|
+
args: z.object({
|
|
46
|
+
repo: z.string().describe("owner/name"), // positional args
|
|
47
|
+
}),
|
|
48
|
+
options: z.object({
|
|
49
|
+
state: z.enum(["open", "closed", "all"]).default("open").describe("Filter by state"), // --state
|
|
50
|
+
}),
|
|
51
|
+
env: z.object({
|
|
52
|
+
GITHUB_TOKEN: z.string().optional().describe("GitHub token"),
|
|
53
|
+
}),
|
|
54
|
+
outputSchema: z.object({
|
|
55
|
+
prs: z.array(z.object({ number: z.number(), title: z.string() })),
|
|
56
|
+
state: z.enum(["open", "closed", "all"]),
|
|
57
|
+
authenticated: z.boolean(),
|
|
58
|
+
}), // describes --json data and MCP output schema
|
|
59
|
+
examples: [{ command: "gh pr list acme/widgets --state closed" }], // shown in --help
|
|
60
|
+
hidden: false, // true hides from help and MCP
|
|
61
|
+
run: ({ args, options, env }) => {
|
|
62
|
+
const prs = [{ number: 1, title: `Fix CI in ${args.repo}` }];
|
|
63
|
+
for (const pull of prs) console.log(`#${pull.number} ${pull.title}`);
|
|
64
|
+
|
|
65
|
+
// returned value is used for --json and MCP tool result
|
|
66
|
+
return { prs, state: options.state, authenticated: Boolean(env.GITHUB_TOKEN) };
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
app.command(pr);
|
|
70
|
+
|
|
71
|
+
app.serve();
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Sample output:
|
|
75
|
+
|
|
76
|
+
```console
|
|
77
|
+
$ gh
|
|
78
|
+
Usage: gh <command>
|
|
79
|
+
|
|
80
|
+
Tiny GitHub-style CLI
|
|
81
|
+
|
|
82
|
+
Commands:
|
|
83
|
+
status Show repository status
|
|
84
|
+
pr Manage pull requests
|
|
85
|
+
|
|
86
|
+
Global options:
|
|
87
|
+
--help show help
|
|
88
|
+
--version print version
|
|
89
|
+
--json emit JSON output
|
|
90
|
+
--format <value> output format: pretty | json
|
|
91
|
+
--color / --no-color force/disable color (--color / --no-color)
|
|
92
|
+
--mcp run as an MCP stdio server
|
|
93
|
+
--llms print a Markdown command manifest
|
|
94
|
+
--schema print input/output JSON Schemas for the command
|
|
95
|
+
|
|
96
|
+
$ gh status
|
|
97
|
+
clean (branch: main)
|
|
98
|
+
|
|
99
|
+
$ gh pr
|
|
100
|
+
Usage: gh pr <command>
|
|
101
|
+
|
|
102
|
+
Manage pull requests
|
|
103
|
+
|
|
104
|
+
Commands:
|
|
105
|
+
list (ls) List pull requests
|
|
106
|
+
|
|
107
|
+
Global options:
|
|
108
|
+
--help show help
|
|
109
|
+
--version print version
|
|
110
|
+
--json emit JSON output
|
|
111
|
+
--format <value> output format: pretty | json
|
|
112
|
+
--color / --no-color force/disable color (--color / --no-color)
|
|
113
|
+
--mcp run as an MCP stdio server
|
|
114
|
+
--llms print a Markdown command manifest
|
|
115
|
+
--schema print input/output JSON Schemas for the command
|
|
116
|
+
|
|
117
|
+
$ gh pr list acme/widgets --state closed
|
|
118
|
+
#1 Fix CI in acme/widgets
|
|
119
|
+
|
|
120
|
+
$ gh pr ls acme/widgets --state closed --json
|
|
121
|
+
{"prs":[{"number":1,"title":"Fix CI in acme/widgets"}],"state":"closed","authenticated":false}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Examples
|
|
125
|
+
|
|
126
|
+
Examples live in [`examples/`](./examples/README.md) and are grouped by what you are trying to learn:
|
|
127
|
+
|
|
128
|
+
| Area | Examples |
|
|
129
|
+
| ---- | -------- |
|
|
130
|
+
| Basics | smallest app, options/coercion, returned data with `outputSchema` |
|
|
131
|
+
| Commands | direct commands, nested command trees, inherited options/env |
|
|
132
|
+
| Runtime IO | env schemas, stdin, raw tokens after `--` |
|
|
133
|
+
| Integrations | `--schema`, feature toggles, thrown errors |
|
|
134
|
+
| Testing | `runCli()` and `runJson()` |
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
bun run examples/basics/hello.ts Ada
|
|
138
|
+
bun run examples/commands/nested-tree.ts task list --state closed
|
|
139
|
+
bun run examples/io/rest.ts rest -- --raw -x
|
|
140
|
+
bun run examples/testing/testkit.ts
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Defining commands
|
|
144
|
+
|
|
145
|
+
Use `cli.create()` for the root app. Use `cli.command()` for commands you mount under an app or command.
|
|
146
|
+
|
|
147
|
+
Common definition fields:
|
|
148
|
+
|
|
149
|
+
| Field | Meaning |
|
|
150
|
+
| ---- | ---- |
|
|
151
|
+
| `description` | Help text; MCP tool description for runnable commands |
|
|
152
|
+
| `args` | Positional arguments, assigned by schema key order |
|
|
153
|
+
| `options` | Named `--flags`; booleans support `--flag` and `--no-flag` |
|
|
154
|
+
| `env` | Environment variables read by exact key name |
|
|
155
|
+
| `outputSchema` | Describes successful structured data and MCP output schema |
|
|
156
|
+
| `validateOutput` | Validate returned data against `outputSchema`; defaults to `"development"` |
|
|
157
|
+
| `examples` | Help examples |
|
|
158
|
+
| `run` | Command handler |
|
|
159
|
+
| `version` | Value printed by `--version` |
|
|
160
|
+
|
|
161
|
+
Root app fields:
|
|
162
|
+
|
|
163
|
+
| Field | Meaning |
|
|
164
|
+
| ---- | ---- |
|
|
165
|
+
| `features` | Enable or disable optional built-in flags; all enabled by default |
|
|
166
|
+
|
|
167
|
+
Child command fields:
|
|
168
|
+
|
|
169
|
+
| Field | Meaning |
|
|
170
|
+
| ---- | ---- |
|
|
171
|
+
| `alias` | Alternate command name |
|
|
172
|
+
| `hidden` | Hide from help and MCP |
|
|
173
|
+
|
|
174
|
+
`run()` owns normal output. Print to stdout, start a TUI, call APIs, or return nothing.
|
|
175
|
+
|
|
176
|
+
Return a value when `--json` or MCP should receive structured data. In structured mode, `console.*`
|
|
177
|
+
is suppressed. If `run()` returns a value, `--json` prints that value directly; if it returns
|
|
178
|
+
nothing, structured output is `null`.
|
|
179
|
+
|
|
180
|
+
The object passed to `run()` is the command context. Destructure only the fields you need:
|
|
181
|
+
|
|
182
|
+
```ts
|
|
183
|
+
run: ({ args }) => {
|
|
184
|
+
console.log(`hello ${args.name}`);
|
|
185
|
+
return { greeted: args.name };
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Context fields:
|
|
190
|
+
|
|
191
|
+
| Field | Meaning |
|
|
192
|
+
| ---- | ---- |
|
|
193
|
+
| `name` | Resolved command name |
|
|
194
|
+
| `args` | Parsed positional args |
|
|
195
|
+
| `options` | Parsed options, including inherited parent options |
|
|
196
|
+
| `env` | Parsed env values, including inherited parent env |
|
|
197
|
+
| `isTTY` | stdout is an interactive terminal |
|
|
198
|
+
| `isJSON` | structured output was requested |
|
|
199
|
+
| `rest` | tokens after `--` |
|
|
200
|
+
| `readStdin()` | read piped stdin |
|
|
201
|
+
|
|
202
|
+
### Zod coercion
|
|
203
|
+
|
|
204
|
+
CLI values arrive as strings. Booleans are inferred from presence. Use `z.coerce.*` for other
|
|
205
|
+
non-string values.
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
options: z.object({
|
|
209
|
+
port: z.coerce.number().default(3000),
|
|
210
|
+
when: z.coerce.date().optional(),
|
|
211
|
+
})
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Output schemas
|
|
215
|
+
|
|
216
|
+
`outputSchema` describes returned data and is included in the MCP output schema. Runtime validation
|
|
217
|
+
is controlled by `validateOutput`, which defaults to `"development"`: invalid returned data fails
|
|
218
|
+
only when `NODE_ENV=development`. Use `true` to always validate, or `false` to always return
|
|
219
|
+
best-effort data.
|
|
220
|
+
|
|
221
|
+
```ts
|
|
222
|
+
app.command("status", {
|
|
223
|
+
outputSchema: z.object({
|
|
224
|
+
clean: z.boolean(),
|
|
225
|
+
branch: z.string(),
|
|
226
|
+
}),
|
|
227
|
+
validateOutput: "development",
|
|
228
|
+
run: () => ({ clean: true, branch: "main" }),
|
|
229
|
+
});
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Invalid returned data exits with a `VALIDATION` error only when output validation is enabled.
|
|
233
|
+
|
|
234
|
+
### Subcommands
|
|
235
|
+
|
|
236
|
+
Add a command directly:
|
|
237
|
+
|
|
238
|
+
```ts
|
|
239
|
+
app.command("status", {
|
|
240
|
+
alias: "st",
|
|
241
|
+
run: () => console.log("clean"),
|
|
242
|
+
});
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Or build it separately and mount it:
|
|
246
|
+
|
|
247
|
+
```ts
|
|
248
|
+
const pr = cli.command("pr", {
|
|
249
|
+
description: "Manage pull requests",
|
|
250
|
+
run: () => console.log("use `gh pr list` to list pull requests"),
|
|
251
|
+
});
|
|
252
|
+
pr.command("list", { alias: "ls", run: () => console.log("no open PRs") });
|
|
253
|
+
app.command(pr);
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
If a command has subcommands but no `run`, invoking it prints its help.
|
|
257
|
+
|
|
258
|
+
### Inheritance
|
|
259
|
+
|
|
260
|
+
Direct child definitions inherit parent `options` and `env` schemas in the handler type. Child
|
|
261
|
+
fields win on name conflicts.
|
|
262
|
+
|
|
263
|
+
```ts
|
|
264
|
+
const app = cli.create("app", {
|
|
265
|
+
options: z.object({ verbose: z.boolean().default(false) }),
|
|
266
|
+
env: z.object({ TOKEN: z.string().optional() }),
|
|
267
|
+
});
|
|
268
|
+
app.command("build", {
|
|
269
|
+
options: z.object({ target: z.string() }),
|
|
270
|
+
run: ({ options, env }) => {
|
|
271
|
+
options.verbose;
|
|
272
|
+
options.target;
|
|
273
|
+
env.TOKEN;
|
|
274
|
+
},
|
|
275
|
+
});
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Separately built `cli.command()` trees are typed from their own schemas. Repeat shared `options` or
|
|
279
|
+
`env` on that tree when its handlers need typed access:
|
|
280
|
+
|
|
281
|
+
```ts
|
|
282
|
+
const pr = cli.command("pr", {
|
|
283
|
+
env: z.object({ TOKEN: z.string().optional() }),
|
|
284
|
+
});
|
|
285
|
+
pr.command("list", {
|
|
286
|
+
run: ({ env }) => {
|
|
287
|
+
env.TOKEN;
|
|
288
|
+
},
|
|
289
|
+
});
|
|
290
|
+
app.command(pr);
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Inherited options appear in help and `--schema`. Inherited options and env appear in `--llms`; MCP
|
|
294
|
+
input schemas include options, while env is read from the server environment.
|
|
295
|
+
|
|
296
|
+
## Output, color, exit codes
|
|
297
|
+
|
|
298
|
+
Normal mode is human output. picocli does not print returned values unless structured output is
|
|
299
|
+
requested.
|
|
300
|
+
|
|
301
|
+
| Behavior | Rule |
|
|
302
|
+
| ---- | ---- |
|
|
303
|
+
| Structured output | `--json` or `--format json` |
|
|
304
|
+
| Color | `--color` / `--no-color`, then `FORCE_COLOR` / `NO_COLOR`, then TTY |
|
|
305
|
+
| Success | exit `0` |
|
|
306
|
+
| Usage or validation error | exit `2` |
|
|
307
|
+
| Handler failure | exit `1` |
|
|
308
|
+
| Error format | `error (CODE): message` or structured JSON |
|
|
309
|
+
|
|
310
|
+
## Built-in flags
|
|
311
|
+
|
|
312
|
+
| Flag | Effect |
|
|
313
|
+
| ---- | ------ |
|
|
314
|
+
| `--help` | Show help (hidden commands omitted) |
|
|
315
|
+
| `--version` | Print the CLI version |
|
|
316
|
+
| `--json` / `--format <pretty\|json>` | `json` prints the structured data; `pretty` (default) is human |
|
|
317
|
+
| `--color` / `--no-color` | Force/disable ANSI color |
|
|
318
|
+
| `--mcp` | Run as an MCP stdio server |
|
|
319
|
+
| `--llms` | Print a Markdown command manifest |
|
|
320
|
+
| `--schema` | Print `{ input, output }` JSON Schemas for the resolved command |
|
|
321
|
+
|
|
322
|
+
If a command declares an option that collides with a built-in name, the **command's option
|
|
323
|
+
wins** and that built-in is disabled for it.
|
|
324
|
+
|
|
325
|
+
Disable optional built-in flags independently:
|
|
326
|
+
|
|
327
|
+
```ts
|
|
328
|
+
cli.create("internal", {
|
|
329
|
+
features: { mcp: false, schema: false, llms: false },
|
|
330
|
+
});
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## MCP
|
|
334
|
+
|
|
335
|
+
`--mcp` starts a stdio MCP server. Every non-hidden runnable command becomes a tool. Nested command
|
|
336
|
+
names are joined with `_`. Input schemas come from args and options. Output schemas are generated
|
|
337
|
+
from `outputSchema`.
|
|
338
|
+
|
|
339
|
+
The MCP SDK is lazy-loaded through `@andrei.fyi/picocli/mcp`; install `@modelcontextprotocol/sdk` if you use
|
|
340
|
+
`--mcp` or import that subpath.
|
|
341
|
+
|
|
342
|
+
## Testing
|
|
343
|
+
|
|
344
|
+
`@andrei.fyi/picocli/testing` runs commands in-process.
|
|
345
|
+
|
|
346
|
+
```ts
|
|
347
|
+
import { runCli, runJson } from "@andrei.fyi/picocli/testing";
|
|
348
|
+
|
|
349
|
+
const r = await runCli(app, ["Ada", "--loud"]);
|
|
350
|
+
expect(r.stdout).toBe("HELLO ADA\n");
|
|
351
|
+
expect(r.exitCode).toBe(0);
|
|
352
|
+
|
|
353
|
+
const j = await runJson(app, ["Ada", "--loud"]);
|
|
354
|
+
expect(j.json).toEqual({ message: "HELLO ADA" });
|
|
355
|
+
|
|
356
|
+
await runCli(app, ["Ada"], { isTTY: true, env: { NO_COLOR: "1" }, stdin: "piped" });
|
|
357
|
+
```
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
type Merge<Parent, Child> = Child & Omit<Parent, keyof Child>;
|
|
4
|
+
|
|
5
|
+
type ContextValue<Schema extends z.ZodObject<z.ZodRawShape> | undefined> = Schema extends z.ZodObject<z.ZodRawShape> ? z.infer<Schema> : Record<never, never>;
|
|
6
|
+
type OutputValue<Schema extends z.ZodType | undefined> = Schema extends z.ZodType ? z.infer<Schema> : unknown;
|
|
7
|
+
type CommandRunReturn<Schema extends z.ZodType | undefined> = Schema extends z.ZodType ? OutputValue<Schema> | Promise<OutputValue<Schema>> : unknown;
|
|
8
|
+
type OutputValidationMode = "development" | boolean;
|
|
9
|
+
interface CommandContextValue<Args, Options, Env> {
|
|
10
|
+
name: string;
|
|
11
|
+
args: Args;
|
|
12
|
+
options: Options;
|
|
13
|
+
env: Env;
|
|
14
|
+
isTTY: boolean;
|
|
15
|
+
isJSON: boolean;
|
|
16
|
+
rest: string[];
|
|
17
|
+
readStdin: () => Promise<string>;
|
|
18
|
+
}
|
|
19
|
+
type Context<ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined> = CommandContextValue<ContextValue<ArgsSchema>, ContextValue<OptionsSchema>, ContextValue<EnvSchema>>;
|
|
20
|
+
type ChildContext<ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined, ParentOptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined, ParentEnvSchema extends z.ZodObject<z.ZodRawShape> | undefined> = CommandContextValue<ContextValue<ArgsSchema>, Merge<ContextValue<ParentOptionsSchema>, ContextValue<OptionsSchema>>, Merge<ContextValue<ParentEnvSchema>, ContextValue<EnvSchema>>>;
|
|
21
|
+
interface CommandDefinition<ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, HandlerContext = Context<ArgsSchema, OptionsSchema, EnvSchema>, OutputSchema extends z.ZodType | undefined = undefined> {
|
|
22
|
+
description?: string;
|
|
23
|
+
args?: ArgsSchema;
|
|
24
|
+
options?: OptionsSchema;
|
|
25
|
+
env?: EnvSchema;
|
|
26
|
+
outputSchema?: OutputSchema;
|
|
27
|
+
validateOutput?: OutputValidationMode;
|
|
28
|
+
alias?: string[] | string;
|
|
29
|
+
examples?: {
|
|
30
|
+
command: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
}[];
|
|
33
|
+
version?: string;
|
|
34
|
+
hidden?: boolean;
|
|
35
|
+
run?: (context: HandlerContext) => CommandRunReturn<OutputSchema>;
|
|
36
|
+
}
|
|
37
|
+
interface CliFeatures {
|
|
38
|
+
mcp?: boolean;
|
|
39
|
+
schema?: boolean;
|
|
40
|
+
llms?: boolean;
|
|
41
|
+
}
|
|
42
|
+
type AppDefinition<ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, HandlerContext = Context<ArgsSchema, OptionsSchema, EnvSchema>, OutputSchema extends z.ZodType | undefined = undefined> = Omit<CommandDefinition<ArgsSchema, OptionsSchema, EnvSchema, HandlerContext, OutputSchema>, "alias" | "hidden"> & {
|
|
43
|
+
features?: CliFeatures;
|
|
44
|
+
};
|
|
45
|
+
type CommandChildDefinition<ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined, OutputSchema extends z.ZodType | undefined, ParentOptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined, ParentEnvSchema extends z.ZodObject<z.ZodRawShape> | undefined> = CommandDefinition<ArgsSchema, OptionsSchema, EnvSchema, ChildContext<ArgsSchema, OptionsSchema, EnvSchema, ParentOptionsSchema, ParentEnvSchema>, OutputSchema>;
|
|
46
|
+
type AnyCommandDefinition = CommandDefinition<z.ZodObject<z.ZodRawShape> | undefined, z.ZodObject<z.ZodRawShape> | undefined, z.ZodObject<z.ZodRawShape> | undefined, never, z.ZodType | undefined>;
|
|
47
|
+
|
|
48
|
+
type CommandSuccessResult<T = unknown> = {
|
|
49
|
+
ok: true;
|
|
50
|
+
data: T;
|
|
51
|
+
};
|
|
52
|
+
type CommandErrorResult = {
|
|
53
|
+
ok: false;
|
|
54
|
+
error: {
|
|
55
|
+
code: string;
|
|
56
|
+
message: string;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
type CommandResult<T = unknown> = CommandErrorResult | CommandSuccessResult<T>;
|
|
60
|
+
|
|
61
|
+
interface ServeOptions {
|
|
62
|
+
stdout?: (value: string) => void;
|
|
63
|
+
stderr?: (value: string) => void;
|
|
64
|
+
exit?: (code: number) => void;
|
|
65
|
+
env?: Record<string, string | undefined>;
|
|
66
|
+
stdin?: () => Promise<string>;
|
|
67
|
+
isTTY?: boolean;
|
|
68
|
+
format?: "json" | "pretty";
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
type CliKind = "app" | "command";
|
|
72
|
+
declare class Cli<ParentOptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, ParentEnvSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, Kind extends CliKind = CliKind> {
|
|
73
|
+
private readonly kind;
|
|
74
|
+
readonly name: string;
|
|
75
|
+
readonly def: AnyCommandDefinition;
|
|
76
|
+
readonly features: Required<CliFeatures>;
|
|
77
|
+
constructor(name: string, def?: AnyCommandDefinition, features?: CliFeatures);
|
|
78
|
+
command<ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OutputSchema extends z.ZodType | undefined = undefined>(name: string, def: CommandChildDefinition<ArgsSchema, OptionsSchema, EnvSchema, OutputSchema, ParentOptionsSchema, ParentEnvSchema>): this;
|
|
79
|
+
command(sub: Cli<z.ZodObject<z.ZodRawShape> | undefined, z.ZodObject<z.ZodRawShape> | undefined, "command">): this;
|
|
80
|
+
serve(argv?: string[], opts?: ServeOptions): Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
declare const cli: {
|
|
83
|
+
create: <ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OutputSchema extends z.ZodType | undefined = undefined>(name: string, def?: AppDefinition<ArgsSchema, OptionsSchema, EnvSchema, Context<ArgsSchema, OptionsSchema, EnvSchema>, OutputSchema>) => Cli<OptionsSchema, EnvSchema, "app">;
|
|
84
|
+
command: <ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OutputSchema extends z.ZodType | undefined = undefined>(name: string, def?: CommandDefinition<ArgsSchema, OptionsSchema, EnvSchema, Context<ArgsSchema, OptionsSchema, EnvSchema>, OutputSchema>) => Cli<OptionsSchema, EnvSchema, "command">;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export { type AppDefinition as A, type CommandDefinition as C, type OutputValidationMode as O, type ServeOptions as S, type Context as a, Cli as b, cli as c, type CliFeatures as d, type CommandErrorResult as e, type CommandResult as f, type CommandSuccessResult as g };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
type Merge<Parent, Child> = Child & Omit<Parent, keyof Child>;
|
|
4
|
+
|
|
5
|
+
type ContextValue<Schema extends z.ZodObject<z.ZodRawShape> | undefined> = Schema extends z.ZodObject<z.ZodRawShape> ? z.infer<Schema> : Record<never, never>;
|
|
6
|
+
type OutputValue<Schema extends z.ZodType | undefined> = Schema extends z.ZodType ? z.infer<Schema> : unknown;
|
|
7
|
+
type CommandRunReturn<Schema extends z.ZodType | undefined> = Schema extends z.ZodType ? OutputValue<Schema> | Promise<OutputValue<Schema>> : unknown;
|
|
8
|
+
type OutputValidationMode = "development" | boolean;
|
|
9
|
+
interface CommandContextValue<Args, Options, Env> {
|
|
10
|
+
name: string;
|
|
11
|
+
args: Args;
|
|
12
|
+
options: Options;
|
|
13
|
+
env: Env;
|
|
14
|
+
isTTY: boolean;
|
|
15
|
+
isJSON: boolean;
|
|
16
|
+
rest: string[];
|
|
17
|
+
readStdin: () => Promise<string>;
|
|
18
|
+
}
|
|
19
|
+
type Context<ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined> = CommandContextValue<ContextValue<ArgsSchema>, ContextValue<OptionsSchema>, ContextValue<EnvSchema>>;
|
|
20
|
+
type ChildContext<ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined, ParentOptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined, ParentEnvSchema extends z.ZodObject<z.ZodRawShape> | undefined> = CommandContextValue<ContextValue<ArgsSchema>, Merge<ContextValue<ParentOptionsSchema>, ContextValue<OptionsSchema>>, Merge<ContextValue<ParentEnvSchema>, ContextValue<EnvSchema>>>;
|
|
21
|
+
interface CommandDefinition<ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, HandlerContext = Context<ArgsSchema, OptionsSchema, EnvSchema>, OutputSchema extends z.ZodType | undefined = undefined> {
|
|
22
|
+
description?: string;
|
|
23
|
+
args?: ArgsSchema;
|
|
24
|
+
options?: OptionsSchema;
|
|
25
|
+
env?: EnvSchema;
|
|
26
|
+
outputSchema?: OutputSchema;
|
|
27
|
+
validateOutput?: OutputValidationMode;
|
|
28
|
+
alias?: string[] | string;
|
|
29
|
+
examples?: {
|
|
30
|
+
command: string;
|
|
31
|
+
description?: string;
|
|
32
|
+
}[];
|
|
33
|
+
version?: string;
|
|
34
|
+
hidden?: boolean;
|
|
35
|
+
run?: (context: HandlerContext) => CommandRunReturn<OutputSchema>;
|
|
36
|
+
}
|
|
37
|
+
interface CliFeatures {
|
|
38
|
+
mcp?: boolean;
|
|
39
|
+
schema?: boolean;
|
|
40
|
+
llms?: boolean;
|
|
41
|
+
}
|
|
42
|
+
type AppDefinition<ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, HandlerContext = Context<ArgsSchema, OptionsSchema, EnvSchema>, OutputSchema extends z.ZodType | undefined = undefined> = Omit<CommandDefinition<ArgsSchema, OptionsSchema, EnvSchema, HandlerContext, OutputSchema>, "alias" | "hidden"> & {
|
|
43
|
+
features?: CliFeatures;
|
|
44
|
+
};
|
|
45
|
+
type CommandChildDefinition<ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined, OutputSchema extends z.ZodType | undefined, ParentOptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined, ParentEnvSchema extends z.ZodObject<z.ZodRawShape> | undefined> = CommandDefinition<ArgsSchema, OptionsSchema, EnvSchema, ChildContext<ArgsSchema, OptionsSchema, EnvSchema, ParentOptionsSchema, ParentEnvSchema>, OutputSchema>;
|
|
46
|
+
type AnyCommandDefinition = CommandDefinition<z.ZodObject<z.ZodRawShape> | undefined, z.ZodObject<z.ZodRawShape> | undefined, z.ZodObject<z.ZodRawShape> | undefined, never, z.ZodType | undefined>;
|
|
47
|
+
|
|
48
|
+
type CommandSuccessResult<T = unknown> = {
|
|
49
|
+
ok: true;
|
|
50
|
+
data: T;
|
|
51
|
+
};
|
|
52
|
+
type CommandErrorResult = {
|
|
53
|
+
ok: false;
|
|
54
|
+
error: {
|
|
55
|
+
code: string;
|
|
56
|
+
message: string;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
type CommandResult<T = unknown> = CommandErrorResult | CommandSuccessResult<T>;
|
|
60
|
+
|
|
61
|
+
interface ServeOptions {
|
|
62
|
+
stdout?: (value: string) => void;
|
|
63
|
+
stderr?: (value: string) => void;
|
|
64
|
+
exit?: (code: number) => void;
|
|
65
|
+
env?: Record<string, string | undefined>;
|
|
66
|
+
stdin?: () => Promise<string>;
|
|
67
|
+
isTTY?: boolean;
|
|
68
|
+
format?: "json" | "pretty";
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
type CliKind = "app" | "command";
|
|
72
|
+
declare class Cli<ParentOptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, ParentEnvSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, Kind extends CliKind = CliKind> {
|
|
73
|
+
private readonly kind;
|
|
74
|
+
readonly name: string;
|
|
75
|
+
readonly def: AnyCommandDefinition;
|
|
76
|
+
readonly features: Required<CliFeatures>;
|
|
77
|
+
constructor(name: string, def?: AnyCommandDefinition, features?: CliFeatures);
|
|
78
|
+
command<ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OutputSchema extends z.ZodType | undefined = undefined>(name: string, def: CommandChildDefinition<ArgsSchema, OptionsSchema, EnvSchema, OutputSchema, ParentOptionsSchema, ParentEnvSchema>): this;
|
|
79
|
+
command(sub: Cli<z.ZodObject<z.ZodRawShape> | undefined, z.ZodObject<z.ZodRawShape> | undefined, "command">): this;
|
|
80
|
+
serve(argv?: string[], opts?: ServeOptions): Promise<void>;
|
|
81
|
+
}
|
|
82
|
+
declare const cli: {
|
|
83
|
+
create: <ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OutputSchema extends z.ZodType | undefined = undefined>(name: string, def?: AppDefinition<ArgsSchema, OptionsSchema, EnvSchema, Context<ArgsSchema, OptionsSchema, EnvSchema>, OutputSchema>) => Cli<OptionsSchema, EnvSchema, "app">;
|
|
84
|
+
command: <ArgsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OptionsSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, EnvSchema extends z.ZodObject<z.ZodRawShape> | undefined = undefined, OutputSchema extends z.ZodType | undefined = undefined>(name: string, def?: CommandDefinition<ArgsSchema, OptionsSchema, EnvSchema, Context<ArgsSchema, OptionsSchema, EnvSchema>, OutputSchema>) => Cli<OptionsSchema, EnvSchema, "command">;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export { type AppDefinition as A, type CommandDefinition as C, type OutputValidationMode as O, type ServeOptions as S, type Context as a, Cli as b, cli as c, type CliFeatures as d, type CommandErrorResult as e, type CommandResult as f, type CommandSuccessResult as g };
|