docs+ci: document the plugin path, bump plugin.json version on release
release / tag (push) Successful in 1s

CI now writes the computed semver into .claude-plugin/plugin.json before
tagging, committed with [skip-release] so it does not re-trigger the tagger.
Claude Code gates plugin updates on that field: without the bump, installed
hosts never see a new tag no matter how many releases go out. `task check`
enforces manifest/tag equality so the two cannot silently diverge.

Docs rewritten around the two delivery paths, and the checkout location is now
stated as load-bearing rather than incidental: SKILLS_CHECKOUT_DIR defaults to
~/.local/share/skills because that is host-local and outside any synced
directory. The previous docs told you to clone into ~/dev, which on this fleet
is an iCloud folder shared by two Macs spanning two path roots — a git working
tree with concurrent writers, and absolute links that are broken on one side by
construction. That advice is what #23 is about; it is now inverted with the
reason attached.

Antigravity and Vibe removed from the docs along with their targets.

Bump-Type: patch

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BeAp5LTscnz2W7Ubt4eJ6m
This commit is contained in:
2026-08-23 14:35:38 +02:00
co-authored by Claude Opus 5
parent 88c54399fe
commit 78b9b59eca
3 changed files with 117 additions and 56 deletions
+53 -41
View File
@@ -1,8 +1,12 @@
# skills
Engineering skills library — markdown `SKILL.md` files that plug into any
project or AI-coding harness. Installed via `task skills:install` in
consumer projects, or directly by `install.sh` on hosts without Task.
AI-coding harness.
For **Claude Code** this repo is a plugin, installed from the marketplace it
also hosts; that path carries the hooks and MCP servers too. For **Crush, Pi
and OpenCode** it is a plain library wired by `install.sh` as one directory
symlink per harness. See [`SKILLS_INDEX.md`](./SKILLS_INDEX.md#wiring-into-tools).
## What is a skill?
@@ -16,65 +20,73 @@ references.
See [`SKILLS_INDEX.md`](./SKILLS_INDEX.md) for the full catalogue with
descriptions and "use when" triggers.
## Install (consumer project)
## Install
The expected pattern: each consumer project's `Taskfile.yml` has a
`skills:install` target that delegates here. From a project root:
### Claude Code — the plugin
```bash
task skills:install
```
/plugin marketplace add https://git.d-ma.be/mathias/skills.git
/plugin install skills@mathias
```
Bare-shell fallback for hosts without Task installed:
The plugin ships skills, the `secret-guard` + `pre-task-ritual` hooks, and the
brain/gitea/infra MCP servers as one versioned unit. Skills are namespaced
(`skills:tdd`). Updates land when `.claude-plugin/plugin.json`'s `version`
moves — CI bumps it on every release.
### Crush, Pi, OpenCode — `install.sh`
```bash
curl -fsSL https://gitea.d-ma.be/mathias/skills/raw/branch/main/install.sh | bash
curl -fsSL https://git.d-ma.be/mathias/skills/raw/branch/main/install.sh | bash
```
Both forms are idempotent and re-runnable. On every run they:
Idempotent. It clones or fast-forwards the checkout, then creates **three**
symlinks — one directory link per harness, never one per skill:
1. `git clone` (or `git pull`) this repo into `~/.local/share/skills/` —
the **canonical local checkout** on every host.
2. Wire per-skill symlinks into the harnesses found on the host (see
[Wired harnesses](#wired-harnesses)).
| Link | Target |
|---|---|
| `~/.agents/skills` | `$SKILLS_CHECKOUT_DIR/skills` (Pi reads this path directly) |
| `~/.config/crush/skills` | `~/.agents/skills` |
| `~/.config/opencode/skills` | `~/.agents/skills` |
Re-run after `git pull` upstream to pick up new skills or version
changes. CI tags every change as a `vX.Y.Z` release (see
[Versioning](#versioning)).
Adding a skill wires it everywhere with no re-run.
## Wired harnesses
### Where the checkout must live
| Harness | Target path | Notes |
|---|---|---|
| **Claude Code (global)** | `~/.claude/skills/<name>` | Visible in every Claude Code session on the host. |
| **Claude Code (per-repo)** | `<repo>/.claude/skills/<name>` | Created when `install` is invoked inside a git repo (not the skills repo itself). Gitignored globally via `**/.claude/skills/`. |
| **Crush** | `~/.config/crush/skills/<name>` | Charmbracelet Crush — successor to `opencode-ai/opencode` (archived). |
| **Antigravity** | `~/.gemini/antigravity/skills/<name>` | Google Antigravity (VS Code extension). Our `SKILL.md` frontmatter (`name` + `description`) is already in the format Antigravity expects, so symlinks suffice — no manifest translation. |
`SKILLS_CHECKOUT_DIR` defaults to `~/.local/share/skills`, and that default is
load-bearing: it is **host-local, outside any synced or shared directory**.
### Not wired (and why)
- **opencode** (`opencode-ai/opencode`): archive notice; succeeded by Crush.
Its only "skill"-like surface — Custom Commands at `~/.config/opencode/commands/` —
is for user-facing prompt templates, not system-level instructions.
Misaligned with how we use skills. Skipped.
- **gitea-resident agents** (cobalt-dingo, agentsquad): they consume
skills via their containing project's `.claude/skills` directory
(populated by the per-repo wirer when run from the host), or via the
brain MCP. No special target needed.
On this fleet `~/dev` is an iCloud folder shared by flamingo and iguana, and it
spans two path roots — `/Users/mathias` on the Macs, `/home/mathias` on koala.
A checkout there is a git working tree with two concurrent writers, and any
absolute symlink stored there is broken on one side by construction. That is
what produced 243 dangling links across 12 repos (#23). Do not "fix" the
default to point into `~/dev`.
### Per-host env-var overrides
Each target path can be overridden by setting the matching env var before
running `install.sh`:
| Env var | Default |
|---|---|
| `SKILLS_REPO_URL` | `https://gitea.d-ma.be/mathias/skills.git` |
| `SKILLS_REF` | `main` (set to e.g. `v0.1.0` to pin a release) |
| `SKILLS_REPO_URL` | `https://git.d-ma.be/mathias/skills.git` |
| `SKILLS_REF` | `main` (set to e.g. `v0.4.0` to pin a release) |
| `SKILLS_CHECKOUT_DIR` | `$HOME/.local/share/skills` |
| `CLAUDE_SKILLS_DIR` | `$HOME/.claude/skills` |
| `SKILLS_SKIP_FETCH` | unset (`1` wires an existing checkout without touching HEAD) |
| `AGENTS_SKILLS_DIR` | `$HOME/.agents/skills` |
| `CRUSH_SKILLS_DIR` | `$HOME/.config/crush/skills` |
| `ANTIGRAVITY_SKILLS_DIR` | `$HOME/.gemini/antigravity/skills` |
| `OPENCODE_SKILLS_DIR` | `$HOME/.config/opencode/skills` |
Antigravity and Mistral Vibe targets were removed — unused.
## Checking a host
```bash
task doctor # or bin/doctor
```
Reports dangling links, links resolving into a foreign checkout, skill-count
mismatches, stray entries, and leftover per-skill Claude symlinks. Non-zero
exit on drift. It also runs at session start via the plugin, so a drifting
host says so rather than waiting to be discovered.
## Versioning