a cli for agent skills

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
Claude Code Codex Gemini CLI macOS · Linux · Windows
~/code/my-project
$ 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
why

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.

how it works

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.

01 · the repo

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
02 · the store

~/.config/skills/store

A sparse clone shared by every project on your machine. sync fast-forwards it and never touches installed skills.

skills install
03 · the project

.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.

what you get

Small, explicit, and careful with your edits.

1

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.

get started

Two minutes from install to your first skill.

You need Git 2.45 or newer on your PATH. Everything else is one binary.

  1. Install the CLI. Use Homebrew on macOS, go install, or grab a binary for macOS, Linux, or Windows from Releases.
  2. Point it at your repo. Edit ~/.config/skills/config.toml, or skip this step to try the demo store first.
  3. Install a skill in a project. The first command that needs the store clones it. You never run setup by hand.
  4. Keep it current. sync pulls your repo, update moves installed skills to it. Two steps, on purpose.
Every command, explained →
$ 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
bring your own

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.