publish-plugins
(project) Use when editing any file under skills/ or plugins/ to bump the plugin version and check the manifests
SKILL.md.claude/skills/publish-plugins/SKILL.md
GitHubPublish Plugins
Prepare the repo's plugins for release: work out which ones changed, bump their versions, and check the manifests still describe what is on disk.
Each plugin owns its version in its own .claude-plugin/plugin.json, and the repo-root .claude-plugin/marketplace.json carries no version fields:
| Plugin | Manifest |
|---|---|
hal-skills |
skills/.claude-plugin/plugin.json |
hal-output-styles |
plugins/hal-output-styles/.claude-plugin/plugin.json |
hal-grammar-check |
plugins/hal-grammar-check/.claude-plugin/plugin.json |
hal-session-auto-rename |
plugins/hal-session-auto-rename/.claude-plugin/plugin.json |
hal-voice |
plugins/hal-voice/.claude-plugin/plugin.json |
1. Find the changed plugins
git diff --name-only origin/main...
skills/** belongs to hal-skills, plugins/<name>/** to that plugin. Only the plugins with changes are candidates for a bump.
2. Check what is already bumped
For each candidate, compare the working-tree version against origin/main:
git show origin/main:skills/.claude-plugin/plugin.json
If a plugin's version already differs from origin/main, it was bumped for unreleased work. Do not bump it again. Only bump a plugin whose version still matches origin/main. Check each candidate independently — a change under skills/ says nothing about whether hal-voice needs a bump.
3. Bump
- Patch (0.2.0 -> 0.2.1): bug fixes, config changes, style cleanup.
- Minor (0.2.0 -> 0.3.0): new features, new hooks, new commands.
- Major (0.2.0 -> 1.0.0): breaking changes to hook behavior or config format.
Commit a bump made on its own through the commit skill with no argument: its subject already says why a bump exists.
4. Check the manifests are in sync
python3 .claude/skills/publish-plugins/scripts/check_manifest_sync.py
Every plugin is described twice on purpose: once in its own .claude-plugin/plugin.json and once as an entry in .claude-plugin/marketplace.json. For each plugin the script checks that
- both describe the same fields with the same values, apart from
versionand the directory listing fieldsicon,documentationUrl,supportUrl,privacyPolicyUrl,termsOfServiceUrl(plugin.json only) andsource,category,tags,strict,defaultEnabled(marketplace entry only — Claude Code ignores them in a plugin.json). - every component path either manifest declares exists on disk.
- every skill directory in a plugin's root appears in both skill lists.
It exits non-zero naming each problem. Fix the manifests it names, then run it again.
5. Check the skill descriptions are in sync
python3 .claude/skills/publish-plugins/scripts/check_skill_descriptions_sync.py
For every skill under skills/, check that interface.short_description in agents/openai.yaml matches its description in both README.md and skills/README.md exactly. Treat the README descriptions as the source of truth. Keep descriptions as single-line double-quoted strings. Fix missing entries or mismatches, then rerun until the check passes.
6. Validate
claude plugin validate .
claude plugin validate ./skills
claude plugin validate ./plugins/hal-output-styles
claude plugin validate ./plugins/hal-grammar-check
claude plugin validate ./plugins/hal-session-auto-rename
claude plugin validate ./plugins/hal-voice
The first call validates the marketplace manifest; the rest validate each plugin manifest.
7. Run the mod tests
claude plugin test ./plugins/hal-grammar-check
claude plugin test ./plugins/hal-session-auto-rename
These two plugins are mods (hooks modules with tests/*.test.ts); make test and CI run only the Python tests. Fix the failing test or the module, then rerun until every test passes; a command that fails to start is not a pass.
8. Check the skills still group for other agents
npx -y skills@latest add . -l
This lists what npx skills add vinta/hal-9000 will offer, reading the working tree instead of the published repo, and installs nothing. Every skill has to appear under the Hal Skills heading with a count matching the skills list. A skill listed without that heading means the hal-skills marketplace entry lost its name or its skills array — that CLI reads only the two manifests at the repo root, so it never sees skills/.claude-plugin/plugin.json.