@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.
Files changed (3) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/bin.js +123 -79
  3. 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 the command again`
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, fileError) {
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, fileError);
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, fileError) {
6524
- return projectFrom(projectFile, resolve(cwd), fileError);
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.length === 1 ? "it" : "them"}, then run the same command again: ${missing.map(({ install }) => install).join("; ")}`
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("\n");
6667
+ const lines = (rest + text).split(LINE_END);
6668
6668
  rest = lines.pop() ?? "";
6669
- for (const line of lines) emit(line);
6669
+ for (const line of lines) onLine(line);
6670
6670
  },
6671
6671
  end() {
6672
- if (rest !== "") emit(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 stdoutLines = lineSplitter(onLine);
6730
- const stderrLines = lineSplitter(onLine);
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
- let stopped = Promise.resolve();
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
- if (inputFailure !== void 0) {
6760
- const { error } = inputFailure;
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 the same command again`
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
- /** `ctx.spawn`: `spawn` bound to the run, its start failures classified by errno. */
6810
- function contextSpawn(run, defaults, fileError) {
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 inputFailure;
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.progress === true ? defaults.progress : void 0,
6820
- stdin: reporting(options.stdin, (error) => {
6821
- inputFailure = { error };
6822
- })
6848
+ onLine: reportingLines(options.onLine, caller),
6849
+ stdin: reporting(options.stdin, caller)
6823
6850
  });
6824
6851
  } catch (error) {
6825
- throw inputFailure?.error === error ? error : startError(command, error, fileError);
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, then run it again",
6942
- loginHint: `log in to ${registry} (npm login --registry=${registry}) or set its token in ~/.npmrc, then run it again`,
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 run it again, or install it yourself: ${installCommandLine(ctx.registry)}`
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: "fix what npm reports, then run it again"
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, then run it again" : `check the network or VPN and the ${scope}:registry that ${npmrc} sets, then run it again`,
7304
- loginHint: `log in to it (npm login${scope === void 0 ? "" : ` --scope=${scope}`}) or set its token in ${npmrc}, then run it again`,
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, ctx.fileError)
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 ${fix}, then run doctor again`
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: "run the command again"
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
- const WAIT_HINT = "run it again later, when the service it waits on may answer faster";
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, WAIT_HINT, bound);
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 the same command again`;
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: "free space on that disk, then run the same command again"
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
- progress
9402
- }, fileError)
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: commandLineOf(invocation),
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 typedLine = (change) => commandLineOf(invocation, change);
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(callerLine)
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(callerLine)
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, fileError);
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.12.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": "cc95e77",
9784
+ "sha": "7b1baa9",
9741
9785
  "dirty": false,
9742
- "builtAt": "2026-10-23T01:20:23.000Z"
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.12.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.12.0",
22
+ "@duyquangnvx/agent-cli": "0.13.1",
23
23
  "tsdown": "0.23.0",
24
24
  "zod": "4.6.7"
25
25
  },