skillcask 0.1.0 → 0.2.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 +150 -14
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -8,31 +8,63 @@ version constraints and commits a lock with content hashes. In CI it does frozen
|
|
|
8
8
|
fail on drift, and it links every skill into each agent's skill directory. It ships as a single
|
|
9
9
|
static binary with no runtime, so it works in a repository in any language.
|
|
10
10
|
|
|
11
|
-
Skills
|
|
12
|
-
GitLab's Composer registry, Satis, Private Packagist or the static repository built by
|
|
13
|
-
`skillcask publish` serve private ones.
|
|
11
|
+
Skills come from Composer repositories or straight from GitHub. Packagist serves public skill
|
|
12
|
+
packages; GitLab's Composer registry, Satis, Private Packagist or the static repository built by
|
|
13
|
+
`skillcask publish` serve private ones. Any GitHub repository with `SKILL.md` files works too,
|
|
14
|
+
which covers most of what [skills.sh](https://skills.sh) lists. skillcask does not need PHP,
|
|
15
|
+
Composer or Node.
|
|
14
16
|
|
|
15
17
|
## Install
|
|
16
18
|
|
|
19
|
+
**macOS, Linux**
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
brew install puniserv/tap/skillcask
|
|
23
|
+
# or, without Homebrew:
|
|
24
|
+
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/puniserv/skillcask/releases/latest/download/skillcask-installer.sh | sh
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Windows (PowerShell)**
|
|
28
|
+
|
|
29
|
+
```powershell
|
|
30
|
+
powershell -ExecutionPolicy Bypass -c "irm https://github.com/puniserv/skillcask/releases/latest/download/skillcask-installer.ps1 | iex"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The two installer scripts download the binary for your platform from the latest release and put
|
|
34
|
+
it in `~/.cargo/bin` (`%USERPROFILE%\.cargo\bin` on Windows).
|
|
35
|
+
|
|
36
|
+
**npm, bun**
|
|
37
|
+
|
|
17
38
|
```sh
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
npx skillcask install --frozen
|
|
21
|
-
|
|
39
|
+
npm install -g skillcask # global
|
|
40
|
+
bun add -g skillcask # global, bun
|
|
41
|
+
npx skillcask install --frozen
|
|
42
|
+
bunx skillcask install --frozen
|
|
22
43
|
```
|
|
23
44
|
|
|
24
45
|
The npm package is a thin wrapper that downloads the release binary for your platform from
|
|
25
|
-
GitHub. It does not check a checksum itself; where that matters,
|
|
26
|
-
and verify it.
|
|
46
|
+
GitHub. It does not check a checksum itself; where that matters, use Homebrew or a release
|
|
47
|
+
archive and verify it.
|
|
48
|
+
|
|
49
|
+
**Cargo**
|
|
50
|
+
|
|
51
|
+
```sh
|
|
52
|
+
cargo install --locked skillcask
|
|
53
|
+
```
|
|
27
54
|
|
|
28
|
-
|
|
55
|
+
**Release archives** for macOS, Linux and Windows are on the
|
|
29
56
|
[releases page](https://github.com/puniserv/skillcask/releases), with sha256 checksums and GitHub
|
|
30
|
-
build provenance attestations
|
|
57
|
+
build provenance attestations:
|
|
58
|
+
|
|
59
|
+
```sh
|
|
60
|
+
gh attestation verify skillcask-x86_64-unknown-linux-gnu.tar.xz -R puniserv/skillcask
|
|
61
|
+
```
|
|
31
62
|
|
|
32
63
|
## Use
|
|
33
64
|
|
|
34
65
|
```sh
|
|
35
66
|
skillcask add netresearch/agent-jira-skill # resolve, write skills.toml + skills.lock, install
|
|
67
|
+
skillcask add github:mattpocock/skills/tdd # one skill from a GitHub repository
|
|
36
68
|
skillcask install --frozen # CI: install exactly the lock or exit non-zero
|
|
37
69
|
skillcask status # manifest vs lock vs installed files
|
|
38
70
|
```
|
|
@@ -43,6 +75,7 @@ skillcask status # manifest vs lock vs installed fil
|
|
|
43
75
|
skills.toml # manifest, commit it
|
|
44
76
|
skills.lock # lock, commit it
|
|
45
77
|
.agents/skills/<name>/ # installed skill (gitignored)
|
|
78
|
+
.agents/skills/.skillcask-installed # what this machine installed (gitignored)
|
|
46
79
|
.claude/skills/<name> -> ../../.agents/skills/<name>
|
|
47
80
|
.junie/skills/<name> -> ../../.agents/skills/<name>
|
|
48
81
|
.gitignore # managed block
|
|
@@ -52,7 +85,9 @@ Project skills live in `.skills/<name>/SKILL.md` (`[agents] local`). skillcask l
|
|
|
52
85
|
into the store (`.agents/skills/<name> -> ../../.skills/<name>`) and from there into every agent
|
|
53
86
|
directory. These links are committed, so they work in every clone. A directory written by hand
|
|
54
87
|
straight into `.agents/skills/` is linked the same way. A project skill with the same name as a
|
|
55
|
-
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.
|
|
56
91
|
|
|
57
92
|
### skills.toml
|
|
58
93
|
|
|
@@ -65,6 +100,8 @@ acme = { type = "composer", url = "https://git.example.com/api/v4/group/42/-/pac
|
|
|
65
100
|
"netresearch/agent-jira-skill" = "^3.34"
|
|
66
101
|
"acme/agents-md" = { version = "^1.0", repository = "acme" }
|
|
67
102
|
"acme/review" = { version = "1.4.2", repository = "acme", skills = ["review"] }
|
|
103
|
+
"mattpocock/skills" = { github = true, version = "^1.3", skills = ["tdd", "code-review"], rename = { code-review = "mp-code-review" } }
|
|
104
|
+
"anthropics/skills" = { github = true, skills = ["pdf"] } # default branch
|
|
68
105
|
|
|
69
106
|
[agents]
|
|
70
107
|
targets = [".claude/skills", ".junie/skills"]
|
|
@@ -80,12 +117,48 @@ Constraints follow Composer semantics: `^0.3` means `>=0.3.0 <0.4.0`, `~1.2` mea
|
|
|
80
117
|
`>=1.2 <2.0`, and pre-releases are only selected when the constraint names a stability
|
|
81
118
|
(`^1.0@beta`).
|
|
82
119
|
|
|
120
|
+
### Name conflicts
|
|
121
|
+
|
|
122
|
+
Skills have no namespaces: an agent knows a skill by its name. Two skills with the same name in
|
|
123
|
+
one project are an error. Install one of them under another name with `rename`:
|
|
124
|
+
|
|
125
|
+
```toml
|
|
126
|
+
"mattpocock/skills" = { github = true, rename = { code-review = "mp-code-review" } }
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
skillcask then installs `.agents/skills/mp-code-review` and changes the `name:` line in its
|
|
130
|
+
`SKILL.md`; the lock records the original name and the hash of the renamed copy. Nothing else in
|
|
131
|
+
the skill changes, so text that mentions the old name (`/code-review`) stays as it is.
|
|
132
|
+
`add`, `install` and `update` offer the rename when they hit a conflict in a terminal.
|
|
133
|
+
|
|
134
|
+
### Personal skills (`--global`)
|
|
135
|
+
|
|
136
|
+
`skillcask --global` (`-g`) manages skills for your user instead of a project, with the same
|
|
137
|
+
manifest, lock and verification:
|
|
138
|
+
|
|
139
|
+
```sh
|
|
140
|
+
skillcask -g add github:mattpocock/skills/grill-me
|
|
141
|
+
skillcask -g install --frozen # e.g. from a dotfiles repository
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
- `skills.toml`, `skills.lock` and an optional `auth.json` live in `~/.config/skillcask`
|
|
145
|
+
(`$XDG_CONFIG_HOME/skillcask`; `SKILLCASK_HOME` overrides both). Keep them in your dotfiles.
|
|
146
|
+
- Skills go to `~/.agents/skills` (read by Codex), with links in `~/.claude/skills` and
|
|
147
|
+
`~/.junie/skills` (`[agents] targets`, relative to home). Links are absolute, so a symlinked
|
|
148
|
+
`~/.claude` works. `[agents] local` does not apply.
|
|
149
|
+
- Personal skills you wrote by hand stay where they are and are not linked anywhere.
|
|
150
|
+
- The list of managed paths is `~/.agents/skills/.skillcask-installed`, local to the machine;
|
|
151
|
+
nothing touches git.
|
|
152
|
+
|
|
83
153
|
### Commands
|
|
84
154
|
|
|
155
|
+
Every command except `publish` takes `-g, --global`.
|
|
156
|
+
|
|
85
157
|
| Command | |
|
|
86
158
|
|---|---|
|
|
87
159
|
| `init` | Create `skills.toml`. |
|
|
88
160
|
| `add <vendor/name>[@constraint] [--repository r]` | Resolve, lock and install. |
|
|
161
|
+
| `add github:<owner/repo>[/skill][@version-or-ref]` | The same from a GitHub repository, see below. |
|
|
89
162
|
| `remove <vendor/name>…` | Drop from manifest and lock; delete files, links and gitignore lines. |
|
|
90
163
|
| `install [--frozen]` | Install the lock. `--frozen` (implied by `CI`) fails when the lock is out of date. |
|
|
91
164
|
| `update [vendor/name…]` | Re-resolve within constraints. |
|
|
@@ -93,12 +166,55 @@ Constraints follow Composer semantics: `^0.3` means `>=0.3.0 <0.4.0`, `~1.2` mea
|
|
|
93
166
|
| `status` | Exit 1 when manifest, lock or installed files disagree. |
|
|
94
167
|
| `doctor [--fix]` | Broken or committed links, stale gitignore block, modified skills. |
|
|
95
168
|
| `search <query>` | Packagist (`type=ai-agent-skill`) and listed private packages. |
|
|
96
|
-
| `publish --vendor v --base-url URL --out DIR [paths…]` | Build a static Composer repository from a monorepo. |
|
|
169
|
+
| `publish --vendor v --base-url URL --out DIR [--inline] [--dist-url TPL] [paths…]` | Build a static Composer repository from a monorepo. |
|
|
97
170
|
| `<other>` | Runs `skillcask-<other>` from `PATH`, like git and cargo plugins. |
|
|
98
171
|
|
|
99
172
|
Exit codes: 0 ok, 1 manifest/lock/status problems, 2 authentication, 3 network, 4 hash mismatch,
|
|
100
173
|
5 IO or archive error.
|
|
101
174
|
|
|
175
|
+
### Skills from GitHub and skills.sh
|
|
176
|
+
|
|
177
|
+
[skills.sh](https://skills.sh) lists skills as `owner/repo/skill`, for example
|
|
178
|
+
`mattpocock/skills/grill-me`. Put `github:` in front and add it:
|
|
179
|
+
|
|
180
|
+
```sh
|
|
181
|
+
skillcask add github:mattpocock/skills/grill-me # one skill
|
|
182
|
+
skillcask add github:mattpocock/skills/tdd # a second one from the same repository
|
|
183
|
+
skillcask add github:anthropics/skills # every skill in the repository
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
All skills of one repository share one entry in `skills.toml`:
|
|
187
|
+
|
|
188
|
+
```toml
|
|
189
|
+
"mattpocock/skills" = { github = true, version = "^1.3", skills = ["grill-me", "tdd"] }
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Which version you get:
|
|
193
|
+
|
|
194
|
+
- **Repository with version tags** (`v1.3.1`): `add` writes `version = "^<major.minor>"`, like
|
|
195
|
+
for Composer packages, and `update` moves within it. The release time of a tag is its commit
|
|
196
|
+
date.
|
|
197
|
+
- **Repository without tags**: the entry follows the default branch; `ref = "main"` names a
|
|
198
|
+
branch, tag or commit instead. The lock pins the commit sha, so `install` keeps installing that
|
|
199
|
+
commit until you run `update`.
|
|
200
|
+
- `@` picks explicitly: `github:owner/repo@^2.0` (version tags), `github:owner/repo@main` or
|
|
201
|
+
`@<commit sha>` (ref).
|
|
202
|
+
- With `policy.allow-ranges = false` a branch counts as a range: `add` writes the full commit sha
|
|
203
|
+
as `ref`, and a hand-written branch name is rejected.
|
|
204
|
+
|
|
205
|
+
Skills are found by their `SKILL.md` anywhere in the repository, except inside another skill.
|
|
206
|
+
The install name is the frontmatter `name`; when that is not a valid name (`Jira Automation`), the
|
|
207
|
+
directory name is used. `skills = [...]` takes these names.
|
|
208
|
+
|
|
209
|
+
GitHub allows 60 anonymous API requests per hour. `add`, `update` and `outdated` use a few per
|
|
210
|
+
entry; `install` from the lock uses none, it downloads the pinned archive. Set `GITHUB_TOKEN`
|
|
211
|
+
(GitHub Actions has one) or Composer's `"github-oauth": {"github.com": "<token>"}` in `auth.json`
|
|
212
|
+
for a higher limit and for private repositories. `SKILLCASK_GITHUB_API` points at GitHub
|
|
213
|
+
Enterprise (`https://ghe.example.com/api/v3`).
|
|
214
|
+
|
|
215
|
+
skills.sh itself is not queried: its API needs a Vercel token. Search on the website, then add
|
|
216
|
+
what you picked.
|
|
217
|
+
|
|
102
218
|
## Security
|
|
103
219
|
|
|
104
220
|
- The lock pins the version, the commit reference, the sha256 of the downloaded archive and
|
|
@@ -109,7 +225,13 @@ Exit codes: 0 ok, 1 manifest/lock/status problems, 2 authentication, 3 network,
|
|
|
109
225
|
- Archives with absolute paths, `..`, devices or symlinks that leave their skill are rejected.
|
|
110
226
|
No symlink is ever written from a package. Size and file count are capped (`--max-download`,
|
|
111
227
|
`--max-unpacked`, `--max-files`).
|
|
228
|
+
- File names must be valid on every OS: Windows-reserved names, `<>:"|?*\`, control characters
|
|
229
|
+
and paths that collide by case or Unicode form fail a skill that contains them, and are
|
|
230
|
+
skipped outside the selected skills.
|
|
112
231
|
- No package code runs, ever. No telemetry.
|
|
232
|
+
- `min-release-age` for GitHub sources reads commit dates, which the committer sets. A
|
|
233
|
+
backdated commit passes the cooldown; reviewing what `add`/`update` change in `skills.lock` is
|
|
234
|
+
the real check there.
|
|
113
235
|
- Credentials come from Composer's `auth.json` / `COMPOSER_AUTH` (`http-basic`, `bearer`,
|
|
114
236
|
`gitlab-token`, `gitlab-oauth`) and are never printed. In GitLab CI use `http-basic` with the
|
|
115
237
|
user `gitlab-ci-token` and the password `$CI_JOB_TOKEN`.
|
|
@@ -130,9 +252,23 @@ This writes `packages.json`, `p2/acme/<name>.json` and deterministic zips under
|
|
|
130
252
|
versions are immutable, and re-running on unchanged skills changes no file. Serve the directory
|
|
131
253
|
over HTTPS.
|
|
132
254
|
|
|
255
|
+
Hosts that cannot serve `/` inside file names (GitLab's Generic Package Registry) take a single
|
|
256
|
+
file instead:
|
|
257
|
+
|
|
258
|
+
```sh
|
|
259
|
+
skillcask publish --inline --vendor acme --out composer/ skills/ \
|
|
260
|
+
--dist-url 'https://git.example.com/api/v4/projects/7/packages/generic/{vendor}-{name}/{version}/{name}-{version}.zip'
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
`--inline` puts every package into `packages.json` and writes no `p2/`. Upload each
|
|
264
|
+
`dist/<vendor>/<name>/<version>.zip` to the URL the template gives, and commit `packages.json` to
|
|
265
|
+
a repository. A repository `url` with a query string is used as given, so clients can read the
|
|
266
|
+
file through the GitLab raw files API
|
|
267
|
+
(`.../repository/files/composer%2Fpackages.json/raw?ref=main`) with a `gitlab-token`.
|
|
268
|
+
|
|
133
269
|
## Design
|
|
134
270
|
|
|
135
|
-
See [docs/
|
|
271
|
+
See [docs/specs/2026-10-19-skillcask-v1.md](docs/specs/2026-10-19-skillcask-v1.md).
|
|
136
272
|
|
|
137
273
|
## License
|
|
138
274
|
|
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.2.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.2.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.2.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.2.0",
|
|
108
108
|
"volta": {
|
|
109
109
|
"node": "18.14.1",
|
|
110
110
|
"npm": "9.5.0"
|