skillcask 0.1.2 → 0.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 +127 -10
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -75,6 +75,7 @@ skillcask status # manifest vs lock vs installed fil
|
|
|
75
75
|
skills.toml # manifest, commit it
|
|
76
76
|
skills.lock # lock, commit it
|
|
77
77
|
.agents/skills/<name>/ # installed skill (gitignored)
|
|
78
|
+
.agents/skills/.skillcask-installed # what this machine installed (gitignored)
|
|
78
79
|
.claude/skills/<name> -> ../../.agents/skills/<name>
|
|
79
80
|
.junie/skills/<name> -> ../../.agents/skills/<name>
|
|
80
81
|
.gitignore # managed block
|
|
@@ -84,20 +85,26 @@ Project skills live in `.skills/<name>/SKILL.md` (`[agents] local`). skillcask l
|
|
|
84
85
|
into the store (`.agents/skills/<name> -> ../../.skills/<name>`) and from there into every agent
|
|
85
86
|
directory. These links are committed, so they work in every clone. A directory written by hand
|
|
86
87
|
straight into `.agents/skills/` is linked the same way. A project skill with the same name as a
|
|
87
|
-
locked one is an error.
|
|
88
|
+
locked one is an error. When a skill with the same name exists in your home (`~/.claude/skills`,
|
|
89
|
+
`~/.agents/skills`, …), `install` and `doctor` print a warning: Claude Code runs the personal one,
|
|
90
|
+
Codex lists both.
|
|
88
91
|
|
|
89
92
|
### skills.toml
|
|
90
93
|
|
|
91
94
|
```toml
|
|
92
95
|
[repositories]
|
|
93
|
-
# Packagist is the implicit last repository.
|
|
94
96
|
acme = { type = "composer", url = "https://git.example.com/api/v4/group/42/-/packages/composer/packages.json" }
|
|
97
|
+
# A repository you review yourself can skip the cooldown; the others keep it.
|
|
98
|
+
own = { url = "https://git.example.com/own/packages.json", min-release-age = "0" }
|
|
99
|
+
# Default sources, written by `init`; `= false` turns one off. Packagist is always searched last.
|
|
100
|
+
packagist = { url = "https://repo.packagist.org" }
|
|
101
|
+
github = { type = "github", url = "https://api.github.com" } # GitHub Enterprise: its API URL
|
|
95
102
|
|
|
96
103
|
[skills]
|
|
97
104
|
"netresearch/agent-jira-skill" = "^3.34"
|
|
98
105
|
"acme/agents-md" = { version = "^1.0", repository = "acme" }
|
|
99
106
|
"acme/review" = { version = "1.4.2", repository = "acme", skills = ["review"] }
|
|
100
|
-
"mattpocock/skills" = { github = true, version = "^1.3", skills = ["tdd", "
|
|
107
|
+
"mattpocock/skills" = { github = true, version = "^1.3", skills = ["tdd", "code-review"], rename = { code-review = "mp-code-review" } }
|
|
101
108
|
"anthropics/skills" = { github = true, skills = ["pdf"] } # default branch
|
|
102
109
|
|
|
103
110
|
[agents]
|
|
@@ -108,14 +115,101 @@ local = ".skills" # project skills
|
|
|
108
115
|
min-release-age = "3d" # cooldown for add/update; "0" disables
|
|
109
116
|
allow-ranges = true # false: every version must be exact
|
|
110
117
|
packagist = true # false: drop the implicit Packagist repository
|
|
118
|
+
github-requires = false # true: dependencies may come from GitHub
|
|
119
|
+
allow-sources = ["acme", "own", "packagist", "github"] # only these sources; default: all
|
|
111
120
|
```
|
|
112
121
|
|
|
113
122
|
Constraints follow Composer semantics: `^0.3` means `>=0.3.0 <0.4.0`, `~1.2` means
|
|
114
123
|
`>=1.2 <2.0`, and pre-releases are only selected when the constraint names a stability
|
|
115
124
|
(`^1.0@beta`).
|
|
116
125
|
|
|
126
|
+
### Allowed sources and policy for every project
|
|
127
|
+
|
|
128
|
+
`allow-sources` lists the only places skills may come from: repository names, `packagist`,
|
|
129
|
+
`github`, or `https://` URL prefixes (`https://api.github.com/repos/acme/` allows one GitHub
|
|
130
|
+
organisation). Other repositories get no request, and `install` refuses a lock entry from them,
|
|
131
|
+
also with `--frozen`, so a committed lock cannot bring them back. Dependencies follow the same
|
|
132
|
+
rule.
|
|
133
|
+
|
|
134
|
+
Policy can also come from `config.toml` next to the global manifest (`~/.config/skillcask`) and
|
|
135
|
+
from the environment. The first layer that sets a key wins:
|
|
136
|
+
|
|
137
|
+
1. `SKILLCASK_ALLOW_SOURCES`, `SKILLCASK_MIN_RELEASE_AGE`, `SKILLCASK_ALLOW_RANGES`,
|
|
138
|
+
`SKILLCASK_PACKAGIST`, `SKILLCASK_GITHUB_REQUIRES` (overriding an enforced key prints a
|
|
139
|
+
warning);
|
|
140
|
+
2. keys `config.toml` lists in `enforce`: a project that sets them otherwise fails;
|
|
141
|
+
3. `[policy]` in `skills.toml`;
|
|
142
|
+
4. the other keys of `config.toml`, as defaults.
|
|
143
|
+
|
|
144
|
+
```toml
|
|
145
|
+
# ~/.config/skillcask/config.toml: only the company registry and GitHub, in every project
|
|
146
|
+
[policy]
|
|
147
|
+
allow-sources = ["https://gitlab.example.com/", "github"]
|
|
148
|
+
enforce = ["allow-sources"]
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
`config.toml` and the environment take URL prefixes, not repository names, since a name means
|
|
152
|
+
whatever a project calls it. `skillcask status` prints each key that is set and where it came
|
|
153
|
+
from.
|
|
154
|
+
|
|
155
|
+
### Dependencies
|
|
156
|
+
|
|
157
|
+
A skill that needs other skills lists them in its `SKILL.md`:
|
|
158
|
+
|
|
159
|
+
```yaml
|
|
160
|
+
---
|
|
161
|
+
name: gitlab-branch-mr
|
|
162
|
+
version: 1.2.0
|
|
163
|
+
requires:
|
|
164
|
+
acme/security-review: ^1.0
|
|
165
|
+
github:mattpocock/skills/pr: main
|
|
166
|
+
---
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`add`, `install` and `update` resolve, lock and install them like your own entries: same
|
|
170
|
+
cooldown, same hashes, one version per package (the highest one every requirer accepts). They
|
|
171
|
+
stay out of `skills.toml`; the lock records each package's `requires` and switches to
|
|
172
|
+
`version = 2`. A dependency is looked up only in your repositories, in order, then Packagist;
|
|
173
|
+
a `github:` one needs `github-requires = true`. `remove` drops dependencies nobody needs any
|
|
174
|
+
more, and `status` shows them as `via <requirer>`.
|
|
175
|
+
|
|
176
|
+
### Name conflicts
|
|
177
|
+
|
|
178
|
+
Skills have no namespaces: an agent knows a skill by its name. Two skills with the same name in
|
|
179
|
+
one project are an error. Install one of them under another name with `rename`:
|
|
180
|
+
|
|
181
|
+
```toml
|
|
182
|
+
"mattpocock/skills" = { github = true, rename = { code-review = "mp-code-review" } }
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
skillcask then installs `.agents/skills/mp-code-review` and changes the `name:` line in its
|
|
186
|
+
`SKILL.md`; the lock records the original name and the hash of the renamed copy. Nothing else in
|
|
187
|
+
the skill changes, so text that mentions the old name (`/code-review`) stays as it is.
|
|
188
|
+
`add`, `install` and `update` offer the rename when they hit a conflict in a terminal.
|
|
189
|
+
|
|
190
|
+
### Personal skills (`--global`)
|
|
191
|
+
|
|
192
|
+
`skillcask --global` (`-g`) manages skills for your user instead of a project, with the same
|
|
193
|
+
manifest, lock and verification:
|
|
194
|
+
|
|
195
|
+
```sh
|
|
196
|
+
skillcask -g add github:mattpocock/skills/grill-me
|
|
197
|
+
skillcask -g install --frozen # e.g. from a dotfiles repository
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
- `skills.toml`, `skills.lock` and an optional `auth.json` live in `~/.config/skillcask`
|
|
201
|
+
(`$XDG_CONFIG_HOME/skillcask`; `SKILLCASK_HOME` overrides both). Keep them in your dotfiles.
|
|
202
|
+
- Skills go to `~/.agents/skills` (read by Codex), with links in `~/.claude/skills` and
|
|
203
|
+
`~/.junie/skills` (`[agents] targets`, relative to home). Links are absolute, so a symlinked
|
|
204
|
+
`~/.claude` works. `[agents] local` does not apply.
|
|
205
|
+
- Personal skills you wrote by hand stay where they are and are not linked anywhere.
|
|
206
|
+
- The list of managed paths is `~/.agents/skills/.skillcask-installed`, local to the machine;
|
|
207
|
+
nothing touches git.
|
|
208
|
+
|
|
117
209
|
### Commands
|
|
118
210
|
|
|
211
|
+
Every command except `publish` takes `-g, --global`.
|
|
212
|
+
|
|
119
213
|
| Command | |
|
|
120
214
|
|---|---|
|
|
121
215
|
| `init` | Create `skills.toml`. |
|
|
@@ -127,8 +221,9 @@ Constraints follow Composer semantics: `^0.3` means `>=0.3.0 <0.4.0`, `~1.2` mea
|
|
|
127
221
|
| `outdated` | Newer versions, and when cooled-down ones become eligible. |
|
|
128
222
|
| `status` | Exit 1 when manifest, lock or installed files disagree. |
|
|
129
223
|
| `doctor [--fix]` | Broken or committed links, stale gitignore block, modified skills. |
|
|
130
|
-
| `search <query>` | Packagist (`type=ai-agent-skill`) and
|
|
131
|
-
| `
|
|
224
|
+
| `search <query>` | Packagist (`type=ai-agent-skill`) and skill packages of the other repositories, GitLab included. |
|
|
225
|
+
| `auth set\|remove <host>` | Keep a registry token in git's credential helper (Keychain, Credential Manager, libsecret). |
|
|
226
|
+
| `publish --vendor v --base-url URL --out DIR [--inline] [--dist-url TPL] [paths…]` | Build a static Composer repository from a monorepo. |
|
|
132
227
|
| `<other>` | Runs `skillcask-<other>` from `PATH`, like git and cargo plugins. |
|
|
133
228
|
|
|
134
229
|
Exit codes: 0 ok, 1 manifest/lock/status problems, 2 authentication, 3 network, 4 hash mismatch,
|
|
@@ -187,12 +282,20 @@ what you picked.
|
|
|
187
282
|
- Archives with absolute paths, `..`, devices or symlinks that leave their skill are rejected.
|
|
188
283
|
No symlink is ever written from a package. Size and file count are capped (`--max-download`,
|
|
189
284
|
`--max-unpacked`, `--max-files`).
|
|
285
|
+
- File names must be valid on every OS: Windows-reserved names, `<>:"|?*\`, control characters
|
|
286
|
+
and paths that collide by case or Unicode form fail a skill that contains them, and are
|
|
287
|
+
skipped outside the selected skills.
|
|
190
288
|
- No package code runs, ever. No telemetry.
|
|
191
|
-
- `min-release-age` for GitHub sources
|
|
192
|
-
|
|
193
|
-
the
|
|
289
|
+
- `min-release-age` for GitHub sources uses times GitHub sets: release publication for tags,
|
|
290
|
+
push times from the Activity API for branches. A tag without a release, or a ref GitHub lists no
|
|
291
|
+
pushes for, falls back to commit dates, which the committer sets; reviewing what `add`/`update`
|
|
292
|
+
change in `skills.lock` is the real check there.
|
|
194
293
|
- Credentials come from Composer's `auth.json` / `COMPOSER_AUTH` (`http-basic`, `bearer`,
|
|
195
|
-
`gitlab-token`, `gitlab-oauth`) and are never printed.
|
|
294
|
+
`gitlab-token`, `gitlab-oauth`), then from git's credential helper, and are never printed.
|
|
295
|
+
`skillcask auth set git.example.com` keeps a token in the macOS Keychain, the Windows Credential
|
|
296
|
+
Manager or libsecret instead of a plain-text file (the default username `PRIVATE-TOKEN` sends
|
|
297
|
+
GitLab's header; `--username oauth2` a Bearer token). `SKILLCASK_GIT_CREDENTIALS=0` turns the
|
|
298
|
+
helper off. In GitLab CI use `http-basic` with the
|
|
196
299
|
user `gitlab-ci-token` and the password `$CI_JOB_TOKEN`.
|
|
197
300
|
|
|
198
301
|
## Publishing skills
|
|
@@ -211,9 +314,23 @@ This writes `packages.json`, `p2/acme/<name>.json` and deterministic zips under
|
|
|
211
314
|
versions are immutable, and re-running on unchanged skills changes no file. Serve the directory
|
|
212
315
|
over HTTPS.
|
|
213
316
|
|
|
317
|
+
Hosts that cannot serve `/` inside file names (GitLab's Generic Package Registry) take a single
|
|
318
|
+
file instead:
|
|
319
|
+
|
|
320
|
+
```sh
|
|
321
|
+
skillcask publish --inline --vendor acme --out composer/ skills/ \
|
|
322
|
+
--dist-url 'https://git.example.com/api/v4/projects/7/packages/generic/{vendor}-{name}/{version}/{name}-{version}.zip'
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
`--inline` puts every package into `packages.json` and writes no `p2/`. Upload each
|
|
326
|
+
`dist/<vendor>/<name>/<version>.zip` to the URL the template gives, and commit `packages.json` to
|
|
327
|
+
a repository. A repository `url` with a query string is used as given, so clients can read the
|
|
328
|
+
file through the GitLab raw files API
|
|
329
|
+
(`.../repository/files/composer%2Fpackages.json/raw?ref=main`) with a `gitlab-token`.
|
|
330
|
+
|
|
214
331
|
## Design
|
|
215
332
|
|
|
216
|
-
See [docs/
|
|
333
|
+
See [docs/specs/2026-10-19-skillcask-v1.md](docs/specs/2026-10-19-skillcask-v1.md).
|
|
217
334
|
|
|
218
335
|
## License
|
|
219
336
|
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"hasInstallScript": true,
|
|
20
20
|
"license": "MIT OR Apache-2.0",
|
|
21
21
|
"name": "skillcask",
|
|
22
|
-
"version": "0.
|
|
22
|
+
"version": "0.3.0"
|
|
23
23
|
},
|
|
24
24
|
"node_modules/detect-libc": {
|
|
25
25
|
"engines": {
|
|
@@ -48,5 +48,5 @@
|
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
"requires": true,
|
|
51
|
-
"version": "0.
|
|
51
|
+
"version": "0.3.0"
|
|
52
52
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"artifactDownloadUrls": [
|
|
3
|
-
"https://github.com/puniserv/skillcask/releases/download/v0.
|
|
3
|
+
"https://github.com/puniserv/skillcask/releases/download/v0.3.0"
|
|
4
4
|
],
|
|
5
5
|
"bin": {
|
|
6
6
|
"skillcask": "run-skillcask.js"
|
|
@@ -104,7 +104,7 @@
|
|
|
104
104
|
"zipExt": ".tar.xz"
|
|
105
105
|
}
|
|
106
106
|
},
|
|
107
|
-
"version": "0.
|
|
107
|
+
"version": "0.3.0",
|
|
108
108
|
"volta": {
|
|
109
109
|
"node": "18.14.1",
|
|
110
110
|
"npm": "9.5.0"
|