argsbarg 3.3.5 → 3.3.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.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [3.3.7] - 2026-06-21
11
+
12
+ ### Changed
13
+
14
+ - **`docs mcp`** — intro copy is user-facing (`exposes an MCP server with features similar to the CLI`) instead of describing argsbarg internals.
15
+
16
+ ## [3.3.6] - 2026-06-21
17
+
18
+ ### Added
19
+
20
+ - **`install --skill`** — installed `SKILL.md` and `reference.md` include a `Generated by … install --skill` HTML comment (after SKILL.md frontmatter).
21
+
10
22
  ## [3.3.5] - 2026-06-21
11
23
 
12
24
  ### Changed
@@ -276,7 +288,9 @@ const cli = { ... } satisfies CliProgram; // or : CliProgram
276
288
  - 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`).
277
289
  - Imports: use `CliPositional` where needed; replace `CliOptionDef` with `CliOption` or `CliPositional` as appropriate.
278
290
 
279
- [Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v3.3.5...HEAD
291
+ [Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v3.3.7...HEAD
292
+ [3.3.7]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.3.7
293
+ [3.3.6]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.3.6
280
294
  [3.3.5]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.3.5
281
295
  [3.3.4]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.3.4
282
296
  [3.3.3]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.3.3
package/docs/ai-skills.md CHANGED
@@ -34,6 +34,8 @@ For library use, call `cliSkillInstall(root, "cursor" | "claude", { global: true
34
34
  - **`SKILL.md`** — YAML frontmatter, when-to-use guidance, shell command catalog, pitfalls
35
35
  - **`reference.md`** — full `docs schema` JSON export
36
36
 
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`.
38
+
37
39
  Skills describe **shell invocation only** — no MCP setup, `mcp.json`, or `tools/call` guidance. Use **`myapp docs mcp`** (when `docs` and `mcpServer` are enabled) or connect the MCP server for agent execution.
38
40
 
39
41
  ## MCP vs skills vs docs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "argsbarg",
3
- "version": "3.3.5",
3
+ "version": "3.3.7",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "bun": ">=1.3"
@@ -29,7 +29,7 @@ export function generateMcpGuide(root: CliProgram): string {
29
29
  const lines: string[] = [
30
30
  `# MCP server (${root.key})`,
31
31
  "",
32
- `${root.key} exposes an MCP server via argsbarg. Each exposed leaf command becomes an MCP tool.`,
32
+ `${root.key} exposes an MCP server with features similar to the CLI.`,
33
33
  "",
34
34
  "## Quick start",
35
35
  "",
package/src/docs/save.ts CHANGED
@@ -2,6 +2,7 @@ import { mkdirSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import type { CliProgram } from "../types.ts";
4
4
  import { docsTopicContent } from "./resolve.ts";
5
+ import { generatedFileHtmlComment, insertGeneratedHint } from "../skill/hint.ts";
5
6
 
6
7
  /** Relative output directory for `docs --save`. */
7
8
  export const DOCS_SAVE_DIR = "docs";
@@ -16,24 +17,16 @@ export function docsTopicIsGeneratedByArgsbarg(topic: string): boolean {
16
17
 
17
18
  /** HTML comment for generated markdown saved with `--save`. */
18
19
  export function docsSaveGeneratedHint(program: CliProgram, topic: string): string {
19
- return `<!-- Generated by ${program.key} docs ${topic} --save; do not edit. -->\n\n`;
20
+ return generatedFileHtmlComment(`${program.key} docs ${topic} --save`);
20
21
  }
21
22
 
22
- const SKILL_FRONTMATTER_RE = /^---\r?\n[\s\S]*?\r?\n---\r?\n/;
23
-
24
23
  /** Inserts save hint without breaking YAML frontmatter (`docs skill`). */
25
24
  export function applySaveGeneratedHint(program: CliProgram, topic: string, content: string): string {
26
25
  if (!docsTopicIsGeneratedByArgsbarg(topic)) {
27
26
  return content;
28
27
  }
29
28
  const hint = docsSaveGeneratedHint(program, topic);
30
- if (topic === "skill") {
31
- const match = content.match(SKILL_FRONTMATTER_RE);
32
- if (match) {
33
- return `${match[0]}${hint}${content.slice(match[0].length)}`;
34
- }
35
- }
36
- return `${hint}${content}`;
29
+ return insertGeneratedHint(content, hint, topic === "skill" ? { afterFrontmatter: true } : undefined);
37
30
  }
38
31
 
39
32
  /** File body for `--save` (hint on argsbarg-generated markdown only). */
package/src/index.test.ts CHANGED
@@ -1773,7 +1773,9 @@ test("generateSkillBundle includes frontmatter and command catalog", () => {
1773
1773
  expect(bundle.skillMd).not.toContain("mcp.json");
1774
1774
  expect(bundle.skillMd).not.toContain("Prefer MCP");
1775
1775
  expect(bundle.skillMd).not.toContain("tools/call");
1776
+ expect(bundle.skillMd).not.toContain("Generated by");
1776
1777
  expect(bundle.referenceMd).toContain("```json");
1778
+ expect(bundle.referenceMd).not.toContain("Generated by");
1777
1779
  expect(() => JSON.parse(bundle.referenceMd.match(/```json\n([\s\S]*?)\n```/)![1]!)).not.toThrow();
1778
1780
  });
1779
1781
 
@@ -1788,6 +1790,12 @@ test("cliSkillInstall writes project Cursor skill files", () => {
1788
1790
  expect(existsSync(join(skillDir, "SKILL.md"))).toBe(true);
1789
1791
  expect(existsSync(join(skillDir, "reference.md"))).toBe(true);
1790
1792
  expect(readFileSync(join(skillDir, "SKILL.md"), "utf8")).toContain("stat owner lookup");
1793
+ const skillText = readFileSync(join(skillDir, "SKILL.md"), "utf8");
1794
+ expect(skillText.startsWith("---\n")).toBe(true);
1795
+ const hint = "<!-- Generated by nested.ts install --skill; do not edit. -->";
1796
+ expect(skillText.indexOf(hint)).toBeGreaterThan(skillText.indexOf("---\n", 4));
1797
+ const refText = readFileSync(join(skillDir, "reference.md"), "utf8");
1798
+ expect(refText.startsWith(hint)).toBe(true);
1791
1799
  } finally {
1792
1800
  process.chdir(prev);
1793
1801
  rmSync(cwd, { recursive: true, force: true });
@@ -0,0 +1,42 @@
1
+ import type { CliProgram } from "../types.ts";
2
+
3
+ /** YAML frontmatter block at the start of SKILL.md. */
4
+ export const MARKDOWN_FRONTMATTER_RE = /^---\r?\n[\s\S]*?\r?\n---\r?\n/;
5
+
6
+ /** HTML comment marking argsbarg-generated markdown. */
7
+ export function generatedFileHtmlComment(source: string): string {
8
+ return `<!-- Generated by ${source}; do not edit. -->\n\n`;
9
+ }
10
+
11
+ /** Prepends a hint, or inserts after frontmatter when requested. */
12
+ export function insertGeneratedHint(
13
+ content: string,
14
+ hint: string,
15
+ options?: { afterFrontmatter?: boolean },
16
+ ): string {
17
+ if (options?.afterFrontmatter) {
18
+ const match = content.match(MARKDOWN_FRONTMATTER_RE);
19
+ if (match) {
20
+ return `${match[0]}${hint}${content.slice(match[0].length)}`;
21
+ }
22
+ }
23
+ return `${hint}${content}`;
24
+ }
25
+
26
+ /** Hint for `install --skill` output files. */
27
+ export function skillInstallHint(program: CliProgram): string {
28
+ return generatedFileHtmlComment(`${program.key} install --skill`);
29
+ }
30
+
31
+ /** Applies install hints to SKILL.md (after frontmatter) and reference.md. */
32
+ export function applySkillInstallHints(
33
+ program: CliProgram,
34
+ skillMd: string,
35
+ referenceMd: string,
36
+ ): { skillMd: string; referenceMd: string } {
37
+ const hint = skillInstallHint(program);
38
+ return {
39
+ skillMd: insertGeneratedHint(skillMd, hint, { afterFrontmatter: true }),
40
+ referenceMd: insertGeneratedHint(referenceMd, hint),
41
+ };
42
+ }
@@ -3,6 +3,7 @@ import { homedir } from "node:os";
3
3
  import { join } from "node:path";
4
4
  import { CliProgram } from "../types.ts";
5
5
  import { generateSkillBundle, type SkillTarget } from "./generate.ts";
6
+ import { applySkillInstallHints } from "./hint.ts";
6
7
 
7
8
  export interface SkillInstallOpts {
8
9
  global?: boolean;
@@ -26,6 +27,7 @@ function resolveSkillDir(target: SkillTarget, dirName: string, global: boolean):
26
27
  /** Writes SKILL.md and reference.md; returns changed file paths. */
27
28
  export function cliSkillInstall(root: CliProgram, target: SkillTarget, opts: SkillInstallOpts): string[] {
28
29
  const bundle = generateSkillBundle(root, target);
30
+ const { skillMd, referenceMd } = applySkillInstallHints(root, bundle.skillMd, bundle.referenceMd);
29
31
  const dir = resolveSkillDir(target, bundle.dirName, opts.global ?? false);
30
32
  const changed: string[] = [];
31
33
 
@@ -38,8 +40,8 @@ export function cliSkillInstall(root: CliProgram, target: SkillTarget, opts: Ski
38
40
 
39
41
  if (!opts.dry) {
40
42
  mkdirSync(dir, { recursive: true });
41
- writeFileSync(skillPath, bundle.skillMd, "utf8");
42
- writeFileSync(refPath, bundle.referenceMd, "utf8");
43
+ writeFileSync(skillPath, skillMd, "utf8");
44
+ writeFileSync(refPath, referenceMd, "utf8");
43
45
  }
44
46
 
45
47
  changed.push(skillPath, refPath);