@duyquangnvx/agent-cli 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/README.md +11 -0
- package/dist/command-spec.d.ts +28 -0
- package/dist/command-spec.js +31 -0
- package/dist/command-spec.js.map +1 -0
- package/dist/confirm.d.ts +0 -1
- package/dist/confirm.js +4 -4
- package/dist/confirm.js.map +1 -1
- package/dist/define.d.ts +30 -6
- package/dist/define.js +2 -0
- package/dist/define.js.map +1 -1
- package/dist/execute.d.ts +12 -3
- package/dist/execute.js +10 -2
- package/dist/execute.js.map +1 -1
- package/dist/flags.d.ts +44 -6
- package/dist/flags.js +53 -16
- package/dist/flags.js.map +1 -1
- package/dist/global-install.d.ts +2 -0
- package/dist/global-install.js +5 -4
- package/dist/global-install.js.map +1 -1
- package/dist/help-json.d.ts +4 -4
- package/dist/help-json.js +26 -42
- package/dist/help-json.js.map +1 -1
- package/dist/help.d.ts +4 -5
- package/dist/help.js +15 -12
- package/dist/help.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/input.d.ts +8 -8
- package/dist/input.js +9 -16
- package/dist/input.js.map +1 -1
- package/dist/list.d.ts +44 -0
- package/dist/list.js +126 -0
- package/dist/list.js.map +1 -0
- package/dist/output.d.ts +33 -0
- package/dist/output.js +65 -0
- package/dist/output.js.map +1 -0
- package/dist/parse-input.d.ts +18 -4
- package/dist/parse-input.js +82 -49
- package/dist/parse-input.js.map +1 -1
- package/dist/route.d.ts +25 -0
- package/dist/route.js +75 -0
- package/dist/route.js.map +1 -0
- package/dist/run-cli.d.ts +2 -6
- package/dist/run-cli.js +53 -179
- package/dist/run-cli.js.map +1 -1
- package/dist/suggest.d.ts +4 -0
- package/dist/suggest.js +19 -11
- package/dist/suggest.js.map +1 -1
- package/dist/tokenize.d.ts +20 -0
- package/dist/tokenize.js +79 -0
- package/dist/tokenize.js.map +1 -0
- package/dist/usage.d.ts +3 -11
- package/dist/usage.js +20 -55
- package/dist/usage.js.map +1 -1
- package/package.json +1 -4
- package/dist/fields.d.ts +0 -14
- package/dist/fields.js +0 -71
- package/dist/fields.js.map +0 -1
- package/dist/page.d.ts +0 -26
- package/dist/page.js +0 -49
- package/dist/page.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,18 @@ What changed in each release of `@duyquangnvx/agent-cli` (the Runtime) and `@duy
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## v0.2.0 (2026-10-19)
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- **Breaking:** a List Command is declared by its row schema alone: a read Command sets `rows: rowSchema` in place of `output`, and the Runtime adds `--limit`, `--cursor` and `--fields`, passes `limit` and `cursor` to `run` and gives help JSON the page of rows as its output schema. A described or otherwise wrapped row schema keeps `--fields`, and a write or destructive Command with `rows` fails type checking. The exports `pageOf` and `pageOptions` are removed; the agent-cli skill and the scaffolded template use `rows`.
|
|
12
|
+
- **Breaking:** help and `--help --json` list `--limit`, `--cursor` and `--fields` under Standard flags instead of among the Command's options, so help JSON's `options` no longer has `fields`, `limit` or `cursor`. Each entry of help JSON's `standardFlags` carries the JSON Schema of the flag's value as `schema`, such as `--limit`'s positive integer with default 20.
|
|
13
|
+
- **Breaking:** `defineCommand` throws, and type checking fails, when a Command declares an arg or option named like any Standard flag, whether or not that Command gets the flag: `json`, `help`, `h`, `version`, `dry-run` (key `dryRun`), `confirm`, `limit`, `cursor` or `fields`.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- `--help` or `-h` after `--` is an argument, as every other word after `--` is, instead of showing help.
|
|
18
|
+
|
|
7
19
|
## v0.1.0 (2026-10-18)
|
|
8
20
|
|
|
9
21
|
### Added
|
package/README.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# @duyquangnvx/agent-cli
|
|
2
|
+
|
|
3
|
+
The Runtime for Agent CLIs: command-line tools whose main caller is an LLM coding agent. You declare Commands with Zod schemas. The Runtime does the parsing, help (as text and as `--help --json`), output, errors with hints, exit codes, `--dry-run` and `--confirm`, pagination, Ctrl-C and deadlines, and the built-in `doctor` and `update`.
|
|
4
|
+
|
|
5
|
+
An Agent CLI bundles the Runtime, so install it as a devDependency next to `zod`. The fastest start is the Scaffolder:
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pnpm create @duyquangnvx/agent-cli <name> --description "One line saying what it does"
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
See the [repository](https://github.com/duyquangnvx/cli-for-agent) for an overview and the [agent-cli skill](https://github.com/duyquangnvx/cli-for-agent/blob/release/skills/agent-cli/SKILL.md) for the full guide.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type * as z from "zod";
|
|
2
|
+
import { type Command, type Commands, type Example } from "./define.js";
|
|
3
|
+
import { type StandardFlag } from "./flags.js";
|
|
4
|
+
import { type InputField } from "./input.js";
|
|
5
|
+
import { type ListSpec } from "./list.js";
|
|
6
|
+
/** Everything help, help JSON and input parsing know about one Command. */
|
|
7
|
+
export interface CommandSpec {
|
|
8
|
+
readonly kind: "command";
|
|
9
|
+
readonly commandLine: string;
|
|
10
|
+
readonly command: Command;
|
|
11
|
+
readonly description: string;
|
|
12
|
+
readonly effect: Command["effect"];
|
|
13
|
+
readonly examples: readonly Example[];
|
|
14
|
+
readonly args: readonly InputField[];
|
|
15
|
+
/** The options the author declared; Standard flags are kept apart in `standardFlags`. */
|
|
16
|
+
readonly options: readonly InputField[];
|
|
17
|
+
readonly standardFlags: readonly StandardFlag[];
|
|
18
|
+
readonly list: ListSpec | undefined;
|
|
19
|
+
readonly output: z.ZodType | undefined;
|
|
20
|
+
}
|
|
21
|
+
export interface GroupSpec {
|
|
22
|
+
readonly kind: "group";
|
|
23
|
+
readonly commandLine: string;
|
|
24
|
+
readonly commands: Readonly<Record<string, SpecNode>>;
|
|
25
|
+
}
|
|
26
|
+
export type SpecNode = CommandSpec | GroupSpec;
|
|
27
|
+
export declare function commandSpec(commandLine: string, command: Command): CommandSpec;
|
|
28
|
+
export declare function groupSpec(commandLine: string, commands: Commands): GroupSpec;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { isCommand } from "./define.js";
|
|
2
|
+
import { standardFlagsFor } from "./flags.js";
|
|
3
|
+
import { argFields, optionFields } from "./input.js";
|
|
4
|
+
import { listSpec } from "./list.js";
|
|
5
|
+
export function commandSpec(commandLine, command) {
|
|
6
|
+
const list = command.rows === undefined ? undefined : listSpec(command.rows);
|
|
7
|
+
return {
|
|
8
|
+
kind: "command",
|
|
9
|
+
commandLine,
|
|
10
|
+
command,
|
|
11
|
+
description: command.description,
|
|
12
|
+
effect: command.effect,
|
|
13
|
+
examples: command.examples,
|
|
14
|
+
args: argFields(command.args),
|
|
15
|
+
options: optionFields(command.options),
|
|
16
|
+
standardFlags: standardFlagsFor(command.effect, list),
|
|
17
|
+
list,
|
|
18
|
+
output: list?.output ?? command.output,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function groupSpec(commandLine, commands) {
|
|
22
|
+
return {
|
|
23
|
+
kind: "group",
|
|
24
|
+
commandLine,
|
|
25
|
+
commands: Object.fromEntries(Object.entries(commands).map(([key, node]) => [key, specOf(`${commandLine} ${key}`, node)])),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function specOf(commandLine, node) {
|
|
29
|
+
return isCommand(node) ? commandSpec(commandLine, node) : groupSpec(commandLine, node);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=command-spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-spec.js","sourceRoot":"","sources":["../src/command-spec.ts"],"names":[],"mappings":"AACA,OAAO,EAA6C,SAAS,EAAE,MAAM,aAAa,CAAC;AACnF,OAAO,EAAqB,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,SAAS,EAAmB,YAAY,EAAE,MAAM,YAAY,CAAC;AACtE,OAAO,EAAiB,QAAQ,EAAE,MAAM,WAAW,CAAC;AA0BpD,MAAM,UAAU,WAAW,CAAC,WAAmB,EAAE,OAAgB;IAC/D,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,OAAO;QACL,IAAI,EAAE,SAAS;QACf,WAAW;QACX,OAAO;QACP,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,IAAI,EAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;QAC7B,OAAO,EAAE,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC;QACtC,aAAa,EAAE,gBAAgB,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC;QACrD,IAAI;QACJ,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,OAAO,CAAC,MAAM;KACvC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,WAAmB,EAAE,QAAkB;IAC/D,OAAO;QACL,IAAI,EAAE,OAAO;QACb,WAAW;QACX,QAAQ,EAAE,MAAM,CAAC,WAAW,CAC1B,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,WAAW,IAAI,GAAG,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAC5F;KACF,CAAC;AACJ,CAAC;AAED,SAAS,MAAM,CAAC,WAAmB,EAAE,IAAwB;IAC3D,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;AACzF,CAAC"}
|
package/dist/confirm.d.ts
CHANGED
package/dist/confirm.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { UsageError } from "./errors.js";
|
|
2
|
+
import { CONFIRM_FLAG } from "./flags.js";
|
|
2
3
|
import { commandLineWith } from "./invocation.js";
|
|
3
|
-
export const CONFIRM_OPTION = "--confirm";
|
|
4
4
|
export function checkConfirmation({ invocation, commandLine, given }, expected) {
|
|
5
5
|
if (given === expected) {
|
|
6
6
|
return;
|
|
7
7
|
}
|
|
8
|
-
const hint = `to confirm, run \`${commandLineWith(invocation,
|
|
8
|
+
const hint = `to confirm, run \`${commandLineWith(invocation, CONFIRM_FLAG.flag, expected)}\``;
|
|
9
9
|
if (given === undefined) {
|
|
10
10
|
throw new UsageError({
|
|
11
11
|
code: "CONFIRMATION_REQUIRED",
|
|
12
|
-
message: `\`${commandLine}\` is destructive and needs ${
|
|
12
|
+
message: `\`${commandLine}\` is destructive and needs ${CONFIRM_FLAG.flag}`,
|
|
13
13
|
hint,
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
16
|
throw new UsageError({
|
|
17
17
|
code: "CONFIRMATION_MISMATCH",
|
|
18
|
-
message: `${
|
|
18
|
+
message: `${CONFIRM_FLAG.flag} ${JSON.stringify(given)} does not match the target of \`${commandLine}\``,
|
|
19
19
|
hint,
|
|
20
20
|
});
|
|
21
21
|
}
|
package/dist/confirm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"confirm.js","sourceRoot":"","sources":["../src/confirm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"confirm.js","sourceRoot":"","sources":["../src/confirm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAmB,MAAM,iBAAiB,CAAC;AAQnE,MAAM,UAAU,iBAAiB,CAC/B,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAgB,EAChD,QAAgB;IAEhB,IAAI,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvB,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,qBAAqB,eAAe,CAAC,UAAU,EAAE,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC;IAC/F,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,IAAI,UAAU,CAAC;YACnB,IAAI,EAAE,uBAAuB;YAC7B,OAAO,EAAE,KAAK,WAAW,+BAA+B,YAAY,CAAC,IAAI,EAAE;YAC3E,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IACD,MAAM,IAAI,UAAU,CAAC;QACnB,IAAI,EAAE,uBAAuB;QAC7B,OAAO,EAAE,GAAG,YAAY,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,mCAAmC,WAAW,IAAI;QACxG,IAAI;KACL,CAAC,CAAC;AACL,CAAC"}
|
package/dist/define.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type * as z from "zod";
|
|
2
|
+
import { type StandardFlagName } from "./flags.js";
|
|
3
|
+
import type { Page, PageInput, RowSchema } from "./list.js";
|
|
2
4
|
import type { Style } from "./style.js";
|
|
3
5
|
export type Env = Readonly<Record<string, string | undefined>>;
|
|
4
6
|
export interface Example {
|
|
@@ -30,15 +32,27 @@ interface CommandBase<Args extends InputSchema, Options extends InputSchema> {
|
|
|
30
32
|
readonly examples: readonly Example[];
|
|
31
33
|
readonly args?: Args;
|
|
32
34
|
readonly options?: Options;
|
|
35
|
+
}
|
|
36
|
+
interface UnpagedCommand<Args extends InputSchema, Options extends InputSchema> extends CommandBase<Args, Options> {
|
|
33
37
|
readonly output?: z.ZodType;
|
|
38
|
+
readonly rows?: never;
|
|
34
39
|
}
|
|
35
|
-
export interface ReadCommand<Args extends InputSchema, Options extends InputSchema, Data> extends
|
|
40
|
+
export interface ReadCommand<Args extends InputSchema, Options extends InputSchema, Data> extends UnpagedCommand<Args, Options> {
|
|
36
41
|
readonly effect: "read";
|
|
37
42
|
run(input: Input<Args, Options>, ctx: Context): Data | Promise<Data>;
|
|
38
43
|
render(data: Data, style: Style): string;
|
|
39
44
|
}
|
|
45
|
+
/** A read Command whose data is a page of rows; the Runtime adds `--limit`, `--cursor` and `--fields`. */
|
|
46
|
+
export interface ListCommand<Args extends InputSchema, Options extends InputSchema, Row extends RowSchema> extends CommandBase<Args, Options> {
|
|
47
|
+
readonly effect: "read";
|
|
48
|
+
/** The schema of one row; the page's output schema is derived from it. */
|
|
49
|
+
readonly rows: Row;
|
|
50
|
+
readonly output?: never;
|
|
51
|
+
run(input: Flatten<OutputOf<Args> & OutputOf<Options> & PageInput>, ctx: Context): Page<z.output<Row>> | Promise<Page<z.output<Row>>>;
|
|
52
|
+
render(page: Page<z.output<Row>>, style: Style): string;
|
|
53
|
+
}
|
|
40
54
|
/** A Command that changes something: `plan` has no side effects, `apply` performs the Plan. */
|
|
41
|
-
interface PlannedCommand<Args extends InputSchema, Options extends InputSchema, Plan, Data> extends
|
|
55
|
+
interface PlannedCommand<Args extends InputSchema, Options extends InputSchema, Plan, Data> extends UnpagedCommand<Args, Options> {
|
|
42
56
|
plan(input: Input<Args, Options>, ctx: Context): Plan | Promise<Plan>;
|
|
43
57
|
apply(plan: Plan, ctx: Context): Data | Promise<Data>;
|
|
44
58
|
render(data: Data, style: Style): string;
|
|
@@ -52,7 +66,7 @@ export interface DestructiveCommand<Args extends InputSchema, Options extends In
|
|
|
52
66
|
/** The value the caller must repeat as `--confirm`, naming the target the Plan changes. */
|
|
53
67
|
confirm(plan: Plan): string;
|
|
54
68
|
}
|
|
55
|
-
export type Command = ReadCommand<InputSchema, InputSchema, unknown> | WriteCommand<InputSchema, InputSchema, unknown, unknown> | DestructiveCommand<InputSchema, InputSchema, unknown, unknown>;
|
|
69
|
+
export type Command = ReadCommand<InputSchema, InputSchema, unknown> | ListCommand<InputSchema, InputSchema, RowSchema> | WriteCommand<InputSchema, InputSchema, unknown, unknown> | DestructiveCommand<InputSchema, InputSchema, unknown, unknown>;
|
|
56
70
|
export interface Commands {
|
|
57
71
|
readonly [key: string]: Command | Commands;
|
|
58
72
|
}
|
|
@@ -101,8 +115,18 @@ export interface SingleCommandCli extends CliBase {
|
|
|
101
115
|
readonly commands?: never;
|
|
102
116
|
}
|
|
103
117
|
export type Cli = CommandTreeCli | SingleCommandCli;
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
118
|
+
type Kebab<Key extends string> = Key extends `${infer Head}${infer Tail}` ? `${Head extends Lowercase<Head> ? Head : `-${Lowercase<Head>}`}${Kebab<Tail>}` : Key;
|
|
119
|
+
type Taken<Schema extends InputSchema> = Extract<Kebab<Extract<keyof Schema["shape"], string>>, StandardFlagName>;
|
|
120
|
+
type Unreserved<Schema extends InputSchema> = [Taken<Schema>] extends [never] ? unknown : {
|
|
121
|
+
readonly standardFlagDeclared: Taken<Schema>;
|
|
122
|
+
};
|
|
123
|
+
interface WithoutStandardFlags<Args extends InputSchema, Options extends InputSchema> {
|
|
124
|
+
readonly args?: Unreserved<Args>;
|
|
125
|
+
readonly options?: Unreserved<Options>;
|
|
126
|
+
}
|
|
127
|
+
export declare function defineCommand<Row extends RowSchema, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput>(command: ListCommand<Args, Options, Row> & WithoutStandardFlags<Args, Options>): ListCommand<Args, Options, Row>;
|
|
128
|
+
export declare function defineCommand<Data, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput>(command: ReadCommand<Args, Options, Data> & WithoutStandardFlags<Args, Options>): ReadCommand<Args, Options, Data>;
|
|
129
|
+
export declare function defineCommand<Plan, Data, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput>(command: WriteCommand<Args, Options, Plan, Data> & WithoutStandardFlags<Args, Options>): WriteCommand<Args, Options, Plan, Data>;
|
|
130
|
+
export declare function defineCommand<Plan, Data, Args extends InputSchema = NoInput, Options extends InputSchema = NoInput>(command: DestructiveCommand<Args, Options, Plan, Data> & WithoutStandardFlags<Args, Options>): DestructiveCommand<Args, Options, Plan, Data>;
|
|
107
131
|
export declare function isCommand(node: Command | Commands): node is Command;
|
|
108
132
|
export {};
|
package/dist/define.js
CHANGED
package/dist/define.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"define.js","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"define.js","sourceRoot":"","sources":["../src/define.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAyB,MAAM,YAAY,CAAC;AAgNzE,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,SAAS,CAAC,IAAwB;IAChD,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC;AACzC,CAAC"}
|
package/dist/execute.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type Confirmation } from "./confirm.js";
|
|
2
1
|
import type { Command, Context } from "./define.js";
|
|
2
|
+
import type { Invocation } from "./invocation.js";
|
|
3
|
+
import type { PageInput } from "./list.js";
|
|
3
4
|
import type { Style } from "./style.js";
|
|
4
5
|
export interface Outcome {
|
|
5
6
|
readonly value: unknown;
|
|
@@ -7,6 +8,14 @@ export interface Outcome {
|
|
|
7
8
|
}
|
|
8
9
|
export interface ExecuteFlags {
|
|
9
10
|
readonly dryRun: boolean;
|
|
10
|
-
|
|
11
|
+
/** The target the caller named with `--confirm`, if any. */
|
|
12
|
+
readonly confirm: string | undefined;
|
|
13
|
+
/** The page a List Command's `run` receives with its input. */
|
|
14
|
+
readonly page: PageInput;
|
|
15
|
+
/** The caller's command line and the Command's, for the hint of a confirmation error. */
|
|
16
|
+
readonly invocation: Invocation;
|
|
17
|
+
readonly commandLine: string;
|
|
11
18
|
}
|
|
12
|
-
|
|
19
|
+
/** How the Command prints data it fails with, which is the data its `run` or `apply` returns. */
|
|
20
|
+
export declare function renderOf(command: Command): (data: unknown, style: Style) => string;
|
|
21
|
+
export declare function execute(command: Command, input: Record<string, unknown>, ctx: Context, { dryRun, confirm, page, invocation, commandLine }: ExecuteFlags): Promise<Outcome>;
|
package/dist/execute.js
CHANGED
|
@@ -2,7 +2,15 @@ import { checkConfirmation } from "./confirm.js";
|
|
|
2
2
|
function outcomeOf(value, render) {
|
|
3
3
|
return { value, render: (style) => render(value, style) };
|
|
4
4
|
}
|
|
5
|
-
|
|
5
|
+
/** How the Command prints data it fails with, which is the data its `run` or `apply` returns. */
|
|
6
|
+
export function renderOf(command) {
|
|
7
|
+
// The union of render signatures only accepts the intersection of their data types.
|
|
8
|
+
return (data, style) => command.render(data, style);
|
|
9
|
+
}
|
|
10
|
+
export async function execute(command, input, ctx, { dryRun, confirm, page, invocation, commandLine }) {
|
|
11
|
+
if (command.rows !== undefined) {
|
|
12
|
+
return outcomeOf(await command.run({ ...input, ...page }, ctx), (data, style) => command.render(data, style));
|
|
13
|
+
}
|
|
6
14
|
if (command.effect === "read") {
|
|
7
15
|
return outcomeOf(await command.run(input, ctx), (data, style) => command.render(data, style));
|
|
8
16
|
}
|
|
@@ -11,7 +19,7 @@ export async function execute(command, input, ctx, { dryRun, confirmation }) {
|
|
|
11
19
|
return outcomeOf(plan, (value, style) => command.renderPlan(value, style));
|
|
12
20
|
}
|
|
13
21
|
if (command.effect === "destructive") {
|
|
14
|
-
checkConfirmation(
|
|
22
|
+
checkConfirmation({ invocation, commandLine, given: confirm }, command.confirm(plan));
|
|
15
23
|
}
|
|
16
24
|
return outcomeOf(await command.apply(plan, ctx), (data, style) => command.render(data, style));
|
|
17
25
|
}
|
package/dist/execute.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"execute.js","sourceRoot":"","sources":["../src/execute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAsBjD,SAAS,SAAS,CAAQ,KAAY,EAAE,MAA8C;IACpF,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,iGAAiG;AACjG,MAAM,UAAU,QAAQ,CAAC,OAAgB;IACvC,oFAAoF;IACpF,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAE,OAAO,CAAC,MAAkD,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACnG,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,OAAgB,EAChB,KAA8B,EAC9B,GAAY,EACZ,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAgB;IAEhE,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,SAAS,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAC9E,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAC5B,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IAChG,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC5C,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,SAAS,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAC7E,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,aAAa,EAAE,CAAC;QACrC,iBAAiB,CAAC,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACxF,CAAC;IACD,OAAO,SAAS,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;AACjG,CAAC"}
|
package/dist/flags.d.ts
CHANGED
|
@@ -1,12 +1,50 @@
|
|
|
1
|
+
import * as z from "zod";
|
|
1
2
|
import type { Command } from "./define.js";
|
|
3
|
+
import { type ListFlagName, type ListSpec } from "./list.js";
|
|
4
|
+
import type { Takes } from "./tokenize.js";
|
|
2
5
|
type Effect = Command["effect"];
|
|
3
|
-
export
|
|
6
|
+
export declare const HELP_FLAG = "--help";
|
|
7
|
+
export declare const HELP_SHORT = "-h";
|
|
8
|
+
export declare const VERSION_FLAG = "--version";
|
|
9
|
+
declare const ROUTING_FLAGS: readonly ["--help", "-h", "--version"];
|
|
10
|
+
export type NameOf<Flag extends string> = Flag extends `--${infer Name}` ? Name : Flag extends `-${infer Name}` ? Name : Flag;
|
|
11
|
+
export interface StandardFlag {
|
|
12
|
+
/** The flag as the caller types it, such as `--json`. */
|
|
13
|
+
readonly flag: string;
|
|
4
14
|
readonly usage: string;
|
|
5
15
|
readonly description: string;
|
|
6
|
-
readonly
|
|
16
|
+
readonly takes: Takes;
|
|
17
|
+
readonly schema: z.ZodType;
|
|
7
18
|
}
|
|
8
|
-
export declare const JSON_FLAG:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export declare
|
|
19
|
+
export declare const JSON_FLAG: StandardFlag & {
|
|
20
|
+
readonly flag: "--json";
|
|
21
|
+
};
|
|
22
|
+
export declare const DRY_RUN_FLAG: StandardFlag & {
|
|
23
|
+
readonly flag: "--dry-run";
|
|
24
|
+
};
|
|
25
|
+
export declare const CONFIRM_FLAG: StandardFlag & {
|
|
26
|
+
readonly flag: "--confirm";
|
|
27
|
+
};
|
|
28
|
+
declare const EFFECT_FLAGS: {
|
|
29
|
+
readonly read: readonly [StandardFlag & {
|
|
30
|
+
readonly flag: "--json";
|
|
31
|
+
}];
|
|
32
|
+
readonly write: readonly [StandardFlag & {
|
|
33
|
+
readonly flag: "--json";
|
|
34
|
+
}, StandardFlag & {
|
|
35
|
+
readonly flag: "--dry-run";
|
|
36
|
+
}];
|
|
37
|
+
readonly destructive: readonly [StandardFlag & {
|
|
38
|
+
readonly flag: "--json";
|
|
39
|
+
}, StandardFlag & {
|
|
40
|
+
readonly flag: "--dry-run";
|
|
41
|
+
}, StandardFlag & {
|
|
42
|
+
readonly flag: "--confirm";
|
|
43
|
+
}];
|
|
44
|
+
};
|
|
45
|
+
export type StandardFlagName = NameOf<(typeof ROUTING_FLAGS)[number]> | NameOf<(typeof EFFECT_FLAGS)[Effect][number]["flag"]> | ListFlagName;
|
|
46
|
+
/** The Standard flags of a Command with this Effect, and of a List Command. */
|
|
47
|
+
export declare function standardFlagsFor(effect: Effect, list: ListSpec | undefined): readonly StandardFlag[];
|
|
48
|
+
/** Throws when the Command declares an arg or option under a Standard flag's name. */
|
|
49
|
+
export declare function checkNoStandardFlags(command: Command): void;
|
|
12
50
|
export {};
|
package/dist/flags.js
CHANGED
|
@@ -1,22 +1,59 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import * as z from "zod";
|
|
2
|
+
import { argFields, kebab, optionFields } from "./input.js";
|
|
3
|
+
import { LIST_FLAGS } from "./list.js";
|
|
4
|
+
export const HELP_FLAG = "--help";
|
|
5
|
+
export const HELP_SHORT = "-h";
|
|
6
|
+
export const VERSION_FLAG = "--version";
|
|
7
|
+
// The Runtime reads these at every level of the command line, so no Command can declare them.
|
|
8
|
+
const ROUTING_FLAGS = [HELP_FLAG, HELP_SHORT, VERSION_FLAG];
|
|
9
|
+
function nameOf(flag) {
|
|
10
|
+
return flag.replace(/^--?/, "");
|
|
11
|
+
}
|
|
12
|
+
function standardFlag(flag, { placeholder, ...rest }) {
|
|
13
|
+
return { flag, usage: placeholder === undefined ? flag : `${flag} ${placeholder}`, ...rest };
|
|
14
|
+
}
|
|
15
|
+
export const JSON_FLAG = standardFlag("--json", {
|
|
4
16
|
description: "print the result as JSON",
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
17
|
+
takes: "nothing",
|
|
18
|
+
schema: z.boolean(),
|
|
19
|
+
});
|
|
20
|
+
export const DRY_RUN_FLAG = standardFlag("--dry-run", {
|
|
9
21
|
description: "print the Plan without changing anything",
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
22
|
+
takes: "nothing",
|
|
23
|
+
schema: z.boolean(),
|
|
24
|
+
});
|
|
25
|
+
export const CONFIRM_FLAG = standardFlag("--confirm", {
|
|
26
|
+
placeholder: "<target>",
|
|
14
27
|
description: "name the target to confirm the change; an error hint gives the exact command",
|
|
15
|
-
|
|
28
|
+
takes: "value",
|
|
29
|
+
schema: z.string(),
|
|
30
|
+
});
|
|
31
|
+
const EFFECT_FLAGS = {
|
|
32
|
+
read: [JSON_FLAG],
|
|
33
|
+
write: [JSON_FLAG, DRY_RUN_FLAG],
|
|
34
|
+
destructive: [JSON_FLAG, DRY_RUN_FLAG, CONFIRM_FLAG],
|
|
16
35
|
};
|
|
17
|
-
//
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
36
|
+
// Every name is reserved on every Command, whatever flags it gets, so a name means one thing.
|
|
37
|
+
const RESERVED = new Map([...ROUTING_FLAGS, ...EFFECT_FLAGS.destructive.map(({ flag }) => flag), ...LIST_FLAGS].map((flag) => [nameOf(flag), flag]));
|
|
38
|
+
/** The Standard flags of a Command with this Effect, and of a List Command. */
|
|
39
|
+
export function standardFlagsFor(effect, list) {
|
|
40
|
+
return [...EFFECT_FLAGS[effect], ...(list?.standardFlags ?? [])];
|
|
41
|
+
}
|
|
42
|
+
/** Throws when the Command declares an arg or option under a Standard flag's name. */
|
|
43
|
+
export function checkNoStandardFlags(command) {
|
|
44
|
+
const declared = [
|
|
45
|
+
...argFields(command.args).map(({ key }) => ({ kind: "arg", key })),
|
|
46
|
+
...optionFields(command.options).map(({ key }) => ({ kind: "option", key })),
|
|
47
|
+
];
|
|
48
|
+
const lines = declared.flatMap(({ kind, key }) => {
|
|
49
|
+
const flag = RESERVED.get(kebab(key));
|
|
50
|
+
return flag === undefined ? [] : [` ${kind} '${key}' is the Standard flag ${flag}`];
|
|
51
|
+
});
|
|
52
|
+
if (lines.length > 0) {
|
|
53
|
+
throw new Error([
|
|
54
|
+
`Command '${command.name}' declares Standard flags the Runtime adds; rename them:`,
|
|
55
|
+
...lines,
|
|
56
|
+
].join("\n"));
|
|
57
|
+
}
|
|
21
58
|
}
|
|
22
59
|
//# sourceMappingURL=flags.js.map
|
package/dist/flags.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"flags.js","sourceRoot":"","sources":["../src/flags.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"flags.js","sourceRoot":"","sources":["../src/flags.ts"],"names":[],"mappings":"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"}
|
package/dist/global-install.d.ts
CHANGED
|
@@ -4,6 +4,8 @@ export interface InstalledCopy {
|
|
|
4
4
|
readonly prefix: string;
|
|
5
5
|
readonly packageDir: string;
|
|
6
6
|
}
|
|
7
|
+
/** Where npm puts global packages under its global prefix. */
|
|
8
|
+
export declare function globalModulesDir(prefix: string): string;
|
|
7
9
|
/**
|
|
8
10
|
* The global npm install this copy runs from, found by asking npm for its global prefix.
|
|
9
11
|
* `bin` is the script that started the CLI; throws `NOT_GLOBAL_INSTALL` when it is not inside that install.
|
package/dist/global-install.js
CHANGED
|
@@ -2,10 +2,11 @@ import { lstat, realpath } from "node:fs/promises";
|
|
|
2
2
|
import { isAbsolute, join, relative } from "node:path";
|
|
3
3
|
import { CliError, isMissingFile } from "./errors.js";
|
|
4
4
|
import { globalPrefix, installCommandLine } from "./npm.js";
|
|
5
|
-
|
|
5
|
+
/** Where npm puts global packages under its global prefix. */
|
|
6
|
+
export function globalModulesDir(prefix) {
|
|
6
7
|
return process.platform === "win32"
|
|
7
|
-
? join(prefix, "node_modules"
|
|
8
|
-
: join(prefix, "lib", "node_modules"
|
|
8
|
+
? join(prefix, "node_modules")
|
|
9
|
+
: join(prefix, "lib", "node_modules");
|
|
9
10
|
}
|
|
10
11
|
function notGlobal(ctx, message) {
|
|
11
12
|
return new CliError({
|
|
@@ -35,7 +36,7 @@ export async function globalInstallOf(bin, ctx) {
|
|
|
35
36
|
throw notGlobal(ctx, `${ctx.cliName} runs from source, not from an npm install`);
|
|
36
37
|
}
|
|
37
38
|
const prefix = await globalPrefix(ctx);
|
|
38
|
-
const packageDir =
|
|
39
|
+
const packageDir = join(globalModulesDir(prefix), ctx.install.package);
|
|
39
40
|
const installed = await realpathOrUndefined(packageDir);
|
|
40
41
|
const here = (await realpathOrUndefined(bin)) ?? bin;
|
|
41
42
|
if (installed === undefined || !isInside(installed, here)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"global-install.js","sourceRoot":"","sources":["../src/global-install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAmB,MAAM,UAAU,CAAC;AAQ7E,
|
|
1
|
+
{"version":3,"file":"global-install.js","sourceRoot":"","sources":["../src/global-install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAmB,MAAM,UAAU,CAAC;AAQ7E,8DAA8D;AAC9D,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,OAAO,OAAO,CAAC,QAAQ,KAAK,OAAO;QACjC,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC;QAC9B,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;AAC1C,CAAC;AAED,SAAS,SAAS,CAAC,GAAe,EAAE,OAAe;IACjD,OAAO,IAAI,QAAQ,CAAC;QAClB,IAAI,EAAE,oBAAoB;QAC1B,OAAO;QACP,IAAI,EAAE,6BAA6B,GAAG,CAAC,OAAO,6BAA6B,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;QAC5G,SAAS,EAAE,KAAK;KACjB,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,IAAY;IAC7C,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QAC7C,IAAI,aAAa,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,MAAM,KAAK,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW,EAAE,IAAY;IACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAClC,OAAO,KAAK,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AACvE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,GAAuB,EACvB,GAAe;IAEf,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;QACtB,MAAM,SAAS,CAAC,GAAG,EAAE,GAAG,GAAG,CAAC,OAAO,4CAA4C,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,UAAU,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,CAAC,MAAM,mBAAmB,CAAC,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC;IACrD,IAAI,SAAS,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC;QAC1D,MAAM,SAAS,CACb,GAAG,EACH,GAAG,GAAG,CAAC,OAAO,cAAc,IAAI,sCAAsC,UAAU,EAAE,CACnF,CAAC;IACJ,CAAC;IACD,6EAA6E;IAC7E,IAAI,CAAC,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,cAAc,EAAE,EAAE,CAAC;QAC/C,MAAM,SAAS,CACb,GAAG,EACH,GAAG,GAAG,CAAC,OAAO,wBAAwB,SAAS,sCAAsC,CACtF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AAChC,CAAC"}
|
package/dist/help-json.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export declare function cliHelpJson(
|
|
3
|
-
export declare function groupHelpJson(
|
|
4
|
-
export declare function commandHelpJson(
|
|
1
|
+
import type { CommandSpec, GroupSpec, SpecNode } from "./command-spec.js";
|
|
2
|
+
export declare function cliHelpJson(version: string, root: SpecNode): string;
|
|
3
|
+
export declare function groupHelpJson(group: GroupSpec): string;
|
|
4
|
+
export declare function commandHelpJson(spec: CommandSpec): string;
|
package/dist/help-json.js
CHANGED
|
@@ -1,60 +1,44 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
|
-
import { isCommand } from "./define.js";
|
|
3
|
-
import { fieldsDescription, rowFieldsOf } from "./fields.js";
|
|
4
|
-
import { runtimeFlagsFor } from "./flags.js";
|
|
5
|
-
import { kebab } from "./input.js";
|
|
6
2
|
// Transforms and other unrepresentable parts become `{}` rather than failing the whole help.
|
|
7
3
|
function inputSchema(schema) {
|
|
8
|
-
return z.toJSONSchema(schema
|
|
9
|
-
}
|
|
10
|
-
//
|
|
11
|
-
function optionsSchema(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
]);
|
|
16
|
-
const rowFields = rowFieldsOf(command);
|
|
17
|
-
const fields = rowFields === undefined
|
|
18
|
-
? []
|
|
19
|
-
: [["fields", z.string().optional().describe(fieldsDescription(rowFields))]];
|
|
20
|
-
return inputSchema(z.object(Object.fromEntries([...shape, ...fields])));
|
|
21
|
-
}
|
|
22
|
-
function commandData(commandLine, command) {
|
|
4
|
+
return z.toJSONSchema(schema, { io: "input", unrepresentable: "any" });
|
|
5
|
+
}
|
|
6
|
+
// Keys are the names the caller types, so option `greetingWord` reads `greeting-word`.
|
|
7
|
+
function optionsSchema(options) {
|
|
8
|
+
return inputSchema(z.object(Object.fromEntries(options.map(({ name, schema }) => [name, schema]))));
|
|
9
|
+
}
|
|
10
|
+
function commandData(spec) {
|
|
23
11
|
return {
|
|
24
|
-
name: commandLine,
|
|
25
|
-
description:
|
|
26
|
-
effect:
|
|
27
|
-
examples:
|
|
28
|
-
args: inputSchema(command.args),
|
|
29
|
-
options: optionsSchema(
|
|
30
|
-
standardFlags:
|
|
12
|
+
name: spec.commandLine,
|
|
13
|
+
description: spec.description,
|
|
14
|
+
effect: spec.effect,
|
|
15
|
+
examples: spec.examples,
|
|
16
|
+
args: inputSchema(spec.command.args ?? z.object({})),
|
|
17
|
+
options: optionsSchema(spec.options),
|
|
18
|
+
standardFlags: spec.standardFlags.map(({ usage, description, schema }) => ({
|
|
31
19
|
usage,
|
|
32
20
|
description,
|
|
21
|
+
schema: inputSchema(schema),
|
|
33
22
|
})),
|
|
34
|
-
output:
|
|
35
|
-
? null
|
|
36
|
-
: z.toJSONSchema(command.output, { unrepresentable: "any" }),
|
|
23
|
+
output: spec.output === undefined ? null : z.toJSONSchema(spec.output, { unrepresentable: "any" }),
|
|
37
24
|
};
|
|
38
25
|
}
|
|
39
|
-
function nodeData(
|
|
40
|
-
return
|
|
26
|
+
function nodeData(node) {
|
|
27
|
+
return node.kind === "command" ? commandData(node) : groupData(node);
|
|
41
28
|
}
|
|
42
|
-
function groupData(
|
|
43
|
-
return {
|
|
44
|
-
name: commandLine,
|
|
45
|
-
commands: Object.entries(commands).map(([key, node]) => nodeData(`${commandLine} ${key}`, node)),
|
|
46
|
-
};
|
|
29
|
+
function groupData(group) {
|
|
30
|
+
return { name: group.commandLine, commands: Object.values(group.commands).map(nodeData) };
|
|
47
31
|
}
|
|
48
32
|
function printed(data) {
|
|
49
33
|
return `${JSON.stringify(data)}\n`;
|
|
50
34
|
}
|
|
51
|
-
export function cliHelpJson(
|
|
52
|
-
return printed({ name, version, ...nodeData(
|
|
35
|
+
export function cliHelpJson(version, root) {
|
|
36
|
+
return printed({ name: root.commandLine, version, ...nodeData(root) });
|
|
53
37
|
}
|
|
54
|
-
export function groupHelpJson(
|
|
55
|
-
return printed(groupData(
|
|
38
|
+
export function groupHelpJson(group) {
|
|
39
|
+
return printed(groupData(group));
|
|
56
40
|
}
|
|
57
|
-
export function commandHelpJson(
|
|
58
|
-
return printed(commandData(
|
|
41
|
+
export function commandHelpJson(spec) {
|
|
42
|
+
return printed(commandData(spec));
|
|
59
43
|
}
|
|
60
44
|
//# sourceMappingURL=help-json.js.map
|
package/dist/help-json.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"help-json.js","sourceRoot":"","sources":["../src/help-json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"help-json.js","sourceRoot":"","sources":["../src/help-json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAMzB,6FAA6F;AAC7F,SAAS,WAAW,CAAC,MAAiB;IACpC,OAAO,CAAC,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC,CAAC;AACzE,CAAC;AAED,uFAAuF;AACvF,SAAS,aAAa,CAAC,OAA8B;IACnD,OAAO,WAAW,CAChB,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAChF,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,IAAiB;IACpC,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,WAAW;QACtB,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACpD,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC;QACpC,aAAa,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;YACzE,KAAK;YACL,WAAW;YACX,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC;SAC5B,CAAC,CAAC;QACH,MAAM,EACJ,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;KAC7F,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,IAAc;IAC9B,OAAO,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,SAAS,CAAC,KAAgB;IACjC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;AAC5F,CAAC;AAED,SAAS,OAAO,CAAC,IAAgB;IAC/B,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,IAAc;IACzD,OAAO,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAgB;IAC5C,OAAO,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAiB;IAC/C,OAAO,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;AACpC,CAAC"}
|
package/dist/help.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import type { InputFields } from "./input.js";
|
|
1
|
+
import type { CommandSpec, GroupSpec } from "./command-spec.js";
|
|
3
2
|
import type { Style } from "./style.js";
|
|
4
|
-
export declare function cliHelp(
|
|
5
|
-
export declare function groupHelp(
|
|
6
|
-
export declare function commandHelp(
|
|
3
|
+
export declare function cliHelp(version: string, root: GroupSpec, style: Style): string;
|
|
4
|
+
export declare function groupHelp(group: GroupSpec, style: Style): string;
|
|
5
|
+
export declare function commandHelp(spec: CommandSpec, style: Style): string;
|