argsbarg 2.1.1 → 3.1.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 +25 -1
- package/README.md +11 -7
- package/bun.lock +21 -0
- package/docs/ai-skills.md +7 -3
- package/docs/bundled-docs.md +77 -0
- package/docs/install.md +2 -2
- package/docs/mcp.md +18 -13
- package/examples/mcp-test.ts +2 -2
- package/examples/minimal.ts +2 -0
- package/examples/nested.ts +9 -1
- package/examples/option-required.ts +2 -0
- package/index.d.ts +36 -7
- package/package.json +4 -1
- package/src/builtins/builtins.test.ts +8 -3
- package/src/builtins/dispatch.ts +35 -1
- package/src/builtins/export.ts +10 -1
- package/src/builtins/install.ts +2 -1
- package/src/builtins/presentation.ts +10 -1
- package/src/builtins/version.ts +10 -0
- package/src/capabilities.ts +7 -2
- package/src/docs/builtin.ts +58 -0
- package/src/docs/docs.test.ts +121 -0
- package/src/docs/mcp-guide.ts +118 -0
- package/src/docs/resolve.ts +88 -0
- package/src/index.test.ts +186 -123
- package/src/index.ts +2 -0
- package/src/install/index.ts +2 -1
- package/src/install/install.test.ts +2 -1
- package/src/install/paths.ts +2 -2
- package/src/install/plan.ts +3 -2
- package/src/install/uninstall.ts +2 -1
- package/src/invoke.ts +16 -4
- package/src/mcp/tools.ts +21 -24
- package/src/runtime.ts +6 -1
- package/src/schema.ts +1 -1
- package/src/skill/generate.ts +3 -36
- package/src/types.test.ts +3 -2
- package/src/types.ts +38 -7
- package/src/validate.ts +55 -3
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,28 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [3.1.0] - 2026-06-20
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **`docs` built-in** — opt in with `docs: { enabled: true, topics: { ... } }` on the program root. Bundled markdown topics on stdout (`myapp docs`, `myapp docs readme`, `myapp docs all`). Auto **`docs mcp`** guide when `docs` and `mcpServer` are both enabled. See [docs/bundled-docs.md](docs/bundled-docs.md).
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **Agent skills** — `SKILL.md` is shell-only (removed MCP setup, `mcp.json`, and `tools/call` content). Use `docs mcp` or MCP tools for agent execution guidance.
|
|
19
|
+
|
|
20
|
+
## [3.0.0] - 2026-06-20
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
|
|
24
|
+
- **`version` built-in** — `myapp version` prints `CliProgram.version` (always available; reserved command name).
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- **`CliProgram.version`** (required) — single source of truth for the `version` built-in and MCP `serverInfo.version`. Removed `mcpServer.version` and automatic `package.json` lookup.
|
|
29
|
+
- **MCP opt-in** — `mcpServer: { enabled: true }` enables MCP; omit `mcpServer` to disable. Empty `mcpServer: {}` is rejected at validation.
|
|
30
|
+
- **MCP identity from `key`** — removed `mcpServer.name`. MCP `serverInfo.name`, schema URI, and `mcp.json` entry keys use `sanitizeToolSegment(root.key)` (e.g. `nested.ts` → `nested_ts://schema`). Shell `command` stays the raw `key`.
|
|
31
|
+
|
|
10
32
|
## [2.1.1] - 2026-06-20
|
|
11
33
|
|
|
12
34
|
### Changed
|
|
@@ -186,7 +208,9 @@ const cli = { ... } satisfies CliProgram; // or : CliProgram
|
|
|
186
208
|
- 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`).
|
|
187
209
|
- Imports: use `CliPositional` where needed; replace `CliOptionDef` with `CliOption` or `CliPositional` as appropriate.
|
|
188
210
|
|
|
189
|
-
[Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/
|
|
211
|
+
[Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v3.1.0...HEAD
|
|
212
|
+
[3.1.0]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.1.0
|
|
213
|
+
[3.0.0]: https://github.com/bdombro/bun-argsbarg/releases/tag/v3.0.0
|
|
190
214
|
[2.1.1]: https://github.com/bdombro/bun-argsbarg/releases/tag/v2.1.1
|
|
191
215
|
[2.1.0]: https://github.com/bdombro/bun-argsbarg/releases/tag/v2.1.0
|
|
192
216
|
[2.0.1]: https://github.com/bdombro/bun-argsbarg/releases/tag/v2.0.1
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Why another CLI parser?
|
|
|
16
16
|
|
|
17
17
|
*Shell completions* — `completion bash`, `completion zsh`, and `completion fish` built-ins generate installable scripts from your schema so users get tab completion for commands, flags, and positionals without extra tooling.
|
|
18
18
|
|
|
19
|
-
*Optional MCP server* — set `mcpServer: {}` on the program root to expose leaf commands as MCP tools and the full CLI tree as a schema resource (`myapp mcp` over stdio). See [docs/mcp.md](docs/mcp.md). Compiled binaries can install binary, completions, skills, and MCP config with `myapp install` — see [docs/install.md](docs/install.md).
|
|
19
|
+
*Optional MCP server* — set `mcpServer: { enabled: true }` on the program root to expose leaf commands as MCP tools and the full CLI tree as a schema resource (`myapp mcp` over stdio). See [docs/mcp.md](docs/mcp.md). Compiled binaries can install binary, completions, skills, and MCP config with `myapp install` — see [docs/install.md](docs/install.md).
|
|
20
20
|
|
|
21
21
|
*Bun-optimized* — built from the ground up for Bun and TypeScript, leveraging Bun’s performance and modern JavaScript features without any extra dependencies.
|
|
22
22
|
|
|
@@ -39,6 +39,7 @@ import { cliRun, type CliProgram, CliOptionKind } from "argsbarg";
|
|
|
39
39
|
|
|
40
40
|
const cli = {
|
|
41
41
|
key: "helloapp",
|
|
42
|
+
version: "1.0.0",
|
|
42
43
|
description: "Tiny demo.",
|
|
43
44
|
positionals: [
|
|
44
45
|
{
|
|
@@ -96,17 +97,20 @@ Every app gets:
|
|
|
96
97
|
- `-h` / `--help` at any routing depth (scoped help).
|
|
97
98
|
- **`--schema`** at the program root — print the full command tree as JSON (for tooling and agents).
|
|
98
99
|
- **`completion bash` / `completion zsh` / `completion fish`** — print shell completion scripts to stdout (injected by `cliRun`).
|
|
99
|
-
- **`
|
|
100
|
+
- **`version`** — print `CliProgram.version` (`myapp version`).
|
|
101
|
+
- **`mcp`** — when `mcpServer.enabled` is `true`, run as an MCP stdio server (`myapp mcp`).
|
|
102
|
+
- **`docs`** — when `docs.enabled` is `true`, print bundled markdown topics (`myapp docs`, `myapp docs readme`, …). See [docs/bundled-docs.md](docs/bundled-docs.md).
|
|
100
103
|
- **`install`** — install the binary, completions, skills, and MCP config to the user environment (`myapp install --all --yes`). See [docs/install.md](docs/install.md).
|
|
101
104
|
|
|
102
|
-
Do not declare a top-level command named **`completion
|
|
103
|
-
When **`mcpServer`** is
|
|
105
|
+
Do not declare a top-level command named **`completion`**, **`version`**, or **`install`** — they are reserved.
|
|
106
|
+
When **`mcpServer.enabled`** is `true`, do not declare a top-level command named **`mcp`** — it is reserved for the MCP built-in.
|
|
107
|
+
When **`docs.enabled`** is `true`, do not declare a top-level command named **`docs`** — it is reserved for the docs built-in.
|
|
104
108
|
Do not declare an option named **`schema`** — it is reserved for `--schema`.
|
|
105
109
|
|
|
106
110
|
|
|
107
111
|
### MCP (AI agents)
|
|
108
112
|
|
|
109
|
-
Opt in on the program root with `mcpServer: {
|
|
113
|
+
Opt in on the program root with `mcpServer: { enabled: true }`, then run `myapp mcp` for a stdio MCP server. Each leaf command becomes a tool; the CLI tree is available as resource `<sanitized-key>://schema` (same as `myapp --schema`). Handlers can read `ctx.invocation` and use `cliInvoke` for headless testing.
|
|
110
114
|
|
|
111
115
|
See **[docs/mcp.md](docs/mcp.md)** for configuration, env bootstrapping, custom resources, Cursor setup, and protocol details.
|
|
112
116
|
|
|
@@ -185,7 +189,7 @@ Add `CliPositional` entries to the command’s `positionals` list (separate from
|
|
|
185
189
|
|
|
186
190
|
### Capabilities (built-ins)
|
|
187
191
|
|
|
188
|
-
`completion`, `install`, and `mcp` are not part of your schema — they are injected at runtime from program-level config (`mcpServer`, `install`). Reserved command names
|
|
192
|
+
`completion`, `version`, `install`, and `mcp` are not part of your schema — they are injected at runtime from program-level config (`mcpServer`, `install`). Reserved command names: `completion` and `version` always; `install` unless `install.enabled: false`; `mcp` when `mcpServer.enabled` is `true`.
|
|
189
193
|
|
|
190
194
|
|
|
191
195
|
|
|
@@ -226,7 +230,7 @@ The package root (`argsbarg` / `src/index.ts`) exports the types and runtime you
|
|
|
226
230
|
| `cliInvoke(root, argv)` | Parse and dispatch without exiting; returns captured stdout/stderr. |
|
|
227
231
|
| `cliErrWithHelp(ctx, msg)` | Print error + scoped help on stderr, exit 1. |
|
|
228
232
|
|
|
229
|
-
Reserved identifiers (validated at startup): root commands **`completion`**, **`install`**, and **`mcp`** (
|
|
233
|
+
Reserved identifiers (validated at startup): root commands **`completion`**, **`version`**, **`install`**, **`docs`** (when `docs.enabled` is `true`), and **`mcp`** (when `mcpServer.enabled` is `true`).
|
|
230
234
|
|
|
231
235
|
---
|
|
232
236
|
|
package/bun.lock
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 1,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"name": "argsbarg",
|
|
7
|
+
"devDependencies": {
|
|
8
|
+
"@types/bun": "^1.3.12",
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
},
|
|
12
|
+
"packages": {
|
|
13
|
+
"@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
|
|
14
|
+
|
|
15
|
+
"@types/node": ["@types/node@26.0.0", "", { "dependencies": { "undici-types": "~8.3.0" } }, "sha512-vf2YFi1iY9lHGwNJMs01biZFbKJkrZR1T6/MlzjhJLPdntOHLhTrDSnSVcdtvjihi4VQNlrFRIxLsDBlQpAipA=="],
|
|
16
|
+
|
|
17
|
+
"bun-types": ["bun-types@1.3.14", "", { "dependencies": { "@types/node": "*" } }, "sha512-4N0ig0fEomHt5R0KCFWjovxow98rIoRwKolrYdCcknNwMekCXRnWEUvgu5soYV8QXtVsrUD8B95MBOZGPvr6KQ=="],
|
|
18
|
+
|
|
19
|
+
"undici-types": ["undici-types@8.3.0", "", {}, "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ=="],
|
|
20
|
+
}
|
|
21
|
+
}
|
package/docs/ai-skills.md
CHANGED
|
@@ -31,17 +31,21 @@ 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, command catalog,
|
|
34
|
+
- **`SKILL.md`** — YAML frontmatter, when-to-use guidance, shell command catalog, pitfalls
|
|
35
35
|
- **`reference.md`** — full `--schema` JSON export
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
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
|
+
|
|
39
|
+
## MCP vs skills vs docs
|
|
38
40
|
|
|
39
41
|
| Mechanism | Role |
|
|
40
42
|
| --- | --- |
|
|
41
43
|
| **`myapp mcp`** (requires `mcpServer`) | Runtime tool execution over MCP |
|
|
42
|
-
| **`myapp install --skill`** | Static
|
|
44
|
+
| **`myapp install --skill`** | Static shell command catalog for agents |
|
|
45
|
+
| **`myapp docs`** (requires `docs`) | Bundled markdown on stdout (`docs mcp` when MCP enabled) |
|
|
43
46
|
|
|
44
47
|
See also:
|
|
45
48
|
|
|
49
|
+
- [Bundled docs](bundled-docs.md) — `docs` config and compile-time imports
|
|
46
50
|
- [MCP server](mcp.md) — `mcpServer` config and `mcp` protocol
|
|
47
51
|
- [Install](install.md) — binary, completions, skills, and MCP config
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Bundled documentation (`docs`)
|
|
2
|
+
|
|
3
|
+
ArgsBarg can expose bundled markdown topics as the built-in `docs` command group. Opt in on the program root with `docs: { enabled: true, topics: { ... } }`.
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
```typescript
|
|
8
|
+
import readmeText from "../README.md" with { type: "text" };
|
|
9
|
+
import archText from "../docs/architecture.md" with { type: "text" };
|
|
10
|
+
|
|
11
|
+
const cli = {
|
|
12
|
+
key: "myapp",
|
|
13
|
+
version: "1.0.0",
|
|
14
|
+
description: "My app.",
|
|
15
|
+
docs: {
|
|
16
|
+
enabled: true,
|
|
17
|
+
topics: {
|
|
18
|
+
readme: { text: readmeText },
|
|
19
|
+
architecture: { text: archText, description: "Contributor architecture notes." },
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
commands: [/* ... */],
|
|
23
|
+
} satisfies CliProgram;
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
myapp docs # first topic (readme) via fallback
|
|
28
|
+
myapp docs readme
|
|
29
|
+
myapp docs architecture
|
|
30
|
+
myapp docs all # all user topics; includes auto mcp when MCP enabled
|
|
31
|
+
myapp docs mcp # auto-generated when mcpServer.enabled
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Configuration
|
|
35
|
+
|
|
36
|
+
| Field | Default | Purpose |
|
|
37
|
+
| --- | --- | --- |
|
|
38
|
+
| `enabled` | *(required)* | Must be `true` when `docs` is set |
|
|
39
|
+
| `description` | `"Print bundled CLI documentation."` | Router help for `myapp docs` |
|
|
40
|
+
| `defaultTopic` | first key in `topics` | `fallbackCommand` for bare `myapp docs` |
|
|
41
|
+
| `topics` | *(required)* | Topic key → `{ text, description? }` |
|
|
42
|
+
|
|
43
|
+
Reserved topic keys in `topics`: **`mcp`**, **`all`** (supplied by the built-in).
|
|
44
|
+
|
|
45
|
+
When `description` is omitted on a topic, ArgsBarg generates leaf help (`readme` → "Print README (user guide).").
|
|
46
|
+
|
|
47
|
+
## Compile-time bundling
|
|
48
|
+
|
|
49
|
+
Topic `text` must be **bundled markdown strings**. Use Bun text imports in the consumer module graph:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
import readmeText from "../README.md" with { type: "text" };
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Bun embeds the file when you `bun build --compile`. ArgsBarg does not read the filesystem at runtime.
|
|
56
|
+
|
|
57
|
+
For several topics, use a barrel file (e.g. `src/docs/topics.ts`) so `index.tsx` stays small.
|
|
58
|
+
|
|
59
|
+
## MCP guide (`docs mcp`)
|
|
60
|
+
|
|
61
|
+
When both `docs.enabled` and `mcpServer.enabled` are `true`, ArgsBarg injects a **`docs mcp`** topic with an auto-generated guide: tool list, `requiresEnv`, schema resource URI, `install --mcp`, and protocol notes.
|
|
62
|
+
|
|
63
|
+
There is no override API in v1 — customize behavior via `mcpTool.description` on leaf commands.
|
|
64
|
+
|
|
65
|
+
## MCP tools
|
|
66
|
+
|
|
67
|
+
All `docs` subcommands are hidden from MCP `tools/list` (`mcpTool: { enabled: false }`).
|
|
68
|
+
|
|
69
|
+
## Skills vs docs vs MCP
|
|
70
|
+
|
|
71
|
+
| Channel | Role |
|
|
72
|
+
| --- | --- |
|
|
73
|
+
| `install --skill` | Shell command catalog + `--schema` JSON (no MCP setup) |
|
|
74
|
+
| `docs` | Bundled markdown on stdout |
|
|
75
|
+
| `mcp` | Callable tools + schema resource |
|
|
76
|
+
|
|
77
|
+
Do not declare a top-level command named **`docs`** when `docs.enabled` is `true` — it is reserved.
|
package/docs/install.md
CHANGED
|
@@ -30,7 +30,7 @@ myapp install --uninstall --yes
|
|
|
30
30
|
| Claude skill | `--skill` | `~/.claude/skills/<dir>/` when `~/.claude` exists |
|
|
31
31
|
| MCP config | `--mcp` | `~/.cursor/mcp.json` and `~/.claude.json` when MCP is enabled |
|
|
32
32
|
|
|
33
|
-
`--all` expands to `--bin`, `--completions`, `--skill`, and `--mcp` (when `mcpServer` is
|
|
33
|
+
`--all` expands to `--bin`, `--completions`, `--skill`, and `--mcp` (when `mcpServer.enabled` is `true`).
|
|
34
34
|
|
|
35
35
|
Shells not on PATH are skipped silently (no warnings).
|
|
36
36
|
|
|
@@ -64,7 +64,7 @@ Environment:
|
|
|
64
64
|
|
|
65
65
|
## MCP merge behavior
|
|
66
66
|
|
|
67
|
-
When `--mcp` runs, entries are merged into `mcpServers[<
|
|
67
|
+
When `--mcp` runs, entries are merged into `mcpServers[<sanitized-key>]` with:
|
|
68
68
|
|
|
69
69
|
```json
|
|
70
70
|
{ "command": "<root.key>", "args": ["mcp"] }
|
package/docs/mcp.md
CHANGED
|
@@ -9,15 +9,18 @@ MCP is **opt-in**. Apps that do not set `mcpServer` on the program root behave e
|
|
|
9
9
|
1. Add `mcpServer` to your program root:
|
|
10
10
|
|
|
11
11
|
```typescript
|
|
12
|
+
import pkg from "../package.json" with { type: "json" };
|
|
13
|
+
|
|
12
14
|
const cli = {
|
|
13
15
|
key: "myapp",
|
|
16
|
+
version: pkg.version,
|
|
14
17
|
description: "My app.",
|
|
15
|
-
mcpServer: {
|
|
18
|
+
mcpServer: { enabled: true },
|
|
16
19
|
commands: [/* ... */],
|
|
17
20
|
} satisfies CliProgram;
|
|
18
21
|
```
|
|
19
22
|
|
|
20
|
-
`mcpServer: {}`
|
|
23
|
+
`mcpServer: { enabled: true }` opts in. Omit `mcpServer` entirely to disable MCP. Empty `mcpServer: {}` is rejected at validation.
|
|
21
24
|
|
|
22
25
|
2. Run the MCP server:
|
|
23
26
|
|
|
@@ -66,26 +69,27 @@ Set `mcpServer` on the **program root only** (the `CliProgram` passed to `cliRun
|
|
|
66
69
|
|
|
67
70
|
| Field | Default | Purpose |
|
|
68
71
|
| --- | --- | --- |
|
|
69
|
-
| `
|
|
70
|
-
| `
|
|
71
|
-
| `schemaResourceUri` | `"argsbarg://schema"` | URI for the schema resource |
|
|
72
|
+
| `enabled` | *(required)* | Must be `true` when `mcpServer` is set |
|
|
73
|
+
| `schemaResourceUri` | `<sanitized root key>://schema` | URI for the built-in schema resource |
|
|
72
74
|
| `shellEnv` | off | Capture login-shell `env` at startup (`true` uses `$SHELL`, or pass a shell path) |
|
|
73
75
|
| `envFile` | off | Load a `.env` file after `shellEnv` (`~` supported); warns on stderr if missing |
|
|
74
|
-
| `resources` | `[]` | Custom `CliMcpResource` entries
|
|
76
|
+
| `resources` | `[]` | Custom `CliMcpResource` entries (additive; schema resource is always included) |
|
|
77
|
+
|
|
78
|
+
MCP `serverInfo.name` and the default schema URI use the sanitized program `key` (non-alphanumeric characters become `_`). Program `version` comes from `CliProgram.version` (also used by the `version` built-in).
|
|
75
79
|
|
|
76
|
-
Example with
|
|
80
|
+
Example with optional fields:
|
|
77
81
|
|
|
78
82
|
```typescript
|
|
79
83
|
mcpServer: {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
enabled: true,
|
|
85
|
+
shellEnv: true,
|
|
86
|
+
envFile: "~/.config/myapp/mcp.env",
|
|
83
87
|
}
|
|
84
88
|
```
|
|
85
89
|
|
|
86
90
|
## Tools
|
|
87
91
|
|
|
88
|
-
Every **user-defined leaf command** in your schema becomes one MCP tool. Built-ins (`completion`, `
|
|
92
|
+
Every **user-defined leaf command** in your schema becomes one MCP tool. Built-ins (`completion`, `version`, `install`, `mcp`) are not exposed as tools.
|
|
89
93
|
|
|
90
94
|
### Tool names
|
|
91
95
|
|
|
@@ -172,11 +176,11 @@ Help and `--schema` are not available through tool calls; use the schema resourc
|
|
|
172
176
|
|
|
173
177
|
## Schema and custom resources
|
|
174
178
|
|
|
175
|
-
The built-in resource
|
|
179
|
+
The built-in schema resource (default URI `<sanitized-key>://schema`, e.g. `nested.ts` → `nested_ts://schema`) exposes your full CLI tree as JSON — the same output as `myapp --schema`. Override with `schemaResourceUri` if needed.
|
|
176
180
|
|
|
177
181
|
| Property | Value |
|
|
178
182
|
| --- | --- |
|
|
179
|
-
| Default URI |
|
|
183
|
+
| Default URI | `<sanitized root key>://schema` |
|
|
180
184
|
| MIME type | `application/json` |
|
|
181
185
|
| Contents | `cliSchemaJson(root)` — handlers omitted, built-ins excluded |
|
|
182
186
|
|
|
@@ -184,6 +188,7 @@ Add custom resources on the program root:
|
|
|
184
188
|
|
|
185
189
|
```typescript
|
|
186
190
|
mcpServer: {
|
|
191
|
+
enabled: true,
|
|
187
192
|
resources: [
|
|
188
193
|
{
|
|
189
194
|
uri: "myapp://config",
|
package/examples/mcp-test.ts
CHANGED
|
@@ -9,10 +9,10 @@ const envFilePath = process.env.ARGS_TEST_ENV_FILE;
|
|
|
9
9
|
|
|
10
10
|
const cli = {
|
|
11
11
|
key: "mcp-test",
|
|
12
|
+
version: "0.0.0-test",
|
|
12
13
|
description: "MCP integration test fixture.",
|
|
13
14
|
mcpServer: {
|
|
14
|
-
|
|
15
|
-
version: "0.0.0-test",
|
|
15
|
+
enabled: true,
|
|
16
16
|
...(envFilePath ? { envFile: envFilePath } : {}),
|
|
17
17
|
resources: [
|
|
18
18
|
{
|
package/examples/minimal.ts
CHANGED
|
@@ -7,10 +7,12 @@ readers can copy the pattern into their own scripts quickly.
|
|
|
7
7
|
It demonstrates the minimal Bun integration path.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import pkg from "../package.json" with { type: "json" };
|
|
10
11
|
import { cliRun, CliProgram, CliOptionKind } from "../src/index.ts";
|
|
11
12
|
|
|
12
13
|
const cli = {
|
|
13
14
|
key: "minimal.ts",
|
|
15
|
+
version: pkg.version,
|
|
14
16
|
description: "Tiny demo.",
|
|
15
17
|
positionals: [
|
|
16
18
|
{
|
package/examples/nested.ts
CHANGED
|
@@ -7,12 +7,20 @@ and fallback commands fit together in one schema.
|
|
|
7
7
|
It demonstrates how the schema scales beyond one command.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import pkg from "../package.json" with { type: "json" };
|
|
10
11
|
import { cliRun, CliProgram, CliOptionKind, CliFallbackMode } from "../src/index.ts";
|
|
11
12
|
|
|
12
13
|
const cli = {
|
|
13
14
|
key: "nested.ts",
|
|
15
|
+
version: pkg.version,
|
|
14
16
|
description: "Nested groups demo.",
|
|
15
|
-
mcpServer: {
|
|
17
|
+
mcpServer: { enabled: true },
|
|
18
|
+
docs: {
|
|
19
|
+
enabled: true,
|
|
20
|
+
topics: {
|
|
21
|
+
readme: { text: "# nested.ts\n\nNested groups demo.\n" },
|
|
22
|
+
},
|
|
23
|
+
},
|
|
16
24
|
commands: [
|
|
17
25
|
{
|
|
18
26
|
key: "stat",
|
|
@@ -7,10 +7,12 @@ readers can copy the pattern into their own scripts quickly.
|
|
|
7
7
|
It demonstrates the minimal Bun integration path.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
+
import pkg from "../package.json" with { type: "json" };
|
|
10
11
|
import { cliRun, CliProgram, CliOptionKind, CliFallbackMode, isInteractiveTty } from "../src/index.ts";
|
|
11
12
|
|
|
12
13
|
const cli = {
|
|
13
14
|
key: "option-required.ts",
|
|
15
|
+
version: pkg.version,
|
|
14
16
|
description: "Demo of a required option.",
|
|
15
17
|
options: [
|
|
16
18
|
{
|
package/index.d.ts
CHANGED
|
@@ -106,13 +106,12 @@ export interface CliPositional {
|
|
|
106
106
|
}
|
|
107
107
|
/**
|
|
108
108
|
* Enables `myapp mcp` and MCP stdio server metadata (program root only).
|
|
109
|
+
* Must include `enabled: true`; omit `mcpServer` entirely to disable MCP.
|
|
109
110
|
*/
|
|
110
111
|
export interface CliMcpServerConfig {
|
|
111
|
-
/** `
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
version?: string;
|
|
115
|
-
/** Resource URI for schema export (default: `"argsbarg://schema"`). */
|
|
112
|
+
/** When `true`, enables the `mcp` built-in and MCP stdio server. */
|
|
113
|
+
enabled: boolean;
|
|
114
|
+
/** Resource URI for schema export (default: `<sanitized root key>://schema`). */
|
|
116
115
|
schemaResourceUri?: string;
|
|
117
116
|
/**
|
|
118
117
|
* Capture the user's login shell environment at MCP server start and merge it
|
|
@@ -127,7 +126,7 @@ export interface CliMcpServerConfig {
|
|
|
127
126
|
*/
|
|
128
127
|
envFile?: string;
|
|
129
128
|
/**
|
|
130
|
-
* Custom MCP resources exposed alongside the built-in
|
|
129
|
+
* Custom MCP resources exposed alongside the built-in schema resource.
|
|
131
130
|
* URIs must be unique and must not equal schemaResourceUri.
|
|
132
131
|
*/
|
|
133
132
|
resources?: CliMcpResource[];
|
|
@@ -174,6 +173,32 @@ export interface CliInstallConfig {
|
|
|
174
173
|
/** Default bin directory (default: `~/.local/bin`). Overridden by `INSTALL_PREFIX` env and `--prefix`. */
|
|
175
174
|
prefix?: string;
|
|
176
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* One bundled documentation topic for the `docs` built-in (program root only).
|
|
178
|
+
*/
|
|
179
|
+
export interface CliDocsTopic {
|
|
180
|
+
/** Bundled markdown (use compile-time text imports in the consumer). */
|
|
181
|
+
text: string;
|
|
182
|
+
/** Leaf help text for `myapp docs <key> -h`. Auto-generated from key when omitted. */
|
|
183
|
+
description?: string;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Enables `myapp docs` and bundled markdown topics (program root only).
|
|
187
|
+
* Must include `enabled: true`; omit `docs` entirely to disable.
|
|
188
|
+
*/
|
|
189
|
+
export interface CliDocsConfig {
|
|
190
|
+
/** When `true`, enables the `docs` built-in command group. */
|
|
191
|
+
enabled: boolean;
|
|
192
|
+
/** Router description for `myapp docs` (default: "Print bundled CLI documentation."). */
|
|
193
|
+
description?: string;
|
|
194
|
+
/**
|
|
195
|
+
* Subcommand for bare `myapp docs` (maps to router `fallbackCommand`).
|
|
196
|
+
* When omitted, uses the first key in `topics` (insertion order).
|
|
197
|
+
*/
|
|
198
|
+
defaultTopic?: string;
|
|
199
|
+
/** Topic key → bundled markdown. Reserved keys: `mcp`, `all` (supplied by the built-in). */
|
|
200
|
+
topics: Record<string, CliDocsTopic>;
|
|
201
|
+
}
|
|
177
202
|
/**
|
|
178
203
|
* Base properties shared by all nodes in the user command tree.
|
|
179
204
|
*/
|
|
@@ -218,10 +243,14 @@ export type CliNode = CliLeaf | CliRouter;
|
|
|
218
243
|
* May be a leaf or router, plus optional program-level MCP and install config.
|
|
219
244
|
*/
|
|
220
245
|
export type CliProgram = CliNode & {
|
|
221
|
-
/**
|
|
246
|
+
/** Program version (printed by the `version` built-in and MCP serverInfo). */
|
|
247
|
+
version: string;
|
|
248
|
+
/** When set with `enabled: true`, enables the `mcp` built-in subcommand. */
|
|
222
249
|
mcpServer?: CliMcpServerConfig;
|
|
223
250
|
/** Opt-out and defaults for `install`. */
|
|
224
251
|
install?: CliInstallConfig;
|
|
252
|
+
/** When set with `enabled: true`, enables the `docs` built-in command group. */
|
|
253
|
+
docs?: CliDocsConfig;
|
|
225
254
|
};
|
|
226
255
|
/**
|
|
227
256
|
* Handler closure type for leaf commands.
|
package/package.json
CHANGED
|
@@ -8,8 +8,9 @@ import { CliProgram } from "../types.ts";
|
|
|
8
8
|
|
|
9
9
|
const fixture: CliProgram = {
|
|
10
10
|
key: "myapp",
|
|
11
|
+
version: "0.0.0",
|
|
11
12
|
description: "Demo app.",
|
|
12
|
-
mcpServer: {
|
|
13
|
+
mcpServer: { enabled: true },
|
|
13
14
|
commands: [
|
|
14
15
|
{
|
|
15
16
|
key: "hello",
|
|
@@ -31,7 +32,7 @@ describe("builtins help copy", () => {
|
|
|
31
32
|
});
|
|
32
33
|
|
|
33
34
|
test("install omits --mcp option when mcpServer unset", () => {
|
|
34
|
-
const noMcp: CliProgram = { key: "x", description: "x", handler: () => {} };
|
|
35
|
+
const noMcp: CliProgram = { key: "x", version: "0.0.0", description: "x", handler: () => {} };
|
|
35
36
|
const names = installBuiltinOptions(noMcp).map((o) => o.name);
|
|
36
37
|
expect(names).not.toContain("mcp");
|
|
37
38
|
});
|
|
@@ -56,6 +57,10 @@ describe("presentation root", () => {
|
|
|
56
57
|
const root = cliPresentationRoot(disabled);
|
|
57
58
|
expect(root.commands?.map((c) => c.key)).not.toContain("install");
|
|
58
59
|
});
|
|
60
|
+
test("includes version builtin", () => {
|
|
61
|
+
const root = cliPresentationRoot(fixture);
|
|
62
|
+
expect(root.commands?.map((c) => c.key)).toContain("version");
|
|
63
|
+
});
|
|
59
64
|
});
|
|
60
65
|
|
|
61
66
|
describe("completion emitters", () => {
|
|
@@ -75,7 +80,7 @@ describe("completion emitters", () => {
|
|
|
75
80
|
});
|
|
76
81
|
|
|
77
82
|
test("zsh script registers compdef", () => {
|
|
78
|
-
const schema = cliPresentationRoot({ key: "zapp", description: "z", handler: () => {} });
|
|
83
|
+
const schema = cliPresentationRoot({ key: "zapp", version: "0.0.0", description: "z", handler: () => {} });
|
|
79
84
|
const zsh = completionZshScript(schema);
|
|
80
85
|
expect(zsh).toContain("#compdef zapp");
|
|
81
86
|
expect(zsh).toContain("compdef _zapp zapp");
|
package/src/builtins/dispatch.ts
CHANGED
|
@@ -6,8 +6,10 @@ import { completionFishScript } from "./completion-fish.ts";
|
|
|
6
6
|
import { completionZshScript } from "./completion-zsh.ts";
|
|
7
7
|
import { cliBuiltinInstallCommand } from "./install.ts";
|
|
8
8
|
import { cliBuiltinMcpCommand } from "./mcp.ts";
|
|
9
|
+
import { cliBuiltinVersionCommand } from "./version.ts";
|
|
9
10
|
import { cliBuiltinCompletionGroup as completionGroup } from "./completion-group.ts";
|
|
10
11
|
import { cliPresentationRoot } from "./presentation.ts";
|
|
12
|
+
import { cliBuiltinDocsGroupIfEnabled } from "../docs/builtin.ts";
|
|
11
13
|
import { cliMcpServeStdio } from "../mcp.ts";
|
|
12
14
|
import { cliInstall } from "../install/index.ts";
|
|
13
15
|
import type { ParseResult } from "../parse.ts";
|
|
@@ -56,9 +58,18 @@ export async function dispatchBuiltin(
|
|
|
56
58
|
return;
|
|
57
59
|
}
|
|
58
60
|
|
|
61
|
+
if (pr.path[0] === "version") {
|
|
62
|
+
if (pr.path.length !== 1) {
|
|
63
|
+
process.stderr.write("Unknown subcommand: version " + pr.path.slice(1).join(" ") + "\n");
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
process.stdout.write(program.version + "\n");
|
|
67
|
+
process.exit(0);
|
|
68
|
+
}
|
|
69
|
+
|
|
59
70
|
if (pr.path[0] === "mcp") {
|
|
60
71
|
if (!caps.mcp) {
|
|
61
|
-
process.stderr.write("MCP is not enabled. Set mcpServer on the program root.\n");
|
|
72
|
+
process.stderr.write("MCP is not enabled. Set mcpServer: { enabled: true } on the program root.\n");
|
|
62
73
|
process.exit(1);
|
|
63
74
|
}
|
|
64
75
|
if (pr.path.length !== 1) {
|
|
@@ -127,5 +138,28 @@ export function builtinInterceptRoot(
|
|
|
127
138
|
};
|
|
128
139
|
}
|
|
129
140
|
|
|
141
|
+
if (first === "version") {
|
|
142
|
+
return {
|
|
143
|
+
parseRoot: {
|
|
144
|
+
key: program.key,
|
|
145
|
+
description: program.description,
|
|
146
|
+
commands: [cliBuiltinVersionCommand()],
|
|
147
|
+
},
|
|
148
|
+
isLeafCompletionIntercept: false,
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const docsGroup = cliBuiltinDocsGroupIfEnabled(program);
|
|
153
|
+
if (first === "docs" && docsGroup) {
|
|
154
|
+
return {
|
|
155
|
+
parseRoot: {
|
|
156
|
+
key: program.key,
|
|
157
|
+
description: program.description,
|
|
158
|
+
commands: [docsGroup],
|
|
159
|
+
},
|
|
160
|
+
isLeafCompletionIntercept: false,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
130
164
|
return { parseRoot: program, isLeafCompletionIntercept: false };
|
|
131
165
|
}
|
package/src/builtins/export.ts
CHANGED
|
@@ -3,6 +3,8 @@ import type { CliFallbackMode, CliOption, CliPositional, CliProgram } from "../t
|
|
|
3
3
|
import { cliBuiltinCompletionGroup } from "./completion-group.ts";
|
|
4
4
|
import { cliBuiltinInstallCommand } from "./install.ts";
|
|
5
5
|
import { cliBuiltinMcpCommand } from "./mcp.ts";
|
|
6
|
+
import { cliBuiltinVersionCommand } from "./version.ts";
|
|
7
|
+
import { cliBuiltinDocsGroupIfEnabled } from "../docs/builtin.ts";
|
|
6
8
|
|
|
7
9
|
/** JSON-safe command node (no handlers). */
|
|
8
10
|
export interface CliSchemaExport {
|
|
@@ -42,10 +44,17 @@ function exportBuiltinNode(cmd: {
|
|
|
42
44
|
/** Built-in subtrees matching help visibility for `--schema` export. */
|
|
43
45
|
export function exportPresentationBuiltins(program: CliProgram, caps?: CliCapabilities): CliSchemaExport[] {
|
|
44
46
|
const resolved = caps ?? resolveCapabilities(program);
|
|
45
|
-
const builtins: CliSchemaExport[] = [
|
|
47
|
+
const builtins: CliSchemaExport[] = [
|
|
48
|
+
exportBuiltinNode(cliBuiltinCompletionGroup(program.key)),
|
|
49
|
+
exportBuiltinNode(cliBuiltinVersionCommand()),
|
|
50
|
+
];
|
|
46
51
|
if (resolved.install) {
|
|
47
52
|
builtins.push(exportBuiltinNode(cliBuiltinInstallCommand(program)));
|
|
48
53
|
}
|
|
54
|
+
const docsGroup = cliBuiltinDocsGroupIfEnabled(program);
|
|
55
|
+
if (docsGroup) {
|
|
56
|
+
builtins.push(exportBuiltinNode(docsGroup));
|
|
57
|
+
}
|
|
49
58
|
if (resolved.mcp) {
|
|
50
59
|
builtins.push(exportBuiltinNode(cliBuiltinMcpCommand()));
|
|
51
60
|
}
|
package/src/builtins/install.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { resolveCapabilities } from "../capabilities.ts";
|
|
1
2
|
import { CliProgram, CliOption, CliOptionKind, type CliLeaf } from "../types.ts";
|
|
2
3
|
|
|
3
4
|
/** Install command options (dynamic: `--mcp` only when MCP is enabled). */
|
|
@@ -66,7 +67,7 @@ export function installBuiltinOptions(root: CliProgram): CliOption[] {
|
|
|
66
67
|
},
|
|
67
68
|
];
|
|
68
69
|
|
|
69
|
-
if (root.
|
|
70
|
+
if (resolveCapabilities(root).mcp) {
|
|
70
71
|
opts.splice(4, 0, {
|
|
71
72
|
name: "mcp",
|
|
72
73
|
description: "Add or update MCP server entries in Cursor and Claude config files.",
|
|
@@ -5,13 +5,22 @@ import { isCliLeaf, isCliRouter } from "../types.ts";
|
|
|
5
5
|
import { cliBuiltinCompletionGroup } from "./completion-group.ts";
|
|
6
6
|
import { cliBuiltinInstallCommand } from "./install.ts";
|
|
7
7
|
import { cliBuiltinMcpCommand } from "./mcp.ts";
|
|
8
|
+
import { cliBuiltinVersionCommand } from "./version.ts";
|
|
9
|
+
import { cliBuiltinDocsGroupIfEnabled } from "../docs/builtin.ts";
|
|
8
10
|
|
|
9
11
|
/** Built-in command nodes injected for help, schema, and completions. */
|
|
10
12
|
export function presentationBuiltins(program: CliProgram, caps: CliCapabilities): CliNode[] {
|
|
11
|
-
const builtins: CliNode[] = [
|
|
13
|
+
const builtins: CliNode[] = [
|
|
14
|
+
cliBuiltinCompletionGroup(program.key),
|
|
15
|
+
cliBuiltinVersionCommand(),
|
|
16
|
+
];
|
|
12
17
|
if (caps.install) {
|
|
13
18
|
builtins.push(cliBuiltinInstallCommand(program));
|
|
14
19
|
}
|
|
20
|
+
const docsGroup = cliBuiltinDocsGroupIfEnabled(program);
|
|
21
|
+
if (docsGroup) {
|
|
22
|
+
builtins.push(docsGroup);
|
|
23
|
+
}
|
|
15
24
|
if (caps.mcp) {
|
|
16
25
|
builtins.push(cliBuiltinMcpCommand());
|
|
17
26
|
}
|