cankun.me

A Shelf for My Agent Skills

Jun 24, 2026
A long shelf holds many dormant blank volumes while a selector lamp activates only a chosen few
A long shelf holds many dormant blank volumes while a selector lamp activates only a chosen few · View full resolution

Every coding agent I use keeps its skills in a different drawer. Claude Code reads ~/.claude/skills. Codex reads ~/.codex/skills. Cursor has its own. Then there are the per-project .claude dirs, and a few more stashed in an Obsidian vault. The copies drift. I rewrite skills I already wrote. I forget which ones even exist.

The obvious fix is to dump everything into one folder and point every agent at it. That trades one problem for a worse one: now every session loads hundreds of skill descriptions at once, and you pay for all of them on every turn, whether you use them or not.

So I made myself a tool. It is called skillshelf, and the idea is a package manager for agent skills: one canonical library, loaded on demand, never all at once.

One library, nothing auto-loads

There is exactly one copy of each skill, in a plain git repo. The library is a passive shelf. Nothing in it loads itself. I can search it, read any skill's instructions from the command line, and bundle skills by domain tag. A skill tagged both coding and bioinfo shows up in both bundles from a single copy on disk. The token cost stays near zero until I actually ask for something.

skillshelf library view: a scrollable list of skills, each with per-agent deployment toggles, a domain sidebar, and a scope switcher across the top
The library view. Every skill in one place; flip each one on or off per agent without leaving the list.

Toggle per agent, not per copy

This is the part I wanted a real interface for. Each skill has a row of toggles, one per agent: Claude, Codex, and the rest. Turning one on symlinks the skill into that agent's directory. A scope switcher at the top lets me do this globally or for just the project I'm in, so a one-off project loadout never leaks into everything else.

The state is read from the filesystem every time, never stored. The UI shows what is actually deployed, so it cannot quietly tell me a skill is on when the link is broken or a stray copy has drifted. When something is wrong it surfaces a resolve step instead of pretending.

Selective updates that never clobber my own work

Here is the reason I built this instead of living with a folder of symlinks: I am always writing new skills, and I did not want an update to ever overwrite one I am in the middle of.

So a library entry is one of two kinds. Either it owns its bytes, a real copy, good for things I downloaded and want to pin, or it is linked to its own git repo. For the skills I actively develop, I shelve a link. The dev repo stays canonical, my edits show up live, and update and outdated skip linked entries entirely. They never reach back into my working repo. For the owned ones, an update re-pulls only the instruction body and leaves my tags and notes alone, since those live in a separate file. The upstream swaps in cleanly without touching anything I added.

skillshelf detail drawer: the rendered SKILL.md body on the left, with provenance, an agent-by-scope deployment matrix, tags, and lifecycle actions on the right
The detail drawer: the skill's body, where it came from, its tags, and an agent-by-scope deployment matrix.

Why not just use Vercel's skills CLI?

Fair question. vercel-labs/skills is a good tool, and it solves the other half of the problem. Vercel's skills is a distributor: point it at a repo or the skills.sh registry and it fetches a skill and installs it into your agents in one step, where installed means present and loading. skillshelf is the librarian for the skills I already have, most of them scattered across local dirs and never published anywhere. It keeps one passive shelf, separates owning a skill from loading it, and pulls skills into a project on demand by tag, so no session pays to load the whole collection at once.

They compose, not compete. Both speak the same SKILL.md, so I can vendor something out of Vercel's ecosystem into my library, then bundle and load it like everything else. One is how a skill reaches me; the other is how I keep a hundred of them straight.

Where it is

skillshelf is a Bun CLI (skl) with a Tauri desktop app on top of the same engine. The app reads the real library, and every toggle writes the same symlinks the CLI does, so the two never disagree. It is open source.

← Back to Writing