argsbarg 4.0.3 → 4.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.
Files changed (99) hide show
  1. package/CHANGELOG.md +42 -1
  2. package/README.md +6 -6
  3. package/docs/ai-skills.md +9 -4
  4. package/docs/bundled-docs.md +1 -0
  5. package/docs/cli-program.md +4 -4
  6. package/docs/config-schema.md +1 -4
  7. package/docs/developing.md +1 -1
  8. package/docs/install.md +160 -39
  9. package/docs/mcp.md +38 -11
  10. package/docs/templates/cursor/rules/cli-program.mdc +1 -1
  11. package/examples/config-app/program.ts +0 -3
  12. package/examples/consumer-app/README.md +1 -1
  13. package/examples/consumer-app/src/program.ts +5 -13
  14. package/examples/mcp-test.ts +14 -24
  15. package/index.d.ts +60 -5
  16. package/package.json +1 -1
  17. package/src/builtins/builtins.test.ts +20 -4
  18. package/src/builtins/config.test.ts +31 -25
  19. package/src/builtins/config.ts +4 -3
  20. package/src/builtins/install.ts +50 -57
  21. package/src/builtins/mcp.ts +1 -1
  22. package/src/capabilities.ts +4 -4
  23. package/src/cli.ts +2 -0
  24. package/src/config/bootstrap.ts +167 -66
  25. package/src/config/context.test.ts +22 -36
  26. package/src/config/context.ts +5 -4
  27. package/src/config/file.test.ts +66 -56
  28. package/src/config/file.ts +33 -25
  29. package/src/config/resolve.test.ts +25 -1
  30. package/src/config/resolve.ts +43 -8
  31. package/src/config.integration.test.ts +17 -10
  32. package/src/docs/api-guide.test.ts +1 -1
  33. package/src/docs/docs.test.ts +1 -1
  34. package/src/docs/mcp-guide.ts +15 -4
  35. package/src/docs/mcp-resources.test.ts +63 -0
  36. package/src/docs/mcp-resources.ts +68 -0
  37. package/src/hidden-mcpb.test.ts +41 -1
  38. package/src/index.ts +4 -0
  39. package/src/install/{binary.ts → app.ts} +13 -13
  40. package/src/install/bootstrap.ts +22 -0
  41. package/src/install/detect-installed.ts +2 -97
  42. package/src/install/index.ts +187 -110
  43. package/src/install/install-validate.test.ts +61 -0
  44. package/src/install/install.test.ts +138 -42
  45. package/src/install/mcp-openclaw.test.ts +40 -0
  46. package/src/install/mcp-openclaw.ts +106 -0
  47. package/src/install/normalize.ts +35 -0
  48. package/src/install/paths.ts +27 -13
  49. package/src/install/plan.ts +30 -259
  50. package/src/install/shell.ts +2 -2
  51. package/src/install/status.test.ts +85 -0
  52. package/src/install/status.ts +22 -9
  53. package/src/install/target-base.ts +93 -0
  54. package/src/install/target-detect.ts +20 -0
  55. package/src/install/target-effective.ts +131 -0
  56. package/src/install/target-mcp-cli.ts +149 -0
  57. package/src/install/target-mcp-json.ts +130 -0
  58. package/src/install/target-plan-build.ts +67 -0
  59. package/src/install/target-registry.ts +57 -0
  60. package/src/install/target-scope.ts +266 -0
  61. package/src/install/target-skill.ts +104 -0
  62. package/src/install/target-types.ts +145 -0
  63. package/src/install/targets/app.ts +69 -0
  64. package/src/install/targets/chatgpt-mcp.ts +12 -0
  65. package/src/install/targets/claude-code-mcp.ts +15 -0
  66. package/src/install/targets/claude-desktop-mcp.ts +12 -0
  67. package/src/install/targets/claude-skill.ts +16 -0
  68. package/src/install/targets/codex-mcp.ts +25 -0
  69. package/src/install/targets/codex-skill.ts +14 -0
  70. package/src/install/targets/completions.ts +133 -0
  71. package/src/install/targets/configure.ts +59 -0
  72. package/src/install/targets/cursor-mcp.ts +15 -0
  73. package/src/install/targets/cursor-skill.ts +16 -0
  74. package/src/install/targets/index.ts +53 -0
  75. package/src/install/targets/openclaw-mcp.ts +25 -0
  76. package/src/install/targets/openclaw-skill.ts +17 -0
  77. package/src/install/targets/opencode-mcp.ts +101 -0
  78. package/src/install/targets/opencode-skill.ts +15 -0
  79. package/src/install/targets.test.ts +136 -0
  80. package/src/install/uninstall.ts +16 -152
  81. package/src/install/update.test.ts +17 -2
  82. package/src/install/update.ts +2 -5
  83. package/src/invoke.test.ts +7 -1
  84. package/src/mcp/bundle.ts +16 -4
  85. package/src/mcp/claude.test.ts +23 -4
  86. package/src/mcp/claude.ts +18 -13
  87. package/src/mcp/tools.ts +4 -1
  88. package/src/mcp/zip.test.ts +17 -0
  89. package/src/mcp/zip.ts +62 -9
  90. package/src/mcp.integration.test.ts +18 -1
  91. package/src/parse.test.ts +57 -4
  92. package/src/paths/host.ts +11 -11
  93. package/src/paths/remove-empty-dir.ts +13 -0
  94. package/src/skill/generate.ts +89 -5
  95. package/src/skill/hint.ts +5 -0
  96. package/src/skill/install.ts +33 -6
  97. package/src/skill/naming.ts +28 -0
  98. package/src/types.ts +65 -4
  99. package/src/validate.ts +79 -4
package/CHANGELOG.md CHANGED
@@ -7,6 +7,45 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [4.1.0] - 2026-07-01
11
+
12
+ ### Added
13
+
14
+ - **Install bootstrap** — bare `myapp` (empty argv, TTY, binary not on PATH) rewrites to `myapp install`.
15
+ - **Interactive install banner** — TTY install/uninstall prints `{app} Setup` before the numbered plan; config wizard uses `Configuration Setup`.
16
+ - **Config file** — path is `~/.local/lib/<sanitized-key>/config.json`. Configure wizard writes accepted values (including Enter to copy from env) to the file.
17
+ - **`install.targets`** — `InstallTargetSpec` per artifact; `install.agentIntegration` for MCP vs skill defaults.
18
+ - **Agent install targets** — `codexSkill`, `opencodeSkill`, `openclawSkill`, `openclawMcp`.
19
+ - **Install status JSON** — `install --status --json` includes `agentIntegration` and `effective` target preview.
20
+ - **`mcpServer.mcpd`** — opt-in Claude Desktop `.mcpb` from `mcp bundle` (default off).
21
+ - **`mcpServer.claudePlugin`** — opt-in Claude Code plugin zip from `mcp bundle` (default off).
22
+
23
+ ### Changed
24
+
25
+ - **Sensitive config prompts** — `sensitive: true` entries disable terminal echo (raw-mode read with `*` feedback); Ctrl+C exits as usual.
26
+ - **Breaking: `install --all`** — includes agent targets per `agentIntegration` (skills when MCP off, MCP when `mcpServer.enabled`); not both for the same host unless `both`.
27
+ - **Scoped `--skill` / `--mcp`** — install only targets enabled by `agentIntegration` + `install.targets`, not every host in the category.
28
+ - **Breaking: `--config` removed** — use **`--configure`** (install = wizard; uninstall = remove config directory).
29
+ - **Breaking: `program.appConfig.path` removed** — config file is always `~/.local/lib/<sanitized-key>/config.json`.
30
+ - **Breaking: `--quiet` removed** from `install`.
31
+ - **Breaking: `--prefix` removed** — app always installs to `~/.local/bin/<key>`.
32
+ - **Breaking: `install.prefix` and `INSTALL_PREFIX` removed** — custom install locations are not supported.
33
+ - **Breaking: `--reinstall` / `--update`** — refresh detected artifacts in effective target scope (not bin-only).
34
+ - **Breaking: `mcp bundle`** — writes artifacts only when `mcpServer.mcpd` and/or `mcpServer.claudePlugin` is true (both default off).
35
+ - **Breaking: bare `install --uninstall`** — equivalent to `--uninstall --all` (removes all detected artifacts; ignores `install.targets`).
36
+ - **Claude plugin zip** — `plugin.json` includes `"mcpServers": ".mcp.json"` so Claude Desktop/Code load the bundled MCP server; `bin/<key>` retains executable permissions in the zip.
37
+
38
+ ## [4.0.4] - 2026-06-25
39
+
40
+ ### Added
41
+
42
+ - **MCP docs topic resources** — when `docs.enabled` and `mcpServer.enabled`, each user `docs.topics` key is auto-exposed as `<mcpId>://docs/<topicKey>` (`text/markdown`, same body as `myapp docs <topic>`). Built-in `docs schema` / `api` / `skill` / `mcp` are not auto-exposed.
43
+
44
+ ### Changed
45
+
46
+ - **Claude Code plugin skill** — `mcp bundle` plugin zip includes an MCP routing `SKILL.md` only (no shell catalog, no `reference.md`). `install --skill` unchanged.
47
+ - **Validation** — `mcpServer.resources` URIs that collide with auto docs topic resources are rejected at schema validation time.
48
+
10
49
  ## [4.0.3] - 2026-06-24
11
50
 
12
51
 
@@ -458,7 +497,9 @@ const cli = { ... } satisfies CliProgram; // or : CliProgram
458
497
  - 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`).
459
498
  - Imports: use `CliPositional` where needed; replace `CliOptionDef` with `CliOption` or `CliPositional` as appropriate.
460
499
 
461
- [Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v4.0.3...HEAD
500
+ [Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v4.1.0...HEAD
501
+ [4.1.0]: https://github.com/bdombro/bun-argsbarg/releases/tag/v4.1.0
502
+ [4.0.4]: https://github.com/bdombro/bun-argsbarg/releases/tag/v4.0.4
462
503
  [4.0.3]: https://github.com/bdombro/bun-argsbarg/releases/tag/v4.0.3
463
504
  [4.0.2]: https://github.com/bdombro/bun-argsbarg/releases/tag/v4.0.2
464
505
  [4.0.1]: https://github.com/bdombro/bun-argsbarg/releases/tag/v4.0.1
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![npm version](https://img.shields.io/npm/v/argsbarg.svg)](https://www.npmjs.com/package/argsbarg)
7
7
  [![Bun](https://img.shields.io/badge/Bun-%23000000.svg?logo=bun&logoColor=white)](https://bun.sh)
8
8
 
9
- Build beautiful, well-behaved CLI apps with Bun — **no third-party runtime dependencies**.
9
+ Build beautiful, well-behaved CLI+MCP apps with Bun — **no third-party runtime dependencies**.
10
10
 
11
11
  Why another CLI parser?
12
12
 
@@ -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: { 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).
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 apps can install the app, 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
 
@@ -100,7 +100,7 @@ Every app gets:
100
100
  - **`version`** — print `CliProgram.version` (`myapp version`).
101
101
  - **`mcp`** — when `mcpServer.enabled` is `true`, run as an MCP stdio server (`myapp mcp`).
102
102
  - **`docs`** — when `docs.enabled` is `true`, print bundled markdown topics, schema JSON, API markdown, and generated skill content (`myapp docs`, `myapp docs readme`, `myapp docs schema`, `myapp docs api`, `myapp docs skill`, …). See [docs/bundled-docs.md](docs/bundled-docs.md).
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).
103
+ - **`install`** — install the app, completions, skills, and MCP config to the user environment (`myapp install --yes`). See [docs/install.md](docs/install.md).
104
104
 
105
105
  Do not declare a top-level command named **`completion`**, **`version`**, or **`install`** — they are reserved.
106
106
  When **`mcpServer.enabled`** is `true`, do not declare a top-level command named **`mcp`** — it is reserved for the MCP built-in.
@@ -118,10 +118,10 @@ See **[docs/mcp.md](docs/mcp.md)** for configuration, env bootstrapping, custom
118
118
  argsbarg includes CLI features to manage installation of your compiled bun app. After `bun build --compile` (or when running via `bun`), ship your CLI and let users run:
119
119
 
120
120
  ```bash
121
- myapp install --all --yes
121
+ myapp install --yes
122
122
  ```
123
123
 
124
- This copies the binary to `~/.local/bin`, installs shell completions (bash/zsh/fish when each shell is on PATH), writes Cursor/Claude skills when agent directories exist, and merges MCP server entries into Cursor and Claude config files.
124
+ This copies the app to `~/.local/bin`, installs shell completions (bash/zsh/fish when each shell is on PATH), and runs the configure wizard when `program.appConfig` is set. Agent skills or MCP config are included in `--all` per `install.agentIntegration` (skills when MCP is off; MCP when `mcpServer.enabled`).
125
125
 
126
126
  See **[docs/install.md](docs/install.md)** for `--reinstall`, `install --update`, `--status`, `--uninstall`, and flags.
127
127
 
@@ -161,7 +161,7 @@ Add app-specific conventions in a second rule if needed. Copy the rule from the
161
161
 
162
162
  ## How it works
163
163
 
164
- 1. Build a **program root** with `satisfies CliProgram` (or `: CliProgram`): `key` is the app/binary name, `commands` are top-level subcommands, `options` are global flags. A router root must not set `handler` or declare `positionals` (validated at startup). A leaf root may set `handler` and `positionals` directly. Use `fallbackCommand` / `fallbackMode` on any **routing node** for default subcommand routing (not root-only).
164
+ 1. Build a **program root** with `satisfies CliProgram` (or `: CliProgram`): `key` is the app name, `commands` are top-level subcommands, `options` are global flags. A router root must not set `handler` or declare `positionals` (validated at startup). A leaf root may set `handler` and `positionals` directly. Use `fallbackCommand` / `fallbackMode` on any **routing node** for default subcommand routing (not root-only).
165
165
  2. Call `await new Cli(program).run()` — validates, parses argv, renders help or errors, invokes the leaf handler, and `process.exit`s with status **0** on success, **1** on implicit help or error (explicit `--help` → **0**).
166
166
  3. From a handler, `cliErrWithHelp(ctx, "message")` prints a red error line plus contextual help on stderr and exits **1**.
167
167
 
package/docs/ai-skills.md CHANGED
@@ -8,14 +8,17 @@ Install skills to the user environment:
8
8
 
9
9
  ```bash
10
10
  myapp install --skill --yes
11
- # or
12
- myapp install --all --yes
11
+ # or bare install when agentIntegration defaults to skill:
12
+ myapp install --yes
13
13
  ```
14
14
 
15
- Skills are written when the agent home exists:
15
+ Skills are written when the agent home or CLI exists:
16
16
 
17
17
  - Cursor: `~/.cursor/skills/<dir>/` when `~/.cursor` exists
18
18
  - Claude Code: `~/.claude/skills/<dir>/` when `~/.claude` exists
19
+ - Codex: `~/.codex/skills/<dir>/` when `codex` is on PATH
20
+ - OpenCode: `~/.config/opencode/skills/<dir>/`
21
+ - OpenClaw: `~/.openclaw/skills/<dir>/` when `openclaw` is on PATH
19
22
 
20
23
  The skill directory name defaults to the sanitized program `key` (e.g. `minimal.ts` → `minimal_ts`).
21
24
 
@@ -48,8 +51,10 @@ Skills describe **shell invocation only** — no MCP setup, `mcp.json`, or `tool
48
51
 
49
52
  `SKILL.md` is the routing index; `reference.md` matches `docs api`. Prefer `install --skill` over `docs skill` for agents. See [cli-program.md](cli-program.md).
50
53
 
54
+ **Claude Code plugin** (`mcpServer.claudePlugin: true` → `mcp bundle` writes `dist/claude-plugin/<name>.zip`) ships a separate MCP pointer skill (`SKILL.md` only) that routes agents to the bundled MCP server. This is a **dist artifact**, not installed via `install`. Use **`install --skill`** for persisted shell-oriented skills.
55
+
51
56
  See also:
52
57
 
53
58
  - [Bundled docs](bundled-docs.md) — `docs` config and compile-time imports
54
59
  - [MCP server](mcp.md) — `mcpServer` config and `mcp` protocol
55
- - [Install](install.md) — binary, completions, skills, and MCP config
60
+ - [Install](install.md) — app, completions, skills, and MCP config
@@ -104,6 +104,7 @@ All `docs` subcommands are hidden from MCP `tools/list` (`mcpTool: { enabled: fa
104
104
  | `docs api` | Print command tree markdown to stdout |
105
105
  | `docs schema` | Print command tree JSON to stdout |
106
106
  | `docs` | Bundled markdown topics on stdout |
107
+ | MCP docs topic resources | User `docs.topics` on the MCP wire (`<mcpId>://docs/<topic>`) when docs + MCP enabled |
107
108
  | `mcp` | Callable tools + schema resource |
108
109
 
109
110
  Do not declare a top-level command named **`docs`** when `docs.enabled` is `true` — it is reserved.
@@ -385,7 +385,6 @@ const program = {
385
385
  version: "1.0.0",
386
386
  description: "…",
387
387
  appConfig: {
388
- path: "~/.config/myapp/config", // optional override
389
388
  jsonSchema: APP_CONFIG_JSON_SCHEMA, // optional; omit for all-string mode
390
389
  entries: {
391
390
  apiToken: {
@@ -427,11 +426,12 @@ await cli.run();
427
426
  - **Strict:** unknown keys rejected on load.
428
427
  - **CLI:** missing required config exits 1 before the leaf handler (TTY prompt when interactive). Built-in `docs` and `config get`/`set` skip this exit.
429
428
  - **MCP:** server stays up; missing config returns `isError: true` at `tools/call`.
430
- - **Configure:** `myapp install --configure` (not part of `--all`).
429
+ - **Configure:** included in default `--all` via `install.targets.configure`; also **`myapp install --configure`** (wizard only).
430
+ - **Agent integration:** `install.agentIntegration` (`mcp` | `skill` | `both`) sets default `--all` targets; see [install.md](install.md#examples).
431
431
 
432
- See [config-schema.md](config-schema.md) for codegen, [install.md](install.md), and [mcp.md](mcp.md).
432
+ See [config-schema.md](config-schema.md) for codegen, [install.md](install.md) (`install.targets`), and [mcp.md](mcp.md).
433
433
 
434
- **Handler access (`ctx.appConfig`):** `get`, `require`, `set`, `read`, `path`, `dir` — prefer over `process.env` in handlers; env export remains for subprocess inheritance. `path` is the resolved absolute config file path; `dir` is its parent directory (both honor `program.appConfig.path` when set, otherwise the OS default from `program.key`).
434
+ **Handler access (`ctx.appConfig`):** `get`, `require`, `set`, `read`, `path`, `dir` — prefer over `process.env` in handlers; env export remains for subprocess inheritance. `path` is the resolved absolute config file path (`~/.local/lib/<key>/config`); `dir` is its parent directory.
435
435
 
436
436
  ## Reserved names
437
437
 
@@ -63,7 +63,6 @@ export interface CliAppConfigEntry {
63
63
  }
64
64
 
65
65
  export interface CliAppConfig {
66
- path?: string; // default: ~/.config/<key>/config (OS rules)
67
66
  commands?: boolean | { enabled?: boolean; mcpSet?: boolean };
68
67
  jsonSchema?: Record<string, unknown>; // draft-07 block schema
69
68
  entries: Record<string, CliAppConfigEntry>;
@@ -78,7 +77,7 @@ export interface CliAppConfig {
78
77
 
79
78
  ## Config file shape
80
79
 
81
- Flat JSON at `config.path` (default OS path unchanged):
80
+ Flat JSON at `~/.local/lib/<sanitized-key>/config`:
82
81
 
83
82
  ```json
84
83
  {
@@ -188,5 +187,3 @@ Object/array/`$ref` properties require `--json` on `config set`.
188
187
  cd examples/consumer-app && bun install && bun run schemagen
189
188
  CONSUMER_APP_API_TOKEN=dev bun run start config get apiToken --json
190
189
  ```
191
-
192
- Set `CONSUMER_APP_CONFIG_FILE` to override the config file path.
@@ -32,7 +32,7 @@ Sibling repos under `../../ss/` (paths are machine-specific; adjust in `justfile
32
32
 
33
33
  | Recipe | When | Effect |
34
34
  | --- | --- | --- |
35
- | `just consumer-dev` | Before publish; hacking on argsbarg locally | `bun add argsbarg@file:<relative>`; refresh `.cursor/rules/cli-program.mdc` from template (keeps app-specific suffix) |
35
+ | `just consumers-dev` | Before publish; hacking on argsbarg locally | `bun add argsbarg@file:<relative>`; refresh `.cursor/rules/cli-program.mdc` from template (keeps app-specific suffix) |
36
36
  | `just consumers-sync` | After release | Sets `"argsbarg": "^<this package.json version>"`, `bun install`, merge **argsbarg Cursor rule**, `just build`, `just docgen`, `just install` (consumer app binary, completions, and **app** skill) |
37
37
 
38
38
  `consumers-sync` reads the version from **this repo’s** `package.json` — not npm. Run it **after** `just release` so consumers pin a version that exists on the registry.
package/docs/install.md CHANGED
@@ -1,44 +1,149 @@
1
1
  # Install command
2
2
 
3
- The `install` built-in installs the binary, shell completions, agent skills, and MCP config. Opt out with `install: { enabled: false }` on the program root.
3
+ The `install` built-in installs the app, shell completions, agent skills, and MCP config. Opt out with `install: { enabled: false }` on the program root.
4
4
 
5
- ## Quick start
5
+ ## End-user install
6
+
7
+ Ship a compiled binary (or app bundle). Users install interactively — no `--yes` required when stdin is a TTY:
8
+
9
+ - **Terminal:** run `./myapp`, `myapp`, or `myapp install` (bare `install` is equivalent to `--all`).
10
+ - **macOS app:** double-click the `.app`; when the binary is not yet on PATH and stdin is a TTY, launching with no arguments bootstraps to **`myapp install`**.
11
+
12
+ Interactive flow prints a **`{app} Setup`** banner, a numbered plan, and a confirm prompt. When the app needs API keys or other settings, a **`Configuration Setup`** section runs after install (or immediately for **`install --configure`**).
13
+
14
+ **Uninstall is CLI-only** — there is no GUI uninstaller. Users run:
15
+
16
+ ```bash
17
+ myapp install --uninstall # remove all detected artifacts
18
+ myapp install --uninstall --app # scoped removal
19
+ ```
20
+
21
+ Non-interactive / CI: pass **`--yes`** (or **`--json`**, **`--reinstall`**, **`--update`**) — see [Confirmation](#confirmation).
22
+
23
+ ## Quick start (automation)
6
24
 
7
25
  ```bash
8
- # First-time setup
26
+ # First-time setup (bare `install` is equivalent to `--all`)
27
+ myapp install --yes
28
+
29
+ # Or explicitly
9
30
  myapp install --all --yes
10
31
 
11
- # Refresh after upgrading (re-copy running binary + refresh installed artifacts)
32
+ # Refresh after upgrading (re-copy running app + refresh detected artifacts in scope)
12
33
  myapp install --reinstall
13
34
 
14
- # Upgrade to latest release (when install.updateGetLatest is configured)
35
+ # Upgrade to latest release (when this app supports remote updates)
15
36
  myapp install --update
16
37
 
17
38
  # See what is installed
18
39
  myapp install --status
19
40
 
20
- # Remove everything installed with --all
21
- myapp install --uninstall --all --yes
41
+ # Remove everything detected on disk (bare `install --uninstall` is equivalent to `--uninstall --all`)
42
+ myapp install --uninstall --yes
22
43
  ```
23
44
 
24
45
  ## What gets installed
25
46
 
26
47
  | Target | Flag | Destination |
27
48
  | --- | --- | --- |
28
- | Binary | `--bin` | `~/.local/bin/<key>` (or `--prefix`) |
49
+ | App | `--app` | `~/.local/bin/<key>` |
29
50
  | Bash completion | `--completions` | `~/.bash_completion.d/<key>` + `.bashrc` PATH snippet |
30
51
  | Zsh completion | `--completions` | `~/.zsh/completions/_<key>` + `.zshrc` fpath snippet |
31
52
  | Fish completion | `--completions` | `~/.config/fish/completions/<key>.fish` |
32
53
  | Cursor skill | `--skill` | `~/.cursor/skills/<dir>/` when `~/.cursor` exists |
33
54
  | Claude skill | `--skill` | `~/.claude/skills/<dir>/` when `~/.claude` exists |
34
- | MCP config | `--mcp` | Cursor, Claude Code/Desktop, OpenCode (`~/.config/opencode`), Codex (`codex` on PATH), ChatGPT desktop (when app data exists). ChatGPT web uses Connectors — see `docs mcp` |
35
- | App config | `--config` | JSON config file for `program.appConfig` (with `--uninstall`; included in `--uninstall --all`) |
55
+ | Codex / OpenCode / OpenClaw skills | `--skill` | Agent-specific dirs when the agent home or CLI is available |
56
+ | MCP config | `--mcp` | Cursor, Claude Code/Desktop, OpenCode, Codex, OpenClaw, ChatGPT desktop (when app data exists). ChatGPT web uses Connectors — see `docs mcp` |
57
+ | App config | `--configure` | Interactive wizard writes app settings; `--uninstall --configure` removes the file |
58
+
59
+ ### Default `--all` behavior
60
+
61
+ Bare **`install`** and **`install --all`** install targets with **`includedInAll: true`**. Core defaults:
62
+
63
+ - **Always included:** `app`, `completions`, `configure` (wizard when `program.appConfig` is set)
64
+ - **Agent integration** (`install.agentIntegration`, default from `mcpServer.enabled`):
65
+ - **`skill`** (default when MCP off): all `*Skill` keys in `--all`; paired `*Mcp` keys excluded
66
+ - **`mcp`** (default when `mcpServer.enabled`): all `*Mcp` keys in `--all`; paired skills excluded
67
+ - **`both`**: MCP and skill for the same host when available
68
+
69
+ Desktop-only MCP hosts (`claudeDesktopMcp`, `chatgptMcp`) follow the MCP side only — no skill pair.
70
+
71
+ Scoped flags (`--app`, `--completions`, `--configure`) run that artifact category. **`--skill`** and **`--mcp`** install only targets enabled by `agentIntegration` and per-key `install.targets`. Honor `enabled: false` as a hard off.
72
+
73
+ Use **`install --status --json`** to preview effective targets (`effective.all`, `effective.mcp`, `effective.skill`) before installing.
74
+
75
+ ### Asymmetric uninstall
76
+
77
+ - **`install --uninstall --all`** (including bare **`install --uninstall`**) removes **every detected artifact type**, ignoring `install.targets`.
78
+ - Scoped uninstall (`--app`, `--skill`, …) removes only that category.
79
+
80
+ Missing targets are skipped silently (no error if nothing is on disk or a shell/agent directory does not exist). Shells not on PATH are skipped silently (no warnings).
81
+
82
+ ## `install.targets`
83
+
84
+ Configure which artifacts participate in `--all`, `--reinstall`, and `--update`:
85
+
86
+ ```typescript
87
+ install: {
88
+ agentIntegration: "mcp", // | "skill" | "both" — default from mcpServer.enabled
89
+ targets: {
90
+ app: { includedInAll: false },
91
+ chatgptMcp: false,
92
+ cursorSkill: { includedInAll: true },
93
+ },
94
+ },
95
+ ```
96
+
97
+ `InstallTargetSpec` is `boolean` or `{ enabled?: boolean; includedInAll?: boolean }`. Shorthand `true` enables the target with default `includedInAll`; `false` disables it.
98
+
99
+ Artifact keys: `app`, `chatgptMcp`, `claudeCodeMcp`, `claudeDesktopMcp`, `claudeSkill`, `codexMcp`, `codexSkill`, `completions`, `configure`, `cursorMcp`, `cursorSkill`, `openclawMcp`, `openclawSkill`, `opencodeMcp`, `opencodeSkill`.
100
+
101
+ Conflicting targets (e.g. both `cursorMcp` and `cursorSkill` without `agentIntegration: 'both'`) fail at program validation time.
102
+
103
+ ## Examples
104
+
105
+ ### MCP CLI (default)
106
+
107
+ ```typescript
108
+ const program = {
109
+ key: "myapp",
110
+ version: "1.0.0",
111
+ description: "…",
112
+ mcpServer: { enabled: true },
113
+ install: {}, // agentIntegration defaults to "mcp"
114
+ // …
115
+ } satisfies CliProgram;
116
+ ```
117
+
118
+ Bare **`myapp install --yes`** installs the app, completions, configure wizard (when `appConfig` is set), and MCP hosts — not shell skills for paired agents.
36
119
 
37
- `--all` expands to `--bin`, `--completions`, `--skill`, and `--mcp` (when `mcpServer.enabled` is `true`) for both install and uninstall. Missing targets are skipped silently (no error if nothing is on disk or a shell/agent directory does not exist).
120
+ ### Shell-only CLI (default)
38
121
 
39
- `install --uninstall` requires the same target flags as install (`--all`, `--bin`, etc.) — bare `--uninstall` alone is an error.
122
+ ```typescript
123
+ const program = {
124
+ key: "myapp",
125
+ version: "1.0.0",
126
+ description: "…",
127
+ install: {}, // agentIntegration defaults to "skill"
128
+ // …
129
+ } satisfies CliProgram;
130
+ ```
131
+
132
+ Bare install includes agent skills (when each host is available), not MCP config.
133
+
134
+ ### Overrides
135
+
136
+ ```typescript
137
+ install: {
138
+ agentIntegration: "both", // MCP + skill on the same host
139
+ targets: {
140
+ chatgptMcp: false, // opt out of one MCP host
141
+ app: { includedInAll: false }, // skip app on --all
142
+ },
143
+ },
144
+ ```
40
145
 
41
- Shells not on PATH are skipped silently (no warnings).
146
+ Preview resolved targets: **`myapp install --status --json`**.
42
147
 
43
148
  ## Configuration
44
149
 
@@ -47,19 +152,18 @@ On the program root:
47
152
  ```typescript
48
153
  install: {
49
154
  enabled: false, // opt out of the install built-in
50
- prefix: "~/.local/bin", // default bin directory
51
155
  updateGetLatest: async ({ version }) => {
52
- // download or locate latest binary; return { path, version, cleanup }
156
+ // download or locate latest release; return { path, version, cleanup }
53
157
  return { path: "/tmp/myapp", version: "2.0.0" };
54
158
  },
55
159
  }
56
160
  ```
57
161
 
58
- When `updateGetLatest` is set, ArgsBarg adds **`install --update`** (download latest release and reinstall installed artifacts).
162
+ When `updateGetLatest` is set, ArgsBarg adds **`install --update`** (download latest release and reinstall installed artifacts in scope).
59
163
 
60
164
  ### GitHub releases (`ghReleaseUpdateGetLatest`)
61
165
 
62
- For compiled binaries published via `gh release`, wire a hook without hand-rolling download logic:
166
+ For compiled apps published via `gh release`, wire a hook without hand-rolling download logic:
63
167
 
64
168
  ```typescript
65
169
  import {
@@ -92,10 +196,6 @@ versionCheck.refreshIfStale();
92
196
 
93
197
  Requires `gh` on PATH and `gh auth login`. Consumers keep app-specific config only (~15 lines).
94
198
 
95
- Environment:
96
-
97
- - `INSTALL_PREFIX` — same as `install.prefix` / `--prefix`
98
-
99
199
  ## App config (`program.appConfig`)
100
200
 
101
201
  When `program.appConfig` is set on the program root, ArgsBarg manages a flat JSON config file:
@@ -109,53 +209,74 @@ appConfig: {
109
209
  sensitive: true,
110
210
  },
111
211
  },
112
- path: "~/.config/myapp/config", // optional; default is OS-specific
113
212
  },
114
213
  ```
115
214
 
116
- Default path: `$XDG_CONFIG_HOME/<sanitized-key>/config` (Linux/macOS) or `%APPDATA%/<key>/config` (Windows).
215
+ Config file path: `~/.local/lib/<sanitized-key>/config.json`.
117
216
 
118
217
  | Flag | Description |
119
218
  | --- | --- |
120
- | `--configure` | Interactive prompt for each schema entry; writes or updates the config file (standalone — not part of `--all`) |
121
- | `--uninstall --config` | Remove the config file (included in `--uninstall --all`) |
219
+ | `--configure` | Interactive prompt for each setting; writes or updates the config file. On full install, the wizard runs automatically when configuration is in scope. Standalone **`install --configure`** runs the wizard only (no other install steps). |
220
+ | `--uninstall --configure` | Remove the config directory (`~/.local/lib/<key>/`) |
122
221
  | `--status` | Shows config path and which required keys are set or missing |
123
222
 
124
223
  **Configure UX** (TTY):
125
224
 
126
225
  ```
127
- API token
226
+ Configuration Setup
227
+
228
+ API token (API_TOKEN)
128
229
  Create at https://example.com/settings/tokens
129
- Current: REDACTED
130
- Value (Enter to keep):
230
+ Current: REDACTED
231
+ Value (Enter to copy from env):
131
232
  ```
132
233
 
133
- Non-sensitive vars show the current value; first-time setup omits the `Current:` line.
234
+ Non-sensitive vars show the current value; first-time setup omits the `Current:` line. When the current value comes from a mapped environment variable, Enter copies it into `config.json`; otherwise Enter keeps the existing file value. At runtime, a non-empty mapped environment variable always wins over `config.json` (the file is the fallback when env is unset).
134
235
 
135
236
  ## Flags
136
237
 
238
+ ### Target flags
239
+
240
+ | Flag | Description |
241
+ | --- | --- |
242
+ | `--all` | Install the default set (app, shell completions, and configuration when supported) |
243
+ | `--app` | Copy this app to the install directory |
244
+ | `--completions` | Install bash, zsh, and fish tab-completion scripts |
245
+ | `--skill` | Install agent skills for Cursor, Claude, and other supported AI tools |
246
+ | `--mcp` | Add MCP server configuration for Cursor, Claude Code, and other supported agents |
247
+ | `--configure` | Run the configuration wizard (install) or remove the config file (`--uninstall`) |
248
+
249
+ ### Operation flags
250
+
137
251
  | Flag | Description |
138
252
  | --- | --- |
139
- | `--yes` | Skip confirmation (required for non-TTY unless `--json`, `--reinstall`, or `--update`) |
253
+ | `--status` | Read-only inventory |
254
+ | `--reinstall` | Refresh everything already installed (implies `--yes`; no numbered confirm) |
255
+ | `--update` | Download the latest release and refresh installed files (implies `--yes`) |
256
+ | `--uninstall` | Remove installed files (`--all` removes everything; use individual flags for one category) |
257
+ | `--from <path>` | App executable to copy with `--reinstall` / `--update` (default: running executable) |
258
+
259
+ ### Behavior flags
260
+
261
+ | Flag | Description |
262
+ | --- | --- |
263
+ | `--yes`, `-y` | Skip confirmation (required for non-TTY unless `--json`, `--reinstall`, or `--update`) |
140
264
  | `--dry` | Preview changes; per-step messages on stderr with `[dry run]` |
141
265
  | `--json` | Machine-readable output on stdout (implies `--yes`) |
142
- | `--quiet` | Suppress summaries and per-step messages (requires `--yes`) |
143
- | `--prefix <dir>` | Override binary install directory |
144
- | `--reinstall` | Reinstall artifacts already on disk (implies `--bin` + `--yes`) |
145
- | `--update` | Download latest release and reinstall installed artifacts (requires `install.updateGetLatest`; implies `--yes`) |
146
- | `--from <path>` | Binary to copy with `--reinstall` (default: running executable) |
147
- | `--status` | Read-only inventory |
148
- | `--uninstall` | Remove artifacts in scope (`--all`, `--bin`, `--completions`, `--skill`, `--mcp`, `--config`); skips targets not installed |
266
+
267
+ ## Confirmation
268
+
269
+ Install and uninstall (except `--yes`, `--json`, `--dry`, `--reinstall`, `--update`) print a **`{app} Setup`** banner on stderr, then a numbered list of planned actions on stdout. Reply **`y`** for all, **`n`** or Enter to abort, or numbers for a subset. On **install**, when the plan includes the app as item **1**, it is always installed (prompt example: **`2,3`**); MCP and other targets need the binary on PATH. On **uninstall**, use any subset (e.g. **`1,3`**). After you confirm, **`Done.`** prints on stderr. Per-step progress is suppressed until you confirm; the final **`Installed N file(s).`** summary still prints.
149
270
 
150
271
  ## MCP merge behavior
151
272
 
152
- When `--mcp` runs, entries are merged into `mcpServers[<sanitized-key>]` with:
273
+ When `--mcp` runs, entries are merged into host config with:
153
274
 
154
275
  ```json
155
276
  { "command": "<root.key>", "args": ["mcp"] }
156
277
  ```
157
278
 
158
- If an existing entry differs, the command exits with an error unless `--yes` is passed (then it overwrites).
279
+ If an existing entry differs, the command exits with an error unless `--yes` is passed (then it overwrites). MCP conflict checks run only for hosts present in the current plan.
159
280
 
160
281
  ## Opt out
161
282
 
package/docs/mcp.md CHANGED
@@ -244,6 +244,20 @@ The built-in schema resource (default URI `<sanitized-key>://schema`, e.g. `nest
244
244
  | MIME type | `application/json` |
245
245
  | Contents | `cliSchemaJson(root)` — handlers omitted, built-ins excluded |
246
246
 
247
+ ### Auto docs topic resources
248
+
249
+ When both **`docs.enabled`** and **`mcpServer.enabled`** are true, each user key in **`docs.topics`** is also exposed as an MCP resource:
250
+
251
+ | Property | Value |
252
+ | --- | --- |
253
+ | URI | `<sanitized root key>://docs/<topicKey>` (e.g. `myapp://docs/readme`) |
254
+ | MIME type | `text/markdown` |
255
+ | Contents | Same body as `myapp docs <topicKey>` |
256
+
257
+ Built-in docs subcommands (`schema`, `api`, `skill`, `mcp`) are **not** auto-exposed — use the schema resource, `install --skill`, or CLI `docs` instead. `docs` subcommands remain hidden from MCP `tools/list`.
258
+
259
+ Custom `mcpServer.resources` URIs must not collide with the schema URI or any auto docs topic URI (validated at program compile time).
260
+
247
261
  Add custom resources on the program root:
248
262
 
249
263
  ```typescript
@@ -261,7 +275,7 @@ mcpServer: {
261
275
  },
262
276
  ```
263
277
 
264
- URIs must be unique and must not equal `schemaResourceUri`. `load()` runs synchronously at `resources/read` time.
278
+ URIs must be unique and must not equal `schemaResourceUri` or any auto docs topic URI (`<mcpId>://docs/<topicKey>`). `load()` runs synchronously at `resources/read` time.
265
279
 
266
280
  ## Invocation context
267
281
 
@@ -308,7 +322,7 @@ At server start (`Cli.serveMcp()`), before the NDJSON loop:
308
322
 
309
323
  **App config (`program.appConfig`):**
310
324
 
311
- - Default path: `$XDG_CONFIG_HOME/<sanitized-key>/config` (Linux/macOS) or `%APPDATA%/<key>/config` (Windows). Override with `config.path`.
325
+ - Default path: `~/.local/lib/<sanitized-key>/config`.
312
326
  - JSON shape: flat object keyed by schema names — `{ "apiToken": "…" }`. Unknown keys rejected on load.
313
327
  - Loaded at MCP startup; host `process.env` wins for mapped env vars already set.
314
328
  - Missing required config does **not** exit the MCP server — enforced at `tools/call` with a helpful error.
@@ -359,34 +373,47 @@ You should get one JSON line on stdout with `result.capabilities` and `result.se
359
373
 
360
374
  ## MCP Bundle (`mcp bundle`)
361
375
 
362
- When `mcpServer.enabled` is true, **`mcp bundle`** writes two distribution artifacts:
376
+ When `mcpServer.enabled` is true, **`mcp bundle`** writes dist artifacts you opt into on the program root:
363
377
 
364
378
  ```bash
365
379
  just build
366
380
  ./dist/myapp mcp bundle
367
- # → dist/myapp.mcpb
368
- # → dist/claude-plugin/myapp.zip
381
+ # → dist/myapp.mcpb (when mcpServer.mcpd: true)
382
+ # → dist/claude-plugin/myapp.zip (when mcpServer.claudePlugin: true)
383
+ ```
384
+
385
+ Enable one or both flags:
386
+
387
+ ```typescript
388
+ mcpServer: {
389
+ enabled: true,
390
+ mcpd: true, // Claude Desktop `.mcpb`
391
+ claudePlugin: true, // Claude Code plugin zip
392
+ },
369
393
  ```
370
394
 
371
- Expects the compiled binary at **`dist/<program.key>`**.
395
+ Expects the compiled binary at **`dist/<program.key>`**. Stdout prints one path per artifact produced.
372
396
 
373
397
  | Output | Purpose |
374
398
  | --- | --- |
375
- | **`dist/<key>.mcpb`** | Claude Desktop MCP Bundle (`.mcpb` zip) |
376
- | **`dist/claude-plugin/<name>.zip`** | Claude Code plugin zip (`<name>` is kebab-case from `program.key`) |
399
+ | **`dist/<key>.mcpb`** | Claude Desktop MCP Bundle — when `mcpd: true` (default **false**) |
400
+ | **`dist/claude-plugin/<name>.zip`** | Claude Code plugin zip — when `claudePlugin: true` (default **false**) |
377
401
 
378
402
  Manifest metadata is generated from your schema (`mcpServerId`, tools, `program.appConfig` user config for env-mapped entries). Optional pack-time fields live under **`mcpServer.bundle`** (`author`, `icon`, `longDescription`).
379
403
 
380
404
  **Claude Code plugin zip layout** (paths at archive root):
381
405
 
382
406
  ```
383
- .claude-plugin/plugin.json
407
+ .claude-plugin/plugin.json # includes "mcpServers": ".mcp.json"
384
408
  .mcp.json
385
- bin/myapp
409
+ bin/myapp # executable (0755 preserved in the zip)
386
410
  skills/<dirName>/SKILL.md
387
- skills/<dirName>/reference.md
388
411
  ```
389
412
 
413
+ `plugin.json` references `.mcp.json` so Claude Desktop and Claude Code load the bundled MCP server when the plugin is enabled. The plugin zip preserves the executable bit on `bin/<key>`.
414
+
415
+ The bundled `SKILL.md` is an **MCP routing stub** — it tells Claude to use the plugin’s MCP toolset (server id, `tools/list`, schema resource). It is not a shell CLI catalog and does not include `reference.md`. Use **`install --skill`** for a persisted shell-oriented skill bundle.
416
+
390
417
  Load locally with `claude --plugin-dir ./dist/claude-plugin/myapp.zip`.
391
418
 
392
419
  Bare **`myapp mcp`** still runs the stdio MCP server (unchanged for `install --mcp` and MCP hosts). Use **`install --mcp`** for Cursor, Claude Code, Claude Desktop, and OpenCode JSON config.
@@ -10,7 +10,7 @@ When adding or changing argsbarg schema, leaf handlers, or MCP exposure:
10
10
  2. MCP tools, varargs, `inputSchema` → also `node_modules/argsbarg/docs/mcp.md`.
11
11
  3. JSON stdout / `outputSchema` guide and codegen → `node_modules/argsbarg/docs/output-schema.md`.
12
12
  4. App config / `program.appConfig` guide and codegen → `node_modules/argsbarg/docs/config-schema.md`.
13
- 5. `install`, completions, skills → `node_modules/argsbarg/docs/install.md`.
13
+ 5. `install`, `install.targets`, completions, skills → `node_modules/argsbarg/docs/install.md`.
14
14
  6. Bundled `docs` built-in → `node_modules/argsbarg/docs/bundled-docs.md`.
15
15
  7. **Examples** (shipped under `node_modules/argsbarg/examples/`):
16
16
  - Concepts / minimal config → `examples/config-app/`
@@ -11,8 +11,6 @@ import {
11
11
  } from "../../src/index.ts";
12
12
  import { APP_CONFIG_JSON_SCHEMA } from "./schema.ts";
13
13
 
14
- const configPath = process.env.CONFIG_APP_CONFIG_FILE;
15
-
16
14
  const configSchema = {
17
15
  apiToken: {
18
16
  description: "Create at https://example.com/settings/tokens",
@@ -37,7 +35,6 @@ export const program = {
37
35
  version: pkg.version,
38
36
  description: "Demonstrates program.appConfig, ctx.appConfig, and built-in config get/set.",
39
37
  appConfig: {
40
- ...(configPath ? { path: configPath } : {}),
41
38
  jsonSchema: APP_CONFIG_JSON_SCHEMA,
42
39
  entries: configSchema,
43
40
  } satisfies CliAppConfig,
@@ -11,6 +11,7 @@
11
11
  | `outputSchema` | `src/commands/status/types.ts` (`StatusJsonOutput`) → `schemas/outputSchemas.ts` |
12
12
  | Schemagen | `scripts/schemagen.ts` + `scripts/schemagen/discover-schema-roots.ts` |
13
13
  | Handler access | `ctx.appConfig` in `src/program.ts` |
14
+ | MCP doc topics | `docs.topics` auto-exposed as `<key>://docs/<topic>` resources when docs + MCP enabled |
14
15
  | Package import | `from "argsbarg"` (not relative to argsbarg `src/`) |
15
16
 
16
17
  ## Quick start (in this repo)
@@ -45,7 +46,6 @@ Discovery walks `src/**/types.ts` only.
45
46
  | Variable | Purpose |
46
47
  | --- | --- |
47
48
  | `CONSUMER_APP_API_TOKEN` | Overrides `apiToken` via `program.appConfig` env mapping |
48
- | `CONSUMER_APP_CONFIG_FILE` | Overrides config file path (`config.path`) |
49
49
 
50
50
  ## Maintainers (argsbarg repo)
51
51