Skip to main content

Command Palette

Search for a command to run...

I Built a TUI Package Manager for AI Agent Skills — Here's Why

Updated
5 min readView as Markdown
I Built a TUI Package Manager for AI Agent Skills — Here's Why
N
Love to code, gaming. And I use vim btw.

If you've been using AI coding agents for a while, you've probably collected a pile of SKILL.md files scattered across different folders. One for Claude Code, another for Cursor, maybe a third sitting in a GitHub repo you keep re-cloning every time you set up a new machine.

I got tired of that. So I built skmp — a full-screen TUI package manager for AI agent skills, inspired by how Homebrew and npm handle software packages, but purpose-built for the chaotic multi-harness world of agentic AI tools.


The Problem It Solves

Modern AI coding agents — Claude Code, Codex, Cursor, Antigravity, pi, OpenCode — all support skills or custom instructions. The problem is that each tool expects them in a different directory, with no shared standard.

You end up with something like this:

  • ~/.claude/skills/ for Claude Code

  • ~/.codex/skills/ for Codex

  • ~/.cursor/skills/ for Cursor

  • ~/.agents/skills/ for pi

  • ~/.gemini/antigravity-ide/skills/ for Antigravity

Every time you install a new skill, you either manually copy it into each folder or you forget and wonder why it isn't available in half your tools.

skmp fixes this with a single store and symlinks:

~/.skmp/skills/         ← downloaded once, skmp owns this
     ↓ symlinked to
~/.agents/skills/
~/.claude/skills/
~/.codex/skills/
~/.cursor/skills/
~/.gemini/antigravity-ide/skills/

Install a skill once. It appears everywhere.


What It Looks Like

The interface is a split-pane terminal UI built with Bubble Tea and Lipgloss. On the left, a scrollable list of skills. On the right, a detail pane with the description, author, version, and tags. Four tabs let you switch between all skills, bundles, your installed skills, and your installed bundles.

Navigation is fully keyboard-driven in a vim-ish style:

Key Action
j / k move down / up
K / J jump to top / bottom
tab focus detail pane
i / x install / remove
/ search

Install in Seconds

npm install -g skmp-cli

Or via Homebrew:

brew tap Nitesh000/tap
brew install skmp

Or grab a binary directly from the Releases page.

Once installed, just run skmp. It fetches the registry on first launch, caches it for 24 hours, and you're browsing.


The Registry Model

This is the part I'm most proud of architecturally. The registry is just a index.json file living in the GitHub repo, served directly from raw.githubusercontent.com. No CDN middleman, no server infrastructure to maintain.

Each entry is metadata only:

{
  "name": "caveman",
  "description": "Ultra-compressed communication mode. Cuts token usage ~75%.",
  "author": "yuu",
  "version": "1.0.0",
  "source": "https://raw.githubusercontent.com/...",
  "harnesses": ["claude-code", "pi", "codex"],
  "tags": ["communication", "tokens"]
}

The actual skill files live in their author's own repository. skmp only stores the URL. This means:

  • Authors own their skills. You push an update to your repo, all users get it on next install.

  • The registry is just an index. No assets, no binary blobs, no storage costs.

  • Contributing is a one-PR process. Add your entry to registry/index.json, open a PR, done.


How Search Works

Fuzzy full-text search is powered by Bleve, an embedded Go search library. The tricky part was handling skill names that contain hyphens and dots — by default, most text analyzers tokenize write-a-skill into three separate tokens (write, a, skill), which breaks exact name queries.

The fix was a custom Bleve analyzer using a keyword tokenizer (treats the whole string as one token) plus a to_lower filter. This means write-a-skill is indexed and searchable as a single unit. Hyphenated names, versioned names like tdd-v2, multi-word names — all work correctly.


The Harness Abstraction

Each AI tool skmp supports is called a harness. Harnesses are detected automatically at runtime by checking if a known binary is present on your $PATH.

Harness Binary Detected Skills Path
pi pi ~/.agents/skills/
Claude Code claude ~/.claude/skills/
Antigravity agy-ide ~/.gemini/antigravity-ide/skills/
Codex codex ~/.codex/skills/
Cursor cursor ~/.cursor/skills/
OpenCode opencode registered in opencode.jsonc

When you install a skill, skmp symlinks it into every harness it detects. If you install a new AI tool later, just run skmp sync to wire up your existing skills into the new harness automatically.

OpenCode is a special case — it doesn't read from a skills directory; it reads paths from its own config file. So skmp registers ~/.skmp/skills under skills.paths in ~/.config/opencode/opencode.jsonc instead of symlinking.


What's Next

A few things on the roadmap:

  • Skill updatesskmp upgrade to pull the latest version of every installed skill

  • Private registries — point skmp at your own index.json for internal team skills

  • More harnesses — Windsurf, Zed, and others as their skill systems mature


Try It

npm install -g skmp-cli
skmp

The repo is at github.com/Nitesh000/skmp. PRs, bug reports, and new skill submissions are all welcome — the contributing bar is intentionally low.

If you've got a skill you've been carrying around manually, consider submitting it to the registry. The whole point of skmp is that a skill you write once should be available everywhere with a single command.