One skill store. Clean agent folders. Activate from anywhere.
skill-cli is a cross-agent skill manager for AI coding agents (Claude Code, Codex, Cursor, Gemini, …). Skills live in a single global store — your agent directories stay clean — and you control which skill is active where with one config file.
- 🗂️ One canonical store —
~/.skill-cli/store. No more copies scattered across~/.claude,~/.codex,~/.cursor, … - 🧹 Agent folders untouched — nothing is written into agent directories.
- 🎛️ Three-layer activation — installed → enabled globally → enabled per project.
allowalways wins overdeny. - 🔌 Universal sources —
owner/repo, GitHub/GitLab URL, git URL, local path, npm package (vianpx skills). - ⚡ Pull-based — agents pull skill content into context on demand via
skill trigger /X. No hooks required. - 🔍 Interactive TUIs —
skill searchto discover & multi-install from the skills registry;skill(no args) to manage every installed skill with the keyboard. TTY-only; agents & CI stay non-interactive. - ⭐ Default skills — one global list: active by default in every project AND auto-loaded on session start.
- 🖥️ Cross-platform — Windows, macOS, Linux (handles the Windows
npxspawn quirk for you). - 🧪 Well tested — 225 unit + CLI tests, network-free by default.
If skill-cli saves you time, please give it a star ⭐ on GitHub — it helps others discover the project and keeps development going. Thank you! 💜
npm install -g @victortomaili/skill-cliRequires Node.js 22+.
# 1) one-time global setup (creates the store + bootstraps detected agents)
skill init -g
# 2) install a skill from any source (or `skill search` to browse interactively)
skill install owner/repo
# 3) manage everything with the keyboard (terminal only)
skill # ↑↓ move · space toggle · a default · d delete · enter view
skill list
skill cat <name>That's it. Your agent now knows: when the user types /X, run skill trigger X.
~/.skill-cli/
store/<skill>/SKILL.md ← one canonical store (skills live here)
config.yaml ← global defaults (active by default + auto-load)
<project>/skill.config ← per-project overrides (inherit / deny / allow)
~/.claude/CLAUDE.md ← bootstrap block injected by `skill init -g`
~/.codex/AGENTS.md (idempotent — preserves your existing content)
~/.gemini/GEMINI.md
~/.pi/agent/AGENTS.md
Agents don't read skill.config directly — the CLI does. The agent only needs the
short bootstrap block telling it to run skill on /X.
| Command | Description |
|---|---|
skill init -g |
Global setup: create store + inject bootstrap into agent files |
skill init |
Create a skill.config for the current project |
skill install <source> |
Fetch skill(s) to the store (agent dirs untouched) |
skill search |
Interactive search & multi-install from the skills registry (TTY) |
skill / skill manager |
Interactive manager: toggle, default, delete, view (TTY) |
skill enable <name> [-g] |
Allow in project, or global default with -g |
skill disable <name> [-g] |
Deny in project, or remove global default with -g |
skill default <name> |
Mark a default skill (global: active + auto-load) |
skill undefault <name> |
Remove the default flag |
skill active |
List ACTIVE skills + descriptions (the command your agent runs on start; alias: status) |
skill list |
Show installed + active skills (cwd-aware, ★ = default) |
skill show <name> |
Skill metadata (path, triggers, version) |
skill cat <name> |
Dump skill content into context |
skill trigger <keyword|name> |
/X trigger or skill name → content (single), candidates (multi) |
skill update [name…|--all] |
Re-fetch from source, update changed skills |
skill remove <name> [-y] |
Remove from store (prompts on TTY; agents / CI / -y skip) |
Aliases: ls (list), add (install), info (show), rm/uninstall (remove), browse (search), ui (manager), def (default), undef (undefault).
install delegates resolution to npx skills, so every format works:
owner/repo GitHub shorthand
https://github.com/owner/repo full GitHub URL
https://github.com/owner/repo/tree/main/skills/x path inside a repo
https://gitlab.com/org/repo GitLab URL
git@github.com:owner/repo.git any git URL
./my-local-skills local path
<npm-package> npm package shipping skills
Install runs npx skills add in a temp cwd so files land in <tmp>/.claude/skills/
and are then moved into ~/.skill-cli/store/. Your real agent directories are
never written to.
Faithful to the SKILL.md standard (the author decides the structure):
---
name: deep-research
description: Deep source-research workflow
version: 1.2.0
triggers: [research, deep-search] # skill-cli-specific; powers /<trigger>
---
# Your instructions heretriggers is optional and skill-cli-specific. See examples/hello-world/SKILL.md
for a minimal, copy-paste template.
One global concept, refined per project:
- installed — present in the store (passive)
- default (global) — listed in
config.yamldefaults:; active by default in every project and auto-loaded on agent session start. Mark one withskill default <name>(orskill enable -g). - per-project override — a project's
skill.configrefines the set:allow— activate an otherwise-passive skill in this project onlydeny— turn off a default skill in this project onlyinherit: false— ignore global defaults entirely (onlyallowapplies)
A project with no skill.config inherits the global defaults (all active). Pure
allowlist mode in a single project:
# <project>/skill.config
inherit: false # ignore global defaults in this project
allow: [react-best-practices] # only this skill is active here
allowalways wins overdeny, so withinherit: trueyou can also writedeny: ["*"]+allow: [X]= "only X here". Matching is case-insensitive throughout.
When run in a real terminal, skill-cli offers two keyboard UIs. Agents and CI never enter them (a non-TTY stdin is detected) — they use the plain commands.
Opens a full-screen manager over your store:
| Key | Action |
|---|---|
↑ / ↓ |
move |
space |
toggle active in the current project |
a |
toggle the global default (active + auto-load) |
d |
delete (asks y/N) |
enter |
view the SKILL.md |
q / esc |
quit |
Type a query → browse live results from the skills registry
(npx skills find) → mark one or more with space → enter installs all marked
→ loops back so you can search again. esc or an empty query quits. skill install
with no source also opens it.
A default is a skill that is active by default in every project AND
auto-loaded on agent session start — one unified global list in config.yaml
(defaults:). Mark one with skill default <name>, remove with
skill undefault <name>, list them with skill active. The AGENTS.md bootstrap
block tells your agent to run skill active on start, then skill cat <name>
for each.
Defaults are a global concept (never per-project). A project can still turn a
default off locally with skill disable <name> (a project deny), or activate a
non-default locally with skill enable <name> (a project allow) — see
Activation. In the interactive manager, a toggles the global
default; space toggles the per-project override.
skill init -g injects a short, idempotent block into each detected agent's global
instruction file (CLAUDE.md, AGENTS.md, GEMINI.md):
START GATE: on the first user message, your VERY FIRST action — BEFORE ANYTHING ELSE (before thinking, before any tool call) — is
skill active, the skill catalog (every active skill's name + full description; never the body). Read it and decide per skill from its description: AUTO-LOAD (silently) anything needed to do the task at all, or that makes the work higher-quality / more correct (domain knowledge, best-practice, standards). PROPOSE (apply only after the user confirms;/X= confirm) anything that's an optional change to the experience — response style/format/mode, context-cost optimization, or an optional shortcut (easier/faster, not about correctness). When unsure, propose. LOADED ≠ LISTED: a skill is loaded only if youcat-ed it this session. PRIORITIES: correctness > quality > cost (cheap) > speed — never sacrifice correctness/quality for speed or cost./X→skill trigger X.
It's wrapped in <!-- BEGIN skill-cli --> … <!-- END skill-cli --> markers, never
duplicates, and preserves your existing file content. Re-run init -g any time —
it reports already set up and rewrites nothing.
Supported agents: Claude Code, Codex, Gemini, and pi. (Cursor uses .cursor/rules with
a different format — adapter planned. See issue tracker.)
Works on Windows, macOS, and Linux. On Windows it spawns npx via cmd.exe /c
(the Node 20+ CVE-2024-27980 workaround) with shell:false and validates the
source against shell metacharacters, so it's safe by default.
git clone https://github.com/victortomaili/skill-cli
cd skill-cli
npm install
npm link # makes `skill` point at your checkout
npm test # 225 tests, network-free (~3s)
npm run test:e2e # opt-in: real npx fetch over the networkTests never touch your real ~ — they use an isolated SKILL_CLI_HOME. See
CONTRIBUTING.md for the project structure, how to add a command,
and the PR checklist.
Contributions are welcome! 💜 Please read CONTRIBUTING.md and follow our Code of Conduct.
- 🐛 Report a bug
- ✨ Request a feature
- 🔒 Found a security issue? See SECURITY.md — report it privately, not as a public issue.
See CHANGELOG.md.
MIT © skill-cli contributors