agent-skillboard 0.2.3 → 0.2.4

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 CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.2.4 — 2026-07-03
6
+
7
+ ### Changed
8
+
9
+ - `skillboard uninstall --purge` now removes the entire `.skillboard/` project
10
+ state directory, including source caches, rollout logs, variant snapshots, and
11
+ profiles, while preserving local skill files.
12
+
5
13
  ## 0.2.3 — 2026-07-03
6
14
 
7
15
  ### Added
package/README.md CHANGED
@@ -125,8 +125,9 @@ npx --yes --package agent-skillboard skillboard uninstall --dir /path/to/your/pr
125
125
  npx --yes --package agent-skillboard skillboard uninstall --dir /path/to/your/project --purge
126
126
  ```
127
127
 
128
- `--purge` deletes SkillBoard config, reports, hooks, bridge blocks, and empty
129
- generated directories while leaving `skills/*/SKILL.md` in place.
128
+ `--purge` deletes SkillBoard config, bridge blocks, and the entire
129
+ `.skillboard/` project state directory while leaving `skills/*/SKILL.md` in
130
+ place.
130
131
 
131
132
  See [docs/install.md](docs/install.md) for global installs, `--dir`, GitHub
132
133
  builds, clone-based development, Hermes bridge setup, refresh, and uninstall.
package/docs/install.md CHANGED
@@ -319,9 +319,11 @@ skillboard uninstall --dir /path/to/your/project --purge --dry-run
319
319
  skillboard uninstall --dir /path/to/your/project --purge
320
320
  ```
321
321
 
322
- `--purge` removes SkillBoard config, reports, hooks, bridge blocks, and empty
323
- generated directories. It preserves local `skills/` files because skills that
324
- were created or deleted are outside the uninstall scope.
322
+ `--purge` removes SkillBoard config, bridge blocks, and the entire
323
+ `.skillboard/` project state directory, including reports, hooks, source caches,
324
+ rollout logs, variant snapshots, and profiles. It preserves local `skills/`
325
+ files because skills that were created or deleted are outside the uninstall
326
+ scope.
325
327
 
326
328
  Use `--remove-config` to delete `skillboard.config.yaml` only when it still
327
329
  matches the untouched default config. If the config contains scanned skills or
@@ -342,8 +344,9 @@ Add `--remove-hooks` only when a reset should also delete the entire
342
344
  `.skillboard/hooks/` directory contents. This is explicit because hook scripts
343
345
  may be wired into local agent/runtime configuration. Combine `--reset-config`,
344
346
  `--remove-reports`, and `--remove-hooks` for a clean test reset that removes
345
- SkillBoard-owned lifecycle scaffolding while preserving local `skills/`. The
346
- equivalent short form is `--purge`.
347
+ the most common SkillBoard-owned lifecycle scaffolding while preserving local
348
+ `skills/`. Use `--purge` instead when no `.skillboard/` project state should
349
+ remain at all.
347
350
 
348
351
  ## Upper-Layer Control
349
352
 
package/docs/user-flow.md CHANGED
@@ -288,8 +288,6 @@ skillboard init
288
288
  Use `--purge` when you want SkillBoard's allow/block/preference influence gone
289
289
  from the project while keeping local skill files. It discards the current
290
290
  SkillBoard config even if it contains imported skills or workflow edits,
291
- discards generated dashboard and impact reports, and removes the entire
292
- `.skillboard/hooks/` directory contents. It is equivalent to
293
- `--reset-config --remove-reports --remove-hooks`, so `.skillboard/` can
294
- disappear when no other SkillBoard state remains. Local `skills/` files stay in
295
- place.
291
+ removes generated dashboard and impact reports, and removes the entire
292
+ `.skillboard/` project state directory, including hooks, source caches, rollout
293
+ logs, variant snapshots, and profiles. Local `skills/` files stay in place.
@@ -8,7 +8,7 @@ source profiles, and the generated lockfile.
8
8
 
9
9
  ## Status
10
10
 
11
- Current package version: `0.2.3`
11
+ Current package version: `0.2.4`
12
12
 
13
13
  Current config schema version:
14
14
 
@@ -59,7 +59,7 @@ must call them out clearly.
59
59
  Suggested tags:
60
60
 
61
61
  - `v0.1.0-alpha`: first public GitHub alpha.
62
- - `v0.2.3`: one-time runtime source review before manual activation, ask-after
62
+ - `v0.2.4`: one-time runtime source review before manual activation, ask-after
63
63
  skill routing, purge uninstall, README benefit-first positioning,
64
64
  source inventory refresh, doctor/status, source pin refresh,
65
65
  installer/config detection, resilient detector warnings, and richer dry-run
@@ -194,8 +194,8 @@ Before tagging a public release:
194
194
  provenance with GitHub Actions OIDC, so keep `permissions.id-token: write`,
195
195
  the npm registry URL in `setup-node`, and
196
196
  `NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}` on the publish step.
197
- - Push a version tag that exactly matches `package.json`, for example `v0.2.3`
198
- for package version `0.2.3`.
197
+ - Push a version tag that exactly matches `package.json`, for example `v0.2.4`
198
+ for package version `0.2.4`.
199
199
  - Let `.github/workflows/publish.yml` publish from the tag. The workflow runs
200
200
  the full check suite, validates that the tag matches the package version, and
201
201
  skips `npm publish` only when that exact version already exists on npm.
@@ -229,6 +229,13 @@ completion notes:
229
229
  - update README quick-start to verify the installed version before running
230
230
  policy commands.
231
231
 
232
+ ## 0.2.4 Completion Notes
233
+
234
+ - broaden `skillboard uninstall --purge` from reports/hooks cleanup to removal
235
+ of the full `.skillboard/` project state directory, covering source caches,
236
+ rollout logs, variant snapshots, profiles, hooks, and reports while preserving
237
+ local skill files.
238
+
232
239
  ## 0.2.3 Completion Notes
233
240
 
234
241
  - add `skillboard uninstall --purge` for users who want SkillBoard's policy
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-skillboard",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Let AI agents pick and use allowed skills in each workflow.",
5
5
  "keywords": [
6
6
  "ai-agent",
package/src/cli.mjs CHANGED
@@ -1633,8 +1633,8 @@ function uninstallHelpText() {
1633
1633
  " --keep-empty-dirs Preserve empty generated directories.",
1634
1634
  "",
1635
1635
  "Purge:",
1636
- " Equivalent to --reset-config --remove-reports --remove-hooks.",
1637
- " It removes SkillBoard config, reports, hooks, bridge blocks, and empty generated dirs.",
1636
+ " Removes SkillBoard config, bridge blocks, and the entire .skillboard/ project state directory.",
1637
+ " This includes reports, hooks, source caches, rollout logs, variant snapshots, and profiles.",
1638
1638
  " It does not delete local skills under skills/.",
1639
1639
  ""
1640
1640
  ].join("\n");
@@ -54,6 +54,7 @@ export async function runUninstallCommand(options, stdout) {
54
54
  resetConfig: resetConfig || purge,
55
55
  removeReports: options.get("remove-reports") === "true" || purge,
56
56
  removeHooks: options.get("remove-hooks") === "true" || purge,
57
+ removeProjectState: purge,
57
58
  removeEmptyDirs: options.get("keep-empty-dirs") !== "true"
58
59
  });
59
60
  stdout.write(`${result.dryRun ? "Dry run: " : ""}Uninstalled SkillBoard: ${root}\n`);
package/src/uninstall.mjs CHANGED
@@ -19,14 +19,6 @@ export async function uninstallProject(options) {
19
19
  recordFileResult(filename, result, { removed, updated, preserved });
20
20
  }
21
21
 
22
- for (const entry of generatedFiles(root)) {
23
- const result = await removeGeneratedFile(entry.path, entry.expected, dryRun);
24
- if (result === "removed") {
25
- plannedRemovedPaths.add(entry.path);
26
- }
27
- recordFileResult(entry.label, result, { removed, updated, preserved });
28
- }
29
-
30
22
  if (options.resetConfig === true) {
31
23
  const path = join(root, "skillboard.config.yaml");
32
24
  const result = await removeConfigFile(path, dryRun);
@@ -45,7 +37,24 @@ export async function uninstallProject(options) {
45
37
  preserved.push("skillboard.config.yaml");
46
38
  }
47
39
 
48
- if (options.removeReports === true) {
40
+ if (options.removeProjectState === true) {
41
+ const path = join(root, ".skillboard");
42
+ const result = await removeProjectStateDir(path, dryRun);
43
+ if (result === "removed") {
44
+ plannedRemovedPaths.add(path);
45
+ }
46
+ recordFileResult(".skillboard", result, { removed, updated, preserved });
47
+ } else {
48
+ for (const entry of generatedFiles(root)) {
49
+ const result = await removeGeneratedFile(entry.path, entry.expected, dryRun);
50
+ if (result === "removed") {
51
+ plannedRemovedPaths.add(entry.path);
52
+ }
53
+ recordFileResult(entry.label, result, { removed, updated, preserved });
54
+ }
55
+ }
56
+
57
+ if (options.removeReports === true && options.removeProjectState !== true) {
49
58
  const path = join(root, ".skillboard", "reports");
50
59
  const result = await removeGeneratedDir(path, dryRun);
51
60
  if (result === "removed") {
@@ -54,7 +63,7 @@ export async function uninstallProject(options) {
54
63
  recordFileResult(".skillboard/reports", result, { removed, updated, preserved });
55
64
  }
56
65
 
57
- if (options.removeHooks === true) {
66
+ if (options.removeHooks === true && options.removeProjectState !== true) {
58
67
  const path = join(root, ".skillboard", "hooks");
59
68
  const result = await removeGeneratedDir(path, dryRun);
60
69
  if (result === "removed") {
@@ -66,7 +75,8 @@ export async function uninstallProject(options) {
66
75
  if (options.removeEmptyDirs !== false) {
67
76
  for (const dir of emptyDirs(root, {
68
77
  skipReports: options.removeReports === true,
69
- skipHooks: options.removeHooks === true
78
+ skipHooks: options.removeHooks === true,
79
+ skipSkillboard: options.removeProjectState === true
70
80
  })) {
71
81
  const result = await removeEmptyDir(dir.path, dryRun, plannedRemovedPaths);
72
82
  if (result === "removed") {
@@ -109,6 +119,9 @@ function emptyDirs(root, options = {}) {
109
119
  if (options.skipHooks === true && dir.label === ".skillboard/hooks") {
110
120
  return false;
111
121
  }
122
+ if (options.skipSkillboard === true && dir.label.startsWith(".skillboard")) {
123
+ return false;
124
+ }
112
125
  return true;
113
126
  });
114
127
  }
@@ -210,6 +223,26 @@ async function removeGeneratedDir(path, dryRun) {
210
223
  return "removed";
211
224
  }
212
225
 
226
+ async function removeProjectStateDir(path, dryRun) {
227
+ const stats = await pathStats(path);
228
+ if (stats === null) {
229
+ return "absent";
230
+ }
231
+ if (stats.isSymbolicLink()) {
232
+ if (!dryRun) {
233
+ await rm(path);
234
+ }
235
+ return "removed";
236
+ }
237
+ if (!stats.isDirectory()) {
238
+ return "preserved";
239
+ }
240
+ if (!dryRun) {
241
+ await rm(path, { recursive: true });
242
+ }
243
+ return "removed";
244
+ }
245
+
213
246
  async function removeEmptyDir(path, dryRun, plannedRemovedPaths) {
214
247
  const stats = await pathStats(path);
215
248
  if (stats === null) {