A complete, self-installing template for building a Claude Code plugin. Clone it, run scripts/init.sh, replace the example capability, and ship. This one repo is both the marketplace and the plugin.
Private repo: your
gitmust be authenticated to theSprintRay-Softwareorg (gh CLI or SSH) for the marketplace add to succeed.
/plugin marketplace add SprintRay-Software/plugin-shell
/plugin install plugin-shell@plugin-shell
/reload-plugins
After install you get one worked example of every primitive (echo/greet theme):
- Command
/shell-hello [name] - Skill
greeter - Subagent
example-agent - A
SessionStarthook that prints a load-confirmation banner - An MCP server exposing the
greet(name)tool
scripts/init.sh <plugin-name> <marketplace-name> "<description>" <owner> [--bare]
- Default keeps the examples as live reference.
--barestrips the examples, leaving emptycommands/ skills/ agents/to fill in.
Manual equivalent (if you prefer): edit name/description/author in plugin/.claude-plugin/plugin.json, name/owner/plugins[0] in .claude-plugin/marketplace.json, then find/replace plugin-shell across plugin/ and this README.
| Path | What |
|---|---|
.claude-plugin/marketplace.json | Marketplace manifest (this repo is its own marketplace). |
plugin/ | The plugin payload — only this dir is copied into the plugin cache. |
plugin/.claude-plugin/plugin.json | Plugin manifest (lean; convention over declaration). |
plugin/{commands,skills,agents,hooks,mcp} | One example of each primitive. |
scripts/validate.sh | The validation gate (zero deps beyond node). |
scripts/init.sh | Rename/personalize the template. |
.github/workflows/ | validate on PR; best-effort release tag on version bump. |
bash scripts/validate.sh
Checks manifests, frontmatter, hooks, and runs a live smoke test of the example MCP server. CI runs the same script — CI is the verdict.
Bump version in plugin/.claude-plugin/plugin.json (keep it equal to the marketplace entry — the gate enforces this). On merge to main, CI attempts claude plugin tag. Manual fallback: claude plugin tag plugin from a local checkout.
Reference bundled files with ${CLAUDE_PLUGIN_ROOT} (read-only, changes on update) and durable state with ${CLAUDE_PLUGIN_DATA}. Installed plugins are copied into a cache — never read outside the plugin dir.