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.
-
Write the frontmatter
Every
SKILL.mdstarts 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
metadatamust 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
referencesfolder and link to it from the body. The agent then opens those files only when it needs them. -
Follow the strictest rules
Your
SKILL.mdwill 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:Rule Agents that require it A name is present Codex, Cursor, Copilot, OpenCode, Kilo Code The name matches the folder name OpenCode The name has at most 64 characters OpenCode, Copilot A description is present Codex, Cursor, Copilot, OpenCode, Antigravity The description has at most 1,024 characters Roo Code, Kilo Code Avoid fields that only one agent understands, such as
allowed-tools,paths,icon,modelordisable-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.
-
Create the version folder
Create a folder named after the version, such as
v0.1.0, and put theSKILL.mdfile 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
-
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:
latestpoints to the highest version you have published, anddefaultpoints to the release you want people to use.Terminalcd 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 -akeeps the permissions for you, so copying is safer than writing the files twice.Make sure every link inside
SKILL.mdworks from both copies, because people can install the skill from either one. In practice, copy the wholereferencesfolder to the top level, not onlySKILL.md.The
latestanddefaultlinks must name a version folder inside the same package, such asv0.1.0, and nothing else. -
Check the package
Before you open a pull request, run the registry's checks from the root of the repository:
Terminaltask 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-reviewerskill can guide you through that review. Install it withskm add skills-yaml/skill-reviewer --source default. -
Open a pull request
Add the skill to the list of skills in the registry's README, and open a pull request against the
developbranch.Merging into
developbrings your skill into the registry, but people can install it only afterdevelophas been released intomain, becausemainis the branch skm reads from.
The resulting package looks like this:
├── 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:
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:
-
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.
-
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. -
Move the top level to the new release
Point
latestto the new folder, and update the copy at the top of the package so that it matches the new release. -
Check and open a pull request
Run
task checkand open a pull request againstdevelop, as for the first release. If the namespace offers bundles, runtask manifestfirst, 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:
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.
| Agent | In a project | For 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 |
hermes | not 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
--globaloption.
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:
-
Write the bundles section
Bundles are declared in a file called
manifest.yamlat the top of the namespace folder. If you maintain the namespace by hand, thebundlessection is the only part you write yourself:skills/skills-yaml/manifest.yamlbundles: authoring-toolkit: packages: - skill-creator - skill-reviewerBundle 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.
-
Generate the rest of the manifest
Run this command from the root of the registry:
Terminaltask 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.
-
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-reviewerThe package names now appear twice. The
packagessection 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. -
Keep the manifest up to date
Whenever you publish a new version of a package in the namespace, run
task manifestagain so that the file picks up the new version.If you forget,
task checkfails 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:
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.