@daoyeet/librarian
v0.1.1
Published
A skill manager for AI agents — the shelving system and the librarian, not the books. (beta)
Readme
Librarian
A skill manager for AI agents — the shelving system and the librarian, not the books.
Agent skills now come from everywhere — marketplace plugins, npx skills
libraries, git repos, self-managed CLIs — and a model can't sensibly pick from
500+, the context window bloats, and your devices drift out of sync.
Librarian is the manager for that mess: it classifies, places, serves, and
syncs whatever you already have, from one config file that travels — and it
ships no third-party skill content of its own. Point it at your stack; it
does the shelving.
🚧 Beta
Public beta (
v0.1.0). The 8 verbs and the data formats below are what ships and are exercised bytest/smoke.mjs. Expect rough edges on non–Claude-Code harnesses (Codex/Cursor skill install is best-effort and flagged provisional). Feedback and issues welcome.
Known limitations (beta)
- Cross-harness drift/sync is Claude-Code-accurate today; Codex/Cursor are
provisional. The index scanner reads Claude Code's
~/.claude/skills(+ plugins), so drift checks,sync, and map-seeding are exact there. Codex (.codex/skills) and Cursor (.cursor/rules/*.mdc) skill install is best-effort and flagged provisional — those installs aren't scanned yet, soinitskips seeding them and their drift status isn't authoritative. healthreads your committed index;syncrebuilds it live. Right after installing skills, runlibrarian syncbefore trustinghealth—healthis a cheap read of the last index,syncrebuilds from the harness.
Try it in 30 seconds
See the whole flow work — offline, in one command, against a throwaway HOME so
your real ~/.claude is never touched:
node sandbox.mjs # or: npm run sandboxIt builds a tiny fake stack, then runs init → browse → find → place →
sync --dry → health and prints each labeled step. No installs, no network, all
in a temp dir it cleans up. That's Librarian's whole loop in one screen.
The magic moment
New device → librarian init → an organized, navigable library with a working
table + backpack, and zero manual curation.
One command detects your harness, installs Librarian's own interaction skills,
infers your starter libraries from the stack already present (a ~/.claude
with ECC installed → ECC is enabled — it looks, it doesn't ask), sets a sensible
always-on table + per-profile backpack, and explains what it did. From then on
your agent can browse / find / place / use skills, and librarian sync
keeps every device identical. Falling behind is noticed and offered a fix,
never silently applied.
librarian init
harness: claude-code
skills: installed 7 Librarian skill(s) into claude-code (~/.claude/skills)
libraries (inferred from your stack): ecc, ponytail
- ecc: plugin:ecc → the giant general library — language reviewers/builders, framework patterns, agent-engineering, ops, and vertical domains
- ponytail: skill:ponytail → laziness/YAGNI discipline + over-engineering audit/debt/review
table (always-on): skill-router, operating-modes
backpack (carried): ponytail, caveman [per-profile matrix set for 5 profiles]
map: seeded 7 Librarian skill(s) as classified (shelf) → ./skill-map.json
wrote ./librarian.config.json
next: librarian browse · librarian find "which skill for X?" · librarian syncQuickstart
npx librarian initNot published to npm yet. Until it is, run it from a clone:
git clone https://github.com/DaoYeeT/dyt-librarian && cd dyt-librarian node bin/librarian init # same as `librarian init` / `npx librarian init`
init writes librarian.config.json to the current directory — commit that
file. It is the whole travelling state. On any other machine, clone your config
and run librarian sync.
Node ≥ 18. No dependencies (Node built-ins only).
The eight verbs
librarian <verb> [options]| Verb | What it does |
|---|---|
| init | detect harness, install the Librarian skill, infer starter libraries, set table/backpack |
| browse | view the catalog by profile / pack / placement (no filter → the provider collections view) |
| find | "which skill for X?" — deterministic best-fit skill(s) with pack + placement (never a guess) |
| place | set a skill's placement (shelf/table/backpack) + per-profile backpack toggles |
| use | resolve what a shelf skill would load, or what a profile's table+backpack posture would inject |
| health | drift check + provider reachability, each non-green state with its fix command |
| sync | update enabled libraries, rebuild the index, re-render views, drift-check, append the changelog |
| intake | install + record a new library, rebuild the index, then offer the one classify step |
Run librarian with no verb for the usage list.
The placement model — shelf / table / backpack
Every managed skill carries a placement. This is what kills context bloat and what survives model/harness swaps:
- 🗄️ shelf — installed, surfaced as a one-liner in the index, loaded only when the agent commits to it. The default and the long tail. Shelf is why a 600-skill library doesn't drown the context window.
- 🪑 table — always loaded. A deliberately small always-on core (e.g.
skill-router,operating-modes). - 🎒 backpack — a posture injected per profile (e.g.
ponytailon forbuild, off fordesign). The model never has to find it, so it carries across a model or harness swap. Backpack items also carry a per-profile toggle matrix (which profile runs the posture at which level).
Placement lives as a field on each map entry. Move a skill with
librarian place <skill> <shelf|table|backpack>; the generated views re-render
off the map.
The providers model — pointers, never vendored
A library is a source of skills. providers.json models four source types:
| Type | Install | Update |
|---|---|---|
| marketplace | claude plugin install <p>@<mp> | claude plugin update --all |
| npx (skills CLI) | npx skills add <src> -g -y | npx skills update -g -y |
| git | clone a repo of skills | git pull |
| self (self-managed) | the tool's own installer | the tool's own upgrade |
Each provider entry holds a pointer (source repo + channel) plus covers /
reach navigation copy — never the skills' content. Adding a library is one
entry in providers.json plus enabling it in librarian.config.json. Sync runs
the typed install/update commands (deduped — every marketplace provider shares one
claude plugin update --all); --dry prints every command and shells out for
none.
No vendored skills — a hard constraint
The only skills in this repo are Librarian's own seven interaction skills under
skills/librarian/. There is no third-party skill content anywhere in the
package — providers hold pointers, the map holds classifications, and the skills
themselves are fetched from their real sources on your machine. This is the whole
point of "manager, not library": Librarian is the shelving system, your providers
are the books, and the two never get vendored together.
How the pieces fit
librarian.config.json— the travelling state: enabled libraries + placement prefs + harness. Commit it.skill-map.json— the classification data (profile / tier / pack / placement / useful_for per skill). Generated at your site, not shipped; travels alongside the config.providers.json— the provider registry (pointers + navigation copy).profiles/profiles.json— workflow profiles: model + sets + the backpack default matrix.
Everything downstream (per-profile rosters, the provider collections view, the graphify extraction) is generated from the map — edit the map and re-render, never the generated files.
Learn more
sandbox.mjs— the one-command offline demo (node sandbox.mjs); the fastest way to see the loop.examples/README.md— a hands-on, copy-pasteableinit → browse → find → place → syncwalkthrough over the test fixtures (temp HOME forinit,--dryforsync— nothing real installs).SPEC.md— the formal schemas for the four data files (librarian.config.json,skill-map.json,providers.json,profiles.json), matched to the shipped code.
License
MIT © 2026 Dao (DaoYeeT). See LICENSE.
