chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,259 @@
|
||||
# CC Plugin Forge
|
||||
|
||||
A comprehensive skill for building and managing Claude Code plugins with proper structure, manifests, and marketplace integration.
|
||||
|
||||
## Purpose
|
||||
|
||||
Plugin Forge streamlines the entire lifecycle of Claude Code plugin development. It provides automation scripts, reference documentation, and structured workflows to help you create professional-quality plugins that integrate seamlessly with the Claude Code plugin ecosystem.
|
||||
|
||||
Whether you're building a framework-specific plugin for React or Vue, a utility plugin for common tasks, or a domain-specific knowledge plugin, Plugin Forge guides you through the correct structure and patterns.
|
||||
|
||||
## When to Use
|
||||
|
||||
Use this skill when you need to:
|
||||
|
||||
- **Create new plugins** - "Create a new Claude Code plugin for my project"
|
||||
- **Add plugin components** - "Add a new command to my plugin", "Create a skill for this plugin"
|
||||
- **Manage versions** - "Bump the plugin version", "Update plugin to 2.0.0"
|
||||
- **Work with manifests** - "Update plugin.json", "Register plugin in marketplace"
|
||||
- **Set up local testing** - "Test my plugin locally", "Install plugin for development"
|
||||
- **Publish plugins** - "Publish plugin to marketplace", "Distribute my plugin"
|
||||
|
||||
**Trigger phrases:**
|
||||
- "Create a Claude Code plugin"
|
||||
- "Build a plugin for marketplace"
|
||||
- "Add command/skill/agent/hook to plugin"
|
||||
- "Bump plugin version"
|
||||
- "Update plugin.json"
|
||||
- "Set up plugin testing"
|
||||
|
||||
## How It Works
|
||||
|
||||
### Plugin Creation Flow
|
||||
|
||||
1. **Scaffold Structure** - The `create_plugin.py` script generates the correct directory hierarchy with all required files
|
||||
2. **Generate Manifests** - Creates `plugin.json` with metadata and updates `marketplace.json` with the plugin entry
|
||||
3. **Create Templates** - Generates a README template for your plugin documentation
|
||||
4. **Guide Next Steps** - Provides instructions for adding components and testing
|
||||
|
||||
### Version Management Flow
|
||||
|
||||
1. **Parse Current Version** - Reads version from `plugin.json`
|
||||
2. **Calculate New Version** - Applies semantic versioning rules (major/minor/patch)
|
||||
3. **Sync Both Manifests** - Updates version in both `plugin.json` and `marketplace.json`
|
||||
4. **Confirm Success** - Reports the version change
|
||||
|
||||
## Key Features
|
||||
|
||||
### Automation Scripts
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
| `create_plugin.py` | Scaffold new plugins with complete structure and manifests |
|
||||
| `bump_version.py` | Update versions across all manifest files consistently |
|
||||
|
||||
### Reference Documentation
|
||||
|
||||
| Document | Content |
|
||||
|----------|---------|
|
||||
| `plugin-structure.md` | Directory hierarchy, manifest schema, component types |
|
||||
| `marketplace-schema.md` | Marketplace format, plugin entries, source specifications |
|
||||
| `workflows.md` | Development workflows, testing patterns, publishing guide |
|
||||
|
||||
### Plugin Patterns
|
||||
|
||||
- **Framework Plugin** - For framework-specific guidance (React, Vue, Nuxt)
|
||||
- **Utility Plugin** - For tools and command collections
|
||||
- **Domain Plugin** - For domain-specific knowledge with scripts
|
||||
|
||||
### Component Support
|
||||
|
||||
| Component | Location | Format |
|
||||
|-----------|----------|--------|
|
||||
| Commands | `commands/` | Markdown with frontmatter |
|
||||
| Skills | `skills/<name>/` | Directory with `SKILL.md` |
|
||||
| Agents | `agents/` | Markdown definitions |
|
||||
| Hooks | `hooks/hooks.json` | Event handlers |
|
||||
| MCP Servers | `.mcp.json` | External integrations |
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Create a New Plugin
|
||||
|
||||
```bash
|
||||
python scripts/create_plugin.py my-awesome-plugin \
|
||||
--marketplace-root /path/to/marketplace \
|
||||
--author-name "Your Name" \
|
||||
--author-email "you@example.com" \
|
||||
--description "A plugin that does awesome things" \
|
||||
--keywords "awesome,utility,productivity" \
|
||||
--category "productivity"
|
||||
```
|
||||
|
||||
This creates:
|
||||
```
|
||||
plugins/my-awesome-plugin/
|
||||
├── .claude-plugin/
|
||||
│ └── plugin.json
|
||||
├── commands/
|
||||
├── skills/
|
||||
└── README.md
|
||||
```
|
||||
|
||||
### Bump Version
|
||||
|
||||
```bash
|
||||
# Patch bump (bug fixes): 1.0.0 → 1.0.1
|
||||
python scripts/bump_version.py my-plugin patch --marketplace-root /path/to/marketplace
|
||||
|
||||
# Minor bump (new features): 1.0.0 → 1.1.0
|
||||
python scripts/bump_version.py my-plugin minor --marketplace-root /path/to/marketplace
|
||||
|
||||
# Major bump (breaking changes): 1.0.0 → 2.0.0
|
||||
python scripts/bump_version.py my-plugin major --marketplace-root /path/to/marketplace
|
||||
```
|
||||
|
||||
### Local Testing
|
||||
|
||||
```bash
|
||||
# Add your marketplace
|
||||
/plugin marketplace add /path/to/marketplace-root
|
||||
|
||||
# Install the plugin
|
||||
/plugin install my-plugin@marketplace-name
|
||||
|
||||
# After making changes, reinstall
|
||||
/plugin uninstall my-plugin@marketplace-name
|
||||
/plugin install my-plugin@marketplace-name
|
||||
```
|
||||
|
||||
### Create Command with Namespace
|
||||
|
||||
Create `commands/docs/generate.md` to get `/docs:generate` command:
|
||||
|
||||
```markdown
|
||||
---
|
||||
description: Generate documentation for the current project
|
||||
---
|
||||
|
||||
# Generate Documentation
|
||||
|
||||
Instructions for the command...
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- **Python 3.10+** - Required for running automation scripts
|
||||
- **Existing Marketplace** - A marketplace with `.claude-plugin/marketplace.json` must exist before creating plugins
|
||||
- **Claude Code** - For testing and using plugins
|
||||
|
||||
## Output
|
||||
|
||||
### create_plugin.py Output
|
||||
|
||||
```
|
||||
✅ Created plugin manifest: plugins/my-plugin/.claude-plugin/plugin.json
|
||||
✅ Created README: plugins/my-plugin/README.md
|
||||
✅ Updated marketplace manifest: .claude-plugin/marketplace.json
|
||||
|
||||
🎉 Plugin 'my-plugin' created successfully!
|
||||
|
||||
Next steps:
|
||||
1. Add commands to: plugins/my-plugin/commands
|
||||
2. Add skills to: plugins/my-plugin/skills
|
||||
3. Test with: /plugin install my-plugin@marketplace-name
|
||||
```
|
||||
|
||||
### bump_version.py Output
|
||||
|
||||
```
|
||||
✅ Updated plugin.json: 1.0.0 → 1.1.0
|
||||
✅ Updated marketplace.json: 1.0.0 → 1.1.0
|
||||
|
||||
🎉 Version bumped successfully: 1.0.0 → 1.1.0
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Naming Conventions
|
||||
|
||||
- **Plugin names**: Use `kebab-case` (e.g., `vue-components`, `api-testing`)
|
||||
- **Command files**: Use `kebab-case.md` (e.g., `generate-docs.md`)
|
||||
- **Command namespaces**: Use subdirectories for grouping (e.g., `commands/prime/vue.md` becomes `/prime:vue`)
|
||||
|
||||
### Version Management
|
||||
|
||||
- Always use semantic versioning
|
||||
- **Major (x.0.0)**: Breaking changes that require user action
|
||||
- **Minor (0.x.0)**: New features, significant refactoring
|
||||
- **Patch (0.0.x)**: Bug fixes, documentation updates
|
||||
- Always bump versions in both `plugin.json` and `marketplace.json` - use `bump_version.py` to automate this
|
||||
|
||||
### Plugin Structure
|
||||
|
||||
- Keep the plugin manifest in `.claude-plugin/plugin.json` (required location)
|
||||
- Place components at the plugin root, not inside `.claude-plugin/`
|
||||
- Use `${CLAUDE_PLUGIN_ROOT}` for dynamic path resolution in hooks and MCP configs
|
||||
|
||||
### Git Commits
|
||||
|
||||
Use conventional commits for clear history:
|
||||
```bash
|
||||
git commit -m "feat: add new plugin"
|
||||
git commit -m "fix: correct plugin manifest"
|
||||
git commit -m "docs: update plugin README"
|
||||
git commit -m "feat!: breaking change"
|
||||
```
|
||||
|
||||
### Testing
|
||||
|
||||
- Always test locally before publishing
|
||||
- Restart Claude Code after reinstalling to ensure changes take effect
|
||||
- Claude Code caches plugin files, so reinstallation is needed for updates
|
||||
|
||||
## Plugin Directory Structure Reference
|
||||
|
||||
```
|
||||
plugin-name/
|
||||
├── .claude-plugin/
|
||||
│ └── plugin.json # Required: Plugin metadata manifest
|
||||
├── commands/ # Optional: Custom slash commands
|
||||
│ ├── simple.md # → /simple
|
||||
│ └── namespace/
|
||||
│ └── action.md # → /namespace:action
|
||||
├── agents/ # Optional: Agent definitions
|
||||
├── skills/ # Optional: Agent Skills
|
||||
│ └── skill-name/
|
||||
│ ├── SKILL.md # Required for each skill
|
||||
│ ├── scripts/ # Optional: Executable code
|
||||
│ ├── references/ # Optional: Documentation
|
||||
│ └── assets/ # Optional: Output files
|
||||
├── hooks/ # Optional: Event handlers
|
||||
│ └── hooks.json
|
||||
├── .mcp.json # Optional: MCP server integrations
|
||||
└── README.md # Recommended: Plugin documentation
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Plugin directory already exists
|
||||
|
||||
The `create_plugin.py` script will not overwrite existing plugins. Either:
|
||||
- Delete the existing directory if you want to start fresh
|
||||
- Manually update the existing plugin
|
||||
|
||||
### Plugin not found in marketplace manifest
|
||||
|
||||
When using `bump_version.py`, ensure:
|
||||
- The plugin name matches exactly (case-sensitive)
|
||||
- The plugin entry exists in `.claude-plugin/marketplace.json`
|
||||
|
||||
### Changes not taking effect after reinstall
|
||||
|
||||
Claude Code caches plugin files. After reinstalling:
|
||||
1. Restart Claude Code completely
|
||||
2. Verify the plugin is listed with `/plugin list`
|
||||
|
||||
### Marketplace manifest not found
|
||||
|
||||
Ensure you're running scripts from the correct directory or provide the full path with `--marketplace-root`.
|
||||
@@ -0,0 +1,224 @@
|
||||
---
|
||||
name: plugin-forge
|
||||
description: Create and manage Claude Code plugins with proper structure, manifests, and marketplace integration. Use when creating plugins for a marketplace, adding plugin components (commands, agents, hooks), bumping plugin versions, or working with plugin.json/marketplace.json manifests.
|
||||
---
|
||||
|
||||
# CC Plugin Forge
|
||||
|
||||
## Purpose
|
||||
|
||||
Build and manage Claude Code plugins with correct structure, manifests, and marketplace integration. Includes workflows, automation scripts, and reference docs.
|
||||
|
||||
## When to Use
|
||||
|
||||
- Creating new plugins for a marketplace
|
||||
- Adding/modifying plugin components (commands, skills, agents, hooks)
|
||||
- Updating plugin versions
|
||||
- Working with plugin or marketplace manifests
|
||||
- Setting up local plugin testing
|
||||
- Publishing plugins
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Create New Plugin
|
||||
|
||||
Use `create_plugin.py` to generate plugin structure:
|
||||
|
||||
```bash
|
||||
python scripts/create_plugin.py plugin-name \
|
||||
--marketplace-root /path/to/marketplace \
|
||||
--author-name "Your Name" \
|
||||
--author-email "your.email@example.com" \
|
||||
--description "Plugin description" \
|
||||
--keywords "keyword1,keyword2" \
|
||||
--category "productivity"
|
||||
```
|
||||
|
||||
This automatically:
|
||||
|
||||
- Creates plugin directory structure
|
||||
- Generates `plugin.json` manifest
|
||||
- Creates README template
|
||||
- Updates `marketplace.json`
|
||||
|
||||
### Bump Version
|
||||
|
||||
Use `bump_version.py` to update versions in both manifests:
|
||||
|
||||
```bash
|
||||
python scripts/bump_version.py plugin-name major|minor|patch \
|
||||
--marketplace-root /path/to/marketplace
|
||||
```
|
||||
|
||||
Semantic versioning:
|
||||
|
||||
- **major**: Breaking changes (1.0.0 → 2.0.0)
|
||||
- **minor**: New features, refactoring (1.0.0 → 1.1.0)
|
||||
- **patch**: Bug fixes, docs (1.0.0 → 1.0.1)
|
||||
|
||||
## Development Workflow
|
||||
|
||||
### 1. Create Structure
|
||||
|
||||
Manual approach (if not using script):
|
||||
|
||||
```bash
|
||||
mkdir -p plugins/plugin-name/.claude-plugin
|
||||
mkdir -p plugins/plugin-name/commands
|
||||
mkdir -p plugins/plugin-name/skills
|
||||
```
|
||||
|
||||
### 2. Plugin Manifest
|
||||
|
||||
File: `plugins/plugin-name/.claude-plugin/plugin.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "plugin-name",
|
||||
"version": "0.1.0",
|
||||
"description": "Plugin description",
|
||||
"author": {
|
||||
"name": "Your Name",
|
||||
"email": "your.email@example.com"
|
||||
},
|
||||
"keywords": ["keyword1", "keyword2"]
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Register in Marketplace
|
||||
|
||||
Update `.claude-plugin/marketplace.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "plugin-name",
|
||||
"source": "./plugins/plugin-name",
|
||||
"description": "Plugin description",
|
||||
"version": "0.1.0",
|
||||
"keywords": ["keyword1", "keyword2"],
|
||||
"category": "productivity"
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Add Components
|
||||
|
||||
Create in respective directories:
|
||||
|
||||
| Component | Location | Format |
|
||||
|-----------|----------|--------|
|
||||
| Commands | `commands/` | Markdown with frontmatter |
|
||||
| Skills | `skills/<name>/` | Directory with `SKILL.md` |
|
||||
| Agents | `agents/` | Markdown definitions |
|
||||
| Hooks | `hooks/hooks.json` | Event handlers |
|
||||
| MCP Servers | `.mcp.json` | External integrations |
|
||||
|
||||
### 5. Local Testing
|
||||
|
||||
```bash
|
||||
# Add marketplace
|
||||
/plugin marketplace add /path/to/marketplace-root
|
||||
|
||||
# Install plugin
|
||||
/plugin install plugin-name@marketplace-name
|
||||
|
||||
# After changes: reinstall
|
||||
/plugin uninstall plugin-name@marketplace-name
|
||||
/plugin install plugin-name@marketplace-name
|
||||
```
|
||||
|
||||
## Plugin Patterns
|
||||
|
||||
### Framework Plugin
|
||||
|
||||
For framework-specific guidance (React, Vue, etc.):
|
||||
|
||||
```
|
||||
plugins/framework-name/
|
||||
├── .claude-plugin/plugin.json
|
||||
├── skills/
|
||||
│ └── framework-name/
|
||||
│ ├── SKILL.md
|
||||
│ └── references/
|
||||
├── commands/
|
||||
│ └── prime/
|
||||
│ ├── components.md
|
||||
│ └── framework.md
|
||||
└── README.md
|
||||
```
|
||||
|
||||
### Utility Plugin
|
||||
|
||||
For tools and commands:
|
||||
|
||||
```
|
||||
plugins/utility-name/
|
||||
├── .claude-plugin/plugin.json
|
||||
├── commands/
|
||||
│ ├── action1.md
|
||||
│ └── action2.md
|
||||
└── README.md
|
||||
```
|
||||
|
||||
### Domain Plugin
|
||||
|
||||
For domain-specific knowledge:
|
||||
|
||||
```
|
||||
plugins/domain-name/
|
||||
├── .claude-plugin/plugin.json
|
||||
├── skills/
|
||||
│ └── domain-name/
|
||||
│ ├── SKILL.md
|
||||
│ ├── references/
|
||||
│ └── scripts/
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Command Naming
|
||||
|
||||
Subdirectory-based namespacing with `:` separator:
|
||||
|
||||
- `commands/namespace/command.md` → `/namespace:command`
|
||||
- `commands/simple.md` → `/simple`
|
||||
|
||||
Examples:
|
||||
|
||||
- `commands/prime/vue.md` → `/prime:vue`
|
||||
- `commands/docs/generate.md` → `/docs:generate`
|
||||
|
||||
## Version Management
|
||||
|
||||
**Important:** Update version in BOTH locations:
|
||||
|
||||
1. `plugins/<name>/.claude-plugin/plugin.json`
|
||||
2. `.claude-plugin/marketplace.json`
|
||||
|
||||
Use `bump_version.py` to automate.
|
||||
|
||||
## Git Commits
|
||||
|
||||
Use conventional commits:
|
||||
|
||||
```bash
|
||||
git commit -m "feat: add new plugin"
|
||||
git commit -m "fix: correct plugin manifest"
|
||||
git commit -m "docs: update plugin README"
|
||||
git commit -m "feat!: breaking change"
|
||||
```
|
||||
|
||||
## Reference Docs
|
||||
|
||||
Detailed documentation included:
|
||||
|
||||
| Reference | Content |
|
||||
|-----------|---------|
|
||||
| `references/plugin-structure.md` | Directory structure, manifest schema, components |
|
||||
| `references/marketplace-schema.md` | Marketplace format, plugin entries, distribution |
|
||||
| `references/workflows.md` | Step-by-step workflows, patterns, publishing |
|
||||
|
||||
### Scripts
|
||||
|
||||
| Script | Purpose |
|
||||
|--------|---------|
|
||||
| `scripts/create_plugin.py` | Scaffold new plugin |
|
||||
| `scripts/bump_version.py` | Update versions |
|
||||
@@ -0,0 +1,132 @@
|
||||
# Marketplace Schema Reference
|
||||
|
||||
## Marketplace Structure
|
||||
|
||||
A marketplace is a JSON catalog enabling plugin discovery and distribution.
|
||||
|
||||
**File location:** `.claude-plugin/marketplace.json`
|
||||
|
||||
## Required Fields
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "marketplace-identifier",
|
||||
"owner": {
|
||||
"name": "Maintainer Name",
|
||||
"email": "maintainer@example.com"
|
||||
},
|
||||
"plugins": []
|
||||
}
|
||||
```
|
||||
|
||||
**name**: Kebab-case marketplace identifier
|
||||
**owner**: Maintainer contact information
|
||||
**plugins**: Array of plugin entries
|
||||
|
||||
## Optional Marketplace Fields
|
||||
|
||||
**description**: Marketplace overview text
|
||||
**version**: Release version
|
||||
**pluginRoot**: Base path for relative plugin sources
|
||||
|
||||
## Plugin Entry Schema
|
||||
|
||||
Each plugin entry in the `plugins` array:
|
||||
|
||||
**Required:**
|
||||
|
||||
- `name`: Plugin identifier (kebab-case, must match plugin.json)
|
||||
- `source`: Plugin origin specification
|
||||
|
||||
**Optional:**
|
||||
|
||||
- `description`: Plugin purpose
|
||||
- `version`: Plugin version (semantic versioning)
|
||||
- `author`: Creator information
|
||||
- `homepage`: URL
|
||||
- `repository`: URL
|
||||
- `license`: SPDX identifier
|
||||
- `keywords`: Array of search terms
|
||||
- `category`: Classification (e.g., "framework", "productivity")
|
||||
- `tags`: Additional discovery tags
|
||||
- `commands`: Path to commands directory
|
||||
- `agents`: Path to agents directory
|
||||
- `hooks`: Path to hooks configuration
|
||||
- `mcpServers`: Path to MCP configuration
|
||||
|
||||
## Source Specifications
|
||||
|
||||
### Relative Path Source
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-plugin",
|
||||
"source": "./plugins/my-plugin"
|
||||
}
|
||||
```
|
||||
|
||||
### GitHub Source
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-plugin",
|
||||
"source": {
|
||||
"source": "github",
|
||||
"repo": "owner/repo"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Generic Git Source
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "my-plugin",
|
||||
"source": {
|
||||
"source": "url",
|
||||
"url": "https://git.example.com/plugin.git"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Complete Example
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "example-marketplace",
|
||||
"description": "Example plugin marketplace",
|
||||
"version": "1.0.0",
|
||||
"owner": {
|
||||
"name": "Marketplace Owner",
|
||||
"email": "owner@example.com"
|
||||
},
|
||||
"pluginRoot": "./plugins",
|
||||
"plugins": [
|
||||
{
|
||||
"name": "example-plugin",
|
||||
"source": "./example-plugin",
|
||||
"description": "Example plugin",
|
||||
"version": "1.0.0",
|
||||
"keywords": ["example"],
|
||||
"category": "productivity"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Team Distribution
|
||||
|
||||
Configure automatic marketplace availability via `.claude/settings.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"extraKnownMarketplaces": [
|
||||
{
|
||||
"source": {
|
||||
"source": "github",
|
||||
"repo": "company/marketplace"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,103 @@
|
||||
# Plugin Structure Reference
|
||||
|
||||
## Directory Hierarchy
|
||||
|
||||
```
|
||||
plugin-name/
|
||||
├── .claude-plugin/
|
||||
│ └── plugin.json # Required: Plugin metadata manifest
|
||||
├── commands/ # Optional: Custom slash commands
|
||||
├── agents/ # Optional: Agent definitions
|
||||
├── skills/ # Optional: Agent Skills
|
||||
│ └── skill-name/
|
||||
│ ├── SKILL.md # Required for each skill
|
||||
│ ├── scripts/ # Optional: Executable code
|
||||
│ ├── references/ # Optional: Documentation
|
||||
│ └── assets/ # Optional: Output files
|
||||
├── hooks/ # Optional: Event handlers
|
||||
│ └── hooks.json
|
||||
└── .mcp.json # Optional: MCP server integrations
|
||||
```
|
||||
|
||||
## Plugin Manifest (`plugin.json`)
|
||||
|
||||
**Location:** `.claude-plugin/plugin.json` (must be in this directory)
|
||||
|
||||
**Required fields:**
|
||||
|
||||
- `name`: Unique identifier (kebab-case)
|
||||
|
||||
**Standard metadata:**
|
||||
|
||||
- `version`: Semantic versioning (e.g., "1.0.0")
|
||||
- `description`: Plugin purpose
|
||||
- `author`: Object with name, email, url
|
||||
- `homepage`: URL
|
||||
- `repository`: URL
|
||||
- `license`: SPDX identifier
|
||||
- `keywords`: Array of search terms
|
||||
|
||||
**Component paths (optional):**
|
||||
|
||||
- `commands`: Path to commands directory
|
||||
- `agents`: Path to agents directory
|
||||
- `hooks`: Path to hooks configuration
|
||||
- `mcpServers`: Path to MCP configuration
|
||||
|
||||
### Example plugin.json
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "example-plugin",
|
||||
"version": "1.0.0",
|
||||
"description": "Example plugin for demonstration",
|
||||
"author": {
|
||||
"name": "Plugin Creator",
|
||||
"email": "creator@example.com"
|
||||
},
|
||||
"keywords": ["example", "demo"]
|
||||
}
|
||||
```
|
||||
|
||||
## Component Types
|
||||
|
||||
### Commands
|
||||
|
||||
**Location:** `commands/` directory
|
||||
**Format:** Markdown files with frontmatter
|
||||
**Naming:** Subdirectories create namespaces via `:`
|
||||
|
||||
```
|
||||
commands/
|
||||
├── simple.md # Invoked as /simple
|
||||
└── namespace/
|
||||
└── command.md # Invoked as /namespace:command
|
||||
```
|
||||
|
||||
### Agents
|
||||
|
||||
**Location:** `agents/` directory
|
||||
**Format:** Markdown files describing agent capabilities
|
||||
|
||||
### Skills
|
||||
|
||||
**Location:** `skills/` directory
|
||||
**Format:** Subdirectories with `SKILL.md` file
|
||||
**Structure:** See skills documentation
|
||||
|
||||
### Hooks
|
||||
|
||||
**Location:** `hooks/hooks.json` or path specified in manifest
|
||||
**Events:** PreToolUse, PostToolUse, UserPromptSubmit, Notification, Stop, SubagentStop, SessionStart, SessionEnd, PreCompact
|
||||
|
||||
### MCP Servers
|
||||
|
||||
**Location:** `.mcp.json` at plugin root
|
||||
**Purpose:** External tool integrations
|
||||
|
||||
## Path Requirements
|
||||
|
||||
- All paths relative to plugin root
|
||||
- Start with `./` for custom paths
|
||||
- Use `${CLAUDE_PLUGIN_ROOT}` for dynamic resolution in hooks/MCP
|
||||
- Components must be at plugin root, not inside `.claude-plugin/`
|
||||
@@ -0,0 +1,191 @@
|
||||
# Plugin Development Workflows
|
||||
|
||||
## Creating a New Plugin
|
||||
|
||||
### 1. Create Plugin Directory Structure
|
||||
|
||||
```bash
|
||||
mkdir -p plugins/plugin-name/.claude-plugin
|
||||
mkdir -p plugins/plugin-name/commands
|
||||
mkdir -p plugins/plugin-name/skills
|
||||
```
|
||||
|
||||
### 2. Create Plugin Manifest
|
||||
|
||||
Create `plugins/plugin-name/.claude-plugin/plugin.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "plugin-name",
|
||||
"version": "0.1.0",
|
||||
"description": "Plugin description",
|
||||
"author": {
|
||||
"name": "Your Name",
|
||||
"email": "your.email@example.com"
|
||||
},
|
||||
"keywords": ["keyword1", "keyword2"]
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Add Plugin to Marketplace
|
||||
|
||||
Update `.claude-plugin/marketplace.json` by adding entry to `plugins` array:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "plugin-name",
|
||||
"source": "./plugins/plugin-name",
|
||||
"description": "Plugin description",
|
||||
"version": "0.1.0",
|
||||
"keywords": ["keyword1", "keyword2"],
|
||||
"category": "productivity"
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Add Plugin Components
|
||||
|
||||
Create commands, skills, agents, or hooks as needed in their respective directories.
|
||||
|
||||
## Version Bumping
|
||||
|
||||
When making changes to a plugin, update version in **both** locations:
|
||||
|
||||
1. `plugins/<plugin-name>/.claude-plugin/plugin.json`
|
||||
2. `.claude-plugin/marketplace.json` (matching plugin entry)
|
||||
|
||||
**Semantic versioning:**
|
||||
|
||||
- **Major (x.0.0)**: Breaking changes
|
||||
- **Minor (0.x.0)**: New features, refactoring
|
||||
- **Patch (0.0.x)**: Bug fixes, documentation only
|
||||
|
||||
## Local Testing Workflow
|
||||
|
||||
### Initial Setup
|
||||
|
||||
```bash
|
||||
# Add marketplace
|
||||
/plugin marketplace add /path/to/marketplace-root
|
||||
|
||||
# Install plugin
|
||||
/plugin install plugin-name@marketplace-name
|
||||
```
|
||||
|
||||
### Iterative Testing
|
||||
|
||||
After making changes to a plugin:
|
||||
|
||||
```bash
|
||||
# Uninstall
|
||||
/plugin uninstall plugin-name@marketplace-name
|
||||
|
||||
# Reinstall
|
||||
/plugin install plugin-name@marketplace-name
|
||||
|
||||
# Restart Claude Code to load changes
|
||||
```
|
||||
|
||||
**Note:** Claude Code caches plugin files, so restart may be required for changes to take effect.
|
||||
|
||||
## Publishing Workflow
|
||||
|
||||
### 1. Commit Changes
|
||||
|
||||
Use conventional commits:
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "feat: add new plugin"
|
||||
git commit -m "fix: correct plugin manifest"
|
||||
git commit -m "docs: update plugin README"
|
||||
```
|
||||
|
||||
### 2. Push to Repository
|
||||
|
||||
```bash
|
||||
git push origin main
|
||||
```
|
||||
|
||||
### 3. Distribution
|
||||
|
||||
**GitHub-hosted marketplace:**
|
||||
|
||||
Users add via:
|
||||
|
||||
```bash
|
||||
/plugin marketplace add owner/repo
|
||||
/plugin install plugin-name@marketplace-name
|
||||
```
|
||||
|
||||
**Local marketplace:**
|
||||
|
||||
Users add via absolute path:
|
||||
|
||||
```bash
|
||||
/plugin marketplace add /path/to/marketplace
|
||||
```
|
||||
|
||||
## Command Naming Convention
|
||||
|
||||
Commands use subdirectory-based namespacing:
|
||||
|
||||
- File: `commands/namespace/command.md`
|
||||
- Invoked as: `/namespace:command`
|
||||
- The `:` represents directory separator `/`
|
||||
|
||||
**Examples:**
|
||||
|
||||
- `commands/prime/vue.md` → `/prime:vue`
|
||||
- `commands/docs/generate.md` → `/docs:generate`
|
||||
- `commands/simple.md` → `/simple`
|
||||
|
||||
## Common Plugin Patterns
|
||||
|
||||
### Framework Plugin
|
||||
|
||||
Structure for framework-specific guidance (React, Vue, Nuxt, etc.):
|
||||
|
||||
```
|
||||
plugins/framework-name/
|
||||
├── .claude-plugin/plugin.json
|
||||
├── skills/
|
||||
│ └── framework-name/
|
||||
│ ├── SKILL.md # Quick reference
|
||||
│ └── references/ # Library-specific patterns
|
||||
├── commands/
|
||||
│ └── prime/ # Namespace for loading patterns
|
||||
│ ├── components.md
|
||||
│ └── framework.md
|
||||
└── README.md
|
||||
```
|
||||
|
||||
### Utility Plugin
|
||||
|
||||
Structure for tools and utilities:
|
||||
|
||||
```
|
||||
plugins/utility-name/
|
||||
├── .claude-plugin/plugin.json
|
||||
├── commands/
|
||||
│ ├── action1.md
|
||||
│ └── action2.md
|
||||
└── README.md
|
||||
```
|
||||
|
||||
### Domain Plugin
|
||||
|
||||
Structure for domain-specific knowledge:
|
||||
|
||||
```
|
||||
plugins/domain-name/
|
||||
├── .claude-plugin/plugin.json
|
||||
├── skills/
|
||||
│ └── domain-name/
|
||||
│ ├── SKILL.md
|
||||
│ ├── references/
|
||||
│ │ ├── schema.md
|
||||
│ │ └── policies.md
|
||||
│ └── scripts/
|
||||
│ └── automation.py
|
||||
└── README.md
|
||||
```
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Bump plugin version in both plugin.json and marketplace.json.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Literal
|
||||
|
||||
|
||||
VersionPart = Literal["major", "minor", "patch"]
|
||||
|
||||
|
||||
def parse_version(version: str) -> tuple[int, int, int]:
|
||||
"""Parse semantic version string into tuple."""
|
||||
try:
|
||||
parts = version.split(".")
|
||||
return int(parts[0]), int(parts[1]), int(parts[2])
|
||||
except (ValueError, IndexError):
|
||||
print(f"❌ Invalid version format: {version}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def bump_version(version: str, part: VersionPart) -> str:
|
||||
"""Bump semantic version."""
|
||||
major, minor, patch = parse_version(version)
|
||||
|
||||
if part == "major":
|
||||
return f"{major + 1}.0.0"
|
||||
elif part == "minor":
|
||||
return f"{major}.{minor + 1}.0"
|
||||
elif part == "patch":
|
||||
return f"{major}.{minor}.{patch + 1}"
|
||||
else:
|
||||
print(f"❌ Invalid version part: {part}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def update_plugin_version(plugin_name: str, marketplace_root: Path, part: VersionPart) -> None:
|
||||
"""Update version in both plugin.json and marketplace.json."""
|
||||
|
||||
# Update plugin.json
|
||||
plugin_json_path = marketplace_root / "plugins" / plugin_name / ".claude-plugin" / "plugin.json"
|
||||
|
||||
if not plugin_json_path.exists():
|
||||
print(f"❌ Plugin manifest not found: {plugin_json_path}")
|
||||
sys.exit(1)
|
||||
|
||||
with open(plugin_json_path, "r") as f:
|
||||
plugin_data = json.load(f)
|
||||
|
||||
old_version = plugin_data.get("version", "0.0.0")
|
||||
new_version = bump_version(old_version, part)
|
||||
plugin_data["version"] = new_version
|
||||
|
||||
with open(plugin_json_path, "w") as f:
|
||||
json.dump(plugin_data, f, indent=2)
|
||||
|
||||
print(f"✅ Updated plugin.json: {old_version} → {new_version}")
|
||||
|
||||
# Update marketplace.json
|
||||
marketplace_json_path = marketplace_root / ".claude-plugin" / "marketplace.json"
|
||||
|
||||
if not marketplace_json_path.exists():
|
||||
print(f"❌ Marketplace manifest not found: {marketplace_json_path}")
|
||||
sys.exit(1)
|
||||
|
||||
with open(marketplace_json_path, "r") as f:
|
||||
marketplace_data = json.load(f)
|
||||
|
||||
plugin_found = False
|
||||
for plugin in marketplace_data.get("plugins", []):
|
||||
if plugin.get("name") == plugin_name:
|
||||
plugin["version"] = new_version
|
||||
plugin_found = True
|
||||
break
|
||||
|
||||
if not plugin_found:
|
||||
print(f"❌ Plugin '{plugin_name}' not found in marketplace manifest")
|
||||
sys.exit(1)
|
||||
|
||||
with open(marketplace_json_path, "w") as f:
|
||||
json.dump(marketplace_data, f, indent=2)
|
||||
|
||||
print(f"✅ Updated marketplace.json: {old_version} → {new_version}")
|
||||
print(f"\n🎉 Version bumped successfully: {old_version} → {new_version}")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Bump plugin version")
|
||||
parser.add_argument("plugin_name", help="Plugin name")
|
||||
parser.add_argument("part", choices=["major", "minor", "patch"], help="Version part to bump")
|
||||
parser.add_argument("--marketplace-root", default=".", help="Path to marketplace root directory")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
marketplace_root = Path(args.marketplace_root).resolve()
|
||||
|
||||
update_plugin_version(
|
||||
plugin_name=args.plugin_name,
|
||||
marketplace_root=marketplace_root,
|
||||
part=args.part
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Create a new Claude Code plugin with proper directory structure and manifests.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def create_plugin_structure(plugin_name: str, marketplace_root: Path, author_name: str, author_email: str, description: str, keywords: list[str], category: str = "productivity") -> None:
|
||||
"""Create complete plugin directory structure with manifests."""
|
||||
|
||||
# Create plugin directory
|
||||
plugin_dir = marketplace_root / "plugins" / plugin_name
|
||||
if plugin_dir.exists():
|
||||
print(f"❌ Plugin directory already exists: {plugin_dir}")
|
||||
sys.exit(1)
|
||||
|
||||
# Create directory structure
|
||||
plugin_config_dir = plugin_dir / ".claude-plugin"
|
||||
commands_dir = plugin_dir / "commands"
|
||||
skills_dir = plugin_dir / "skills"
|
||||
|
||||
plugin_config_dir.mkdir(parents=True, exist_ok=True)
|
||||
commands_dir.mkdir(parents=True, exist_ok=True)
|
||||
skills_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create plugin.json
|
||||
plugin_manifest = {
|
||||
"name": plugin_name,
|
||||
"version": "0.1.0",
|
||||
"description": description,
|
||||
"author": {
|
||||
"name": author_name,
|
||||
"email": author_email
|
||||
},
|
||||
"keywords": keywords
|
||||
}
|
||||
|
||||
plugin_json_path = plugin_config_dir / "plugin.json"
|
||||
with open(plugin_json_path, "w") as f:
|
||||
json.dump(plugin_manifest, f, indent=2)
|
||||
|
||||
print(f"✅ Created plugin manifest: {plugin_json_path}")
|
||||
|
||||
# Create README.md
|
||||
readme_content = f"""# {plugin_name}
|
||||
|
||||
{description}
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
/plugin marketplace add <marketplace-source>
|
||||
/plugin install {plugin_name}@<marketplace-name>
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- TODO: List features here
|
||||
|
||||
## Usage
|
||||
|
||||
TODO: Add usage examples
|
||||
|
||||
## Development
|
||||
|
||||
See [workflows.md](../../CLAUDE.md) for development guidelines.
|
||||
"""
|
||||
|
||||
readme_path = plugin_dir / "README.md"
|
||||
with open(readme_path, "w") as f:
|
||||
f.write(readme_content)
|
||||
|
||||
print(f"✅ Created README: {readme_path}")
|
||||
|
||||
# Update marketplace.json
|
||||
marketplace_json_path = marketplace_root / ".claude-plugin" / "marketplace.json"
|
||||
|
||||
if not marketplace_json_path.exists():
|
||||
print(f"❌ Marketplace manifest not found: {marketplace_json_path}")
|
||||
sys.exit(1)
|
||||
|
||||
with open(marketplace_json_path, "r") as f:
|
||||
marketplace_data = json.load(f)
|
||||
|
||||
# Check if plugin already exists in marketplace
|
||||
for plugin in marketplace_data.get("plugins", []):
|
||||
if plugin.get("name") == plugin_name:
|
||||
print(f"❌ Plugin '{plugin_name}' already exists in marketplace manifest")
|
||||
sys.exit(1)
|
||||
|
||||
# Add plugin entry
|
||||
plugin_entry = {
|
||||
"name": plugin_name,
|
||||
"source": f"./plugins/{plugin_name}",
|
||||
"description": description,
|
||||
"version": "0.1.0",
|
||||
"keywords": keywords,
|
||||
"category": category
|
||||
}
|
||||
|
||||
if "plugins" not in marketplace_data:
|
||||
marketplace_data["plugins"] = []
|
||||
|
||||
marketplace_data["plugins"].append(plugin_entry)
|
||||
|
||||
with open(marketplace_json_path, "w") as f:
|
||||
json.dump(marketplace_data, f, indent=2)
|
||||
|
||||
print(f"✅ Updated marketplace manifest: {marketplace_json_path}")
|
||||
|
||||
print(f"\n🎉 Plugin '{plugin_name}' created successfully!")
|
||||
print(f"\nNext steps:")
|
||||
print(f"1. Add commands to: {commands_dir}")
|
||||
print(f"2. Add skills to: {skills_dir}")
|
||||
print(f"3. Test with: /plugin install {plugin_name}@marketplace-name")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Create a new Claude Code plugin")
|
||||
parser.add_argument("plugin_name", help="Plugin name (kebab-case)")
|
||||
parser.add_argument("--marketplace-root", default=".", help="Path to marketplace root directory")
|
||||
parser.add_argument("--author-name", required=True, help="Plugin author name")
|
||||
parser.add_argument("--author-email", required=True, help="Plugin author email")
|
||||
parser.add_argument("--description", required=True, help="Plugin description")
|
||||
parser.add_argument("--keywords", required=True, help="Comma-separated keywords")
|
||||
parser.add_argument("--category", default="productivity", help="Plugin category (default: productivity)")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
marketplace_root = Path(args.marketplace_root).resolve()
|
||||
keywords = [k.strip() for k in args.keywords.split(",")]
|
||||
|
||||
create_plugin_structure(
|
||||
plugin_name=args.plugin_name,
|
||||
marketplace_root=marketplace_root,
|
||||
author_name=args.author_name,
|
||||
author_email=args.author_email,
|
||||
description=args.description,
|
||||
keywords=keywords,
|
||||
category=args.category
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user