Registry

Authoring guide

This page explains how to write a skill package that installs into every agent skm supports, and how to offer several skills together as a bundle.

A skill is a folder that contains a SKILL.md file. The file holds the instructions an agent follows when a task calls for the skill, and the folder can also hold reference documents, templates or scripts that those instructions point to.

To share a skill through a registry, you publish it as a package: the same skill, but versioned, so that people can pin the exact release they rely on. skm then reads the package from the registry and links it into the skill folder of every agent a project uses. See also: SKILL_STRUCTURE.md and VERSIONING.md (skills-yaml registry).

This guide summarises the registry's rules. The official source is the registry itself: its structure and versioning documents, together with its validation script. If this guide and the registry ever disagree, follow the registry.

Publish a skill package

A package in the registry can be added to any project with skm add, and skm links it into the skill folder of every agent the project uses. The steps below publish a skill called release-notes as version 0.1.0.

  1. Write the frontmatter

    Every SKILL.md starts with a short header, called frontmatter, written in YAML between two lines of three dashes. A skill published in a registry needs only three fields:

    SKILL.md
    ---
    name: release-notes
    description: Draft release notes from merged pull requests. Use when preparing a release, summarizing changes since the last tag, or writing a changelog entry.
    metadata:
      skm-version: "0.1.0"
    ---
    name
    Exactly the same as the name of the skill's folder. Lowercase letters, digits and single hyphens, at most 64 characters, and no hyphen at the start or end.
    description
    Most agents read only the description when they decide whether a skill is relevant, so say both what the skill does and when to use it. Up to 1,024 characters.
    metadata.skm-version
    The version number of the package. Write it in quotes, because every value under metadata must be text.

    The body of the skill comes after the frontmatter. Write it for an agent that is about to carry out the task, and start with the steps it should take.

    If the skill needs long background material, put it in a references folder and link to it from the body. The agent then opens those files only when it needs them.

  2. Follow the strictest rules

    Your SKILL.md will be installed into many different agents, and they do not all apply the same rules. Follow the strictest version of each rule, and the same file will work in all of them:

    RuleAgents that require it
    A name is presentCodex, Cursor, Copilot, OpenCode, Kilo Code
    The name matches the folder nameOpenCode
    The name has at most 64 charactersOpenCode, Copilot
    A description is presentCodex, Cursor, Copilot, OpenCode, Antigravity
    The description has at most 1,024 charactersRoo Code, Kilo Code

    Avoid fields that only one agent understands, such as allowed-tools, paths, icon, model or disable-model-invocation. Other agents usually ignore them, so the skill will not behave the same way everywhere.

    If your skill really depends on one of them, keep it in your own project instead of publishing it to a shared registry.

  3. Create the version folder

    Create a folder named after the version, such as v0.1.0, and put the SKILL.md file and everything else the skill needs inside it. This folder is the release.

    Make sure the package stays within the registry's limits:

    • at most 256 files and 10 MB of data in the whole package
    • no symbolic links inside a version folder
    • scripts, if the skill has any, must be executable
  4. Copy the release to the top level and add the links

    Copy the contents of the version folder to the top of the package, so that tools can find the latest release easily. Then create two links: latest points to the highest version you have published, and default points to the release you want people to use.

    Terminal
    cd skills/<namespace>/release-notes
    cp -a v0.1.0/SKILL.md v0.1.0/references .
    ln -s v0.1.0 latest
    ln -s v0.1.0 default

    The registry checks that the two copies are identical, including their file permissions. cp -a keeps the permissions for you, so copying is safer than writing the files twice.

    Make sure every link inside SKILL.md works from both copies, because people can install the skill from either one. In practice, copy the whole references folder to the top level, not only SKILL.md.

    The latest and default links must name a version folder inside the same package, such as v0.1.0, and nothing else.

  5. Check the package

    Before you open a pull request, run the registry's checks from the root of the repository:

    Terminal
    task check    # checks the structure, links, frontmatter, dependencies and versions
    task test     # runs the tests for the checks themselves

    If a check fails, its error message tells you which rule was broken. Search for that message in validate_registry.py to see exactly what the check looks for.

    The checks confirm that a package is put together correctly, not that it is safe to use. Before you trust a skill, and especially one that includes scripts, read what it actually asks the agent to do.

    The skills-yaml/skill-reviewer skill can guide you through that review. Install it with skm add skills-yaml/skill-reviewer --source default.

  6. Open a pull request

    Add the skill to the list of skills in the registry's README, and open a pull request against the develop branch.

    Merging into develop brings your skill into the registry, but people can install it only after develop has been released into main, because main is the branch skm reads from.

The resulting package looks like this:

skills/<namespace>/release-notes/
├── SKILL.md            # the same file as v0.1.0/SKILL.md
├── references/         # the same folder as v0.1.0/references/
├── latest -> v0.1.0
├── default -> v0.1.0
└── v0.1.0/
    ├── SKILL.md
    └── references/
        └── style.md

Declare dependencies

Declare a dependency when a skill cannot work without another skill. skm installs the dependencies automatically whenever the skill is added. List them in the frontmatter, under metadata:

SKILL.md
metadata:
  skm-version: "0.1.0"
  skm-dependencies: "my-namespace/[email protected], my-namespace/[email protected]"

Each dependency names an exact version of a skill from the same registry. Separate the entries with a comma followed by a space, and list each one only once.

Make sure no chain of dependencies leads back to the skill it started from. Version ranges, aliases such as latest, and file paths are not accepted.

Dependencies are not the right tool for grouping skills that simply work well together. For that, use a bundle.

Update a published skill

Once a version has been released to main, it can no longer be changed or removed. This protects everyone who has pinned that version in their projects. To change the skill, you publish a new version next to the old one.

To publish a new version:

  1. Choose a version number

    Choose the number by what has changed for the people who use the skill. If the skill now asks the agent to do something different, the change deserves at least a new minor version.

  2. Add a new version folder

    Create a folder for the new release, such as v0.2.0, and leave the old folder where it is.

  3. Move the top level to the new release

    Point latest to the new folder, and update the copy at the top of the package so that it matches the new release.

  4. Check and open a pull request

    Run task check and open a pull request against develop, as for the first release. If the namespace offers bundles, run task manifest first, as described in Bundle skills together.

In the rare case where a published version has to be taken down, for example because it exposed private information, you can withdraw it. Delete its folder and add an entry to WITHDRAWN.yaml that records the date and the reason.

The version still exists in the repository's Git history, so treat anything it contained as public.

Where the skill is installed

People add your skill to their project by name, and skm then links it into the skill folder of each agent they use:

Terminal
skm add <namespace>/release-notes --source default
skm install

skm 0.7.0 supports sixteen agents. Several of them read from the same shared folder, .agents/skills, and in that case skm creates a single link that all of them use.

AgentIn a projectFor your user account
claude.claude/skills~/.claude/skills
codex.agents/skills~/.agents/skills
copilot.github/skills~/.copilot/skills
cursor.cursor/skills~/.cursor/skills
antigravity.agents/skills~/.gemini/config/skills
pi.pi/skills~/.pi/agent/skills
opencode.opencode/skills~/.config/opencode/skills
cline.cline/skills~/.cline/skills
kilo.kilo/skills~/.kilo/skills
gemini-cli.gemini/skills~/.gemini/skills
goose.agents/skills~/.agents/skills
crush.crush/skills~/.config/crush/skills
openhands.agents/skills~/.openhands/skills
grok.grok/skills~/.grok/skills
qwen.qwen/skills~/.qwen/skills
hermesnot supported~/.hermes/skills

In two cases, installing a skill is not quite enough:

  • Pi loads a project's skills only after you have marked the project as trusted.
  • Hermes does not read project folders at all, so it only finds skills installed for your user account with the --global option.

Bundle skills together

A bundle is a named group of skills that are meant to be used together, added to a project with one command. The skills-yaml namespace, for instance, publishes skill-creator and skill-reviewer together as the authoring-toolkit bundle.

A bundle contains no instructions of its own, which makes it different from a skill. It is also different from a dependency:

Dependency
One skill needs another one in order to work. It is declared inside the skill, and skm always installs the two together.
Bundle
Several skills are useful together. It is declared in the namespace manifest, and people choose whether they want to add it.

Do not create a bundle as an empty skill that lists the other skills as its dependencies. Every agent would still show the empty skill as something it can run, and it would describe a relationship between the skills that does not really exist.

To declare a bundle:

  1. Write the bundles section

    Bundles are declared in a file called manifest.yaml at the top of the namespace folder. If you maintain the namespace by hand, the bundles section is the only part you write yourself:

    skills/skills-yaml/manifest.yaml
    bundles:
      authoring-toolkit:
        packages:
          - skill-creator
          - skill-reviewer

    Bundle names follow the same rules as skill names. Every skill you list must already be published in the same namespace. Always write the members out in full, because skm never tries to work them out from the folders it finds.

  2. Generate the rest of the manifest

    Run this command from the root of the registry:

    Terminal
    task manifest

    The command reads the package folders and completes the file for you. It adds the name of the namespace and the current version of every package in it, sorts everything, and places a comment at the top to show which part it maintains. It refuses to write the file if a bundle lists a skill that is not published.

  3. Review the result

    skills/skills-yaml/manifest.yaml
    # The packages section is generated from the package folders by
    # `task manifest`. Edit only the bundles section, then run it again.
    schema_version: 2
    namespace: skills-yaml
    packages:
      skill-creator: "0.1.0"
      skill-reviewer: "0.1.0"
    bundles:
      authoring-toolkit:
        packages:
          - skill-creator
          - skill-reviewer

    The package names now appear twice. The packages section records the exact version of each package, and the bundle refers to those packages by name, so each version is written down in only one place. You never have to copy version numbers by hand.

  4. Keep the manifest up to date

    Whenever you publish a new version of a package in the namespace, run task manifest again so that the file picks up the new version.

    If you forget, task check fails and tells you that the manifest is out of date.

The manifest is optional, so a namespace only needs one if it offers bundles.

A namespace whose packages are generated by an external packager is the one exception to the steps above. Today that is only workspace. The packager writes the whole manifest, including extra fields that record the source repository and revision, so task manifest never changes it.

Add a bundle to a project

With skm 0.7.0 or later, preview the bundle first, and then add it to the project:

Terminal
skm add skills-yaml/authoring-toolkit --source default --kind bundle --dry-run
skm add skills-yaml/authoring-toolkit --source default --kind bundle --yes

The second command is equivalent to the following command:

skm bundle add skills-yaml/authoring-toolkit --source default --yes

To find published bundles, run skm search. It lists bundles and skills in one result list, sums up each bundle’s member skills, and shows the skm add command for each result.

Adding a bundle writes each of its skills into skills.yaml as a separate entry, pinned to an exact version. From then on, those entries behave like any others, so skm install, skm check and version changes all work as usual.

skm does not remember that the entries came from a bundle, so it will not update them automatically if the bundle changes later.

Notice a mistake in this guide? Open an issue on GitHub.