argsbarg 7.0.6 → 7.0.7

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 (41) hide show
  1. package/CHANGELOG.md +13 -1
  2. package/README.md +3 -3
  3. package/docs/README.md +1 -1
  4. package/docs/ai-skills.md +14 -62
  5. package/docs/bundled-docs.md +9 -13
  6. package/docs/cli-program.md +10 -11
  7. package/docs/configure.md +9 -11
  8. package/docs/output-schema.md +0 -1
  9. package/examples/full-example/AGENTS.md +3 -3
  10. package/examples/full-example/docs/README.md +1 -1
  11. package/examples/full-example/justfile +0 -1
  12. package/examples/full-example/skills/full-example/SKILL.md +0 -2
  13. package/examples/full-example/src/program.ts +0 -1
  14. package/examples/full-example-json/AGENTS.md +3 -3
  15. package/examples/full-example-json/docs/README.md +1 -1
  16. package/examples/full-example-json/justfile +0 -1
  17. package/examples/full-example-json/skills/full-example-json/SKILL.md +0 -2
  18. package/examples/full-example-json/src/program.ts +0 -1
  19. package/index.d.ts +5 -3
  20. package/package.json +1 -1
  21. package/src/builtins/builtins.test.ts +1 -22
  22. package/src/builtins/configure-copy.ts +4 -11
  23. package/src/builtins/presentation.ts +2 -5
  24. package/src/configure/artifacts/status.test.ts +5 -5
  25. package/src/configure/artifacts/target-effective.ts +1 -2
  26. package/src/configure/artifacts/target-skill.ts +9 -15
  27. package/src/configure/artifacts/targets/skill.ts +8 -1
  28. package/src/configure/artifacts/targets.test.ts +5 -5
  29. package/src/configure/configure.test.ts +4 -4
  30. package/src/core/parse.test.ts +1 -112
  31. package/src/core/types.ts +5 -3
  32. package/src/core/validate.ts +4 -2
  33. package/src/docs/builtin.ts +5 -3
  34. package/src/docs/cli-guide.ts +3 -3
  35. package/src/docs/docs.test.ts +3 -47
  36. package/src/docs/resolve.ts +5 -5
  37. package/src/docs/save.ts +9 -20
  38. package/src/help.test.ts +6 -7
  39. package/src/skill/generate.ts +30 -156
  40. package/src/skill/hint.ts +2 -15
  41. package/src/skill/install.ts +3 -35
package/src/help.test.ts CHANGED
@@ -64,7 +64,7 @@ describe("cliResolveNotes", () => {
64
64
  });
65
65
 
66
66
  describe("cliHelpRender", () => {
67
- test("docs help lists schema, cli, and skill subcommands", () => {
67
+ test("docs help lists schema and cli subcommands", () => {
68
68
  const root = testProgram({
69
69
  key: "app",
70
70
  version: "1.0.0",
@@ -85,8 +85,7 @@ describe("cliHelpRender", () => {
85
85
  expect(help).toContain("Print the full CLI command tree as JSON.");
86
86
  expect(help).toContain("cli");
87
87
  expect(help).toContain("markdown");
88
- expect(help).toContain("skill");
89
- expect(help).toContain("reference agent SKILL");
88
+ expect(help).not.toContain("skill");
90
89
  });
91
90
 
92
91
  test("root help omits legacy --schema flag", () => {
@@ -106,7 +105,7 @@ describe("cliHelpRender", () => {
106
105
  expect(help).not.toContain("--schema");
107
106
  });
108
107
 
109
- test("root help shows agent docs hint when docs enabled", () => {
108
+ test("root help omits agent docs hint when docs enabled", () => {
110
109
  const root = testProgram({
111
110
  key: "myapp",
112
111
  version: "1.0.0",
@@ -117,7 +116,7 @@ describe("cliHelpRender", () => {
117
116
  commands: [{ key: "run", description: "Run.", handler: () => {} }],
118
117
  });
119
118
  const help = cliHelpRender(cliPresentationRoot(root), [], false);
120
- expect(help).toContain("For AI agents: `myapp docs skill`.");
119
+ expect(help).not.toContain("docs skill");
121
120
  expect(help).not.toContain("install --skill");
122
121
  });
123
122
 
@@ -134,7 +133,7 @@ describe("cliHelpRender", () => {
134
133
  expect(help).not.toContain("docs skill");
135
134
  });
136
135
 
137
- test("root help includes program notes and agent hint", () => {
136
+ test("root help includes program notes", () => {
138
137
  const root = testProgram({
139
138
  key: "myapp",
140
139
  version: "1.0.0",
@@ -147,6 +146,6 @@ describe("cliHelpRender", () => {
147
146
  });
148
147
  const help = cliHelpRender(cliPresentationRoot(root), [], false);
149
148
  expect(help).toContain("See `myapp docs readme` for the user guide.");
150
- expect(help).toContain("myapp docs skill");
149
+ expect(help).not.toContain("docs skill");
151
150
  });
152
151
  });
@@ -1,28 +1,16 @@
1
1
  /*
2
- This module generates Agent Skills content (SKILL.md) from a CLI schema.
3
- It creates an intent-based router that directs agents to specific subcommands
4
- and guides them to use `--help` for option and flag discovery.
2
+ This module generates the MCP routing skill (SKILL.md) for Claude Code plugin zips.
5
3
  */
6
4
 
7
5
  import { defaultConfigEntryTitle } from "../config/entry.ts";
8
- import { CliOptionKind, type CliProgram } from "../core/types.ts";
6
+ import type { CliProgram } from "../core/types.ts";
9
7
  import {
10
8
  collectMcpTools,
11
9
  leafWireOptions,
12
- type McpToolDef,
13
10
  mcpServerId,
14
11
  resolveMcpSchemaUri,
15
12
  sanitizeToolSegment,
16
13
  } from "../mcp/tools.ts";
17
- import { skillDirName } from "./naming.ts";
18
-
19
- /** Agent skill bundle containing the target directory name and SKILL.md router content. */
20
- export interface SkillBundle {
21
- /** Target directory name under `~/.agents/skills/`. */
22
- dirName: string;
23
- /** Generated SKILL.md router content. */
24
- skillMd: string;
25
- }
26
14
 
27
15
  /** MCP routing skill for Claude Code plugin zips (SKILL.md only). */
28
16
  export interface PluginSkillBundle {
@@ -48,168 +36,63 @@ function pluginSkillDescription(root: CliProgram): string {
48
36
  return truncate(desc, 1024);
49
37
  }
50
38
 
51
- /** Builds third-person skill description for YAML frontmatter. */
52
- function skillDescription(root: CliProgram): string {
53
- const tools = collectMcpTools(root);
54
- const paths = tools.map((t) => (t.path.length > 0 ? t.path.join(" ") : root.key));
55
- const sample = paths.slice(0, 5).join(", ");
56
- const more = paths.length > 5 ? `, and ${paths.length - 5} more` : "";
57
- const desc = `Operates the ${root.key} CLI (${sample}${more}). Use when the user mentions ${root.key}${paths.length > 0 ? `, ${paths.slice(0, 3).join(", ")}` : ""}, or related tasks.`;
58
- return truncate(desc, 1024);
59
- }
60
-
61
- /** CLI path with required single-slot positionals for the compact catalog. */
62
- function commandCatalogPath(root: CliProgram, tool: McpToolDef): string {
63
- const base = tool.path.length > 0 ? `${root.key} ${tool.path.join(" ")}` : root.key;
64
- const slots = (tool.leaf.positionals ?? [])
65
- .filter((p) => (p.argMin ?? 1) > 0 && (p.argMax ?? 1) === 1)
66
- .map((p) => `<${p.name}>`);
67
- if (slots.length === 0) {
68
- return base;
69
- }
70
- return `${base} ${slots.join(" ")}`;
71
- }
72
-
73
- /** Formats one command line for the SKILL.md router. */
74
- function formatCommandEntry(root: CliProgram, tool: McpToolDef): string {
75
- const cliPath = commandCatalogPath(root, tool);
76
- let line = `- **\`${cliPath}\`** — ${tool.leaf.description}`;
77
- const opts = leafWireOptions(tool.leaf);
78
- const flags = opts.filter((o) => o.kind === CliOptionKind.Presence).map((o) => `--${o.name}`);
79
- if (flags.length > 0) {
80
- line += ` (flags: ${flags.join(", ")})`;
81
- }
82
- const enums = opts.filter((o) => o.kind === CliOptionKind.Enum && o.choices?.length);
83
- for (const e of enums) {
84
- line += ` (\`--${e.name}\`: ${e.choices?.join(" | ")})`;
85
- }
86
- const varargs = (tool.leaf.positionals ?? []).filter((p) => (p.argMax ?? 1) === 0);
87
- if (varargs.length > 0) {
88
- line += ` (varargs: ${varargs.map((p) => p.name).join(", ")})`;
89
- }
90
- return line;
91
- }
92
-
93
- /** Builds configuration section for SKILL.md when appConfig entries exist. */
39
+ /** Builds configuration section lines for YAML and markdown. */
94
40
  function buildConfigurationSection(root: CliProgram): string[] {
95
- const schema = root.appConfig?.entries;
96
- if (!schema || Object.keys(schema).length === 0) {
41
+ if (!root.appConfig || Object.keys(root.appConfig.entries).length === 0) {
97
42
  return [];
98
43
  }
99
- const lines = ["## Configuration", ""];
100
- for (const [key, entry] of Object.entries(schema)) {
101
- const label = entry.title ?? defaultConfigEntryTitle(key);
102
- const envNote = entry.env ? ` (env: \`${entry.env}\`)` : "";
103
- lines.push(`- **${label}** (\`${key}\`${envNote}) — ${entry.description}`);
44
+ const entries = root.appConfig.entries;
45
+ const lines: string[] = ["## Configuration", ""];
46
+ for (const name of Object.keys(entries).sort()) {
47
+ const entry = entries[name];
48
+ if (!entry) continue;
49
+ const title = defaultConfigEntryTitle(name);
50
+ const envStr = entry.env ? ` (env: \`${entry.env}\`)` : "";
51
+ const desc = entry.description ? ` — ${entry.description}` : "";
52
+ lines.push(`- **${name}** (\`${title}\`${envStr})${desc}`);
104
53
  }
105
54
  lines.push("");
106
55
  return lines;
107
56
  }
108
57
 
109
- /** Builds SKILL.md body for the agent skill bundle as an intent-based router. */
110
- function buildSkillMd(root: CliProgram, dirName: string): string {
111
- const name = dirName;
112
- const description = skillDescription(root);
113
- const tools = collectMcpTools(root);
114
-
58
+ /** Builds SKILL.md for Claude Code plugin zips (MCP routing only). */
59
+ function buildPluginSkillMd(root: CliProgram, dirName: string): string {
115
60
  const lines: string[] = [
116
61
  "---",
117
- `id: ${dirName}`,
118
- `name: ${name}`,
119
- `description: ${description}`,
120
- "enabled: true",
62
+ `name: ${dirName}`,
63
+ `description: ${pluginSkillDescription(root)}`,
121
64
  "---",
122
65
  "",
123
66
  `# ${root.key}`,
124
67
  "",
125
68
  root.description,
126
69
  "",
127
- "## Execution",
128
- "",
129
- "Invoke via shell:",
130
- "",
131
- "```bash",
132
- `${root.key} <subcommand> [options] [args]`,
133
- "```",
70
+ "## MCP Tools",
134
71
  "",
135
- "## Options & Help Discovery",
72
+ `Server id: \`${mcpServerId(root)}\``,
136
73
  "",
137
- `- Run \`${root.key} <subcommand> --help\` to inspect flags, choices, and positional arguments before running unfamiliar subcommands.`,
138
- `- Run \`${root.key} --help\` at the root for top-level options and command routing.`,
74
+ "Prefer using MCP tools over terminal commands when available.",
139
75
  "",
140
- "## Commands",
76
+ `- Run \`tools/list\` against \`${mcpServerId(root)}\` to discover tools.`,
77
+ `- Read schema resource \`${resolveMcpSchemaUri(root)}\` for types.`,
141
78
  "",
142
79
  ];
143
80
 
144
- if (tools.length === 0) {
145
- lines.push("(No leaf commands in schema.)", "");
146
- } else {
81
+ const tools = collectMcpTools(root);
82
+ if (tools.length > 0) {
83
+ lines.push("### Available tools", "");
147
84
  for (const tool of tools) {
148
- lines.push(formatCommandEntry(root, tool));
85
+ const toolName = sanitizeToolSegment(tool.path.join("_"));
86
+ const desc = tool.leaf.description;
87
+ const wire = leafWireOptions(tool.leaf);
88
+ const flags = wire.length > 0 ? ` (flags: ${wire.map((o) => `--${o.name}`).join(", ")})` : "";
89
+ lines.push(`- \`${toolName}\` — ${desc}${flags}`);
149
90
  }
150
91
  lines.push("");
151
92
  }
152
93
 
153
94
  lines.push(...buildConfigurationSection(root));
154
95
 
155
- lines.push(
156
- "## Workflow & Pitfalls",
157
- "",
158
- `- Always run \`${root.key} <subcommand> --help\` instead of guessing options or reading large doc files.`,
159
- "- Pass `--` before arguments that look like flags.",
160
- "- Pass `--yes` for non-interactive execution when confirmation is required.",
161
- "- Pass `--json` when machine-readable structured output is supported.",
162
- "",
163
- "## Install location",
164
- "",
165
- "Install follows the https://dotagentsprotocol.com:",
166
- "",
167
- `- Auto-install: \`${root.key} configure install\` when \`skill.enabled\` → \`~/.agents/skills/${dirName}/\``,
168
- `- Cursor and most coding agents read \`~/.agents/skills/\` natively`,
169
- "",
170
- "**Claude Code (manual):** symlink or copy into Claude's skill directory:",
171
- "",
172
- "```bash",
173
- "mkdir -p ~/.claude/skills",
174
- `ln -sf ~/.agents/skills/${dirName} ~/.claude/skills/${dirName}`,
175
- "```",
176
- "",
177
- `Project override (optional): \`.agents/skills/${dirName}/\``,
178
- "",
179
- );
180
-
181
- return lines.join("\n");
182
- }
183
-
184
- /** Builds MCP routing SKILL.md for Claude Code plugin zips. */
185
- function buildPluginSkillMd(root: CliProgram, dirName: string): string {
186
- const name = sanitizeToolSegment(root.key);
187
- const description = pluginSkillDescription(root);
188
- const serverId = mcpServerId(root);
189
- const schemaUri = resolveMcpSchemaUri(root);
190
-
191
- const lines: string[] = [
192
- "---",
193
- `name: ${name}`,
194
- `description: ${description}`,
195
- "---",
196
- "",
197
- `# ${root.key}`,
198
- "",
199
- root.description,
200
- "",
201
- "## Execution",
202
- "",
203
- "This plugin bundles an MCP server. Use MCP tools to fulfill requests.",
204
- "",
205
- `- Server id: \`${serverId}\` (configured in plugin \`.mcp.json\`)`,
206
- "- Tool names and argument shapes come from MCP `tools/list`",
207
- `- Full schema: \`${schemaUri}\` (same as \`${root.key} docs cli-schema\`)`,
208
- "",
209
- ];
210
-
211
- lines.push(...buildConfigurationSection(root));
212
-
213
96
  lines.push(
214
97
  "## Claude Code plugin",
215
98
  "",
@@ -228,12 +111,3 @@ export function generatePluginSkillBundle(root: CliProgram): PluginSkillBundle {
228
111
  skillMd: buildPluginSkillMd(root, dirName),
229
112
  };
230
113
  }
231
-
232
- /** Generates SKILL.md router content for agent skill install. */
233
- export function generateSkillBundle(root: CliProgram): SkillBundle {
234
- const dirName = skillDirName(root.key);
235
- return {
236
- dirName,
237
- skillMd: buildSkillMd(root, dirName),
238
- };
239
- }
package/src/skill/hint.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /*
2
2
  This module provides HTML comment hints embedded in generated documentation
3
- and agent skill artifacts to mark them as machine-generated.
3
+ and plugin artifacts to mark them as machine-generated.
4
4
  */
5
5
 
6
6
  import type { CliProgram } from "../core/types.ts";
7
7
 
8
- /** YAML frontmatter block at the start of SKILL.md. */
8
+ /** YAML frontmatter block at the start of markdown files. */
9
9
  export const MARKDOWN_FRONTMATTER_RE = /^---\r?\n[\s\S]*?\r?\n---\r?\n/;
10
10
 
11
11
  /** HTML comment marking argsbarg-generated markdown. */
@@ -24,19 +24,6 @@ export function insertGeneratedHint(content: string, hint: string, options?: { a
24
24
  return `${hint}${content}`;
25
25
  }
26
26
 
27
- /** Hint for `configure` skill output files. */
28
- export function skillInstallHint(program: CliProgram): string {
29
- return generatedFileHtmlComment(`${program.key} configure`);
30
- }
31
-
32
- /** Applies install hint to SKILL.md (after frontmatter). */
33
- export function applySkillInstallHints(program: CliProgram, skillMd: string): { skillMd: string } {
34
- const hint = skillInstallHint(program);
35
- return {
36
- skillMd: insertGeneratedHint(skillMd, hint, { afterFrontmatter: true }),
37
- };
38
- }
39
-
40
27
  /** Hint for `mcp bundle` plugin skill output. */
41
28
  export function skillBundleHint(program: CliProgram): string {
42
29
  return generatedFileHtmlComment(`${program.key} mcp bundle`);
@@ -1,14 +1,11 @@
1
1
  /*
2
- This module installs agent skills to ~/.agents/skills/<key>/ per the dotagents protocol.
3
- It writes skill.md and SKILL.md (compatibility copy) as an intent-based router.
2
+ This module provides paths and helpers for agent skill directories (~/.agents/skills/<key>/).
3
+ Skill generation is removed; skills are authored directly in repositories under skills/<app>/SKILL.md.
4
4
  */
5
5
 
6
- import { existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
7
6
  import { join } from "node:path";
8
7
  import type { CliProgram } from "../core/types.ts";
9
- import { displayHomePath, userHome } from "../paths/host.ts";
10
- import { generateSkillBundle } from "./generate.ts";
11
- import { applySkillInstallHints } from "./hint.ts";
8
+ import { userHome } from "../paths/host.ts";
12
9
  import { skillDirName } from "./naming.ts";
13
10
 
14
11
  export { skillDirName } from "./naming.ts";
@@ -29,35 +26,6 @@ export function resolveAgentsSkillDir(root: CliProgram, global = true): string {
29
26
  return join(base, ".agents", "skills", skillDirName(root.key));
30
27
  }
31
28
 
32
- /** Writes skill.md and SKILL.md (compatibility copy); returns changed file paths. */
33
- export function cliSkillInstall(root: CliProgram, opts: SkillInstallOpts): string[] {
34
- const bundle = generateSkillBundle(root);
35
- const { skillMd } = applySkillInstallHints(root, bundle.skillMd);
36
- const dir = resolveAgentsSkillDir(root, opts.global ?? true);
37
- const changed: string[] = [];
38
-
39
- if (opts.rimraf && existsSync(dir) && !opts.dry) {
40
- rmSync(dir, { recursive: true, force: true });
41
- }
42
-
43
- const skillPath = join(dir, "skill.md");
44
- const skillCompatPath = join(dir, "SKILL.md");
45
-
46
- if (!opts.dry) {
47
- mkdirSync(dir, { recursive: true });
48
- const legacyRef = join(dir, "reference.md");
49
- if (existsSync(legacyRef)) {
50
- rmSync(legacyRef, { force: true });
51
- }
52
- writeFileSync(skillPath, skillMd, "utf8");
53
- writeFileSync(skillCompatPath, skillMd, "utf8");
54
- process.stdout.write(`Installed skill to ${displayHomePath(dir)}/\n`);
55
- }
56
-
57
- changed.push(skillPath, skillCompatPath);
58
- return changed;
59
- }
60
-
61
29
  /** True when the plan action kind installs the agent skill bundle. */
62
30
  export function isAgentSkillActionKind(kind: string): boolean {
63
31
  return kind === "agent-skill";