Claude Code Skill Versioning: How I Versioned 64 Skills With a Changelog From Git

Claude Code skill versioning mockup with SKILL.md version line and changelog
Built by me · Open SourcePersonal Memory TemplateFree LLM Wiki for Claude CodeSee how it works →
On this page

Disclosure: this article contains affiliate links to Wispr Flow. If you subscribe through them, I earn a commission at no extra cost to you. Nobody at Wispr reviewed this article before publication.

Short answer

Claude Code skill versioning, when you have dozens of skills, is a small contract: a version line in each SKILL.md, one version for the set in .claude-plugin/plugin.json, a changelog you actually keep, and a lint check that flags skills with no version. In my October 2026 audit, skills with a version went from 30 of 64, no changelog, to all 64, with a changelog generated from git. The free personal-memory template ships the version lines, plugin.json, CHANGELOG.md, and the lint warnings — not my private skill set, and not a git-based changelog generator.

👉 Use this template on GitHub — click Use this template, make the copy private, run /setup. Star the repo if it helps you keep the pattern around. Product page: /products/personal-memory-template/.

When I draft longer skill instructions, I often dictate them into Claude Code with Wispr Flow — same habit as in my Wispr Flow review. Try Wispr Flow’s free plan if you want to test that workflow.

Why skills need versions

A skill is a procedure the agent loads when the description matches. When you change the steps — for example how invoice-client builds a draft for Acme or Example Client — every session that uses that skill gets the new behaviour. Without a version and a changelog entry, you cannot tell what changed or when. That matters if the same skill is referenced from several projects or client reading maps by name.

This is agent skills versioning as hygiene, not a marketing feature. Anthropic’s skill docs focus on name and description for discovery (Agent Skills overview); they do not replace a changelog you maintain in the repo. The same idea shows up when you ship reusable tooling — see building an MCP server and custom MCP server lessons for neighbouring “what changed in the tool” problems.

The version line in SKILL.md

In the template, each English skill puts a version line immediately after the YAML frontmatter. From skills/ingest/SKILL.md (MIT License):

---
name: ingest
description: Use after a finished piece of work, or when the user says "ingest"…
---
_Version 0.1.0 · source: skills/ingest/SKILL.md_

setup and invoice-client use the same shape. The Norwegian simple variant under enkel/skills/ uses a _Versjon …_ line that the same lint regex accepts. Reading maps name the skill (invoice-client), not the version, so bumping the skill does not force edits across every client file — the same facts-vs-skills split as in the LLM wiki template.

This body line is skill versioning Claude practice in the template. It is not a documented frontmatter field in Anthropic’s Agent Skills format.

One version for the set: plugin.json

Claude Code plugins use a manifest at .claude-plugin/plugin.json. The plugins overview describes that file as giving the plugin its name and optional metadata. The plugins reference documents an optional version string: setting it keeps users on that version until you change it (Claude Code does not enforce SemVer on the string).

The template’s manifest (checked on main, version 0.2.0 at time of writing):

{
  "name": "memory",
  "description": "Skills that work on this knowledge base, versioned alongside the facts they read",
  "version": "0.2.0"
}

Source: .claude-plugin/plugin.json. One plugin version for the whole set; each skill still shows its own version on its second line, as CHANGELOG.md states.

Keeping the always-on rules file short is a separate problem — CLAUDE.md too long — but versioned skills belong with procedures, not in that always-on file.

Generating the changelog from git

The template’s CHANGELOG.md uses Keep a Changelog and SemVer. It says: collect under [Unreleased]; cut a version when you link the skills somewhere new or share them.

Honest split: in my knowledge base I draft changelog entries from git history. The public template does not ship a git-based changelog generator or a pre-commit hook — only CHANGELOG.md for you to maintain and scripts/lint.py for warnings. Treat the next command as a suggestion for drafting, not a template feature:

# Suggestion: list commits that touched one skill since the last tag
git log --oneline "$(git describe --tags --abbrev=0 2>/dev/null || echo HEAD~20)"..HEAD -- skills/ingest/

Copy the useful lines under [Unreleased], rewrite them as Added / Changed / Fixed, bump the skill’s version line, and when you cut a release, move the block under ## [x.y.z] - YYYY-MM-DD and bump plugin.json. That is how I keep a Claude Code changelog skill history readable without inventing release notes.

A lint check that flags unversioned skills

Run:

python3 scripts/lint.py

Verified behaviour in scripts/lint.py on main:

  • WARN if a skills/*/SKILL.md (or enkel/skills/*/SKILL.md) has no _Version …_ / _Versjon …_ line in the first few lines after the frontmatter.
  • WARN if .claude-plugin/plugin.json has a "version" that has no matching ## [that-version] section in CHANGELOG.md.
  • Warnings alone exit 0; only ERROR-level findings (broken links, oversized index, and similar) exit 1. Lint does not block commits by itself.

Optional: wire the script into a pre-commit hook if you want the warning in your face every commit. Example hook body (optional — not shipped by the template):

#!/usr/bin/env bash
# optional: .git/hooks/pre-commit
python3 scripts/lint.py

Make it executable with chmod +x .git/hooks/pre-commit. In my own knowledge base I run lint before every commit; the public scaffold leaves that choice to you. The same “automate the check” idea sits next to the ingest loop in Claude Code automation.

When to bump patch, minor or major

From the template CHANGELOG.md, aligned with SemVer and Keep a Changelog:

ChangeBump
New skill, or new behaviour in an existing skillMINOR
Fix or wording onlyPATCH
Removed or renamed skillMAJOR

Collect under [Unreleased]. Cut a version when you link the skills somewhere new or share them. Bump the skill’s own line when that skill changes; bump plugin.json when you cut the set. That is the whole Claude Code skills update policy the template documents — no extra ceremony.

Where this fits in the series

  1. Architecture: five-layer Claude Code memory system (March).
  2. Measured failures: 7 lessons from the October 2026 audit — including the skills-with-a-version row (30 of 64 to all 64) this post expands.
  3. Always-on rules: CLAUDE.md too long.
  4. Auto-memory load window: Claude Code auto memory not working?.
  5. Template product page: free LLM wiki template for Claude Code.
  6. This post: Claude Code skill versioning — version lines, plugin version, changelog, lint, bump rules.

👉 Use this template on GitHub — Use this template, make it private, run /setup.

If you write a lot of skill instructions by voice into the terminal, Wispr Flow’s free plan is the dictation path I compared with Claude Code /voice in Claude Code /voice vs Wispr Flow.

Subscribe below if you want template updates and later series posts by email.

FAQ: Claude Code skill versioning

Do Claude Code skills have a version field?

Anthropic’s Agent Skills overview and best practices require name and description in SKILL.md frontmatter. They do not document a version field in that frontmatter. For Claude Code plugins, plugin.json supports an optional version string for the plugin as a whole. In the personal-memory template, each skill also carries a body line such as _Version 0.1.0 · …_ after the frontmatter.

How do I do agent skills versioning in a repo?

Put a version line on the second content line of each SKILL.md, keep one plugin version in .claude-plugin/plugin.json, and record changes in CHANGELOG.md (Keep a Changelog + SemVer). Draft entries from git log for the skill folder if that helps; the public template does not ship a git-based changelog generator.

What does skill versioning Claude Code lint check?

In the template, scripts/lint.py WARNs when a skill has no version line after the frontmatter, and when the plugin version has no matching ## [x.y.z] section in CHANGELOG.md. Those are warnings (exit 0 if there are no ERROR-level findings). The template does not ship a pre-commit hook.

How should I handle a Claude Code changelog skill bump?

Follow the template’s bump rules: new skill or new behaviour → MINOR; fix or wording → PATCH; removed or renamed skill → MAJOR. Collect under [Unreleased], then cut a version when you link the skills somewhere new or share them. See CHANGELOG.md.

How do I keep Claude Code skills update history honest?

Version the file that changed, write what changed in the changelog, and run python3 scripts/lint.py so missing skill versions and a missing plugin changelog section show up as warnings. Do not invent release notes; draft from git log --oneline -- skills/ingest/ (swap the folder) since the last tag if you need a starting list.

Built by me · Open SourcePersonal Memory TemplateFree LLM Wiki for Claude CodeSee how it works →

Stay in the loop

Productivity tips, tool reviews and early access to new products, straight to your inbox.