publish-plugins · git:20261017.cb041d1 · 2026-10-17 · sha256 5aca8775c88e285d
publish-plugins git:20261017.cb041d1A
Immutable. This exact content never changes and is served at /api/v1/blob/5aca8775c88e285d.
--- name: publish-plugins description: (project) Use when editing any file under skills/ or plugins/ to bump the plugin version and check the manifests user-invocable: true model: sonnet effort: medium allowed-tools: - Edit(**/.claude-plugin/*.json) - Bash(python3 .claude/skills/publish-plugins/scripts/check_manifest_sync.py:*) - Bash(python3 .claude/skills/publish-plugins/scripts/check_skill_descriptions_sync.py:*) - Bash(claude plugin validate:*) - Bash(claude plugin test:*) - Bash(npx -y skills@latest add . -l) metadata: internal: true --- # Publish 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 ```bash 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`: ```bash 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 ```bash 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 `version` and the directory listing fields `icon`, `documentationUrl`, `supportUrl`, `privacyPolicyUrl`, `termsOfServiceUrl` (plugin.json only) and `source`, `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 ```bash 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 ```bash 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 ```bash 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 ```bash 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`.