Introduction
A local skill that works for you is useful. A packaged skill that other people can install in one command is reusable. The difference is mostly about layout: directory shape, naming, and the small set of conventions that let any standards-compliant client pick up your skill without per-tool fiddling. Packaging is not a build step. It is a way of laying out files.
Key Concepts
- Slug: The directory name. Becomes the install identifier and slash command.
- Canonical layout:
SKILL.mdat the root, optionalreferences/,templates/,scripts/,assets/subdirectories. - Single-file skill: A standalone
SKILL.mdwith no subdirectories. Distributable via direct URL. - Multi-file skill: A directory with subdirectories. Distributable via GitHub tap, well-known endpoint, or marketplace.
- Slug-only ignores: Directories starting with
.or_are skipped by Hermes when scanning.
Real World Context
A team has three skills they want to share: a single-file git-commit-style skill, a multi-file terraform-plan-review skill with scripts and templates, and a single-file lunch-coordinator skill. They put all three in a GitHub repo called my-org/hermes-skills. Each lives under skills/<name>/SKILL.md. Anyone in the org runs hermes skills tap add my-org/hermes-skills once and gets all three available.
For a public-facing single-file skill (git-commit-style) they also publish it as a direct URL at https://example.com/git-commit-style/SKILL.md. Now any user, even outside the org, can install it with hermes skills install https://example.com/git-commit-style/SKILL.md. Two distribution shapes, same source files.
Deep Dive
For a single-file skill, packaging is trivial: just the file itself.
textSKILL.md # name in frontmatter, install via direct URL
For a multi-file skill, the layout follows the canonical contract:
textmy-skill/ ├── SKILL.md ├── references/ │ ├── deep-dive.md │ └── api-notes.md ├── templates/ │ └── output.j2 ├── scripts/ │ └── helper.py └── assets/ └── example.png
For a GitHub tap (a repo containing many skills), the layout is one level up:
textowner/repo └── skills/ # default path; configurable per-tap ├── my-workflow/ │ ├── SKILL.md │ ├── references/ │ └── scripts/ ├── another-skill/ │ └── SKILL.md └── third-skill/ └── SKILL.md
A few conventions to keep in mind:
- Directory names are slugs. They become the install identifier and slash command. Use lowercase kebab-case (
git-commit-style, notGitCommitStyle). - Slugs starting with
.or_are ignored. Use them for work-in-progress drafts that should not appear in the index. - The
namefield in frontmatter should match the directory name. Mismatch is a smell; clients accept it but reviewers will be confused. - Subdirectory names are canonical. Use
references/,templates/,scripts/,assets/. Invented names (docs/,bin/) make the layout harder to scan. - One skill per directory. Do not bundle two unrelated skills in one folder. If you have two workflows, make two skill directories.
A few packaging gotchas:
- Direct URL skills must be single-file.
hermes skills install https://example.com/SKILL.mdonly fetches that one file. For multi-file skills, publish via GitHub tap or marketplace instead. - The tap path is configurable but defaults to
skills/. If your repo uses a different path (internal/skills/or just root), declare it in the tap entry (or accept the default). - Hidden directories under
.hub/,.bundled_manifest, etc. are reserved by Hermes. Do not create them in your tap.
Naming consistency matters more than you might expect. A user typing /git-commit-style after installing git-commit-style expects the slash command to match the slug. Keep all three in sync (directory name, frontmatter name, slash command).
Common Pitfalls
- Mismatched slug, directory name, and frontmatter name: Pick one form and use it everywhere.
- Trying to ship multi-file skills via direct URL: Direct URL installs are single-file only. Use GitHub for anything with subdirectories.
Best Practices
- Start with the canonical layout, even for trivial skills: Costs nothing, looks familiar to every reviewer.
- Use kebab-case slugs: Matches the slash command convention and avoids casing pitfalls across operating systems.
Summary
- Packaging is a layout:
SKILL.mdplus optional canonical subdirectories. - Single-file skills can ship via direct URL; multi-file skills need a tap or marketplace.
- Directory names are slugs; keep them in kebab-case and matching the frontmatter
name. - Use canonical subdirectory names (
references/,templates/,scripts/,assets/); avoid invented ones.
Code Examples
# A clean GitHub tap repo for your team
my-org/hermes-skills
├── README.md
└── skills/
├── git-commit-style/
│ └── SKILL.md
├── pg-slow-query-debug/
│ ├── SKILL.md
│ ├── references/
│ │ └── lock-modes.md
│ └── scripts/
│ └── explain.py
└── release-notes/
└── SKILL.md
# Subscribers add it with:
hermes skills tap add my-org/hermes-skills
hermes skills search release
hermes skills install my-org/hermes-skills/release-notes