A Shelf for My Agent Skills
One canonical library, skills toggled on or off per coding agent, and updates that never clobber the ones I'm still writing.

Every coding agent I use keeps its skills in a different place: Claude Code reads ~/.claude/skills, Codex reads ~/.codex/skills, and Cursor has its own folder, on top of the per-project .claude directories and a few more stashed in an Obsidian vault. Before long the copies drift apart, and I end up rewriting skills I already wrote or forgetting which ones even exist.
Dumping everything into a single shared folder and pointing every agent at it is the obvious fix, but it trades one problem for a worse one. Every session then 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 built skillshelf, a package manager for agent skills that keeps one canonical library on disk and loads skills on demand rather than all at once.
One library, nothing auto-loads
The library is a plain git repo holding a single copy of each skill. Nothing in it loads automatically, so the token cost stays near zero until I actually ask for something. From the command line I can search the shelf, read any skill's instructions, and bundle skills by domain tag; a skill tagged both coding and bioinfo shows up in both bundles from that single copy on disk.

Toggle per agent, not per copy
I wanted a visual interface for the daily toggle work. Each skill has a row of switches, one for Claude, Codex, and each of my other agents, and turning one on symlinks the skill into that agent's directory. A scope switcher at the top lets me apply changes globally or just to the project I am in, so a one-off project loadout never leaks into everything else.
Rather than storing its own state, the app reads directly from the filesystem every time. The UI shows what is actually deployed on disk, so it never reports a skill as active when a symlink is broken or a stray copy has drifted. When something is out of sync, it surfaces a step to resolve the conflict instead of pretending everything is fine.
Selective updates that never clobber my own work
I could almost have lived with a folder of manual symlinks, except that I am always writing new skills and never want an update to overwrite one I am in the middle of editing.
To prevent that, skillshelf distinguishes between copied skills and linked ones. For skills I downloaded and want to pin, the library stores a real copy. For the skills I actively develop myself, I shelve a link to the skill's own git repo instead. That development repo stays canonical, my edits show up live, and update and outdated skip linked entries entirely so they never reach back into my working repo. For the copied skills, an update re-pulls only the upstream instruction body and leaves my tags and notes alone in their separate file, swapping in the new version cleanly without touching anything I added.

How it fits with Vercel's skills CLI
vercel-labs/skills is a good tool that solves the other half of this problem. Vercel's skills CLI 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 for managing 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.
Because both tools speak the same SKILL.md format, they work together cleanly. I can vendor something out of Vercel's ecosystem into my library, then bundle and load it like everything else: Vercel's tool is how a skill reaches me, and skillshelf is how I keep a hundred of them organized.
Where to find it
skillshelf is a Bun CLI (skl) with a Tauri desktop app built 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.
给智能体的技能,做了个货架
一个统一的规范库,技能按编码智能体逐个开关,更新时绝不覆盖我还在写的那些。

我常用的每个编码智能体,存放技能的地方都不一样:Claude Code 读 ~/.claude/skills,Codex 读 ~/.codex/skills,Cursor 有自己的一套,此外还有各个项目里的 .claude 目录,外加几个塞在 Obsidian 笔记库里的。时间一长,不同地方的副本各自漂移,我会重写早就写过的技能,也会忘了哪些已经存在。
最直接的办法是把所有技能倒进同一个文件夹,让每个智能体都指向那里。但这只是拿一个问题换来一个更糟的问题:每次开启会话都要一口气加载几百条技能描述,不管这一轮用不用得上,每一轮都得为它们付出 token 成本。
于是我做了 skillshelf,思路是给智能体技能做一个包管理器:磁盘上只维护一个统一的规范库,按需加载,绝不一次性全装。
一个库,什么都不自动加载
整个库就是一个普通的 git 仓库,每个技能在里面只存一份副本。这个货架是被动的,里面没有任何东西会自动加载,所以在我真正开口要某样东西之前,token 成本几乎为零。平时我可以在命令行里检索技能、读取任意技能的说明,或者按领域标签把技能打成包;比如一个同时标了 coding 和 bioinfo 的技能,靠磁盘上的同一份副本就能出现在两个包里。

按智能体切换,而不是按副本
为了方便日常开关,我给它做了一个图形界面。每个技能旁边都有一排对应 Claude、Codex 等智能体的开关,打开其中一个,就会把这个技能软链接进对应智能体的目录。顶部有一个作用域切换器,既可以全局生效,也可以只作用于当前项目,这样一次性的项目配置就不会泄漏到其他地方。
应用本身不存储状态,每次都直接从文件系统读取。界面上显示的就是磁盘上的真实部署情况,不会在软链接已经失效、或者某个野副本已经漂移时,还显示这个技能处于开启状态。遇到状态不一致时,它会直接给出解决冲突的步骤,而不是假装一切正常。
有选择的更新,绝不动我自己在写的东西
如果只是静态管理,用一个文件夹的软链接也能凑合;但我一直在写新技能,不想让任何一次更新覆盖掉我正写到一半的那个。
为此,skillshelf 把库里的条目分成两类。对于我下载下来、想要固定版本的技能,库里会保存一份真正的副本;而对于我正在开发的技能,货架上只放一个指向它自身 git 仓库的链接。这样一来,开发仓库始终是唯一的数据源,我的修改实时生效,同时 update 和 outdated 命令会完全跳过这类链接条目,绝不会反过来动我的工作仓库。至于保存了副本的技能,更新时只重新拉取上游的正文说明,不动我加在独立文件里的标签和笔记,干净地完成替换。

和 Vercel skills CLI 的关系
vercel-labs/skills 是个好工具,解决的是问题的另一半。Vercel 的 skills 是一个分发器:把它指向某个仓库或 skills.sh 注册表,它就能一步把技能拉取下来并安装进你的智能体里,装好即加载。skillshelf 则负责管理我已经有的那些技能,它们大多散落在本地各个目录里,从没发布到任何地方。它只维护一个被动的货架,把“拥有一个技能”和“加载它”分开,并按标签把技能按需拉进某个项目,让每次会话都不必一次性加载整个集合。
因为两个工具都使用同一种 SKILL.md 格式,配合起来很自然。我可以把 Vercel 生态里的技能收进自己的库里,再像对待其他技能一样给它打包和加载:一个解决技能怎么到我手里,另一个解决我怎么把上百个技能管得井井有条。
在哪里找到它
skillshelf 是一个基于 Bun 的命令行工具(skl),上面配了一个共用同一套引擎的 Tauri 桌面应用。应用读取的是真实的库,每次切换开关写入的也是命令行写的那些软链接,所以两边从不打架。代码已经开源。