argsbarg 4.1.1 → 5.0.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 (62) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/README.md +5 -5
  3. package/docs/README.md +3 -3
  4. package/docs/ai-skills.md +9 -9
  5. package/docs/bundled-docs.md +4 -4
  6. package/docs/cli-program.md +8 -8
  7. package/docs/config-schema.md +2 -2
  8. package/docs/configure.md +177 -0
  9. package/docs/developing.md +1 -1
  10. package/docs/distribution-homebrew.md +10 -9
  11. package/docs/mcp.md +9 -9
  12. package/examples/full-example/README.md +3 -3
  13. package/examples/full-example/justfile +6 -6
  14. package/examples/full-example/scripts/formula-shared.ts +2 -2
  15. package/examples/full-example/src/program.ts +3 -3
  16. package/examples/nested.ts +1 -1
  17. package/index.d.ts +23 -16
  18. package/package.json +1 -1
  19. package/src/builtins/builtins.test.ts +82 -61
  20. package/src/builtins/completion-group.ts +4 -6
  21. package/src/builtins/configure-copy.ts +86 -0
  22. package/src/builtins/configure.ts +70 -0
  23. package/src/builtins/dispatch.ts +13 -33
  24. package/src/builtins/index.ts +1 -1
  25. package/src/builtins/mcp.ts +2 -2
  26. package/src/builtins/registry.ts +6 -6
  27. package/src/capabilities.ts +22 -13
  28. package/src/cli-tool/cli-smoke.test.ts +13 -3
  29. package/src/cli-tool/create.test.ts +23 -1
  30. package/src/cli-tool/create.ts +26 -4
  31. package/src/cli-tool/full-example-capabilities.test.ts +2 -2
  32. package/src/cli-tool/program.ts +20 -5
  33. package/src/cli-tool/run-create.ts +8 -19
  34. package/src/config/bootstrap.ts +11 -9
  35. package/src/config/file.test.ts +1 -1
  36. package/src/config/resolve.ts +2 -2
  37. package/src/configure/configure.test.ts +148 -0
  38. package/src/configure/index.ts +284 -0
  39. package/src/configure/prompt.ts +40 -0
  40. package/src/docs/builtin.ts +3 -5
  41. package/src/docs/docs.test.ts +5 -5
  42. package/src/docs/mcp-guide.ts +4 -4
  43. package/src/index.ts +2 -2
  44. package/src/install/install-validate.test.ts +5 -5
  45. package/src/install/opts.ts +17 -0
  46. package/src/install/target-effective.ts +8 -8
  47. package/src/install/target-scope.ts +11 -8
  48. package/src/install/targets/configure.ts +1 -1
  49. package/src/install/targets.test.ts +4 -4
  50. package/src/invoke.test.ts +1 -1
  51. package/src/mcp/tools.ts +1 -1
  52. package/src/mcp.integration.test.ts +4 -4
  53. package/src/parse.test.ts +11 -13
  54. package/src/schema.ts +1 -9
  55. package/src/skill/hint.ts +2 -2
  56. package/src/types.ts +22 -14
  57. package/src/validate.ts +17 -17
  58. package/docs/install.md +0 -206
  59. package/src/builtins/install.ts +0 -106
  60. package/src/builtins/uninstall.ts +0 -80
  61. package/src/install/index.ts +0 -409
  62. package/src/install/install.test.ts +0 -317
@@ -35,7 +35,7 @@ test("collectMcpTools lists user leaf commands only", () => {
35
35
  expect(names).toContain("stat_owner_lookup");
36
36
  expect(names).toContain("read");
37
37
  expect(names).not.toContain("hidden");
38
- expect(names).not.toContain("install");
38
+ expect(names).not.toContain("configure");
39
39
  expect(names).not.toContain("mcp");
40
40
  expect(names).not.toContain("completion");
41
41
  const lookup = tools.find((t) => t.name === "stat_owner_lookup")!;
@@ -242,19 +242,19 @@ test("mcpToolCallToArgv expands varargs positionals", () => {
242
242
  expect(argv).toEqual(["read", "a", "b"]);
243
243
  });
244
244
 
245
- test("reserved command name install is rejected", () => {
245
+ test("reserved command name configure is rejected", () => {
246
246
  const root = testProgram({
247
247
  key: "app",
248
248
  description: "",
249
249
  commands: [
250
250
  {
251
- key: "install",
251
+ key: "configure",
252
252
  description: "bad",
253
253
  handler: () => {},
254
254
  },
255
255
  ],
256
256
  });
257
- expect(() => cliValidateProgram(root)).toThrow(/Reserved command name: install/);
257
+ expect(() => cliValidateProgram(root)).toThrow(/Reserved command name: configure/);
258
258
  });
259
259
 
260
260
  test("top-level command name mcp is allowed without mcpServer", () => {
package/src/parse.test.ts CHANGED
@@ -526,10 +526,8 @@ test("docs schema exports JSON for leaf roots", async () => {
526
526
  expect(schema.positionals[0].name).toBe("name");
527
527
  expect(schema.options[0].name).toBe("verbose");
528
528
  expect(schema.commands.map((c: { key: string }) => c.key)).toEqual([
529
- "completion",
530
529
  "version",
531
- "install",
532
- "uninstall",
530
+ "configure",
533
531
  "docs",
534
532
  ]);
535
533
  });
@@ -540,11 +538,11 @@ test("version builtin prints program version", async () => {
540
538
  expect(stdout.toString().trim()).toMatch(/^\d+\.\d+\.\d+/);
541
539
  });
542
540
 
543
- test("leaf root help lists completion built-in", async () => {
541
+ test("leaf root help omits hidden completion built-in", async () => {
544
542
  const { stdout, exitCode } = await $`bun run examples/minimal.ts -h`.nothrow().quiet();
545
543
  expect(exitCode).toBe(0);
546
- expect(stdout.toString()).toContain("completion");
547
- expect(stdout.toString()).toContain("Generate the autocompletion script for shells.");
544
+ expect(stdout.toString()).not.toContain("completion");
545
+ expect(stdout.toString()).toContain("configure");
548
546
  });
549
547
 
550
548
  test("root --schema is no longer a flag", () => {
@@ -1108,7 +1106,7 @@ test("mcpToolCallToArgv empty array varargs errors when required", () => {
1108
1106
 
1109
1107
  // ── Skills ────────────────────────────────────────────────────────────────────
1110
1108
 
1111
- test("install config on non-root node is rejected", () => {
1109
+ test("configure config on non-root node is rejected", () => {
1112
1110
  const root = {
1113
1111
  key: "app",
1114
1112
  version: "0.0.0",
@@ -1117,23 +1115,23 @@ test("install config on non-root node is rejected", () => {
1117
1115
  {
1118
1116
  key: "x",
1119
1117
  description: "",
1120
- install: { enabled: false },
1118
+ configure: { enabled: false },
1121
1119
  handler: () => {},
1122
1120
  },
1123
1121
  ],
1124
1122
  } as unknown as CliProgram;
1125
- expect(() => cliValidateProgram(root)).toThrow(/install is only supported on the program root/);
1123
+ expect(() => cliValidateProgram(root)).toThrow(/configure is only supported on the program root/);
1126
1124
  });
1127
1125
 
1128
- test("install.prefix is rejected", () => {
1126
+ test("configure.prefix is rejected", () => {
1129
1127
  const root = {
1130
1128
  key: "app",
1131
1129
  version: "0.0.0",
1132
1130
  description: "",
1133
- install: { prefix: "/opt/bin" },
1131
+ configure: { prefix: "/opt/bin" },
1134
1132
  handler: () => {},
1135
1133
  } as unknown as CliProgram;
1136
- expect(() => cliValidateProgram(root)).toThrow(/install\.prefix removed/);
1134
+ expect(() => cliValidateProgram(root)).toThrow(/configure\.prefix removed/);
1137
1135
  });
1138
1136
 
1139
1137
  test("generateSkillBundle includes frontmatter and compact command index", () => {
@@ -1184,7 +1182,7 @@ test("cliSkillInstall writes project Cursor skill files", () => {
1184
1182
  expect(readFileSync(join(skillDir, "reference.md"), "utf8")).toContain("CLI API reference");
1185
1183
  const skillText = readFileSync(join(skillDir, "SKILL.md"), "utf8");
1186
1184
  expect(skillText.startsWith("---\n")).toBe(true);
1187
- const hint = "<!-- Generated by nested.ts install --skill; do not edit. -->";
1185
+ const hint = "<!-- Generated by nested.ts configure; do not edit. -->";
1188
1186
  expect(skillText.indexOf(hint)).toBeGreaterThan(skillText.indexOf("---\n", 4));
1189
1187
  const refText = readFileSync(join(skillDir, "reference.md"), "utf8");
1190
1188
  expect(refText.startsWith(hint)).toBe(true);
package/src/schema.ts CHANGED
@@ -13,15 +13,7 @@ import {
13
13
  leafOutputSchema,
14
14
  } from "./types.ts";
15
15
 
16
- const RESERVED = new Set([
17
- "completion",
18
- "install",
19
- "uninstall",
20
- "docs",
21
- "mcp",
22
- "version",
23
- "config",
24
- ]);
16
+ const RESERVED = new Set(["completion", "configure", "docs", "mcp", "version", "config"]);
25
17
 
26
18
  function exportCommand(cmd: CliNode, root: CliProgram): CliSchemaExport | null {
27
19
  if (cmd.hidden) {
package/src/skill/hint.ts CHANGED
@@ -23,9 +23,9 @@ export function insertGeneratedHint(
23
23
  return `${hint}${content}`;
24
24
  }
25
25
 
26
- /** Hint for `install --skill` output files. */
26
+ /** Hint for `configure` skill output files. */
27
27
  export function skillInstallHint(program: CliProgram): string {
28
- return generatedFileHtmlComment(`${program.key} install --skill`);
28
+ return generatedFileHtmlComment(`${program.key} configure`);
29
29
  }
30
30
 
31
31
  /** Applies install hints to SKILL.md (after frontmatter) and reference.md. */
package/src/types.ts CHANGED
@@ -261,18 +261,24 @@ export interface CliAppConfig {
261
261
  entries: Record<string, CliAppConfigEntry>;
262
262
  }
263
263
 
264
- export interface CliInstallConfig {
265
- /** When `false`, hide/disable `install` (default: enabled). */
264
+ /** Opt-out for the `completion` built-in (default: enabled). */
265
+ export interface CliCompletionConfig {
266
+ /** When `false`, hide/disable `completion` (default: enabled). */
267
+ enabled?: boolean;
268
+ }
269
+
270
+ export interface CliConfigureConfig {
271
+ /** When `false`, hide/disable `configure` (default: enabled). */
266
272
  enabled?: boolean;
267
273
  /**
268
- * Default agent integration for full install (`install --all`).
269
- * - `'mcp'` when `mcpServer.enabled` (default): MCP targets in `--all`; paired skills excluded.
270
- * - `'skill'` when MCP is off (default): skill targets in `--all`; paired MCP excluded.
271
- * - `'both'`: install MCP and skill for the same host when both are available.
274
+ * Default agent integration for sync (`configure --sync`).
275
+ * - `'mcp'` when `mcpServer.enabled` (default): MCP targets in sync; paired skills excluded.
276
+ * - `'skill'` when MCP is off (default): skill targets in sync; paired MCP excluded.
277
+ * - `'both'`: sync MCP and skill for the same host when both are available.
272
278
  */
273
279
  agentIntegration?: InstallAgentIntegration;
274
- /** Per-artifact gates for full install/uninstall. See {@link resolveEffectiveInstallTargets}. */
275
- targets?: CliInstallTargets;
280
+ /** Per-artifact gates for configure sync and interactive wizard. See {@link resolveEffectiveInstallTargets}. */
281
+ targets?: CliConfigureTargets;
276
282
  }
277
283
 
278
284
  /** Agent integration mode for install — MCP vs shell skill per host. */
@@ -284,7 +290,7 @@ export type InstallTargetSpec =
284
290
  | {
285
291
  /** When false, artifact is never installed (even with scoped CLI flags). Default true. */
286
292
  enabled?: boolean;
287
- /** When true, included in bare `install` / `install --all`. Default varies by key. */
293
+ /** When true, included in `configure --sync`. Default varies by key. */
288
294
  includedInAll?: boolean;
289
295
  };
290
296
 
@@ -293,8 +299,8 @@ export interface ResolvedInstallTarget {
293
299
  includedInAll: boolean;
294
300
  }
295
301
 
296
- /** Per-artifact gates for full install/uninstall. See {@link resolveEffectiveInstallTargets}. */
297
- export interface CliInstallTargets {
302
+ /** Per-artifact gates for configure. See {@link resolveEffectiveInstallTargets}. */
303
+ export interface CliConfigureTargets {
298
304
  /** App binary status only (Homebrew PATH); no self-install. */
299
305
  app?: InstallTargetSpec;
300
306
  /** ChatGPT desktop MCP. Default false. */
@@ -309,7 +315,7 @@ export interface CliInstallTargets {
309
315
  codexMcp?: InstallTargetSpec;
310
316
  /** Codex skill. Default false. */
311
317
  codexSkill?: InstallTargetSpec;
312
- /** App config: wizard via install --configure only. Default not in --all. */
318
+ /** App config: interactive wizard step in `configure`. Default not in sync. */
313
319
  configure?: InstallTargetSpec;
314
320
  /** Cursor MCP. Default false. */
315
321
  cursorMcp?: InstallTargetSpec;
@@ -414,8 +420,10 @@ export type CliProgram = CliNode & {
414
420
  appConfig?: CliAppConfig;
415
421
  /** When set with `enabled: true`, enables the `mcp` built-in subcommand. */
416
422
  mcpServer?: CliMcpServerConfig;
417
- /** Opt-out and defaults for `install`. */
418
- install?: CliInstallConfig;
423
+ /** Opt-out and defaults for `configure`. */
424
+ configure?: CliConfigureConfig;
425
+ /** Opt-out for shell completion generation (`completion bash|zsh|fish`). */
426
+ completion?: CliCompletionConfig;
419
427
  /** When set with `enabled: true`, enables the `docs` built-in command group. */
420
428
  docs?: CliDocsConfig;
421
429
  };
package/src/validate.ts CHANGED
@@ -127,28 +127,28 @@ function installTargetExplicitTruthy(spec: InstallTargetSpec | undefined): boole
127
127
  return spec.enabled !== false;
128
128
  }
129
129
 
130
- /** Validates `program.install` targets and agentIntegration. */
131
- function validateInstallConfig(program: CliProgram): void {
132
- const install = program.install;
133
- if (!install) return;
130
+ /** Validates `program.configure` targets and agentIntegration. */
131
+ function validateConfigureConfig(program: CliProgram): void {
132
+ const configure = program.configure;
133
+ if (!configure) return;
134
134
 
135
- if ("prefix" in install) {
135
+ if ("prefix" in configure) {
136
136
  throw new CliSchemaValidationError(
137
- "install.prefix removed; app installs to ~/.local/bin/<key>",
137
+ "configure.prefix removed; app binary installs via Homebrew",
138
138
  );
139
139
  }
140
140
 
141
- if (!install.targets) return;
141
+ if (!configure.targets) return;
142
142
 
143
- const targets = install.targets;
143
+ const targets = configure.targets;
144
144
  if ("allSkills" in targets || "allMcps" in targets) {
145
145
  throw new CliSchemaValidationError(
146
- "install.targets.allSkills/allMcps removed; use agentIntegration and per-key targets",
146
+ "configure.targets.allSkills/allMcps removed; use agentIntegration and per-key targets",
147
147
  );
148
148
  }
149
149
 
150
150
  const integration: InstallAgentIntegration =
151
- install.agentIntegration ?? (program.mcpServer?.enabled === true ? "mcp" : "skill");
151
+ configure.agentIntegration ?? (program.mcpServer?.enabled === true ? "mcp" : "skill");
152
152
 
153
153
  for (const [mcpKey, skillKey] of AGENT_PAIRS) {
154
154
  const mcpSpec = targets[mcpKey];
@@ -159,18 +159,18 @@ function validateInstallConfig(program: CliProgram): void {
159
159
 
160
160
  if (mcpOn && skillOn && integration !== "both") {
161
161
  throw new CliSchemaValidationError(
162
- `install.targets: ${host} has both MCP and skill configured; set agentIntegration: 'both' or disable one side`,
162
+ `configure.targets: ${host} has both MCP and skill configured; set agentIntegration: 'both' or disable one side`,
163
163
  );
164
164
  }
165
165
 
166
166
  if (integration === "skill" && mcpOn) {
167
167
  throw new CliSchemaValidationError(
168
- `install.targets.${mcpKey} requires agentIntegration: 'both' when agentIntegration is 'skill'`,
168
+ `configure.targets.${mcpKey} requires agentIntegration: 'both' when agentIntegration is 'skill'`,
169
169
  );
170
170
  }
171
171
  if (integration === "mcp" && skillOn) {
172
172
  throw new CliSchemaValidationError(
173
- `install.targets.${skillKey} requires agentIntegration: 'both' when agentIntegration is 'mcp'`,
173
+ `configure.targets.${skillKey} requires agentIntegration: 'both' when agentIntegration is 'mcp'`,
174
174
  );
175
175
  }
176
176
  }
@@ -202,8 +202,8 @@ export function cliValidateProgram(program: CliProgram): void {
202
202
  validateConfigBlock(program.appConfig);
203
203
  }
204
204
 
205
- if (program.install !== undefined) {
206
- validateInstallConfig(program);
205
+ if (program.configure !== undefined) {
206
+ validateConfigureConfig(program);
207
207
  }
208
208
 
209
209
  const caps = resolveCapabilities(program);
@@ -228,9 +228,9 @@ function walkNode(node: CliNode, program: CliProgram, isRoot: boolean): void {
228
228
  `mcpServer is only supported on the program root (not on ${node.key})`,
229
229
  );
230
230
  }
231
- if (rogue.install !== undefined) {
231
+ if (rogue.configure !== undefined) {
232
232
  throw new CliSchemaValidationError(
233
- `install is only supported on the program root (not on ${node.key})`,
233
+ `configure is only supported on the program root (not on ${node.key})`,
234
234
  );
235
235
  }
236
236
  if (rogue.docs !== undefined) {
package/docs/install.md DELETED
@@ -1,206 +0,0 @@
1
- # Install command
2
-
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
-
5
- Opt out with `install: { enabled: false }` on the program root.
6
-
7
- ## End-user install (Homebrew)
8
-
9
- ```bash
10
- brew tap <org>/<repo>
11
- brew install <tap>/<key>
12
- <key> install --configure # when app config is required (interactive)
13
- ```
14
-
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).
16
-
17
- **Uninstall the binary:** `brew uninstall <key>`. Remove agent artifacts first (while the CLI is still on PATH):
18
-
19
- ```bash
20
- <key> uninstall --yes
21
- brew uninstall <tap>/<key>
22
- ```
23
-
24
- ## Developer install
25
-
26
- ```bash
27
- just build
28
- just install-local # same formula as production; gen-dev-formula uses file:// URL (`just install` is an alias)
29
- ```
30
-
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.
32
-
33
- ## Quick reference
34
-
35
- ```bash
36
- # Refresh skills/MCP after upgrade (Homebrew post_install runs this automatically)
37
- <key> install --reinstall --yes
38
-
39
- # See what is installed
40
- <key> install --status
41
-
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
47
- ```
48
-
49
- Non-interactive / CI: pass **`--yes`** (or **`--json`**, **`--reinstall`**) — see [Confirmation](#confirmation).
50
-
51
- ## What gets installed
52
-
53
- | Target | Flag | Mechanism |
54
- | --- | --- | --- |
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.
71
-
72
- ### Default `--all` behavior
73
-
74
- Bare **`install`** and **`install --all`** install targets with **`includedInAll: true`**. Core defaults:
75
-
76
- - **Agent integration** (`install.agentIntegration`, default from `mcpServer.enabled`):
77
- - **`skill`** (default when MCP off): all `*Skill` keys in `--all`; paired `*Mcp` keys excluded
78
- - **`mcp`** (default when `mcpServer.enabled`): all `*Mcp` keys in `--all`; paired skills excluded
79
- - **`both`**: MCP and skill for the same host when available
80
- - **`configure`** is **opt-in** (`includedInAll: false`) — run **`install --configure`** separately
81
-
82
- Desktop-only MCP hosts (`claudeDesktopMcp`, `chatgptMcp`) follow the MCP side only — no skill pair.
83
-
84
- Scoped flags (`--skill`, `--mcp`, `--configure`) run that artifact category. Honor `enabled: false` as a hard off.
85
-
86
- Use **`install --status --json`** to preview effective targets before installing.
87
-
88
- ### Asymmetric uninstall
89
-
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.
94
-
95
- Missing targets are skipped silently.
96
-
97
- ## `install.targets`
98
-
99
- Configure which artifacts participate in `--all`, `--reinstall`:
100
-
101
- ```typescript
102
- install: {
103
- agentIntegration: "mcp", // | "skill" | "both" — default from mcpServer.enabled
104
- targets: {
105
- chatgptMcp: false,
106
- cursorSkill: { includedInAll: true },
107
- },
108
- },
109
- ```
110
-
111
- `InstallTargetSpec` is `boolean` or `{ enabled?: boolean; includedInAll?: boolean }`.
112
-
113
- Artifact keys: `chatgptMcp`, `claudeCodeMcp`, `claudeDesktopMcp`, `claudeSkill`, `codexMcp`, `codexSkill`, `configure`, `cursorMcp`, `cursorSkill`, `openclawMcp`, `openclawSkill`, `opencodeMcp`, `opencodeSkill`.
114
-
115
- ## App config (`program.appConfig`)
116
-
117
- When `program.appConfig` is set, ArgsBarg manages a flat JSON config file at `~/.local/lib/<sanitized-key>/config.json`.
118
-
119
- | Flag | Description |
120
- | --- | --- |
121
- | `--configure` | Interactive prompt; writes or updates the config file. **Not** included in `--all`. |
122
- | `--status` | Shows config path and which required keys are set or missing |
123
-
124
- Use **`uninstall --configure`** to remove the config directory.
125
-
126
- Export helpers from `argsbarg`: `resolveAppConfigPath`, `displayAppConfigPath`.
127
-
128
- ## `uninstall` command
129
-
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
136
- ```
137
-
138
- Same behavior flags as install: `--yes`, `--dry`, `--json`. Does not support `--status` or `--reinstall`.
139
-
140
- ## Flags (`install`)
141
-
142
- ### Target flags
143
-
144
- | Flag | Description |
145
- | --- | --- |
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 |
150
-
151
- ### Operation flags (`install`)
152
-
153
- | Flag | Description |
154
- | --- | --- |
155
- | `--status` | Read-only inventory |
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) |
158
-
159
- ### Behavior flags
160
-
161
- | Flag | Description |
162
- | --- | --- |
163
- | `--yes`, `-y` | Skip confirmation |
164
- | `--dry` | Preview changes |
165
- | `--json` | Machine-readable output (implies `--yes`) |
166
-
167
- ## Confirmation
168
-
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.
170
-
171
- ## MCP merge behavior
172
-
173
- When `--mcp` runs, entries are merged into host config with:
174
-
175
- ```json
176
- { "command": "<root.key>", "args": ["mcp"] }
177
- ```
178
-
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).
201
-
202
- ## Opt out
203
-
204
- ```typescript
205
- install: { enabled: false },
206
- ```
@@ -1,106 +0,0 @@
1
- import { resolveCapabilities } from "../capabilities.ts";
2
- import { type CliLeaf, type CliOption, CliOptionKind, type CliProgram } from "../types.ts";
3
-
4
- /** Install command options (dynamic: `--mcp` only when MCP is enabled). */
5
- export function installBuiltinOptions(root: CliProgram): CliOption[] {
6
- const opts: CliOption[] = [
7
- {
8
- name: "all",
9
- description: "Install agent skills and MCP config (default artifact set for this app).",
10
- kind: CliOptionKind.Presence,
11
- },
12
- {
13
- name: "skill",
14
- description:
15
- "Install agent skills for Cursor, Claude, and other supported AI tools on this machine.",
16
- kind: CliOptionKind.Presence,
17
- },
18
- ];
19
-
20
- if (resolveCapabilities(root).mcp) {
21
- opts.push({
22
- name: "mcp",
23
- description:
24
- "Add MCP server configuration for Cursor, Claude Code, and other supported agents.",
25
- kind: CliOptionKind.Presence,
26
- });
27
- }
28
-
29
- if (root.appConfig) {
30
- opts.push({
31
- name: "configure",
32
- description: "Run the interactive configuration wizard.",
33
- kind: CliOptionKind.Presence,
34
- });
35
- }
36
-
37
- opts.push(
38
- {
39
- name: "status",
40
- description: "Print what is currently installed (read-only).",
41
- kind: CliOptionKind.Presence,
42
- },
43
- {
44
- name: "reinstall",
45
- description:
46
- "Refresh installed agent artifacts (skills, MCP). Used by Homebrew post_install.",
47
- kind: CliOptionKind.Presence,
48
- },
49
- {
50
- name: "yes",
51
- description: "Skip the confirmation prompt.",
52
- kind: CliOptionKind.Presence,
53
- shortName: "y",
54
- },
55
- {
56
- name: "dry",
57
- description: "Show what would change without writing files.",
58
- kind: CliOptionKind.Presence,
59
- },
60
- {
61
- name: "json",
62
- description: "Print changed paths (install/reinstall) or status JSON on stdout.",
63
- kind: CliOptionKind.Presence,
64
- },
65
- );
66
-
67
- return opts;
68
- }
69
-
70
- /** Builds the `install` built-in command. */
71
- export function cliBuiltinInstallCommand(root: CliProgram): CliLeaf {
72
- const app = root.key;
73
- const notesLines = [
74
- "Install the binary via Homebrew (tap-from-repo), then refresh agent artifacts:",
75
- ` brew tap <org>/<repo>`,
76
- ` brew install <tap>/${app}`,
77
- "",
78
- "Homebrew post_install runs:",
79
- ` ${app} install --reinstall --yes`,
80
- "",
81
- "Configure separately (interactive):",
82
- ` ${app} install --configure`,
83
- "",
84
- "Upgrade:",
85
- ` brew upgrade ${app}`,
86
- "",
87
- "Shell completions are installed by Homebrew during brew install.",
88
- "See: https://docs.brew.sh/Shell-Completion",
89
- "",
90
- "See what is installed:",
91
- ` ${app} install --status`,
92
- "",
93
- "Remove agent artifacts:",
94
- ` ${app} uninstall --yes`,
95
- "",
96
- "Use --dry to preview changes without writing files.",
97
- "Use --json for machine-readable output.",
98
- ];
99
- return {
100
- key: "install",
101
- description: "Install agent skills and MCP config for this app (binary via Homebrew).",
102
- options: installBuiltinOptions(root),
103
- notes: notesLines.join("\n"),
104
- handler: () => {},
105
- };
106
- }