ainb Skill Manager

The Skill Manager — guide

One screen to keep the skills, agents, commands and plugins for all your AI coding tools — Claude Code, Codex, Cursor, Copilot, Gemini — in sync. Install from a repo or the catalog, adopt what's already on your machine, keep your own skills in a library, and push your edits back upstream — across every tool at once.

1Getting in & what you see

Run ainb, then press m (or pick Skills (manager) in the sidebar). You get three panes:

Sources

Where your skills come from — repos you added, the catalog, your own machine.

Units

The actual skills / agents / commands / plugins, each with a status glyph on the right.

Detail

Info on the selected unit — its URI, where it deployed, how often you've used it.

2The keys, in plain words

PressWhat it does
mOpen the Skill Manager (from home) · press again to re-scan for new skills
iAdd a source — paste a repo like gh:owner/repo
bBrowse the catalog — search for new skills online, Enter to install
lYour library — skills you wrote yourself
uUpdate the selected skill to latest
cCheck which skills are behind upstream
rRemove the selected skill
sSync — push your local edits back upstream
/Search / filter the list
↑↓ j kMove the cursor · g/G first/last
q EscLeave

3The status glyphs

up to date
behind — press u
you're ahead
diverged
checking

4The things you'll actually do

Each one recorded — what you press, what you see. (CLI equivalent under each.)

① Adopt what's already installed

Press m → the discovery banner appears → press Enter. You see: Sources + Units fill with the skills & plugins you already had.
discover and import
CLI: ainb migrate --discover

② Find & install a new skill

Press b → type a query → Enter to search → Enter to install the pick. You see: catalog results, then the skill installs into your tools.
browse and install
CLI: ainb skill browse <query>ainb skill install <uri>

③ Keep your own skills

Press l. You see: your hand-written skills in one Library view.
own library
CLI: ainb skill library new <name> · ainb skill library list

④ Push an edit back upstream

Edit a deployed skill file → press m → select it → s. You see: a sync: notification; your change is committed + pushed.
sync an edit
CLI: ainb skill sync --to-repo

⑤ Update & remove

Select a unit → u to update, r to remove. You see: an update notification, then the unit leaves the list.
update and remove
CLI: ainb skill check · ainb skill update <uri> · ainb skill remove <uri>

⑥ Search & navigate

Arrow / jk to move; / then type to filter. You see: the cursor + Detail track each row; the list narrows as you type.
search and navigate
CLI: this one is interactive-only — use ainb skill check --source <name> to scope on the terminal.
It manages plugins too. Unlike other skill managers, ainb understands Claude marketplace plugins — the discovery banner counts them separately and manages them like any other unit.

Every journey, recorded both ways — the TUI keypresses and the equivalent CLI commands. (Recorded with vhs.)

A reconciler for units (skills, agents, commands, mcp-servers, hooks, and Claude plugins) across many tool homes and source repos. State lives in three YAML files — no database. Every key maps to an event and a real on-disk effect.

The data model — three YAML files, no DB

FileWhat it holds
manifest.yamlYour source of truth: sources (each with a target_layout) + the units you manage. User-authored, git-diffable.
lock.yamlResolved state: each unit's pinned SHA, deploy paths per tool, usage telemetry.
library.yamlYour own authored skills — a first-class personal library.

All under ~/.agents-in-a-box/. Plain serde load/save — reviewable in a PR, never an opaque store.

Discovery — two walkers + a provenance matcher

# Class-A — Claude marketplace plugins
~/.claude/plugins/cache/<mp>/<plugin>/<ver>/.claude-plugin/plugin.json
    marketplace:<plugin>@<mp>

# Class-C — orphan units across 9 tool homes
~/.{claude,codex,copilot,gemini,cursor,amazonq,claude-desktop,cline,roo}/{skills,agents,commands,...}/

# Provenance matcher (pure) — attribute each finding to its real source
attribute(classA, classC, sources)  Vec<AttributedUnit>
   Marketplace | ExternalRepo (external-dependencies.yaml) | Toolkit | AlreadyAdopted | Local
Plugins are first-class. Class-A reads plugin.json and treats a plugin as a bundle of skills — the exact layout other skill managers deliberately filter out. The matcher resolves an externally-cloned skill to its gh: upstream instead of mislabelling it local:.

Sources & target_layout — the fan-out

sources:
  - name: my-skills
    uri: gh:owner/repo
    target_layout:
      - glob: "skills/*/SKILL.md"
        home: ".claude/skills"   # where it lands on your machine
        repo: "skills"           # where it lives in the repo

The pure resolve_pair(source, unit_path) translates each unit's path into its (home, repo) pair (first-glob-wins); an empty layout falls back to bootstrap defaults.

Sync — pure planner, IO executors, bidirectional

plan_sync(source, mappings, units)  # pure: direction per unit
   ToHome  apply_to_home()   # fetch upstream, atomic write
    ToRepo  apply_to_repo()   # copy, git add/commit/push (per-source lock)

Unlike one-way installers, ainb does push-back: edit a deployed file, press s, and your change is committed + pushed to the source. A per-source lock at .git/ainb-sync.lock stops two syncs racing.

Drift & catalog — both behind a mockable trait

SubsystemProductionTests
DriftGitLsRemoteBackendgit ls-remote → ✓/⚠/▲/⟷, background poll on openMockBackend
CatalogSkillsShHttpBackend — skills.sh; key from config.toml [skills].api_key or AINB_SKILLS_API_KEYMockCatalogBackend (zero network)

Every key → event → effect

KeyEffect
mreload from disk · drift poll · run walkers · (re-)show banner, clearing any skip-marker
Enter (banner)reconcile walker output → write manifest
iainb source add <uri> in-process → reload
bCatalogBackend.search → results modal → install selected
lrender library.yaml owned skills
u / rainb skill update/remove on the selected unit → toast + reload
cre-trigger background drift scan → glyphs refresh
sno peer → sync intent + toast; conflict pair → flip shadowed_by
/filter Units (name / source / kind)

How it's tested

A feature-gated sandbox fixture seeds a fake ~/.claude/~/.codex + a bare git remote, used by both in-process tests and a scripts/skill-manager-sandbox.sh launcher for manual testing. Three tiers: pure unit tests, CLI integration tests, and live tmux tripwires that spawn the real binary, press keys, and assert the captured pane — every keybind proven end-to-end against the actual program. (The Demos tab gifs above were recorded the same way, with vhs.)