Migrating a Claude Code Skill to Hermes: A Worked Example
Step-by-step port of a write-changelog skill from Claude Code to Hermes. Original file, target file, line-by-line what changes and why.
Step-by-step port of a write-changelog skill from Claude Code to Hermes. Original file, target file, line-by-line what changes and why.
There is no substitute for seeing a concrete example. This post takes a representative Claude Code skill — a hypothetical write-changelog that reads recent git commits and produces a CHANGELOG.md entry — and walks through porting it to Hermes. You will see the original file, the target file, and every change we make in between, with the reasoning attached.
For the broader compatibility rules this example is putting into practice, see Are Claude Code Skills Portable to Hermes?. This post is the hands-on companion. By the end you should be comfortable porting your own skills.
metadata.hermes block, reshaping the description to "Use when..." style, normalizing tags, and fixing related-skill references.~/.hermes/skills/<category>/<skill-name>/SKILL.md.~/.hermes/skills/software-development/write-changelog/SKILL.md.Here is the original Claude Code skill. It lives at .claude/skills/write-changelog/SKILL.md in a project repo.
---
name: write-changelog
description: Generates a CHANGELOG.md entry from recent git commits.
version: 1.0.0
author: Duke
license: MIT
tags: [Git, Changelog_Generation, Docs]
related_skills:
- ./semver-bumping/SKILL.md
- ./release-notes/SKILL.md
---
# write-changelog
Generate a CHANGELOG.md entry from recent git commits.
## When to use
Trigger this skill when the user asks to write a changelog, summarize recent commits,
or prepare release notes. Typical prompts include:
- "write a changelog for the last release"
- "summarize the commits since v1.2.0"
- "update CHANGELOG.md"
## Procedure
1. Identify the target version. If the user did not specify one, ask.
2. Identify the base reference (usually the previous tag or the `main` branch).
3. Run `git log <base>..HEAD --oneline` to get the commit list.
4. Group commits by conventional commit prefix (feat, fix, docs, refactor, etc).
5. Write the entry in the existing CHANGELOG.md format.
6. Show the diff before committing.
## Output format
- Use the Keep a Changelog format (https://keepachangelog.com/).
- Group under headings: Added, Changed, Deprecated, Removed, Fixed, Security.
- Sort by impact within each group (breaking changes first).
## Notes
Do not commit. Leave the staging to the user. Always show the diff first.
This is a reasonable Claude Code skill. Clear description, specific triggers, step-by-step procedure, concrete output format. Now let's port it.
The Claude Code description reads: Generates a CHANGELOG.md entry from recent git commits.
That describes what the skill does. For Hermes, we want to describe when to invoke it. The convention is "Use when..." phrasing, because Hermes's autonomous loop matches against trigger phrasing more aggressively than Claude Code's session-scoped scoring:
description: Use when the user asks to write a changelog, summarize recent commits, or prepare release notes. Generates a CHANGELOG.md entry grouped by conventional commit type.
Same information, reordered. "Use when..." first, then "what it does" after.
Original:
tags: [Git, Changelog_Generation, Docs]
Hermes expects lowercase-hyphenated tags:
tags: [git, changelog, release-notes, docs]
I also split Changelog_Generation into two more specific tags (changelog, release-notes) because Hermes's FTS5 memory index rewards granular tagging when searching for related skills.
Original:
related_skills:
- ./semver-bumping/SKILL.md
- ./release-notes/SKILL.md
Hermes resolves related skills by bare name across the whole ~/.hermes/skills/ tree, not by relative path. Strip the paths:
related_skills:
- semver-bumping
- release-notes
Bare names work in Claude Code too, so this change is safe in either runtime.
metadata.hermes BlockHermes namespaces its runtime-specific metadata under metadata.hermes. The ported tags and related skills move into this block:
metadata:
hermes:
tags: [git, changelog, release-notes, docs]
related_skills: [semver-bumping, release-notes]
You can also keep the top-level tags field if you want the skill to stay readable in tools that do not look inside metadata.hermes. Hermes does not mind the duplication.
Putting those changes together, here is the Hermes version at ~/.hermes/skills/software-development/write-changelog/SKILL.md:
---
name: write-changelog
description: Use when the user asks to write a changelog, summarize recent commits, or prepare release notes. Generates a CHANGELOG.md entry grouped by conventional commit type.
version: 1.0.0
author: Duke
license: MIT
metadata:
hermes:
tags: [git, changelog, release-notes, docs]
related_skills: [semver-bumping, release-notes]
---
# write-changelog
Generate a CHANGELOG.md entry from recent git commits.
## When to use
Trigger this skill when the user asks to write a changelog, summarize recent commits,
or prepare release notes. Typical prompts include:
- "write a changelog for the last release"
- "summarize the commits since v1.2.0"
- "update CHANGELOG.md"
## Procedure
1. Identify the target version. If the user did not specify one, ask.
2. Identify the base reference (usually the previous tag or the `main` branch).
3. Run `git log <base>..HEAD --oneline` to get the commit list.
4. Group commits by conventional commit prefix (feat, fix, docs, refactor, etc).
5. Write the entry in the existing CHANGELOG.md format.
6. Show the diff before committing.
## Output format
- Use the Keep a Changelog format (https://keepachangelog.com/).
- Group under headings: Added, Changed, Deprecated, Removed, Fixed, Security.
- Sort by impact within each group (breaking changes first).
## Notes
Do not commit. Leave the staging to the user. Always show the diff first.
Notice the body is completely unchanged. All four edits are in the frontmatter. This is typical — body markdown is about instructing the model and that instruction does not depend on the runtime.
Here is every line that changed, for clarity:
---
name: write-changelog
-description: Generates a CHANGELOG.md entry from recent git commits.
+description: Use when the user asks to write a changelog, summarize recent commits, or prepare release notes. Generates a CHANGELOG.md entry grouped by conventional commit type.
version: 1.0.0
author: Duke
license: MIT
-tags: [Git, Changelog_Generation, Docs]
-related_skills:
- - ./semver-bumping/SKILL.md
- - ./release-notes/SKILL.md
+metadata:
+ hermes:
+ tags: [git, changelog, release-notes, docs]
+ related_skills: [semver-bumping, release-notes]
---
Four hunks, under ten lines touched. The body is untouched.
Drop the file at:
~/.hermes/skills/software-development/write-changelog/SKILL.md
The software-development directory is a category convention — Hermes walks the whole tree so you can use whatever grouping makes sense. Common category folders in the bundled skills include software-development, autonomous-ai-agents, red-teaming, and writing.
If the skill needs supporting files (templates, scripts, examples), put them next to SKILL.md in the same directory. Hermes treats the folder as the skill's package.
Start Hermes:
hermes chat --provider anthropic --model claude-sonnet-4-6
At the prompt, give it a trigger that should match the skill's description:
> Write a changelog for everything since v2.3.0
If Hermes picks up the skill, you will see it activate and walk through the procedure. If it does not, the usual culprits are:
~/.hermes/skills/**/SKILL.md. Hermes scans only that tree.claude-sonnet-4-6 decides the skill is not a match. Revisit the description phrasing.For the broader memory and skill-discovery mechanics that make this matching work, see Writing Your First Hermes SKILL.md.
This was a simple skill. For more complex ports — skills with supporting scripts, templates, multi-file packages — the frontmatter changes are the same. The extra work is making sure paths inside the body point correctly. For example, if the Claude Code skill body says see ./templates/entry.md, that relative path still works in Hermes as long as the templates folder ported alongside the SKILL.md.
One more case worth flagging: skills that reference Claude Code hooks or Claude Code-specific tools by name in the body text. Those references are not wrong, they are just Claude Code-specific. In Hermes, the equivalent capability might be exposed under a different tool name. Check the 47 Hermes tools Claude Code does not have catalog if your skill leans on specific tooling and reword the body if needed.
The ported file still works in Claude Code. The metadata.hermes block is ignored, the lowercase tags are fine, the bare related-skill names resolve. If you want one SKILL.md that runs in both runtimes, the Hermes form is the portable form. Write to the Hermes conventions from the start and you get Claude Code compatibility for free.
Use when creating new skills, editing existing skills, or verifying skills work before deployment
Use when starting any conversation - establishes how to find and use skills, requiring Skill tool invocation before ANY response including clarifying questions
Teaches Claude how to use the linear-CLI tool for issue tracking
Delegate coding tasks to OpenAI Codex CLI agent. Use for building features, refactoring, PR reviews, and batch issue fixing. Requires the codex CLI and a git repository.