@duyquangnvx/create-agent-cli 0.15.1 → 0.16.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.16.0 (2026-10-27)
8
+
9
+ ### Changed
10
+
11
+ - **Breaking:** a Packaged skill's `AGENTS.md` block is the text the CLI declares as `skill: { packaged, agents }`, written verbatim between its markers; the Runtime no longer composes a sentence from `description` and the run-as. Without `agents`, `skill install` writes no block and names no `CLAUDE.md` hand edit, its `--json` `agentsMd` is `null`, and `doctor` has no `agents` row. A CLI relying on the old block declares `agents` to keep one, and the Scaffolder's `--dependency` template declares none.
12
+
7
13
  ## v0.15.1 (2026-10-27)
8
14
 
9
15
  ### Fixed
package/dist/bin.js CHANGED
@@ -7390,7 +7390,6 @@ function dependencyInstall(cli, install) {
7390
7390
  runAs,
7391
7391
  builtIns: () => ({}),
7392
7392
  exitClasses: [],
7393
- agentsCaveat: `and only from a package that has \`${install.package}\` in its dependencies; from anywhere else npx reports the package missing`,
7394
7393
  check: (launch) => checkOf$1(cli, install, runAs, launch)
7395
7394
  };
7396
7395
  }
@@ -7492,12 +7491,6 @@ function hubSkill(cli, source) {
7492
7491
  }
7493
7492
  //#endregion
7494
7493
  //#region ../agent-cli/dist/built-ins/agents-md.js
7495
- /** One paragraph telling every session that the CLI exists, how to run it and which skill to load. */
7496
- function agentsBlock(cli, { runAs, agentsCaveat }) {
7497
- const what = cli.description.replace(/\.$/, "");
7498
- const run = `Run it as \`${runAs}\`${agentsCaveat === void 0 ? "" : `, ${agentsCaveat}`}`;
7499
- return `\`${cli.name}\`: ${what}. ${run}. Load the \`${cli.name}\` skill before using it.`;
7500
- }
7501
7494
  function markersOf(name) {
7502
7495
  return {
7503
7496
  begin: `<!-- BEGIN:${name} -->`,
@@ -7505,33 +7498,32 @@ function markersOf(name) {
7505
7498
  };
7506
7499
  }
7507
7500
  /** `text` with the CLI's block between its markers, appended when they are missing; nothing else changes. */
7508
- function withBlock(cli, install, text) {
7509
- const { begin, end } = markersOf(cli.name);
7510
- const whole = `${begin}\n${agentsBlock(cli, install)}\n${end}`;
7501
+ function withBlock({ name, text: block }, text) {
7502
+ const { begin, end } = markersOf(name);
7503
+ const whole = `${begin}\n${block}\n${end}`;
7511
7504
  const start = text.indexOf(begin);
7512
7505
  const stop = start === -1 ? -1 : text.indexOf(end, start);
7513
7506
  if (stop !== -1) return `${text.slice(0, start)}${whole}${text.slice(stop + end.length)}`;
7514
7507
  if (text === "") return `${whole}\n`;
7515
7508
  return `${text}${text.endsWith("\n") ? "" : "\n"}\n${whole}\n`;
7516
7509
  }
7517
- async function agentsMdAt(cli, install, root) {
7510
+ async function agentsMdAt(agents, root) {
7518
7511
  const path = join(root, "AGENTS.md");
7519
7512
  const existing = await orMissing(readFile(path, "utf8"));
7520
- const block = agentsBlock(cli, install);
7521
7513
  if (existing === void 0) return {
7522
7514
  path,
7523
- block,
7515
+ agents,
7524
7516
  change: "create"
7525
7517
  };
7526
- if (withBlock(cli, install, existing) === existing) return {
7518
+ if (withBlock(agents, existing) === existing) return {
7527
7519
  path,
7528
- block,
7520
+ agents,
7529
7521
  change: null
7530
7522
  };
7531
7523
  return {
7532
7524
  path,
7533
- block,
7534
- change: existing.includes(markersOf(cli.name).begin) ? "rewrite" : "add"
7525
+ agents,
7526
+ change: existing.includes(markersOf(agents.name).begin) ? "rewrite" : "add"
7535
7527
  };
7536
7528
  }
7537
7529
  async function handEditsAt(root) {
@@ -7540,25 +7532,26 @@ async function handEditsAt(root) {
7540
7532
  if (text === void 0 || text.split(/\r?\n/).some((line) => line.trim() === "@AGENTS.md")) return [];
7541
7533
  return [`add a line \`@AGENTS.md\` to ${claudeMd}, so Claude Code reads AGENTS.md`];
7542
7534
  }
7543
- function agentsRow(cli, install) {
7535
+ function agentsRow(agents, install) {
7536
+ const { name } = agents;
7544
7537
  return {
7545
7538
  name: "agents",
7546
7539
  advisory: true,
7547
7540
  run: async (ctx) => {
7548
7541
  const root = await projectRootOf(ctx.cwd);
7549
- const { path, change } = await agentsMdAt(cli, install, root);
7542
+ const { path, change } = await agentsMdAt(agents, root);
7550
7543
  const fix = `${install.runAs} skill install`;
7551
7544
  if (change === "rewrite") return {
7552
7545
  state: "problem",
7553
- message: `${path} holds a ${cli.name} block other than the one ${fix} writes`,
7546
+ message: `${path} holds a ${name} block other than the one ${fix} writes`,
7554
7547
  fix
7555
7548
  };
7556
7549
  if (change !== null) return {
7557
7550
  state: "problem",
7558
- message: `${path} holds no ${cli.name} block, so sessions in this repo do not know ${cli.name}`,
7551
+ message: `${path} holds no ${name} block, so sessions in this repo do not know ${name}`,
7559
7552
  fix
7560
7553
  };
7561
- const holds = `${path} holds the ${cli.name} block`;
7554
+ const holds = `${path} holds the ${name} block`;
7562
7555
  const [edit] = await handEditsAt(root);
7563
7556
  return edit === void 0 ? {
7564
7557
  state: "ok",
@@ -7936,14 +7929,14 @@ const installSchema = object({
7936
7929
  agentsMd: object({
7937
7930
  path: string(),
7938
7931
  changed: boolean()
7939
- }),
7932
+ }).nullable(),
7940
7933
  handEdits: array(string())
7941
7934
  });
7942
7935
  async function sameContent(left, right) {
7943
7936
  const [a, b] = await Promise.all([readFile(left), readFile(right)]);
7944
7937
  return a.equals(b);
7945
7938
  }
7946
- async function planOf(cli, folder, install, cwd, packageRoot) {
7939
+ async function planOf(cli, folder, agents, cwd, packageRoot) {
7947
7940
  const source = join(packageRoot, folder);
7948
7941
  const { root, copy } = await skillCopyOf(cli, cwd);
7949
7942
  const [shipped, present] = await Promise.all([filesIn(source), filesIn(copy)]);
@@ -7955,8 +7948,8 @@ async function planOf(cli, folder, install, cwd, packageRoot) {
7955
7948
  replace: shipped.filter((_file, index) => differs[index]),
7956
7949
  remove: present.filter((file) => !shipped.includes(file)),
7957
7950
  sameVersion: (await skillVersionsOf(source, copy)).same,
7958
- agentsMd: await agentsMdAt(cli, install, root),
7959
- handEdits: await handEditsAt(root)
7951
+ agentsMd: agents === void 0 ? null : await agentsMdAt(agents, root),
7952
+ handEdits: agents === void 0 ? [] : await handEditsAt(root)
7960
7953
  };
7961
7954
  }
7962
7955
  const BLOCK_VERBS = {
@@ -7970,11 +7963,11 @@ function renderPlan(cli, plan) {
7970
7963
  ...plan.replace.map((file) => ` replace ${file}`),
7971
7964
  ...plan.remove.map((file) => ` remove ${file}`)
7972
7965
  ];
7973
- const { path, block, change } = plan.agentsMd;
7966
+ const { agentsMd } = plan;
7974
7967
  return [
7975
7968
  files.length === 0 ? `the ${cli.name} skill at ${plan.copy} already matches the package` : `would copy the ${cli.name} skill to ${plan.copy}:`,
7976
7969
  ...files,
7977
- change === null ? `${path} already holds the ${cli.name} block` : `would ${BLOCK_VERBS[change]} ${path}:\n${block}`,
7970
+ ...agentsMd === null ? [] : [agentsMd.change === null ? `${agentsMd.path} already holds the ${cli.name} block` : `would ${BLOCK_VERBS[agentsMd.change]} ${agentsMd.path}:\n${agentsMd.agents.text}`],
7978
7971
  ...plan.handEdits.map((edit) => `by hand: ${edit}`)
7979
7972
  ].join("\n");
7980
7973
  }
@@ -7982,7 +7975,7 @@ function renderInstalled(cli, data) {
7982
7975
  const { written, removed, agentsMd } = data;
7983
7976
  return [
7984
7977
  written.length + removed.length === 0 ? `the ${cli.name} skill at ${data.copy} already matches the package` : `copied the ${cli.name} skill to ${data.copy}: wrote ${written.length} files, removed ${removed.length}`,
7985
- agentsMd.changed ? `wrote the ${cli.name} block in ${agentsMd.path}` : `${agentsMd.path} already holds the ${cli.name} block`,
7978
+ ...agentsMd === null ? [] : [agentsMd.changed ? `wrote the ${cli.name} block in ${agentsMd.path}` : `${agentsMd.path} already holds the ${cli.name} block`],
7986
7979
  ...data.handEdits.map((edit) => `by hand: ${edit}`)
7987
7980
  ].join("\n");
7988
7981
  }
@@ -7995,11 +7988,11 @@ function editedRemovals(plan, ctx) {
7995
7988
  });
7996
7989
  }
7997
7990
  /** The built-in `skill install`, for a CLI whose skill ships in its package. */
7998
- function skillInstallCommand(cli, folder, install) {
7991
+ function skillInstallCommand(cli, folder, install, agents) {
7999
7992
  const { runAs } = install;
8000
7993
  return defineCommand$1({
8001
7994
  name: "install",
8002
- description: "copy this CLI's skill into the project and write its AGENTS.md block",
7995
+ description: agents === void 0 ? "copy this CLI's skill into the project" : "copy this CLI's skill into the project and write its AGENTS.md block",
8003
7996
  examples: [{
8004
7997
  command: `${runAs} skill install`,
8005
7998
  note: "install the skill this version ships"
@@ -8010,24 +8003,24 @@ function skillInstallCommand(cli, folder, install) {
8010
8003
  effect: "write",
8011
8004
  output: installSchema,
8012
8005
  force: "replace or remove hand-edited files of a skill copy at the package's version",
8013
- plan: (_input, ctx) => planOf(cli, folder, install, ctx.cwd, ctx.packageRoot),
8006
+ plan: (_input, ctx) => planOf(cli, folder, agents, ctx.cwd, ctx.packageRoot),
8014
8007
  outputs: (plan) => plan.sameVersion ? [...plan.write, ...plan.replace].map((file) => join(plan.copy, file)) : [],
8015
8008
  apply: async (plan, ctx) => {
8016
8009
  if (plan.sameVersion && plan.remove.length > 0 && !ctx.force) throw editedRemovals(plan, ctx);
8017
8010
  for (const file of [...plan.write, ...plan.replace]) await ctx.files.write(join(plan.copy, file), await readFile(join(plan.source, file)));
8018
8011
  for (const file of plan.remove) await ctx.files.remove(join(plan.copy, file));
8019
- const { path, change } = plan.agentsMd;
8020
- if (change !== null) {
8021
- const existing = await orMissing(readFile(path, "utf8")) ?? "";
8022
- await ctx.files.write(path, withBlock(cli, install, existing));
8012
+ const { agentsMd } = plan;
8013
+ if (agentsMd !== null && agentsMd.change !== null) {
8014
+ const existing = await orMissing(readFile(agentsMd.path, "utf8")) ?? "";
8015
+ await ctx.files.write(agentsMd.path, withBlock(agentsMd.agents, existing));
8023
8016
  }
8024
8017
  return {
8025
8018
  copy: plan.copy,
8026
8019
  written: [...plan.write, ...plan.replace].sort(),
8027
8020
  removed: [...plan.remove],
8028
- agentsMd: {
8029
- path,
8030
- changed: change !== null
8021
+ agentsMd: agentsMd === null ? null : {
8022
+ path: agentsMd.path,
8023
+ changed: agentsMd.change !== null
8031
8024
  },
8032
8025
  handEdits: [...plan.handEdits]
8033
8026
  };
@@ -8102,16 +8095,20 @@ async function notice(cli, folder, install, { builtIn, bin }, ctx) {
8102
8095
  if (finding.state !== "problem") return;
8103
8096
  ctx.notice(finding.fix === void 0 ? finding.message : `${finding.message}; run \`${finding.fix}\``);
8104
8097
  }
8105
- /** A skill shipped in the package at `folder`, which `skill install` copies to the project root. */
8106
- function packagedSkill(cli, folder, install) {
8098
+ /** A skill shipped in the package at `packaged`, which `skill install` copies to the project root. */
8099
+ function packagedSkill(cli, { packaged: folder, agents: text }, install) {
8100
+ const agents = text === void 0 ? void 0 : {
8101
+ name: cli.name,
8102
+ text
8103
+ };
8107
8104
  return {
8108
8105
  kind: "packaged",
8109
- builtIns: { skill: { install: skillInstallCommand(cli, folder, install) } },
8106
+ builtIns: { skill: { install: skillInstallCommand(cli, folder, install, agents) } },
8110
8107
  rows: [{
8111
8108
  name: "skill",
8112
8109
  advisory: true,
8113
8110
  run: (ctx) => findingOf(cli, folder, install, ctx)
8114
- }, agentsRow(cli, install)],
8111
+ }, ...agents === void 0 ? [] : [agentsRow(agents, install)]],
8115
8112
  notice: (launch, ctx) => notice(cli, folder, install, launch, ctx),
8116
8113
  findingAt: (_version, ctx) => findingOf(cli, folder, install, ctx)
8117
8114
  };
@@ -8121,7 +8118,7 @@ function packagedSkill(cli, folder, install) {
8121
8118
  /** A Packaged skill, or else a Skill Hub's, also for a CLI that declares no `skill`. */
8122
8119
  function skillOf(cli, install) {
8123
8120
  const { skill } = cli;
8124
- return skill !== void 0 && "packaged" in skill ? packagedSkill(cli, skill.packaged, install) : hubSkill(cli, skill?.source);
8121
+ return skill !== void 0 && "packaged" in skill ? packagedSkill(cli, skill, install) : hubSkill(cli, skill?.source);
8125
8122
  }
8126
8123
  //#endregion
8127
8124
  //#region ../agent-cli/dist/interrupts.js
@@ -8509,7 +8506,6 @@ function globalInstall(cli, install) {
8509
8506
  runAs: runAsOf(cli),
8510
8507
  builtIns: (launch) => ({ update: updateCommand(cli, install, skillOf(cli, adapter), launch) }),
8511
8508
  exitClasses: ["source"],
8512
- agentsCaveat: void 0,
8513
8509
  check: (launch) => checkOf(cli, install, launch)
8514
8510
  };
8515
8511
  return adapter;
@@ -8525,7 +8521,6 @@ function noInstall(cli) {
8525
8521
  runAs: runAsOf(cli),
8526
8522
  builtIns: () => ({}),
8527
8523
  exitClasses: [],
8528
- agentsCaveat: void 0,
8529
8524
  check: () => ({
8530
8525
  install: skipped,
8531
8526
  release: async () => ({ skipped: await skipped() })
@@ -10258,14 +10253,14 @@ async function runProcess(cli) {
10258
10253
  }
10259
10254
  //#endregion
10260
10255
  //#region package.json
10261
- var version$1 = "0.15.1";
10256
+ var version$1 = "0.16.0";
10262
10257
  var description = "Creates a new Agent CLI repository wired to @duyquangnvx/agent-cli.";
10263
10258
  //#endregion
10264
10259
  //#region src/build.ts
10265
10260
  const build = {
10266
- "sha": "da48f36",
10261
+ "sha": "648fa57",
10267
10262
  "dirty": false,
10268
- "builtAt": "2026-10-27T08:31:19.000Z"
10263
+ "builtAt": "2026-10-27T10:21:48.000Z"
10269
10264
  };
10270
10265
  //#endregion
10271
10266
  //#region src/fill.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duyquangnvx/create-agent-cli",
3
- "version": "0.15.1",
3
+ "version": "0.16.0",
4
4
  "description": "Creates a new Agent CLI repository wired to @duyquangnvx/agent-cli.",
5
5
  "type": "module",
6
6
  "engines": {
@@ -20,7 +20,7 @@
20
20
  "access": "public"
21
21
  },
22
22
  "devDependencies": {
23
- "@duyquangnvx/agent-cli": "0.15.1",
23
+ "@duyquangnvx/agent-cli": "0.16.0",
24
24
  "tsdown": "0.23.0",
25
25
  "zod": "4.6.7"
26
26
  },