@duyquangnvx/agent-cli 0.4.0 → 0.6.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 +80 -0
- package/dist/agent-cli.js +2 -2
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent.d.ts +5 -3
- package/dist/agent.js +31 -10
- package/dist/agent.js.map +1 -1
- package/dist/built-ins/commands.d.ts +8 -0
- package/dist/{built-ins.js → built-ins/commands.js} +4 -4
- package/dist/built-ins/commands.js.map +1 -0
- package/dist/built-ins/doctor-rows.d.ts +4 -0
- package/dist/{doctor-rows.js → built-ins/doctor-rows.js} +18 -26
- package/dist/built-ins/doctor-rows.js.map +1 -0
- package/dist/built-ins/doctor.d.ts +5 -0
- package/dist/{doctor.js → built-ins/doctor.js} +27 -20
- package/dist/built-ins/doctor.js.map +1 -0
- package/dist/{global-install.js → built-ins/global-install.js} +1 -1
- package/dist/built-ins/global-install.js.map +1 -0
- package/dist/{npm.d.ts → built-ins/npm.d.ts} +5 -2
- package/dist/{npm.js → built-ins/npm.js} +25 -33
- package/dist/built-ins/npm.js.map +1 -0
- package/dist/built-ins/semver.js.map +1 -0
- package/dist/built-ins/skills.d.ts +18 -0
- package/dist/built-ins/skills.js +97 -0
- package/dist/built-ins/skills.js.map +1 -0
- package/dist/{update.d.ts → built-ins/update.d.ts} +3 -2
- package/dist/{update.js → built-ins/update.js} +28 -18
- package/dist/built-ins/update.js.map +1 -0
- package/dist/{upgrade-notes.js → built-ins/upgrade-notes.js} +1 -1
- package/dist/built-ins/upgrade-notes.js.map +1 -0
- package/dist/clock.d.ts +1 -0
- package/dist/clock.js.map +1 -1
- package/dist/command-spec.d.ts +17 -2
- package/dist/command-spec.js +30 -9
- package/dist/command-spec.js.map +1 -1
- package/dist/confirm.js +6 -2
- package/dist/confirm.js.map +1 -1
- package/dist/context.d.ts +139 -0
- package/dist/context.js +2 -0
- package/dist/context.js.map +1 -0
- package/dist/cost.js +2 -2
- package/dist/cost.js.map +1 -1
- package/dist/define.d.ts +100 -87
- package/dist/define.js +3 -1
- package/dist/define.js.map +1 -1
- package/dist/errno.d.ts +8 -4
- package/dist/errno.js +21 -4
- package/dist/errno.js.map +1 -1
- package/dist/error-table.d.ts +6 -1
- package/dist/error-table.js +5 -1
- package/dist/error-table.js.map +1 -1
- package/dist/errors.d.ts +11 -2
- package/dist/errors.js +21 -8
- package/dist/errors.js.map +1 -1
- package/dist/execute.d.ts +9 -2
- package/dist/execute.js +10 -3
- package/dist/execute.js.map +1 -1
- package/dist/exit-classes.js +38 -38
- package/dist/exit-classes.js.map +1 -1
- package/dist/files.d.ts +30 -8
- package/dist/files.js +104 -17
- package/dist/files.js.map +1 -1
- package/dist/help-json.d.ts +2 -2
- package/dist/help-json.js +6 -2
- package/dist/help-json.js.map +1 -1
- package/dist/help.d.ts +1 -1
- package/dist/help.js +14 -9
- package/dist/help.js.map +1 -1
- package/dist/index.d.ts +12 -5
- package/dist/index.js +6 -2
- package/dist/index.js.map +1 -1
- package/dist/input.d.ts +7 -1
- package/dist/input.js +33 -4
- package/dist/input.js.map +1 -1
- package/dist/interrupts.d.ts +7 -2
- package/dist/interrupts.js +29 -15
- package/dist/interrupts.js.map +1 -1
- package/dist/invocation.d.ts +10 -5
- package/dist/invocation.js +24 -11
- package/dist/invocation.js.map +1 -1
- package/dist/list.d.ts +12 -3
- package/dist/list.js +38 -6
- package/dist/list.js.map +1 -1
- package/dist/manifest.d.ts +17 -0
- package/dist/manifest.js +24 -0
- package/dist/manifest.js.map +1 -0
- package/dist/operator.d.ts +5 -0
- package/dist/operator.js +15 -0
- package/dist/operator.js.map +1 -0
- package/dist/output.d.ts +6 -4
- package/dist/output.js +5 -6
- package/dist/output.js.map +1 -1
- package/dist/outputs.d.ts +24 -1
- package/dist/outputs.js +58 -2
- package/dist/outputs.js.map +1 -1
- package/dist/parse-input.d.ts +11 -2
- package/dist/parse-input.js +78 -27
- package/dist/parse-input.js.map +1 -1
- package/dist/project.d.ts +3 -2
- package/dist/project.js +11 -10
- package/dist/project.js.map +1 -1
- package/dist/route.d.ts +1 -1
- package/dist/route.js +2 -1
- package/dist/route.js.map +1 -1
- package/dist/run-cli.d.ts +8 -33
- package/dist/run-cli.js +50 -157
- package/dist/run-cli.js.map +1 -1
- package/dist/run-command.d.ts +11 -0
- package/dist/run-command.js +234 -0
- package/dist/run-command.js.map +1 -0
- package/dist/run-options.d.ts +48 -0
- package/dist/run-options.js +2 -0
- package/dist/run-options.js.map +1 -0
- package/dist/run-process.js +7 -4
- package/dist/run-process.js.map +1 -1
- package/dist/secrets.d.ts +10 -6
- package/dist/secrets.js +8 -9
- package/dist/secrets.js.map +1 -1
- package/dist/side-task.d.ts +27 -0
- package/dist/side-task.js +31 -0
- package/dist/side-task.js.map +1 -0
- package/dist/spawn.d.ts +29 -6
- package/dist/spawn.js +126 -29
- package/dist/spawn.js.map +1 -1
- package/dist/spill.d.ts +4 -3
- package/dist/spill.js +1 -7
- package/dist/spill.js.map +1 -1
- package/dist/stdin.d.ts +33 -0
- package/dist/stdin.js +92 -0
- package/dist/stdin.js.map +1 -0
- package/dist/style.d.ts +1 -1
- package/dist/tokenize.d.ts +3 -0
- package/dist/tokenize.js +5 -4
- package/dist/tokenize.js.map +1 -1
- package/dist/tools.d.ts +6 -3
- package/dist/tools.js +18 -11
- package/dist/tools.js.map +1 -1
- package/dist/usage.d.ts +2 -0
- package/dist/usage.js +12 -1
- package/dist/usage.js.map +1 -1
- package/dist/version.d.ts +3 -0
- package/dist/version.js +7 -0
- package/dist/version.js.map +1 -0
- package/package.json +1 -1
- package/dist/built-ins.d.ts +0 -3
- package/dist/built-ins.js.map +0 -1
- package/dist/doctor-rows.d.ts +0 -3
- package/dist/doctor-rows.js.map +0 -1
- package/dist/doctor.d.ts +0 -4
- package/dist/doctor.js.map +0 -1
- package/dist/global-install.js.map +0 -1
- package/dist/npm.js.map +0 -1
- package/dist/semver.js.map +0 -1
- package/dist/skills.d.ts +0 -11
- package/dist/skills.js +0 -58
- package/dist/skills.js.map +0 -1
- package/dist/update.js.map +0 -1
- package/dist/upgrade-notes.js.map +0 -1
- /package/dist/{global-install.d.ts → built-ins/global-install.d.ts} +0 -0
- /package/dist/{semver.d.ts → built-ins/semver.d.ts} +0 -0
- /package/dist/{semver.js → built-ins/semver.js} +0 -0
- /package/dist/{upgrade-notes.d.ts → built-ins/upgrade-notes.d.ts} +0 -0
package/dist/run-cli.js
CHANGED
|
@@ -1,193 +1,86 @@
|
|
|
1
1
|
import { isAgent } from "./agent.js";
|
|
2
|
-
import { builtInCommands } from "./built-ins.js";
|
|
3
|
-
import { poll, realClock } from "./clock.js";
|
|
2
|
+
import { builtInCommands } from "./built-ins/commands.js";
|
|
4
3
|
import { commandSpec, groupSpec } from "./command-spec.js";
|
|
5
|
-
import {
|
|
6
|
-
import { classifiedFiles, realFiles } from "./files.js";
|
|
7
|
-
import { RunControl } from "./interrupts.js";
|
|
8
|
-
import { commandLineOf } from "./invocation.js";
|
|
9
|
-
import { commandResult, errorResult, helpResult, STOPPED_RESULT, startedOutput, textHelp, versionResult, } from "./output.js";
|
|
4
|
+
import { errorResult, helpResult, progressLine, textHelp, versionResult, } from "./output.js";
|
|
10
5
|
import { packageRootOf } from "./package-root.js";
|
|
11
|
-
import { parseCommand } from "./parse-input.js";
|
|
12
|
-
import { projectOf } from "./project.js";
|
|
13
6
|
import { route } from "./route.js";
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import { spillTo } from "./spill.js";
|
|
7
|
+
import { runCommand } from "./run-command.js";
|
|
8
|
+
import { noSideTask } from "./side-task.js";
|
|
17
9
|
import { styleFor } from "./style.js";
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
let parsed;
|
|
23
|
-
let project;
|
|
24
|
-
try {
|
|
25
|
-
parsed = parseCommand(routed, invocation);
|
|
26
|
-
project = projectFile === undefined ? undefined : projectOf(projectFile, base.cwd);
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
return errorResult(error, format);
|
|
30
|
-
}
|
|
31
|
-
const { input, flags } = parsed;
|
|
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));
|
|
63
|
-
const ctx = {
|
|
64
|
-
...base,
|
|
65
|
-
...portsBase,
|
|
66
|
-
deadline: (ms) => control.deadline(ms),
|
|
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
|
-
},
|
|
78
|
-
};
|
|
79
|
-
let served = false;
|
|
80
|
-
let settled;
|
|
81
|
-
try {
|
|
82
|
-
const outcome = await control.settle(execute(command, input, ctx, {
|
|
83
|
-
dryRun: flags.dryRun,
|
|
84
|
-
confirm: flags.confirm,
|
|
85
|
-
yes: flags.yes,
|
|
86
|
-
page: flags.page,
|
|
87
|
-
invocation,
|
|
88
|
-
commandLine,
|
|
89
|
-
started: async (outcome) => {
|
|
90
|
-
writeStdout(await startedOutput(outcome, format, spill));
|
|
91
|
-
served = true;
|
|
92
|
-
},
|
|
93
|
-
}));
|
|
94
|
-
settled = { ok: true, outcome };
|
|
95
|
-
}
|
|
96
|
-
catch (error) {
|
|
97
|
-
if (served && control.signal.aborted) {
|
|
98
|
-
return STOPPED_RESULT;
|
|
99
|
-
}
|
|
100
|
-
settled = {
|
|
101
|
-
ok: false,
|
|
102
|
-
error: control.errorAfter(error),
|
|
103
|
-
delivered,
|
|
104
|
-
};
|
|
105
|
-
}
|
|
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
|
-
};
|
|
124
|
-
}
|
|
10
|
+
/**
|
|
11
|
+
* Runs the CLI in-process on `argv` and returns its `stdout`, `stderr` and `exitCode`, as a Coding
|
|
12
|
+
* agent would see them; the options replace the process's env, cwd and the Runtime's helpers.
|
|
13
|
+
*/
|
|
125
14
|
export async function runCli(cli, argv, options) {
|
|
126
15
|
const stdout = [];
|
|
127
16
|
const stderr = [];
|
|
128
|
-
const
|
|
17
|
+
const { exitCode } = await runWithProgress(cli, argv, options, {
|
|
129
18
|
stdout: (text) => stdout.push(text),
|
|
130
19
|
stderr: (text) => stderr.push(text),
|
|
20
|
+
result: async (result) => {
|
|
21
|
+
stdout.push(result.stdout);
|
|
22
|
+
stderr.push(result.stderr);
|
|
23
|
+
},
|
|
131
24
|
});
|
|
132
|
-
return {
|
|
133
|
-
...result,
|
|
134
|
-
stdout: stdout.join("") + result.stdout,
|
|
135
|
-
stderr: stderr.join("") + result.stderr,
|
|
136
|
-
};
|
|
25
|
+
return { stdout: stdout.join(""), stderr: stderr.join(""), exitCode };
|
|
137
26
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
27
|
+
// Without --json, the leading newline moves the notice off the terminal's echoed ^C.
|
|
28
|
+
function stopLine(notice, json) {
|
|
29
|
+
return json ? progressLine(notice, true) : `\n${notice}\n`;
|
|
30
|
+
}
|
|
31
|
+
/** Calls `onStop` if `signal` aborts while `work` runs. */
|
|
32
|
+
async function whileStopping(signal, onStop, work) {
|
|
33
|
+
if (signal === undefined || onStop === undefined)
|
|
34
|
+
return work();
|
|
35
|
+
signal.addEventListener("abort", onStop, { once: true });
|
|
36
|
+
try {
|
|
37
|
+
return await work();
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
signal.removeEventListener("abort", onStop);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/** Runs the CLI, writes its output, then waits for the Side task it started. */
|
|
44
|
+
export async function runWithProgress(cli, argv, options, write, stopNotice) {
|
|
45
|
+
const { result, finishSideTask } = await routeAndRun(cli, argv, options, write, stopNotice);
|
|
46
|
+
await write.result(result);
|
|
47
|
+
await finishSideTask();
|
|
48
|
+
return result;
|
|
142
49
|
}
|
|
143
50
|
// Progress is written as it happens: a Coding agent kills a process that stays silent too long.
|
|
144
51
|
// A serve Command's data is too, since the caller uses it while the Command runs.
|
|
145
|
-
|
|
52
|
+
async function routeAndRun(cli, argv, options, write, stopNotice) {
|
|
146
53
|
const format = {
|
|
147
54
|
cliName: cli.name,
|
|
148
55
|
env: options.env,
|
|
149
56
|
style: styleFor(options.env, options.stdoutIsTTY === true),
|
|
150
|
-
invocation: { cliName: cli.name, argv },
|
|
57
|
+
invocation: { cliName: cli.name, argv, flags: [] },
|
|
151
58
|
json: false,
|
|
152
59
|
errors: cli.errors ?? {},
|
|
153
60
|
stop: options.signal,
|
|
154
61
|
};
|
|
155
|
-
const builtIns = cli.commands === undefined ? {} : builtInCommands(cli, options.bin);
|
|
156
62
|
const root = cli.commands === undefined
|
|
157
|
-
?
|
|
158
|
-
|
|
63
|
+
? // A single-Command CLI is its Command, so the CLI's line stands in for the Command's.
|
|
64
|
+
{ ...commandSpec(cli.name, cli.command), description: cli.description }
|
|
65
|
+
: groupSpec(cli.name, cli.commands, builtInCommands(cli, { bin: options.bin, node: options.node }));
|
|
159
66
|
const routed = route(root, format.invocation);
|
|
160
67
|
const misused = (node) => isAgent(options.env)
|
|
161
68
|
? { ...format, usageHelp: textHelp(node, root, cli, format.style) }
|
|
162
69
|
: format;
|
|
163
70
|
switch (routed.kind) {
|
|
164
71
|
case "version":
|
|
165
|
-
return versionResult(cli, packageRootOf(options.bin, options.cwd));
|
|
72
|
+
return ranAlone(versionResult(cli, packageRootOf(options.bin, options.cwd)));
|
|
166
73
|
case "help":
|
|
167
|
-
return helpResult(routed.node, root, cli, { ...format, json: routed.json });
|
|
74
|
+
return ranAlone(helpResult(routed.node, root, cli, { ...format, json: routed.json }));
|
|
168
75
|
case "usage error":
|
|
169
|
-
return errorResult(routed.error, { ...misused(routed.node), json: routed.json });
|
|
76
|
+
return ranAlone(errorResult(routed.error, { ...misused(routed.node), json: routed.json }));
|
|
170
77
|
case "command":
|
|
171
|
-
return
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
env: options.env,
|
|
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),
|
|
178
|
-
},
|
|
179
|
-
writeStdout: (text) => write.stdout(text),
|
|
180
|
-
signal: options.signal,
|
|
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,
|
|
190
|
-
});
|
|
78
|
+
return whileStopping(options.signal, stopNotice === undefined
|
|
79
|
+
? undefined
|
|
80
|
+
: () => write.stderr(stopLine(stopNotice, routed.json)), () => runCommand(cli, routed, options, write, misused(routed.spec)));
|
|
191
81
|
}
|
|
192
82
|
}
|
|
83
|
+
async function ranAlone(result) {
|
|
84
|
+
return { result: await result, finishSideTask: noSideTask };
|
|
85
|
+
}
|
|
193
86
|
//# sourceMappingURL=run-cli.js.map
|
package/dist/run-cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-cli.js","sourceRoot":"","sources":["../src/run-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"run-cli.js","sourceRoot":"","sources":["../src/run-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Cli } from "./define.js";
|
|
2
|
+
import { type OutputFormat, type RunResult } from "./output.js";
|
|
3
|
+
import type { CommandRoute } from "./route.js";
|
|
4
|
+
import type { RunOptions, Writers } from "./run-options.js";
|
|
5
|
+
import { type FinishSideTask } from "./side-task.js";
|
|
6
|
+
export interface Ran {
|
|
7
|
+
readonly result: RunResult;
|
|
8
|
+
readonly finishSideTask: FinishSideTask;
|
|
9
|
+
}
|
|
10
|
+
/** Leaves the Side task running, so the caller writes the result before it waits for it. */
|
|
11
|
+
export declare function runCommand(cli: Cli, routed: CommandRoute, options: RunOptions<unknown>, write: Writers, baseFormat: OutputFormat): Promise<Ran>;
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { poll, realClock } from "./clock.js";
|
|
2
|
+
import { fileErrorOf } from "./errno.js";
|
|
3
|
+
import { isDebug, traceOf } from "./errors.js";
|
|
4
|
+
import { deliveredOutcome, execute } from "./execute.js";
|
|
5
|
+
import { classifiedFiles, realFiles } from "./files.js";
|
|
6
|
+
import { RunControl } from "./interrupts.js";
|
|
7
|
+
import { commandLineOf } from "./invocation.js";
|
|
8
|
+
import { manifestAt } from "./manifest.js";
|
|
9
|
+
import { checkOperator } from "./operator.js";
|
|
10
|
+
import { commandResult, errorResult, progressLine, STOPPED_RESULT, startedOutput, } from "./output.js";
|
|
11
|
+
import { outputsGuard } from "./outputs.js";
|
|
12
|
+
import { packageRootOf } from "./package-root.js";
|
|
13
|
+
import { knownFlags, parseCommand } from "./parse-input.js";
|
|
14
|
+
import { projectOf } from "./project.js";
|
|
15
|
+
import { envFileOf, secretOf } from "./secrets.js";
|
|
16
|
+
import { noSideTask, startSideTask } from "./side-task.js";
|
|
17
|
+
import { contextSpawn, realSpawn } from "./spawn.js";
|
|
18
|
+
import { spillTo } from "./spill.js";
|
|
19
|
+
import { isTerminal, readingLine, readStdin, stdinStalled } from "./stdin.js";
|
|
20
|
+
function stdinNeverEndedHint(callerLine) {
|
|
21
|
+
return `stdin never ended: pipe the text into \`${callerLine}\`, or redirect a file into it`;
|
|
22
|
+
}
|
|
23
|
+
function selfOf(name, bin) {
|
|
24
|
+
return bin === undefined ? [name] : [process.execPath, ...process.execArgv, bin];
|
|
25
|
+
}
|
|
26
|
+
function portsOf(cli, replacement) {
|
|
27
|
+
if (replacement !== undefined)
|
|
28
|
+
return () => replacement;
|
|
29
|
+
return cli.ports ?? (() => ({}));
|
|
30
|
+
}
|
|
31
|
+
function portsBaseOf(scope, signal) {
|
|
32
|
+
const { cli, options, packageRoot, progress, fileError, clock, files } = scope;
|
|
33
|
+
const { cwd, env } = options;
|
|
34
|
+
const envFile = envFileOf(cli.name, env);
|
|
35
|
+
return {
|
|
36
|
+
cwd,
|
|
37
|
+
env,
|
|
38
|
+
packageRoot,
|
|
39
|
+
progress,
|
|
40
|
+
secret: (name) => secretOf({ envFile, env, fileError }, name),
|
|
41
|
+
envFile,
|
|
42
|
+
fileError,
|
|
43
|
+
version: cli.version,
|
|
44
|
+
build: cli.build,
|
|
45
|
+
self: selfOf(cli.name, options.bin),
|
|
46
|
+
signal,
|
|
47
|
+
clock,
|
|
48
|
+
files,
|
|
49
|
+
spawn: contextSpawn(options.spawn ?? realSpawn, { cwd, env, signal, progress }, fileError),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function contextOf(portsBase, control, parts) {
|
|
53
|
+
const { ports, project, force, commandLine, deliver } = parts;
|
|
54
|
+
return {
|
|
55
|
+
...portsBase,
|
|
56
|
+
deadline: (ms) => control.deadline(ms),
|
|
57
|
+
timeout: (ms) => control.timeout(ms),
|
|
58
|
+
runToEnd: (name, work) => control.runToEnd(name, work),
|
|
59
|
+
// Built on first read, so a factory that throws fails only what needs the ports, never `doctor`.
|
|
60
|
+
get ports() {
|
|
61
|
+
return ports();
|
|
62
|
+
},
|
|
63
|
+
project,
|
|
64
|
+
force,
|
|
65
|
+
commandLine,
|
|
66
|
+
poll: (check, { intervalMs, signal: stop }) => poll(portsBase.clock, check, intervalMs, stop === undefined ? control.signal : AbortSignal.any([control.signal, stop])),
|
|
67
|
+
deliver,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/** Leaves the Side task running, so the caller writes the result before it waits for it. */
|
|
71
|
+
export async function runCommand(cli, routed, options, write, baseFormat) {
|
|
72
|
+
const { command, commandLine, builtIn } = routed.spec;
|
|
73
|
+
const { cwd, env } = options;
|
|
74
|
+
const clock = options.clock ?? realClock;
|
|
75
|
+
const files = options.files ?? realFiles();
|
|
76
|
+
const stdin = options.stdin ?? "";
|
|
77
|
+
const platform = options.platform ?? process.platform;
|
|
78
|
+
const ports = portsOf(cli, options.ports);
|
|
79
|
+
const packageRoot = packageRootOf(options.bin, cwd);
|
|
80
|
+
const fileError = fileErrorOf({
|
|
81
|
+
callerLine: commandLineOf(baseFormat.invocation),
|
|
82
|
+
env,
|
|
83
|
+
platform,
|
|
84
|
+
});
|
|
85
|
+
const progress = (message) => write.stderr(progressLine(message, routed.json));
|
|
86
|
+
const invocation = { ...baseFormat.invocation, flags: knownFlags(routed.spec) };
|
|
87
|
+
const format = {
|
|
88
|
+
...baseFormat,
|
|
89
|
+
bugs: () => manifestAt(packageRoot).bugs,
|
|
90
|
+
json: routed.json,
|
|
91
|
+
invocation,
|
|
92
|
+
};
|
|
93
|
+
const typedLine = (change) => commandLineOf(invocation, change);
|
|
94
|
+
// Set once the input is parsed; a deadline before that can only have cut off the stdin read.
|
|
95
|
+
let resumeHint;
|
|
96
|
+
// Created before the input is parsed, so Ctrl-C and the run deadline also bound the stdin read.
|
|
97
|
+
const control = new RunControl({
|
|
98
|
+
commandLine,
|
|
99
|
+
outer: options.signal,
|
|
100
|
+
clock,
|
|
101
|
+
progress,
|
|
102
|
+
runDeadline: command.deadline === undefined
|
|
103
|
+
? undefined
|
|
104
|
+
: {
|
|
105
|
+
ms: command.deadline.ms,
|
|
106
|
+
hint: () => resumeHint ?? stdinNeverEndedHint(typedLine()),
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
const failed = (error, finishSideTask) => {
|
|
110
|
+
control.close();
|
|
111
|
+
return { result: errorResult(error, format), finishSideTask };
|
|
112
|
+
};
|
|
113
|
+
let parsed;
|
|
114
|
+
try {
|
|
115
|
+
checkOperator(routed.spec, env, typedLine());
|
|
116
|
+
parsed = await parseCommand(routed, invocation, (field) => {
|
|
117
|
+
if (isTerminal(stdin))
|
|
118
|
+
progress(readingLine(field.name, platform));
|
|
119
|
+
return readStdin(stdin, control.signal, {
|
|
120
|
+
clock,
|
|
121
|
+
stalled: () => stdinStalled(typedLine()),
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
return failed(error, noSideTask);
|
|
127
|
+
}
|
|
128
|
+
const { input, flags } = parsed;
|
|
129
|
+
resumeHint = command.deadline?.resume(input, typedLine);
|
|
130
|
+
const outputs = outputsGuard(classifiedFiles(files, { cwd, fileError }), cwd);
|
|
131
|
+
const scope = {
|
|
132
|
+
cli,
|
|
133
|
+
options,
|
|
134
|
+
packageRoot,
|
|
135
|
+
progress,
|
|
136
|
+
fileError,
|
|
137
|
+
clock,
|
|
138
|
+
files: outputs.files,
|
|
139
|
+
};
|
|
140
|
+
const portsBase = portsBaseOf(scope, control.signal);
|
|
141
|
+
const finishSideTask = startSideTask(builtIn ? undefined : cli.sideTask?.bind(cli), (sideSignal) => {
|
|
142
|
+
const sideBase = portsBaseOf(scope, sideSignal);
|
|
143
|
+
const sidePorts = once(() => ports(sideBase));
|
|
144
|
+
return {
|
|
145
|
+
...sideBase,
|
|
146
|
+
command: routed.spec.path,
|
|
147
|
+
dryRun: flags.dryRun,
|
|
148
|
+
get ports() {
|
|
149
|
+
return sidePorts();
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}, {
|
|
153
|
+
clock,
|
|
154
|
+
failed: (error) => {
|
|
155
|
+
if (isDebug(baseFormat))
|
|
156
|
+
progress(`side task failed: ${traceOf(error)}`);
|
|
157
|
+
},
|
|
158
|
+
});
|
|
159
|
+
let project;
|
|
160
|
+
try {
|
|
161
|
+
// A built-in reads no Project file, so an invalid one never keeps `doctor` from reporting it.
|
|
162
|
+
project =
|
|
163
|
+
builtIn || cli.project === undefined ? undefined : projectOf(cli.project, cwd, fileError);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
return failed(error, finishSideTask);
|
|
167
|
+
}
|
|
168
|
+
let delivered;
|
|
169
|
+
const ctx = contextOf(portsBase, control, {
|
|
170
|
+
ports: once(() => ports(portsBase)),
|
|
171
|
+
project,
|
|
172
|
+
force: flags.force,
|
|
173
|
+
commandLine: typedLine,
|
|
174
|
+
deliver: (data) => {
|
|
175
|
+
delivered = deliveredOutcome(command, data);
|
|
176
|
+
},
|
|
177
|
+
});
|
|
178
|
+
const spill = spillTo({
|
|
179
|
+
cliName: format.cliName,
|
|
180
|
+
commandName: command.name,
|
|
181
|
+
env,
|
|
182
|
+
clock,
|
|
183
|
+
files: outputs.files,
|
|
184
|
+
fileError,
|
|
185
|
+
});
|
|
186
|
+
let served = false;
|
|
187
|
+
let settled;
|
|
188
|
+
try {
|
|
189
|
+
const outcome = await control.settle(execute(command, input, ctx, {
|
|
190
|
+
dryRun: flags.dryRun,
|
|
191
|
+
confirm: flags.confirm,
|
|
192
|
+
yes: flags.yes,
|
|
193
|
+
page: flags.page,
|
|
194
|
+
invocation,
|
|
195
|
+
commandLine,
|
|
196
|
+
started: async (outcome) => {
|
|
197
|
+
write.stdout(await startedOutput(outcome, format, spill));
|
|
198
|
+
served = true;
|
|
199
|
+
},
|
|
200
|
+
files,
|
|
201
|
+
guardOutputs: outputs.guard,
|
|
202
|
+
}));
|
|
203
|
+
settled = { ok: true, outcome };
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
// A serve Command that started its output and is then stopped has nothing more to write.
|
|
207
|
+
if (served && control.signal.aborted) {
|
|
208
|
+
return { result: STOPPED_RESULT, finishSideTask };
|
|
209
|
+
}
|
|
210
|
+
settled = { ok: false, error: control.errorAfter(error), delivered };
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
result: await commandResult(settled, { ...format, fields: flags.fields }, spill),
|
|
214
|
+
finishSideTask,
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
/** `build` runs on the first call; later calls give its value or throw its error again. */
|
|
218
|
+
function once(build) {
|
|
219
|
+
let outcome;
|
|
220
|
+
return () => {
|
|
221
|
+
if (outcome === undefined) {
|
|
222
|
+
try {
|
|
223
|
+
outcome = { ok: true, value: build() };
|
|
224
|
+
}
|
|
225
|
+
catch (error) {
|
|
226
|
+
outcome = { ok: false, error };
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (outcome.ok)
|
|
230
|
+
return outcome.value;
|
|
231
|
+
throw outcome.error;
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=run-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-command.js","sourceRoot":"","sources":["../src/run-command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Clock } from "./clock.js";
|
|
2
|
+
import type { Env } from "./context.js";
|
|
3
|
+
import type { NoPorts } from "./define.js";
|
|
4
|
+
import type { Files } from "./files.js";
|
|
5
|
+
import type { RunResult } from "./output.js";
|
|
6
|
+
import type { Spawn } from "./spawn.js";
|
|
7
|
+
import type { StdinSource } from "./stdin.js";
|
|
8
|
+
export interface RunOptions<Ports = NoPorts> {
|
|
9
|
+
readonly env: Env;
|
|
10
|
+
readonly cwd: string;
|
|
11
|
+
readonly stdoutIsTTY?: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Aborting it interrupts the running Command, which then ends with `INTERRUPTED`: exit 143 when
|
|
14
|
+
* the abort reason is `"SIGTERM"`, else 130, as for Ctrl-C.
|
|
15
|
+
*/
|
|
16
|
+
readonly signal?: AbortSignal;
|
|
17
|
+
/**
|
|
18
|
+
* The script that started the CLI, as `process.argv[1]`; `doctor` checks it is inside npm's
|
|
19
|
+
* global install. Absent, the CLI counts as run from source.
|
|
20
|
+
*/
|
|
21
|
+
readonly bin?: string;
|
|
22
|
+
/**
|
|
23
|
+
* The Node running the CLI, as `process.execPath`; `doctor` and `update` run the npm beside it,
|
|
24
|
+
* which installs into that Node. Absent, or with no npm beside it, they run the npm on PATH.
|
|
25
|
+
*/
|
|
26
|
+
readonly node?: string;
|
|
27
|
+
/** Replaces the ports the CLI's factory builds, for a test. */
|
|
28
|
+
readonly ports?: Ports;
|
|
29
|
+
/** Replaces the real clock, for a test that runs deadlines and waits instantly. */
|
|
30
|
+
readonly clock?: Clock;
|
|
31
|
+
/** Replaces the real file system, for a test of a write that fails. */
|
|
32
|
+
readonly files?: Files;
|
|
33
|
+
/** Replaces the real child processes, for a test of a tool that fails. */
|
|
34
|
+
readonly spawn?: Spawn;
|
|
35
|
+
/** What an arg given `-` reads; absent, it reads an empty text. */
|
|
36
|
+
readonly stdin?: StdinSource;
|
|
37
|
+
/**
|
|
38
|
+
* Replaces `process.platform` in picking the wording of hints, such as `PERMISSION_DENIED`'s and
|
|
39
|
+
* how to end stdin, for a test of the Windows wording.
|
|
40
|
+
*/
|
|
41
|
+
readonly platform?: NodeJS.Platform;
|
|
42
|
+
}
|
|
43
|
+
/** Where output that cannot wait for the run's end is written as it happens, and the run's output once it ends. */
|
|
44
|
+
export interface Writers {
|
|
45
|
+
stdout(text: string): void;
|
|
46
|
+
stderr(text: string): void;
|
|
47
|
+
result(result: RunResult): Promise<void>;
|
|
48
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-options.js","sourceRoot":"","sources":["../src/run-options.ts"],"names":[],"mappings":""}
|
package/dist/run-process.js
CHANGED
|
@@ -10,7 +10,6 @@ export async function runProcess(cli) {
|
|
|
10
10
|
if (stop.signal.aborted) {
|
|
11
11
|
process.exit(SIGNAL_EXIT_CODES[signal]);
|
|
12
12
|
}
|
|
13
|
-
process.stderr.write("\nstopping… (Ctrl-C again to quit now)\n");
|
|
14
13
|
stop.abort(signal);
|
|
15
14
|
};
|
|
16
15
|
process.on("SIGINT", onSignal);
|
|
@@ -22,12 +21,16 @@ export async function runProcess(cli) {
|
|
|
22
21
|
stdoutIsTTY: process.stdout.isTTY === true,
|
|
23
22
|
signal: stop.signal,
|
|
24
23
|
bin: process.argv[1],
|
|
24
|
+
node: process.execPath,
|
|
25
|
+
stdin: process.stdin,
|
|
25
26
|
}, {
|
|
26
27
|
stdout: (text) => process.stdout.write(text),
|
|
27
28
|
stderr: (text) => process.stderr.write(text),
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
result: async ({ stdout, stderr }) => {
|
|
30
|
+
await written(process.stdout, stdout);
|
|
31
|
+
await written(process.stderr, stderr);
|
|
32
|
+
},
|
|
33
|
+
}, "stopping… (Ctrl-C again to quit now)");
|
|
31
34
|
process.exitCode = result.exitCode;
|
|
32
35
|
}
|
|
33
36
|
finally {
|
package/dist/run-process.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-process.js","sourceRoot":"","sources":["../src/run-process.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAmB,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,SAAS,OAAO,CAAC,MAA0B,EAAE,IAAY;IACvD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAQ;IACvC,MAAM,IAAI,GAAG,IAAI,eAAe,EAAE,CAAC;IACnC,iGAAiG;IACjG,MAAM,QAAQ,GAAG,CAAC,MAAkB,EAAQ,EAAE;QAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1C,CAAC;QACD,
|
|
1
|
+
{"version":3,"file":"run-process.js","sourceRoot":"","sources":["../src/run-process.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAmB,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,SAAS,OAAO,CAAC,MAA0B,EAAE,IAAY;IACvD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAQ;IACvC,MAAM,IAAI,GAAG,IAAI,eAAe,EAAE,CAAC;IACnC,iGAAiG;IACjG,MAAM,QAAQ,GAAG,CAAC,MAAkB,EAAQ,EAAE;QAC5C,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACxB,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,eAAe,CAClC,GAAG,EACH,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EACrB;YACE,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;YAClB,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI;YAC1C,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YACpB,IAAI,EAAE,OAAO,CAAC,QAAQ;YACtB,KAAK,EAAE,OAAO,CAAC,KAAK;SACrB,EACD;YACE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;YAC5C,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;YAC5C,MAAM,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE;gBACnC,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;gBACtC,MAAM,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YACxC,CAAC;SACF,EACD,sCAAsC,CACvC,CAAC;QACF,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;IACrC,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IACD,mGAAmG;IACnG,OAAO,CAAC,IAAI,EAAE,CAAC;AACjB,CAAC"}
|