@duyquangnvx/create-agent-cli 0.12.0 → 0.13.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 CHANGED
@@ -4,6 +4,12 @@ What changed in each release of `@duyquangnvx/agent-cli` (the Runtime) and `@duy
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## v0.13.0 (2026-10-23)
8
+
9
+ ### Changed
10
+
11
+ - **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.
12
+
7
13
  ## v0.12.0 (2026-10-23)
8
14
 
9
15
  ### Added
package/dist/bin.js CHANGED
@@ -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,
@@ -6806,23 +6821,36 @@ 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
  }
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
+ }
6809
6836
  /** `ctx.spawn`: `spawn` bound to the run, its start failures classified by errno. */
6810
6837
  function contextSpawn(run, defaults, fileError) {
6811
6838
  return async (command, args = [], options = {}) => {
6812
- let inputFailure;
6839
+ let callerFailure;
6840
+ const caller = (error) => {
6841
+ callerFailure = { error };
6842
+ };
6813
6843
  let result;
6814
6844
  try {
6815
6845
  result = await run(command, args, {
6816
6846
  cwd: options.cwd ?? defaults.cwd,
6817
6847
  env: options.env ?? defaults.env,
6818
6848
  signal: defaults.signal,
6819
- onLine: options.progress === true ? defaults.progress : void 0,
6820
- stdin: reporting(options.stdin, (error) => {
6821
- inputFailure = { error };
6822
- })
6849
+ onLine: reportingLines(options.onLine, caller),
6850
+ stdin: reporting(options.stdin, caller)
6823
6851
  });
6824
6852
  } catch (error) {
6825
- throw inputFailure?.error === error ? error : startError(command, error, fileError);
6853
+ throw callerFailure?.error === error ? error : startError(command, error, fileError);
6826
6854
  }
6827
6855
  if (options.check === true && result.exitCode !== 0) throw failedError(command, result);
6828
6856
  return result;
@@ -9397,8 +9425,7 @@ function portsBaseOf(scope, signal) {
9397
9425
  spawn: contextSpawn(options.spawn ?? realSpawn, {
9398
9426
  cwd,
9399
9427
  env,
9400
- signal,
9401
- progress
9428
+ signal
9402
9429
  }, fileError)
9403
9430
  };
9404
9431
  }
@@ -9732,14 +9759,14 @@ async function runProcess(cli) {
9732
9759
  }
9733
9760
  //#endregion
9734
9761
  //#region package.json
9735
- var version$1 = "0.12.0";
9762
+ var version$1 = "0.13.0";
9736
9763
  var description = "Creates a new Agent CLI repository wired to @duyquangnvx/agent-cli.";
9737
9764
  //#endregion
9738
9765
  //#region src/build.ts
9739
9766
  const build = {
9740
- "sha": "cc95e77",
9767
+ "sha": "1c3a29e",
9741
9768
  "dirty": false,
9742
- "builtAt": "2026-10-23T01:20:23.000Z"
9769
+ "builtAt": "2026-10-23T05:43:49.000Z"
9743
9770
  };
9744
9771
  //#endregion
9745
9772
  //#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.0",
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.0",
23
23
  "tsdown": "0.23.0",
24
24
  "zod": "4.6.7"
25
25
  },