argsbarg 7.1.2 → 7.1.3

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 (58) hide show
  1. package/CHANGELOG.md +24 -1
  2. package/README.md +7 -7
  3. package/docs/README.md +1 -1
  4. package/docs/cli-program.md +1 -1
  5. package/docs/configure.md +2 -2
  6. package/docs/mcp.md +20 -0
  7. package/docs/output-schema.md +6 -0
  8. package/examples/full-example/AGENTS.md +1 -1
  9. package/examples/full-example/bun.lock +83 -1
  10. package/examples/full-example/justfile +5 -3
  11. package/examples/full-example-json/AGENTS.md +1 -1
  12. package/examples/full-example-json/README.md +1 -0
  13. package/examples/full-example-json/bun.lock +83 -1
  14. package/examples/full-example-json/docs/cli-schema.json +284 -9
  15. package/examples/full-example-json/docs/cli.md +236 -18
  16. package/examples/full-example-json/docs/http.md +1 -0
  17. package/examples/full-example-json/docs/mcp.md +18 -0
  18. package/examples/full-example-json/docs/openapi.json +155 -0
  19. package/examples/full-example-json/justfile +5 -3
  20. package/examples/full-example-json/src/commands/shape-area/__generated__/ShapeAreaInputSchema.json +59 -0
  21. package/examples/full-example-json/src/commands/shape-area/__generated__/index.ts +5 -0
  22. package/examples/full-example-json/src/commands/shape-area/command.test.ts +34 -0
  23. package/examples/full-example-json/src/commands/shape-area/command.ts +31 -0
  24. package/examples/full-example-json/src/commands/shape-area/types.ts +28 -0
  25. package/examples/full-example-json/src/program.ts +2 -1
  26. package/examples/mcp-plugin/.claude-plugin/plugin.json +7 -1
  27. package/examples/mcp-plugin/.cursor-plugin/plugin.json +7 -1
  28. package/examples/mcp-plugin/AGENTS.md +14 -1
  29. package/examples/mcp-plugin/README.md +19 -10
  30. package/examples/mcp-plugin/bun.lock +83 -1
  31. package/examples/mcp-plugin/bunfig.toml +4 -0
  32. package/examples/mcp-plugin/docs/node-distro.md +97 -0
  33. package/examples/mcp-plugin/justfile +12 -11
  34. package/examples/mcp-plugin/package.json +2 -1
  35. package/examples/mcp-plugin/scripts/release.ts +10 -11
  36. package/package.json +1 -1
  37. package/src/cli-tool/create.test.ts +14 -0
  38. package/src/cli-tool/create.ts +9 -0
  39. package/src/cli-tool/main.ts +1 -1
  40. package/src/cli-tool/schemagen/run.ts +41 -2
  41. package/src/cli-tool/schemagen/schemagen.test.ts +87 -2
  42. package/src/config/validate.ts +13 -31
  43. package/src/core/json-pointer.ts +46 -0
  44. package/src/core/validate.ts +64 -1
  45. package/src/headless/tool-call.test.ts +74 -2
  46. package/src/headless/tool-call.ts +44 -22
  47. package/src/http/schema-deref.ts +1 -23
  48. package/src/mcp/tools.test.ts +137 -3
  49. package/src/mcp/tools.ts +50 -5
  50. package/examples/mcp-plugin/.mcp.json +0 -6
  51. package/examples/mcp-plugin/mcp.json +0 -8
  52. package/examples/mcp-plugin/scripts/mcp.mjs +0 -11106
  53. package/examples/mcp-plugin/src/commands/render-json/__generated__/RenderJsonInputSchema.json +0 -15
  54. package/examples/mcp-plugin/src/commands/render-json/__generated__/index.ts +0 -5
  55. package/examples/mcp-plugin/src/commands/status/__generated__/StatusJsonOutputSchema.json +0 -15
  56. package/examples/mcp-plugin/src/commands/status/__generated__/index.ts +0 -5
  57. package/examples/mcp-plugin/src/commands/workspaces/__generated__/WorkspaceNameInputSchema.json +0 -15
  58. package/examples/mcp-plugin/src/commands/workspaces/__generated__/index.ts +0 -5
@@ -0,0 +1,31 @@
1
+ /*
2
+ Shape-area leaf — discriminated-union JSON body demo (MCP wraps non-object roots as `{ input }`).
3
+ */
4
+
5
+ import type { CliLeaf, CliProgram } from "argsbarg";
6
+ import { ShapeAreaInputSchema } from "./__generated__";
7
+ import type { ShapeAreaInput } from "./types.ts";
8
+
9
+ export const shapeAreaCommand = {
10
+ key: "shape-area",
11
+ description: "Compute the area of a circle or rectangle (union-input JSON leaf demo).",
12
+ kind: "json",
13
+ inputSchema: ShapeAreaInputSchema,
14
+ handler: (ctx) => {
15
+ const shape = ctx.inputsAs<ShapeAreaInput>();
16
+ const area = shape.kind === "circle" ? Math.PI * shape.radius ** 2 : shape.width * shape.height;
17
+ if (ctx.invocation === "cli") {
18
+ console.log(area);
19
+ return;
20
+ }
21
+ return { area };
22
+ },
23
+ } satisfies CliLeaf;
24
+
25
+ /** Program stub for colocated tests. */
26
+ export function shapeAreaTestProgram(base: CliProgram): CliProgram {
27
+ return {
28
+ ...base,
29
+ commands: [shapeAreaCommand],
30
+ };
31
+ }
@@ -0,0 +1,28 @@
1
+ /*
2
+ Input types for the shape-area demo leaf (discriminated-union input).
3
+ The union root is not `type: "object"`, so MCP clients see it wrapped as `{ input: ... }`.
4
+ */
5
+
6
+ /** A circle, measured by radius. */
7
+ export interface Circle {
8
+ /** Shape discriminator. */
9
+ kind: "circle";
10
+ /** Circle radius. */
11
+ radius: number;
12
+ }
13
+
14
+ /** A rectangle, measured by width and height. */
15
+ export interface Rect {
16
+ /** Shape discriminator. */
17
+ kind: "rect";
18
+ /** Rectangle width. */
19
+ width: number;
20
+ /** Rectangle height. */
21
+ height: number;
22
+ }
23
+
24
+ /**
25
+ * Shape to measure: a circle or a rectangle.
26
+ * @sg
27
+ */
28
+ export type ShapeAreaInput = Circle | Rect;
@@ -7,12 +7,13 @@ import readmeText from "../README.md" with { type: "text" };
7
7
  import { createIdentity } from "../scripts/create-identity.ts";
8
8
  import { echoCommand } from "./commands/echo/command.ts";
9
9
  import { renderJsonCommand } from "./commands/render-json/command.ts";
10
+ import { shapeAreaCommand } from "./commands/shape-area/command.ts";
10
11
  import { statusCommand } from "./commands/status/command.ts";
11
12
  import { workspacesCommand } from "./commands/workspaces/command.ts";
12
13
  import { AppDb } from "./db";
13
14
 
14
15
  export const program = {
15
- commands: [echoCommand, renderJsonCommand, statusCommand, workspacesCommand],
16
+ commands: [echoCommand, renderJsonCommand, shapeAreaCommand, statusCommand, workspacesCommand],
16
17
  description: createIdentity.desc,
17
18
  docs: {
18
19
  topics: {
@@ -6,5 +6,11 @@
6
6
  "name": "Brian Dombrowski"
7
7
  },
8
8
  "homepage": "https://github.com/bdombro/bun-argsbarg",
9
- "repository": "https://github.com/bdombro/bun-argsbarg"
9
+ "repository": "https://github.com/bdombro/bun-argsbarg",
10
+ "mcpServers": {
11
+ "mcp-plugin": {
12
+ "command": "bun",
13
+ "args": ["--cwd", "${CLAUDE_PLUGIN_ROOT}", "start"]
14
+ }
15
+ }
10
16
  }
@@ -7,5 +7,11 @@
7
7
  "name": "Brian Dombrowski"
8
8
  },
9
9
  "homepage": "https://github.com/bdombro/bun-argsbarg",
10
- "repository": "https://github.com/bdombro/bun-argsbarg"
10
+ "repository": "https://github.com/bdombro/bun-argsbarg",
11
+ "mcpServers": {
12
+ "mcp-plugin": {
13
+ "command": "bun",
14
+ "args": ["--cwd", "${CURSOR_PLUGIN_ROOT}", "start"]
15
+ }
16
+ }
11
17
  }
@@ -76,11 +76,24 @@ Avoid needless extraction: keep single-use helpers in the calling file by defaul
76
76
 
77
77
  ## Tooling
78
78
 
79
- - Bun only (`bun`, `bunx`, `bun test`). No Node/npm/pnpm.
79
+ - Use Bun for development and the default plugin runtime (`bun`, `bun x`, `bun test`).
80
+ - `bun start` installs locked dependencies, generates schemas, then starts MCP. Keep setup output on stderr; stdout is the MCP protocol.
81
+ - Ship source, `bun.lock`, and inline plugin manifests. Do not ship `node_modules`, generated schemas, or a compiled bundle.
82
+ - Node distribution is an explicit alternative documented in `docs/node-distro.md`; do not change the default runtime implicitly.
83
+
84
+ ## Testing Boundaries
85
+
86
+ - Use the cheapest test level that establishes the behavior. Reuse existing tests and helpers.
87
+ - Unit/offline: deterministic parsing, validation, state changes, and request planning. Keep these tests independent of live services and paid agents.
88
+ - Integration: contracts unit tests cannot establish, such as clean plugin installation, MCP startup/transport, or actual external persistence. Do not duplicate unit coverage with live calls.
89
+ - Agent E2E: safe user-task completion and agent efficiency. Check outcomes and protected content, not exact tool-call sequences or exhaustive protocol details. Run explicitly, never as part of the default unit test command.
90
+ - When E2E exposes a tool bug, reproduce and fix it in unit tests first; use integration only where necessary. Check verifier changes offline against retained or synthetic evidence before another paid run.
91
+ - Attribute agent failures and recovery from observable evidence. A failed call alone does not establish task failure or a tool defect.
80
92
 
81
93
  ## Documentation
82
94
 
83
95
  - `README.md` — user-facing install/commands
96
+ - `docs/node-distro.md` — optional conversion from source-only Bun plugins to a bundled Node MCP distribution
84
97
  - `docs/architecture.md` — maintainer internals (create if missing)
85
98
  - Generated: `just docgen` → `docs/cli.md`, `docs/cli-schema.json`
86
99
  - `skills/mcp-plugin/SKILL.md` — agent skill router (scaffolded from template; customize as needed)
@@ -6,13 +6,17 @@ Argsbarg MCP plugin template for Cursor and Claude Code marketplaces (@sg schema
6
6
 
7
7
  `mcp-plugin` packages an MCP server and agent skills directly for Cursor and Claude Code marketplaces:
8
8
 
9
- - **Cursor Plugin**: `.cursor-plugin/plugin.json` and `mcp.json` running `${CURSOR_PLUGIN_ROOT}/scripts/mcp.mjs` via `node`.
10
- - **Claude Code Plugin**: `.claude-plugin/plugin.json` and `.mcp.json` running `${CLAUDE_PLUGIN_ROOT}/scripts/mcp.mjs` via `node`.
9
+ - **Cursor Plugin**: inline MCP configuration in `.cursor-plugin/plugin.json` runs `bun --cwd ${CURSOR_PLUGIN_ROOT} start`.
10
+ - **Claude Code Plugin**: inline MCP configuration in `.claude-plugin/plugin.json` runs `bun --cwd ${CLAUDE_PLUGIN_ROOT} start`.
11
11
  - **In-repo skills**: `skills/mcp-plugin/SKILL.md` discovered and loaded by agent platforms.
12
- - **Standalone runner**: `bun build --target=node src/index.ts --outfile scripts/mcp.mjs` creates an inlined, zero-npm-install script.
12
+ - **Source-only distribution**: TypeScript and `bun.lock` are shipped; dependencies and generated schemas are prepared locally. No compiled bundle is shipped.
13
13
 
14
14
  ## Installation
15
15
 
16
+ Requires Bun >=1.3 on the host's PATH, a writable plugin directory, and network access for uncached dependencies. `bun start` installs locked dependencies and generates schemas before starting MCP. Setup output goes to stderr; stdout contains only MCP messages. Startup stops if preparation fails.
17
+
18
+ The in-repo example retains its `argsbarg: file:../..` development dependency. Before distributing a standalone copy, resolve that dependency for the destination repository and regenerate its lockfile; the parent-checkout path is not portable.
19
+
16
20
  ### Cursor
17
21
 
18
22
  Recommended: import directly from GitHub — Cursor Dashboard → **Settings → Plugins → Team Marketplaces → Import**, then enter `https://github.com/bdombro/bun-argsbarg` (subdirectory `examples/mcp-plugin` once copied to its own repo). Once published to the [official marketplace](https://cursor.com/marketplace/publish), install via `/add-plugin mcp-plugin` or the Customize sidebar.
@@ -23,9 +27,11 @@ Recommended: add the GitHub repo as a marketplace, then install:
23
27
 
24
28
  ```bash
25
29
  /plugin marketplace add <owner>/<repo>
26
- /plugin install mcp-plugin@<repo>
30
+ /plugin install mcp-plugin@mcp-plugin
27
31
  ```
28
32
 
33
+ The marketplace name comes from `.claude-plugin/marketplace.json`, not the repository name.
34
+
29
35
  Once merged into [anthropics/claude-plugins-official](https://github.com/anthropics/claude-plugins-official), install via `/plugin install mcp-plugin@claude-plugins-official`.
30
36
 
31
37
  ## Commands
@@ -52,16 +58,18 @@ cd bun-argsbarg/examples/mcp-plugin
52
58
  # Install dependencies and generate schemas
53
59
  just setup
54
60
 
55
- # Build standalone MCP bundle
56
- just build
57
-
58
- # Test MCP server directly with node
59
- node ./scripts/mcp.mjs mcp
61
+ # Run the source-only MCP server
62
+ bun start
60
63
 
61
64
  # Link into local Cursor plugins for live testing
62
- just install-plugin-cursor
65
+ just plugin-cursor-upsert
66
+
67
+ # Register this checkout as a marketplace and install in Claude Code
68
+ just plugin-claude-install
63
69
  ```
64
70
 
71
+ Restart Claude Code after installing. Use `bun src/index.ts <command>` for CLI commands; `bun start` is specifically the MCP entry point. In-repo development uses `just setup` to repair the local dependency's CLI executable link.
72
+
65
73
  ## Documentation
66
74
 
67
75
  | Need | Resource |
@@ -70,3 +78,4 @@ just install-plugin-cursor
70
78
  | MCP tools | [docs/mcp.md](docs/mcp.md) or `mcp-plugin docs mcp` |
71
79
  | HTTP API | [docs/http.md](docs/http.md) or `mcp-plugin docs http` |
72
80
  | OpenAPI 3.1 | [docs/openapi.json](docs/openapi.json) |
81
+ | Optional Node distribution | [docs/node-distro.md](docs/node-distro.md) |
@@ -33,16 +33,98 @@
33
33
 
34
34
  "@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.5.1", "", { "os": "win32", "cpu": "x64" }, "sha512-6uxpR9hvaglANkZemeSiN/FhYgkGasrEGn267eXIWvjrjJ2LhDlk251IhjVJq6MXzkV2/bcXwLwSroLyPtqRZg=="],
35
35
 
36
+ "@cfworker/json-schema": ["@cfworker/json-schema@4.1.1", "", {}, "sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og=="],
37
+
36
38
  "@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
37
39
 
40
+ "@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
41
+
38
42
  "@types/node": ["@types/node@26.0.0", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA=="],
39
43
 
40
- "argsbarg": ["argsbarg@file:../..", { "devDependencies": { "@biomejs/biome": "^2.5.0", "@types/bun": "^1.3.12", "typescript": "^5.9.3" }, "bin": { "argsbarg": "src/index.ts" } }],
44
+ "ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
45
+
46
+ "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
47
+
48
+ "argsbarg": ["argsbarg@file:../..", { "dependencies": { "@cfworker/json-schema": "^4", "ts-json-schema-generator": "^2.3.0" }, "devDependencies": { "@biomejs/biome": "^2.5.5", "@types/bun": "^1.3.12", "dts-bundle-generator": "^9.5.1", "typescript": "^5.9.3" }, "bin": { "argsbarg": "bin/argsbarg" } }],
49
+
50
+ "balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
51
+
52
+ "brace-expansion": ["brace-expansion@5.0.12", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ=="],
41
53
 
42
54
  "bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="],
43
55
 
56
+ "cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
57
+
58
+ "color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
59
+
60
+ "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
61
+
62
+ "commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="],
63
+
64
+ "dts-bundle-generator": ["dts-bundle-generator@9.5.1", "", { "dependencies": { "typescript": ">=5.0.2", "yargs": "^17.6.0" }, "bin": { "dts-bundle-generator": "dist/bin/dts-bundle-generator.js" } }, "sha512-DxpJOb2FNnEyOzMkG11sxO2dmxPjthoVWxfKqWYJ/bI/rT1rvTMktF5EKjAYrRZu6Z6t3NhOUZ0sZ5ZXevOfbA=="],
65
+
66
+ "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
67
+
68
+ "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
69
+
70
+ "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
71
+
72
+ "glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
73
+
74
+ "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
75
+
76
+ "json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
77
+
78
+ "lru-cache": ["lru-cache@11.5.3", "", {}, "sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg=="],
79
+
80
+ "minimatch": ["minimatch@10.2.6", "", { "dependencies": { "brace-expansion": "^5.0.8" } }, "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A=="],
81
+
82
+ "minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
83
+
84
+ "normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
85
+
86
+ "path-scurry": ["path-scurry@2.0.2", "", { "dependencies": { "lru-cache": "^11.0.0", "minipass": "^7.1.2" } }, "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg=="],
87
+
88
+ "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
89
+
90
+ "safe-stable-stringify": ["safe-stable-stringify@2.5.0", "", {}, "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA=="],
91
+
92
+ "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
93
+
94
+ "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
95
+
96
+ "ts-json-schema-generator": ["ts-json-schema-generator@2.9.0", "", { "dependencies": { "@types/json-schema": "^7.0.15", "commander": "^14.0.3", "glob": "^13.0.6", "json5": "^2.2.3", "normalize-path": "^3.0.0", "safe-stable-stringify": "^2.5.0", "tslib": "^2.8.1", "typescript": "^5.9.3" }, "bin": { "ts-json-schema-generator": "bin/ts-json-schema-generator.js" } }, "sha512-NR5ZE108uiPtBHBJNGnhwoUaUx5vWTDJzDFG9YlRoqxPU76n+5FClRh92dcGgysbe1smRmYalM9Saj97GW1J4Q=="],
97
+
98
+ "tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
99
+
44
100
  "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
45
101
 
46
102
  "undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="],
103
+
104
+ "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
105
+
106
+ "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
107
+
108
+ "yargs": ["yargs@17.7.3", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g=="],
109
+
110
+ "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
111
+
112
+ "argsbarg/@biomejs/biome": ["@biomejs/biome@2.5.14", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.5.14", "@biomejs/cli-darwin-x64": "2.5.14", "@biomejs/cli-linux-arm64": "2.5.14", "@biomejs/cli-linux-arm64-musl": "2.5.14", "@biomejs/cli-linux-x64": "2.5.14", "@biomejs/cli-linux-x64-musl": "2.5.14", "@biomejs/cli-win32-arm64": "2.5.14", "@biomejs/cli-win32-x64": "2.5.14" }, "bin": { "biome": "bin/biome" } }, "sha512-0FabLIjd4M/dm8VFI86RMaLLdgepzbdfiAL2R8cr7V81OYYrP1w7Z73KfAwPK5h9SrEBXTzNG2y+mBwPo9xRnw=="],
113
+
114
+ "argsbarg/@biomejs/biome/@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.5.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-UnzaXO65L4tsZimFITFP2M121GyhDcWFrT3pL5ZJ5U4XcS/0L5VHYytVohdCf/gnDUFHgl2I9xnt5bV/J1kxHQ=="],
115
+
116
+ "argsbarg/@biomejs/biome/@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.5.14", "", { "os": "darwin", "cpu": "x64" }, "sha512-kiy8qA16K93J7uvFfWi4LgjqDpnRKyePAna6A0Y4jxyUga35SYpIZ2cNWlhy0lsfgqRenCpfymnJWEZ6mgpRgA=="],
117
+
118
+ "argsbarg/@biomejs/biome/@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.5.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-vO/9BaU1n30CiFNLx49gMTMtbCAAqlo/EqFoG0BU3deQInTbJrmXSmTQ9e3FoDZIKQnvSLDVNL4lx1ci7y1T1Q=="],
119
+
120
+ "argsbarg/@biomejs/biome/@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.5.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-SJ9PrZkBnnH9dHJDnxk34vKs0GB2dbsioaft6/hPhWJ7AHpwYH83Isnhj0FSRpFkGgpVfJ1lds23ApB2czUDLQ=="],
121
+
122
+ "argsbarg/@biomejs/biome/@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.5.14", "", { "os": "linux", "cpu": "x64" }, "sha512-VHZRa7CCQBUWKxNwUvHJeuW03WFRgN5NWO//SDGOitc9QIeNyfA42V9zlKm+x82xFSG9Bzi5fi+hbhm9anO8yA=="],
123
+
124
+ "argsbarg/@biomejs/biome/@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.5.14", "", { "os": "linux", "cpu": "x64" }, "sha512-2kI5PrMgW5dcEZYrstLPmUmCwkUwZY39rP4BN93Vxbwcs2O57LDQOktUZZYPvvspN5i0mhGr3TJtF5sU26NUWg=="],
125
+
126
+ "argsbarg/@biomejs/biome/@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.5.14", "", { "os": "win32", "cpu": "arm64" }, "sha512-pHgAFffmZtaYoxavEsWEYNvcA7NwOIjLyqw2HXyLbt16xYryX0L4fMV2u0G9ag6LNYPIoqWaWqzUcnc6rLGGXg=="],
127
+
128
+ "argsbarg/@biomejs/biome/@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.5.14", "", { "os": "win32", "cpu": "x64" }, "sha512-oJWmBhoHsnhUKIke+0gXDX0mltJrWHA1UyHsrTlXwX0TL64ilVZAo+TYZm97baecV0esBdpzy3k96q+09JaZUQ=="],
47
129
  }
48
130
  }
@@ -1,3 +1,7 @@
1
1
  [install]
2
2
  # fetch package.json deps on first `bun src/index.ts` without manual `bun install`.
3
3
  auto = "fallback"
4
+
5
+ [run]
6
+ shell = "bun"
7
+ silent = true
@@ -0,0 +1,97 @@
1
+ # Node Distribution
2
+
3
+ The default plugin ships TypeScript and starts with Bun. To ship a standalone
4
+ Node MCP server instead, follow the bundle-based distribution described below.
5
+ Bun remains the development/build tool; plugin users need Node but do not need
6
+ Bun, dependency installation, or schema generation at startup.
7
+ Note: bundle distrobutions mean committing large bundled js files to the repo.
8
+ ## 1. Build The Bundle
9
+
10
+ Add this recipe to `justfile`:
11
+
12
+ ```just
13
+ # Generate schemas and bundle the standalone Node MCP server
14
+ build: schemagen
15
+ bun build ./src/index.ts --target=node --outfile=./scripts/mcp.mjs
16
+ ```
17
+
18
+ Run `just setup` and `just build` from the project root. Schemas must exist before
19
+ bundling so their static imports are included in the output.
20
+
21
+ Keep the MCP runtime compatible with Node. Bundling does not implement Bun-only
22
+ APIs such as `Bun.serve` or `bun:sqlite`; port or exclude any such runtime paths.
23
+ The HTTP server capability is separate from this Node MCP distribution.
24
+
25
+ ## 2. Change Startup
26
+
27
+ Remove `prestart` from `package.json` and change `start` to:
28
+
29
+ ```json
30
+ "start": "node scripts/mcp.mjs mcp"
31
+ ```
32
+
33
+ Declare the supported Node version range under `engines.node` and document it in
34
+ the README. Bun is still needed by maintainers for schema generation, tests, and
35
+ bundling. The Bun shell settings in `bunfig.toml` can remain for development.
36
+
37
+ ## 3. Update Inline Plugin Configs
38
+
39
+ Keep MCP configuration inside the plugin manifests; do not reintroduce separate
40
+ root MCP config files. Replace the `mcpServers` field in
41
+ `.claude-plugin/plugin.json` with:
42
+
43
+ ```json
44
+ "mcpServers": {
45
+ "mcp-plugin": {
46
+ "command": "node",
47
+ "args": ["${CLAUDE_PLUGIN_ROOT}/scripts/mcp.mjs", "mcp"]
48
+ }
49
+ }
50
+ ```
51
+
52
+ Use the corresponding field in `.cursor-plugin/plugin.json`:
53
+
54
+ ```json
55
+ "mcpServers": {
56
+ "mcp-plugin": {
57
+ "command": "node",
58
+ "args": ["${CURSOR_PLUGIN_ROOT}/scripts/mcp.mjs", "mcp"]
59
+ }
60
+ }
61
+ ```
62
+
63
+ Launching Node directly avoids relying on a package manager on the user's
64
+ machine. Keep each path as one argument so plugin roots containing spaces work.
65
+
66
+ ## 4. Package And Release
67
+
68
+ - Add `build` as a dependency of `plugin-cursor-upsert` and
69
+ `plugin-claude-install` so local installs have a fresh bundle.
70
+ - Restore `just build` in `scripts/release.ts` after version/documentation
71
+ updates and before committing or publishing. Fail the release if it fails.
72
+ - Include `scripts/mcp.mjs` in the released plugin. For repository-based
73
+ installation, commit the generated bundle so a fresh clone is runnable.
74
+ - Do not ship `node_modules` or generated schemas separately. Their runtime
75
+ contents should be bundled; inspect external imports and package any required
76
+ runtime assets explicitly.
77
+ - Update the README and the project-specific tooling section of `AGENTS.md`
78
+ to describe Node as the plugin runtime and Bun as the development tool.
79
+
80
+ ## 5. Verify The Node Distribution
81
+
82
+ After building, a basic stdio check is:
83
+
84
+ ```bash
85
+ printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
86
+ | node scripts/mcp.mjs mcp
87
+ ```
88
+
89
+ Only JSON-RPC responses should appear on stdout. Exercise `tools/list` and a
90
+ representative tool call as well: successful initialization alone does not prove
91
+ that every command's runtime dependencies are Node-compatible.
92
+
93
+ Check both manifest commands from an unrelated working directory with the
94
+ plugin-root placeholders expanded to the installed path. Verify a clean copy
95
+ with no `node_modules` or generated schemas, using the declared minimum Node
96
+ version and a current supported Node version. Keep transport/package checks at
97
+ the integration level; agent E2E should measure real user-task outcomes.
@@ -7,10 +7,6 @@ export PATH := justfile_directory() + "/node_modules/.bin:" + env_var("PATH")
7
7
  _:
8
8
  @just --list
9
9
 
10
- # Bundle the standalone Node MCP server script
11
- build:
12
- bun build ./src/index.ts --target=node --outfile=./scripts/mcp.mjs
13
-
14
10
  # Run schemagen, typecheck, and format
15
11
  check: schemagen format typecheck
16
12
 
@@ -52,16 +48,21 @@ format:
52
48
  http:
53
49
  @just run http
54
50
 
51
+ # Lint sources without writing
52
+ lint:
53
+ bun run biome check ./src ./scripts
54
+
55
+ # Install the Claude Code plugin from this checkout (restart Claude Code afterwards)
56
+ plugin-claude-install:
57
+ claude plugin marketplace add "$(pwd)"
58
+ claude plugin install mcp-plugin@mcp-plugin
59
+
55
60
  # Link plugin into ~/.cursor/plugins/local/mcp-plugin for local testing
56
- install-plugin-cursor: build
61
+ plugin-cursor-upsert:
57
62
  mkdir -p ~/.cursor/plugins/local
58
63
  ln -sfn '{{justfile_directory()}}' ~/.cursor/plugins/local/mcp-plugin
59
64
  @echo "Linked MCP plugin to ~/.cursor/plugins/local/mcp-plugin"
60
65
 
61
- # Lint sources without writing
62
- lint:
63
- bun run biome check ./src ./scripts
64
-
65
66
  # Run the CLI from source once
66
67
  run *ARGS:
67
68
  bun ./src/index.ts {{ARGS}}
@@ -73,14 +74,14 @@ schemagen:
73
74
  # Install bun/npm dependencies and generate schemas
74
75
  setup:
75
76
  bun install
76
- test -f node_modules/argsbarg/bin/argsbarg && ln -sf ../argsbarg/bin/argsbarg node_modules/.bin/argsbarg
77
+ test -f node_modules/argsbarg/bin/argsbarg && ln -sf ../argsbarg/bin/argsbarg node_modules/.bin/argsbarg # argsbarg-dev-only: fix link for file:../.. installs
77
78
  just schemagen
78
79
 
79
80
  # Run unit tests (after check)
80
81
  test: check
81
82
  bun test .
82
83
 
83
- # Bump version, build, publish release
84
+ # Bump version and publish a source-only release
84
85
  release *ARGS:
85
86
  bun scripts/release.ts {{ARGS}}
86
87
 
@@ -10,7 +10,8 @@
10
10
  },
11
11
  "scripts": {
12
12
  "biome": "biome",
13
- "start": "bun run src/index.ts"
13
+ "prestart": "bun install --frozen-lockfile 1>&2 && bun run argsbarg schemagen 1>&2",
14
+ "start": "bun src/index.ts mcp"
14
15
  },
15
16
  "dependencies": {
16
17
  "argsbarg": "file:../.."
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
  /*
3
- Bump version, build standalone Node MCP server, and publish release tag.
3
+ Bump version and publish a source-only Bun plugin release tag.
4
4
  */
5
5
 
6
6
  import * as fs from "node:fs";
@@ -76,27 +76,26 @@ async function runRelease(
76
76
  /** Parsed CLI options. */
77
77
  options: ReleaseOptions,
78
78
  ): Promise<void> {
79
+ const currentVersion = readCurrentVersion();
80
+ const newVersion = applyBump(currentVersion, bump);
81
+ if (options.dryRun) {
82
+ console.log(
83
+ `[dry-run] Would run checks, bump ${currentVersion} to ${newVersion}, update the changelog, regenerate docs, commit, tag v${newVersion}, push, and create a GitHub release.`,
84
+ );
85
+ return;
86
+ }
87
+
79
88
  const testResult = await $`just test`.nothrow();
80
89
  if (testResult.exitCode !== 0) process.exit(testResult.exitCode);
81
90
 
82
- const currentVersion = readCurrentVersion();
83
- const newVersion = applyBump(currentVersion, bump);
84
91
  console.log(`Releasing ${currentVersion} → ${newVersion}`);
85
92
 
86
93
  updateVersion(newVersion);
87
94
  updateChangelog(newVersion);
88
95
 
89
- const buildResult = await $`just build`.nothrow();
90
- if (buildResult.exitCode !== 0) process.exit(buildResult.exitCode);
91
-
92
96
  const docgenResult = await $`just docgen`.nothrow();
93
97
  if (docgenResult.exitCode !== 0) process.exit(docgenResult.exitCode);
94
98
 
95
- if (options.dryRun) {
96
- console.log(`[dry-run] Would commit, tag v${newVersion}, and create GitHub release.`);
97
- return;
98
- }
99
-
100
99
  await commitAndTag(newVersion);
101
100
  await createGithubRelease(`v${newVersion}`);
102
101
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "argsbarg",
3
- "version": "7.1.2",
3
+ "version": "7.1.3",
4
4
  "main": "./src/index.ts",
5
5
  "module": "./src/index.ts",
6
6
  "dependencies": {
@@ -10,6 +10,7 @@ import {
10
10
  applyCreate,
11
11
  type CreateOptions,
12
12
  classNameFromKey,
13
+ DEV_ONLY_MARKER,
13
14
  diffCreate,
14
15
  diffCreateDetails,
15
16
  renderCreateTree,
@@ -38,6 +39,19 @@ function baseOpts(overrides: Partial<CreateOptions> = {}): CreateOptions {
38
39
 
39
40
  /** Tests for argsbarg create. */
40
41
  describe("argsbarg create", () => {
42
+ test("in-repo example templates match their own create output", () => {
43
+ for (const example of ["full-example", "full-example-json", "mcp-plugin"]) {
44
+ const dir = join(import.meta.dir, "../../examples", example);
45
+ expect({ example, drift: diffCreate(dir, { check: true }) }).toEqual({ example, drift: [] });
46
+ }
47
+ });
48
+
49
+ test("drops argsbarg-dev-only lines outside the in-repo template", () => {
50
+ const content = `setup:\n bun install\n ln -sf a b ${DEV_ONLY_MARKER}: fix link\n just schemagen\n`;
51
+ expect(substituteTemplateContent(content, baseOpts())).toBe("setup:\n bun install\n just schemagen\n");
52
+ expect(substituteTemplateContent(content, baseOpts({ devTemplate: true }))).toBe(content);
53
+ });
54
+
41
55
  test("substitutes {key} tokens", () => {
42
56
  const out = substituteTemplateContent(
43
57
  "key={key} class={className} env={envPrefix}_API_TOKEN tap={tap} org={tapOrg}",
@@ -263,6 +263,12 @@ function tokenMap(opts: CreateOptions): Record<string, string> {
263
263
  };
264
264
  }
265
265
 
266
+ /**
267
+ * Trailing comment marking a template line that only makes sense inside the argsbarg repo (e.g. the
268
+ * `.bin/argsbarg` symlink fix for `file:../..` installs). `create` drops these lines from new projects.
269
+ */
270
+ export const DEV_ONLY_MARKER = "# argsbarg-dev-only";
271
+
266
272
  /** Substitute \`{key}\`-style placeholders; also replace template identity literals. */
267
273
  export function substituteTemplateContent(content: string, opts: CreateOptions): string {
268
274
  const tmpl = templateIdentity(opts.templateId);
@@ -303,6 +309,9 @@ export function substituteTemplateContent(content: string, opts: CreateOptions):
303
309
 
304
310
  if (!opts.devTemplate) {
305
311
  out = out
312
+ .split("\n")
313
+ .filter((line) => !line.includes(DEV_ONLY_MARKER))
314
+ .join("\n")
306
315
  .replace(/"argsbarg":\s*"workspace:\*"/, `"argsbarg": "^${argsbargVersion}"`)
307
316
  .replace(/"argsbarg":\s*"file:\.\.\/\.\."/, `"argsbarg": "^${argsbargVersion}"`);
308
317
  }
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- /** Argsbarg package CLI (`bunx argsbarg`) — bootstrap and tooling; library API is `import from "argsbarg"`. */
2
+ /** Argsbarg package CLI (`bun x argsbarg`) — bootstrap and tooling; library API is `import from "argsbarg"`. */
3
3
 
4
4
  import { Cli } from "../index.ts";
5
5
  import { program } from "./program.ts";