@duyquangnvx/create-agent-cli 0.12.0 → 0.13.1
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/dist/bin.js +123 -79
- package/package.json +2 -2
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.13.1 (2026-10-23)
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- The hints of `INTERRUPTED`, `DEADLINE_EXCEEDED`, `DISK_FULL`, `PERMISSION_DENIED` on Windows, `PROJECT_INVALID`, `TOOL_MISSING`, the npm errors of `update` and `doctor`, and a `doctor` row's fix now name the command line to run again, in backticks like the install and login lines they name, instead of "run the command again". `INTERRUPTED` adds that a run stopped on purpose needs no rerun, and a `ctx.timeout` hint says the call may have been billed, so ask the user before running it again.
|
|
12
|
+
|
|
13
|
+
## v0.13.0 (2026-10-23)
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- **Breaking:** `ctx.spawn`'s `progress: true` is now `onLine: ctx.progress`. `onLine` takes any callback, which receives each line of the child's stdout and stderr as it arrives, so a Command can parse a tool's progress output (`ffmpeg -progress pipe:1`) into its own `ctx.progress` lines; an `onLine` that throws kills the child and fails the run with its error. A lone `\r` now ends a line too, as in ffmpeg's `-stats` and curl's progress, instead of joining every status update into one line.
|
|
18
|
+
|
|
7
19
|
## v0.12.0 (2026-10-23)
|
|
8
20
|
|
|
9
21
|
### Added
|
package/dist/bin.js
CHANGED
|
@@ -6480,11 +6480,11 @@ function isCommand(node) {
|
|
|
6480
6480
|
//#endregion
|
|
6481
6481
|
//#region ../agent-cli/dist/project.js
|
|
6482
6482
|
const PROJECT_INVALID = "PROJECT_INVALID";
|
|
6483
|
-
function invalid(path, problem, options) {
|
|
6483
|
+
function invalid(path, problem, callerLine, options) {
|
|
6484
6484
|
return new CliError({
|
|
6485
6485
|
code: PROJECT_INVALID,
|
|
6486
6486
|
message: `the Project file ${path} is invalid: ${problem}`,
|
|
6487
|
-
hint: `fix ${path}, then run
|
|
6487
|
+
hint: `fix ${path}, then run \`${callerLine}\` again`
|
|
6488
6488
|
}, options);
|
|
6489
6489
|
}
|
|
6490
6490
|
function readText(path, fileError) {
|
|
@@ -6498,30 +6498,30 @@ function readText(path, fileError) {
|
|
|
6498
6498
|
});
|
|
6499
6499
|
}
|
|
6500
6500
|
}
|
|
6501
|
-
function parsed(path, text, schema) {
|
|
6501
|
+
function parsed(path, text, schema, callerLine) {
|
|
6502
6502
|
let json;
|
|
6503
6503
|
try {
|
|
6504
6504
|
json = JSON.parse(text);
|
|
6505
6505
|
} catch (error) {
|
|
6506
|
-
throw invalid(path, messageOf(error), { cause: error });
|
|
6506
|
+
throw invalid(path, messageOf(error), callerLine, { cause: error });
|
|
6507
6507
|
}
|
|
6508
6508
|
const result = schema.safeParse(json);
|
|
6509
|
-
if (!result.success) throw invalid(path, prettifyError(result.error));
|
|
6509
|
+
if (!result.success) throw invalid(path, prettifyError(result.error), callerLine);
|
|
6510
6510
|
return result.data;
|
|
6511
6511
|
}
|
|
6512
|
-
function projectFrom(projectFile, folder,
|
|
6512
|
+
function projectFrom(projectFile, folder, scope) {
|
|
6513
6513
|
const path = join(folder, projectFile.file);
|
|
6514
|
-
const text = readText(path, fileError);
|
|
6514
|
+
const text = readText(path, scope.fileError);
|
|
6515
6515
|
if (text !== void 0) return {
|
|
6516
6516
|
root: folder,
|
|
6517
|
-
settings: parsed(path, text, projectFile.schema)
|
|
6517
|
+
settings: parsed(path, text, projectFile.schema, scope.callerLine)
|
|
6518
6518
|
};
|
|
6519
6519
|
const parent = dirname(folder);
|
|
6520
|
-
return parent === folder ? void 0 : projectFrom(projectFile, parent,
|
|
6520
|
+
return parent === folder ? void 0 : projectFrom(projectFile, parent, scope);
|
|
6521
6521
|
}
|
|
6522
6522
|
/** The nearest Project file at or above `cwd`, parsed by its schema; undefined when there is none. */
|
|
6523
|
-
function projectOf(projectFile, cwd,
|
|
6524
|
-
return projectFrom(projectFile, resolve(cwd),
|
|
6523
|
+
function projectOf(projectFile, cwd, scope) {
|
|
6524
|
+
return projectFrom(projectFile, resolve(cwd), scope);
|
|
6525
6525
|
}
|
|
6526
6526
|
//#endregion
|
|
6527
6527
|
//#region ../agent-cli/dist/tools.js
|
|
@@ -6554,7 +6554,7 @@ async function findTool(name, env) {
|
|
|
6554
6554
|
for (const file of candidates) if (await isExecutable(file)) return file;
|
|
6555
6555
|
}
|
|
6556
6556
|
/** Fails with `TOOL_MISSING`, naming every missing tool at once, unless all are on `PATH`. */
|
|
6557
|
-
async function checkTools(tools, env) {
|
|
6557
|
+
async function checkTools(tools, env, callerLine) {
|
|
6558
6558
|
const found = await Promise.all(tools.map((tool) => findTool(tool.name, env)));
|
|
6559
6559
|
const missing = tools.filter((_tool, index) => found[index] === void 0);
|
|
6560
6560
|
if (missing.length === 0) return;
|
|
@@ -6562,7 +6562,7 @@ async function checkTools(tools, env) {
|
|
|
6562
6562
|
throw new CliError({
|
|
6563
6563
|
code: TOOL_MISSING,
|
|
6564
6564
|
message: `${missing.length === 1 ? "a tool it runs is" : "tools it runs are"} not on PATH: ${names}`,
|
|
6565
|
-
hint: `install ${missing.
|
|
6565
|
+
hint: `install ${missing.map(({ name, install }) => `${name} (\`${install}\`)`).join(", ")}, then run \`${callerLine}\` again`
|
|
6566
6566
|
});
|
|
6567
6567
|
}
|
|
6568
6568
|
function toolsIn(node) {
|
|
@@ -6607,6 +6607,7 @@ const CMD_SHIM = /\.cmd$/i;
|
|
|
6607
6607
|
const CMD_META = /([()\][%!^"`<>&|;, *?])/g;
|
|
6608
6608
|
const PATH_SEPARATOR = /[\\/]/;
|
|
6609
6609
|
const TRAILING_CR = /\r$/;
|
|
6610
|
+
const LINE_END = /\r\n|\r(?!$)|\n/;
|
|
6610
6611
|
function isWhole(input) {
|
|
6611
6612
|
return typeof input === "string" || input instanceof Uint8Array;
|
|
6612
6613
|
}
|
|
@@ -6660,20 +6661,31 @@ function stop(child) {
|
|
|
6660
6661
|
/** Calls `onLine` with each complete line pushed, and with the unterminated rest at the end. */
|
|
6661
6662
|
function lineSplitter(onLine) {
|
|
6662
6663
|
let rest = "";
|
|
6663
|
-
const emit = (line) => onLine?.(line.replace(TRAILING_CR, ""));
|
|
6664
6664
|
return {
|
|
6665
6665
|
push(text) {
|
|
6666
6666
|
if (onLine === void 0) return;
|
|
6667
|
-
const lines = (rest + text).split(
|
|
6667
|
+
const lines = (rest + text).split(LINE_END);
|
|
6668
6668
|
rest = lines.pop() ?? "";
|
|
6669
|
-
for (const line of lines)
|
|
6669
|
+
for (const line of lines) onLine(line);
|
|
6670
6670
|
},
|
|
6671
6671
|
end() {
|
|
6672
|
-
if (rest !== "")
|
|
6672
|
+
if (rest !== "") onLine?.(rest.replace(TRAILING_CR, ""));
|
|
6673
6673
|
rest = "";
|
|
6674
6674
|
}
|
|
6675
6675
|
};
|
|
6676
6676
|
}
|
|
6677
|
+
/** `onLine`, passing what it throws to `fail` and called no more once `failed()`. */
|
|
6678
|
+
function guarded(onLine, failed, fail) {
|
|
6679
|
+
if (onLine === void 0) return void 0;
|
|
6680
|
+
return (line) => {
|
|
6681
|
+
if (failed()) return;
|
|
6682
|
+
try {
|
|
6683
|
+
onLine(line);
|
|
6684
|
+
} catch (error) {
|
|
6685
|
+
fail(error);
|
|
6686
|
+
}
|
|
6687
|
+
};
|
|
6688
|
+
}
|
|
6677
6689
|
/** Settles once the child has taken what was written, or its stdin has closed. */
|
|
6678
6690
|
function drained(stdin) {
|
|
6679
6691
|
return new Promise((resolve) => {
|
|
@@ -6724,10 +6736,22 @@ async function spawnChild(command, args, { cwd, env, signal, onLine, stdin, deta
|
|
|
6724
6736
|
],
|
|
6725
6737
|
detached: detached && process.platform !== "win32"
|
|
6726
6738
|
});
|
|
6739
|
+
let stopped = Promise.resolve();
|
|
6740
|
+
const kill = () => {
|
|
6741
|
+
stopped = stop(child);
|
|
6742
|
+
};
|
|
6743
|
+
signal.addEventListener("abort", kill, { once: true });
|
|
6744
|
+
let callerFailure;
|
|
6745
|
+
const fail = (error) => {
|
|
6746
|
+
if (callerFailure !== void 0) return;
|
|
6747
|
+
callerFailure = { error };
|
|
6748
|
+
kill();
|
|
6749
|
+
};
|
|
6727
6750
|
let stdout = "";
|
|
6728
6751
|
let stderr = "";
|
|
6729
|
-
const
|
|
6730
|
-
const
|
|
6752
|
+
const lines = guarded(onLine, () => callerFailure !== void 0, fail);
|
|
6753
|
+
const stdoutLines = lineSplitter(lines);
|
|
6754
|
+
const stderrLines = lineSplitter(lines);
|
|
6731
6755
|
child.stdout?.setEncoding("utf8").on("data", (chunk) => {
|
|
6732
6756
|
stdout += chunk;
|
|
6733
6757
|
stdoutLines.push(chunk);
|
|
@@ -6736,16 +6760,7 @@ async function spawnChild(command, args, { cwd, env, signal, onLine, stdin, deta
|
|
|
6736
6760
|
stderr += chunk;
|
|
6737
6761
|
stderrLines.push(chunk);
|
|
6738
6762
|
});
|
|
6739
|
-
|
|
6740
|
-
const kill = () => {
|
|
6741
|
-
stopped = stop(child);
|
|
6742
|
-
};
|
|
6743
|
-
signal.addEventListener("abort", kill, { once: true });
|
|
6744
|
-
let inputFailure;
|
|
6745
|
-
if (stdin !== void 0 && child.stdin !== null) feed(child.stdin, stdin, signal).catch((error) => {
|
|
6746
|
-
inputFailure = { error };
|
|
6747
|
-
kill();
|
|
6748
|
-
});
|
|
6763
|
+
if (stdin !== void 0 && child.stdin !== null) feed(child.stdin, stdin, signal).catch(fail);
|
|
6749
6764
|
child.on("error", (error) => {
|
|
6750
6765
|
signal.removeEventListener("abort", kill);
|
|
6751
6766
|
reject(error);
|
|
@@ -6756,13 +6771,13 @@ async function spawnChild(command, args, { cwd, env, signal, onLine, stdin, deta
|
|
|
6756
6771
|
stopped.then(() => reject(signal.reason));
|
|
6757
6772
|
return;
|
|
6758
6773
|
}
|
|
6759
|
-
|
|
6760
|
-
|
|
6774
|
+
stdoutLines.end();
|
|
6775
|
+
stderrLines.end();
|
|
6776
|
+
if (callerFailure !== void 0) {
|
|
6777
|
+
const { error } = callerFailure;
|
|
6761
6778
|
stopped.then(() => reject(error));
|
|
6762
6779
|
return;
|
|
6763
6780
|
}
|
|
6764
|
-
stdoutLines.end();
|
|
6765
|
-
stderrLines.end();
|
|
6766
6781
|
resolve({
|
|
6767
6782
|
stdout,
|
|
6768
6783
|
stderr,
|
|
@@ -6780,15 +6795,15 @@ function failedError(command, { exitCode, stderr }) {
|
|
|
6780
6795
|
hint: `the output of ${command} above says why it failed`
|
|
6781
6796
|
});
|
|
6782
6797
|
}
|
|
6783
|
-
function missingError(command, cause) {
|
|
6798
|
+
function missingError(command, callerLine, cause) {
|
|
6784
6799
|
return new CliError({
|
|
6785
6800
|
code: TOOL_MISSING,
|
|
6786
6801
|
message: `${command} could not be started: it is not on PATH`,
|
|
6787
|
-
hint: `install ${command}, then run
|
|
6802
|
+
hint: `install ${command}, then run \`${callerLine}\` again`
|
|
6788
6803
|
}, { cause });
|
|
6789
6804
|
}
|
|
6790
|
-
function startError(command, error, fileError) {
|
|
6791
|
-
if (isMissingFile(error)) return missingError(command, error);
|
|
6805
|
+
function startError(command, error, { fileError, callerLine }) {
|
|
6806
|
+
if (isMissingFile(error)) return missingError(command, callerLine, error);
|
|
6792
6807
|
return fileError(error, {
|
|
6793
6808
|
path: command,
|
|
6794
6809
|
access: "read"
|
|
@@ -6806,23 +6821,35 @@ async function* reported(stream, onError) {
|
|
|
6806
6821
|
function reporting(input, onError) {
|
|
6807
6822
|
return input === void 0 || isWhole(input) ? input : reported(input, onError);
|
|
6808
6823
|
}
|
|
6809
|
-
/** `
|
|
6810
|
-
function
|
|
6824
|
+
/** `onLine`, passing each error it throws to `onError` before its caller sees it. */
|
|
6825
|
+
function reportingLines(onLine, onError) {
|
|
6826
|
+
if (onLine === void 0) return void 0;
|
|
6827
|
+
return (line) => {
|
|
6828
|
+
try {
|
|
6829
|
+
onLine(line);
|
|
6830
|
+
} catch (error) {
|
|
6831
|
+
onError(error);
|
|
6832
|
+
throw error;
|
|
6833
|
+
}
|
|
6834
|
+
};
|
|
6835
|
+
}
|
|
6836
|
+
function contextSpawn(run, defaults, scope) {
|
|
6811
6837
|
return async (command, args = [], options = {}) => {
|
|
6812
|
-
let
|
|
6838
|
+
let callerFailure;
|
|
6839
|
+
const caller = (error) => {
|
|
6840
|
+
callerFailure = { error };
|
|
6841
|
+
};
|
|
6813
6842
|
let result;
|
|
6814
6843
|
try {
|
|
6815
6844
|
result = await run(command, args, {
|
|
6816
6845
|
cwd: options.cwd ?? defaults.cwd,
|
|
6817
6846
|
env: options.env ?? defaults.env,
|
|
6818
6847
|
signal: defaults.signal,
|
|
6819
|
-
onLine: options.
|
|
6820
|
-
stdin: reporting(options.stdin,
|
|
6821
|
-
inputFailure = { error };
|
|
6822
|
-
})
|
|
6848
|
+
onLine: reportingLines(options.onLine, caller),
|
|
6849
|
+
stdin: reporting(options.stdin, caller)
|
|
6823
6850
|
});
|
|
6824
6851
|
} catch (error) {
|
|
6825
|
-
throw
|
|
6852
|
+
throw callerFailure?.error === error ? error : startError(command, error, scope);
|
|
6826
6853
|
}
|
|
6827
6854
|
if (options.check === true && result.exitCode !== 0) throw failedError(command, result);
|
|
6828
6855
|
return result;
|
|
@@ -6899,6 +6926,7 @@ const NO_LATEST = "NO_LATEST";
|
|
|
6899
6926
|
function npmContext(cli, registry, ctx, node, cwd) {
|
|
6900
6927
|
return {
|
|
6901
6928
|
cliName: cli.name,
|
|
6929
|
+
callerLine: ctx.commandLine(),
|
|
6902
6930
|
registry,
|
|
6903
6931
|
cwd,
|
|
6904
6932
|
env: ctx.env,
|
|
@@ -6938,8 +6966,8 @@ function globalRegistry(install) {
|
|
|
6938
6966
|
package: name,
|
|
6939
6967
|
label: registry,
|
|
6940
6968
|
flags: registryFlags(install),
|
|
6941
|
-
unreachableHint: "check the network or VPN
|
|
6942
|
-
loginHint: `log in to ${registry} (npm login --registry=${registry}) or set its token in ~/.npmrc
|
|
6969
|
+
unreachableHint: "check the network or VPN",
|
|
6970
|
+
loginHint: `log in to ${registry} (\`npm login --registry=${registry}\`) or set its token in ~/.npmrc`,
|
|
6943
6971
|
missingHint: `check that ${name} is published on ${registry}`
|
|
6944
6972
|
};
|
|
6945
6973
|
}
|
|
@@ -6993,26 +7021,27 @@ function failureOf(call, answer, ctx) {
|
|
|
6993
7021
|
const { label: registry, package: name, loginHint, unreachableHint } = ctx.registry;
|
|
6994
7022
|
const code = NPM_CODE.exec(answer.stderr)?.[1];
|
|
6995
7023
|
const output = tail$1(answer.stderr);
|
|
7024
|
+
const rerun = `run \`${ctx.callerLine}\` again`;
|
|
6996
7025
|
if (code !== void 0 && NETWORK_CODES.has(code)) return new CliError({
|
|
6997
7026
|
code: REGISTRY_UNREACHABLE,
|
|
6998
7027
|
message: `npm could not reach ${registry} (${code})${output}`,
|
|
6999
|
-
hint: unreachableHint
|
|
7028
|
+
hint: `${unreachableHint}, then ${rerun}`
|
|
7000
7029
|
});
|
|
7001
7030
|
if (code !== void 0 && AUTH_CODES.has(code)) return new CliError({
|
|
7002
7031
|
code: REGISTRY_AUTH,
|
|
7003
7032
|
message: `${registry} refused npm's credentials (${code})${output}`,
|
|
7004
|
-
hint: loginHint
|
|
7033
|
+
hint: `${loginHint}, then ${rerun}`
|
|
7005
7034
|
});
|
|
7006
7035
|
if (call === "view" && code === "E404") return noLatest(ctx, `npm found no ${name}@latest on ${registry}: no version of it is published there`);
|
|
7007
7036
|
if (call === "install") return new CliError({
|
|
7008
7037
|
code: INSTALL_FAILED,
|
|
7009
7038
|
message: `npm could not install ${name}${code === void 0 ? "" : ` (${code})`}${output}`,
|
|
7010
|
-
hint: `fix what npm reports, then
|
|
7039
|
+
hint: `fix what npm reports, then ${rerun}, or install it yourself: \`${installCommandLine(ctx.registry)}\``
|
|
7011
7040
|
});
|
|
7012
7041
|
return new CliError({
|
|
7013
7042
|
code: NPM_FAILED,
|
|
7014
7043
|
message: `npm ${call} failed with exit code ${answer.exitCode}${output}`,
|
|
7015
|
-
hint:
|
|
7044
|
+
hint: `fix what npm reports, then ${rerun}`
|
|
7016
7045
|
});
|
|
7017
7046
|
}
|
|
7018
7047
|
function noLatest(ctx, message) {
|
|
@@ -7300,8 +7329,8 @@ function registryOf({ package: name }, root) {
|
|
|
7300
7329
|
package: name,
|
|
7301
7330
|
label: `the registry npm uses for ${name}`,
|
|
7302
7331
|
flags: [],
|
|
7303
|
-
unreachableHint: scope === void 0 ? "check the network or VPN
|
|
7304
|
-
loginHint: `log in to it (npm login${scope === void 0 ? "" : ` --scope=${scope}`}) or set its token in ${npmrc}
|
|
7332
|
+
unreachableHint: scope === void 0 ? "check the network or VPN" : `check the network or VPN and the ${scope}:registry that ${npmrc} sets`,
|
|
7333
|
+
loginHint: `log in to it (\`npm login${scope === void 0 ? "" : ` --scope=${scope}`}\`) or set its token in ${npmrc}`,
|
|
7305
7334
|
missingHint: scope === void 0 ? `check that ${name} is published on the registry ${npmrc} names` : `check that ${name} is published, and that ${npmrc} maps ${scope} to its registry: ${scope}:registry=<url>`
|
|
7306
7335
|
};
|
|
7307
7336
|
}
|
|
@@ -7447,7 +7476,10 @@ function readProject(projectFile, ctx) {
|
|
|
7447
7476
|
try {
|
|
7448
7477
|
return {
|
|
7449
7478
|
ok: true,
|
|
7450
|
-
project: projectOf(projectFile, ctx.cwd,
|
|
7479
|
+
project: projectOf(projectFile, ctx.cwd, {
|
|
7480
|
+
fileError: ctx.fileError,
|
|
7481
|
+
callerLine: ctx.commandLine()
|
|
7482
|
+
})
|
|
7451
7483
|
};
|
|
7452
7484
|
} catch (error) {
|
|
7453
7485
|
return {
|
|
@@ -7648,11 +7680,11 @@ function render({ rows, next }, style) {
|
|
|
7648
7680
|
return `${check.padEnd(width)}${label}${" ".repeat(stateWidth - state.length)}${message}`;
|
|
7649
7681
|
}), ...next.map((fix) => `${"next".padEnd(width)}${fix}`)].join("\n");
|
|
7650
7682
|
}
|
|
7651
|
-
function failure(cliName, problems) {
|
|
7683
|
+
function failure(cliName, callerLine, problems) {
|
|
7652
7684
|
const errors = problems.map(({ check, message, fix, code }) => new CliError({
|
|
7653
7685
|
code: code ?? "DOCTOR_PROBLEMS",
|
|
7654
7686
|
message: `${cliName} doctor found a problem in ${check}: ${message}`,
|
|
7655
|
-
hint: fix === void 0 ? "the row says what is wrong" : `run
|
|
7687
|
+
hint: fix === void 0 ? "the row says what is wrong" : `run \`${fix}\`, then run \`${callerLine}\` again`
|
|
7656
7688
|
}));
|
|
7657
7689
|
return new AggregateError(errors);
|
|
7658
7690
|
}
|
|
@@ -7685,7 +7717,7 @@ function doctorCommand(cli, launch) {
|
|
|
7685
7717
|
const problems = checked.filter(({ row, advisory }) => row.state === "problem" && !advisory).map(({ row }) => row);
|
|
7686
7718
|
if (problems.length > 0) {
|
|
7687
7719
|
ctx.deliver(report);
|
|
7688
|
-
throw failure(cli.name, problems);
|
|
7720
|
+
throw failure(cli.name, ctx.commandLine(), problems);
|
|
7689
7721
|
}
|
|
7690
7722
|
return report;
|
|
7691
7723
|
},
|
|
@@ -7699,14 +7731,16 @@ const DEADLINE_EXCEEDED = "DEADLINE_EXCEEDED";
|
|
|
7699
7731
|
/** How long an interrupted Command may take to settle before the run ends without it. */
|
|
7700
7732
|
const GRACE_MS = 3e3;
|
|
7701
7733
|
const GRACE_OVER = Symbol("grace over");
|
|
7702
|
-
function interruptedError() {
|
|
7734
|
+
function interruptedError(callerLine) {
|
|
7703
7735
|
return new CliError({
|
|
7704
7736
|
code: INTERRUPTED,
|
|
7705
7737
|
message: "interrupted before it finished",
|
|
7706
|
-
hint:
|
|
7738
|
+
hint: `to finish it, run \`${callerLine}\` again, unless it was stopped on purpose; if a tool timeout stopped it, give it longer`
|
|
7707
7739
|
});
|
|
7708
7740
|
}
|
|
7709
|
-
|
|
7741
|
+
function waitHint(callerLine, bound) {
|
|
7742
|
+
return bound === "timeout" ? `the call may have been billed: ask your user before running \`${callerLine}\` again` : `run \`${callerLine}\` again later, when the service it waits on may answer faster`;
|
|
7743
|
+
}
|
|
7710
7744
|
function deadlineError(commandLine, ms, hint, bound = "deadline") {
|
|
7711
7745
|
return new CliError({
|
|
7712
7746
|
code: DEADLINE_EXCEEDED,
|
|
@@ -7719,8 +7753,9 @@ var RunControl = class {
|
|
|
7719
7753
|
signal;
|
|
7720
7754
|
#controller = new AbortController();
|
|
7721
7755
|
#commandLine;
|
|
7756
|
+
#callerLine;
|
|
7722
7757
|
#outer;
|
|
7723
|
-
#onOuterAbort = () => this.#controller.abort(interruptedError());
|
|
7758
|
+
#onOuterAbort = () => this.#controller.abort(interruptedError(this.#callerLine));
|
|
7724
7759
|
/** Each running must-finish step, tracked until it settles, with its name. */
|
|
7725
7760
|
#steps = /* @__PURE__ */ new Map();
|
|
7726
7761
|
#progress;
|
|
@@ -7733,8 +7768,9 @@ var RunControl = class {
|
|
|
7733
7768
|
#graceOver = new Promise((resolve) => {
|
|
7734
7769
|
this.#endGrace = resolve;
|
|
7735
7770
|
});
|
|
7736
|
-
constructor({ commandLine, outer, clock, progress, runDeadline }) {
|
|
7771
|
+
constructor({ commandLine, callerLine, outer, clock, progress, runDeadline }) {
|
|
7737
7772
|
this.#commandLine = commandLine;
|
|
7773
|
+
this.#callerLine = callerLine;
|
|
7738
7774
|
this.#outer = outer;
|
|
7739
7775
|
this.#clock = clock;
|
|
7740
7776
|
this.#progress = progress;
|
|
@@ -7756,7 +7792,7 @@ var RunControl = class {
|
|
|
7756
7792
|
#abortsAfter(ms, bound) {
|
|
7757
7793
|
const controller = new AbortController();
|
|
7758
7794
|
after(this.#clock, ms, this.#disposed.signal, () => {
|
|
7759
|
-
const reason = deadlineError(this.#commandLine, ms,
|
|
7795
|
+
const reason = deadlineError(this.#commandLine, ms, waitHint(this.#callerLine, bound), bound);
|
|
7760
7796
|
this.#abortReasons.add(reason);
|
|
7761
7797
|
controller.abort(reason);
|
|
7762
7798
|
});
|
|
@@ -8070,7 +8106,7 @@ const NOT_FOUND = "NOT_FOUND";
|
|
|
8070
8106
|
const ALREADY_EXISTS = "ALREADY_EXISTS";
|
|
8071
8107
|
const NOT_A_FILE = "NOT_A_FILE";
|
|
8072
8108
|
function permissionHint({ path, access, callerLine, env, platform }) {
|
|
8073
|
-
if (platform === "win32") return `a program may hold ${path} open: close it, then run
|
|
8109
|
+
if (platform === "win32") return `a program may hold ${path} open: close it, then run \`${callerLine}\` again`;
|
|
8074
8110
|
if (!isAgent(env)) return `check the permissions of ${path} and its folder`;
|
|
8075
8111
|
return `your sandbox may block it: ask your user to run \`! ${callerLine}\`, or ${access === "read" ? `to allow reading ${path} in the sandbox` : `to allow ${path} in the sandbox's write list`}`;
|
|
8076
8112
|
}
|
|
@@ -8095,7 +8131,7 @@ function classifyErrno(error, context) {
|
|
|
8095
8131
|
case "EDQUOT": return new CliError({
|
|
8096
8132
|
code: DISK_FULL,
|
|
8097
8133
|
message: `no space left on the disk holding ${path}`,
|
|
8098
|
-
hint:
|
|
8134
|
+
hint: `free space on that disk, then run \`${context.callerLine}\` again`
|
|
8099
8135
|
}, { cause: error });
|
|
8100
8136
|
case "ENOENT":
|
|
8101
8137
|
case "ENOTDIR":
|
|
@@ -9018,7 +9054,7 @@ function dryRunOutcome(command, plan) {
|
|
|
9018
9054
|
};
|
|
9019
9055
|
}
|
|
9020
9056
|
async function execute(command, input, ctx, { dryRun, confirm, yes, page, invocation, commandLine, started, files, guardOutputs }) {
|
|
9021
|
-
await checkTools(command.tools ?? [], ctx.env);
|
|
9057
|
+
await checkTools(command.tools ?? [], ctx.env, ctx.commandLine());
|
|
9022
9058
|
if (command.rows !== void 0) return outcomeOf(await command.run({
|
|
9023
9059
|
...input,
|
|
9024
9060
|
...page
|
|
@@ -9373,7 +9409,7 @@ function portsOf(cli, replacement) {
|
|
|
9373
9409
|
return cli.ports ?? (() => ({}));
|
|
9374
9410
|
}
|
|
9375
9411
|
function portsBaseOf(scope, signal) {
|
|
9376
|
-
const { cli, options, packageRoot, progress, fileError, clock, files } = scope;
|
|
9412
|
+
const { cli, options, packageRoot, progress, fileError, callerLine, clock, files } = scope;
|
|
9377
9413
|
const { cwd, env } = options;
|
|
9378
9414
|
const envFile = envFileOf(cli.name, env);
|
|
9379
9415
|
return {
|
|
@@ -9397,9 +9433,11 @@ function portsBaseOf(scope, signal) {
|
|
|
9397
9433
|
spawn: contextSpawn(options.spawn ?? realSpawn, {
|
|
9398
9434
|
cwd,
|
|
9399
9435
|
env,
|
|
9400
|
-
signal
|
|
9401
|
-
|
|
9402
|
-
|
|
9436
|
+
signal
|
|
9437
|
+
}, {
|
|
9438
|
+
fileError,
|
|
9439
|
+
callerLine
|
|
9440
|
+
})
|
|
9403
9441
|
};
|
|
9404
9442
|
}
|
|
9405
9443
|
function contextOf(portsBase, control, parts) {
|
|
@@ -9435,8 +9473,10 @@ async function runCommand(cli, routed, options, write, baseFormat) {
|
|
|
9435
9473
|
flags: knownFlags(routed.spec),
|
|
9436
9474
|
stdinArg: stdinArgOf(routed)
|
|
9437
9475
|
};
|
|
9476
|
+
const typedLine = (change) => commandLineOf(invocation, change);
|
|
9477
|
+
const rerunLine = typedLine();
|
|
9438
9478
|
const fileError = fileErrorOf({
|
|
9439
|
-
callerLine:
|
|
9479
|
+
callerLine: rerunLine,
|
|
9440
9480
|
env,
|
|
9441
9481
|
platform
|
|
9442
9482
|
});
|
|
@@ -9446,20 +9486,20 @@ async function runCommand(cli, routed, options, write, baseFormat) {
|
|
|
9446
9486
|
json: routed.json,
|
|
9447
9487
|
invocation
|
|
9448
9488
|
};
|
|
9449
|
-
const
|
|
9450
|
-
const callerLine = commandLineOf({
|
|
9489
|
+
const pipedLine = commandLineOf({
|
|
9451
9490
|
...invocation,
|
|
9452
9491
|
stdinArg: void 0
|
|
9453
9492
|
});
|
|
9454
9493
|
let resumeHint;
|
|
9455
9494
|
const control = new RunControl({
|
|
9456
9495
|
commandLine,
|
|
9496
|
+
callerLine: rerunLine,
|
|
9457
9497
|
outer: options.signal,
|
|
9458
9498
|
clock,
|
|
9459
9499
|
progress,
|
|
9460
9500
|
runDeadline: command.deadline === void 0 ? void 0 : {
|
|
9461
9501
|
ms: command.deadline.ms,
|
|
9462
|
-
hint: () => resumeHint ?? stdinNeverEndedHint(
|
|
9502
|
+
hint: () => resumeHint ?? stdinNeverEndedHint(pipedLine)
|
|
9463
9503
|
}
|
|
9464
9504
|
});
|
|
9465
9505
|
const failed = (error, finishSideTask) => {
|
|
@@ -9476,7 +9516,7 @@ async function runCommand(cli, routed, options, write, baseFormat) {
|
|
|
9476
9516
|
if (isTerminal(stdin)) progress(readingLine(field.name, platform));
|
|
9477
9517
|
return readStdin(stdin, control.signal, {
|
|
9478
9518
|
clock,
|
|
9479
|
-
stalled: () => stdinStalled(
|
|
9519
|
+
stalled: () => stdinStalled(pipedLine)
|
|
9480
9520
|
});
|
|
9481
9521
|
});
|
|
9482
9522
|
} catch (error) {
|
|
@@ -9494,6 +9534,7 @@ async function runCommand(cli, routed, options, write, baseFormat) {
|
|
|
9494
9534
|
packageRoot,
|
|
9495
9535
|
progress,
|
|
9496
9536
|
fileError,
|
|
9537
|
+
callerLine: rerunLine,
|
|
9497
9538
|
clock,
|
|
9498
9539
|
files: outputs.files
|
|
9499
9540
|
};
|
|
@@ -9517,7 +9558,10 @@ async function runCommand(cli, routed, options, write, baseFormat) {
|
|
|
9517
9558
|
});
|
|
9518
9559
|
let project;
|
|
9519
9560
|
try {
|
|
9520
|
-
project = builtIn || cli.project === void 0 ? void 0 : projectOf(cli.project, cwd,
|
|
9561
|
+
project = builtIn || cli.project === void 0 ? void 0 : projectOf(cli.project, cwd, {
|
|
9562
|
+
fileError,
|
|
9563
|
+
callerLine: rerunLine
|
|
9564
|
+
});
|
|
9521
9565
|
} catch (error) {
|
|
9522
9566
|
return failed(error, finishSideTask);
|
|
9523
9567
|
}
|
|
@@ -9732,14 +9776,14 @@ async function runProcess(cli) {
|
|
|
9732
9776
|
}
|
|
9733
9777
|
//#endregion
|
|
9734
9778
|
//#region package.json
|
|
9735
|
-
var version$1 = "0.
|
|
9779
|
+
var version$1 = "0.13.1";
|
|
9736
9780
|
var description = "Creates a new Agent CLI repository wired to @duyquangnvx/agent-cli.";
|
|
9737
9781
|
//#endregion
|
|
9738
9782
|
//#region src/build.ts
|
|
9739
9783
|
const build = {
|
|
9740
|
-
"sha": "
|
|
9784
|
+
"sha": "7b1baa9",
|
|
9741
9785
|
"dirty": false,
|
|
9742
|
-
"builtAt": "2026-10-
|
|
9786
|
+
"builtAt": "2026-10-23T13:03:05.000Z"
|
|
9743
9787
|
};
|
|
9744
9788
|
//#endregion
|
|
9745
9789
|
//#region src/steps.ts
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@duyquangnvx/create-agent-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.1",
|
|
4
4
|
"description": "Creates a new Agent CLI repository wired to @duyquangnvx/agent-cli.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"access": "public"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
|
-
"@duyquangnvx/agent-cli": "0.
|
|
22
|
+
"@duyquangnvx/agent-cli": "0.13.1",
|
|
23
23
|
"tsdown": "0.23.0",
|
|
24
24
|
"zod": "4.6.7"
|
|
25
25
|
},
|