skilllib 1.0.0 → 1.0.2
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 +240 -166
- package/dist/{chunk-J5ZDUXWL.js → chunk-67BDL5SN.js} +4 -5
- package/dist/index.js +3 -3
- package/dist/{tui-WFN7JSVC.js → tui-CQCVL6IK.js} +29 -21
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -1,266 +1,340 @@
|
|
|
1
|
-
|
|
1
|
+
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# ◆ skilllib
|
|
4
4
|
|
|
5
|
-
**
|
|
5
|
+
**Manage your agent skills like dependencies.**<br>
|
|
6
|
+
One library for all your skills. Each repo gets only the ones it needs,<br>
|
|
7
|
+
and every agent you use can see them.
|
|
6
8
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
[](https://www.npmjs.com/package/skilllib)
|
|
10
|
+
[](LICENSE)
|
|
11
|
+

|
|
12
|
+

|
|
11
13
|
|
|
12
14
|
```bash
|
|
13
|
-
|
|
14
|
-
skilllib
|
|
15
|
+
npx skilllib
|
|
15
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
19
|
|
|
19
|
-
|
|
20
|
+
</div>
|
|
20
21
|
|
|
21
|
-
|
|
22
|
+
---
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
## The problem
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
2. **Where your projects live**, for example `~/Projects`. It finds every git repo there and rescans on each launch.
|
|
26
|
+
[Agent skills](https://code.claude.com/docs/en/skills) (folders with a `SKILL.md`) are one of the best ways to teach Claude Code, Cursor, Codex and Zed how *you* work. But they pile up quickly:
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
- **`npx skills add`** drops skills into `~/.agents/skills`.
|
|
29
|
+
- **Plugins** bring their own.
|
|
30
|
+
- **claude.ai** syncs a few more.
|
|
31
|
+
- **Your teammates** commit some to the repo.
|
|
32
|
+
- **You** copy folders into `~/.claude/skills` "just for now".
|
|
29
33
|
|
|
30
|
-
|
|
34
|
+
A few weeks later:
|
|
31
35
|
|
|
32
|
-
|
|
36
|
+
- **🌍 Global skills load everywhere.** Everything in `~/.claude/skills` or `~/.agents/skills` loads in **every repo, in every session**. Your agent reads the name and description of your Stripe skill while fixing Terraform in your infra repo. That costs context, and skills fire when they shouldn't.
|
|
37
|
+
- **👯 Duplicates.** The same skill arrives through `npx skills` *and* a plugin *and* a copy in the repo, and your agent sees it twice.
|
|
38
|
+
- **🙈 Each agent looks somewhere else.** Claude Code reads `.claude/skills`; Codex and Zed read `.agents/skills`; Cursor reads both. The skills your team committed to `.agents/skills` are invisible to Claude Code.
|
|
39
|
+
- **🧟 Copies drift.** You improved a skill in one repo; the other five still have the old version.
|
|
40
|
+
- **🤷 No overview.** Which skills does this repo actually have? Where did each one come from? Is it committed, or only on my laptop? Does anyone use it?
|
|
33
41
|
|
|
34
|
-
|
|
35
|
-
- **Global folders:** `~/.claude/skills`, `~/.agents/skills` (`npx skills add` installs here), and `~/.cursor/skills`. These load in every repo.
|
|
36
|
-
- **Vendors:** Claude Code plugins (`/plugin`), claude.ai skills synced from your account, Claude Code's bundled commands, Cursor's built-in and marketplace skills, and Codex system skills.
|
|
37
|
-
- **Your skills** (`~/.skilllib/library`): skilllib's master copies. Nothing there loads until you add it to a project.
|
|
42
|
+
Most agents can't turn off a global skill for just one repo. Claude Code can, but Cursor and Codex can't. **The only real fix is to stop using global skills and give each repo what it needs.**
|
|
38
43
|
|
|
39
|
-
|
|
44
|
+
## How skilllib fixes it
|
|
40
45
|
|
|
41
|
-
|
|
46
|
+
- **📚 Your skills: one versioned library.** Every skill has a single master copy in `~/.skilllib/library`, and each change becomes a new version.
|
|
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
|
+
- **🤝 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.
|
|
50
|
+
- **🔎 See everything in a repo:**
|
|
51
|
+
- where each skill comes from (the repo, your library, global, a plugin, claude.ai…)
|
|
52
|
+
- which agents load it
|
|
53
|
+
- whether it's committed to git or gitignored
|
|
54
|
+
- how often it was used
|
|
55
|
+
- **✦ Ask an agent.** Copy a ready-made prompt with all of that data, and let Claude Code, Cursor or Codex tell you what to keep, move or delete.
|
|
56
|
+
- **🛟 Nothing is lost.** Every removal goes to a backup you can restore with one key.
|
|
42
57
|
|
|
43
|
-
|
|
44
|
-
- **How it uses them.** Descriptions are always in context; the full `SKILL.md` loads on `/name` or when Claude decides it's relevant.
|
|
45
|
-
- `disable-model-invocation: true`: only you can run it.
|
|
46
|
-
- `user-invocable: false`: only Claude can run it.
|
|
47
|
-
- **Per-repo control.** `skillOverrides` in `.claude/settings.json`, with values `"off"`, `"name-only"` or `"user-invocable-only"`. This only affects Claude.
|
|
58
|
+
Everything runs locally: no server, no account, no network calls.
|
|
48
59
|
|
|
49
|
-
|
|
60
|
+
---
|
|
50
61
|
|
|
51
|
-
|
|
52
|
-
- In the project: `.agents/skills` and `.cursor/skills`, including nested ones, which only apply to files inside them.
|
|
53
|
-
- In your home folder: `~/.agents/skills` and `~/.cursor/skills`.
|
|
54
|
-
- For compatibility: `.claude/skills`, `.codex/skills`, `~/.claude/skills` and `~/.codex/skills`.
|
|
55
|
-
- It also loads marketplace plugins and its own built-ins. Cloud Agents only see `~/.cursor/skills`.
|
|
56
|
-
- **How it uses them.** Descriptions decide relevance, and the full content loads on use; `/` runs one. A `paths:` glob in the frontmatter limits a skill to matching files. `disable-model-invocation: true` makes it manual.
|
|
57
|
-
- **Limits.** There's no per-project switch for global skills. The docs don't say what happens when two folders hold the same skill.
|
|
62
|
+
## Quick start
|
|
58
63
|
|
|
59
|
-
|
|
64
|
+
```bash
|
|
65
|
+
npm install -g skilllib # or: npx skilllib
|
|
66
|
+
skilllib
|
|
67
|
+
```
|
|
60
68
|
|
|
61
|
-
|
|
62
|
-
- **How it uses them.** Names and descriptions come first (capped at about 2% of context); `SKILL.md` loads when used. Type `$` to pick one.
|
|
63
|
-
- Skills with the same name aren't merged; both can appear.
|
|
64
|
-
- To keep a skill manual, set `policy.allow_implicit_invocation: false` in `agents/openai.yaml`.
|
|
65
|
-
- To disable a skill everywhere, add `[[skills.config]] … enabled = false` to `~/.codex/config.toml`.
|
|
69
|
+
It needs **Node.js 22+** and works on macOS and Linux. Windows support is newer: it uses directory junctions, so no admin rights are needed.
|
|
66
70
|
|
|
67
|
-
|
|
71
|
+
On first run, skilllib asks two things:
|
|
68
72
|
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
1. **Which agents you use:** Claude Code, Cursor, Codex, Zed. The ones installed on your machine are pre-selected.
|
|
74
|
+
2. **Where your projects live**, e.g. `~/Projects`. It finds every git repo in there, and rescans each time it opens.
|
|
71
75
|
|
|
72
|
-
|
|
76
|
+
Then a good first session looks like this:
|
|
73
77
|
|
|
74
|
-
|
|
75
|
-
|
|
78
|
+
1. **Open a repo** (type its name, then Enter) to see everything its agents can use.
|
|
79
|
+
2. **Clean up global skills:** open **Global → ⚠ Clean up…** and decide, skill by skill, which repos keep it.
|
|
80
|
+
3. **Add skills** to a repo from the *Add skills* tab.
|
|
76
81
|
|
|
77
|
-
|
|
82
|
+
---
|
|
78
83
|
|
|
79
|
-
|
|
84
|
+
## Manual
|
|
80
85
|
|
|
81
|
-
|
|
86
|
+
### The screen
|
|
82
87
|
|
|
83
|
-
The left pane lists **places
|
|
88
|
+
The left pane lists **places**, and the right pane shows the skills of the place you pick:
|
|
84
89
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
90
|
+
| Place | What it shows |
|
|
91
|
+
|---|---|
|
|
92
|
+
| **Your skills** | Your library: master copies, versioned. Nothing here loads anywhere until you add it to a repo. |
|
|
93
|
+
| **Global** | Everything your agents load in *every* repo: yours, plus vendor skills (plugins, claude.ai, Cursor built-ins). |
|
|
94
|
+
| **Health** | Problems with one-key fixes, and everything you can restore. |
|
|
95
|
+
| **Projects** | Every repo found in your project folders. `◆` marks the one you're in. |
|
|
96
|
+
| **Settings** | Your agents and your project folders. |
|
|
97
|
+
| **Help** | Where skills come from, and how each agent finds and uses them. |
|
|
91
98
|
|
|
92
|
-
###
|
|
99
|
+
### Keys
|
|
93
100
|
|
|
94
|
-
|
|
101
|
+
| Key | Does |
|
|
102
|
+
|---|---|
|
|
103
|
+
| *type* | Search the pane you're in. Word initials work too: `cfw` finds `cloudflare-workers`. |
|
|
104
|
+
| `↑` `↓` | Move |
|
|
105
|
+
| `space` | The main action: add, remove, copy, clean up, fix, restore |
|
|
106
|
+
| `enter` | Every action for the selected row (or open a place) |
|
|
107
|
+
| `tab` | In a repo: switch between **Usable here** and **Add skills** |
|
|
108
|
+
| `→` `←` | Open or close a group |
|
|
109
|
+
| `esc` | Clear the search, then go back to the left pane |
|
|
110
|
+
| `?` | Help · `ctrl+r` reload · `ctrl+c` quit |
|
|
95
111
|
|
|
96
|
-
|
|
97
|
-
- *From your skills*: versioned skills you added. Space removes one.
|
|
98
|
-
- *The repo's own*: skills committed to the repo. Space copies one to **Your skills** so other repos can use it; the repo keeps its copy.
|
|
99
|
-
- *⚠ Global · yours* ("loaded globally"): skills in `~/.claude/skills` or `~/.agents/skills` that load in every repo, so every agent reads them all the time. Space opens the cleanup wizard.
|
|
100
|
-
- *Global · from vendors*, which only their vendor can remove:
|
|
101
|
-
- **Claude Code plugins** you enabled (`/plugin`); only Claude loads these
|
|
102
|
-
- **claude.ai skills** synced from your account; Claude only
|
|
103
|
-
- **Cursor built-ins** that ship with Cursor; Cursor only
|
|
112
|
+
### A repo
|
|
104
113
|
|
|
105
|
-
|
|
106
|
-
- **✓ committed**: in git, so teammates get it
|
|
107
|
-
- **± changed**: committed, with uncommitted edits
|
|
108
|
-
- **+ not added**: not committed yet
|
|
109
|
-
- **∅ ignored**: matched by `.gitignore`, so it only exists on your machine. Many repos ignore `.claude/skills`.
|
|
114
|
+
A repo has two lists:
|
|
110
115
|
|
|
111
|
-
|
|
112
|
-
- **Add skills:** your skills that this repo doesn't have yet. Space adds one.
|
|
116
|
+
**Usable here** shows everything agents can use in this repo, grouped by where it comes from:
|
|
113
117
|
|
|
114
|
-
|
|
118
|
+
| Group | What it is | `space` |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| *From your skills* | Versioned skills you added from your library | Remove it from this repo |
|
|
121
|
+
| *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 |
|
|
122
|
+
| *⚠ Global · yours* | Your global skills: they load in every repo | Open the cleanup wizard |
|
|
123
|
+
| *Global · from vendors* | Plugins, claude.ai skills, Cursor built-ins | – (manage them at the source) |
|
|
115
124
|
|
|
116
|
-
|
|
125
|
+
**Add skills** shows your skills that this repo doesn't have yet. `space` adds one.
|
|
117
126
|
|
|
118
|
-
|
|
127
|
+
Each row tells you:
|
|
119
128
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
129
|
+
| | Meaning |
|
|
130
|
+
|---|---|
|
|
131
|
+
| **✻ ⬡ ◎ ℤ** | Claude Code, Cursor, Codex, Zed. An icon in color means that agent loads the skill here; a faint one means it doesn't. |
|
|
132
|
+
| `²` | Cursor reaches this skill through two folders, so it may list it twice |
|
|
133
|
+
| `.claude` / `.agents` | The folder holding the real copy |
|
|
134
|
+
| **✓ committed** · **± changed** · **+ not added** · **∅ ignored** | The skill's git state. `∅ ignored` means it only exists on your machine. |
|
|
135
|
+
| `v2` · `v1 → v2` | The installed version, and whether a newer one exists |
|
|
136
|
+
| **⧉ 3 copies** | The same skill reaches your agents from 3 places. The details panel lists them; keep one. |
|
|
137
|
+
| last column | Claude Code uses in the last 30 days |
|
|
124
138
|
|
|
125
|
-
|
|
126
|
-
2. Review, then apply. Moved skills are copied into Your skills and installed where you ticked. Deleted ones are **not** kept in Your skills. Either way the original stops loading globally and goes to a backup you can restore from Health.
|
|
139
|
+
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.
|
|
127
140
|
|
|
128
|
-
|
|
141
|
+
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.
|
|
129
142
|
|
|
130
|
-
|
|
143
|
+
### Adding and removing skills
|
|
131
144
|
|
|
132
|
-
-
|
|
133
|
-
-
|
|
134
|
-
-
|
|
135
|
-
-
|
|
136
|
-
- Claude Code usage per project
|
|
137
|
-
- which projects have it
|
|
138
|
-
- other copies
|
|
139
|
-
- whether it's in Your skills
|
|
145
|
+
- **Adding** (`space` in *Add skills*) copies the newest version into `.claude/skills/<name>`, which Claude Code and Cursor read. If you use Codex or Zed, it also links it into `.agents/skills`. The skill is recorded in `skilllib.json`. Agents pick it up in their next session.
|
|
146
|
+
- **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.
|
|
147
|
+
- **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.
|
|
148
|
+
- **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.
|
|
140
149
|
|
|
141
|
-
|
|
150
|
+
### Versions
|
|
142
151
|
|
|
143
|
-
|
|
144
|
-
- **Global** → **✦ Ask an agent to review all global skills** (Enter lets you pick only your own)
|
|
145
|
-
- Enter on any skill or group → **Copy review prompt**
|
|
146
|
-
- `p` inside the cleanup wizard; then set move / keep / delete per skill based on the answer
|
|
152
|
+
Every change to a library skill becomes a new version, kept in `~/.skilllib/store`. Repos pin the version they use:
|
|
147
153
|
|
|
148
|
-
|
|
154
|
+
```json
|
|
155
|
+
{ "skills": { "stripe-payments": { "version": 2, "hash": "318bf4b94df4911c" } } }
|
|
156
|
+
```
|
|
149
157
|
|
|
150
|
-
|
|
158
|
+
| | Like | What it does |
|
|
159
|
+
|---|---|---|
|
|
160
|
+
| `skilllib sync` | `npm ci` | Installs exactly the pinned versions and restores missing ones. It never touches your edits. |
|
|
161
|
+
| `skilllib outdated` | `npm outdated` | Lists skills with a newer version |
|
|
162
|
+
| `skilllib update [name]` | `npm update` | Moves to the newest version |
|
|
163
|
+
| Enter → *Install a specific version…* | `npm i x@1` | Pins any version, including older ones |
|
|
151
164
|
|
|
152
|
-
|
|
165
|
+
Edit a skill once in **Your skills** (Enter → *Edit SKILL.md*). Every repo that uses it then shows `v1 → v2` and can update.
|
|
153
166
|
|
|
154
|
-
|
|
167
|
+
### Cleaning up global skills
|
|
155
168
|
|
|
156
|
-
|
|
169
|
+
<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%">
|
|
157
170
|
|
|
158
|
-
|
|
171
|
+
Open **Global → ⚠ Clean up…**, or press `space` on any of your global skills. For each skill, `space` cycles through:
|
|
159
172
|
|
|
160
|
-
|
|
173
|
+
- **◉ move:** installed into the repos you tick on the right. Repos that already have it, or where Claude Code used it, are pre-ticked.
|
|
174
|
+
- **○ keep global**
|
|
175
|
+
- **✕ delete** (`d`): removed without keeping a copy in your library
|
|
161
176
|
|
|
162
|
-
|
|
163
|
-
- **Space on it again** deletes that project copy and its links, and drops the entry from `skilllib.json`. Your library copy and other projects aren't touched. If you edited the project copy, you're asked first; Enter → *Save local edits to the library* keeps them.
|
|
164
|
-
- **Adding it back** installs the newest version again.
|
|
165
|
-
- Skills skilllib didn't install (a repo's own skills) are never deleted by Space; it offers to copy them into your library instead.
|
|
177
|
+
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**.
|
|
166
178
|
|
|
167
|
-
|
|
179
|
+
You can also delete one skill (Enter → **Delete**) or a whole group (Enter → **Delete all N**) straight from Global.
|
|
168
180
|
|
|
169
|
-
|
|
181
|
+
### Ask an agent to review your skills
|
|
170
182
|
|
|
171
|
-
|
|
172
|
-
- `◌` means only other agents can see it.
|
|
183
|
+
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:
|
|
173
184
|
|
|
174
|
-
|
|
185
|
+
- its description and SKILL.md
|
|
186
|
+
- how it was installed (plugin, `npx skills`, claude.ai, copied in…)
|
|
187
|
+
- which agents load it
|
|
188
|
+
- usage per repo
|
|
189
|
+
- duplicates
|
|
190
|
+
- your project list, so the agent can check each repo's stack
|
|
175
191
|
|
|
176
|
-
|
|
177
|
-
- **Enter → Link for Claude Code** adds a relative symlink in `.claude/skills` pointing at the repo copy. This is the same thing `npx skills` does, and `.claude/skills` is often gitignored. **Unlink** removes only the link.
|
|
192
|
+
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.
|
|
178
193
|
|
|
179
|
-
|
|
194
|
+
It's available from:
|
|
195
|
+
- **Global → ✦ Ask an agent to review all global skills**
|
|
196
|
+
- Enter on any skill or group → **Copy review prompt**
|
|
197
|
+
- `p` inside the cleanup wizard
|
|
180
198
|
|
|
181
|
-
###
|
|
199
|
+
### Health and backups
|
|
182
200
|
|
|
183
|
-
|
|
201
|
+
**Health** lists broken links, skills loaded twice, out-of-date repos and repo-only skills, each with a one-key fix. Below them is everything skilllib ever moved out, and `space` puts it back where it came from.
|
|
184
202
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
203
|
+
skilllib never really deletes anything:
|
|
204
|
+
- removed library skills go to `~/.skilllib/trash`
|
|
205
|
+
- removed global skills go to `~/.skilllib/global-backup`
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Where skills come from
|
|
210
|
+
|
|
211
|
+
A skill is a folder with a `SKILL.md`. These are all the places your agents load them from:
|
|
188
212
|
|
|
189
|
-
|
|
|
213
|
+
| Where | Examples | Who sees it |
|
|
190
214
|
|---|---|---|
|
|
191
|
-
|
|
|
192
|
-
|
|
|
193
|
-
|
|
|
194
|
-
|
|
|
215
|
+
| **The repo** | `.claude/skills`, `.agents/skills`, `.cursor/skills`, `.codex/skills` | Agents working in that repo |
|
|
216
|
+
| **Global folders** | `~/.claude/skills`, `~/.agents/skills` (`npx skills add` installs here), `~/.cursor/skills` | **Every repo** |
|
|
217
|
+
| **Vendors** | Claude Code plugins (`/plugin`), claude.ai skills, Claude Code's bundled commands, Cursor built-ins and marketplace, Codex system skills | Every repo; only the vendor can remove them |
|
|
218
|
+
| **Your skills** | `~/.skilllib/library` | Nobody, until you add a skill to a repo |
|
|
219
|
+
|
|
220
|
+
### ✻ Claude Code · [docs](https://code.claude.com/docs/en/skills)
|
|
221
|
+
|
|
222
|
+
- **Where it looks.** When names collide, the first one listed wins:
|
|
223
|
+
1. enterprise (managed settings)
|
|
224
|
+
2. `~/.claude/skills`
|
|
225
|
+
3. `.claude/skills`
|
|
226
|
+
4. nested `<subfolder>/.claude/skills`
|
|
227
|
+
5. plugins (as `/plugin:skill`)
|
|
228
|
+
6. bundled
|
|
229
|
+
|
|
230
|
+
It also reads claude.ai skills from `~/.claude/skills/synced` and folders passed with `--add-dir`. It **doesn't read `.agents/skills`** (verified).
|
|
231
|
+
- **How it uses them.** Descriptions are always in context; the full `SKILL.md` loads on `/name` or when Claude decides it's relevant.
|
|
232
|
+
- `disable-model-invocation: true`: only you can run it.
|
|
233
|
+
- `user-invocable: false`: only Claude can.
|
|
234
|
+
- **Per-repo control.** `skillOverrides` in `.claude/settings.json` (`"off"`, `"name-only"`, `"user-invocable-only"`). It's Claude-only, so skilllib moves skills out of global instead of blocking them.
|
|
235
|
+
|
|
236
|
+
### ⬡ Cursor · [docs](https://cursor.com/docs/context/skills)
|
|
237
|
+
|
|
238
|
+
- **Where it looks.**
|
|
239
|
+
- Project: `.agents/skills` and `.cursor/skills`, including nested ones, which apply only to files inside them.
|
|
240
|
+
- Your home folder: `~/.agents/skills` and `~/.cursor/skills`.
|
|
241
|
+
- For compatibility: `.claude/skills`, `.codex/skills`, `~/.claude/skills` and `~/.codex/skills`.
|
|
242
|
+
- Also marketplace plugins and Cursor's built-ins. Cloud Agents only see `~/.cursor/skills`.
|
|
243
|
+
- **How it uses them.** Descriptions decide relevance, and the full content loads on use; `/` runs one. `paths:` globs limit a skill to matching files, and `disable-model-invocation: true` makes it manual.
|
|
244
|
+
- **Limits.** There's no per-project switch for global skills. Its docs don't say how it handles one skill reached through two folders.
|
|
195
245
|
|
|
196
|
-
###
|
|
246
|
+
### ◎ Codex · [docs](https://learn.chatgpt.com/docs/build-skills)
|
|
197
247
|
|
|
198
|
-
- **
|
|
199
|
-
- **
|
|
248
|
+
- **Where it looks.** `.agents/skills` in the working folder, its parents and the repo root; then `~/.agents/skills`; `/etc/codex/skills` (admin); and OpenAI's bundled skills. It **doesn't read `.claude/skills`**.
|
|
249
|
+
- **How it uses them.** Names and descriptions come first (about 2% of context); `SKILL.md` loads when used, and `$` picks one.
|
|
250
|
+
- Same-name skills aren't merged.
|
|
251
|
+
- `policy.allow_implicit_invocation: false` in `agents/openai.yaml` keeps a skill manual.
|
|
252
|
+
- `[[skills.config]] … enabled = false` in `~/.codex/config.toml` disables one everywhere.
|
|
200
253
|
|
|
201
|
-
|
|
254
|
+
### ℤ Zed · [docs](https://zed.dev/docs/ai/skills)
|
|
202
255
|
|
|
203
|
-
|
|
256
|
+
- **Where it looks.** `<worktree>/.agents/skills` (trusted worktrees only) and `~/.agents/skills`. Only direct child folders count, and on a name collision the project's skill wins.
|
|
257
|
+
- **How it uses them.** The agent sees a catalog of names and descriptions; `/` or `@skill` runs one. Changes apply without a restart.
|
|
204
258
|
|
|
205
|
-
|
|
206
|
-
- **Usage only counts Claude Code.**
|
|
207
|
-
- **Unloading a skills.sh skill doesn't update its lock file.** If you stop loading a skill from `~/.agents/skills`, the `npx skills` lock file still lists it as installed.
|
|
259
|
+
---
|
|
208
260
|
|
|
209
|
-
##
|
|
261
|
+
## Command line
|
|
210
262
|
|
|
211
|
-
Everything the app does
|
|
263
|
+
Everything the app does also works as a command, for scripts and CI:
|
|
212
264
|
|
|
213
265
|
```
|
|
266
|
+
skilllib open the app (prints `status` when piped)
|
|
214
267
|
skilllib scan [folder...] add project folders and scan them
|
|
215
268
|
skilllib folders [add|remove] show or change project folders
|
|
216
|
-
skilllib
|
|
217
|
-
|
|
218
|
-
skilllib
|
|
269
|
+
skilllib harnesses [id...] show or set your agents (claude-code cursor codex zed)
|
|
270
|
+
|
|
271
|
+
skilllib status this repo's skills
|
|
272
|
+
skilllib add | remove <name> change this repo's skills
|
|
219
273
|
skilllib sync [--all] install exactly the pinned versions
|
|
220
|
-
skilllib outdated [--all] skills with newer
|
|
221
|
-
skilllib update [name...] move to the newest versions
|
|
222
|
-
skilllib
|
|
274
|
+
skilllib outdated [--all] skills with a newer version
|
|
275
|
+
skilllib update [name...] move to the newest versions
|
|
276
|
+
skilllib link [--all] make every skill here usable by all your agents
|
|
277
|
+
|
|
278
|
+
skilllib list | show <name> your library
|
|
279
|
+
skilllib import <dir>... add skill folders to your library (--global: all your global skills)
|
|
223
280
|
skilllib new <name> [desc] create a skill
|
|
224
|
-
|
|
225
|
-
skilllib usage [--days N]
|
|
226
|
-
skilllib doctor [--fix]
|
|
227
|
-
skilllib restore [name] put back something
|
|
228
|
-
skilllib
|
|
281
|
+
|
|
282
|
+
skilllib usage [--days N] which skills Claude Code used
|
|
283
|
+
skilllib doctor [--fix] find (and fix) problems
|
|
284
|
+
skilllib restore [name] put back something skilllib moved out
|
|
285
|
+
skilllib --version
|
|
229
286
|
```
|
|
230
287
|
|
|
231
|
-
|
|
288
|
+
Flags: `--force` (overwrite local edits), `--allow-tracked` (link into git-tracked folders), `--days N`.
|
|
232
289
|
|
|
233
290
|
## Files
|
|
234
291
|
|
|
235
292
|
| Path | What |
|
|
236
293
|
|---|---|
|
|
237
|
-
|
|
|
238
|
-
| `~/.skilllib/
|
|
239
|
-
| `~/.skilllib/
|
|
240
|
-
| `~/.skilllib/
|
|
241
|
-
| `~/.skilllib/
|
|
242
|
-
|
|
|
294
|
+
| `<repo>/skilllib.json` | The repo's skills and pinned versions. **Commit it.** |
|
|
295
|
+
| `~/.skilllib/library/` | Your skills (master copies). Worth putting under git. |
|
|
296
|
+
| `~/.skilllib/store/` | Every version of every skill, immutable |
|
|
297
|
+
| `~/.skilllib/config.json` | Your agents, project folders, hidden projects |
|
|
298
|
+
| `~/.skilllib/trash/`, `global-backup/` | Everything skilllib removed, restorable from Health |
|
|
299
|
+
| `~/.skilllib/review-prompt.md` | The last review prompt you copied |
|
|
300
|
+
|
|
301
|
+
Environment variables: `SKILLLIB_HOME` moves `~/.skilllib`, `$VISUAL` / `$EDITOR` set the editor, and `CLAUDE_CONFIG_DIR` is honored.
|
|
243
302
|
|
|
244
|
-
|
|
303
|
+
## FAQ
|
|
304
|
+
|
|
305
|
+
**Does it change my repos?** Only when you tell it to: adding, removing or linking a skill, which updates `skilllib.json`. It asks before writing into a folder git tracks, and it never deletes a repo's own skills.
|
|
306
|
+
|
|
307
|
+
**Can I share skills with my team?** Commit `skilllib.json` along with the copies in `.claude/skills`. Or keep your library in a git repo and point `SKILLLIB_HOME` at it.
|
|
308
|
+
|
|
309
|
+
**Why does usage only count Claude Code?** It's the only agent here with local transcripts to read. Cursor doesn't keep them locally, and Codex's format hasn't been tested yet. That's why "unused" is a strong hint, not proof.
|
|
310
|
+
|
|
311
|
+
**What's not supported yet?**
|
|
312
|
+
- Cursor marketplace plugin skills: Cursor doesn't record which ones are enabled in a file skilllib can read.
|
|
313
|
+
- Unloading a `npx skills` skill doesn't update that tool's lock file.
|
|
314
|
+
- Installing new skills straight from GitHub is coming. For now, `skilllib import <folder>` or copy one from a repo.
|
|
315
|
+
|
|
316
|
+
---
|
|
245
317
|
|
|
246
318
|
## Development
|
|
247
319
|
|
|
248
320
|
```bash
|
|
249
321
|
pnpm install
|
|
250
|
-
pnpm test && pnpm type-check && pnpm build # tests
|
|
322
|
+
pnpm test && pnpm type-check && pnpm build # tests run on bun
|
|
251
323
|
pnpm dev # run from source
|
|
252
|
-
npm link # use your checkout as
|
|
324
|
+
npm link # use your checkout as `skilllib`
|
|
253
325
|
```
|
|
254
326
|
|
|
255
|
-
|
|
256
|
-
|
|
327
|
+
**Releasing:**
|
|
257
328
|
1. Bump `version` in `package.json` and merge to `main`.
|
|
258
|
-
2. Tag
|
|
329
|
+
2. Tag and push:
|
|
330
|
+
```bash
|
|
331
|
+
git tag v1.0.2 && git push --tags
|
|
332
|
+
```
|
|
259
333
|
|
|
260
|
-
|
|
334
|
+
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.
|
|
261
335
|
|
|
262
|
-
The earlier registry-server version (Next.js, Postgres, S3)
|
|
336
|
+
The earlier registry-server version (Next.js, Postgres, S3) lives on the `archive/registry-server` branch.
|
|
263
337
|
|
|
264
338
|
## License
|
|
265
339
|
|
|
266
|
-
MIT
|
|
340
|
+
[MIT](LICENSE) © Toni Tralice
|
|
@@ -422,7 +422,7 @@ function globalFolderSkills(enabled) {
|
|
|
422
422
|
linksTo.set(target.path, [...linksTo.get(target.path) ?? [], e]);
|
|
423
423
|
continue;
|
|
424
424
|
}
|
|
425
|
-
const target_ = e.isLink ? readlinkSync(e.path) : "";
|
|
425
|
+
const target_ = e.isLink ? readlinkSync(e.path).replace(/\\/g, "/") : "";
|
|
426
426
|
const inAgents = e.dir === agentsDir || target_.includes(".agents/skills");
|
|
427
427
|
const locked = lock[e.name]?.source;
|
|
428
428
|
skills.push({
|
|
@@ -446,7 +446,8 @@ function globalFolderSkills(enabled) {
|
|
|
446
446
|
return skills;
|
|
447
447
|
}
|
|
448
448
|
function tildify2(p) {
|
|
449
|
-
|
|
449
|
+
const shown = p.startsWith(userHome()) ? "~" + p.slice(userHome().length) : p;
|
|
450
|
+
return shown.replace(/\\/g, "/");
|
|
450
451
|
}
|
|
451
452
|
function cursorBuiltInSkills(enabled) {
|
|
452
453
|
if (!enabled.includes("cursor")) return [];
|
|
@@ -549,8 +550,7 @@ function librarySkills() {
|
|
|
549
550
|
return skillDirsIn(libraryDir()).map((dir) => ({
|
|
550
551
|
name: basename3(dir),
|
|
551
552
|
description: readSkillInfo(dir).description,
|
|
552
|
-
dir
|
|
553
|
-
hash: treeHash(dir) ?? ""
|
|
553
|
+
dir
|
|
554
554
|
}));
|
|
555
555
|
}
|
|
556
556
|
function librarySkillDir(name) {
|
|
@@ -1537,7 +1537,6 @@ export {
|
|
|
1537
1537
|
syncProject,
|
|
1538
1538
|
updateProject,
|
|
1539
1539
|
importSkill,
|
|
1540
|
-
projectsUsing,
|
|
1541
1540
|
deleteLibrarySkill,
|
|
1542
1541
|
deleteGlobal,
|
|
1543
1542
|
unloadGlobal,
|
package/dist/index.js
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
unhide,
|
|
22
22
|
update,
|
|
23
23
|
usage
|
|
24
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-67BDL5SN.js";
|
|
25
25
|
|
|
26
26
|
// src/index.ts
|
|
27
27
|
import { readFileSync } from "fs";
|
|
@@ -73,9 +73,9 @@ async function main() {
|
|
|
73
73
|
const args = parseArgs(rest);
|
|
74
74
|
switch (command) {
|
|
75
75
|
case void 0:
|
|
76
|
-
return process.stdin.isTTY && process.stdout.isTTY ? (await import("./tui-
|
|
76
|
+
return process.stdin.isTTY && process.stdout.isTTY ? (await import("./tui-CQCVL6IK.js")).tui() : status(args);
|
|
77
77
|
case "ui":
|
|
78
|
-
return (await import("./tui-
|
|
78
|
+
return (await import("./tui-CQCVL6IK.js")).tui();
|
|
79
79
|
case "status":
|
|
80
80
|
return status(args);
|
|
81
81
|
case "add":
|
|
@@ -27,7 +27,6 @@ import {
|
|
|
27
27
|
machineSkills,
|
|
28
28
|
projectOfFactory,
|
|
29
29
|
projectStatus,
|
|
30
|
-
projectsUsing,
|
|
31
30
|
readConfig,
|
|
32
31
|
readSkillInfo,
|
|
33
32
|
relinkDependency,
|
|
@@ -47,7 +46,7 @@ import {
|
|
|
47
46
|
versionHistory,
|
|
48
47
|
visibilityOf,
|
|
49
48
|
visibleProjects
|
|
50
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-67BDL5SN.js";
|
|
51
50
|
|
|
52
51
|
// src/tui/index.tsx
|
|
53
52
|
import { render } from "ink";
|
|
@@ -250,7 +249,8 @@ function loadSnapshot() {
|
|
|
250
249
|
name: s.name,
|
|
251
250
|
description: s.description,
|
|
252
251
|
origin: origins[s.name] ?? inferred(s.name),
|
|
253
|
-
|
|
252
|
+
// Managed status entries are the manifest, already read above; no need to re-read every manifest per skill.
|
|
253
|
+
projects: projects.filter((p) => statusOf(p).some((x) => x.managed && x.name === s.name)).sort(),
|
|
254
254
|
version: latestVersion(s.name)?.version ?? null
|
|
255
255
|
}));
|
|
256
256
|
return {
|
|
@@ -474,12 +474,16 @@ function CleanupWizard({
|
|
|
474
474
|
/* @__PURE__ */ jsx2(Box2, { flexGrow: 1 }),
|
|
475
475
|
orphans.length ? /* @__PURE__ */ jsx2(Text2, { color: color.yellow, children: `${plural(orphans.length, "skill")} won't be in any project \u2014 add them later from "Add skills".` }) : null
|
|
476
476
|
] }),
|
|
477
|
-
/* @__PURE__ */
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
477
|
+
/* @__PURE__ */ jsx2(Box2, { height: 1, paddingX: 1, children: /* @__PURE__ */ jsx2(
|
|
478
|
+
KeyBar,
|
|
479
|
+
{
|
|
480
|
+
width: width - 2,
|
|
481
|
+
hints: [
|
|
482
|
+
["enter", "apply"],
|
|
483
|
+
["esc", "back"]
|
|
484
|
+
]
|
|
485
|
+
}
|
|
486
|
+
) })
|
|
483
487
|
] });
|
|
484
488
|
}
|
|
485
489
|
const leftWidth = Math.max(40, Math.floor(width * 0.55));
|
|
@@ -559,17 +563,20 @@ function CleanupWizard({
|
|
|
559
563
|
})() }),
|
|
560
564
|
wrap(skill.description || "(no description)", width - 6, detailHeight - 3).map((l, i) => /* @__PURE__ */ jsx2(Text2, { color: color.text, wrap: "truncate-end", children: l }, i))
|
|
561
565
|
] }) : null,
|
|
562
|
-
/* @__PURE__ */ jsx2(Box2, { height: 1, paddingX: 1, children:
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
566
|
+
/* @__PURE__ */ jsx2(Box2, { height: 1, paddingX: 1, children: /* @__PURE__ */ jsx2(
|
|
567
|
+
KeyBar,
|
|
568
|
+
{
|
|
569
|
+
width: width - 2,
|
|
570
|
+
hints: [
|
|
571
|
+
["space", focus === "skills" ? "move / keep / delete" : "tick project"],
|
|
572
|
+
...focus === "skills" ? [["d", "delete"]] : [],
|
|
573
|
+
["tab", "switch side"],
|
|
574
|
+
["enter", `review (${plural(totalInstalls, "install")})`],
|
|
575
|
+
["p", "ask an agent"],
|
|
576
|
+
["esc", "cancel"]
|
|
577
|
+
]
|
|
578
|
+
}
|
|
579
|
+
) })
|
|
573
580
|
] });
|
|
574
581
|
}
|
|
575
582
|
|
|
@@ -1156,7 +1163,8 @@ function App() {
|
|
|
1156
1163
|
const edit = async (file) => {
|
|
1157
1164
|
const editor = process.env.VISUAL || process.env.EDITOR || (process.platform === "win32" ? "notepad" : "vi");
|
|
1158
1165
|
await suspendTerminal(() => {
|
|
1159
|
-
spawnSync2(`${editor} "${file}"`, { shell: true, stdio: "inherit" });
|
|
1166
|
+
if (process.platform === "win32") spawnSync2(`${editor} "${file}"`, { shell: true, stdio: "inherit" });
|
|
1167
|
+
else spawnSync2("/bin/sh", ["-c", `${editor} "$1"`, "sh", file], { stdio: "inherit" });
|
|
1160
1168
|
});
|
|
1161
1169
|
reload();
|
|
1162
1170
|
say(`Saved ${tildify2(file)}`);
|
package/package.json
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "skilllib",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Manage agent skills like dependencies
|
|
3
|
+
"version": "1.0.2",
|
|
4
|
+
"description": "Manage your agent skills like dependencies. One library for all your skills; each repo gets only the ones it needs, and every agent can see them. Works with Claude Code, Cursor, Codex and Zed.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-skills",
|
|
7
7
|
"skills",
|
|
8
|
+
"skill-md",
|
|
8
9
|
"claude-code",
|
|
10
|
+
"claude",
|
|
9
11
|
"cursor",
|
|
10
12
|
"codex",
|
|
11
13
|
"zed",
|
|
12
|
-
"
|
|
14
|
+
"ai-agents",
|
|
15
|
+
"skills-manager",
|
|
13
16
|
"cli",
|
|
14
17
|
"tui"
|
|
15
18
|
],
|
|
@@ -25,7 +28,7 @@
|
|
|
25
28
|
"author": "Toni Tralice",
|
|
26
29
|
"type": "module",
|
|
27
30
|
"bin": {
|
|
28
|
-
"skilllib": "
|
|
31
|
+
"skilllib": "dist/index.js"
|
|
29
32
|
},
|
|
30
33
|
"files": [
|
|
31
34
|
"dist",
|