@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 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 };