skilllib 1.2.1 → 1.3.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.
package/README.md CHANGED
@@ -15,7 +15,7 @@ and every agent you use can see them.
15
15
  npx skilllib
16
16
  ```
17
17
 
18
- <img src="docs/screenshot-project.svg" alt="skilllib showing a repo's skills: where each comes from, which agents load it, whether it's committed, and how often it's used" width="100%">
18
+ <img src="docs/screenshot-project.svg" alt="skilllib: Places on the left, a repo's skills with their issues and uses, and the selected skill's fixes and actions below" width="100%">
19
19
 
20
20
  </div>
21
21
 
@@ -46,7 +46,7 @@ Most agents can't turn off a global skill for just one repo. Claude Code can, bu
46
46
  - **📚 Your skills: one versioned library.** Every skill has a single master copy in `~/.skilllib/library`, and each change becomes a new version.
47
47
  - **📦 Per-repo installs, pinned like dependencies.** Each repo lists its skills and versions in `skilllib.json`. `sync` reproduces them exactly, and `update` moves to the newest.
48
48
  - **🤝 One copy, every agent.** skilllib puts one real copy in the repo and links it into whichever folders your other agents read.
49
- - **🧹 A cleanup wizard for global skills.** For each global skill, pick the repos that should keep it, keep it global, or delete it. Usage numbers and descriptions help you decide.
49
+ - **🧹 Health: one list of what to fix.** Global skills you haven't decided about, skills loaded twice, updates, broken links, each with its fix. For a global skill: move it to the repos that need it, keep it global, or delete it. Usage numbers and descriptions help you decide.
50
50
  - **✓ Global on purpose.** Some skills belong everywhere. Mark them once and skilllib stops warning about them.
51
51
  - **🔎 See everything in a repo:**
52
52
  - where each skill comes from (the repo, your library, global, a plugin, claude.ai…)
@@ -76,9 +76,9 @@ On first run, skilllib asks two things:
76
76
 
77
77
  Then a good first session looks like this:
78
78
 
79
- 1. **Open a repo** (type its name, then Enter) to see everything its agents can use.
80
- 2. **Clean up global skills:** open **Global → ⚠ Clean up…** and decide, skill by skill, which repos keep it.
81
- 3. **Add skills** to a repo from the *Add skills* tab.
79
+ 1. **You land in Places, on the repo you're in.** `enter` opens its skills; `enter` again opens a skill's issues and actions.
80
+ 2. **Open Health** to see everything worth fixing, in every repo and in your global skills. **✦ Fix N issues automatically…** does the safe ones; the rest are your call, one skill at a time.
81
+ 3. **Add skills** to a repo with **+ Add a skill…**, the top row of its list.
82
82
 
83
83
  ---
84
84
 
@@ -86,69 +86,66 @@ Then a good first session looks like this:
86
86
 
87
87
  ### The screen
88
88
 
89
- The left pane lists **places**, and the right pane shows the skills of the place you pick:
89
+ Three panes: **Places** on the left, a **list** on the right, and the **details** of what you select under it. Terminals under 80 columns get a tab bar instead of Places; under 30 rows, details open on `enter`.
90
90
 
91
91
  | Place | What it shows |
92
92
  |---|---|
93
93
  | **Your skills** | Your library: master copies, versioned. Nothing here loads anywhere until you add it to a repo. |
94
94
  | **Global** | Everything your agents load in *every* repo: yours, plus vendor skills (plugins, claude.ai, Cursor built-ins). |
95
- | **Health** | Problems with one-key fixes, and everything you can restore. |
96
- | **Projects** | Every repo found in your project folders. `◆` marks the one you're in. |
97
- | **Settings** | Your agents and your project folders. |
98
- | **Help** | Where skills come from, and how each agent finds and uses them. |
95
+ | **Health** | Every skill with something to fix, in every repo and in Global, with its fixes. |
96
+ | **Projects** | Every repo found in your project folders. `◆` marks the one you're in; `✕` `⚠` `·` its worst issue. |
97
+ | **Settings** | Your agents, your project folders, hidden repos, and backups. |
98
+ | **Help** | The keys and symbols. |
99
99
 
100
100
  ### Keys
101
101
 
102
102
  | Key | Does |
103
103
  |---|---|
104
- | *type* | Search the pane you're in. Word initials work too: `cfw` finds `cloudflare-workers`. |
104
+ | *type* | Filter the pane you're in. Word initials work too: `cfw` finds `cloudflare-workers`. |
105
105
  | `↑` `↓` | Move |
106
- | `space` | The main action: add, remove, copy, clean up, fix, restore |
107
- | `enter` | Every action for the selected row (or open a place) |
108
- | `tab` | In a repo: switch between **Usable here** and **Add skills** |
109
- | `→` `←` | Open or close a group |
110
- | `esc` | Clear the search, then go back to the left pane |
111
- | `?` | Help · `ctrl+r` reload · `ctrl+c` quit |
106
+ | `enter` `→` | One pane deeper: Places → list → details. In the details, apply the selected fix or action. |
107
+ | `esc` `←` | One pane back (`esc` clears a filter first). In the details, `←` `→` move along the actions. |
108
+ | `space` | Apply the ★ recommended fix, or show the choices when it's your call; on a group, open or close it |
109
+ | `tab` | Next tab: All · Issues · Local · Global · Plugins · Vendor |
110
+ | `ctrl+r` | Read everything again from disk · `ctrl+c` quits |
112
111
 
113
112
  ### A repo
114
113
 
115
- A repo has two lists:
114
+ The list shows everything agents can use in the repo, one row per skill, even when it loads from several places:
116
115
 
117
- **Usable here** shows everything agents can use in this repo, grouped by where it comes from:
116
+ | Column | Meaning |
117
+ |---|---|
118
+ | Source | `lib v2`: from your library · `repo`: committed by your team · `untracked`: only on this machine · `global` (`global ✓`: global on purpose) · `⧉ plugin` · `claude.ai` · `cursor` |
119
+ | Uses | Claude Code uses in this repo, last 30 days |
120
+ | Issue | The worst of its issues; the details show them all |
118
121
 
119
- | Group | What it is | `space` |
120
- |---|---|---|
121
- | *From your skills* | Versioned skills you added from your library | Remove it from this repo |
122
- | *From npx skills* | Skills `npx skills add` installed into this repo (listed in its `skills-lock.json`), with their source | Copy it into your skills; `npx skills` keeps managing this copy |
123
- | *The repo's own* | Skills committed to the repo (e.g. your team's `.agents/skills`) | Copy it into your skills, so other repos can use it |
124
- | *⚠ Global · yours, not reviewed* | Your global skills you haven't decided about: they load in every repo | Open the cleanup wizard |
125
- | *✓ Global · yours, on purpose* | Your global skills you chose to keep global | Open the cleanup wizard |
126
- | *Global · from vendors* | Plugins, claude.ai skills, Cursor built-ins | – (manage them at the source) |
122
+ **Related skills fold into one row**, here, in Global and in Your skills. skilllib groups them by the strongest signal it has: the same source (a plugin, an `npx skills` repo, claude.ai, Cursor), then folders you copied in the same minute (a whole set installed at once), then the same first word (`cloudflare-*`). `→` opens a group and `←` closes it; `enter` on an open group shows actions for all of it: move all to repos, keep all global, delete all, add all to repos, or a review prompt. A group you move together is recorded as its skills' origin, so it stays grouped in your library.
127
123
 
128
- **Add skills** shows your skills that this repo doesn't have yet. `space` adds one.
124
+ The top rows start something: **+ Add a skill…**, **✦ Fix N issues automatically…**, and **⋯ repo…** (open its folder, hide it from the list, copy a review prompt for its skills).
129
125
 
130
- Each row tells you:
126
+ A skill's details show each issue with its fixes (★ is the recommended one; *your call* marks decisions, which are never applied automatically), then its other actions, how often it's used here, and where it loads from with its git state.
131
127
 
132
- | | Meaning |
133
- |---|---|
134
- | **✻ ⬡ ◎ ℤ** | Claude Code, Cursor, Codex, Zed. An icon in color means that agent loads the skill here; a faint one means it doesn't. |
135
- | `.claude` / `.agents` | The folder holding the real copy |
136
- | **✓ committed** · **± changed** · **+ not added** · **∅ ignored** | The skill's git state. `∅ ignored` means it only exists on your machine. |
137
- | `v2` · `v1 → v2` | The installed version, and whether a newer one exists |
138
- | **⧉ 3 copies** | The same skill reaches your agents from 3 places. The details panel lists them, and Health has the fix. |
139
- | last column | Claude Code uses in the last 30 days |
128
+ What skilllib flags:
140
129
 
141
- Related skills fold into one row: skills from the same plugin, the same source repo, or with the same name prefix (`design-*`). Press Enter on the group row for actions on all of them.
142
-
143
- If some skills aren't visible to every agent you use, the top row offers **⇄ Make all N skills usable by …**. It adds links only; nothing is copied or moved.
130
+ | Issue | Fixes |
131
+ |---|---|
132
+ | **Loaded twice** (also global, or also in a plugin) | Keep the repo's copy and stop loading it globally, or keep it global |
133
+ | **Same name as a plugin skill** | Remove the repo's copy, or turn the plugin off with `/plugin` |
134
+ | **Folder missing** · **Not in your library** | Restore it · copy it back into your library |
135
+ | **Update to vN** · **Edited here** | Update · save the edits as a new version, or discard them |
136
+ | ***Agent* can't see it** | Link it for every agent (links only; nothing is copied or moved) |
137
+ | **Differs from library** · **Not tracked** · **Only in this repo** | Update your library from it, or replace it · track it · import it |
138
+ | **Unused 30 days** | Remove it from the repo |
139
+ | **Broken link** · **Not reviewed** (global) | Remove the link · move it to repos, keep it global on purpose, or delete it |
144
140
 
145
141
  ### Adding and removing skills
146
142
 
147
- - **Adding** (`space` in *Add skills*) copies the newest version into the fewest folders your agents read, and records it in `skilllib.json`. Agents pick it up in their next session. The layout matches `npx skills`' symlink option: the real copy lives in `.agents/skills`, which nearly every agent reads, and Claude Code gets a link.
143
+ - **+ Add a skill…** searches your library. Its last rows create a new skill (it opens in `$EDITOR`) or copy a prompt for an agent to write it.
144
+ - **Adding** copies the newest version into the fewest folders your agents read, and records it in `skilllib.json`. Agents pick it up in their next session. The layout matches `npx skills`' symlink option: the real copy lives in `.agents/skills`, which nearly every agent reads, and Claude Code gets a link.
148
145
  - Claude Code (with or without Cursor): `.claude/skills/<name>`.
149
146
  - Cursor, Codex or Zed without Claude Code: `.agents/skills/<name>`.
150
147
  - Claude Code plus Codex or Zed: the copy goes in `.agents/skills`, with a link in `.claude/skills`. Claude Code only reads `.claude/skills`, and Codex and Zed only read `.agents/skills`.
151
- - **Removing** (`space` again) deletes that copy and its links. Your library and other repos aren't touched. If you edited it here, skilllib asks first; Enter → *Save local edits to Your skills* keeps them.
148
+ - **Remove from repo** deletes that copy and its links; your library keeps it. An untracked copy goes to Settings › Backups instead. If you edited a tracked skill here, skilllib asks first.
152
149
  - **The repo's own skills are never deleted by skilllib.** You can copy them into your library, or link them so every agent sees them.
153
150
  - **Git-tracked folders:** if the repo commits the folder a link would go into (common for `.agents/skills`), skilllib asks once and remembers your answer.
154
151
 
@@ -165,37 +162,27 @@ Every change to a library skill becomes a new version, kept in `~/.skilllib/stor
165
162
  | `skilllib sync` | `npm ci` | Installs exactly the pinned versions and restores missing ones. It never touches your edits. |
166
163
  | `skilllib outdated` | `npm outdated` | Lists skills with a newer version |
167
164
  | `skilllib update [name]` | `npm update` | Moves to the newest version |
168
- | Enter → *Install a specific version…* | `npm i x@1` | Pins any version, including older ones |
165
+ | *Other versions…* in a skill's actions | `npm i x@1` | Pins any version, including older ones |
169
166
 
170
167
  Edit a skill once in **Your skills** (Enter → *Edit SKILL.md*). Every repo that uses it then shows `v1 → v2` and can update.
171
168
 
172
- ### Cleaning up global skills
169
+ ### Global skills
173
170
 
174
- <img src="docs/screenshot-cleanup.svg" alt="The cleanup wizard: each global skill with its Claude Code usage, where it moves, and the projects that keep it" width="100%">
171
+ <img src="docs/screenshot-global.svg" alt="Global: everything that loads in every repo, with skills installed together folded into one group and actions for the whole group" width="100%">
175
172
 
176
- Open **Global → ⚠ Clean up…**, or press `space` on any of your global skills. For each skill, `space` cycles through:
173
+ **Global** lists everything that loads in every repo. Each of your global skills you haven't decided about is flagged **Not reviewed**, with three choices:
177
174
 
178
- - **◉ move:** installed into the repos you tick on the right. Repos that already have it, or where Claude Code used it, are pre-ticked.
179
- - **○ keep global**: skilllib remembers this choice, and the next cleanup skips the skill
180
- - **✕ delete** (`d`): removed without keeping a copy in your library
175
+ - **Move it to the repos that need it…**: tick the repos (the ones where Claude Code used it are pre-ticked). It goes into your library and those repos, and stops loading globally.
176
+ - **Keep it global on purpose**: skilllib stops warning about it (also `skilllib global keep <name>`). The mark only records your decision; to undo it, pick **Stop marking it as global on purpose**.
177
+ - **Delete it**: it goes to Settings › Backups.
181
178
 
182
- Each skill shows how often Claude Code used it, and the panel below shows its description and where it was used. Review, apply, and your globals are gone: moved ones are in your library and in the right repos. Originals go to a backup you can restore from **Health**.
179
+ Vendor skills (plugins, claude.ai, Cursor built-ins) are managed at their source: `/plugin` in Claude Code, or claude.ai's settings.
183
180
 
184
- You can also delete one skill (Enter → **Delete**) or a whole group (Enter → **Delete all N**) straight from Global.
185
-
186
- ### Keeping a skill global on purpose
187
-
188
- Some skills are useful in every repo, for example a commit-message skill. Mark them so skilllib stops asking about them:
189
-
190
- - Enter on the skill (in Global or in a repo) → **✓ Keep global on purpose**. Enter on a group → **Keep all N global on purpose**.
191
- - In the cleanup wizard, every skill you leave on **○ keep global** is marked when you apply.
192
- - From the command line: `skilllib global keep <name>`.
193
-
194
- A marked skill shows **✓ global** instead of **⚠ loaded globally**, and has its own group in a repo. The cleanup wizard hides it (`k` shows it again), and review prompts tell the agent that you chose to keep it global. The mark only records your decision: no files move, and agents load the skill as before. Duplicate warnings (⧉) still show. To undo, use Enter → **Unmark** or `skilllib global unkeep <name>`.
181
+ **Replacing a plugin with library skills:** on a plugin's skill or group, **Replace *plugin* with library skills…** copies all its skills into your library (grouped under the plugin), adds them to the repos you tick, and uninstalls the plugin (`claude plugin uninstall`, keeping its saved data; Settings › Backups reinstalls it). A plugin can't be half removed, so it's all its skills at once; the confirmation says what else it brings (commands, agents, hooks, MCP servers) that goes too. If the `claude` command isn't available, skilllib turns the plugin off instead and tells you to finish with `/plugin uninstall`. Plugins synced from claude.ai can't be removed from here: skilllib copies their skills and tells you to remove the plugin on claude.ai.
195
182
 
196
183
  ### Ask an agent to review your skills
197
184
 
198
- Not sure what to keep? **Copy review prompt** puts a ready-to-paste prompt on your clipboard (also saved to `~/.skilllib/review-prompt.md`). For each skill, it includes:
185
+ Not sure what to keep? **Review prompt** puts a ready-to-paste prompt on your clipboard (also saved to `~/.skilllib/review-prompt.md`). For each skill, it includes:
199
186
 
200
187
  - its description and SKILL.md
201
188
  - how it was installed (plugin, `npx skills`, claude.ai, copied in…)
@@ -206,14 +193,11 @@ Not sure what to keep? **Copy review prompt** puts a ready-to-paste prompt on yo
206
193
 
207
194
  Paste it into Claude Code, Cursor or Codex. You get back **keep global / move to projects / delete / turn off at the vendor** for each skill, as a table plus JSON.
208
195
 
209
- It's available from:
210
- - **Global → ✦ Ask an agent to review all global skills**
211
- - Enter on any skill or group → **Copy review prompt**
212
- - `p` inside the cleanup wizard
196
+ It's in every skill's actions, in a repo's **⋯** menu (all its skills), and at the top of Global (all your global skills).
213
197
 
214
198
  ### Duplicates
215
199
 
216
- The same skill often reaches your agents more than once: a copy in `.claude/skills` *and* in `.agents/skills`, a global copy *and* a repo copy, a plugin *and* your skill. skilllib keeps **one real copy per skill, plus only the links your agents need**. Health shows each case, and `skilllib tidy` fixes the folder ones.
200
+ The same skill often reaches your agents more than once: a copy in `.claude/skills` *and* in `.agents/skills`, a global copy *and* a repo copy, a plugin *and* your skill. skilllib keeps **one real copy per skill, plus only the links your agents need**. `skilllib doctor` lists each case, and `skilllib tidy` fixes the folder ones.
217
201
 
218
202
  | What it finds | What it does |
219
203
  |---|---|
@@ -225,16 +209,14 @@ The same skill often reaches your agents more than once: a copy in `.claude/skil
225
209
  | A repo copy of a skill you keep global | The repo copy is the extra one. Claude Code runs the global copy anyway. |
226
210
 
227
211
  - **It never moves a real copy.** `skilllib.json` is shared, so a move for your agents could break a teammate's.
228
- - **It never adds links.** That's **⇄ Make all usable** (`skilllib link`).
229
- - **It asks before changing committed files.** You choose: *tidy, but keep git as it is*, or *tidy everything*. On the command line, pass `--allow-git`.
212
+ - **It never adds links.** That's `skilllib link`, or a skill's *can't see it* fix.
213
+ - **It leaves committed files alone** unless you pass `--allow-git`.
230
214
  - **Cursor lists a skill once** even when it reaches it through several folders (tested September 2026). It lists a plugin's copy and your copy separately.
231
215
 
232
- ### Health and backups
233
-
234
- **Health** lists broken links, duplicates, copies that differ, skills some of your agents can't reach, out-of-date repos and repo-only skills. Each has a one-key fix, or a short list of fixes to pick from. Below them is everything skilllib ever moved out, and `space` puts it back where it came from.
216
+ ### Backups
235
217
 
236
- skilllib never really deletes anything:
237
- - removed library skills go to `~/.skilllib/trash`
218
+ skilllib never really deletes anything you can't get back. What it removes goes to Settings › Backups, and `enter` puts it back where it came from:
219
+ - removed library skills and untracked copies go to `~/.skilllib/trash`
238
220
  - removed global skills go to `~/.skilllib/global-backup`
239
221
  - copies replaced by a link go to `~/.skilllib/tidy-backup`
240
222
  - removed plugins are listed too; restoring one reinstalls it
@@ -332,8 +314,8 @@ Flags: `--force` (overwrite local edits), `--allow-tracked` (link into git-track
332
314
  | `~/.skilllib/library/` | Your skills (master copies). Worth putting under git. |
333
315
  | `~/.skilllib/store/` | Every version of every skill, immutable |
334
316
  | `~/.skilllib/config.json` | Your agents, project folders, hidden projects, skills you keep global |
335
- | `~/.skilllib/trash/`, `global-backup/`, `tidy-backup/` | Everything skilllib removed, restorable from Health |
336
- | `~/.skilllib/plugin-backup.json` | Plugins skilllib removed, so Health can reinstall them |
317
+ | `~/.skilllib/trash/`, `global-backup/`, `tidy-backup/` | Everything skilllib removed, restorable from Settings › Backups |
318
+ | `~/.skilllib/plugin-backup.json` | Plugins skilllib uninstalled, so Settings › Backups can reinstall them |
337
319
  | `~/.skilllib/review-prompt.md` | The last review prompt you copied |
338
320
 
339
321
  Environment variables: `SKILLLIB_HOME` moves `~/.skilllib`, `$VISUAL` / `$EDITOR` set the editor, and `CLAUDE_CONFIG_DIR` is honored.
@@ -366,7 +348,7 @@ npm link # use your checkout as `skilllib`
366
348
  1. Bump `version` in `package.json` and merge to `main`.
367
349
  2. Tag and push:
368
350
  ```bash
369
- git tag v1.2.1 && git push --tags
351
+ git tag v1.3.0 && git push --tags
370
352
  ```
371
353
 
372
354
  CI then tests on Linux, macOS and Windows, publishes to npm through [trusted publishing](https://docs.npmjs.com/trusted-publishers) (no token; provenance is automatic), and creates a GitHub release.
@@ -512,6 +512,14 @@ function claudeAiSkills() {
512
512
  }))
513
513
  );
514
514
  }
515
+ function setPluginEnabled(id, on) {
516
+ const file = join7(claudeDir(), "settings.json");
517
+ const settings = existsSync6(file) ? readJson(file) : {};
518
+ if (!settings) throw new Error(`${file} isn't valid JSON, so skilllib won't rewrite it`);
519
+ settings.enabledPlugins = { ...settings.enabledPlugins, [id]: on };
520
+ mkdirSync4(claudeDir(), { recursive: true });
521
+ writeFileSync4(file, JSON.stringify(settings, null, 2) + "\n");
522
+ }
515
523
  function pluginSkills() {
516
524
  const plugins = join7(claudeDir(), "plugins");
517
525
  const enabled = readJson(join7(claudeDir(), "settings.json"))?.enabledPlugins ?? {};
@@ -532,7 +540,8 @@ function pluginSkills() {
532
540
  (bucket) => readdirSync3(join7(syncedDir, bucket), { withFileTypes: true }).filter((d) => d.isDirectory()).flatMap((d) => {
533
541
  const root = join7(syncedDir, bucket, d.name);
534
542
  const name = readJson(join7(root, ".claude-plugin", "plugin.json"))?.name ?? d.name;
535
- return skillDirsIn(join7(root, "skills")).map((path) => ({ path, origin: `${name} (claude.ai)` }));
543
+ if (enabled[`${name}@synced`] === false) return [];
544
+ return skillDirsIn(join7(root, "skills")).map((path) => ({ path, origin: `${name}@synced` }));
536
545
  })
537
546
  ) : [];
538
547
  return [...fromMarketplaces, ...fromSynced].map(({ path, origin }) => ({
@@ -866,6 +875,10 @@ function stash(dir, bucket) {
866
875
  writeFileSync5(backupIndexFile(bucket), JSON.stringify({ ...readBackupIndex(bucket), [entry]: dir }, null, 2) + "\n");
867
876
  return target;
868
877
  }
878
+ function removeUntracked(root, name, path) {
879
+ unlinkEverywhere(root, name);
880
+ return stash(path, "trash");
881
+ }
869
882
  function projectsUsing(name) {
870
883
  return knownProjects().filter((p) => name in readManifest(p).skills);
871
884
  }
@@ -1130,8 +1143,8 @@ function claudePlugins(machine) {
1130
1143
  const byOrigin = /* @__PURE__ */ new Map();
1131
1144
  for (const m of machine) if (m.kind === "plugin") byOrigin.set(m.origin, [...byOrigin.get(m.origin) ?? [], m.path]);
1132
1145
  return [...byOrigin].map(([origin, skills]) => {
1133
- const synced = origin.endsWith(" (claude.ai)");
1134
- const id = synced ? `${origin.replace(" (claude.ai)", "")}@synced` : origin;
1146
+ const synced = origin.endsWith("@synced");
1147
+ const id = origin;
1135
1148
  const entry = installed[origin]?.[0];
1136
1149
  return {
1137
1150
  id,
@@ -1188,13 +1201,14 @@ function removePlugin(plugin, how) {
1188
1201
  const r = plugin.synced ? turnOffSynced(plugin.id) : claude(["plugin", how === "delete" ? "uninstall" : "disable", plugin.id, ...scope], plugin.projectPath);
1189
1202
  const saved = imported.length ? `; ${imported.join(", ")} copied into Your skills` : "";
1190
1203
  if (!r.ok) return { ok: false, message: `${plugin.id}: ${r.reason}${saved}` };
1191
- if (how === "delete" && !plugin.synced) {
1192
- const list2 = readJson2(removedFile()) ?? [];
1193
- mkdirSync6(skilllibHome(), { recursive: true });
1194
- writeFileSync6(removedFile(), JSON.stringify([...list2, { id: plugin.id, scope: plugin.scope ?? "user", at: (/* @__PURE__ */ new Date()).toISOString() }], null, 2) + "\n");
1195
- }
1204
+ if (how === "delete" && !plugin.synced) recordRemovedPlugin(plugin.id, plugin.scope ?? "user");
1196
1205
  return { ok: true, message: `${plugin.id} ${how === "delete" && !plugin.synced ? "removed" : "turned off"}${saved}` };
1197
1206
  }
1207
+ function recordRemovedPlugin(id, scope) {
1208
+ const list2 = readJson2(removedFile()) ?? [];
1209
+ mkdirSync6(skilllibHome(), { recursive: true });
1210
+ writeFileSync6(removedFile(), JSON.stringify([...list2, { id, scope, at: (/* @__PURE__ */ new Date()).toISOString() }], null, 2) + "\n");
1211
+ }
1198
1212
  function pluginBackups() {
1199
1213
  return (readJson2(removedFile()) ?? []).map((r) => ({
1200
1214
  name: r.id,
@@ -2103,8 +2117,7 @@ export {
2103
2117
  userHome,
2104
2118
  skilllibHome,
2105
2119
  HARNESSES,
2106
- ALL_PROJECT_DIRS,
2107
- installDirs,
2120
+ harness,
2108
2121
  readSkillInfo,
2109
2122
  versionHistory,
2110
2123
  forgetLatest,
@@ -2123,21 +2136,22 @@ export {
2123
2136
  allowTrackedLinks,
2124
2137
  keptGlobal,
2125
2138
  setKeepGlobal,
2139
+ setPluginEnabled,
2126
2140
  machineSkills,
2127
2141
  libraryOrigins,
2142
+ recordOrigin,
2128
2143
  librarySkills,
2129
2144
  librarySkillDir,
2130
- visibilityOf,
2131
2145
  projectStatus,
2132
2146
  linkEverywhere,
2133
- unlinkEverywhere,
2134
2147
  relinkDependency,
2135
- linkAll,
2136
2148
  addSkill,
2137
2149
  removeSkill,
2138
2150
  syncProject,
2139
2151
  updateProject,
2140
2152
  importSkill,
2153
+ removeUntracked,
2154
+ projectsUsing,
2141
2155
  deleteLibrarySkill,
2142
2156
  deleteGlobal,
2143
2157
  unloadGlobal,
@@ -2146,13 +2160,12 @@ export {
2146
2160
  restoreBackup,
2147
2161
  error,
2148
2162
  scanUsage,
2149
- summarize,
2150
2163
  gitInfo,
2151
2164
  relativeTo,
2165
+ claudeBinary,
2166
+ recordRemovedPlugin,
2152
2167
  pluginBackups,
2153
2168
  restorePlugin,
2154
- runFix,
2155
- findIssues,
2156
2169
  parseArgs,
2157
2170
  projectOfFactory,
2158
2171
  status,
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  unhide,
24
24
  update,
25
25
  usage
26
- } from "./chunk-O5TY4NWZ.js";
26
+ } from "./chunk-TWQQHXVG.js";
27
27
 
28
28
  // src/index.ts
29
29
  import { readFileSync } from "fs";
@@ -79,9 +79,9 @@ async function main() {
79
79
  const args = parseArgs(rest);
80
80
  switch (command) {
81
81
  case void 0:
82
- return process.stdin.isTTY && process.stdout.isTTY ? (await import("./tui-6BOQIKAU.js")).tui() : status(args);
82
+ return process.stdin.isTTY && process.stdout.isTTY ? (await import("./tui-H5IQAGAL.js")).tui() : status(args);
83
83
  case "ui":
84
- return (await import("./tui-6BOQIKAU.js")).tui();
84
+ return (await import("./tui-H5IQAGAL.js")).tui();
85
85
  case "status":
86
86
  return status(args);
87
87
  case "add":