@duyquangnvx/agent-cli 0.2.1 → 0.4.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 +71 -0
- package/dist/abort.d.ts +2 -0
- package/dist/abort.js +11 -0
- package/dist/abort.js.map +1 -0
- package/dist/agent-cli.d.ts +17 -0
- package/dist/agent-cli.js +28 -0
- package/dist/agent-cli.js.map +1 -0
- package/dist/agent.d.ts +4 -0
- package/dist/agent.js +14 -0
- package/dist/agent.js.map +1 -0
- package/dist/built-ins.d.ts +1 -2
- package/dist/built-ins.js +0 -10
- package/dist/built-ins.js.map +1 -1
- package/dist/clock.d.ts +10 -0
- package/dist/clock.js +35 -0
- package/dist/clock.js.map +1 -0
- package/dist/command-spec.js +12 -1
- package/dist/command-spec.js.map +1 -1
- package/dist/confirm.d.ts +2 -0
- package/dist/confirm.js +4 -2
- package/dist/confirm.js.map +1 -1
- package/dist/cost.d.ts +9 -0
- package/dist/cost.js +16 -0
- package/dist/cost.js.map +1 -0
- package/dist/define.d.ts +145 -32
- package/dist/define.js +9 -2
- package/dist/define.js.map +1 -1
- package/dist/doctor-rows.d.ts +2 -2
- package/dist/doctor-rows.js +45 -5
- package/dist/doctor-rows.js.map +1 -1
- package/dist/doctor.d.ts +2 -1
- package/dist/doctor.js +31 -29
- package/dist/doctor.js.map +1 -1
- package/dist/errno.d.ts +15 -0
- package/dist/errno.js +50 -0
- package/dist/errno.js.map +1 -0
- package/dist/error-table.d.ts +34 -0
- package/dist/error-table.js +10 -0
- package/dist/error-table.js.map +1 -0
- package/dist/errors.d.ts +17 -12
- package/dist/errors.js +59 -38
- package/dist/errors.js.map +1 -1
- package/dist/execute.d.ts +7 -3
- package/dist/execute.js +38 -5
- package/dist/execute.js.map +1 -1
- package/dist/exit-classes.d.ts +31 -0
- package/dist/exit-classes.js +108 -0
- package/dist/exit-classes.js.map +1 -0
- package/dist/files.d.ts +31 -0
- package/dist/files.js +95 -0
- package/dist/files.js.map +1 -0
- package/dist/flags.d.ts +21 -3
- package/dist/flags.js +41 -4
- package/dist/flags.js.map +1 -1
- package/dist/global-install.d.ts +1 -0
- package/dist/global-install.js +2 -2
- package/dist/global-install.js.map +1 -1
- package/dist/help-json.d.ts +2 -1
- package/dist/help-json.js +18 -2
- package/dist/help-json.js.map +1 -1
- package/dist/help.d.ts +4 -2
- package/dist/help.js +62 -6
- package/dist/help.js.map +1 -1
- package/dist/index.d.ts +11 -4
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/input.d.ts +4 -0
- package/dist/input.js +24 -2
- package/dist/input.js.map +1 -1
- package/dist/interrupts.d.ts +17 -3
- package/dist/interrupts.js +43 -25
- package/dist/interrupts.js.map +1 -1
- package/dist/invocation.d.ts +7 -2
- package/dist/invocation.js +11 -3
- package/dist/invocation.js.map +1 -1
- package/dist/list.d.ts +1 -0
- package/dist/list.js +4 -2
- package/dist/list.js.map +1 -1
- package/dist/npm.d.ts +5 -0
- package/dist/npm.js +19 -17
- package/dist/npm.js.map +1 -1
- package/dist/output.d.ts +18 -4
- package/dist/output.js +65 -23
- package/dist/output.js.map +1 -1
- package/dist/outputs.d.ts +11 -0
- package/dist/outputs.js +22 -0
- package/dist/outputs.js.map +1 -0
- package/dist/package-root.d.ts +6 -0
- package/dist/package-root.js +17 -0
- package/dist/package-root.js.map +1 -0
- package/dist/parse-input.d.ts +2 -0
- package/dist/parse-input.js +41 -8
- package/dist/parse-input.js.map +1 -1
- package/dist/planned.d.ts +6 -0
- package/dist/planned.js +5 -0
- package/dist/planned.js.map +1 -0
- package/dist/project.d.ts +4 -0
- package/dist/project.js +48 -0
- package/dist/project.js.map +1 -0
- package/dist/route.d.ts +2 -0
- package/dist/route.js +2 -1
- package/dist/route.js.map +1 -1
- package/dist/run-cli.d.ts +24 -5
- package/dist/run-cli.js +126 -18
- package/dist/run-cli.js.map +1 -1
- package/dist/run-process.js +6 -3
- package/dist/run-process.js.map +1 -1
- package/dist/secrets.d.ts +19 -0
- package/dist/secrets.js +32 -0
- package/dist/secrets.js.map +1 -0
- package/dist/spawn.d.ts +29 -0
- package/dist/spawn.js +79 -0
- package/dist/spawn.js.map +1 -0
- package/dist/spill.d.ts +16 -0
- package/dist/spill.js +65 -0
- package/dist/spill.js.map +1 -0
- package/dist/style.js +5 -12
- package/dist/style.js.map +1 -1
- package/dist/tail.d.ts +2 -0
- package/dist/tail.js +5 -0
- package/dist/tail.js.map +1 -0
- package/dist/tools.d.ts +6 -0
- package/dist/tools.js +69 -0
- package/dist/tools.js.map +1 -0
- package/dist/update.js +7 -7
- package/dist/update.js.map +1 -1
- package/dist/usage.d.ts +3 -0
- package/dist/usage.js +6 -3
- package/dist/usage.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Files } from "./files.js";
|
|
2
|
+
import { type Invocation } from "./invocation.js";
|
|
3
|
+
export declare const OUTPUT_EXISTS = "OUTPUT_EXISTS";
|
|
4
|
+
export interface Overwrite {
|
|
5
|
+
readonly invocation: Invocation;
|
|
6
|
+
readonly commandLine: string;
|
|
7
|
+
readonly force: boolean;
|
|
8
|
+
readonly files: Files;
|
|
9
|
+
}
|
|
10
|
+
/** Refuses a run that would overwrite existing outputs unless the caller passed `--force`. */
|
|
11
|
+
export declare function checkOutputs({ invocation, commandLine, force, files }: Overwrite, outputs: readonly string[] | undefined): Promise<void>;
|
package/dist/outputs.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { CliError } from "./errors.js";
|
|
2
|
+
import { FORCE_FLAG } from "./flags.js";
|
|
3
|
+
import { commandLineWith } from "./invocation.js";
|
|
4
|
+
export const OUTPUT_EXISTS = "OUTPUT_EXISTS";
|
|
5
|
+
/** Refuses a run that would overwrite existing outputs unless the caller passed `--force`. */
|
|
6
|
+
export async function checkOutputs({ invocation, commandLine, force, files }, outputs) {
|
|
7
|
+
if (outputs === undefined || force) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const found = await Promise.all(outputs.map((path) => files.exists(path)));
|
|
11
|
+
const existing = outputs.filter((_path, index) => found[index]);
|
|
12
|
+
if (existing.length === 0) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const them = existing.length === 1 ? "it" : "them";
|
|
16
|
+
throw new CliError({
|
|
17
|
+
code: OUTPUT_EXISTS,
|
|
18
|
+
message: `\`${commandLine}\` would overwrite ${existing.join(", ")}`,
|
|
19
|
+
hint: `to replace ${them}, run \`${commandLineWith(invocation, FORCE_FLAG.flag)}\``,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=outputs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"outputs.js","sourceRoot":"","sources":["../src/outputs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,eAAe,EAAmB,MAAM,iBAAiB,CAAC;AAEnE,MAAM,CAAC,MAAM,aAAa,GAAG,eAAe,CAAC;AAS7C,8FAA8F;AAC9F,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,KAAK,EAAa,EACpD,OAAsC;IAEtC,IAAI,OAAO,KAAK,SAAS,IAAI,KAAK,EAAE,CAAC;QACnC,OAAO;IACT,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3E,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAChE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO;IACT,CAAC;IACD,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IACnD,MAAM,IAAI,QAAQ,CAAC;QACjB,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,KAAK,WAAW,sBAAsB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACpE,IAAI,EAAE,cAAc,IAAI,WAAW,eAAe,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI;KACpF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The nearest folder holding a `package.json`, searched upward from the bin or, run without one,
|
|
3
|
+
* from `cwd`; the search's start when none holds one. The bin is resolved through links first,
|
|
4
|
+
* since npm's global bin is a link to it.
|
|
5
|
+
*/
|
|
6
|
+
export declare function packageRootOf(bin: string | undefined, cwd: string): string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* The nearest folder holding a `package.json`, searched upward from the bin or, run without one,
|
|
5
|
+
* from `cwd`; the search's start when none holds one. The bin is resolved through links first,
|
|
6
|
+
* since npm's global bin is a link to it.
|
|
7
|
+
*/
|
|
8
|
+
export function packageRootOf(bin, cwd) {
|
|
9
|
+
const start = bin === undefined ? resolve(cwd) : dirname(realpathSync(bin));
|
|
10
|
+
for (let dir = start;; dir = dirname(dir)) {
|
|
11
|
+
if (existsSync(join(dir, "package.json")))
|
|
12
|
+
return dir;
|
|
13
|
+
if (dirname(dir) === dir)
|
|
14
|
+
return start;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=package-root.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-root.js","sourceRoot":"","sources":["../src/package-root.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEnD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,GAAuB,EAAE,GAAW;IAChE,MAAM,KAAK,GAAG,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5E,KAAK,IAAI,GAAG,GAAG,KAAK,GAAI,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3C,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QACtD,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,GAAG;YAAE,OAAO,KAAK,CAAC;IACzC,CAAC;AACH,CAAC"}
|
package/dist/parse-input.d.ts
CHANGED
|
@@ -6,6 +6,8 @@ export interface StandardValues {
|
|
|
6
6
|
readonly json: boolean;
|
|
7
7
|
readonly dryRun: boolean;
|
|
8
8
|
readonly confirm: string | undefined;
|
|
9
|
+
readonly yes: boolean;
|
|
10
|
+
readonly force: boolean;
|
|
9
11
|
/** The page a List Command was asked for; the default page for any other Command. */
|
|
10
12
|
readonly page: PageInput;
|
|
11
13
|
/** The row fields to print, or undefined when the caller gave no `--fields`. */
|
package/dist/parse-input.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as z from "zod";
|
|
2
2
|
import { UsageError } from "./errors.js";
|
|
3
|
-
import { CONFIRM_FLAG, DRY_RUN_FLAG, HELP_FLAG, VERSION_FLAG } from "./flags.js";
|
|
3
|
+
import { CONFIRM_FLAG, DRY_RUN_FLAG, FORCE_FLAG, HELP_FLAG, VERSION_FLAG, YES_FLAG, } from "./flags.js";
|
|
4
4
|
import { commandLineRenaming } from "./invocation.js";
|
|
5
5
|
import { PAGE_INPUT, selectedFields } from "./list.js";
|
|
6
6
|
import { closestFlag } from "./suggest.js";
|
|
7
7
|
import { tokenize } from "./tokenize.js";
|
|
8
|
-
import { invalidInputError, unknownOptionError } from "./usage.js";
|
|
8
|
+
import { INVALID_INPUT, invalidInputError, unknownOptionError } from "./usage.js";
|
|
9
9
|
const NO_INPUT = z.object({});
|
|
10
10
|
function knownFlags(spec) {
|
|
11
11
|
return [
|
|
@@ -34,12 +34,19 @@ function optionValue(field, raw) {
|
|
|
34
34
|
// Strings that read as numbers are converted so authors can write `z.number()`; anything else
|
|
35
35
|
// stays a string for Zod to reject with the caller's own value.
|
|
36
36
|
function converted(field, raw) {
|
|
37
|
+
if (Array.isArray(raw)) {
|
|
38
|
+
return raw.map((element) => converted(field, element));
|
|
39
|
+
}
|
|
37
40
|
if (field.type !== "number" || typeof raw !== "string" || raw.trim() === "") {
|
|
38
41
|
return raw;
|
|
39
42
|
}
|
|
40
43
|
const number = Number(raw);
|
|
41
44
|
return Number.isNaN(number) ? raw : number;
|
|
42
45
|
}
|
|
46
|
+
// No operands for an optional array leave it out, so its default applies.
|
|
47
|
+
function variadicValue(field, values) {
|
|
48
|
+
return values.length === 0 && !field.required ? undefined : values;
|
|
49
|
+
}
|
|
43
50
|
function parse(schema, values) {
|
|
44
51
|
const input = Object.fromEntries([...values]
|
|
45
52
|
.filter(([, raw]) => raw !== undefined)
|
|
@@ -59,11 +66,25 @@ function issueLines(result, values, howToPass, reported) {
|
|
|
59
66
|
return [];
|
|
60
67
|
}
|
|
61
68
|
const raw = values.get(field);
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
if (raw === undefined) {
|
|
70
|
+
return [` ${field.label}: required, ${howToPass(field)}`];
|
|
71
|
+
}
|
|
72
|
+
// Only an arg takes several operands, and args' values are kept in argument order.
|
|
73
|
+
return Array.isArray(raw)
|
|
74
|
+
? [operandsIssueLine(field, raw, issue, [...values.keys()].indexOf(field) + 1)]
|
|
64
75
|
: [` ${field.label} ${JSON.stringify(raw)}: ${issue.message}`];
|
|
65
76
|
});
|
|
66
77
|
}
|
|
78
|
+
// `first` is the 1-based position of the field's first operand on the command line.
|
|
79
|
+
function operandsIssueLine(field, raw, issue, first) {
|
|
80
|
+
const [, element] = issue.path;
|
|
81
|
+
if (typeof element === "number") {
|
|
82
|
+
return ` ${field.label} ${JSON.stringify(raw[element])} (argument ${first + element}): ${issue.message}`;
|
|
83
|
+
}
|
|
84
|
+
return raw.length === 0
|
|
85
|
+
? ` ${field.label}: ${issue.message}, pass them as arguments from ${first}`
|
|
86
|
+
: ` ${field.label} ${JSON.stringify(raw)}: ${issue.message}`;
|
|
87
|
+
}
|
|
67
88
|
function unknownLine({ flag, suggestion }) {
|
|
68
89
|
return ` unknown option '${flag}'${suggestion === undefined ? "" : ` (did you mean ${suggestion}?)`}`;
|
|
69
90
|
}
|
|
@@ -71,7 +92,7 @@ function invalidInput(commandLine, invocation, unknown, otherLines) {
|
|
|
71
92
|
const renames = new Map(unknown.flatMap(({ flag, suggestion }) => suggestion === undefined ? [] : [[flag, suggestion]]));
|
|
72
93
|
const correctable = otherLines.length === 0 && renames.size === unknown.length;
|
|
73
94
|
return new UsageError({
|
|
74
|
-
code:
|
|
95
|
+
code: INVALID_INPUT,
|
|
75
96
|
message: [
|
|
76
97
|
`invalid input for \`${commandLine}\``,
|
|
77
98
|
...unknown.map(unknownLine),
|
|
@@ -92,7 +113,18 @@ function parseInput(spec, words, invocation) {
|
|
|
92
113
|
}
|
|
93
114
|
// A value option given without a value is collected as `true`.
|
|
94
115
|
const missing = [...optionFields, ...pageFields].filter((field) => field.type !== "boolean" && values.get(field.label) === true);
|
|
95
|
-
const argValues = new Map(argFields.map((field, index) => [
|
|
116
|
+
const argValues = new Map(argFields.map((field, index) => [
|
|
117
|
+
field,
|
|
118
|
+
field.variadic
|
|
119
|
+
? variadicValue(field, operands
|
|
120
|
+
.slice(index)
|
|
121
|
+
.filter((operand) => !operand.afterUnknownOption)
|
|
122
|
+
.map((operand) => operand.value))
|
|
123
|
+
: operands[index]?.value,
|
|
124
|
+
]));
|
|
125
|
+
const extraOperands = argFields.some((field) => field.variadic)
|
|
126
|
+
? []
|
|
127
|
+
: operands.slice(argFields.length);
|
|
96
128
|
const valuesOf = (fields) => new Map(fields.map((field) => [
|
|
97
129
|
field,
|
|
98
130
|
missing.includes(field) ? undefined : optionValue(field, values.get(field.label)),
|
|
@@ -105,8 +137,7 @@ function parseInput(spec, words, invocation) {
|
|
|
105
137
|
const unknown = unknownOptionsOf(unknownOptions, candidateFlags(known));
|
|
106
138
|
const otherLines = [
|
|
107
139
|
...missing.map((field) => ` ${field.label}: missing value, pass ${field.usage}`),
|
|
108
|
-
...
|
|
109
|
-
.slice(argFields.length)
|
|
140
|
+
...extraOperands
|
|
110
141
|
// A word right after an unknown flag may be its value, so it isn't an extra arg.
|
|
111
142
|
.filter((operand) => !operand.afterUnknownOption)
|
|
112
143
|
.map((operand) => ` unexpected argument ${JSON.stringify(operand.value)}`),
|
|
@@ -137,6 +168,8 @@ export function parseCommand({ spec, words, json }, invocation) {
|
|
|
137
168
|
json,
|
|
138
169
|
dryRun: values.get(DRY_RUN_FLAG.flag) === true,
|
|
139
170
|
confirm: typeof confirm === "string" ? confirm : undefined,
|
|
171
|
+
yes: values.get(YES_FLAG.flag) === true,
|
|
172
|
+
force: values.get(FORCE_FLAG.flag) === true,
|
|
140
173
|
page,
|
|
141
174
|
fields: spec.list === undefined
|
|
142
175
|
? undefined
|
package/dist/parse-input.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse-input.js","sourceRoot":"","sources":["../src/parse-input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAGzB,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,
|
|
1
|
+
{"version":3,"file":"parse-input.js","sourceRoot":"","sources":["../src/parse-input.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { Command } from "./define.js";
|
|
2
|
+
export type PlannedCommand = Extract<Command, {
|
|
3
|
+
readonly effect: "write" | "destructive";
|
|
4
|
+
}>;
|
|
5
|
+
/** Whether `command` changes something through a Plan: a write or destructive Command. */
|
|
6
|
+
export declare function hasPlan(command: Command): command is PlannedCommand;
|
package/dist/planned.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planned.js","sourceRoot":"","sources":["../src/planned.ts"],"names":[],"mappings":"AAIA,0FAA0F;AAC1F,MAAM,UAAU,OAAO,CAAC,OAAgB;IACtC,OAAO,OAAO,CAAC,MAAM,KAAK,OAAO,IAAI,OAAO,CAAC,MAAM,KAAK,aAAa,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Project, ProjectFile } from "./define.js";
|
|
2
|
+
export declare const PROJECT_INVALID = "PROJECT_INVALID";
|
|
3
|
+
/** The nearest Project file at or above `cwd`, parsed by its schema; undefined when there is none. */
|
|
4
|
+
export declare function projectOf<Settings>(projectFile: ProjectFile<Settings>, cwd: string): Project<Settings> | undefined;
|
package/dist/project.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join, resolve } from "node:path";
|
|
3
|
+
import * as z from "zod";
|
|
4
|
+
import { CliError, isMissingFile, messageOf } from "./errors.js";
|
|
5
|
+
export const PROJECT_INVALID = "PROJECT_INVALID";
|
|
6
|
+
function invalid(path, problem, options) {
|
|
7
|
+
return new CliError({
|
|
8
|
+
code: PROJECT_INVALID,
|
|
9
|
+
message: `the Project file ${path} is invalid: ${problem}`,
|
|
10
|
+
hint: `fix ${path}, then run the command again`,
|
|
11
|
+
}, options);
|
|
12
|
+
}
|
|
13
|
+
function readText(path) {
|
|
14
|
+
try {
|
|
15
|
+
return readFileSync(path, "utf8");
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
if (isMissingFile(error))
|
|
19
|
+
return undefined;
|
|
20
|
+
throw error;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function parsed(path, text, schema) {
|
|
24
|
+
let json;
|
|
25
|
+
try {
|
|
26
|
+
json = JSON.parse(text);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
throw invalid(path, messageOf(error), { cause: error });
|
|
30
|
+
}
|
|
31
|
+
const result = schema.safeParse(json);
|
|
32
|
+
if (!result.success)
|
|
33
|
+
throw invalid(path, z.prettifyError(result.error));
|
|
34
|
+
return result.data;
|
|
35
|
+
}
|
|
36
|
+
function projectFrom({ file, schema }, folder) {
|
|
37
|
+
const path = join(folder, file);
|
|
38
|
+
const text = readText(path);
|
|
39
|
+
if (text !== undefined)
|
|
40
|
+
return { root: folder, settings: parsed(path, text, schema) };
|
|
41
|
+
const parent = dirname(folder);
|
|
42
|
+
return parent === folder ? undefined : projectFrom({ file, schema }, parent);
|
|
43
|
+
}
|
|
44
|
+
/** The nearest Project file at or above `cwd`, parsed by its schema; undefined when there is none. */
|
|
45
|
+
export function projectOf(projectFile, cwd) {
|
|
46
|
+
return projectFrom(projectFile, resolve(cwd));
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../src/project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC;AAEzB,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEjE,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAEjD,SAAS,OAAO,CAAC,IAAY,EAAE,OAAe,EAAE,OAAsB;IACpE,OAAO,IAAI,QAAQ,CACjB;QACE,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,oBAAoB,IAAI,gBAAgB,OAAO,EAAE;QAC1D,IAAI,EAAE,OAAO,IAAI,8BAA8B;KAChD,EACD,OAAO,CACR,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,IAAY;IAC5B,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,aAAa,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,MAAM,CAAW,IAAY,EAAE,IAAY,EAAE,MAA2B;IAC/E,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACxE,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC;AAED,SAAS,WAAW,CAClB,EAAE,IAAI,EAAE,MAAM,EAAyB,EACvC,MAAc;IAEd,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;IACtF,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,OAAO,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC;AAC/E,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,SAAS,CACvB,WAAkC,EAClC,GAAW;IAEX,OAAO,WAAW,CAAC,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AAChD,CAAC"}
|
package/dist/route.d.ts
CHANGED
package/dist/route.js
CHANGED
|
@@ -49,7 +49,7 @@ function walk(node, words, json, invocation) {
|
|
|
49
49
|
if (isFlagLike(first)) {
|
|
50
50
|
const suggestions = closestFlags(first, GROUP_FLAGS);
|
|
51
51
|
const error = unknownOptionError(node.commandLine, invocation, first, suggestions);
|
|
52
|
-
return { kind: "usage error", error, json };
|
|
52
|
+
return { kind: "usage error", error, node, json };
|
|
53
53
|
}
|
|
54
54
|
return unknownCommand(node, first, json);
|
|
55
55
|
}
|
|
@@ -58,6 +58,7 @@ function unknownCommand(group, name, json) {
|
|
|
58
58
|
return {
|
|
59
59
|
kind: "usage error",
|
|
60
60
|
error: unknownCommandError(group.commandLine, name, suggestions),
|
|
61
|
+
node: group,
|
|
61
62
|
json,
|
|
62
63
|
};
|
|
63
64
|
}
|
package/dist/route.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.js","sourceRoot":"","sources":["../src/route.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAmB,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErE,kFAAkF;AAClF,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"route.js","sourceRoot":"","sources":["../src/route.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAmB,MAAM,iBAAiB,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErE,kFAAkF;AAClF,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,YAAY,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;AAuB9D,SAAS,SAAS,CAAC,KAAwB;IACzC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;IAC1C,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,SAAS,CAAC,KAAwB;IACzC,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,UAAU,CAAC,CAAC;AACpF,CAAC;AAED,SAAS,OAAO,CAAC,KAAgB,EAAE,IAAY;IAC7C,OAAO,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAChF,CAAC;AAED,4EAA4E;AAC5E,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;AAC5C,CAAC;AAED,SAAS,IAAI,CACX,IAAc,EACd,KAAwB,EACxB,IAAa,EACb,UAAsB;IAEtB,MAAM,IAAI,GAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACjD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAChF,CAAC;IACD,MAAM,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC;IAC/B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;IAC7C,CAAC;IACD,yEAAyE;IACzE,IAAI,KAAK,KAAK,cAAc,EAAE,CAAC;QAC7B,MAAM,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC;QAC9B,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAClC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,cAAc,EAAE,GAAG,KAAK,CAAC,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;QACnE,CAAC;QACD,OAAO,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;IACD,IAAI,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,WAAW,GAAG,YAAY,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC;QACrD,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;QACnF,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACpD,CAAC;IACD,OAAO,cAAc,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,cAAc,CAAC,KAAgB,EAAE,IAAY,EAAE,IAAa;IACnE,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IACpE,OAAO;QACL,IAAI,EAAE,aAAa;QACnB,KAAK,EAAE,mBAAmB,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,EAAE,WAAW,CAAC;QAChE,IAAI,EAAE,KAAK;QACX,IAAI;KACL,CAAC;AACJ,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,KAAK,CAAC,IAAc,EAAE,UAAsB;IAC1D,MAAM,EAAE,IAAI,EAAE,GAAG,UAAU,CAAC;IAC5B,MAAM,OAAO,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACnC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACnC,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,KAAK,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;IACjG,OAAO,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;AAC7C,CAAC"}
|
package/dist/run-cli.d.ts
CHANGED
|
@@ -1,16 +1,35 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type Clock } from "./clock.js";
|
|
2
|
+
import type { Cli, Env, NoPorts } from "./define.js";
|
|
3
|
+
import { type Files } from "./files.js";
|
|
2
4
|
import { type RunResult } from "./output.js";
|
|
3
|
-
|
|
5
|
+
import { type Spawn } from "./spawn.js";
|
|
6
|
+
export interface RunOptions<Ports = NoPorts> {
|
|
4
7
|
readonly env: Env;
|
|
5
8
|
readonly cwd: string;
|
|
6
9
|
readonly stdoutIsTTY?: boolean;
|
|
7
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Aborting it interrupts the running Command, which then ends with `INTERRUPTED`: exit 143 when
|
|
12
|
+
* the abort reason is `"SIGTERM"`, else 130, as for Ctrl-C.
|
|
13
|
+
*/
|
|
8
14
|
readonly signal?: AbortSignal;
|
|
9
15
|
/**
|
|
10
16
|
* The script that started the CLI, as `process.argv[1]`; `doctor` checks it is inside npm's
|
|
11
17
|
* global install. Absent, the CLI counts as run from source.
|
|
12
18
|
*/
|
|
13
19
|
readonly bin?: string;
|
|
20
|
+
/** Replaces the ports the CLI's factory builds, for a test. */
|
|
21
|
+
readonly ports?: Ports;
|
|
22
|
+
/** Replaces the real clock, for a test that runs deadlines and waits instantly. */
|
|
23
|
+
readonly clock?: Clock;
|
|
24
|
+
/** Replaces the real file system, for a test of a write that fails. */
|
|
25
|
+
readonly files?: Files;
|
|
26
|
+
/** Replaces the real child processes, for a test of a tool that fails. */
|
|
27
|
+
readonly spawn?: Spawn;
|
|
28
|
+
}
|
|
29
|
+
/** Where output that cannot wait for the run's end is written as it happens. */
|
|
30
|
+
export interface Writers {
|
|
31
|
+
stdout(text: string): void;
|
|
32
|
+
stderr(text: string): void;
|
|
14
33
|
}
|
|
15
|
-
export declare function runCli(cli: Cli, argv: readonly string[], options: RunOptions): Promise<RunResult>;
|
|
16
|
-
export declare function runWithProgress(cli: Cli, argv: readonly string[], options: RunOptions
|
|
34
|
+
export declare function runCli<Ports, Settings>(cli: Cli<Ports, Settings>, argv: readonly string[], options: RunOptions<NoInfer<Ports>>): Promise<RunResult>;
|
|
35
|
+
export declare function runWithProgress(cli: Cli, argv: readonly string[], options: RunOptions<unknown>, write: Writers): Promise<RunResult>;
|
package/dist/run-cli.js
CHANGED
|
@@ -1,84 +1,192 @@
|
|
|
1
|
+
import { isAgent } from "./agent.js";
|
|
1
2
|
import { builtInCommands } from "./built-ins.js";
|
|
3
|
+
import { poll, realClock } from "./clock.js";
|
|
2
4
|
import { commandSpec, groupSpec } from "./command-spec.js";
|
|
3
|
-
import {
|
|
5
|
+
import { deliveredOutcome, execute } from "./execute.js";
|
|
6
|
+
import { classifiedFiles, realFiles } from "./files.js";
|
|
4
7
|
import { RunControl } from "./interrupts.js";
|
|
5
|
-
import {
|
|
8
|
+
import { commandLineOf } from "./invocation.js";
|
|
9
|
+
import { commandResult, errorResult, helpResult, STOPPED_RESULT, startedOutput, textHelp, versionResult, } from "./output.js";
|
|
10
|
+
import { packageRootOf } from "./package-root.js";
|
|
6
11
|
import { parseCommand } from "./parse-input.js";
|
|
12
|
+
import { projectOf } from "./project.js";
|
|
7
13
|
import { route } from "./route.js";
|
|
14
|
+
import { secretOf } from "./secrets.js";
|
|
15
|
+
import { contextSpawn, realSpawn } from "./spawn.js";
|
|
16
|
+
import { spillTo } from "./spill.js";
|
|
8
17
|
import { styleFor } from "./style.js";
|
|
9
|
-
async function runCommand(routed, { base, signal, format: baseFormat }) {
|
|
18
|
+
async function runCommand(routed, { base, writeStdout, signal, format: baseFormat, ports, clock, files, spawn, projectFile }) {
|
|
10
19
|
const { command, commandLine } = routed.spec;
|
|
11
20
|
const format = { ...baseFormat, json: routed.json };
|
|
12
21
|
const { invocation } = format;
|
|
13
22
|
let parsed;
|
|
23
|
+
let project;
|
|
14
24
|
try {
|
|
15
25
|
parsed = parseCommand(routed, invocation);
|
|
26
|
+
project = projectFile === undefined ? undefined : projectOf(projectFile, base.cwd);
|
|
16
27
|
}
|
|
17
28
|
catch (error) {
|
|
18
29
|
return errorResult(error, format);
|
|
19
30
|
}
|
|
20
31
|
const { input, flags } = parsed;
|
|
21
|
-
const control = new RunControl(
|
|
32
|
+
const control = new RunControl({
|
|
33
|
+
commandLine,
|
|
34
|
+
outer: signal,
|
|
35
|
+
clock,
|
|
36
|
+
progress: base.progress,
|
|
37
|
+
runDeadline: command.deadline === undefined
|
|
38
|
+
? undefined
|
|
39
|
+
: { ms: command.deadline.ms, hint: command.deadline.resume(input) },
|
|
40
|
+
});
|
|
41
|
+
let delivered;
|
|
42
|
+
const callerLine = commandLineOf(invocation);
|
|
43
|
+
const classified = classifiedFiles(files, { cwd: base.cwd, env: base.env, callerLine });
|
|
44
|
+
const spill = spillTo({
|
|
45
|
+
cliName: format.cliName,
|
|
46
|
+
commandName: command.name,
|
|
47
|
+
env: base.env,
|
|
48
|
+
clock,
|
|
49
|
+
files: classified,
|
|
50
|
+
callerLine,
|
|
51
|
+
});
|
|
52
|
+
const portsBase = {
|
|
53
|
+
cwd: base.cwd,
|
|
54
|
+
env: base.env,
|
|
55
|
+
packageRoot: base.packageRoot,
|
|
56
|
+
secret: base.secret,
|
|
57
|
+
signal: control.signal,
|
|
58
|
+
clock,
|
|
59
|
+
files: classified,
|
|
60
|
+
spawn: contextSpawn(spawn, { cwd: base.cwd, env: base.env, signal: control.signal }, callerLine),
|
|
61
|
+
};
|
|
62
|
+
const builtPorts = once(() => ports(portsBase));
|
|
22
63
|
const ctx = {
|
|
23
64
|
...base,
|
|
24
|
-
|
|
65
|
+
...portsBase,
|
|
25
66
|
deadline: (ms) => control.deadline(ms),
|
|
26
|
-
runToEnd: (work) => control.runToEnd(work),
|
|
67
|
+
runToEnd: (name, work) => control.runToEnd(name, work),
|
|
68
|
+
// Built on first read, so a factory that throws fails only what needs the ports, never `doctor`.
|
|
69
|
+
get ports() {
|
|
70
|
+
return builtPorts();
|
|
71
|
+
},
|
|
72
|
+
project,
|
|
73
|
+
force: flags.force,
|
|
74
|
+
poll: (check, { intervalMs }) => poll(clock, check, intervalMs, control.signal),
|
|
75
|
+
deliver: (data) => {
|
|
76
|
+
delivered = deliveredOutcome(command, data);
|
|
77
|
+
},
|
|
27
78
|
};
|
|
79
|
+
let served = false;
|
|
28
80
|
let settled;
|
|
29
81
|
try {
|
|
30
82
|
const outcome = await control.settle(execute(command, input, ctx, {
|
|
31
83
|
dryRun: flags.dryRun,
|
|
32
84
|
confirm: flags.confirm,
|
|
85
|
+
yes: flags.yes,
|
|
33
86
|
page: flags.page,
|
|
34
87
|
invocation,
|
|
35
88
|
commandLine,
|
|
89
|
+
started: async (outcome) => {
|
|
90
|
+
writeStdout(await startedOutput(outcome, format, spill));
|
|
91
|
+
served = true;
|
|
92
|
+
},
|
|
36
93
|
}));
|
|
37
94
|
settled = { ok: true, outcome };
|
|
38
95
|
}
|
|
39
96
|
catch (error) {
|
|
97
|
+
if (served && control.signal.aborted) {
|
|
98
|
+
return STOPPED_RESULT;
|
|
99
|
+
}
|
|
40
100
|
settled = {
|
|
41
101
|
ok: false,
|
|
42
102
|
error: control.errorAfter(error),
|
|
43
|
-
|
|
103
|
+
delivered,
|
|
44
104
|
};
|
|
45
105
|
}
|
|
46
|
-
return commandResult(settled, { ...format, fields: flags.fields });
|
|
106
|
+
return commandResult(settled, { ...format, fields: flags.fields }, spill);
|
|
107
|
+
}
|
|
108
|
+
/** `build` runs on the first call; later calls give its value or throw its error again. */
|
|
109
|
+
function once(build) {
|
|
110
|
+
let outcome;
|
|
111
|
+
return () => {
|
|
112
|
+
if (outcome === undefined) {
|
|
113
|
+
try {
|
|
114
|
+
outcome = { ok: true, value: build() };
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
outcome = { ok: false, error };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (outcome.ok)
|
|
121
|
+
return outcome.value;
|
|
122
|
+
throw outcome.error;
|
|
123
|
+
};
|
|
47
124
|
}
|
|
48
125
|
export async function runCli(cli, argv, options) {
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
126
|
+
const stdout = [];
|
|
127
|
+
const stderr = [];
|
|
128
|
+
const result = await runWithProgress(cli, argv, options, {
|
|
129
|
+
stdout: (text) => stdout.push(text),
|
|
130
|
+
stderr: (text) => stderr.push(text),
|
|
131
|
+
});
|
|
132
|
+
return {
|
|
133
|
+
...result,
|
|
134
|
+
stdout: stdout.join("") + result.stdout,
|
|
135
|
+
stderr: stderr.join("") + result.stderr,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
function portsOf(cli, replacement) {
|
|
139
|
+
if (replacement !== undefined)
|
|
140
|
+
return () => replacement;
|
|
141
|
+
return cli.ports ?? (() => ({}));
|
|
52
142
|
}
|
|
53
|
-
// Progress is written as it happens:
|
|
54
|
-
|
|
143
|
+
// Progress is written as it happens: a Coding agent kills a process that stays silent too long.
|
|
144
|
+
// A serve Command's data is too, since the caller uses it while the Command runs.
|
|
145
|
+
export async function runWithProgress(cli, argv, options, write) {
|
|
55
146
|
const format = {
|
|
56
147
|
cliName: cli.name,
|
|
57
148
|
env: options.env,
|
|
58
149
|
style: styleFor(options.env, options.stdoutIsTTY === true),
|
|
59
150
|
invocation: { cliName: cli.name, argv },
|
|
60
151
|
json: false,
|
|
152
|
+
errors: cli.errors ?? {},
|
|
153
|
+
stop: options.signal,
|
|
61
154
|
};
|
|
155
|
+
const builtIns = cli.commands === undefined ? {} : builtInCommands(cli, options.bin);
|
|
62
156
|
const root = cli.commands === undefined
|
|
63
157
|
? commandSpec(cli.name, cli.command)
|
|
64
|
-
: groupSpec(cli.name, { ...cli.commands, ...
|
|
158
|
+
: groupSpec(cli.name, { ...cli.commands, ...builtIns });
|
|
65
159
|
const routed = route(root, format.invocation);
|
|
160
|
+
const misused = (node) => isAgent(options.env)
|
|
161
|
+
? { ...format, usageHelp: textHelp(node, root, cli, format.style) }
|
|
162
|
+
: format;
|
|
66
163
|
switch (routed.kind) {
|
|
67
164
|
case "version":
|
|
68
|
-
return versionResult(cli);
|
|
165
|
+
return versionResult(cli, packageRootOf(options.bin, options.cwd));
|
|
69
166
|
case "help":
|
|
70
167
|
return helpResult(routed.node, root, cli, { ...format, json: routed.json });
|
|
71
168
|
case "usage error":
|
|
72
|
-
return errorResult(routed.error, { ...
|
|
169
|
+
return errorResult(routed.error, { ...misused(routed.node), json: routed.json });
|
|
73
170
|
case "command":
|
|
74
171
|
return runCommand(routed, {
|
|
75
172
|
base: {
|
|
76
173
|
cwd: options.cwd,
|
|
77
174
|
env: options.env,
|
|
78
|
-
|
|
175
|
+
packageRoot: packageRootOf(options.bin, options.cwd),
|
|
176
|
+
progress: (message) => write.stderr(`${message}\n`),
|
|
177
|
+
secret: (name) => secretOf({ cliName: cli.name, env: options.env, callerLine: commandLineOf(format.invocation) }, name),
|
|
79
178
|
},
|
|
179
|
+
writeStdout: (text) => write.stdout(text),
|
|
80
180
|
signal: options.signal,
|
|
81
|
-
format,
|
|
181
|
+
format: misused(routed.spec),
|
|
182
|
+
ports: portsOf(cli, options.ports),
|
|
183
|
+
clock: options.clock ?? realClock,
|
|
184
|
+
files: options.files ?? realFiles(),
|
|
185
|
+
spawn: options.spawn ?? realSpawn,
|
|
186
|
+
// A built-in reads no Project file, so an invalid one never keeps `doctor` from reporting it.
|
|
187
|
+
projectFile: Object.values(builtIns).includes(routed.spec.command)
|
|
188
|
+
? undefined
|
|
189
|
+
: cli.project,
|
|
82
190
|
});
|
|
83
191
|
}
|
|
84
192
|
}
|