argsbarg 5.1.12 → 5.1.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -3
- package/docs/configure.md +6 -5
- package/docs/distribution-homebrew.md +6 -6
- package/docs/output-schema.md +1 -1
- package/examples/full-example/scripts/formula-shared.ts +5 -2
- package/package.json +1 -1
- package/src/builtins/configure-copy.ts +2 -3
- package/src/configure/configure.test.ts +42 -1
- package/src/configure/index.ts +12 -2
- package/src/install/target-skill.ts +2 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,7 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
-
## [5.1.
|
|
10
|
+
## [5.1.14] - 2026-07-06
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## [5.1.13] - 2026-07-06
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **`configure --remove-all`** — skill uninstall actions no longer reinstall skills after printing "Removing …".
|
|
18
|
+
- **Interactive `configure`** — choosing `n` on an installed skill now removes the skill directory (same bug as `--remove-all`, different code path).
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
|
|
22
|
+
- **Homebrew formula `uninstall`** — generated formulae run `{key} configure --remove-all --yes` (skills, MCP, and app config).
|
|
11
23
|
|
|
12
24
|
### Changed
|
|
13
25
|
|
|
@@ -665,8 +677,9 @@ const cli = { ... } satisfies CliProgram; // or : CliProgram
|
|
|
665
677
|
- 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`).
|
|
666
678
|
- Imports: use `CliPositional` where needed; replace `CliOptionDef` with `CliOption` or `CliPositional` as appropriate.
|
|
667
679
|
|
|
668
|
-
[Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v5.1.
|
|
669
|
-
[5.1.
|
|
680
|
+
[Unreleased]: https://github.com/bdombro/bun-argsbarg/compare/v5.1.14...HEAD
|
|
681
|
+
[5.1.14]: https://github.com/bdombro/bun-argsbarg/releases/tag/v5.1.14
|
|
682
|
+
[5.1.13]: https://github.com/bdombro/bun-argsbarg/releases/tag/v5.1.13
|
|
670
683
|
[5.1.11]: https://github.com/bdombro/bun-argsbarg/releases/tag/v5.1.11
|
|
671
684
|
[5.1.10]: https://github.com/bdombro/bun-argsbarg/releases/tag/v5.1.10
|
|
672
685
|
[5.1.9]: https://github.com/bdombro/bun-argsbarg/releases/tag/v5.1.9
|
package/docs/configure.md
CHANGED
|
@@ -16,14 +16,15 @@ brew install <tap>/<key>
|
|
|
16
16
|
|
|
17
17
|
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).
|
|
18
18
|
|
|
19
|
-
**Uninstall the binary:**
|
|
19
|
+
**Uninstall the binary:**
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
<key> configure --remove-all --yes
|
|
23
22
|
brew uninstall <tap>/<key>
|
|
24
23
|
```
|
|
25
24
|
|
|
26
|
-
`brew uninstall` runs the formula `uninstall` hook
|
|
25
|
+
`brew uninstall` runs the formula `uninstall` hook (`configure --remove-all --yes`), which removes detected skills, MCP entries, and app config while the binary is still on PATH.
|
|
26
|
+
|
|
27
|
+
To remove app config only (keep skills/MCP), run `configure --remove-config --yes` before uninstall.
|
|
27
28
|
|
|
28
29
|
## Developer install
|
|
29
30
|
|
|
@@ -177,11 +178,11 @@ Release formulae should run:
|
|
|
177
178
|
|
|
178
179
|
```ruby
|
|
179
180
|
def uninstall
|
|
180
|
-
system bin/"myapp", "configure", "--remove-
|
|
181
|
+
system bin/"myapp", "configure", "--remove-all", "--yes"
|
|
181
182
|
end
|
|
182
183
|
```
|
|
183
184
|
|
|
184
|
-
|
|
185
|
+
Removes detected skills, MCP entries, and app config while the binary is still on PATH. Safe no-op when nothing was installed.
|
|
185
186
|
|
|
186
187
|
## Bootstrapping a new CLI
|
|
187
188
|
|
|
@@ -10,7 +10,7 @@ Argsbarg apps distribute the **binary and shell completions** through Homebrew,
|
|
|
10
10
|
| Skills + MCP | Formula `post_install` → `{key} configure --sync --yes` |
|
|
11
11
|
| App config file | Bootstrapped as `{}` on `post_install` via `--sync` (`~/.local/lib/<key>/config.json`) |
|
|
12
12
|
| App config values | User opt-in: `{key} configure` (interactive wizard when `program.appConfig` has entries) |
|
|
13
|
-
| App config cleanup | Formula `uninstall` → `{key} configure --remove-
|
|
13
|
+
| App config cleanup | Formula `uninstall` → `{key} configure --remove-all --yes` |
|
|
14
14
|
|
|
15
15
|
**Only tap-from-repo** — in-repo `Formula/` or GitHub tap. Not Homebrew core.
|
|
16
16
|
|
|
@@ -62,13 +62,13 @@ If `brew install` fails, run `bun scripts/dev-formula.ts reset` manually to rest
|
|
|
62
62
|
|
|
63
63
|
| Recipe | Removes |
|
|
64
64
|
| --- | --- |
|
|
65
|
-
| `just uninstall` | Formula `{key}` + tap symlink + skills/MCP
|
|
65
|
+
| `just uninstall` | Formula `{key}` + tap symlink + skills/MCP + app config via formula `uninstall` |
|
|
66
66
|
| `just uninstall-config` | App config file only (`configure --remove-config --yes`) |
|
|
67
|
-
| `just uninstall-release` | Release formula from `{tap}` (keeps tap;
|
|
68
|
-
| `just uninstall-release-tap` | Release formula + `brew untap {tap}` (
|
|
67
|
+
| `just uninstall-release` | Release formula from `{tap}` (keeps tap; agent artifacts via formula `uninstall`) |
|
|
68
|
+
| `just uninstall-release-tap` | Release formula + `brew untap {tap}` (agent artifacts via formula `uninstall`) |
|
|
69
69
|
| `just test-release` | Install release formula and run formula test |
|
|
70
70
|
|
|
71
|
-
End users:
|
|
71
|
+
End users: `brew uninstall <tap>/<key>`. The formula `uninstall` hook runs `configure --remove-all --yes` (skills, MCP, and app config).
|
|
72
72
|
|
|
73
73
|
## Formula pattern
|
|
74
74
|
|
|
@@ -83,7 +83,7 @@ def post_install
|
|
|
83
83
|
end
|
|
84
84
|
|
|
85
85
|
def uninstall
|
|
86
|
-
system bin/"{key}", "configure", "--remove-
|
|
86
|
+
system bin/"{key}", "configure", "--remove-all", "--yes"
|
|
87
87
|
end
|
|
88
88
|
```
|
|
89
89
|
|
package/docs/output-schema.md
CHANGED
|
@@ -43,7 +43,7 @@ Production CLIs with several JSON commands tend to use **codegen** so types, han
|
|
|
43
43
|
|
|
44
44
|
## Recommended pipeline (copy per repo)
|
|
45
45
|
|
|
46
|
-
No shared npm package — each app copies the same **contract**. Reference implementations: **sqsp-qa-manager-poc**, **
|
|
46
|
+
No shared npm package — each app copies the same **contract**. Reference implementations: **sqsp-qa-manager-poc**, **sqsp-workspaces**, **sqsp-i18n-tools-poc** (see each repo’s `docs/architecture.md` for which commands use which schema root).
|
|
47
47
|
|
|
48
48
|
```mermaid
|
|
49
49
|
flowchart LR
|
|
@@ -24,7 +24,7 @@ export const formulaPostInstallRuby = `def post_install
|
|
|
24
24
|
end`;
|
|
25
25
|
|
|
26
26
|
export const formulaUninstallRuby = `def uninstall
|
|
27
|
-
system bin/"${key}", "configure", "--remove-
|
|
27
|
+
system bin/"${key}", "configure", "--remove-all", "--yes"
|
|
28
28
|
end`;
|
|
29
29
|
|
|
30
30
|
export const formulaCaveatsRuby = `def caveats
|
|
@@ -80,7 +80,10 @@ export function selectStaleReleaseTags(releases: ReleaseTag[]): string[] {
|
|
|
80
80
|
export const releaseRepoSlug = releaseRepo;
|
|
81
81
|
|
|
82
82
|
/** Resolves private GitHub release assets via the API at download time. */
|
|
83
|
-
export const githubPrivateReleaseDownloadStrategyRuby = `
|
|
83
|
+
export const githubPrivateReleaseDownloadStrategyRuby = ` # Private/internal releases: default CurlDownloadStrategy cannot fetch non-public
|
|
84
|
+
# GitHub release assets. Resolve the asset via the API and authenticate with
|
|
85
|
+
# GitHub::API.credentials (set up via \`gh auth login\` or HOMEBREW_GITHUB_API_TOKEN).
|
|
86
|
+
class GitHubPrivateReleaseDownloadStrategy < CurlDownloadStrategy
|
|
84
87
|
def initialize(url, name, version, **meta)
|
|
85
88
|
super
|
|
86
89
|
pattern = %r{https://github\\.com/([^/]+)/([^/]+)/releases/download/([^/]+)/(\\S+)}
|
package/package.json
CHANGED
|
@@ -68,11 +68,10 @@ export function configureCommandNotes(program: CliProgram, _caps: CliCapabilitie
|
|
|
68
68
|
"See what is installed:",
|
|
69
69
|
` ${app} configure --status`,
|
|
70
70
|
"",
|
|
71
|
-
"
|
|
72
|
-
` ${app} configure --remove-all --yes`,
|
|
71
|
+
"Uninstall:",
|
|
73
72
|
` brew uninstall <tap>/${app}`,
|
|
74
73
|
"",
|
|
75
|
-
"
|
|
74
|
+
"The formula uninstall hook runs `configure --remove-all --yes` (skills, MCP, and app config).",
|
|
76
75
|
"",
|
|
77
76
|
];
|
|
78
77
|
if (program.appConfig) {
|
|
@@ -3,7 +3,7 @@ Tests for configure/configure module behavior.
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { afterEach, beforeEach, describe, expect, test } from "bun:test";
|
|
6
|
-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { tmpdir } from "node:os";
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
import { appConfigFileExists } from "../config/file.ts";
|
|
@@ -13,6 +13,8 @@ import { detectInstalledArtifacts } from "../install/detect-installed.ts";
|
|
|
13
13
|
import { parseInstallOpts } from "../install/opts.ts";
|
|
14
14
|
import { resolveClaudeDesktopMcpPath, resolveInstallPaths } from "../install/paths.ts";
|
|
15
15
|
import { buildInstallPlan, buildUpdatePlan } from "../install/plan.ts";
|
|
16
|
+
import { installTargetForKey } from "../install/target-registry.ts";
|
|
17
|
+
import { buildDetectedSnapshot, buildTargetPlanContext } from "../install/target-scope.ts";
|
|
16
18
|
import { buildUninstallPlan } from "../install/uninstall.ts";
|
|
17
19
|
import type { CliProgram } from "../types.ts";
|
|
18
20
|
|
|
@@ -137,6 +139,45 @@ describe("remove plan", () => {
|
|
|
137
139
|
const plan = buildUninstallPlan(fixture, paths, parseInstallOpts({ uninstall: "1", all: "1" }));
|
|
138
140
|
expect(plan.length).toBe(0);
|
|
139
141
|
});
|
|
142
|
+
|
|
143
|
+
test("configure --remove-all removes installed cursor skill", async () => {
|
|
144
|
+
const skillApp: CliProgram = {
|
|
145
|
+
...fixture,
|
|
146
|
+
configure: { agentIntegration: "skill" },
|
|
147
|
+
};
|
|
148
|
+
const paths = resolveInstallPaths(skillApp);
|
|
149
|
+
mkdirSync(paths.cursorSkillDir, { recursive: true });
|
|
150
|
+
writeFileSync(join(paths.cursorSkillDir, "SKILL.md"), "# test\n", "utf8");
|
|
151
|
+
|
|
152
|
+
expect(detectInstalledArtifacts(paths, skillApp).cursorSkill).toBe(true);
|
|
153
|
+
|
|
154
|
+
const result = await new Cli(skillApp).invoke(["configure", "--remove-all", "--yes"]);
|
|
155
|
+
expect(result.exitCode).toBe(0);
|
|
156
|
+
expect(existsSync(paths.cursorSkillDir)).toBe(false);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
test("scoped skill uninstall action removes directory without global uninstall flag", () => {
|
|
160
|
+
const skillApp: CliProgram = {
|
|
161
|
+
...fixture,
|
|
162
|
+
configure: { agentIntegration: "skill" },
|
|
163
|
+
};
|
|
164
|
+
const paths = resolveInstallPaths(skillApp);
|
|
165
|
+
mkdirSync(paths.cursorSkillDir, { recursive: true });
|
|
166
|
+
writeFileSync(join(paths.cursorSkillDir, "SKILL.md"), "# test\n", "utf8");
|
|
167
|
+
|
|
168
|
+
const detected = buildDetectedSnapshot(skillApp, paths);
|
|
169
|
+
const ctx = buildTargetPlanContext(skillApp, paths, {}, detected);
|
|
170
|
+
const target = installTargetForKey("cursorSkill");
|
|
171
|
+
expect(target).toBeDefined();
|
|
172
|
+
const actions = target!.planUninstall({
|
|
173
|
+
...ctx,
|
|
174
|
+
mode: "uninstall-scoped",
|
|
175
|
+
include: (key) => key === "cursorSkill",
|
|
176
|
+
});
|
|
177
|
+
expect(actions).toHaveLength(1);
|
|
178
|
+
expect(actions[0]!.run().length).toBeGreaterThan(0);
|
|
179
|
+
expect(existsSync(paths.cursorSkillDir)).toBe(false);
|
|
180
|
+
});
|
|
140
181
|
});
|
|
141
182
|
|
|
142
183
|
/** Tests for app config wizard. */
|
package/src/configure/index.ts
CHANGED
|
@@ -121,7 +121,17 @@ function executePlan(
|
|
|
121
121
|
if ("kind" in action && action.kind) {
|
|
122
122
|
const skillTarget = skillTargetFromActionKind(action.kind);
|
|
123
123
|
if (skillTarget) {
|
|
124
|
-
|
|
124
|
+
const runResult = action.run();
|
|
125
|
+
if (runResult.length > 0) {
|
|
126
|
+
changed.push(...runResult);
|
|
127
|
+
} else if (opts.uninstall) {
|
|
128
|
+
const skillDir = skillDirFromUninstallSummary(action.summary, paths);
|
|
129
|
+
if (skillDir) {
|
|
130
|
+
changed.push(...uninstallSkillDir(skillDir, !!opts.dry));
|
|
131
|
+
}
|
|
132
|
+
} else {
|
|
133
|
+
changed.push(...runSkillAction(root, action.kind as InstallActionKind, opts));
|
|
134
|
+
}
|
|
125
135
|
continue;
|
|
126
136
|
}
|
|
127
137
|
}
|
|
@@ -221,7 +231,7 @@ async function runInteractiveConfigure(root: CliProgram, opts: ConfigureOpts): P
|
|
|
221
231
|
runTargetPreflight(root, paths, mutationOpts, installActions);
|
|
222
232
|
}
|
|
223
233
|
|
|
224
|
-
changed.push(...executePlan(root, actions, mutationOpts, true));
|
|
234
|
+
changed.push(...executePlan(root, actions, { ...mutationOpts, uninstall: choice === "uninstall" }, true));
|
|
225
235
|
}
|
|
226
236
|
|
|
227
237
|
return changed;
|
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
TargetPlanContext,
|
|
13
13
|
UninstallAction,
|
|
14
14
|
} from "./target-types.ts";
|
|
15
|
+
import { uninstallSkillDir } from "./uninstall.ts";
|
|
15
16
|
|
|
16
17
|
export interface SkillHostSpec {
|
|
17
18
|
key: CliInstallArtifactKey;
|
|
@@ -97,7 +98,7 @@ export class SkillInstallTarget extends InstallTarget {
|
|
|
97
98
|
kind: this.actionKind,
|
|
98
99
|
summary: `${this.uninstallPrefix}: ${displayInstallPath(dir)}/`,
|
|
99
100
|
message: `Removing ${this.spec.label} skill ${displayInstallPath(dir)}/`,
|
|
100
|
-
run: () =>
|
|
101
|
+
run: () => uninstallSkillDir(dir, ctx.dry),
|
|
101
102
|
},
|
|
102
103
|
];
|
|
103
104
|
}
|