argsbarg 3.3.11 → 3.3.12

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
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [3.3.12] - 2026-06-21
11
+
12
+ ### Changed
13
+
14
+ - **Agent skills** — `SKILL.md` embeds the `docs api` command reference (body only) instead of a separate `## Commands` bullet catalog.
15
+
10
16
  ## [3.3.11] - 2026-06-21
11
17
 
12
18
  ### Added
@@ -317,7 +323,8 @@ const cli = { ... } satisfies CliProgram; // or : CliProgram
317
323
  - Migrate schemas: rename every `children` property to **`commands`**; move positional definitions to **`CliPositional`** objects on `positionals` and strip `positional` / `argMin` / `argMax` from flag definitions under `options` (flags only carry `name`, `description`, `kind`, and optional `shortName`).
318
324
  - Imports: use `CliPositional` where needed; replace `CliOptionDef` with `CliOption` or `CliPositional` as appropriate.
319
325
 
320
- [Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v3.3.11...HEAD
326
+ [Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v3.3.12...HEAD
327
+ [3.3.12]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.3.12
321
328
  [3.3.11]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.3.11
322
329
  [3.3.10]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.3.10
323
330
  [3.3.9]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.3.9
package/docs/ai-skills.md CHANGED
@@ -31,7 +31,7 @@ For library use, call `cliSkillInstall(root, "cursor" | "claude", { global: true
31
31
 
32
32
  ## Generated content
33
33
 
34
- - **`SKILL.md`** — YAML frontmatter, when-to-use guidance, shell command catalog, pitfalls
34
+ - **`SKILL.md`** — YAML frontmatter, when-to-use guidance, the same command reference as `docs api` (without the API doc header), pitfalls
35
35
  - **`reference.md`** — full `docs schema` JSON export
36
36
 
37
37
  Installed files include an HTML comment hint (`Generated by myapp install --skill; do not edit.`) after SKILL.md frontmatter and at the top of `reference.md`.
@@ -43,10 +43,10 @@ Skills describe **shell invocation only** — no MCP setup, `mcp.json`, or `tool
43
43
  | Mechanism | Role |
44
44
  | --- | --- |
45
45
  | **`myapp mcp`** (requires `mcpServer`) | Runtime tool execution over MCP |
46
- | **`myapp install --skill`** | Static shell command catalog for agents |
46
+ | **`myapp install --skill`** | Static shell command reference for agents (same body as `docs api`) |
47
47
  | **`myapp docs`** (requires `docs`) | Bundled markdown on stdout (`docs mcp` when MCP enabled) |
48
48
 
49
- Command catalog lines reuse MCP tool descriptions. See [cli-program.md](cli-program.md).
49
+ Command reference in skills reuses the `docs api` command tree. See [cli-program.md](cli-program.md).
50
50
 
51
51
  See also:
52
52
 
@@ -84,7 +84,7 @@ All `docs` subcommands are hidden from MCP `tools/list` (`mcpTool: { enabled: fa
84
84
 
85
85
  | Channel | Role |
86
86
  | --- | --- |
87
- | `install --skill` | Writes shell command catalog + `reference.md` to disk |
87
+ | `install --skill` | Writes `SKILL.md` (API command reference) + `reference.md` to disk |
88
88
  | `docs skill` | Print generated `SKILL.md` to stdout |
89
89
  | `docs api` | Print command tree markdown to stdout |
90
90
  | `docs schema` | Print command tree JSON to stdout |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "argsbarg",
3
- "version": "3.3.11",
3
+ "version": "3.3.12",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "bun": ">=1.3"
@@ -1,7 +1,7 @@
1
1
  import { expect, test } from "bun:test";
2
2
  import type { CliProgram } from "../types.ts";
3
3
  import { CliOptionKind } from "../types.ts";
4
- import { generateApiGuide } from "./api-guide.ts";
4
+ import { generateApiGuide, generateApiGuideBody } from "./api-guide.ts";
5
5
  import { cliSchemaExport } from "../schema.ts";
6
6
 
7
7
  const nestedFixture: CliProgram = {
@@ -45,6 +45,14 @@ const nestedFixture: CliProgram = {
45
45
  ],
46
46
  };
47
47
 
48
+ test("generateApiGuideBody matches command section of full API guide", () => {
49
+ const body = generateApiGuideBody(nestedFixture);
50
+ const full = generateApiGuide(nestedFixture);
51
+ expect(full).toContain(body.trimEnd());
52
+ expect(body).toContain("## `nested.ts stat`");
53
+ expect(body).not.toContain("CLI API reference");
54
+ });
55
+
48
56
  test("generateApiGuide covers the same command keys as cliSchemaExport", () => {
49
57
  const md = generateApiGuide(nestedFixture);
50
58
  const schema = cliSchemaExport(nestedFixture);
@@ -117,6 +117,14 @@ function renderCommandNode(
117
117
  }
118
118
  }
119
119
 
120
+ /** Command-tree markdown shared by `docs api` and generated agent skills (no API doc header). */
121
+ export function generateApiGuideBody(program: CliProgram): string {
122
+ const schema = cliSchemaExport(program);
123
+ const lines: string[] = [];
124
+ renderCommandNode(program.key, [], schema, lines);
125
+ return `${lines.join("\n").trimEnd()}\n`;
126
+ }
127
+
120
128
  /** Generates markdown API reference from the same export as `docs schema`. */
121
129
  export function generateApiGuide(program: CliProgram): string {
122
130
  const schema = cliSchemaExport(program);
@@ -133,6 +141,6 @@ export function generateApiGuide(program: CliProgram): string {
133
141
  lines.push(formatNotesBlockquote(schema.notes, program.key), "");
134
142
  }
135
143
 
136
- renderCommandNode(program.key, [], schema, lines);
144
+ lines.push(generateApiGuideBody(program).trimEnd(), "");
137
145
  return `${lines.join("\n").trimEnd()}\n`;
138
146
  }
@@ -152,7 +152,8 @@ test("docs skill prints Cursor SKILL.md", async () => {
152
152
  expect(result.exitCode).toBe(0);
153
153
  expect(result.stdout).toContain("---");
154
154
  expect(result.stdout).toContain("name: myapp");
155
- expect(result.stdout).toContain("## Commands");
155
+ expect(result.stdout).toContain("#### Options");
156
+ expect(result.stdout).not.toContain("## Commands");
156
157
  expect(result.stdout).not.toContain("mcp.json");
157
158
  });
158
159
 
package/src/index.test.ts CHANGED
@@ -1808,12 +1808,15 @@ test("install config on non-root node is rejected", () => {
1808
1808
  expect(() => cliValidateProgram(root)).toThrow(/install is only supported on the program root/);
1809
1809
  });
1810
1810
 
1811
- test("generateSkillBundle includes frontmatter and command catalog", () => {
1811
+ test("generateSkillBundle includes frontmatter and API command reference", () => {
1812
1812
  const bundle = generateSkillBundle(nestedMcpFixture, "cursor");
1813
1813
  expect(bundle.dirName).toBe("nested_ts");
1814
1814
  expect(bundle.skillMd).toMatch(/^---\nname: nested_ts\n/);
1815
- expect(bundle.skillMd).toContain("stat owner lookup");
1815
+ expect(bundle.skillMd).toContain("`nested.ts stat owner lookup`");
1816
+ expect(bundle.skillMd).toContain("#### Options");
1816
1817
  expect(bundle.skillMd).toContain("Invoke via shell:");
1818
+ expect(bundle.skillMd).not.toContain("## Commands");
1819
+ expect(bundle.skillMd).not.toContain("CLI API reference");
1817
1820
  expect(bundle.skillMd).not.toContain("mcp.json");
1818
1821
  expect(bundle.skillMd).not.toContain("Prefer MCP");
1819
1822
  expect(bundle.skillMd).not.toContain("tools/call");
@@ -1833,7 +1836,7 @@ test("cliSkillInstall writes project Cursor skill files", () => {
1833
1836
  const skillDir = join(cwd, ".cursor", "skills", "nested_ts");
1834
1837
  expect(existsSync(join(skillDir, "SKILL.md"))).toBe(true);
1835
1838
  expect(existsSync(join(skillDir, "reference.md"))).toBe(true);
1836
- expect(readFileSync(join(skillDir, "SKILL.md"), "utf8")).toContain("stat owner lookup");
1839
+ expect(readFileSync(join(skillDir, "SKILL.md"), "utf8")).toContain("`nested.ts stat owner lookup`");
1837
1840
  const skillText = readFileSync(join(skillDir, "SKILL.md"), "utf8");
1838
1841
  expect(skillText.startsWith("---\n")).toBe(true);
1839
1842
  const hint = "<!-- Generated by nested.ts install --skill; do not edit. -->";
@@ -2,10 +2,10 @@
2
2
  This module generates Agent Skills content (SKILL.md + reference.md) from a CLI schema.
3
3
  */
4
4
 
5
- import { collectOptionDefs } from "../parse.ts";
5
+ import { generateApiGuideBody } from "../docs/api-guide.ts";
6
6
  import { cliSchemaJson } from "../schema.ts";
7
7
  import { collectMcpTools, sanitizeToolSegment } from "../mcp/tools.ts";
8
- import { CliProgram, CliOptionKind } from "../types.ts";
8
+ import { CliProgram } from "../types.ts";
9
9
 
10
10
  export type SkillTarget = "cursor" | "claude";
11
11
 
@@ -31,31 +31,10 @@ function skillDescription(root: CliProgram): string {
31
31
  return truncate(desc, 1024);
32
32
  }
33
33
 
34
- /** Formats one command line for the catalog section. */
35
- function formatCommandEntry(root: CliProgram, tool: ReturnType<typeof collectMcpTools>[number]): string {
36
- const cliPath = tool.path.length > 0 ? `${root.key} ${tool.path.join(" ")}` : root.key;
37
- let line = `- **\`${cliPath}\`** — ${tool.description}`;
38
- const opts = collectOptionDefs(root, tool.path);
39
- const flags = opts.filter((o) => o.kind === CliOptionKind.Presence).map((o) => `--${o.name}`);
40
- if (flags.length > 0) {
41
- line += ` (flags: ${flags.join(", ")})`;
42
- }
43
- const enums = opts.filter((o) => o.kind === CliOptionKind.Enum && o.choices?.length);
44
- for (const e of enums) {
45
- line += ` (\`--${e.name}\`: ${e.choices!.join(" | ")})`;
46
- }
47
- const varargs = (tool.leaf.positionals ?? []).filter((p) => (p.argMax ?? 1) === 0);
48
- if (varargs.length > 0) {
49
- line += ` (varargs: ${varargs.map((p) => p.name).join(", ")})`;
50
- }
51
- return line;
52
- }
53
-
54
34
  /** Builds SKILL.md body for the given target. */
55
35
  function buildSkillMd(root: CliProgram, target: SkillTarget, dirName: string): string {
56
36
  const name = sanitizeToolSegment(root.key);
57
37
  const description = skillDescription(root);
58
- const tools = collectMcpTools(root);
59
38
 
60
39
  const lines: string[] = [
61
40
  "---",
@@ -75,20 +54,12 @@ function buildSkillMd(root: CliProgram, target: SkillTarget, dirName: string): s
75
54
  "",
76
55
  "Invoke via shell:",
77
56
  "",
78
- ];
79
-
80
- lines.push("```bash", `${root.key} <subcommand> [options] [args]`, "```", "", "## Commands", "");
81
-
82
- if (tools.length === 0) {
83
- lines.push("(No leaf commands in schema.)", "");
84
- } else {
85
- for (const tool of tools) {
86
- lines.push(formatCommandEntry(root, tool));
87
- }
88
- lines.push("");
89
- }
90
-
91
- lines.push(
57
+ "```bash",
58
+ `${root.key} <subcommand> [options] [args]`,
59
+ "```",
60
+ "",
61
+ generateApiGuideBody(root).trimEnd(),
62
+ "",
92
63
  "## Pitfalls",
93
64
  "",
94
65
  "- Use `--` before tokens that look like flags when they are positional arguments.",
@@ -98,7 +69,7 @@ function buildSkillMd(root: CliProgram, target: SkillTarget, dirName: string): s
98
69
  "",
99
70
  "See `reference.md` in this skill directory for the full `docs schema` JSON export.",
100
71
  "",
101
- );
72
+ ];
102
73
 
103
74
  if (target === "cursor") {
104
75
  lines.push(