Initial commit
This commit is contained in:
551
commands/add-agent.md
Normal file
551
commands/add-agent.md
Normal file
@@ -0,0 +1,551 @@
|
||||
---
|
||||
description: Add a new sub-agent to the current plugin for specialized tasks
|
||||
argument-hint: [agent-name] ["description"]
|
||||
---
|
||||
|
||||
# Add Agent
|
||||
|
||||
Create a new sub-agent file with proper frontmatter and structure.
|
||||
|
||||
## Arguments
|
||||
|
||||
- `$1` (required): Agent name in kebab-case (e.g., `code-reviewer`)
|
||||
- `$2` (optional): Description in quotes (e.g., `"Reviews code for quality"`)
|
||||
- `--plugin=<plugin-name>` (optional): Specify which plugin to add the agent to
|
||||
|
||||
**Usage:**
|
||||
```
|
||||
# From within a plugin directory, with description
|
||||
/plugin-development:add-agent code-reviewer "Reviews code for quality, security, and best practices"
|
||||
|
||||
# Without description (uses default)
|
||||
/plugin-development:add-agent code-reviewer
|
||||
|
||||
# From marketplace root, specifying plugin
|
||||
/plugin-development:add-agent code-reviewer "Reviews code for quality, security, and best practices" --plugin=plugin-development
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Must be run from either:
|
||||
- A plugin root directory (containing `.claude-plugin/plugin.json`), OR
|
||||
- A marketplace root directory (containing `.claude-plugin/marketplace.json`)
|
||||
- `agents/` directory will be created if needed
|
||||
|
||||
## Instructions
|
||||
|
||||
### Validation
|
||||
|
||||
**IMPORTANT**: When running test commands for validation (checking directories, files, etc.), use `require_user_approval: false` since these are read-only checks.
|
||||
|
||||
1. **Detect context and target plugin** (output thoughts during this process):
|
||||
|
||||
a. Check if we're in a plugin directory:
|
||||
- Look for `.claude-plugin/plugin.json` in current directory
|
||||
- **Output**: "Checking for plugin directory..."
|
||||
- If found:
|
||||
- **Output**: "Found plugin.json - using current directory as target plugin"
|
||||
- Use current directory as target plugin
|
||||
- If not found:
|
||||
- **Output**: "Not in a plugin directory, checking for marketplace..."
|
||||
|
||||
b. If not in plugin directory, check if we're in marketplace root:
|
||||
- Look for `.claude-plugin/marketplace.json` in current directory
|
||||
- If found:
|
||||
- **Output**: "Found marketplace.json - this is a marketplace root"
|
||||
- This is a marketplace root
|
||||
- If not found:
|
||||
- **Output**: "Error: Neither plugin.json nor marketplace.json found"
|
||||
- Show error and exit
|
||||
|
||||
c. If in marketplace root, determine target plugin:
|
||||
- Check if `--plugin=<name>` argument was provided
|
||||
- If yes:
|
||||
- **Output**: "Using plugin specified via --plugin argument: <name>"
|
||||
- Use specified plugin name
|
||||
- If no:
|
||||
- **Output**: "No --plugin argument provided, discovering available plugins..."
|
||||
- Discover available plugins and prompt user
|
||||
|
||||
d. **Discover available plugins** (when in marketplace root without --plugin):
|
||||
- **Output**: "Reading marketplace.json..."
|
||||
- Read `.claude-plugin/marketplace.json`
|
||||
- Extract plugin names and sources from `plugins` array
|
||||
- **Output**: "Found [N] plugin(s) in marketplace"
|
||||
- Alternative: List directories in `plugins/` directory
|
||||
- Present list to user: "Which plugin should I add the agent to?"
|
||||
- Options format: `1. plugin-name-1 (description)`, `2. plugin-name-2 (description)`, etc.
|
||||
- Wait for user selection
|
||||
- **Output**: "Selected plugin: <plugin-name>"
|
||||
|
||||
e. **Validate target plugin exists**:
|
||||
- **Output**: "Validating plugin '<plugin-name>' exists..."
|
||||
- If plugin specified/selected, verify `plugins/<plugin-name>/.claude-plugin/plugin.json` exists
|
||||
- If found:
|
||||
- **Output**: "Plugin '<plugin-name>' validated successfully"
|
||||
- If not found:
|
||||
- **Output**: "Error: Plugin '<plugin-name>' not found"
|
||||
- Show error: "Plugin '<plugin-name>' not found. Available plugins: [list]"
|
||||
|
||||
f. If neither plugin.json nor marketplace.json found:
|
||||
- Show error: "Not in a plugin or marketplace directory. Please run from a plugin root or marketplace root."
|
||||
|
||||
2. **Validate arguments**:
|
||||
- `$1` (agent name): Not empty, kebab-case format (lowercase with hyphens), no spaces or special characters
|
||||
- `$2` (description): Optional. If not provided, use default: "Specialized agent for $1 tasks"
|
||||
|
||||
3. **Set working directory**:
|
||||
- If in plugin directory: Use current directory
|
||||
- If in marketplace root: Use `plugins/<plugin-name>/` as working directory
|
||||
|
||||
### Create Agent File
|
||||
|
||||
**Note**: All paths below are relative to the target plugin directory (determined in validation step).
|
||||
|
||||
1. Ensure `agents/` directory exists in target plugin:
|
||||
- Check if `<plugin-dir>/agents/` directory exists
|
||||
- If it doesn't exist, create it (use `require_user_approval: false` for directory creation)
|
||||
2. Create `<plugin-dir>/agents/$1.md` with this template:
|
||||
|
||||
```markdown
|
||||
---
|
||||
description: $2
|
||||
capabilities: ["capability-1", "capability-2", "capability-3"]
|
||||
---
|
||||
|
||||
# $1 Agent
|
||||
|
||||
[Brief introduction explaining the agent's purpose and specialization]
|
||||
|
||||
## Purpose
|
||||
|
||||
[Detailed description of what this agent does and why it exists]
|
||||
|
||||
## What This Agent Does
|
||||
|
||||
This agent specializes in:
|
||||
- [Specialization 1]
|
||||
- [Specialization 2]
|
||||
- [Specialization 3]
|
||||
|
||||
## Capabilities
|
||||
|
||||
1. **Capability 1**: [Description of first capability]
|
||||
2. **Capability 2**: [Description of second capability]
|
||||
3. **Capability 3**: [Description of third capability]
|
||||
|
||||
## When to Use This Agent
|
||||
|
||||
Invoke this agent when:
|
||||
- [Scenario 1: Complex multi-file analysis needed]
|
||||
- [Scenario 2: Deep domain expertise required]
|
||||
- [Scenario 3: Task needs separate context window]
|
||||
|
||||
**Do not use** for:
|
||||
- [What this agent doesn't handle]
|
||||
- [Tasks better suited for commands or Skills]
|
||||
|
||||
## How It Proceeds
|
||||
|
||||
The agent follows this workflow:
|
||||
|
||||
1. **Gather Context**: [What files/information it reads]
|
||||
2. **Analyze**: [How it evaluates the situation]
|
||||
3. **Identify Issues**: [What it looks for]
|
||||
4. **Formulate Recommendations**: [What guidance it provides]
|
||||
5. **Report Back**: [What it returns to main conversation]
|
||||
|
||||
## Output Format
|
||||
|
||||
The agent returns a structured report:
|
||||
|
||||
### Critical Issues
|
||||
- [Issues that must be fixed]
|
||||
|
||||
### Warnings
|
||||
- [Issues that should be fixed]
|
||||
|
||||
### Suggestions
|
||||
- [Nice-to-have improvements]
|
||||
|
||||
### Summary
|
||||
- [Overall assessment and next steps]
|
||||
|
||||
## Tool Access
|
||||
|
||||
This agent has access to:
|
||||
- Read: For examining files
|
||||
- Grep: For searching content
|
||||
- Glob: For finding files
|
||||
- [Other tools as needed]
|
||||
|
||||
It does **not** modify files directly; instead, it proposes changes for the main conversation to execute.
|
||||
|
||||
## Example Invocation
|
||||
|
||||
**From main conversation**:
|
||||
```
|
||||
/agents $1
|
||||
```
|
||||
|
||||
or via Task tool:
|
||||
```
|
||||
Use the $1 agent to [specific task]
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- Agents operate in a **separate context window**
|
||||
- Results are returned as a single message
|
||||
- Use for complex, multi-step analysis tasks
|
||||
- Keep scope focused to 1-3 specific capabilities
|
||||
```
|
||||
|
||||
### Update plugin.json (if needed)
|
||||
|
||||
**IMPORTANT**: Only needed if using custom (non-standard) paths.
|
||||
|
||||
- **Standard setup** (agents in `agents/` directory): No changes to `plugin.json` needed
|
||||
- **Custom paths**: Add `"agents": ["./agents/$1.md"]` (or update existing agents array)
|
||||
|
||||
### Provide Feedback
|
||||
|
||||
After creating the agent:
|
||||
|
||||
```
|
||||
✓ Created <plugin-name>/agents/$1.md
|
||||
|
||||
Plugin: <plugin-name>
|
||||
Agent: $1
|
||||
Description: $2
|
||||
|
||||
Next steps:
|
||||
1. Edit <plugin-name>/agents/$1.md with specific instructions
|
||||
2. Key frontmatter fields:
|
||||
- description: What the agent does (shows in /agents list)
|
||||
- capabilities: List of capabilities (JSON array)
|
||||
3. Define clear workflow steps
|
||||
4. Specify what the agent returns
|
||||
5. Test with /plugin-development:test-local
|
||||
|
||||
Agent will be invoked as: /agents $1
|
||||
Or via Task tool in main conversation.
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: From Plugin Directory
|
||||
|
||||
**Context**: Currently in `/path/to/marketplace/plugins/plugin-development/`
|
||||
|
||||
**Input**:
|
||||
```
|
||||
/plugin-development:add-agent code-reviewer "Reviews code for quality, security, and best practices"
|
||||
```
|
||||
|
||||
**Arguments**:
|
||||
- `$1` = `code-reviewer`
|
||||
- `$2` = `Reviews code for quality, security, and best practices`
|
||||
|
||||
**Process**:
|
||||
1. Detects `.claude-plugin/plugin.json` in current directory
|
||||
2. Uses current directory as target plugin
|
||||
3. Creates `agents/` directory if needed
|
||||
4. Creates `agents/code-reviewer.md`
|
||||
|
||||
**Result**:
|
||||
- Creates `agents/code-reviewer.md` with template
|
||||
- Frontmatter description: "Reviews code for quality, security, and best practices"
|
||||
- Ready to customize with specific review criteria
|
||||
|
||||
### Example 2: From Marketplace Root with --plugin
|
||||
|
||||
**Context**: Currently in `/path/to/marketplace/` (marketplace root)
|
||||
|
||||
**Input**:
|
||||
```
|
||||
/plugin-development:add-agent code-reviewer "Reviews code for quality, security, and best practices" --plugin=plugin-development
|
||||
```
|
||||
|
||||
**Process**:
|
||||
1. Detects `.claude-plugin/marketplace.json` in current directory
|
||||
2. Extracts `--plugin=plugin-development` from arguments
|
||||
3. Validates `plugins/plugin-development/.claude-plugin/plugin.json` exists
|
||||
4. Uses `plugins/plugin-development/` as target
|
||||
5. Creates `plugins/plugin-development/agents/code-reviewer.md`
|
||||
|
||||
**Result**:
|
||||
- Creates `plugins/plugin-development/agents/code-reviewer.md`
|
||||
- Agent added to plugin-development plugin
|
||||
|
||||
### Example 3: From Marketplace Root without --plugin
|
||||
|
||||
**Context**: Currently in `/path/to/marketplace/` (marketplace root)
|
||||
|
||||
**Input**:
|
||||
```
|
||||
/plugin-development:add-agent code-reviewer "Reviews code for quality, security, and best practices"
|
||||
```
|
||||
|
||||
**Process**:
|
||||
1. Detects `.claude-plugin/marketplace.json` in current directory
|
||||
2. No `--plugin` argument provided
|
||||
3. Reads marketplace.json and discovers available plugins:
|
||||
- `hello-world` - A simple example plugin
|
||||
- `plugin-development` - Assist with Claude Code plugin development
|
||||
4. Prompts user: "Which plugin should I add the agent to?"
|
||||
```
|
||||
1. hello-world - A simple example plugin demonstrating basic Claude Code plugin functionality
|
||||
2. plugin-development - Assist with Claude Code plugin development: scaffold, validate, review, and team-ready distribution
|
||||
```
|
||||
5. User selects option 2
|
||||
6. Uses `plugins/plugin-development/` as target
|
||||
7. Creates `plugins/plugin-development/agents/code-reviewer.md`
|
||||
|
||||
**Result**:
|
||||
- Creates `plugins/plugin-development/agents/code-reviewer.md`
|
||||
- Agent added to selected plugin
|
||||
|
||||
## Agent Frontmatter
|
||||
|
||||
### Required Fields
|
||||
|
||||
```yaml
|
||||
---
|
||||
description: Third-person description of what this agent does
|
||||
---
|
||||
```
|
||||
|
||||
### Optional Fields
|
||||
|
||||
```yaml
|
||||
---
|
||||
description: Agent description
|
||||
capabilities: ["capability-1", "capability-2"] # List of what it can do
|
||||
---
|
||||
```
|
||||
|
||||
**For complete details on agents**, see:
|
||||
- [Subagents documentation](/en/docs/claude-code/sub-agents)
|
||||
- [Plugin agents reference](/en/docs/claude-code/plugins-reference#agents)
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Not in Plugin or Marketplace Directory
|
||||
|
||||
**Error**: "Not in a plugin or marketplace directory."
|
||||
|
||||
**Solution**: Navigate to either:
|
||||
- A plugin directory (containing `.claude-plugin/plugin.json`), OR
|
||||
- A marketplace root (containing `.claude-plugin/marketplace.json`)
|
||||
|
||||
### Plugin Not Found
|
||||
|
||||
**Error**: "Plugin 'my-plugin' not found. Available plugins: hello-world, plugin-development"
|
||||
|
||||
**Solution**:
|
||||
- Check plugin name spelling
|
||||
- Use `--plugin=<correct-name>` with one of the available plugins
|
||||
- Or navigate to the plugin directory directly
|
||||
|
||||
### Invalid Agent Name
|
||||
|
||||
**Error**: "Agent name must be in kebab-case format (lowercase with hyphens)"
|
||||
|
||||
**Solution**: Use kebab-case format:
|
||||
- ✅ Good: `code-reviewer`, `security-auditor`, `api-generator`
|
||||
- ❌ Bad: `CodeReviewer`, `code_reviewer`, `code reviewer`
|
||||
|
||||
### Missing Description
|
||||
|
||||
**Error**: "Description is required"
|
||||
|
||||
**Solution**: Provide description in quotes:
|
||||
```
|
||||
/plugin-development:add-agent code-reviewer "Reviews code for quality, security, and best practices"
|
||||
```
|
||||
|
||||
## When to Use Agents vs. Commands vs. Skills
|
||||
|
||||
### Use an Agent when:
|
||||
- Task requires **deep, multi-file analysis**
|
||||
- Need **separate context window** (complex reasoning)
|
||||
- Want **detailed, structured report** back
|
||||
- Task has **multiple steps** that benefit from isolation
|
||||
|
||||
### Use a Command when:
|
||||
- Task is **explicit, one-time action**
|
||||
- User needs to **trigger on demand**
|
||||
- Task is **straightforward** with clear inputs/outputs
|
||||
|
||||
### Use a Skill when:
|
||||
- Want **ambient, automatic activation**
|
||||
- Need **persistent guidance** throughout session
|
||||
- Task benefits from **progressive disclosure**
|
||||
- Should trigger based on **context clues**
|
||||
|
||||
## Agent Design Best Practices
|
||||
|
||||
### 1. Focused Scope
|
||||
|
||||
✅ **Good** (focused):
|
||||
```markdown
|
||||
# Code Security Auditor
|
||||
|
||||
Specializes in security analysis:
|
||||
- SQL injection vulnerabilities
|
||||
- XSS vulnerabilities
|
||||
- Authentication issues
|
||||
```
|
||||
|
||||
❌ **Bad** (too broad):
|
||||
```markdown
|
||||
# General Code Helper
|
||||
|
||||
Does everything related to code.
|
||||
```
|
||||
|
||||
### 2. Clear Capabilities
|
||||
|
||||
List 2-5 specific capabilities:
|
||||
```yaml
|
||||
capabilities: [
|
||||
"security-vulnerability-detection",
|
||||
"authentication-analysis",
|
||||
"dependency-audit"
|
||||
]
|
||||
```
|
||||
|
||||
### 3. Structured Output
|
||||
|
||||
Define consistent report format:
|
||||
```markdown
|
||||
## Critical (P0)
|
||||
- [List critical issues]
|
||||
|
||||
## High Priority (P1)
|
||||
- [List high priority issues]
|
||||
|
||||
## Suggestions
|
||||
- [List improvements]
|
||||
```
|
||||
|
||||
### 4. Tool Restrictions
|
||||
|
||||
Agents typically don't modify files:
|
||||
```markdown
|
||||
## Tool Access
|
||||
|
||||
- Read, Grep, Glob: For analysis
|
||||
- No Write/Edit: Agent proposes, main conversation executes
|
||||
```
|
||||
|
||||
## Agent Workflow Template
|
||||
|
||||
All agents should follow a consistent structure:
|
||||
|
||||
```markdown
|
||||
1. **Understand Context**: Read relevant files
|
||||
2. **Analyze**: Apply domain expertise
|
||||
3. **Identify Issues**: Find problems/opportunities
|
||||
4. **Prioritize**: Rank by severity/importance
|
||||
5. **Recommend**: Provide actionable guidance
|
||||
6. **Report**: Return structured findings
|
||||
```
|
||||
|
||||
## Common Agent Patterns
|
||||
|
||||
### Auditor Pattern
|
||||
|
||||
For review/analysis agents:
|
||||
- Reads multiple files
|
||||
- Checks against standards/criteria
|
||||
- Reports issues by severity
|
||||
- Provides specific fix recommendations
|
||||
|
||||
### Generator Pattern
|
||||
|
||||
For design/planning agents:
|
||||
- Analyzes requirements
|
||||
- Proposes architecture/approach
|
||||
- Provides implementation steps
|
||||
- Returns detailed plan
|
||||
|
||||
### Refactoring Pattern
|
||||
|
||||
For code improvement agents:
|
||||
- Analyzes existing code
|
||||
- Identifies improvement opportunities
|
||||
- Proposes refactoring steps
|
||||
- Estimates impact/effort
|
||||
|
||||
## Invocation Methods
|
||||
|
||||
### Direct Invocation
|
||||
|
||||
User explicitly calls the agent:
|
||||
```
|
||||
/agents code-reviewer
|
||||
```
|
||||
|
||||
### Via Main Conversation
|
||||
|
||||
Claude uses Task tool:
|
||||
```
|
||||
Let me use the code-reviewer agent to analyze this...
|
||||
```
|
||||
|
||||
### From Skill
|
||||
|
||||
Skill escalates to agent for deep analysis:
|
||||
```markdown
|
||||
For comprehensive review, delegate to the code-reviewer agent.
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Single responsibility**: One clear purpose
|
||||
2. **Structured output**: Consistent report format
|
||||
3. **No side effects**: Read-only, propose changes
|
||||
4. **Clear scope**: 2-5 capabilities max
|
||||
5. **Fast feedback**: Aim for < 30 seconds runtime
|
||||
6. **Actionable results**: Specific, implementable recommendations
|
||||
|
||||
## Common Mistakes to Avoid
|
||||
|
||||
❌ **Too broad scope**
|
||||
```yaml
|
||||
capabilities: ["everything", "all-tasks", "general-help"]
|
||||
```
|
||||
|
||||
✅ **Focused capabilities**
|
||||
```yaml
|
||||
capabilities: ["security-audit", "vulnerability-scan", "compliance-check"]
|
||||
```
|
||||
|
||||
❌ **Vague instructions**
|
||||
```markdown
|
||||
Analyze the code and find problems.
|
||||
```
|
||||
|
||||
✅ **Specific workflow**
|
||||
```markdown
|
||||
1. Read all .py files in src/
|
||||
2. Check for SQL injection patterns
|
||||
3. Verify authentication usage
|
||||
4. Report findings by severity
|
||||
```
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
After creating an agent:
|
||||
```
|
||||
□ Agent file created in agents/ directory
|
||||
□ Frontmatter includes description
|
||||
□ Capabilities listed (2-5 items)
|
||||
□ Clear workflow defined
|
||||
□ Output format specified
|
||||
□ Agent name is kebab-case
|
||||
□ plugin.json has agents field
|
||||
□ Purpose is focused and specific
|
||||
```
|
||||
292
commands/add-command.md
Normal file
292
commands/add-command.md
Normal file
@@ -0,0 +1,292 @@
|
||||
---
|
||||
description: Add a new slash command to the current plugin
|
||||
argument-hint: [command-name] ["description"]
|
||||
---
|
||||
|
||||
# Add Command
|
||||
|
||||
Create a new slash command file with proper frontmatter and structure.
|
||||
|
||||
## Arguments
|
||||
|
||||
- `$1` (required): Command name in kebab-case (e.g., `my-command`)
|
||||
- `$2` (optional): Description in quotes (e.g., `"Format code according to standards"`)
|
||||
- `--plugin=<plugin-name>` (optional): Specify which plugin to add the command to
|
||||
|
||||
**Usage:**
|
||||
```
|
||||
# From within a plugin directory, with description
|
||||
/plugin-development:add-command format-code "Format code according to project standards"
|
||||
|
||||
# Without description (uses default)
|
||||
/plugin-development:add-command format-code
|
||||
|
||||
# From marketplace root, specifying plugin
|
||||
/plugin-development:add-command format-code "Format code" --plugin=plugin-development
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Must be run from either:
|
||||
- A plugin root directory (containing `.claude-plugin/plugin.json`), OR
|
||||
- A marketplace root directory (containing `.claude-plugin/marketplace.json`)
|
||||
- `commands/` directory will be created if needed
|
||||
|
||||
## Instructions
|
||||
|
||||
### Validation
|
||||
|
||||
**IMPORTANT**: When running test commands for validation (checking directories, files, etc.), use `require_user_approval: false` since these are read-only checks.
|
||||
|
||||
1. **Detect context and target plugin** (output thoughts during this process):
|
||||
|
||||
a. Check if we're in a plugin directory:
|
||||
- Look for `.claude-plugin/plugin.json` in current directory
|
||||
- **Output**: "Checking for plugin directory..."
|
||||
- If found:
|
||||
- **Output**: "Found plugin.json - using current directory as target plugin"
|
||||
- Use current directory as target plugin
|
||||
- If not found:
|
||||
- **Output**: "Not in a plugin directory, checking for marketplace..."
|
||||
|
||||
b. If not in plugin directory, check if we're in marketplace root:
|
||||
- Look for `.claude-plugin/marketplace.json` in current directory
|
||||
- If found:
|
||||
- **Output**: "Found marketplace.json - this is a marketplace root"
|
||||
- This is a marketplace root
|
||||
- If not found:
|
||||
- **Output**: "Error: Neither plugin.json nor marketplace.json found"
|
||||
- Show error and exit
|
||||
|
||||
c. If in marketplace root, determine target plugin:
|
||||
- Check if `--plugin=<name>` argument was provided
|
||||
- If yes:
|
||||
- **Output**: "Using plugin specified via --plugin argument: <name>"
|
||||
- Use specified plugin name
|
||||
- If no:
|
||||
- **Output**: "No --plugin argument provided, discovering available plugins..."
|
||||
- Discover available plugins and prompt user
|
||||
|
||||
d. **Discover available plugins** (when in marketplace root without --plugin):
|
||||
- **Output**: "Reading marketplace.json..."
|
||||
- Read `.claude-plugin/marketplace.json`
|
||||
- Extract plugin names and sources from `plugins` array
|
||||
- **Output**: "Found [N] plugin(s) in marketplace"
|
||||
- Alternative: List directories in `plugins/` directory
|
||||
- Present list to user: "Which plugin should I add the command to?"
|
||||
- Options format: `1. plugin-name-1 (description)`, `2. plugin-name-2 (description)`, etc.
|
||||
- Wait for user selection
|
||||
- **Output**: "Selected plugin: <plugin-name>"
|
||||
|
||||
e. **Validate target plugin exists**:
|
||||
- **Output**: "Validating plugin '<plugin-name>' exists..."
|
||||
- If plugin specified/selected, verify `plugins/<plugin-name>/.claude-plugin/plugin.json` exists
|
||||
- If found:
|
||||
- **Output**: "Plugin '<plugin-name>' validated successfully"
|
||||
- If not found:
|
||||
- **Output**: "Error: Plugin '<plugin-name>' not found"
|
||||
- Show error: "Plugin '<plugin-name>' not found. Available plugins: [list]"
|
||||
|
||||
f. If neither plugin.json nor marketplace.json found:
|
||||
- Show error: "Not in a plugin or marketplace directory. Please run from a plugin root or marketplace root."
|
||||
|
||||
2. **Validate arguments**:
|
||||
- `$1` (command name): Not empty, kebab-case format (lowercase with hyphens), no spaces or special characters
|
||||
- `$2` (description): Optional. If not provided, use default: "TODO: Add description"
|
||||
|
||||
3. **Set working directory**:
|
||||
- If in plugin directory: Use current directory
|
||||
- If in marketplace root: Use `plugins/<plugin-name>/` as working directory
|
||||
|
||||
If validation fails, provide clear feedback.
|
||||
|
||||
### Create Command File
|
||||
|
||||
**Note**: All paths below are relative to the target plugin directory (determined in validation step).
|
||||
|
||||
1. Ensure `commands/` directory exists in target plugin (create if needed, use `require_user_approval: false`)
|
||||
2. Create `<plugin-dir>/commands/$1.md` with this template:
|
||||
|
||||
```markdown
|
||||
---
|
||||
description: $2
|
||||
argument-hint: [arg1] [arg2]
|
||||
---
|
||||
|
||||
# $1 Command
|
||||
|
||||
[Detailed instructions for Claude on how to execute this command]
|
||||
|
||||
## Purpose
|
||||
|
||||
[Explain what this command does and when to use it]
|
||||
|
||||
## Arguments
|
||||
|
||||
- `$ARGUMENTS`: [Describe expected arguments]
|
||||
- `$1`, `$2`, etc.: [Individual argument descriptions]
|
||||
|
||||
## Instructions
|
||||
|
||||
1. [Step 1: First action]
|
||||
2. [Step 2: Next action]
|
||||
3. [Step 3: Final action]
|
||||
|
||||
## Example Usage
|
||||
|
||||
**Command**: /<plugin-name>:$1 [args]
|
||||
|
||||
**Expected behavior**: [Describe what should happen]
|
||||
|
||||
## Notes
|
||||
|
||||
[Any additional context, warnings, or tips]
|
||||
```
|
||||
|
||||
### Update plugin.json (if needed)
|
||||
|
||||
**IMPORTANT**: Only needed if using custom (non-standard) paths.
|
||||
|
||||
- **Standard setup** (commands in `commands/` directory): No changes to `plugin.json` needed
|
||||
- **Custom paths**: Add `"commands": ["./commands/$1.md"]` (or update existing commands array)
|
||||
|
||||
### Provide Feedback
|
||||
|
||||
After creating the command:
|
||||
|
||||
```
|
||||
✓ Created <plugin-name>/commands/$1.md
|
||||
|
||||
Plugin: <plugin-name>
|
||||
Command: $1
|
||||
Description: $2
|
||||
|
||||
Next steps:
|
||||
1. Edit <plugin-name>/commands/$1.md with specific instructions
|
||||
2. Update frontmatter fields if needed:
|
||||
- argument-hint: [arg1] [arg2] (optional)
|
||||
- allowed-tools: Tool restrictions (optional)
|
||||
3. Test with /plugin-development:test-local
|
||||
|
||||
Command will be invoked as: /<plugin-name>:$1
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
**Input**:
|
||||
```
|
||||
/plugin-development:add-command format-code "Format code according to project standards"
|
||||
```
|
||||
|
||||
**Arguments**:
|
||||
- `$1` = `format-code`
|
||||
- `$2` = `Format code according to project standards`
|
||||
|
||||
**Result**:
|
||||
- Creates `commands/format-code.md` with template
|
||||
- Frontmatter description: "Format code according to project standards"
|
||||
- Ready to edit with specific instructions
|
||||
|
||||
**For complete details on commands**, see:
|
||||
- [Slash commands documentation](/en/docs/claude-code/slash-commands)
|
||||
- [Plugin commands reference](/en/docs/claude-code/plugins-reference#commands)
|
||||
|
||||
## Template Details
|
||||
|
||||
### Frontmatter
|
||||
|
||||
```yaml
|
||||
---
|
||||
description: Brief, third-person description (shows in /help)
|
||||
argument-hint: [arg1] [arg2] # Optional, shows expected arguments
|
||||
allowed-tools: Write, Edit # Optional, restricts tool access
|
||||
---
|
||||
```
|
||||
|
||||
### Using Arguments
|
||||
|
||||
In the command instructions:
|
||||
- `$ARGUMENTS`: All arguments as a single string
|
||||
- `$1`, `$2`, etc.: Individual positional arguments
|
||||
|
||||
Example:
|
||||
```markdown
|
||||
If the user provided a name via `$1`, use it: "Hello, $1!"
|
||||
```
|
||||
|
||||
### Command Instructions
|
||||
|
||||
Write clear, step-by-step instructions for Claude:
|
||||
- Use imperative mood ("Create", "Validate", "Execute")
|
||||
- Be specific about expected behavior
|
||||
- Include error handling
|
||||
- Provide examples
|
||||
|
||||
## Advanced: Bash Preamble
|
||||
|
||||
For commands that need to execute shell commands, add to frontmatter:
|
||||
|
||||
```yaml
|
||||
---
|
||||
description: Run tests and report results
|
||||
allowed-tools: Bash(npm:*), Bash(pytest:*)
|
||||
---
|
||||
|
||||
# Instructions
|
||||
|
||||
!`npm test`
|
||||
|
||||
Analyze the output and report:
|
||||
1. Number of tests passed/failed
|
||||
2. Any error messages
|
||||
3. Suggestions for fixing failures
|
||||
```
|
||||
|
||||
**Note**: Bash commands prefixed with `!` are executed before Claude processes the rest of the instructions.
|
||||
|
||||
## Best Practices
|
||||
|
||||
- **Concise descriptions**: < 100 characters for `description` field
|
||||
- **Clear arguments**: Use descriptive names in `argument-hint`
|
||||
- **Validation first**: Check arguments before execution
|
||||
- **Error handling**: Describe what to do when things go wrong
|
||||
- **Examples**: Include usage examples in the template
|
||||
|
||||
## Common Mistakes to Avoid
|
||||
|
||||
❌ **camelCase or PascalCase names**
|
||||
```
|
||||
/plugin-development:add-command formatCode
|
||||
```
|
||||
|
||||
✅ **kebab-case names**
|
||||
```
|
||||
/plugin-development:add-command format-code
|
||||
```
|
||||
|
||||
❌ **Missing description**
|
||||
```yaml
|
||||
---
|
||||
argument-hint: [arg]
|
||||
---
|
||||
```
|
||||
|
||||
✅ **Always include description**
|
||||
```yaml
|
||||
---
|
||||
description: What the command does
|
||||
argument-hint: [arg]
|
||||
---
|
||||
```
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
After creating a command:
|
||||
```
|
||||
□ File created in commands/ directory
|
||||
□ Frontmatter includes description
|
||||
□ Command name is kebab-case
|
||||
□ Instructions are clear and specific
|
||||
□ Examples provided
|
||||
□ plugin.json has commands field
|
||||
```
|
||||
451
commands/add-hook.md
Normal file
451
commands/add-hook.md
Normal file
@@ -0,0 +1,451 @@
|
||||
---
|
||||
description: Add a hook configuration to automate plugin behavior at lifecycle events
|
||||
argument-hint: [event-type] [matcher-pattern]
|
||||
---
|
||||
|
||||
# Add Hook
|
||||
|
||||
Add or update hooks.json with a new hook configuration for automated behavior.
|
||||
|
||||
## Arguments
|
||||
|
||||
- `$1` (required): Event type (`PreToolUse`, `PostToolUse`, `SessionStart`, `SessionEnd`, `UserPromptSubmit`, `Notification`, `Stop`, `SubagentStop`, or `PreCompact`)
|
||||
- `$2` (optional): Matcher pattern (e.g., `Write|Edit` or `.*`)
|
||||
- `--plugin=<plugin-name>` (optional): Specify which plugin to add the hook to
|
||||
|
||||
**Usage:**
|
||||
```
|
||||
# From within a plugin directory
|
||||
/plugin-development:add-hook PreToolUse "Write|Edit"
|
||||
|
||||
# From marketplace root, specifying plugin
|
||||
/plugin-development:add-hook PreToolUse "Write|Edit" --plugin=plugin-development
|
||||
```
|
||||
|
||||
## Template Variables
|
||||
|
||||
When generating hook configurations and scripts:
|
||||
- `$1`: Event type
|
||||
- `$2`: Matcher pattern (or default based on event type)
|
||||
- `${CLAUDE_PLUGIN_ROOT}`: Plugin root path (use in all hook commands)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Must be run from either:
|
||||
- A plugin root directory (containing `.claude-plugin/plugin.json`), OR
|
||||
- A marketplace root directory (containing `.claude-plugin/marketplace.json`)
|
||||
- `hooks/` directory will be created if needed
|
||||
|
||||
## Instructions
|
||||
|
||||
### Validation
|
||||
|
||||
**IMPORTANT**: When running test commands for validation (checking directories, files, etc.), use `require_user_approval: false` since these are read-only checks.
|
||||
|
||||
1. **Detect context and target plugin** (output thoughts during this process):
|
||||
|
||||
a. Check if we're in a plugin directory:
|
||||
- Look for `.claude-plugin/plugin.json` in current directory
|
||||
- **Output**: "Checking for plugin directory..."
|
||||
- If found:
|
||||
- **Output**: "Found plugin.json - using current directory as target plugin"
|
||||
- Use current directory as target plugin
|
||||
- If not found:
|
||||
- **Output**: "Not in a plugin directory, checking for marketplace..."
|
||||
|
||||
b. If not in plugin directory, check if we're in marketplace root:
|
||||
- Look for `.claude-plugin/marketplace.json` in current directory
|
||||
- If found:
|
||||
- **Output**: "Found marketplace.json - this is a marketplace root"
|
||||
- This is a marketplace root
|
||||
- If not found:
|
||||
- **Output**: "Error: Neither plugin.json nor marketplace.json found"
|
||||
- Show error and exit
|
||||
|
||||
c. If in marketplace root, determine target plugin:
|
||||
- Check if `--plugin=<name>` argument was provided
|
||||
- If yes:
|
||||
- **Output**: "Using plugin specified via --plugin argument: <name>"
|
||||
- Use specified plugin name
|
||||
- If no:
|
||||
- **Output**: "No --plugin argument provided, discovering available plugins..."
|
||||
- Discover available plugins and prompt user
|
||||
|
||||
d. **Discover available plugins** (when in marketplace root without --plugin):
|
||||
- **Output**: "Reading marketplace.json..."
|
||||
- Read `.claude-plugin/marketplace.json`
|
||||
- Extract plugin names and sources from `plugins` array
|
||||
- **Output**: "Found [N] plugin(s) in marketplace"
|
||||
- Alternative: List directories in `plugins/` directory
|
||||
- Present list to user: "Which plugin should I add the hook to?"
|
||||
- Options format: `1. plugin-name-1 (description)`, `2. plugin-name-2 (description)`, etc.
|
||||
- Wait for user selection
|
||||
- **Output**: "Selected plugin: <plugin-name>"
|
||||
|
||||
e. **Validate target plugin exists**:
|
||||
- **Output**: "Validating plugin '<plugin-name>' exists..."
|
||||
- If plugin specified/selected, verify `plugins/<plugin-name>/.claude-plugin/plugin.json` exists
|
||||
- If found:
|
||||
- **Output**: "Plugin '<plugin-name>' validated successfully"
|
||||
- If not found:
|
||||
- **Output**: "Error: Plugin '<plugin-name>' not found"
|
||||
- Show error: "Plugin '<plugin-name>' not found. Available plugins: [list]"
|
||||
|
||||
f. If neither plugin.json nor marketplace.json found:
|
||||
- Show error: "Not in a plugin or marketplace directory. Please run from a plugin root or marketplace root."
|
||||
|
||||
2. **Validate event type**:
|
||||
- Must be one of: `PreToolUse`, `PostToolUse`, `SessionStart`, `SessionEnd`, `UserPromptSubmit`, `Notification`, `Stop`, `SubagentStop`, `PreCompact`
|
||||
|
||||
3. **If no matcher provided, use sensible default based on event type**
|
||||
|
||||
4. **Set working directory**:
|
||||
- If in plugin directory: Use current directory
|
||||
- If in marketplace root: Use `plugins/<plugin-name>/` as working directory
|
||||
|
||||
### Event Types & Default Matchers
|
||||
|
||||
- **PreToolUse**: Default matcher `Write|Edit` (validation before writes)
|
||||
- **PostToolUse**: Default matcher `Write|Edit` (formatting after writes)
|
||||
- **SessionStart**: Default matcher `startup` (also supports: `resume`, `clear`, `compact`)
|
||||
- **SessionEnd**: No matcher (triggers on session end with reason: `clear`, `logout`, `prompt_input_exit`, `other`)
|
||||
- **UserPromptSubmit**: Default matcher `.*` (all prompts)
|
||||
- **Notification**: No matcher (triggers on all notifications)
|
||||
- **Stop**: No matcher (triggers when main agent stops)
|
||||
- **SubagentStop**: No matcher (triggers when subagent stops)
|
||||
- **PreCompact**: Default matcher `manual` (also supports: `auto`)
|
||||
|
||||
### Create or Update hooks.json
|
||||
|
||||
**Note**: All paths below are relative to the target plugin directory (determined in validation step).
|
||||
|
||||
1. Ensure `<plugin-dir>/hooks/` directory exists (use `require_user_approval: false`)
|
||||
2. If `<plugin-dir>/hooks/hooks.json` doesn't exist, create it with this structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"description": "Plugin automation hooks",
|
||||
"hooks": {}
|
||||
}
|
||||
```
|
||||
|
||||
3. Add the new hook configuration based on event type:
|
||||
|
||||
#### PreToolUse Example
|
||||
|
||||
```json
|
||||
{
|
||||
"description": "Plugin automation hooks",
|
||||
"hooks": {
|
||||
"PreToolUse": [
|
||||
{
|
||||
"matcher": "$2 or default",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh",
|
||||
"timeout": 30
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### PostToolUse Example
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"PostToolUse": [
|
||||
{
|
||||
"matcher": "$2 or default",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh",
|
||||
"timeout": 30
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### SessionStart Example
|
||||
|
||||
```json
|
||||
{
|
||||
"hooks": {
|
||||
"SessionStart": [
|
||||
{
|
||||
"matcher": "$2 or 'startup'",
|
||||
"hooks": [
|
||||
{
|
||||
"type": "command",
|
||||
"command": "echo '✓ Plugin loaded'"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Create Hook Script (if needed)
|
||||
|
||||
If the event is PreToolUse or PostToolUse, create a corresponding script:
|
||||
|
||||
1. Ensure `<plugin-dir>/scripts/` directory exists (use `require_user_approval: false`)
|
||||
2. For PreToolUse, create `<plugin-dir>/scripts/validate.sh`:
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Validation logic here
|
||||
# Exit 0: allow
|
||||
# Exit 2: block (with stderr message to Claude)
|
||||
# Exit other: warning
|
||||
|
||||
echo "Validation passed"
|
||||
exit 0
|
||||
```
|
||||
|
||||
3. For PostToolUse, create `<plugin-dir>/scripts/format.sh`:
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Formatting logic here
|
||||
# Always exits 0 for non-blocking
|
||||
|
||||
echo "Formatting complete"
|
||||
exit 0
|
||||
```
|
||||
|
||||
4. Make scripts executable:
|
||||
```bash
|
||||
chmod +x scripts/*.sh
|
||||
```
|
||||
|
||||
### Update plugin.json
|
||||
|
||||
**IMPORTANT**: Only needed if using custom (non-standard) paths.
|
||||
|
||||
- **Standard setup** (hooks at `hooks/hooks.json`): No changes to `plugin.json` needed
|
||||
- **Custom path**: Add `"hooks": "./custom/path/hooks.json"`
|
||||
|
||||
For standard setup:
|
||||
```json
|
||||
{
|
||||
"name": "my-plugin"
|
||||
}
|
||||
```
|
||||
|
||||
### Provide Feedback
|
||||
|
||||
After adding the hook:
|
||||
|
||||
```
|
||||
✓ Added $1 hook to <plugin-name>/hooks/hooks.json
|
||||
✓ Matcher: $2 (or default)
|
||||
✓ Created script: <plugin-name>/scripts/<script-name>.sh (if applicable)
|
||||
|
||||
Plugin: <plugin-name>
|
||||
Hook configuration:
|
||||
- Event: $1
|
||||
- Matcher: $2
|
||||
- Script: ${CLAUDE_PLUGIN_ROOT}/scripts/<script-name>.sh
|
||||
|
||||
Next steps:
|
||||
1. Edit <plugin-name>/hooks/hooks.json to customize timeout or command
|
||||
2. Edit <plugin-name>/scripts/<script-name>.sh with your logic
|
||||
3. Test the hook:
|
||||
- Install plugin with /plugin-development:test-local
|
||||
- Trigger the event (e.g., use Write tool for PreToolUse)
|
||||
4. Debug with: claude --debug
|
||||
|
||||
Exit codes for PreToolUse:
|
||||
- 0: Allow operation
|
||||
- 2: Block operation (stderr shown to Claude)
|
||||
- Other: Warning (non-blocking)
|
||||
|
||||
Exit codes for UserPromptSubmit:
|
||||
- 0: Allow prompt (stdout added as context)
|
||||
- 2: Block prompt (stderr shown to user, prompt erased)
|
||||
- Other: Warning (non-blocking)
|
||||
|
||||
Exit codes for Stop/SubagentStop:
|
||||
- 0: Allow stop
|
||||
- 2: Block stop, continue execution (stderr shown to Claude)
|
||||
- Other: Warning (allows stop)
|
||||
|
||||
Exit codes for PostToolUse, SessionStart, SessionEnd, Notification, PreCompact:
|
||||
- All non-blocking (informational)
|
||||
```
|
||||
|
||||
## Example Usage
|
||||
|
||||
**Input**: `/plugin-development:add-hook PreToolUse "Write|Edit"`
|
||||
|
||||
**Result**:
|
||||
- Creates or updates `hooks/hooks.json`
|
||||
- Adds PreToolUse hook with Write|Edit matcher
|
||||
- Creates `scripts/validate.sh`
|
||||
- Makes script executable
|
||||
- Provides usage instructions
|
||||
|
||||
**For complete details on hooks**, see:
|
||||
- [Hooks reference documentation](/en/docs/claude-code/hooks)
|
||||
- [Plugin hooks reference](/en/docs/claude-code/plugins-reference#hooks)
|
||||
|
||||
## Hook Event Details
|
||||
|
||||
| Event | Purpose | Can Block | Common Use Cases | Default Matcher |
|
||||
|-------|---------|-----------|------------------|-----------------|
|
||||
| **PreToolUse** | Validate before execution | Yes (exit 2) | Validate structure, check permissions | `Write\|Edit` |
|
||||
| **PostToolUse** | React after execution | Partial* | Format files, run linters, update metadata | `Write\|Edit` |
|
||||
| **SessionStart** | Setup at session start | No | Welcome message, check environment, init | `startup` |
|
||||
| **SessionEnd** | Cleanup at session end | No | Save state, log statistics, cleanup | N/A (no matcher) |
|
||||
| **UserPromptSubmit** | Validate/enhance prompts | Yes (exit 2) | Inject context, validate prompts, block sensitive | `.*` |
|
||||
| **Notification** | React to notifications | No | Send alerts, log notifications | N/A (no matcher) |
|
||||
| **Stop** | Control agent stoppage | Yes (exit 2) | Continue with tasks, validate completion | N/A (no matcher) |
|
||||
| **SubagentStop** | Control subagent stoppage | Yes (exit 2) | Continue subagent, validate subagent results | N/A (no matcher) |
|
||||
| **PreCompact** | Before context compact | No | Save state, log compact trigger | `manual` or `auto` |
|
||||
|
||||
\* PostToolUse can't prevent the tool (already ran) but can provide feedback to Claude with `"decision": "block"`
|
||||
|
||||
**Example hook structure**:
|
||||
```json
|
||||
{
|
||||
"matcher": "Write|Edit",
|
||||
"hooks": [{
|
||||
"type": "command",
|
||||
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh",
|
||||
"timeout": 30
|
||||
}]
|
||||
}
|
||||
```
|
||||
|
||||
## Matcher Patterns
|
||||
|
||||
Matchers use **regex patterns**:
|
||||
- `Write`: Only Write tool
|
||||
- `Write|Edit`: Write or Edit
|
||||
- `Bash.*`: Bash with any arguments
|
||||
- `.*`: All tools
|
||||
- `Read|Grep|Glob`: Read operations
|
||||
|
||||
## Script Template: Validation (PreToolUse)
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
ERRS=()
|
||||
|
||||
# Validation checks
|
||||
[ -f "required-file.txt" ] || ERRS+=("Missing required-file.txt")
|
||||
[ -d "required-dir" ] || ERRS+=("Missing required-dir/")
|
||||
|
||||
# If errors, block with exit 2
|
||||
if [ "${#ERRS[@]}" -gt 0 ]; then
|
||||
printf "❌ Validation failed:\n" 1>&2
|
||||
printf " %s\n" "${ERRS[@]}" 1>&2
|
||||
exit 2 # Block the operation
|
||||
fi
|
||||
|
||||
# Success
|
||||
echo "✓ Validation passed"
|
||||
exit 0
|
||||
```
|
||||
|
||||
## Script Template: Formatting (PostToolUse)
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Format files (non-blocking)
|
||||
# Example: run prettier, black, rustfmt, etc.
|
||||
|
||||
if command -v prettier &> /dev/null; then
|
||||
prettier --write "**/*.{js,json,md}" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
echo "✓ Formatting complete"
|
||||
exit 0
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Available in hook scripts:
|
||||
|
||||
- `${CLAUDE_PLUGIN_ROOT}`: Absolute path to plugin root
|
||||
- `$CLAUDE_PROJECT_DIR`: Project root directory (absolute path)
|
||||
- `$CLAUDE_ENV_FILE`: File path for persisting environment variables (SessionStart hooks only)
|
||||
- `$CLAUDE_CODE_REMOTE`: Set to "true" in web environment, unset in CLI
|
||||
- All standard environment variables
|
||||
|
||||
Always use `${CLAUDE_PLUGIN_ROOT}` for portable paths in plugins.
|
||||
|
||||
## Best Practices & Common Mistakes
|
||||
|
||||
### ✅ Do This
|
||||
- **Use ${CLAUDE_PLUGIN_ROOT}**: Portable script paths
|
||||
- **Set timeouts**: 10-30 seconds typical, 300+ for slow ops like `npm install`
|
||||
- **Fast scripts**: Keep runtime < 1 second when possible
|
||||
- **Exit code 2 to block**: Only in PreToolUse for validation failures
|
||||
- **Clear error messages**: Helpful stderr output
|
||||
- **Make executable**: `chmod +x scripts/*.sh`
|
||||
|
||||
### ❌ Avoid This
|
||||
- **Absolute paths**: `/Users/you/plugin/scripts/` (use `${CLAUDE_PLUGIN_ROOT}` instead)
|
||||
- **Missing timeouts**: Slow operations without timeout values
|
||||
- **Non-executable scripts**: Forgot to `chmod +x`
|
||||
|
||||
## Debugging Hooks
|
||||
|
||||
### Use debug mode
|
||||
|
||||
```bash
|
||||
claude --debug
|
||||
```
|
||||
|
||||
This shows:
|
||||
- Hook registration
|
||||
- Hook execution
|
||||
- Exit codes
|
||||
- Stdout/stderr output
|
||||
|
||||
### Test scripts directly
|
||||
|
||||
```bash
|
||||
./scripts/validate.sh
|
||||
echo $? # Check exit code
|
||||
```
|
||||
|
||||
### Check hook configuration
|
||||
|
||||
```bash
|
||||
cat hooks/hooks.json | jq .
|
||||
```
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
After adding a hook:
|
||||
```
|
||||
□ hooks/hooks.json created/updated
|
||||
□ Hook event is valid (PreToolUse, etc.)
|
||||
□ Matcher pattern is appropriate
|
||||
□ Script created (if needed)
|
||||
□ Script is executable (chmod +x)
|
||||
□ Script uses ${CLAUDE_PLUGIN_ROOT}
|
||||
□ Timeout set for long operations
|
||||
□ plugin.json updated (only if using custom paths)
|
||||
□ Tested with /plugin-development:test-local
|
||||
```
|
||||
391
commands/add-skill.md
Normal file
391
commands/add-skill.md
Normal file
@@ -0,0 +1,391 @@
|
||||
---
|
||||
description: Add a new Skill to the current plugin with proper structure
|
||||
argument-hint: [skill-name] ["description"]
|
||||
---
|
||||
|
||||
# Add Skill
|
||||
|
||||
Create a new Skill folder with SKILL.md and supporting directories.
|
||||
|
||||
## Arguments
|
||||
|
||||
- `$1` (required): Skill name in kebab-case (e.g., `code-review`)
|
||||
- `$2` (optional): Description of when to use this Skill in quotes (e.g., `"Use when reviewing code or PRs"`)
|
||||
- `--plugin=<plugin-name>` (optional): Specify which plugin to add the skill to
|
||||
|
||||
**Usage:**
|
||||
```
|
||||
# From within a plugin directory, with description
|
||||
/plugin-development:add-skill code-review "Use when reviewing code or analyzing pull requests"
|
||||
|
||||
# Without description (uses default)
|
||||
/plugin-development:add-skill code-review
|
||||
|
||||
# From marketplace root, specifying plugin
|
||||
/plugin-development:add-skill code-review "Use when reviewing code" --plugin=plugin-development
|
||||
```
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Must be run from either:
|
||||
- A plugin root directory (containing `.claude-plugin/plugin.json`), OR
|
||||
- A marketplace root directory (containing `.claude-plugin/marketplace.json`)
|
||||
- `skills/` directory will be created if needed
|
||||
|
||||
## Instructions
|
||||
|
||||
### Validation
|
||||
|
||||
**IMPORTANT**: When running test commands for validation (checking directories, files, etc.), use `require_user_approval: false` since these are read-only checks.
|
||||
|
||||
1. **Detect context and target plugin** (output thoughts during this process):
|
||||
|
||||
a. Check if we're in a plugin directory:
|
||||
- Look for `.claude-plugin/plugin.json` in current directory
|
||||
- **Output**: "Checking for plugin directory..."
|
||||
- If found:
|
||||
- **Output**: "Found plugin.json - using current directory as target plugin"
|
||||
- Use current directory as target plugin
|
||||
- If not found:
|
||||
- **Output**: "Not in a plugin directory, checking for marketplace..."
|
||||
|
||||
b. If not in plugin directory, check if we're in marketplace root:
|
||||
- Look for `.claude-plugin/marketplace.json` in current directory
|
||||
- If found:
|
||||
- **Output**: "Found marketplace.json - this is a marketplace root"
|
||||
- This is a marketplace root
|
||||
- If not found:
|
||||
- **Output**: "Error: Neither plugin.json nor marketplace.json found"
|
||||
- Show error and exit
|
||||
|
||||
c. If in marketplace root, determine target plugin:
|
||||
- Check if `--plugin=<name>` argument was provided
|
||||
- If yes:
|
||||
- **Output**: "Using plugin specified via --plugin argument: <name>"
|
||||
- Use specified plugin name
|
||||
- If no:
|
||||
- **Output**: "No --plugin argument provided, discovering available plugins..."
|
||||
- Discover available plugins and prompt user
|
||||
|
||||
d. **Discover available plugins** (when in marketplace root without --plugin):
|
||||
- **Output**: "Reading marketplace.json..."
|
||||
- Read `.claude-plugin/marketplace.json`
|
||||
- Extract plugin names and sources from `plugins` array
|
||||
- **Output**: "Found [N] plugin(s) in marketplace"
|
||||
- Alternative: List directories in `plugins/` directory
|
||||
- Present list to user: "Which plugin should I add the skill to?"
|
||||
- Options format: `1. plugin-name-1 (description)`, `2. plugin-name-2 (description)`, etc.
|
||||
- Wait for user selection
|
||||
- **Output**: "Selected plugin: <plugin-name>"
|
||||
|
||||
e. **Validate target plugin exists**:
|
||||
- **Output**: "Validating plugin '<plugin-name>' exists..."
|
||||
- If plugin specified/selected, verify `plugins/<plugin-name>/.claude-plugin/plugin.json` exists
|
||||
- If found:
|
||||
- **Output**: "Plugin '<plugin-name>' validated successfully"
|
||||
- If not found:
|
||||
- **Output**: "Error: Plugin '<plugin-name>' not found"
|
||||
- Show error: "Plugin '<plugin-name>' not found. Available plugins: [list]"
|
||||
|
||||
f. If neither plugin.json nor marketplace.json found:
|
||||
- Show error: "Not in a plugin or marketplace directory. Please run from a plugin root or marketplace root."
|
||||
|
||||
2. **Validate arguments**:
|
||||
- `$1` (skill name): Not empty, kebab-case format (lowercase with hyphens), no spaces or special characters, max 64 characters
|
||||
- `$2` (description): Optional. If not provided, use default: "$1 functionality for plugin development". If provided, must be max 1024 characters and should include both what the Skill does and when to use it
|
||||
|
||||
3. **Set working directory**:
|
||||
- If in plugin directory: Use current directory
|
||||
- If in marketplace root: Use `plugins/<plugin-name>/` as working directory
|
||||
|
||||
### Create Skill Structure
|
||||
|
||||
**Note**: All paths below are relative to the target plugin directory (determined in validation step).
|
||||
|
||||
1. Ensure `<plugin-dir>/skills/` directory exists (create if needed, use `require_user_approval: false`)
|
||||
2. Create skill directory: `<plugin-dir>/skills/$1/`
|
||||
3. Create supporting directories:
|
||||
- `<plugin-dir>/skills/$1/schemas/`
|
||||
- `<plugin-dir>/skills/$1/templates/`
|
||||
- `<plugin-dir>/skills/$1/examples/`
|
||||
- `<plugin-dir>/skills/$1/best-practices/`
|
||||
|
||||
### Create SKILL.md
|
||||
|
||||
Create `<plugin-dir>/skills/$1/SKILL.md` with this template:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: $1
|
||||
description: $2
|
||||
---
|
||||
|
||||
# $1 Skill
|
||||
|
||||
[Brief introduction to what this Skill provides and its purpose]
|
||||
|
||||
## When to Activate
|
||||
|
||||
This Skill activates when:
|
||||
- [Condition 1: e.g., user mentions specific keywords]
|
||||
- [Condition 2: e.g., working with specific file types]
|
||||
- [Condition 3: e.g., certain files are present]
|
||||
|
||||
## Capabilities
|
||||
|
||||
What this Skill can help with:
|
||||
|
||||
1. [Capability 1]
|
||||
2. [Capability 2]
|
||||
3. [Capability 3]
|
||||
|
||||
## Quick Links (Progressive Disclosure)
|
||||
|
||||
- [Schemas](./schemas/)
|
||||
- [Templates](./templates/)
|
||||
- [Examples](./examples/)
|
||||
- [Best Practices](./best-practices/)
|
||||
|
||||
## Workflow
|
||||
|
||||
How this Skill operates:
|
||||
|
||||
1. **Analyze**: [What to read and understand]
|
||||
2. **Propose**: [What actions to suggest]
|
||||
3. **Execute**: [How to carry out the work]
|
||||
4. **Validate**: [How to verify success]
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Pattern 1: [Name]
|
||||
|
||||
[Description of common usage pattern]
|
||||
|
||||
### Pattern 2: [Name]
|
||||
|
||||
[Description of another pattern]
|
||||
|
||||
## Notes
|
||||
|
||||
- [Important consideration 1]
|
||||
- [Important consideration 2]
|
||||
- [Links to other Skills or commands if applicable]
|
||||
```
|
||||
|
||||
### Update plugin.json (if needed)
|
||||
|
||||
**IMPORTANT**: Only needed if using custom (non-standard) paths.
|
||||
|
||||
- **Standard setup** (skills in `skills/` directory): No changes to `plugin.json` needed
|
||||
- **Custom paths**: Skills cannot be specified with custom paths (must use standard `skills/` directory)
|
||||
|
||||
### Provide Feedback
|
||||
|
||||
After creating the Skill:
|
||||
|
||||
```
|
||||
✓ Created <plugin-name>/skills/$1/SKILL.md
|
||||
✓ Created supporting directories:
|
||||
- <plugin-name>/skills/$1/schemas/
|
||||
- <plugin-name>/skills/$1/templates/
|
||||
- <plugin-name>/skills/$1/examples/
|
||||
- <plugin-name>/skills/$1/best-practices/
|
||||
|
||||
Plugin: <plugin-name>
|
||||
Skill: $1
|
||||
Description: $2
|
||||
|
||||
Next steps:
|
||||
1. Edit <plugin-name>/skills/$1/SKILL.md with specific guidance
|
||||
2. Key frontmatter fields:
|
||||
- name: Must match directory name ($1)
|
||||
- description: When to use this Skill (include trigger conditions, max 1024 chars)
|
||||
- allowed-tools: (Optional) Restrict tools available to this Skill. If omitted, Claude asks for permission
|
||||
3. Add support files:
|
||||
- schemas/: Document data formats
|
||||
- templates/: Provide reusable templates
|
||||
- examples/: Show usage examples
|
||||
- best-practices/: Detailed guidance
|
||||
4. Keep SKILL.md concise (< 500 lines), use progressive disclosure
|
||||
5. Test with /plugin-development:test-local
|
||||
|
||||
Claude will auto-discover this Skill when the plugin is installed.
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
**Input**:
|
||||
```
|
||||
/plugin-development:add-skill code-review "Use when reviewing code or analyzing pull requests"
|
||||
```
|
||||
|
||||
**Arguments**:
|
||||
- `$1` = `code-review`
|
||||
- `$2` = `Use when reviewing code or analyzing pull requests`
|
||||
|
||||
**Result**:
|
||||
- Creates `skills/code-review/` directory
|
||||
- Creates `SKILL.md` with frontmatter `name: code-review`
|
||||
- Frontmatter description: "Use when reviewing code or analyzing pull requests"
|
||||
- Creates supporting directories (schemas/, templates/, examples/, best-practices/)
|
||||
- Ready to add guidance and reference files
|
||||
|
||||
**For complete details on Skills**, see:
|
||||
- [Agent Skills documentation](/en/docs/claude-code/skills)
|
||||
- [Agent Skills overview](/en/docs/agents-and-tools/agent-skills/overview)
|
||||
- [Skills best practices](/en/docs/agents-and-tools/agent-skills/best-practices)
|
||||
|
||||
## Skill Frontmatter
|
||||
|
||||
### Required Fields
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: skill-name # Must match directory, kebab-case
|
||||
description: When and how to use this Skill (be specific about triggers)
|
||||
---
|
||||
```
|
||||
|
||||
### Optional Fields
|
||||
|
||||
```yaml
|
||||
---
|
||||
name: skill-name
|
||||
description: Detailed description
|
||||
allowed-tools: Read, Grep, Glob # Restrict tool access (if omitted, Claude asks for permission)
|
||||
---
|
||||
```
|
||||
|
||||
**Important**: `allowed-tools` is optional. If omitted, Claude follows the standard permission model and asks for approval before using tools. Only add `allowed-tools` when you want to restrict available tools (e.g., read-only Skills).
|
||||
|
||||
### allowed-tools Options
|
||||
|
||||
Restrict to read-only for safety:
|
||||
```yaml
|
||||
allowed-tools: Read, Grep, Glob
|
||||
```
|
||||
|
||||
Allow specific tools:
|
||||
```yaml
|
||||
allowed-tools: Read, Write, Edit, Bash(npm:*)
|
||||
```
|
||||
|
||||
## Description Best Practices
|
||||
|
||||
The `description` field is critical for Claude to discover when to use your Skill. Requirements:
|
||||
- **Max length**: 1024 characters
|
||||
- **Include both**: what the Skill does AND when to use it
|
||||
- **Be specific**: Include trigger keywords users would naturally mention
|
||||
|
||||
✅ **Good** (specific triggers):
|
||||
```yaml
|
||||
description: Review code for best practices, detect bugs, and suggest improvements. Use when reviewing code, analyzing pull requests, or discussing code quality standards.
|
||||
```
|
||||
|
||||
❌ **Bad** (too vague):
|
||||
```yaml
|
||||
description: Helps with code
|
||||
```
|
||||
|
||||
✅ **Good** (context-based):
|
||||
```yaml
|
||||
description: Create and manage React components following best practices. Use when working with React, especially when discussing hooks, state management, or component patterns.
|
||||
```
|
||||
|
||||
## Progressive Disclosure Pattern
|
||||
|
||||
Keep SKILL.md concise by linking to support files:
|
||||
|
||||
### In SKILL.md:
|
||||
```markdown
|
||||
## Quick Links
|
||||
- [API Schema](./schemas/api-schema.md)
|
||||
- [Component Templates](./templates/)
|
||||
```
|
||||
|
||||
### In Support Files:
|
||||
- `schemas/api-schema.md`: Detailed schema documentation
|
||||
- `templates/component.tsx`: Reusable template files
|
||||
|
||||
This keeps SKILL.md under 500 lines while providing deep reference material.
|
||||
|
||||
## Skill Structure Example
|
||||
|
||||
```
|
||||
skills/
|
||||
└── code-review/
|
||||
├── SKILL.md # Main skill (concise)
|
||||
├── schemas/
|
||||
│ └── review-checklist.md # Review criteria
|
||||
├── templates/
|
||||
│ └── review-comment.md # Comment templates
|
||||
├── examples/
|
||||
│ ├── basic-review.md # Simple example
|
||||
│ └── security-review.md # Advanced example
|
||||
└── best-practices/
|
||||
├── review-process.md # Detailed guidance
|
||||
└── common-issues.md # Issue catalog
|
||||
```
|
||||
|
||||
## Advanced: Tool Restrictions
|
||||
|
||||
For read-only Skills (safest):
|
||||
```yaml
|
||||
allowed-tools: Read, Grep, Glob
|
||||
```
|
||||
|
||||
For Skills that propose changes but don't execute:
|
||||
```yaml
|
||||
allowed-tools: Read, Grep, Glob
|
||||
```
|
||||
(Propose commands for user to run)
|
||||
|
||||
For Skills that need to write:
|
||||
```yaml
|
||||
allowed-tools: Read, Write, Edit, Grep, Glob
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Concise SKILL.md**: Keep main file < 500 lines
|
||||
2. **Progressive disclosure**: Link to detailed support files
|
||||
3. **Specific triggers**: Clear description of when to activate
|
||||
4. **Tool restrictions**: Only add `allowed-tools` when restricting is necessary (e.g., read-only Skills)
|
||||
5. **Organized support**: Use all subdirectories for comprehensive guidance
|
||||
|
||||
## Common Mistakes to Avoid
|
||||
|
||||
❌ **Name doesn't match directory**
|
||||
```
|
||||
Directory: skills/code-review/
|
||||
Frontmatter: name: codeReview # Wrong case!
|
||||
```
|
||||
|
||||
✅ **Name matches directory**
|
||||
```
|
||||
Directory: skills/code-review/
|
||||
Frontmatter: name: code-review
|
||||
```
|
||||
|
||||
❌ **Vague description**
|
||||
```yaml
|
||||
description: A helpful Skill
|
||||
```
|
||||
|
||||
✅ **Specific triggers**
|
||||
```yaml
|
||||
description: Use when reviewing code, analyzing PRs, or discussing code quality
|
||||
```
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
After creating a Skill:
|
||||
```
|
||||
□ SKILL.md created in skills/<name>/ directory
|
||||
□ Frontmatter name matches directory name (kebab-case, max 64 chars)
|
||||
□ Description includes specific trigger conditions (max 1024 chars)
|
||||
□ Description includes both what the Skill does AND when to use it
|
||||
□ SKILL.md is uppercase
|
||||
□ Supporting directories created
|
||||
□ If using allowed-tools, it restricts tools appropriately
|
||||
```
|
||||
149
commands/init.md
Normal file
149
commands/init.md
Normal file
@@ -0,0 +1,149 @@
|
||||
---
|
||||
description: Scaffold a new Claude Code plugin with standard structure and starter files
|
||||
argument-hint: [plugin-name]
|
||||
---
|
||||
|
||||
# Initialize Plugin
|
||||
|
||||
Create the standard directory structure and files for a new Claude Code plugin.
|
||||
|
||||
## Arguments
|
||||
|
||||
- `$1` (required): Plugin name in kebab-case (e.g., `my-awesome-plugin`)
|
||||
|
||||
## What This Command Does
|
||||
|
||||
1. Creates the plugin directory structure:
|
||||
- `.claude-plugin/` with `plugin.json`
|
||||
- `commands/` directory
|
||||
- `agents/` directory
|
||||
- `skills/` directory
|
||||
- `hooks/` directory with `hooks.json`
|
||||
- `scripts/` directory
|
||||
2. Generates a starter `plugin.json` with the provided name
|
||||
3. Creates a README.md template
|
||||
4. Provides next steps
|
||||
|
||||
## Instructions
|
||||
|
||||
### Validation
|
||||
|
||||
First, validate the plugin name:
|
||||
- Must be provided (not empty)
|
||||
- Should be kebab-case (lowercase with hyphens)
|
||||
- Should not contain spaces or special characters
|
||||
|
||||
If validation fails, explain the requirements and ask for a valid name.
|
||||
|
||||
### Create Directory Structure
|
||||
|
||||
Create these directories:
|
||||
```
|
||||
$1/
|
||||
├── .claude-plugin/
|
||||
├── commands/
|
||||
├── agents/
|
||||
├── skills/
|
||||
├── hooks/
|
||||
└── scripts/
|
||||
```
|
||||
|
||||
### Create plugin.json
|
||||
|
||||
Create `.claude-plugin/plugin.json` with this template:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "$1",
|
||||
"version": "0.1.0",
|
||||
"description": "Brief description of what this plugin does",
|
||||
"author": {
|
||||
"name": "Your Name",
|
||||
"email": "you@example.com"
|
||||
},
|
||||
"license": "MIT",
|
||||
"keywords": ["keyword1", "keyword2"]
|
||||
}
|
||||
```
|
||||
|
||||
### Create hooks.json
|
||||
|
||||
Create `hooks/hooks.json` with a basic structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"description": "Plugin hooks",
|
||||
"hooks": {}
|
||||
}
|
||||
```
|
||||
|
||||
### Create README.md
|
||||
|
||||
Create `README.md` with this template:
|
||||
|
||||
```markdown
|
||||
# $1
|
||||
|
||||
[Brief description of what this plugin does]
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
/plugin install $1@marketplace-name
|
||||
```
|
||||
|
||||
## Commands
|
||||
|
||||
[List commands here]
|
||||
|
||||
## Usage
|
||||
|
||||
[Provide examples]
|
||||
```
|
||||
|
||||
### Create Validation Script
|
||||
|
||||
Create `scripts/validate-plugin.sh` with executable permissions:
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
# Basic plugin structure validation
|
||||
[ -f ".claude-plugin/plugin.json" ] || { echo "Missing plugin.json" >&2; exit 2; }
|
||||
exit 0
|
||||
```
|
||||
|
||||
Make it executable: `chmod +x scripts/validate-plugin.sh`
|
||||
|
||||
## Next Steps
|
||||
|
||||
After scaffolding, provide these instructions to the user:
|
||||
|
||||
```
|
||||
✓ Plugin scaffolded at $1/
|
||||
|
||||
Next steps:
|
||||
1. Edit $1/.claude-plugin/plugin.json with your metadata
|
||||
2. Add components:
|
||||
- /plugin-development:add-command <name> <description>
|
||||
- /plugin-development:add-skill <name> <description>
|
||||
- /plugin-development:add-agent <name> <description>
|
||||
3. Validate: /plugin-development:validate
|
||||
4. Test locally: /plugin-development:test-local
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
**Input**: `/plugin-development:init my-awesome-plugin`
|
||||
|
||||
**Result**:
|
||||
- Creates `my-awesome-plugin/` with full structure
|
||||
- Generates starter files
|
||||
- Displays next steps
|
||||
|
||||
## Notes
|
||||
|
||||
- The command creates the plugin directory in the current working directory
|
||||
- All paths in generated files are relative (use `./`)
|
||||
- The plugin is not yet installed; use `/plugin-development:test-local` to test it
|
||||
379
commands/test-local.md
Normal file
379
commands/test-local.md
Normal file
@@ -0,0 +1,379 @@
|
||||
---
|
||||
description: Create a local dev marketplace and install the plugin for testing
|
||||
---
|
||||
|
||||
# Test Plugin Locally
|
||||
|
||||
Set up a development marketplace for local testing and install the current plugin.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Must be run from a plugin root directory (containing `.claude-plugin/plugin.json`)
|
||||
- Plugin should pass validation (run `/plugin-development:validate` first)
|
||||
|
||||
## Instructions
|
||||
|
||||
### What This Command Does
|
||||
|
||||
1. Creates a sibling `dev-marketplace/` directory (if it doesn't exist)
|
||||
2. Generates `dev-marketplace/.claude-plugin/marketplace.json` pointing to your plugin
|
||||
3. Provides instructions for:
|
||||
- Adding the marketplace to Claude Code
|
||||
- Installing the plugin
|
||||
- Testing workflow (edit → reinstall → test loop)
|
||||
|
||||
### Step 1: Read Plugin Metadata
|
||||
|
||||
Read `.claude-plugin/plugin.json` to get:
|
||||
- Plugin name
|
||||
- Plugin description
|
||||
- Plugin version
|
||||
|
||||
### Step 2: Determine Plugin Path
|
||||
|
||||
Get the current plugin directory path. Common patterns:
|
||||
- Current working directory
|
||||
- From the location of plugin.json
|
||||
|
||||
The marketplace source path should be relative from marketplace to plugin:
|
||||
- If plugin is at `/path/to/my-plugin/`
|
||||
- Dev marketplace at `/path/to/dev-marketplace/`
|
||||
- Source path: `../my-plugin`
|
||||
|
||||
### Step 3: Create Dev Marketplace Structure
|
||||
|
||||
1. Create directory: `../dev-marketplace/.claude-plugin/`
|
||||
2. Create `marketplace.json` at `../dev-marketplace/.claude-plugin/marketplace.json`
|
||||
|
||||
### Step 4: Generate marketplace.json
|
||||
|
||||
Create with this structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "dev-marketplace",
|
||||
"owner": {
|
||||
"name": "Developer"
|
||||
},
|
||||
"metadata": {
|
||||
"description": "Local development marketplace for testing plugins",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"name": "<plugin-name-from-plugin.json>",
|
||||
"description": "<description-from-plugin.json>",
|
||||
"version": "<version-from-plugin.json>",
|
||||
"source": "../<plugin-directory-name>"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Important**: The `source` path is relative from marketplace to plugin directory.
|
||||
|
||||
### Step 5: Provide Testing Instructions
|
||||
|
||||
Display clear instructions for the user:
|
||||
|
||||
```
|
||||
✅ Dev marketplace created at ../dev-marketplace/
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
🚀 Testing Workflow
|
||||
|
||||
1️⃣ ADD MARKETPLACE (First time only)
|
||||
/plugin marketplace add ../dev-marketplace
|
||||
|
||||
Verify:
|
||||
/plugin marketplace list
|
||||
|
||||
2️⃣ INSTALL PLUGIN
|
||||
/plugin install <plugin-name>@dev-marketplace
|
||||
|
||||
Verify:
|
||||
/help
|
||||
(Your commands should appear)
|
||||
|
||||
3️⃣ TEST COMMANDS
|
||||
/<plugin-name>:<command-name> [args]
|
||||
|
||||
Examples:
|
||||
/<plugin-name>:command1
|
||||
/<plugin-name>:command2 arg
|
||||
|
||||
4️⃣ ITERATION LOOP (After making changes)
|
||||
|
||||
a. Edit your plugin files
|
||||
b. Validate: /plugin-development:validate
|
||||
c. Uninstall: /plugin uninstall <plugin-name>@dev-marketplace
|
||||
d. Reinstall: /plugin install <plugin-name>@dev-marketplace
|
||||
e. Test again: /<plugin-name>:command-name
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
💡 Tips
|
||||
|
||||
- Must uninstall/reinstall to pick up changes
|
||||
- Use /plugin-development:validate before each test
|
||||
- Check /agents to see if your agents appear
|
||||
- Use claude --debug to see plugin loading details
|
||||
- Run hooks/scripts directly to test them: ./scripts/validate.sh
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
📦 Marketplace Location
|
||||
Path: ../dev-marketplace/
|
||||
Config: ../dev-marketplace/.claude-plugin/marketplace.json
|
||||
|
||||
Plugin reference:
|
||||
- Name: <plugin-name>
|
||||
- Source: ../<plugin-directory>
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
**Input**: `/plugin-development:test-local`
|
||||
|
||||
(Run from `/path/to/my-plugin/`)
|
||||
|
||||
**Output**:
|
||||
```
|
||||
✅ Dev marketplace created at ../dev-marketplace/
|
||||
|
||||
Registered plugin: my-plugin
|
||||
Source path: ../my-plugin
|
||||
|
||||
Next: /plugin marketplace add ../dev-marketplace
|
||||
Then: /plugin install my-plugin@dev-marketplace
|
||||
```
|
||||
|
||||
## Handling Existing Marketplace
|
||||
|
||||
If `../dev-marketplace/.claude-plugin/marketplace.json` already exists:
|
||||
|
||||
### Option 1: Update Existing (Recommended)
|
||||
|
||||
1. Read existing marketplace.json
|
||||
2. Check if current plugin already registered
|
||||
3. If yes: Update the entry
|
||||
4. If no: Append to plugins array
|
||||
5. Write back to file
|
||||
|
||||
### Option 2: Ask User
|
||||
|
||||
```
|
||||
⚠️ Dev marketplace already exists at ../dev-marketplace/
|
||||
|
||||
Current plugins registered:
|
||||
- plugin-a
|
||||
- plugin-b
|
||||
|
||||
Would you like to:
|
||||
1. Add <current-plugin> to existing marketplace
|
||||
2. Replace existing marketplace.json
|
||||
3. Cancel
|
||||
|
||||
(Auto-select option 1 for smooth workflow)
|
||||
```
|
||||
|
||||
## Marketplace Structure Reference
|
||||
|
||||
```
|
||||
dev-marketplace/
|
||||
└── .claude-plugin/
|
||||
└── marketplace.json
|
||||
```
|
||||
|
||||
**marketplace.json**:
|
||||
```json
|
||||
{
|
||||
"name": "dev-marketplace",
|
||||
"owner": {
|
||||
"name": "Developer"
|
||||
},
|
||||
"metadata": {
|
||||
"description": "Local development marketplace",
|
||||
"version": "0.1.0"
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"name": "plugin-name",
|
||||
"description": "Plugin description",
|
||||
"version": "1.0.0",
|
||||
"source": "../plugin-name"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Testing Multiple Plugins
|
||||
|
||||
If user has multiple plugins, the dev marketplace can reference them all:
|
||||
|
||||
```json
|
||||
{
|
||||
"plugins": [
|
||||
{
|
||||
"name": "plugin-one",
|
||||
"source": "../plugin-one"
|
||||
},
|
||||
{
|
||||
"name": "plugin-two",
|
||||
"source": "../plugin-two"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Install separately:
|
||||
```
|
||||
/plugin install plugin-one@dev-marketplace
|
||||
/plugin install plugin-two@dev-marketplace
|
||||
```
|
||||
|
||||
## Troubleshooting Tips
|
||||
|
||||
Include these in the output:
|
||||
|
||||
```
|
||||
🔧 Troubleshooting
|
||||
|
||||
Plugin not loading?
|
||||
□ Check /plugin list to verify installation
|
||||
□ Verify plugin.json paths are relative (./commands/)
|
||||
□ Run /plugin-development:validate
|
||||
|
||||
Commands not showing?
|
||||
□ Check /help for command list
|
||||
□ Verify commands/ directory has .md files
|
||||
□ Ensure frontmatter has description field
|
||||
□ Reinstall the plugin
|
||||
|
||||
Skills not triggering?
|
||||
□ Check SKILL.md frontmatter name matches directory
|
||||
□ Verify description has clear trigger conditions
|
||||
□ Skills auto-activate based on context
|
||||
|
||||
Hooks not running?
|
||||
□ Make scripts executable: chmod +x scripts/*.sh
|
||||
□ Use ${CLAUDE_PLUGIN_ROOT} in hook commands
|
||||
□ Test script directly: ./scripts/script-name.sh
|
||||
□ Check claude --debug for hook execution logs
|
||||
```
|
||||
|
||||
## Advanced: Custom Marketplace Location
|
||||
|
||||
If user wants marketplace elsewhere:
|
||||
|
||||
```
|
||||
You can specify a custom location:
|
||||
1. Create marketplace structure anywhere
|
||||
2. Update source paths accordingly
|
||||
3. Add marketplace: /plugin marketplace add /path/to/marketplace
|
||||
|
||||
Example for repo root:
|
||||
- Plugin: /repo/plugins/my-plugin/
|
||||
- Marketplace: /repo/dev-marketplace/
|
||||
- Source path: ../plugins/my-plugin
|
||||
```
|
||||
|
||||
## Validation Before Testing
|
||||
|
||||
Remind user to validate:
|
||||
|
||||
```
|
||||
⚡ Quick Check
|
||||
|
||||
Before testing, validate your plugin:
|
||||
/plugin-development:validate
|
||||
|
||||
This catches common issues:
|
||||
- Invalid JSON
|
||||
- Path errors
|
||||
- Naming mismatches
|
||||
- Missing files
|
||||
```
|
||||
|
||||
## Complete Workflow Example
|
||||
|
||||
Show a complete example session:
|
||||
|
||||
```
|
||||
📝 Complete Testing Session
|
||||
|
||||
# Initial setup (once)
|
||||
$ cd my-plugin/
|
||||
$ /plugin-development:validate
|
||||
✅ Validation passed
|
||||
|
||||
$ /plugin-development:test-local
|
||||
✅ Dev marketplace created
|
||||
|
||||
$ /plugin marketplace add ../dev-marketplace
|
||||
✅ Marketplace added
|
||||
|
||||
$ /plugin install my-plugin@dev-marketplace
|
||||
✅ Plugin installed
|
||||
|
||||
$ /help
|
||||
Commands:
|
||||
/my-plugin:command1 - Does something
|
||||
/my-plugin:command2 - Does another thing
|
||||
|
||||
$ /my-plugin:command1
|
||||
[Command executes successfully]
|
||||
|
||||
# After making changes
|
||||
$ [edit files]
|
||||
|
||||
$ /plugin-development:validate
|
||||
✅ Validation passed
|
||||
|
||||
$ /plugin uninstall my-plugin@dev-marketplace
|
||||
✅ Plugin uninstalled
|
||||
|
||||
$ /plugin install my-plugin@dev-marketplace
|
||||
✅ Plugin installed
|
||||
|
||||
$ /my-plugin:command1
|
||||
[Tests updated functionality]
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- The dev marketplace is for **local testing only**
|
||||
- Do not commit `dev-marketplace/` to your plugin repository
|
||||
- For team distribution, create a proper marketplace repository
|
||||
- The source path must be relative from marketplace to plugin
|
||||
- Must uninstall/reinstall to pick up plugin changes
|
||||
|
||||
## After Testing
|
||||
|
||||
When ready for team distribution:
|
||||
|
||||
```
|
||||
✅ Plugin tested successfully!
|
||||
|
||||
Ready for team distribution:
|
||||
1. Create a proper marketplace repository
|
||||
2. Add your plugin to the marketplace
|
||||
3. Commit and push to GitHub
|
||||
4. Team installs via: /plugin marketplace add your-org/marketplace-repo
|
||||
5. Or configure in .claude/settings.json for auto-install
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Validate first**: Always run `/plugin-development:validate` before testing
|
||||
2. **Clean reinstalls**: Uninstall fully before reinstalling
|
||||
3. **Test all components**: Commands, skills, agents, hooks
|
||||
4. **Incremental changes**: Test small changes frequently
|
||||
5. **Debug mode**: Use `claude --debug` when troubleshooting
|
||||
6. **Direct testing**: Test hook scripts directly before installing
|
||||
|
||||
## Related Commands
|
||||
|
||||
- `/plugin-development:validate` - Validate before testing
|
||||
- `/plugin-development:init` - Scaffold new plugin
|
||||
- `/plugin marketplace list` - See available marketplaces
|
||||
- `/plugin list` - See installed plugins
|
||||
- `/help` - See available commands
|
||||
353
commands/validate.md
Normal file
353
commands/validate.md
Normal file
@@ -0,0 +1,353 @@
|
||||
---
|
||||
description: Validate plugin structure, manifest, and component files for common issues
|
||||
---
|
||||
|
||||
# Validate Plugin
|
||||
|
||||
Comprehensive validation of plugin structure, configuration, and components.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Must be run from a plugin root directory (containing `.claude-plugin/plugin.json`)
|
||||
|
||||
## Instructions
|
||||
|
||||
### What This Command Does
|
||||
|
||||
Performs a thorough validation of the plugin:
|
||||
|
||||
1. **Structure validation**: Check directories and files exist
|
||||
2. **Manifest validation**: Verify plugin.json is valid and complete
|
||||
3. **Component validation**: Check commands, agents, skills, hooks
|
||||
4. **Path validation**: Ensure all paths are relative and resolve correctly
|
||||
5. **Naming validation**: Verify kebab-case conventions
|
||||
6. **Common issues**: Flag typical mistakes
|
||||
|
||||
### Validation Steps
|
||||
|
||||
#### 1. Check Core Structure
|
||||
|
||||
Verify these exist:
|
||||
```
|
||||
□ .claude-plugin/plugin.json
|
||||
□ At least one component directory (commands/, agents/, skills/, or hooks/)
|
||||
```
|
||||
|
||||
#### 2. Validate plugin.json
|
||||
|
||||
Read and check:
|
||||
- **Valid JSON**: Can parse without errors
|
||||
- **Required fields present**: `name`, `version`, `description`
|
||||
- **Name format**: kebab-case (lowercase with hyphens)
|
||||
- **Version format**: Valid SemVer (e.g., "1.0.0")
|
||||
- **Paths are relative**: Start with `./` not `/`
|
||||
- **Author format**: If present, valid object or string
|
||||
|
||||
Example valid structure:
|
||||
```json
|
||||
{
|
||||
"name": "plugin-name",
|
||||
"version": "1.0.0",
|
||||
"description": "What the plugin does",
|
||||
"author": {
|
||||
"name": "Your Name"
|
||||
},
|
||||
"license": "MIT",
|
||||
"keywords": ["keyword1"],
|
||||
"commands": "./commands/",
|
||||
"agents": "./agents/",
|
||||
"hooks": "./hooks/hooks.json"
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. Validate Component Paths
|
||||
|
||||
For each path in plugin.json:
|
||||
- **commands**: Check directory exists, contains .md files
|
||||
- **agents**: Check directory exists, contains .md files
|
||||
- **skills**: Check directory exists, contains skill folders with SKILL.md
|
||||
- **hooks**: Check file exists and is valid JSON
|
||||
|
||||
#### 4. Validate Commands
|
||||
|
||||
For each file in `commands/`:
|
||||
- **File extension**: Must be .md
|
||||
- **Frontmatter present**: Has `---` delimiters
|
||||
- **Description field**: Frontmatter includes `description`
|
||||
- **Naming**: kebab-case filename
|
||||
- **Content**: Not empty after frontmatter
|
||||
|
||||
#### 5. Validate Skills
|
||||
|
||||
For each directory in `skills/`:
|
||||
- **SKILL.md exists**: In uppercase
|
||||
- **Frontmatter present**: Has `---` delimiters
|
||||
- **Required fields**: `name` and `description` present
|
||||
- **Name matches directory**: Exact match, kebab-case
|
||||
- **Description is specific**: Includes when/why to use
|
||||
|
||||
#### 6. Validate Agents
|
||||
|
||||
For each file in `agents/`:
|
||||
- **File extension**: Must be .md
|
||||
- **Frontmatter present**: Has `---` delimiters
|
||||
- **Description field**: Present in frontmatter
|
||||
- **Naming**: kebab-case filename
|
||||
- **Content**: Not empty after frontmatter
|
||||
|
||||
#### 7. Validate Hooks
|
||||
|
||||
If `hooks.json` exists:
|
||||
- **Valid JSON**: Can parse without errors
|
||||
- **Proper structure**: Has `hooks` object
|
||||
- **Event names**: Valid events (PreToolUse, PostToolUse, etc.)
|
||||
- **Hook commands**: Scripts use `${CLAUDE_PLUGIN_ROOT}`
|
||||
- **Scripts exist**: Referenced scripts are present
|
||||
- **Scripts executable**: Have execute permissions
|
||||
|
||||
### Validation Output Format
|
||||
|
||||
Report findings in this structure:
|
||||
|
||||
```
|
||||
🔍 Validating plugin: <plugin-name>
|
||||
|
||||
✅ Structure
|
||||
✓ .claude-plugin/plugin.json exists
|
||||
✓ Component directories present
|
||||
|
||||
✅ Manifest (plugin.json)
|
||||
✓ Valid JSON
|
||||
✓ Required fields: name, version, description
|
||||
✓ Name format: kebab-case
|
||||
✓ Version format: SemVer
|
||||
✓ Paths are relative
|
||||
|
||||
✅ Commands (3 files)
|
||||
✓ commands/init.md
|
||||
✓ commands/validate.md
|
||||
✓ commands/test-local.md
|
||||
|
||||
✅ Skills (1 skill)
|
||||
✓ skills/plugin-authoring/SKILL.md
|
||||
- name matches directory: ✓
|
||||
- description present: ✓
|
||||
|
||||
✅ Agents (1 agent)
|
||||
✓ agents/plugin-reviewer.md
|
||||
|
||||
✅ Hooks
|
||||
✓ hooks/hooks.json is valid
|
||||
✓ Scripts exist and are executable
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
✅ Validation passed: 0 errors, 0 warnings
|
||||
```
|
||||
|
||||
### Error Reporting
|
||||
|
||||
If issues are found, report clearly:
|
||||
|
||||
```
|
||||
❌ Errors Found
|
||||
|
||||
1. Manifest: plugin.json missing required field "version"
|
||||
Fix: Add "version": "1.0.0" to .claude-plugin/plugin.json
|
||||
|
||||
2. Command: commands/myCommand.md uses camelCase
|
||||
Fix: Rename to commands/my-command.md (kebab-case)
|
||||
|
||||
3. Skill: skills/MySkill/SKILL.md name doesn't match directory
|
||||
Fix: Change frontmatter 'name' to "my-skill" (matches directory)
|
||||
|
||||
⚠️ Warnings
|
||||
|
||||
1. No README.md found
|
||||
Suggestion: Create README.md with usage documentation
|
||||
|
||||
2. No keywords in plugin.json
|
||||
Suggestion: Add keywords array for discoverability
|
||||
|
||||
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
❌ Validation failed: 3 errors, 2 warnings
|
||||
```
|
||||
|
||||
## Validation Categories
|
||||
|
||||
### Critical (Must Fix)
|
||||
|
||||
- Missing plugin.json
|
||||
- Invalid JSON in config files
|
||||
- Missing required fields (name, version, description)
|
||||
- Absolute paths in configuration
|
||||
- Component name mismatches (skill name ≠ directory)
|
||||
- Non-executable hook scripts
|
||||
|
||||
### Warnings (Should Fix)
|
||||
|
||||
- Missing README.md
|
||||
- No keywords in plugin.json
|
||||
- Empty component directories
|
||||
- Commands missing argument-hint
|
||||
- Skills without progressive disclosure structure
|
||||
|
||||
### Suggestions (Nice to Have)
|
||||
|
||||
- Add CHANGELOG.md
|
||||
- Include examples directory
|
||||
- Add more descriptive descriptions
|
||||
- Use consistent naming patterns
|
||||
|
||||
## Common Issues Detected
|
||||
|
||||
### Issue: Paths Not Relative
|
||||
|
||||
```json
|
||||
❌ "commands": "/Users/you/plugin/commands/"
|
||||
✅ "commands": "./commands/"
|
||||
```
|
||||
|
||||
### Issue: Name Mismatch
|
||||
|
||||
```
|
||||
Directory: skills/code-review/
|
||||
Frontmatter: name: codeReview
|
||||
❌ Names don't match
|
||||
|
||||
Fix: Change frontmatter to name: code-review
|
||||
```
|
||||
|
||||
### Issue: Missing Frontmatter
|
||||
|
||||
```markdown
|
||||
# My Command
|
||||
|
||||
Instructions...
|
||||
```
|
||||
❌ No frontmatter with description
|
||||
|
||||
```markdown
|
||||
---
|
||||
description: What this command does
|
||||
---
|
||||
|
||||
# My Command
|
||||
|
||||
Instructions...
|
||||
```
|
||||
✅ Has required frontmatter
|
||||
|
||||
### Issue: Hook Script Not Executable
|
||||
|
||||
```bash
|
||||
$ ls -l scripts/validate.sh
|
||||
-rw-r--r-- validate.sh
|
||||
❌ Not executable
|
||||
|
||||
$ chmod +x scripts/validate.sh
|
||||
✅ Now executable
|
||||
```
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
Complete checklist used for validation:
|
||||
|
||||
```
|
||||
Structure:
|
||||
□ .claude-plugin/plugin.json exists
|
||||
□ At least one component directory present
|
||||
□ README.md exists
|
||||
|
||||
Manifest:
|
||||
□ Valid JSON syntax
|
||||
□ name field: present, kebab-case
|
||||
□ version field: present, valid SemVer
|
||||
□ description field: present, non-empty
|
||||
□ Paths are relative (start with ./)
|
||||
□ Referenced paths exist
|
||||
|
||||
Commands:
|
||||
□ .md extension
|
||||
□ Frontmatter with description
|
||||
□ kebab-case naming
|
||||
□ Non-empty content
|
||||
|
||||
Skills:
|
||||
□ Directory structure (skill-name/SKILL.md)
|
||||
□ SKILL.md in uppercase
|
||||
□ Frontmatter with name and description
|
||||
□ Name matches directory (exact, kebab-case)
|
||||
|
||||
Agents:
|
||||
□ .md extension
|
||||
□ Frontmatter with description
|
||||
□ kebab-case naming
|
||||
□ Non-empty content
|
||||
|
||||
Hooks:
|
||||
□ hooks.json valid JSON
|
||||
□ Proper structure (hooks object)
|
||||
□ Valid event names
|
||||
□ Scripts use ${CLAUDE_PLUGIN_ROOT}
|
||||
□ Scripts exist
|
||||
□ Scripts are executable (chmod +x)
|
||||
```
|
||||
|
||||
## After Validation
|
||||
|
||||
### If Validation Passes
|
||||
|
||||
```
|
||||
✅ Plugin is valid and ready for testing!
|
||||
|
||||
Next steps:
|
||||
1. Test locally: /plugin-development:test-local
|
||||
2. Create dev marketplace and install
|
||||
3. Test all commands and features
|
||||
4. Register in team marketplace when ready
|
||||
```
|
||||
|
||||
### If Validation Fails
|
||||
|
||||
```
|
||||
❌ Please fix the errors above before testing.
|
||||
|
||||
Need help?
|
||||
- Review error messages for specific fixes
|
||||
- Check best practices: /plugin-development:help
|
||||
- Common issues documented in examples
|
||||
```
|
||||
|
||||
## Example Usage
|
||||
|
||||
**Input**: `/plugin-development:validate`
|
||||
|
||||
**Output**:
|
||||
```
|
||||
🔍 Validating plugin: my-awesome-plugin
|
||||
|
||||
✅ All checks passed
|
||||
✓ Structure correct
|
||||
✓ Manifest valid
|
||||
✓ 5 commands validated
|
||||
✓ 2 skills validated
|
||||
✓ 1 agent validated
|
||||
✓ Hooks configured correctly
|
||||
|
||||
✅ Plugin ready for testing!
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Validate often**: Run before testing or commits
|
||||
2. **Fix errors first**: Address critical issues before warnings
|
||||
3. **Read messages carefully**: Each error includes fix instructions
|
||||
4. **Use debug mode**: Run `claude --debug` for deep inspection
|
||||
5. **Incremental fixes**: Fix and re-validate one issue at a time
|
||||
|
||||
## Notes
|
||||
|
||||
- This command only reads files (no modifications)
|
||||
- Validation is comprehensive but not exhaustive
|
||||
- Some issues may only appear during runtime testing
|
||||
- Always test in a dev marketplace after validation passes
|
||||
Reference in New Issue
Block a user