argsbarg 4.1.0 → 4.1.1

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 (103) hide show
  1. package/CHANGELOG.md +48 -1
  2. package/README.md +90 -84
  3. package/docs/README.md +6 -6
  4. package/docs/bundled-docs.md +1 -1
  5. package/docs/cli-program.md +5 -3
  6. package/docs/config-schema.md +36 -9
  7. package/docs/developing.md +7 -7
  8. package/docs/distribution-homebrew.md +103 -0
  9. package/docs/install.md +105 -189
  10. package/docs/mcp.md +2 -3
  11. package/docs/output-schema.md +1 -1
  12. package/examples/full-example/Formula/.gitkeep +0 -0
  13. package/examples/full-example/README.md +98 -0
  14. package/examples/full-example/biome.json +22 -0
  15. package/examples/{consumer-app → full-example}/bun.lock +2 -0
  16. package/examples/full-example/justfile +134 -0
  17. package/examples/{consumer-app → full-example}/package.json +10 -3
  18. package/examples/{consumer-app → full-example}/schemas/generated/app-config.json +1 -1
  19. package/examples/{consumer-app → full-example}/schemas/generated/status.json +1 -1
  20. package/examples/full-example/scripts/create-identity.ts +11 -0
  21. package/examples/full-example/scripts/formula-shared.ts +73 -0
  22. package/examples/full-example/scripts/gen-dev-formula.ts +26 -0
  23. package/examples/full-example/scripts/print-identity.ts +27 -0
  24. package/examples/full-example/src/commands/echo/command.ts +21 -0
  25. package/examples/full-example/src/commands/status/command.test.ts +10 -0
  26. package/examples/full-example/src/commands/status/command.ts +36 -0
  27. package/examples/{consumer-app → full-example}/src/commands/status/types.ts +1 -1
  28. package/examples/full-example/src/index.ts +10 -0
  29. package/examples/full-example/src/program.ts +57 -0
  30. package/examples/{consumer-app → full-example}/src/types.ts +1 -1
  31. package/examples/nested.ts +1 -3
  32. package/index.d.ts +27 -66
  33. package/package.json +2 -2
  34. package/src/builtins/builtins.test.ts +22 -23
  35. package/src/builtins/completion-group.ts +17 -15
  36. package/src/builtins/dispatch.ts +25 -1
  37. package/src/builtins/install.ts +22 -52
  38. package/src/builtins/registry.ts +2 -0
  39. package/src/builtins/uninstall.ts +80 -0
  40. package/src/capabilities.ts +1 -3
  41. package/src/cli-tool/cli-smoke.test.ts +19 -0
  42. package/src/cli-tool/create.test.ts +119 -0
  43. package/src/cli-tool/create.ts +380 -0
  44. package/{examples/consumer-app/capabilities.test.ts → src/cli-tool/full-example-capabilities.test.ts} +15 -14
  45. package/src/cli-tool/main.ts +8 -0
  46. package/src/cli-tool/post-create.ts +111 -0
  47. package/src/cli-tool/program.ts +82 -0
  48. package/src/cli-tool/prompt.ts +28 -0
  49. package/src/cli-tool/run-create.ts +149 -0
  50. package/src/cli.ts +0 -2
  51. package/src/config/bootstrap.ts +16 -9
  52. package/src/config/resolve.test.ts +167 -0
  53. package/src/config/resolve.ts +50 -6
  54. package/src/docs/api-guide.test.ts +4 -5
  55. package/src/docs/docs.test.ts +2 -1
  56. package/src/docs/mcp-guide.ts +7 -8
  57. package/src/index.ts +3 -10
  58. package/src/install/binary-placement.test.ts +101 -0
  59. package/src/install/binary-placement.ts +47 -0
  60. package/src/install/index.ts +117 -123
  61. package/src/install/install.test.ts +89 -105
  62. package/src/install/normalize-uninstall.ts +11 -0
  63. package/src/install/normalize.ts +4 -19
  64. package/src/install/paths.ts +0 -22
  65. package/src/install/plan.ts +14 -6
  66. package/src/install/shell.ts +0 -14
  67. package/src/install/status.test.ts +6 -6
  68. package/src/install/status.ts +0 -6
  69. package/src/install/target-effective.ts +0 -2
  70. package/src/install/target-scope.ts +15 -28
  71. package/src/install/target-types.ts +0 -16
  72. package/src/install/targets/app.ts +19 -28
  73. package/src/install/targets/configure.ts +5 -1
  74. package/src/install/targets/index.ts +0 -3
  75. package/src/install/targets.test.ts +24 -42
  76. package/src/mcp/env.test.ts +92 -0
  77. package/src/mcp/env.ts +15 -14
  78. package/src/parse.test.ts +3 -2
  79. package/src/prompt.ts +10 -0
  80. package/src/schema.ts +9 -1
  81. package/src/types.ts +27 -9
  82. package/src/validate.ts +5 -11
  83. package/docs/templates/cursor/rules/cli-program.mdc +0 -31
  84. package/examples/config-app/main.ts +0 -20
  85. package/examples/config-app/program.ts +0 -78
  86. package/examples/config-app/schema.ts +0 -37
  87. package/examples/config-app/types.ts +0 -19
  88. package/examples/consumer-app/README.md +0 -56
  89. package/examples/consumer-app/src/main.ts +0 -15
  90. package/examples/consumer-app/src/program.ts +0 -108
  91. package/src/install/app.ts +0 -94
  92. package/src/install/bootstrap.ts +0 -22
  93. package/src/install/completions.ts +0 -56
  94. package/src/install/targets/completions.ts +0 -133
  95. package/src/install/update.test.ts +0 -123
  96. package/src/install/update.ts +0 -54
  97. /package/examples/{consumer-app → full-example}/schemas/configSchemas.ts +0 -0
  98. /package/examples/{consumer-app → full-example}/schemas/outputSchemas.ts +0 -0
  99. /package/examples/{consumer-app → full-example}/scripts/schemagen/discover-schema-roots.test.ts +0 -0
  100. /package/examples/{consumer-app → full-example}/scripts/schemagen/discover-schema-roots.ts +0 -0
  101. /package/examples/{consumer-app → full-example}/scripts/schemagen/naming.ts +0 -0
  102. /package/examples/{consumer-app → full-example}/scripts/schemagen.ts +0 -0
  103. /package/examples/{consumer-app → full-example}/tsconfig.json +0 -0
@@ -0,0 +1,103 @@
1
+ # Shipping via Homebrew (tap-from-repo)
2
+
3
+ Argsbarg apps distribute the **binary and shell completions** through Homebrew, and **agent artifacts** (skills, MCP config) through `install --reinstall`.
4
+
5
+ ## Distribution model
6
+
7
+ | Layer | Mechanism |
8
+ | --- | --- |
9
+ | Binary + completions | Formula `install` block |
10
+ | Skills + MCP | Formula `post_install` → `{key} install --reinstall --yes` |
11
+ | App config | User opt-in: `{key} install --configure` (interactive; not run from formula `post_install`) |
12
+
13
+ **Only tap-from-repo** — in-repo `Formula/` or GitHub tap. Not Homebrew core.
14
+
15
+ ### End-user install
16
+
17
+ ```bash
18
+ brew tap <org>/<repo>
19
+ brew install <tap>/{key}
20
+ {key} install --configure # when app config is required
21
+ ```
22
+
23
+ ### Developer install
24
+
25
+ ```bash
26
+ just build
27
+ just install-local # or `just install` (alias)
28
+ just reinstall-local # fast binary swap (`install -m 755` into Cellar; run install-local first)
29
+ just uninstall # undo formula + agent artifacts (not app config)
30
+ ```
31
+
32
+ Dev and release use the **same formula** (`Formula/{key}.rb`, class name, install/post_install/test). `gen-dev-formula.ts` only changes `url`, `version`, and `sha256` to point at the local binary in `Formula/.staging/`. Release bumps restore the GitHub URL via `scripts/release.ts`.
33
+
34
+ ### Developer uninstall
35
+
36
+ | Recipe | Removes |
37
+ | --- | --- |
38
+ | `just uninstall` | Formula `{key}` + tap symlink + skills/MCP |
39
+ | `just uninstall-config` | App config file only (`uninstall --configure`) |
40
+ | `just uninstall-release` | Release formula from `{tap}` (keeps tap) |
41
+ | `just uninstall-release-tap` | Release formula + `brew untap {tap}` |
42
+ | `just test-release` | Install release formula and run formula test |
43
+
44
+ End users: `<key> uninstall --yes` then `brew uninstall <tap>/<key>`.
45
+
46
+ ## Formula pattern
47
+
48
+ ```ruby
49
+ def install
50
+ bin.install "{key}"
51
+ generate_completions_from_executable(bin/"{key}", "completion", base_name: "{key}")
52
+ end
53
+
54
+ def post_install
55
+ system bin/"{key}", "install", "--reinstall", "--yes"
56
+ end
57
+ ```
58
+
59
+ Completions require users to configure their shell per [Homebrew Shell Completion](https://docs.brew.sh/Shell-Completion).
60
+
61
+ **Why configure is separate from `post_install`:** the wizard is interactive (TTY + prompts for secrets). Formula `post_install` runs non-interactively during `brew install` and in CI (`brew test`). Apps with `appConfig` print a one-line configure hint in formula `caveats` instead.
62
+
63
+ ## Bootstrap CLI (`argsbarg create`)
64
+
65
+ Copy the shipped `examples/full-example` template into a new directory with identity substitutions, then run install, schemagen, tests, and git init (when appropriate):
66
+
67
+ ```bash
68
+ bunx argsbarg create my-cli \
69
+ --key my-cli --class-name MyCli --tap org/my-cli \
70
+ --homepage https://github.com/org/my-cli --release-repo org/my-cli \
71
+ --yes
72
+ ```
73
+
74
+ On a TTY, omit flags to use the interactive wizard. Verify an existing tree:
75
+
76
+ ```bash
77
+ bunx argsbarg create --check .
78
+ ```
79
+
80
+ Template source: [`examples/full-example/`](../examples/full-example/) in the argsbarg package (also under `node_modules/argsbarg/examples/full-example` after `bun add argsbarg`).
81
+
82
+ **Git bootstrap skip rules:** post-create skips `git init` when the target already has a `.git` directory, or when the target sits inside an existing git work tree (e.g. a monorepo subfolder). Standalone new directories get an `Initial commit`.
83
+
84
+ ## Release workflow
85
+
86
+ 1. `just build` → `dist/{key}`
87
+ 2. `scripts/release.ts` → writes `Formula/{key}.rb` (GitHub URL + sha256), commits, tags, uploads `dist/{key}` to GitHub Releases
88
+ 3. Users `brew upgrade {key}` from the tap
89
+
90
+ ## Removed (breaking)
91
+
92
+ - Self-install to `~/.local/bin`
93
+ - `install --update` / `updateGetLatest`
94
+ - `install --completions` (Homebrew owns completions)
95
+ - Bare-argv install bootstrap
96
+ - Auto configure wizard after `install --all`
97
+ - Separate `{key}-local` formula and `{key}/dev` tap
98
+
99
+ ## Config path
100
+
101
+ Default: `~/.local/lib/<sanitized-key>/config.json`
102
+
103
+ Export helpers: `resolveAppConfigPath`, `displayAppConfigPath` from `argsbarg`.
package/docs/install.md CHANGED
@@ -1,272 +1,172 @@
1
1
  # Install command
2
2
 
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.
3
+ The `install` built-in manages **agent artifacts** (skills, MCP config, app config). The **binary and shell completions** ship via Homebrew — see [distribution-homebrew.md](distribution-homebrew.md).
4
4
 
5
- ## End-user install
5
+ Opt out with `install: { enabled: false }` on the program root.
6
6
 
7
- Ship a compiled binary (or app bundle). Users install interactively — no `--yes` required when stdin is a TTY:
7
+ ## End-user install (Homebrew)
8
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`**.
9
+ ```bash
10
+ brew tap <org>/<repo>
11
+ brew install <tap>/<key>
12
+ <key> install --configure # when app config is required (interactive)
13
+ ```
11
14
 
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`**).
15
+ Upgrade with `brew upgrade <key>`. Shell completions are installed by Homebrew during `brew install`. Users must configure their shell per [Homebrew Shell Completion](https://docs.brew.sh/Shell-Completion).
13
16
 
14
- **Uninstall is CLI-only** — there is no GUI uninstaller. Users run:
17
+ **Uninstall the binary:** `brew uninstall <key>`. Remove agent artifacts first (while the CLI is still on PATH):
15
18
 
16
19
  ```bash
17
- myapp install --uninstall # remove all detected artifacts
18
- myapp install --uninstall --app # scoped removal
20
+ <key> uninstall --yes
21
+ brew uninstall <tap>/<key>
19
22
  ```
20
23
 
21
- Non-interactive / CI: pass **`--yes`** (or **`--json`**, **`--reinstall`**, **`--update`**) — see [Confirmation](#confirmation).
22
-
23
- ## Quick start (automation)
24
+ ## Developer install
24
25
 
25
26
  ```bash
26
- # First-time setup (bare `install` is equivalent to `--all`)
27
- myapp install --yes
27
+ just build
28
+ just install-local # same formula as production; gen-dev-formula uses file:// URL (`just install` is an alias)
29
+ ```
28
30
 
29
- # Or explicitly
30
- myapp install --all --yes
31
+ Dev flow matches release: formula `install` copies the binary and generates completions; `post_install` runs `<key> install --reinstall --yes` for skills/MCP. Use `just reinstall-local` to swap the binary into Cellar during tight edit cycles (skips completions and `post_install`). Use `just install-artifacts` to refresh agent artifacts without touching the binary.
31
32
 
32
- # Refresh after upgrading (re-copy running app + refresh detected artifacts in scope)
33
- myapp install --reinstall
33
+ ## Quick reference
34
34
 
35
- # Upgrade to latest release (when this app supports remote updates)
36
- myapp install --update
35
+ ```bash
36
+ # Refresh skills/MCP after upgrade (Homebrew post_install runs this automatically)
37
+ <key> install --reinstall --yes
37
38
 
38
39
  # See what is installed
39
- myapp install --status
40
+ <key> install --status
40
41
 
41
- # Remove everything detected on disk (bare `install --uninstall` is equivalent to `--uninstall --all`)
42
- myapp install --uninstall --yes
42
+ # Configure app settings (interactive wizard — not part of --all or post_install)
43
+ <key> install --configure
44
+
45
+ # Remove agent artifacts (default: --all)
46
+ <key> uninstall --yes
43
47
  ```
44
48
 
49
+ Non-interactive / CI: pass **`--yes`** (or **`--json`**, **`--reinstall`**) — see [Confirmation](#confirmation).
50
+
45
51
  ## What gets installed
46
52
 
47
- | Target | Flag | Destination |
53
+ | Target | Flag | Mechanism |
48
54
  | --- | --- | --- |
49
- | App | `--app` | `~/.local/bin/<key>` |
50
- | Bash completion | `--completions` | `~/.bash_completion.d/<key>` + `.bashrc` PATH snippet |
51
- | Zsh completion | `--completions` | `~/.zsh/completions/_<key>` + `.zshrc` fpath snippet |
52
- | Fish completion | `--completions` | `~/.config/fish/completions/<key>.fish` |
53
- | Cursor skill | `--skill` | `~/.cursor/skills/<dir>/` when `~/.cursor` exists |
54
- | Claude skill | `--skill` | `~/.claude/skills/<dir>/` when `~/.claude` exists |
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 |
55
+ | Binary | Homebrew formula | `bin.install` in Formula |
56
+ | Shell completions | Homebrew formula | `generate_completions_from_executable` |
57
+ | Cursor skill | `--skill` / `--all` | `~/.cursor/skills/<dir>/` when `~/.cursor` exists |
58
+ | Claude skill | `--skill` / `--all` | `~/.claude/skills/<dir>/` when `~/.claude` exists |
59
+ | Codex / OpenCode / OpenClaw skills | `--skill` / `--all` | Agent-specific dirs when available |
60
+ | MCP config | `--mcp` / `--all` | Cursor, Claude Code/Desktop, OpenCode, Codex, OpenClaw, ChatGPT desktop |
61
+ | App config | `--configure` | Interactive wizard writes `~/.local/lib/<key>/config.json` |
62
+
63
+ ### Externally managed binary (Homebrew)
64
+
65
+ When **`PATH`** resolves the program key to the **running executable** (e.g. after `brew install`):
66
+
67
+ - **`install --status`** shows `app: system (PATH)`
68
+ - **`--all`** / **`--reinstall`** refresh skills and MCP only — not the binary or completions
69
+
70
+ MCP config uses the command name on **`PATH`**, not a Cellar path.
58
71
 
59
72
  ### Default `--all` behavior
60
73
 
61
74
  Bare **`install`** and **`install --all`** install targets with **`includedInAll: true`**. Core defaults:
62
75
 
63
- - **Always included:** `app`, `completions`, `configure` (wizard when `program.appConfig` is set)
64
76
  - **Agent integration** (`install.agentIntegration`, default from `mcpServer.enabled`):
65
77
  - **`skill`** (default when MCP off): all `*Skill` keys in `--all`; paired `*Mcp` keys excluded
66
78
  - **`mcp`** (default when `mcpServer.enabled`): all `*Mcp` keys in `--all`; paired skills excluded
67
79
  - **`both`**: MCP and skill for the same host when available
80
+ - **`configure`** is **opt-in** (`includedInAll: false`) — run **`install --configure`** separately
68
81
 
69
82
  Desktop-only MCP hosts (`claudeDesktopMcp`, `chatgptMcp`) follow the MCP side only — no skill pair.
70
83
 
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.
84
+ Scoped flags (`--skill`, `--mcp`, `--configure`) run that artifact category. Honor `enabled: false` as a hard off.
72
85
 
73
- Use **`install --status --json`** to preview effective targets (`effective.all`, `effective.mcp`, `effective.skill`) before installing.
86
+ Use **`install --status --json`** to preview effective targets before installing.
74
87
 
75
88
  ### Asymmetric uninstall
76
89
 
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.
90
+ The top-level **`uninstall`** command removes agent artifacts. Bare **`uninstall`** is equivalent to **`uninstall --all`**.
91
+
92
+ - **`uninstall --all`** removes **every detected artifact type**, ignoring `install.targets`.
93
+ - Scoped uninstall (`--skill`, `--mcp`, `--configure`, …) removes only that category.
79
94
 
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).
95
+ Missing targets are skipped silently.
81
96
 
82
97
  ## `install.targets`
83
98
 
84
- Configure which artifacts participate in `--all`, `--reinstall`, and `--update`:
99
+ Configure which artifacts participate in `--all`, `--reinstall`:
85
100
 
86
101
  ```typescript
87
102
  install: {
88
103
  agentIntegration: "mcp", // | "skill" | "both" — default from mcpServer.enabled
89
104
  targets: {
90
- app: { includedInAll: false },
91
105
  chatgptMcp: false,
92
106
  cursorSkill: { includedInAll: true },
93
107
  },
94
108
  },
95
109
  ```
96
110
 
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.
119
-
120
- ### Shell-only CLI (default)
121
-
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
- ```
145
-
146
- Preview resolved targets: **`myapp install --status --json`**.
147
-
148
- ## Configuration
149
-
150
- On the program root:
151
-
152
- ```typescript
153
- install: {
154
- enabled: false, // opt out of the install built-in
155
- updateGetLatest: async ({ version }) => {
156
- // download or locate latest release; return { path, version, cleanup }
157
- return { path: "/tmp/myapp", version: "2.0.0" };
158
- },
159
- }
160
- ```
161
-
162
- When `updateGetLatest` is set, ArgsBarg adds **`install --update`** (download latest release and reinstall installed artifacts in scope).
163
-
164
- ### GitHub releases (`ghReleaseUpdateGetLatest`)
165
-
166
- For compiled apps published via `gh release`, wire a hook without hand-rolling download logic:
111
+ `InstallTargetSpec` is `boolean` or `{ enabled?: boolean; includedInAll?: boolean }`.
167
112
 
168
- ```typescript
169
- import {
170
- createGhFetchLatest,
171
- createGhVersionCheck,
172
- ghReleaseUpdateGetLatest,
173
- } from "argsbarg";
174
-
175
- const cachePath = path.join(configDir, "version-check.json");
176
-
177
- install: {
178
- updateGetLatest: ghReleaseUpdateGetLatest({
179
- repo: "owner/repo",
180
- asset: "myapp",
181
- tempPrefix: "myapp-update.",
182
- cachePath,
183
- }),
184
- }
185
-
186
- // Optional: summary notice + background refresh
187
- const versionCheck = createGhVersionCheck({
188
- currentVersion: "1.0.0",
189
- commandName: "myapp",
190
- cachePath,
191
- fetchLatest: createGhFetchLatest({ repo: "owner/repo" }),
192
- });
193
- versionCheck.getUpdateNotice();
194
- versionCheck.refreshIfStale();
195
- ```
196
-
197
- Requires `gh` on PATH and `gh auth login`. Consumers keep app-specific config only (~15 lines).
113
+ Artifact keys: `chatgptMcp`, `claudeCodeMcp`, `claudeDesktopMcp`, `claudeSkill`, `codexMcp`, `codexSkill`, `configure`, `cursorMcp`, `cursorSkill`, `openclawMcp`, `openclawSkill`, `opencodeMcp`, `opencodeSkill`.
198
114
 
199
115
  ## App config (`program.appConfig`)
200
116
 
201
- When `program.appConfig` is set on the program root, ArgsBarg manages a flat JSON config file:
202
-
203
- ```typescript
204
- appConfig: {
205
- entries: {
206
- apiToken: {
207
- description: "Create at https://example.com/settings/tokens",
208
- env: "API_TOKEN",
209
- sensitive: true,
210
- },
211
- },
212
- },
213
- ```
214
-
215
- Config file path: `~/.local/lib/<sanitized-key>/config.json`.
117
+ When `program.appConfig` is set, ArgsBarg manages a flat JSON config file at `~/.local/lib/<sanitized-key>/config.json`.
216
118
 
217
119
  | Flag | Description |
218
120
  | --- | --- |
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>/`) |
121
+ | `--configure` | Interactive prompt; writes or updates the config file. **Not** included in `--all`. |
221
122
  | `--status` | Shows config path and which required keys are set or missing |
222
123
 
223
- **Configure UX** (TTY):
124
+ Use **`uninstall --configure`** to remove the config directory.
224
125
 
225
- ```
226
- Configuration Setup
126
+ Export helpers from `argsbarg`: `resolveAppConfigPath`, `displayAppConfigPath`.
127
+
128
+ ## `uninstall` command
227
129
 
228
- API token (API_TOKEN)
229
- Create at https://example.com/settings/tokens
230
- Current: REDACTED
231
- Value (Enter to copy from env):
130
+ Sibling of `install` for removing agent artifacts:
131
+
132
+ ```bash
133
+ <key> uninstall --yes # all artifacts (default)
134
+ <key> uninstall --configure --yes # config only
135
+ <key> uninstall --skill --yes # skills only
232
136
  ```
233
137
 
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).
138
+ Same behavior flags as install: `--yes`, `--dry`, `--json`. Does not support `--status` or `--reinstall`.
235
139
 
236
- ## Flags
140
+ ## Flags (`install`)
237
141
 
238
142
  ### Target flags
239
143
 
240
144
  | Flag | Description |
241
145
  | --- | --- |
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`) |
146
+ | `--all` | Install the default agent artifact set for this app |
147
+ | `--skill` | Install agent skills |
148
+ | `--mcp` | Add MCP server configuration |
149
+ | `--configure` | Run the interactive configuration wizard |
248
150
 
249
- ### Operation flags
151
+ ### Operation flags (`install`)
250
152
 
251
153
  | Flag | Description |
252
154
  | --- | --- |
253
155
  | `--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) |
156
+ | `--reinstall` | Refresh installed agent artifacts (Homebrew `post_install`; greenfield → full `--all` plan) |
157
+ | `--from <path>` | App executable reference for status detection (rare; default: running executable) |
258
158
 
259
159
  ### Behavior flags
260
160
 
261
161
  | Flag | Description |
262
162
  | --- | --- |
263
- | `--yes`, `-y` | Skip confirmation (required for non-TTY unless `--json`, `--reinstall`, or `--update`) |
264
- | `--dry` | Preview changes; per-step messages on stderr with `[dry run]` |
265
- | `--json` | Machine-readable output on stdout (implies `--yes`) |
163
+ | `--yes`, `-y` | Skip confirmation |
164
+ | `--dry` | Preview changes |
165
+ | `--json` | Machine-readable output (implies `--yes`) |
266
166
 
267
167
  ## Confirmation
268
168
 
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.
169
+ Install and uninstall (except `--yes`, `--json`, `--dry`, `--reinstall`) print a **`{app} Setup`** banner and numbered plan. Reply **`y`** for all, **`n`** or Enter to abort, or numbers for a subset.
270
170
 
271
171
  ## MCP merge behavior
272
172
 
@@ -276,15 +176,31 @@ When `--mcp` runs, entries are merged into host config with:
276
176
  { "command": "<root.key>", "args": ["mcp"] }
277
177
  ```
278
178
 
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.
179
+ If an existing entry differs, the command exits with an error unless `--yes` is passed.
180
+
181
+ ## Formula `post_install`
182
+
183
+ Release formulae should run:
184
+
185
+ ```ruby
186
+ def post_install
187
+ system bin/"myapp", "install", "--reinstall", "--yes"
188
+ end
189
+ ```
190
+
191
+ This refreshes skills/MCP without running the configure wizard (configure is opt-in).
192
+
193
+ ## Bootstrapping a new CLI
194
+
195
+ ```bash
196
+ bunx argsbarg create my-cli --key my-cli --class-name MyCli --tap org/repo --yes
197
+ bunx argsbarg create --check .
198
+ ```
199
+
200
+ See [distribution-homebrew.md](distribution-homebrew.md) and [../examples/full-example/README.md](../examples/full-example/README.md).
280
201
 
281
202
  ## Opt out
282
203
 
283
204
  ```typescript
284
- const cli = {
285
- key: "myapp",
286
- description: "...",
287
- install: { enabled: false },
288
- // ...
289
- } satisfies CliProgram;
205
+ install: { enabled: false },
290
206
  ```
package/docs/mcp.md CHANGED
@@ -131,7 +131,7 @@ Set `mcpServer` on the **program root only** (the `CliProgram` passed to `new Cl
131
131
  | --- | --- | --- |
132
132
  | `enabled` | *(required)* | Must be `true` when `mcpServer` is set |
133
133
  | `schemaResourceUri` | `<sanitized root key>://schema` | URI for the built-in schema resource |
134
- | `shellEnv` | off | Capture login-shell `env` at startup (`true` uses `$SHELL`, or pass a shell path) |
134
+ | `shellEnv` | on (opt-out with `false`) | Capture login-shell `env` at startup (`true` uses `$SHELL`, or pass a shell path) |
135
135
  | `resources` | `[]` | Custom `CliMcpResource` entries (additive; schema resource is always included) |
136
136
 
137
137
  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).
@@ -141,7 +141,7 @@ Example with optional fields:
141
141
  ```typescript
142
142
  mcpServer: {
143
143
  enabled: true,
144
- shellEnv: true,
144
+ shellEnv: false, // opt out of login-shell capture
145
145
  }
146
146
  ```
147
147
 
@@ -339,7 +339,6 @@ appConfig: {
339
339
  },
340
340
  mcpServer: {
341
341
  enabled: true,
342
- shellEnv: true,
343
342
  },
344
343
  ```
345
344
 
@@ -186,7 +186,7 @@ Per repo:
186
186
 
187
187
  Add a bullet under your app’s `**… conventions:**` block in `.cursor/rules/cli-program.mdc` pointing at `node_modules/argsbarg/docs/output-schema.md` and your `src/schemas/` layout.
188
188
 
189
- **Reference implementation:** [`examples/consumer-app/`](../examples/consumer-app/) in this repo (shipped in npm as `node_modules/argsbarg/examples/consumer-app/`) — discovery script, bridges, and `status` leaf with `outputSchema`.
189
+ **Reference implementation:** [`examples/full-example/`](../examples/full-example/) in this repo (shipped in npm as `node_modules/argsbarg/examples/full-example/`) — discovery script, bridges, and `status` leaf with `outputSchema`.
190
190
 
191
191
  ## Out of scope
192
192
 
File without changes
@@ -0,0 +1,98 @@
1
+ # full-example
2
+
3
+ **Full argsbarg reference app** — bootstrap new production CLIs with `bunx argsbarg create`.
4
+
5
+ ## What this demonstrates
6
+
7
+ | Area | Files / wiring |
8
+ | --- | --- |
9
+ | All builtins | `completion`, `version`, `install`, `docs`, `mcp`, `config get`/`set` |
10
+ | `program.appConfig` | `src/types.ts` (`AppConfig`) → `schemas/configSchemas.ts` |
11
+ | `outputSchema` | `src/commands/status/types.ts` (`StatusJsonOutput`) → `schemas/outputSchemas.ts` |
12
+ | Schemagen | `scripts/schemagen.ts` + `scripts/schemagen/discover-schema-roots.ts` |
13
+ | Command layout | `src/commands/<name>/command.ts`; registration in `src/program.ts` |
14
+ | MCP doc topics | `docs.topics` auto-exposed as `<key>://docs/<topic>` resources when docs + MCP enabled |
15
+ | Package import | `from "argsbarg"` (not relative to argsbarg `src/`) |
16
+ | Homebrew distribution | `scripts/formula-shared.ts`, `scripts/gen-dev-formula.ts`, `Formula/`, `justfile` |
17
+ | Dev tooling | Biome (`just format` / `just lint`), TypeScript, colocated tests |
18
+ | Cursor rules | `.cursor/rules/cli-program.mdc`, `.cursor/rules/code.mdc` |
19
+
20
+ ## Bootstrap a new CLI
21
+
22
+ Interactive (TTY):
23
+
24
+ ```bash
25
+ bunx argsbarg create my-cli
26
+ ```
27
+
28
+ Non-interactive:
29
+
30
+ ```bash
31
+ bunx argsbarg create my-cli \
32
+ --key my-cli --class-name MyCli --tap org/my-cli \
33
+ --homepage https://github.com/org/my-cli --release-repo org/my-cli \
34
+ --yes
35
+ ```
36
+
37
+ `create` copies this template (including `.cursor/rules/cli-program.mdc`), substitutes identity placeholders, runs `bun install`, schemagen, `bun test`, and `git init` + Initial commit when appropriate.
38
+
39
+ **Git bootstrap:** skipped when `{target}/.git` already exists, or when the target is inside an existing git work tree (monorepo subfolder). Standalone new directories get `Initial commit`.
40
+
41
+ To refresh the Cursor rule in an existing consumer: `bun scripts/merge-cli-program-rule.ts .` from an argsbarg checkout (or pass the npm package path to the template).
42
+
43
+ ## Quick start (in this repo)
44
+
45
+ ```bash
46
+ cd examples/full-example
47
+ just setup
48
+ just schemagen # after changing src/**/types.ts
49
+ FULL_EXAMPLE_API_TOKEN=dev just run status --json
50
+ FULL_EXAMPLE_API_TOKEN=dev just run config get apiToken --json
51
+ FULL_EXAMPLE_API_TOKEN=dev just run docs readme
52
+ ```
53
+
54
+ ## Homebrew dev install
55
+
56
+ Requires [Homebrew](https://brew.sh) and a compiled binary at `dist/full-example`:
57
+
58
+ ```bash
59
+ just build
60
+ just install-local # first-time dev formula (`just install` is an alias)
61
+ just reinstall-local # fast binary swap during development
62
+ just install-production # uninstall local dev, install from GitHub tap
63
+ just test-release
64
+ ```
65
+
66
+ Undo a local dev install:
67
+
68
+ ```bash
69
+ just uninstall # dev formula + agent artifacts
70
+ just uninstall-config # app config only
71
+ just uninstall-release # release formula (keeps tap)
72
+ ```
73
+
74
+ See [docs/distribution-homebrew.md](../../docs/distribution-homebrew.md).
75
+
76
+ ## Schemagen markers
77
+
78
+ | Marker in interface JSDoc | Artifact |
79
+ | --- | --- |
80
+ | `Config schema` | `schemas/configSchemas.ts` + `schemas/generated/*-config.json` |
81
+ | `JSON payload` | `schemas/outputSchemas.ts` + `schemas/generated/*.json` |
82
+
83
+ Discovery walks `src/**/types.ts` only.
84
+
85
+ ## Environment
86
+
87
+ | Variable | Purpose |
88
+ | --- | --- |
89
+ | `FULL_EXAMPLE_API_TOKEN` | Overrides `apiToken` via `program.appConfig` env mapping |
90
+
91
+ ## Maintainers (argsbarg repo)
92
+
93
+ When adding or changing builtins, update this example and run:
94
+
95
+ ```bash
96
+ just check-full-example # from argsbarg repo root
97
+ just test # from examples/full-example
98
+ ```
@@ -0,0 +1,22 @@
1
+ {
2
+ "$schema": "https://biomejs.dev/schemas/2.5.0/schema.json",
3
+ "assist": { "actions": { "source": { "organizeImports": "on" } } },
4
+ "linter": {
5
+ "enabled": true,
6
+ "rules": {
7
+ "preset": "recommended"
8
+ }
9
+ },
10
+ "formatter": {
11
+ "enabled": true,
12
+ "indentStyle": "space",
13
+ "lineWidth": 120
14
+ },
15
+ "overrides": [
16
+ {
17
+ "includes": ["**/*.json"],
18
+ "formatter": { "enabled": false },
19
+ "linter": { "enabled": false }
20
+ }
21
+ ]
22
+ }