Your skills.
Your repo.
Your rules.
skills is a small Go CLI that installs agent skills from a Git repository
you own into Claude Code, Codex, and Gemini CLI, and keeps them current as your repo changes.
go install github.com/madalinpopa/skills@latest
$ skills sync pulled store a1b2c3d -> e4f5a6b $ skills install go-review + go-review added 1 skill, 1 changed $ skills update ~ go-review updated ! sql-review skipped, you edited it 2 skills, 1 changed, 1 needs attention
Stop installing skills you have never read.
A skill is a prompt that runs with your permissions, inside your projects, with your tools. It deserves the same care as any code you pull into a build.
-
01
Skills are personal.
A good skill encodes how you work: your review checklist, your test layout, your release steps. Somebody else's skill encodes somebody else's habits.
-
02
Internet skills are unreviewed input.
You would not paste a random script into your shell. A skill from an unknown marketplace is the same thing, dressed up as Markdown.
-
03
Build your own private store.
One Git repo. A folder per skill. Review it like code, sync it to every machine, and install it into any project with one command.
-
04
Borrow ideas, not files.
Read other people's skills for inspiration. Then write your own, in your own words, and keep it where you can see it change.
Three moving parts, no server.
The CLI shells out to Git. It uses your existing credentials, works with private repositories, and never needs a registry.
github.com/you/skills
Any Git repository with a skills/ folder. One folder per skill, one SKILL.md inside. The rest of the repo can hold anything.
skills sync
~/.config/skills/store
A sparse clone shared by every project on your machine. sync fast-forwards it and never touches installed skills.
skills install
.claude/skills · .agents/skills
A copy per agent, each with its own .skill-lock.json. Delete the folder and the state goes with it.
Skills are not compiled into the binary. Pushing a change to your repo is the whole release:
the next sync plus update brings it into every project.
Small, explicit, and careful with your edits.
One file, three agents
Write one SKILL.md. The CLI strips store-only fields and resolves Claude-specific frontmatter on install, so the copies never drift apart.
Updates that never clobber you
Every file is compared three ways: what the store wants, what is on disk, and what the CLI last wrote. Your edits are detected, not guessed.
Conflicts skip, never overwrite
An edited skill is skipped and reported. --force replaces it only after a timestamped backup, and prints the exact path.
Drafts without a release
Put status: draft in the frontmatter and a skill stays invisible until you flip it. Publishing is a field, not a registry.
Stateless about projects
Each installed skill carries its own lock with source, commit, and file hashes. Copy it to another project and the record goes along.
Built for scripts
Exit codes mean something: 0 done, 1 error, 2 bad usage, 3 needs your attention. --dry-run shows the plan and writes nothing.
Two minutes from install to your first skill.
You need Git 2.45 or newer on your PATH. Everything else is one binary.
- Install the CLI. Use Homebrew on macOS,
go install, or grab a binary for macOS, Linux, or Windows from Releases. - Point it at your repo. Edit
~/.config/skills/config.toml, or skip this step to try the demo store first. - Install a skill in a project. The first command that needs the store clones it. You never run setup by hand.
- Keep it current.
syncpulls your repo,updatemoves installed skills to it. Two steps, on purpose.
$ brew install --cask madalinpopa/tap/skills # or: go install github.com/madalinpopa/skills@latest $ cd ~/code/my-project $ skills ls # what the store offers $ skills install go-review # copy it into this project $ skills ls --local # what is installed here $ skills sync # pull new commits into the store $ skills update # bring installed skills up to date $ skills diff go-review # see what you changed locally $ skills remove go-review # uninstall, backed up first
A store is just a repo with a folder in it.
No fork needed. Create a Git repository, add a skills/ folder,
and tell the CLI where it lives. Private repos work through your normal Git credentials.
skills/
go-review/
SKILL.md the skill itself
agents/openai.yaml optional, Codex only
references/ optional, every agent
django-testing/
SKILL.md
release-notes/
SKILL.md status: draft, not installable yet
# ~/.config/skills/config.toml [store] repo = "https://github.com/your-name/your-skills" branch = "main" [agents.claude] project = ".claude/skills" global = "~/.claude/skills" [agents.codex] project = ".agents/skills" global = "~/.agents/skills" [defaults] agents = ["claude", "codex"]
The folder name is the skill name. The CLI reads only committed files under skills/,
so your repo can also hold notes, prompts, or anything else.
See using your own store for switching from another repository.