@duyquangnvx/create-agent-cli 0.9.1 → 0.10.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 CHANGED
@@ -4,6 +4,22 @@ What changed in each release of `@duyquangnvx/agent-cli` (the Runtime) and `@duy
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## v0.10.1 (2026-10-22)
8
+
9
+ ### Changed
10
+
11
+ - A scaffolded CLI's tests create their temp folders under one root that `test/global-setup.ts` removes after the run, so they leave nothing in `$TMPDIR`.
12
+
13
+ ## v0.10.0 (2026-10-21)
14
+
15
+ ### Changed
16
+
17
+ - `ctx.commandLine` and every hint that names a command to run again end in ` < <name file>` when an `orStdin` arg was given `-`, so the rerun sends the text again; the hint of a stdin that never ends still names the line as typed.
18
+
19
+ ### Fixed
20
+
21
+ - `--dry-run` text no longer prints an empty `outputs:` line when `outputs` returns no files; `--json` still gives `outputs: []`.
22
+
7
23
  ## v0.9.1 (2026-10-20)
8
24
 
9
25
  ### Fixed
package/dist/bin.js CHANGED
@@ -6141,8 +6141,9 @@ const SHELL_SAFE = /^[\w@%+=:,./-]+$/;
6141
6141
  function quoted$1(token) {
6142
6142
  return SHELL_SAFE.test(token) ? token : `'${token.replaceAll("'", `'\\''`)}'`;
6143
6143
  }
6144
- function pasteable(cliName, tokens) {
6145
- return [cliName, ...tokens].map(quoted$1).join(" ");
6144
+ function pasteable(cliName, tokens, stdinArg) {
6145
+ const line = [cliName, ...tokens].map(quoted$1).join(" ");
6146
+ return stdinArg === void 0 ? line : `${line} < <${stdinArg} file>`;
6146
6147
  }
6147
6148
  function split(argv) {
6148
6149
  const end = argv.indexOf("--");
@@ -6169,16 +6170,16 @@ function without(flag, takes, tokens) {
6169
6170
  }
6170
6171
  /**
6171
6172
  * The caller's command line as typed, ready to paste, with each flag in `remove` dropped along with
6172
- * its value and the words in `add` placed before any `--`.
6173
+ * its value, the words in `add` placed before any `--`, and the stdin arg's file redirected in.
6173
6174
  */
6174
- function commandLineOf({ cliName, argv, flags }, { add = [], remove = [] } = {}) {
6175
+ function commandLineOf({ cliName, argv, flags, stdinArg }, { add = [], remove = [] } = {}) {
6175
6176
  const { options, operands } = split(argv);
6176
6177
  const takes = new Map(flags.map((known) => [known.flag, known.takes]));
6177
6178
  return pasteable(cliName, [
6178
6179
  ...remove.reduce((tokens, flag) => without(flag, takes.get(flag) ?? "nothing", tokens), options),
6179
6180
  ...add,
6180
6181
  ...operands
6181
- ]);
6182
+ ], stdinArg);
6182
6183
  }
6183
6184
  function renamed(token, renames) {
6184
6185
  const [flag = token, ...value] = token.split("=");
@@ -6187,9 +6188,9 @@ function renamed(token, renames) {
6187
6188
  return value.length === 0 ? name : `${name}=${value.join("=")}`;
6188
6189
  }
6189
6190
  /** The caller's command line, ready to paste, with each flag in `renames` typed as its new name. */
6190
- function commandLineRenaming({ cliName, argv }, renames) {
6191
+ function commandLineRenaming({ cliName, argv, stdinArg }, renames) {
6191
6192
  const { options, operands } = split(argv);
6192
- return pasteable(cliName, [...options.map((token) => renamed(token, renames)), ...operands]);
6193
+ return pasteable(cliName, [...options.map((token) => renamed(token, renames)), ...operands], stdinArg);
6193
6194
  }
6194
6195
  //#endregion
6195
6196
  //#region ../agent-cli/dist/usage.js
@@ -8700,7 +8701,7 @@ function dryRunOutcome(command, plan) {
8700
8701
  },
8701
8702
  render: (style) => [
8702
8703
  renderPlan(style),
8703
- ...outputs === void 0 ? [] : ["outputs:", ...outputs.map((path) => ` ${path}`)],
8704
+ ...outputs === void 0 || outputs.length === 0 ? [] : ["outputs:", ...outputs.map((path) => ` ${path}`)],
8704
8705
  ...cost === void 0 ? [] : [`cost: ${cost}`]
8705
8706
  ].join("\n")
8706
8707
  };
@@ -8842,11 +8843,17 @@ function invalidInput(commandLine, invocation, unknown, otherLines) {
8842
8843
  hint: correctable ? `did you mean \`${commandLineRenaming(invocation, renames)}\`?` : `run \`${commandLine} --help\` to see the expected input`
8843
8844
  });
8844
8845
  }
8845
- async function stdinTextOf(spec, operands, read) {
8846
+ function stdinFieldOf(spec, operands) {
8846
8847
  const index = spec.args.findIndex((field) => field.stdin);
8847
- const field = spec.args[index];
8848
- if (field === void 0 || operands[index]?.value !== "-") return void 0;
8849
- return {
8848
+ return operands[index]?.value === "-" ? spec.args[index] : void 0;
8849
+ }
8850
+ /** The name of the routed Command's arg given `-`, which takes its text from stdin. */
8851
+ function stdinArgOf({ spec, words }) {
8852
+ return stdinFieldOf(spec, tokenize(words, knownFlags(spec)).operands)?.name;
8853
+ }
8854
+ async function stdinTextOf(spec, operands, read) {
8855
+ const field = stdinFieldOf(spec, operands);
8856
+ return field === void 0 ? void 0 : {
8850
8857
  field,
8851
8858
  text: await read(field)
8852
8859
  };
@@ -9111,16 +9118,17 @@ async function runCommand(cli, routed, options, write, baseFormat) {
9111
9118
  const platform = options.platform ?? process.platform;
9112
9119
  const ports = portsOf(cli, options.ports);
9113
9120
  const packageRoot = packageRootOf(options.bin, cwd);
9114
- const fileError = fileErrorOf({
9115
- callerLine: commandLineOf(baseFormat.invocation),
9116
- env,
9117
- platform
9118
- });
9119
9121
  const progress = (message) => write.stderr(progressLine(message, routed.json));
9120
9122
  const invocation = {
9121
9123
  ...baseFormat.invocation,
9122
- flags: knownFlags(routed.spec)
9124
+ flags: knownFlags(routed.spec),
9125
+ stdinArg: stdinArgOf(routed)
9123
9126
  };
9127
+ const fileError = fileErrorOf({
9128
+ callerLine: commandLineOf(invocation),
9129
+ env,
9130
+ platform
9131
+ });
9124
9132
  const format = {
9125
9133
  ...baseFormat,
9126
9134
  bugs: () => manifestAt(packageRoot).bugs,
@@ -9128,6 +9136,10 @@ async function runCommand(cli, routed, options, write, baseFormat) {
9128
9136
  invocation
9129
9137
  };
9130
9138
  const typedLine = (change) => commandLineOf(invocation, change);
9139
+ const callerLine = commandLineOf({
9140
+ ...invocation,
9141
+ stdinArg: void 0
9142
+ });
9131
9143
  let resumeHint;
9132
9144
  const control = new RunControl({
9133
9145
  commandLine,
@@ -9136,7 +9148,7 @@ async function runCommand(cli, routed, options, write, baseFormat) {
9136
9148
  progress,
9137
9149
  runDeadline: command.deadline === void 0 ? void 0 : {
9138
9150
  ms: command.deadline.ms,
9139
- hint: () => resumeHint ?? stdinNeverEndedHint(typedLine())
9151
+ hint: () => resumeHint ?? stdinNeverEndedHint(callerLine)
9140
9152
  }
9141
9153
  });
9142
9154
  const failed = (error, finishSideTask) => {
@@ -9153,7 +9165,7 @@ async function runCommand(cli, routed, options, write, baseFormat) {
9153
9165
  if (isTerminal(stdin)) progress(readingLine(field.name, platform));
9154
9166
  return readStdin(stdin, control.signal, {
9155
9167
  clock,
9156
- stalled: () => stdinStalled(typedLine())
9168
+ stalled: () => stdinStalled(callerLine)
9157
9169
  });
9158
9170
  });
9159
9171
  } catch (error) {
@@ -9409,14 +9421,14 @@ async function runProcess(cli) {
9409
9421
  }
9410
9422
  //#endregion
9411
9423
  //#region package.json
9412
- var version$1 = "0.9.1";
9424
+ var version$1 = "0.10.1";
9413
9425
  var description = "Creates a new Agent CLI repository wired to @duyquangnvx/agent-cli.";
9414
9426
  //#endregion
9415
9427
  //#region src/build.ts
9416
9428
  const build = {
9417
- "sha": "3014a0a",
9429
+ "sha": "0e1aa22",
9418
9430
  "dirty": false,
9419
- "builtAt": "2026-10-20T10:05:03.000Z"
9431
+ "builtAt": "2026-10-22T01:43:18.000Z"
9420
9432
  };
9421
9433
  //#endregion
9422
9434
  //#region src/steps.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duyquangnvx/create-agent-cli",
3
- "version": "0.9.1",
3
+ "version": "0.10.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.9.1",
22
+ "@duyquangnvx/agent-cli": "0.10.1",
23
23
  "tsdown": "0.23.0",
24
24
  "zod": "4.6.7"
25
25
  },
@@ -0,0 +1,13 @@
1
+ import { mkdtempSync, rmSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+
5
+ // Workers and the processes they spawn read the temp dir from these variables, so every
6
+ // temp folder a test makes lands under one root that the teardown removes, even after a failure.
7
+ export default function setup(): () => void {
8
+ const root = mkdtempSync(join(tmpdir(), "{{binName}}-test-"));
9
+ process.env.TMPDIR = root;
10
+ process.env.TEMP = root;
11
+ process.env.TMP = root;
12
+ return () => rmSync(root, { recursive: true, force: true, maxRetries: 3 });
13
+ }
@@ -2,6 +2,7 @@ import { defineConfig } from "vitest/config";
2
2
 
3
3
  export default defineConfig({
4
4
  test: {
5
+ globalSetup: ["test/global-setup.ts"],
5
6
  include: ["test/**/*.test.ts"],
6
7
  },
7
8
  });