commit c8b2901108f851e318867e48f2ea6b40748fe996 Author: Zhongwei Li Date: Sat Nov 29 18:47:48 2025 +0800 Initial commit diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..b3ed656 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,22 @@ +{ + "name": "plugin-development", + "description": "A comprehensive toolkit for creating, validating, and distributing Claude Code plugins", + "version": "1.1.0", + "author": { + "name": "Ivan Magda", + "email": "ivan.magda@outlook.com", + "url": "https://github.com/ivan-magda" + }, + "skills": [ + "./skills" + ], + "agents": [ + "./agents" + ], + "commands": [ + "./commands" + ], + "hooks": [ + "./hooks" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..f6ac3d8 --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# plugin-development + +A comprehensive toolkit for creating, validating, and distributing Claude Code plugins diff --git a/agents/plugin-reviewer.md b/agents/plugin-reviewer.md new file mode 100644 index 0000000..e44a4f3 --- /dev/null +++ b/agents/plugin-reviewer.md @@ -0,0 +1,384 @@ +--- +description: Reviews a plugin for correct structure, safe hooks, clear commands and skills, and marketplace readiness +capabilities: ["structure-audit", "hook-safety-checks", "component-validation", "marketplace-readiness"] +--- + +# Plugin Reviewer Agent + +Comprehensive audit of Claude Code plugins for structure, safety, and best practices. + +## Purpose + +This agent performs deep, multi-file analysis of plugins to ensure: +- Correct directory structure and file organization +- Valid manifests and configuration files +- Safe hook implementations +- Clear, well-documented components +- Marketplace readiness +- Adherence to naming conventions and best practices + +## What This Agent Does + +### Structure Audit +- Verifies standard directory layout +- Checks file naming conventions +- Validates component organization +- Ensures proper separation of concerns + +### Manifest Validation +- Inspects plugin.json for completeness +- Verifies required fields (name, version, description) +- Validates path references +- Checks author and metadata formatting + +### Component Analysis +- **Commands**: Frontmatter, descriptions, argument handling +- **Skills**: SKILL.md structure, progressive disclosure, trigger clarity +- **Agents**: Purpose clarity, capability definition, output format +- **Hooks**: Safety checks, timeout configuration, script permissions + +### Hook Safety Checks +- Verifies scripts use `${CLAUDE_PLUGIN_ROOT}` +- Checks for timeouts on potentially slow operations +- Validates exit code handling (blocking vs. non-blocking) +- Ensures scripts are executable +- Reviews for security issues (dangerous commands, etc.) + +### Marketplace Readiness +- README.md presence and quality +- Plugin discoverability (keywords, description) +- Documentation completeness +- Testing instructions +- Distribution readiness + +## When to Use This Agent + +Invoke this agent when: +- Preparing a plugin for release or distribution +- Conducting a comprehensive plugin audit +- Need detailed, multi-file analysis +- Want prioritized list of issues to fix +- Reviewing security and safety posture +- Before submitting to team marketplace + +**Do not use** for: +- Quick validation (use `/plugin-development:validate` instead) +- Single-file review +- Real-time development (too heavyweight) + +## How It Proceeds + +### Phase 1: Discovery (2-3 minutes) + +1. **Locate plugin root** + - Find `.claude-plugin/plugin.json` + - Identify plugin name and version + +2. **Map component structure** + - List all commands/agents/skills/hooks + - Identify which components are present + - Note directory organization + +### Phase 2: Detailed Analysis (5-10 minutes) + +3. **Manifest deep dive** + - Parse and validate plugin.json + - Check all fields for correctness + - Verify path resolution + - Validate SemVer versioning + +4. **Component-by-component review** + - Read each command file + - Analyze each skill directory + - Review each agent definition + - Inspect hooks configuration + +5. **Hook safety analysis** + - Read all hook scripts + - Check for dangerous patterns + - Verify portable paths + - Validate timeouts and exit codes + +6. **Documentation review** + - Check README.md quality + - Verify examples are present + - Assess discoverability + +### Phase 3: Reporting (1-2 minutes) + +7. **Categorize findings** + - Critical: Must fix before release + - High: Should fix soon + - Medium: Consider fixing + - Low: Nice to have + +8. **Generate report** + - Summary of findings + - Specific issues with locations + - Recommendations with examples + - Overall readiness assessment + +## Output Format + +### Report Structure + +```markdown +# Plugin Review: v + +## Summary +- Plugin: +- Version: +- Components: X commands, Y skills, Z agents, hooks: yes/no +- Overall: Ready / Needs Work / Not Ready + +## Critical Issues (Must Fix) + +### 1. [Issue Title] +**Location**: `path/to/file.ext:line` +**Problem**: [Description of issue] +**Impact**: [Why this matters] +**Fix**: [Specific steps to resolve] + +Example: +``` +[Code or config showing the fix] +``` + +## High Priority Issues (Should Fix) + +### 1. [Issue Title] +[Same structure as Critical] + +## Medium Priority Issues (Consider Fixing) + +### 1. [Issue Title] +[Same structure] + +## Low Priority (Nice to Have) + +### 1. [Issue Title] +[Same structure] + +## Positive Findings + +- ✅ [What the plugin does well] +- ✅ [Good practices observed] + +## Component-Specific Notes + +### Commands (X files) +- [Observations about commands] + +### Skills (Y skills) +- [Observations about skills] + +### Agents (Z agents) +- [Observations about agents] + +### Hooks +- [Observations about hooks] + +## Marketplace Readiness + +✅ Ready for marketplace +OR +❌ Not ready - fix critical and high priority issues first + +Checklist: +□ Structure valid +□ Manifest complete +□ Components documented +□ Hooks safe +□ README present +□ Examples included + +## Recommendations + +1. [Priority 1 recommendation] +2. [Priority 2 recommendation] +3. [Priority 3 recommendation] + +## Next Steps + +1. Fix critical issues +2. Address high priority issues +3. Re-run: /plugin-development:validate +4. Test locally: /plugin-development:test-local +5. Request another review if needed +``` + +## Common Issues Detected + +### Critical Issues + +1. **Absolute paths in configuration** + ```json + ❌ "commands": "/Users/you/plugin/commands" + ✅ "commands": "./commands/" + ``` + +2. **Hook scripts not executable** + ```bash + ❌ -rw-r--r-- validate.sh + ✅ -rwxr-xr-x validate.sh + Fix: chmod +x scripts/*.sh + ``` + +3. **Missing required manifest fields** + ```json + ❌ { "name": "plugin" } + ✅ { "name": "plugin", "version": "1.0.0", "description": "..." } + ``` + +4. **Skill name mismatch** + ``` + ❌ Directory: code-review/, Frontmatter: name: codeReview + ✅ Both: code-review + ``` + +### High Priority Issues + +1. **Hooks without timeouts on slow operations** + ```json + ❌ { "command": "npm install" } + ✅ { "command": "npm install", "timeout": 300000 } + ``` + +2. **Commands missing descriptions** + ```yaml + ❌ --- + --- + ✅ --- + description: What the command does + --- + ``` + +3. **Skills with vague trigger descriptions** + ```yaml + ❌ description: Helps with code + ✅ description: Use when reviewing code, analyzing PRs, or discussing code quality + ``` + +4. **Hook scripts with hardcoded paths** + ```bash + ❌ /Users/you/scripts/validate.sh + ✅ ${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh + ``` + +### Security Concerns + +1. **Dangerous hook commands** + - `rm -rf` without safeguards + - Unvalidated user input execution + - Credentials in scripts + +2. **Overly permissive tool access** + ```yaml + ⚠️ allowed-tools: Bash(*) + ✅ allowed-tools: Read, Grep, Glob + ``` + +## Validation Approach + +### File-by-File Analysis + +For each component file: +1. Parse frontmatter (if applicable) +2. Check required fields +3. Validate naming conventions +4. Review content quality +5. Flag issues with line numbers + +### Cross-File Consistency + +- Skill names match directories +- Hook scripts referenced actually exist +- Paths in plugin.json resolve correctly +- Naming is consistent throughout + +### Best Practice Checks + +- Progressive disclosure in skills +- Clear command descriptions +- Focused agent capabilities +- Safe hook implementations +- Comprehensive documentation + +## Tool Access + +This agent has access to: +- **Read**: Examine all plugin files +- **Grep**: Search for patterns +- **Glob**: Find files by pattern + +It does **not** modify files. All fixes are proposed in the report. + +## Example Invocation + +### From Main Conversation + +``` +/agents plugin-reviewer +``` + +### Via Task Tool + +``` +Please use the plugin-reviewer agent to conduct a comprehensive audit of this plugin before we distribute it to the team. +``` + +### From Skill + +The plugin-authoring skill may escalate: +``` +For a thorough review before release, I'll delegate to the plugin-reviewer agent. +``` + +## Performance Notes + +- **Runtime**: 5-15 minutes depending on plugin size +- **Context**: Separate from main conversation +- **Depth**: More thorough than `/plugin-development:validate` +- **Output**: Single comprehensive report + +## After Review + +### If Issues Found + +1. Review the report carefully +2. Fix critical issues first +3. Address high priority issues +4. Run `/plugin-development:validate` to confirm +5. Test locally: `/plugin-development:test-local` +6. Request another review if major changes made + +### If Review Passes + +1. Plugin is ready for distribution +2. Add to team marketplace +3. Update documentation +4. Announce to team + +## Best Practices Applied by This Agent + +1. **Safety first**: Hook security is top priority +2. **Actionable feedback**: Every issue includes fix instructions +3. **Prioritized**: Issues sorted by severity +4. **Specific**: Issues include file paths and line numbers +5. **Balanced**: Notes both problems and positive findings +6. **Comprehensive**: Covers all aspects of plugin quality + +## Limitations + +- Does not test runtime behavior (use local testing for that) +- Does not execute hooks or commands +- Cannot validate plugin logic correctness +- Does not check for performance issues +- Does not validate domain-specific correctness + +## Related Tools + +- **Quick validation**: `/plugin-development:validate` +- **Local testing**: `/plugin-development:test-local` +- **Skill guidance**: plugin-authoring Skill +- **Debug mode**: `claude --debug` for runtime issues diff --git a/commands/add-agent.md b/commands/add-agent.md new file mode 100644 index 0000000..2cedd2b --- /dev/null +++ b/commands/add-agent.md @@ -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=` (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=` argument was provided + - If yes: + - **Output**: "Using plugin specified via --plugin argument: " + - 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: " + + e. **Validate target plugin exists**: + - **Output**: "Validating plugin '' exists..." + - If plugin specified/selected, verify `plugins//.claude-plugin/plugin.json` exists + - If found: + - **Output**: "Plugin '' validated successfully" + - If not found: + - **Output**: "Error: Plugin '' not found" + - Show error: "Plugin '' 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//` 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 `/agents/` directory exists + - If it doesn't exist, create it (use `require_user_approval: false` for directory creation) +2. Create `/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 /agents/$1.md + +Plugin: +Agent: $1 +Description: $2 + +Next steps: +1. Edit /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=` 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 +``` diff --git a/commands/add-command.md b/commands/add-command.md new file mode 100644 index 0000000..7496ab5 --- /dev/null +++ b/commands/add-command.md @@ -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=` (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=` argument was provided + - If yes: + - **Output**: "Using plugin specified via --plugin argument: " + - 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: " + + e. **Validate target plugin exists**: + - **Output**: "Validating plugin '' exists..." + - If plugin specified/selected, verify `plugins//.claude-plugin/plugin.json` exists + - If found: + - **Output**: "Plugin '' validated successfully" + - If not found: + - **Output**: "Error: Plugin '' not found" + - Show error: "Plugin '' 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//` 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 `/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**: /:$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 /commands/$1.md + +Plugin: +Command: $1 +Description: $2 + +Next steps: +1. Edit /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: /:$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 +``` diff --git a/commands/add-hook.md b/commands/add-hook.md new file mode 100644 index 0000000..b4ae03d --- /dev/null +++ b/commands/add-hook.md @@ -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=` (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=` argument was provided + - If yes: + - **Output**: "Using plugin specified via --plugin argument: " + - 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: " + + e. **Validate target plugin exists**: + - **Output**: "Validating plugin '' exists..." + - If plugin specified/selected, verify `plugins//.claude-plugin/plugin.json` exists + - If found: + - **Output**: "Plugin '' validated successfully" + - If not found: + - **Output**: "Error: Plugin '' not found" + - Show error: "Plugin '' 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//` 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 `/hooks/` directory exists (use `require_user_approval: false`) +2. If `/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 `/scripts/` directory exists (use `require_user_approval: false`) +2. For PreToolUse, create `/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 `/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 /hooks/hooks.json +✓ Matcher: $2 (or default) +✓ Created script: /scripts/.sh (if applicable) + +Plugin: +Hook configuration: +- Event: $1 +- Matcher: $2 +- Script: ${CLAUDE_PLUGIN_ROOT}/scripts/.sh + +Next steps: +1. Edit /hooks/hooks.json to customize timeout or command +2. Edit /scripts/.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 +``` diff --git a/commands/add-skill.md b/commands/add-skill.md new file mode 100644 index 0000000..abe2193 --- /dev/null +++ b/commands/add-skill.md @@ -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=` (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=` argument was provided + - If yes: + - **Output**: "Using plugin specified via --plugin argument: " + - 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: " + + e. **Validate target plugin exists**: + - **Output**: "Validating plugin '' exists..." + - If plugin specified/selected, verify `plugins//.claude-plugin/plugin.json` exists + - If found: + - **Output**: "Plugin '' validated successfully" + - If not found: + - **Output**: "Error: Plugin '' not found" + - Show error: "Plugin '' 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//` as working directory + +### Create Skill Structure + +**Note**: All paths below are relative to the target plugin directory (determined in validation step). + +1. Ensure `/skills/` directory exists (create if needed, use `require_user_approval: false`) +2. Create skill directory: `/skills/$1/` +3. Create supporting directories: + - `/skills/$1/schemas/` + - `/skills/$1/templates/` + - `/skills/$1/examples/` + - `/skills/$1/best-practices/` + +### Create SKILL.md + +Create `/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 /skills/$1/SKILL.md +✓ Created supporting directories: + - /skills/$1/schemas/ + - /skills/$1/templates/ + - /skills/$1/examples/ + - /skills/$1/best-practices/ + +Plugin: +Skill: $1 +Description: $2 + +Next steps: +1. Edit /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// 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 +``` diff --git a/commands/init.md b/commands/init.md new file mode 100644 index 0000000..f3aa6a0 --- /dev/null +++ b/commands/init.md @@ -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 + - /plugin-development:add-skill + - /plugin-development:add-agent +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 diff --git a/commands/test-local.md b/commands/test-local.md new file mode 100644 index 0000000..8c09d81 --- /dev/null +++ b/commands/test-local.md @@ -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": "", + "description": "", + "version": "", + "source": "../" + } + ] +} +``` + +**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 @dev-marketplace + + Verify: + /help + (Your commands should appear) + +3️⃣ TEST COMMANDS + /: [args] + + Examples: + /:command1 + /:command2 arg + +4️⃣ ITERATION LOOP (After making changes) + + a. Edit your plugin files + b. Validate: /plugin-development:validate + c. Uninstall: /plugin uninstall @dev-marketplace + d. Reinstall: /plugin install @dev-marketplace + e. Test again: /: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: +- Source: ../ +``` + +## 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 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 diff --git a/commands/validate.md b/commands/validate.md new file mode 100644 index 0000000..e485df9 --- /dev/null +++ b/commands/validate.md @@ -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: + +✅ 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 diff --git a/hooks/hooks.json b/hooks/hooks.json new file mode 100644 index 0000000..8b9fa90 --- /dev/null +++ b/hooks/hooks.json @@ -0,0 +1,40 @@ +{ + "description": "Auto-validate basic plugin structure and format code after edits", + "hooks": { + "PreToolUse": [ + { + "matcher": "Write|Edit", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate-plugin.sh", + "timeout": 30 + } + ] + } + ], + "PostToolUse": [ + { + "matcher": "Write|Edit", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/format-or-lint.sh", + "timeout": 30 + } + ] + } + ], + "SessionStart": [ + { + "matcher": "startup", + "hooks": [ + { + "type": "command", + "command": "echo '✓ plugin-development loaded: Use /plugin-development:init to scaffold a new plugin'" + } + ] + } + ] + } +} diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..bd48ee1 --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,129 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:hyperskill/claude-code-marketplace:plugins/plugin-development", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "149cdff3c4c2b10ab962ee2c1ef78785bc1737c9", + "treeHash": "5f8402e3425b6ee10222d8819e0c60b0d1e72fedbee46b50f653a1d916871719", + "generatedAt": "2025-11-28T10:17:37.719322Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "plugin-development", + "description": "A comprehensive toolkit for creating, validating, and distributing Claude Code plugins", + "version": "1.1.0" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "7e40a2fdd33c71bf0aedffcb99b04edb883128201263f4af88d207f1c304f8e4" + }, + { + "path": "agents/plugin-reviewer.md", + "sha256": "b2564a6b73ca15916023377255afcaac29cfb96c1d53150d9ccb7bfdd75efaa5" + }, + { + "path": "hooks/hooks.json", + "sha256": "d0a49a21dc5c3dc92806d198f5ebbb1fa762b38dfa3b11eff141635af6dd1eb3" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "79e17e9c73c4f0aaf8b42282565ad6eac8fbfb733b09ae9a2d62b155afd4001f" + }, + { + "path": "commands/validate.md", + "sha256": "d2ebf7e2ae9064db1c29b9c5d3225f53834722255b78e92249c089b3f41928eb" + }, + { + "path": "commands/add-command.md", + "sha256": "a8b39cb46aa78e6bd2029fb96964aebac9499698f07cfc364dc92588c9011652" + }, + { + "path": "commands/add-skill.md", + "sha256": "625d19b59616d6ce5e50493780421d6bf682eb26a7a724c68e78a86efa20a6f9" + }, + { + "path": "commands/init.md", + "sha256": "2ad5ef2dcb47f55d0eed10f101f2d1eb61ddef5000bfc8f74ecf0a2c16e170d3" + }, + { + "path": "commands/add-agent.md", + "sha256": "ddb33e31bb2cadc6db6ae8a26b33d7fc346f50dc1d3006671f284c8670065260" + }, + { + "path": "commands/add-hook.md", + "sha256": "9d83c53e0ebbd2ec423944d44758ae068185f0513803d31328002d6fecf55b9b" + }, + { + "path": "commands/test-local.md", + "sha256": "962cfff40088a49a08077593cdec40c7181b507b8d080f655a68c6bd59a87b07" + }, + { + "path": "skills/plugin-authoring/SKILL.md", + "sha256": "f1f7fd2a1e62c1104cd072746c98104d45aa59108fbe57aad871462a924d9e5f" + }, + { + "path": "skills/plugin-authoring/schemas/plugin-manifest.md", + "sha256": "5cb9645ece62a19f8feca1ba1d3cf59ffc7c07a3bf3180c009010e308eae8a31" + }, + { + "path": "skills/plugin-authoring/schemas/marketplace-schema.md", + "sha256": "988393ba54d41dc7b07498db5f610738d7e4f89bee3ac58b1699e37163002ab0" + }, + { + "path": "skills/plugin-authoring/schemas/hooks-schema.md", + "sha256": "b4e54cc0cc52439baf25aa948cf08260d8c72c86c458237efd23a43c6ed6215c" + }, + { + "path": "skills/plugin-authoring/examples/testing-workflow.md", + "sha256": "f831efa815f482fee8f03cc078ec45754f94907a8c82e881bc1c82d084673c27" + }, + { + "path": "skills/plugin-authoring/examples/simple-plugin.md", + "sha256": "e3a4335978e255f2a6f8eadb7555fae5672e972d1a5526802757a5ec0b679ef8" + }, + { + "path": "skills/plugin-authoring/templates/command-template.md", + "sha256": "a672d0568129b1341f1c771e577a0e9c8b3ac9b479f5355ad5ec48f3fff533a9" + }, + { + "path": "skills/plugin-authoring/templates/skill-template.md", + "sha256": "2b7ae11946d9108aec512d593630f9babe47b930e90c5f3b3cf3d3d6de09375c" + }, + { + "path": "skills/plugin-authoring/templates/agent-template.md", + "sha256": "bc85933c047bed503aa5b42d8d7b6cf919ee27750dc92970a6d8645c42a43df4" + }, + { + "path": "skills/plugin-authoring/templates/plugin-manifest.json", + "sha256": "3c61491573f02126697871853f9a0d3508211e0ed6088b07544ea95c8e6fb45a" + }, + { + "path": "skills/plugin-authoring/templates/marketplace-manifest.json", + "sha256": "fb3a17392dfb7fd0692160152671041434ab75fb6172956d036332ecc6100a63" + }, + { + "path": "skills/plugin-authoring/best-practices/naming-conventions.md", + "sha256": "034e424d7f5ba92e5a25408cd41b3260e1dde9cfc514a1e586df6b5322099cd3" + }, + { + "path": "skills/plugin-authoring/best-practices/organization.md", + "sha256": "84fa7976e8c5c081dd923f56c12617c57bb977b9f94878b648e86b2e704e067a" + } + ], + "dirSha256": "5f8402e3425b6ee10222d8819e0c60b0d1e72fedbee46b50f653a1d916871719" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/skills/plugin-authoring/SKILL.md b/skills/plugin-authoring/SKILL.md new file mode 100644 index 0000000..cae0957 --- /dev/null +++ b/skills/plugin-authoring/SKILL.md @@ -0,0 +1,102 @@ +--- +name: plugin-authoring +description: Expert guidance for Claude Code plugin development. Use when creating or modifying plugins, working with plugin.json or marketplace.json, or adding commands, agents, Skills, or hooks. +allowed-tools: Read, Grep, Glob +--- + +# Plugin Authoring (Skill) + +You are the canonical guide for Claude Code plugin development. Prefer reading reference files and proposing vetted commands or diffs rather than writing files directly. + +## Triggers & Scope + +Activate whenever context includes `.claude-plugin/`, `plugin.json`, `marketplace.json`, `commands/`, `agents/`, `skills/`, or `hooks/`. + +## Flow of Operation + +1. **Diagnose** current repo layout (read-only) +2. **Propose** the minimal safe action (scaffold, validate, or review) +3. **Execute** via `/plugin-development:...` commands when the user agrees +4. **Escalate** to the **plugin-reviewer** agent for deep audits +5. **Guardrails**: default to read-only; ask before edits + +## Quick Links (Progressive Disclosure) + +- **Schemas**: [schemas/plugin-manifest.md](schemas/plugin-manifest.md), [schemas/hooks-schema.md](schemas/hooks-schema.md), [schemas/marketplace-schema.md](schemas/marketplace-schema.md) +- **Templates**: [templates/](templates/) +- **Examples**: [examples/](examples/) +- **Best practices**: [best-practices/](best-practices/) + +## Checklists + +### Component Checklist + +``` +□ .claude-plugin/plugin.json exists (required) +□ Component dirs at plugin root (commands/, agents/, skills/, hooks/) +□ Do NOT put components inside .claude-plugin/ directory +□ Commands use kebab-case naming +□ Skills have valid frontmatter (name + description required) +□ Skills name matches directory (lowercase-hyphenated, max 64 chars) +□ Hooks use ${CLAUDE_PLUGIN_ROOT} for paths (not relative paths) +□ All scripts are executable (chmod +x) +``` + +### Release Checklist + +``` +□ plugin.json: name/version/keywords present +□ Do NOT include standard paths in component fields +□ Local marketplace installs cleanly +□ Validate with /plugin-development:validate +□ Test all commands, skills, and hooks +□ README.md exists with usage examples +``` + +## Playbooks + +- **Scaffold** → `/plugin-development:init ` then fill templates +- **Add a component** → `/plugin-development:add-command|add-skill|add-agent|add-hook` +- **Validate** → `/plugin-development:validate` (schema & structure checks) +- **Test locally** → `/plugin-development:test-local` (dev marketplace) + +## Common Workflows + +### Creating a New Plugin + +1. Run `/plugin-development:init ` to scaffold structure +2. Edit `.claude-plugin/plugin.json` with your metadata +3. Add components using `/plugin-development:add-command`, etc. +4. Validate with `/plugin-development:validate` +5. Test locally with `/plugin-development:test-local` + +### Adding a Slash Command + +1. Run `/plugin-development:add-command ` +2. Edit `commands/.md` with instructions +3. Add frontmatter: `description` and `argument-hint` +4. Test: `/plugin install` your plugin, then `/` + +### Adding a Skill + +1. Run `/plugin-development:add-skill ` +2. Edit `skills//SKILL.md` with your instructions +3. **Frontmatter requirements**: + - `name`: lowercase, hyphenated, max 64 chars (required) + - `description`: include both WHAT the Skill does AND WHEN to use it, max 1024 chars (required) + - `allowed-tools`: comma-separated list of tools (optional, restricts tool access) +4. Keep SKILL.md concise; place details in sibling files (reference.md, examples.md, scripts/) + +### Troubleshooting + +- **Plugin not loading?** Check `plugin.json` paths are relative to plugin root. Do NOT include `commands`, `agents`, `skills`, or `hooks` fields for standard directories. +- **Commands not showing?** Verify `commands/` directory exists at plugin root with `.md` files. Do NOT add `commands` field to `plugin.json` for standard paths. +- **Hooks not running?** Ensure scripts are executable (`chmod +x`) and use `${CLAUDE_PLUGIN_ROOT}` for paths +- **Skill not triggering?** Check `name` matches directory and is lowercase-hyphenated (max 64 chars). Ensure `description` includes both what and when to use (max 1024 chars) + +## Notes + +- Prefer templates & scripts over freeform generation for deterministic tasks +- If writes are needed, propose a command or a PR-style diff first +- For complex audits, delegate to `/agents plugin-reviewer` +- Always validate with `/plugin-development:validate` before testing diff --git a/skills/plugin-authoring/best-practices/naming-conventions.md b/skills/plugin-authoring/best-practices/naming-conventions.md new file mode 100644 index 0000000..9aa313b --- /dev/null +++ b/skills/plugin-authoring/best-practices/naming-conventions.md @@ -0,0 +1,404 @@ +# Naming Conventions + +Consistent naming patterns for Claude Code plugins and components. + +## General Principles + +1. **Predictable**: Names should indicate purpose +2. **Consistent**: Follow patterns throughout plugin +3. **Case-sensitive**: Respect case conventions for each component type +4. **Descriptive**: Prefer clarity over brevity +5. **Avoid conflicts**: Namespace to prevent collisions + +## Plugin Names + +### Format + +**kebab-case** (lowercase with hyphens) + +### Examples + +✅ **Good**: +- `plugin-development` +- `code-review-tools` +- `git-workflow` +- `python-helpers` + +❌ **Bad**: +- `PluginDevelopment` (camelCase) +- `plugin_development` (snake_case) +- `plugindevelopment` (no separators) +- `PLUGIN-DEVELOPMENT` (uppercase) + +### Naming Tips + +- **Descriptive**: Name reflects functionality +- **Concise**: 1-3 words typical +- **No prefix**: Don't use "plugin-" prefix (redundant) + - ✅ `code-review` + - ❌ `plugin-code-review` + +## Command Names + +### Format + +**kebab-case** (lowercase with hyphens) + +Files: `command-name.md` + +### Examples + +✅ **Good**: +- `init.md` → `/plugin-name:init` +- `add-command.md` → `/plugin-name:add-command` +- `validate-all.md` → `/plugin-name:validate-all` +- `run-tests.md` → `/plugin-name:run-tests` + +❌ **Bad**: +- `Init.md` (capitalized) +- `add_command.md` (snake_case) +- `addCommand.md` (camelCase) + +### Command Invocation + +Commands can be invoked with or without the plugin prefix: + +**Full format**: `/plugin-name:command-name` + +**Examples**: +- `/plugin-development:init` +- `/git-workflow:commit-push` +- `/test-runner:run-all` + +### Namespacing + +**Plugin prefix is optional** unless there are name conflicts. When no conflict exists, you can use the command directly: + +- Direct: `/format-code` (when no conflict) +- Prefixed: `/my-tools:format-code` (when needed for disambiguation) + +Commands are automatically namespaced by plugin name: +- Plugin: `my-tools` +- Command file: `format.md` +- Invocation options: + - `/format` (if no other plugin has this command) + - `/my-tools:format` (when needed to disambiguate) + +This prevents conflicts between plugins. + +### Verb-Based Naming + +Start commands with action verbs: + +✅ **Good**: +- `create-component` +- `validate-config` +- `run-tests` +- `deploy-app` + +❌ **Bad**: +- `component-creation` (noun-based) +- `config-validation` (noun-based) + +## Skill Names + +### Format + +**kebab-case** (lowercase with hyphens) + +Directory: `skill-name/` +File: `SKILL.md` (always uppercase) + +### Examples + +✅ **Good**: +- `plugin-authoring/SKILL.md` +- `code-review/SKILL.md` +- `api-design/SKILL.md` + +❌ **Bad**: +- `PluginAuthoring/SKILL.md` (camelCase) +- `plugin_authoring/SKILL.md` (snake_case) +- `plugin-authoring/skill.md` (lowercase skill.md) + +### Frontmatter Name + +Should match directory name (recommended for consistency): + +```markdown +--- +name: plugin-authoring # Matches directory +description: ... +--- +``` + +❌ **Poor practice**: +``` +Directory: plugin-authoring/ +Frontmatter: name: PluginAuthoring # Doesn't match! Use kebab-case +``` + +**Note**: While the `name` field in frontmatter is what Claude uses to discover and reference Skills, having it match the directory name prevents confusion and follows best practices. + +### Skill Naming Tips + +- **Domain-focused**: Name reflects area of expertise +- **Singular**: `code-review` not `code-reviews` +- **Avoid "skill" suffix**: Name is the capability + - ✅ `plugin-authoring` + - ❌ `plugin-authoring-skill` + +## Agent Names + +### Format + +**kebab-case** (lowercase with hyphens) + +Files: `agent-name.md` + +### Examples + +✅ **Good**: +- `code-reviewer.md` +- `test-analyzer.md` +- `security-auditor.md` +- `plugin-reviewer.md` + +❌ **Bad**: +- `CodeReviewer.md` (camelCase) +- `code_reviewer.md` (snake_case) + +### Agent Naming Tips + +- **Role-based**: Name indicates what agent does +- **Often noun**: Describes the agent's role + - `reviewer`, `analyzer`, `auditor` +- **Suffix optional**: `-er`, `-or` common but not required + - ✅ `code-reviewer` + - ✅ `security-audit` + +## Hook Script Names + +### Format + +**kebab-case** (lowercase with hyphens) + +Extension: `.sh` for bash scripts + +### Examples + +✅ **Good**: +- `validate-plugin.sh` +- `format-code.sh` +- `pre-write-check.sh` +- `session-start-info.sh` + +❌ **Bad**: +- `validatePlugin.sh` (camelCase) +- `validate_plugin.sh` (snake_case) +- `VALIDATE-PLUGIN.sh` (uppercase) + +### Hook Naming Tips + +- **Purpose-based**: Name indicates what hook does +- **Event optional**: Can include event in name + - `pre-write-validate.sh` + - `post-write-format.sh` + +## Marketplace Names + +### Format + +**kebab-case** (lowercase with hyphens) + +### Examples + +✅ **Good**: +- `team-tools` +- `acme-plugins` +- `dev-marketplace` +- `internal-tools` + +❌ **Bad**: +- `TeamTools` (camelCase) +- `team_tools` (snake_case) + +## Variable and Argument Names + +### In Commands + +Use uppercase with underscores for built-in variables: +- `$ARGUMENTS`: All arguments as string +- `$1`, `$2`, etc.: Individual arguments + +### In Documentation + +Use lowercase with hyphens in examples: +```markdown +argument-hint: [plugin-name] [command-type] +``` + +## File Extensions + +### Markdown + +- Commands: `.md` +- Agents: `.md` +- Skills: `SKILL.md` (specific name) +- Documentation: `.md` + +### Configuration + +- Plugin manifest: `plugin.json` +- Marketplace manifest: `marketplace.json` +- Hooks config: `hooks.json` + +### Scripts + +- Bash: `.sh` +- Python: `.py` +- Node: `.js` + +## Directory Names + +### Standard Directories + +Use these exact names: +- `commands/` (not `command/` or `cmd/`) +- `agents/` (not `agent/` or `subagents/`) +- `skills/` (not `skill/`) +- `hooks/` (not `hook/`) +- `scripts/` (not `script/` or `bin/`) + +### Custom Directories + +For additional organization, use kebab-case: +- `templates/` +- `schemas/` +- `examples/` +- `best-practices/` +- `test-fixtures/` + +## Metadata Fields + +### In plugin.json + +```json +{ + "name": "kebab-case", + "description": "Sentence case with capital first letter", + "keywords": ["lowercase", "multi-word-hyphenated"], + "license": "UPPERCASE (e.g., MIT, Apache-2.0)" +} +``` + +### Author Names + +Use natural capitalization: +```json +{ + "author": { + "name": "John Smith", + "email": "john@example.com" + } +} +``` + +## Category and Tag Conventions + +### Categories + +Use singular, lowercase: +- `development` +- `productivity` +- `utilities` +- `devops` + +### Tags + +Use lowercase, hyphenated for multi-word: +- `code-review` +- `testing` +- `deployment` +- `git-workflow` + +## Consistency Checklist + +``` +□ Plugin name: kebab-case +□ Commands: kebab-case, .md extension +□ Skills: kebab-case directory, SKILL.md file +□ Agents: kebab-case, .md extension +□ Scripts: kebab-case, appropriate extension +□ Directories: standard names (commands/, agents/, etc.) +□ Frontmatter names match directory/file names +□ Categories and tags: lowercase +``` + +## Examples by Component + +### Complete Plugin + +``` +my-dev-tools/ # kebab-case +├── .claude-plugin/ +│ └── plugin.json # name: "my-dev-tools" +├── commands/ +│ ├── format-code.md # kebab-case +│ ├── run-tests.md # kebab-case +│ └── validate-all.md # kebab-case +├── agents/ +│ └── code-reviewer.md # kebab-case +├── skills/ +│ └── code-quality/ # kebab-case +│ └── SKILL.md # UPPERCASE +├── hooks/ +│ └── hooks.json +└── scripts/ + ├── pre-write-check.sh # kebab-case + └── post-write-format.sh # kebab-case +``` + +### Invocations + +```bash +/my-dev-tools:format-code +/my-dev-tools:run-tests +/my-dev-tools:validate-all +``` + +## Anti-Patterns + +### ❌ Mixed Case + +``` +MyDevTools/ +├── commands/ +│ ├── FormatCode.md # Wrong! +│ └── runTests.md # Wrong! +``` + +### ❌ Inconsistent Separators + +``` +my_dev_tools/ # snake_case +├── commands/ +│ ├── format-code.md # kebab-case +│ └── runTests.md # camelCase +``` + +### ❌ Wrong SKILL.md Case + +``` +skills/ +└── my-skill/ + └── skill.md # Should be SKILL.md +``` + +## When in Doubt + +Follow these defaults: +- **Files/directories**: kebab-case +- **SKILL.md**: Always uppercase +- **JSON fields**: Follow schema (usually camelCase for author fields, kebab-case for names) +- **Invocation**: `/plugin-name:command-name` (always kebab-case) diff --git a/skills/plugin-authoring/best-practices/organization.md b/skills/plugin-authoring/best-practices/organization.md new file mode 100644 index 0000000..f62dea9 --- /dev/null +++ b/skills/plugin-authoring/best-practices/organization.md @@ -0,0 +1,440 @@ +# Plugin Organization Best Practices + +Guidelines for structuring well-organized, maintainable Claude Code plugins. + +## Directory Structure + +### Standard Layout + +``` +plugin-name/ +├── .claude-plugin/ +│ └── plugin.json # Manifest only +├── commands/ # Slash commands (*.md) +├── agents/ # Sub-agents (*.md) +├── skills/ # Skills (folders with SKILL.md) +├── hooks/ # Hook configurations +│ └── hooks.json # Main hook config file +├── scripts/ # Hook scripts, utilities +└── README.md # User-facing documentation +``` + +### Key Principles + +1. **Manifest isolation**: Only `plugin.json` goes in `.claude-plugin/` +2. **Component separation**: Keep commands, agents, skills, and hooks in separate directories +3. **Relative paths**: All paths in manifests are relative to plugin root +4. **Default directories**: Standard directories (`commands/`, `agents/`, `skills/`, `hooks/`) are automatically discovered +5. **Flat commands**: Command files go directly in `commands/`, not subdirectories (unless using custom paths) +6. **Nested skills**: Skills are folders with `SKILL.md` + support files +7. **Custom paths**: Use component fields in `plugin.json` only for non-standard locations + +## File Naming + +### Commands + +- **Format**: `command-name.md` +- **Case**: kebab-case (lowercase with hyphens) +- **Examples**: `init.md`, `add-command.md`, `validate.md` + +### Agents + +- **Format**: `agent-name.md` +- **Case**: kebab-case +- **Examples**: `code-reviewer.md`, `test-analyzer.md` + +### Skills + +- **Format**: `skill-name/SKILL.md` (directory + SKILL.md) +- **Case**: kebab-case for directory +- **Examples**: `plugin-authoring/SKILL.md`, `code-review/SKILL.md` + +### Hooks + +- **Standard**: `hooks.json` (one per plugin) +- **Scripts**: `scripts/script-name.sh` (kebab-case) + +## Skill Organization + +### Progressive Disclosure Pattern + +Keep `SKILL.md` concise (< 500 lines) and link to detailed files: + +``` +skills/my-skill/ +├── SKILL.md # Main skill definition (concise) +├── schemas/ # Data format documentation +│ └── config-schema.md +├── templates/ # Reusable templates +│ └── config-template.json +├── examples/ # Usage examples +│ └── basic-usage.md +└── best-practices/ # Detailed guidance + └── patterns.md +``` + +### SKILL.md Structure + +```markdown +--- +name: skill-name +description: What and when (concise, < 200 chars) +allowed-tools: Read, Grep, Glob +--- + +# Skill Name + +[2-3 sentence overview] + +## Quick Links +- [Reference 1](./reference1.md) +- [Reference 2](./reference2.md) + +## [Concise sections...] +``` + +## Command Organization + +### Simple Plugins + +For plugins with few commands (< 5): + +``` +commands/ +├── command1.md +├── command2.md +└── command3.md +``` + +### Complex Plugins + +For plugins with many related commands, consider namespacing: + +``` +commands/ +├── git-commit.md +├── git-push.md +├── git-branch.md +├── test-unit.md +├── test-integration.md +└── test-e2e.md +``` + +Commands are invoked as `/plugin-name:git-commit`, etc. + +## Hook Organization + +### Simple Hooks + +Hooks configuration goes in `hooks/hooks.json`: + +``` +hooks/ +└── hooks.json +``` + +Alternatively, hooks can be defined inline in `plugin.json` or specified via the `hooks` field: + +```json +{ + "name": "my-plugin", + "hooks": "./hooks/hooks.json" +} +``` + +Or inline configuration: + +```json +{ + "name": "my-plugin", + "hooks": { + "PostToolUse": [...] + } +} +``` + +### Complex Hooks + +With multiple scripts, organize them under `hooks/scripts/`: + +``` +hooks/ +├── hooks.json +└── scripts/ + ├── pre-write-validation.sh + ├── post-write-format.sh + └── session-start-info.sh +``` + +Reference scripts using the `${CLAUDE_PLUGIN_ROOT}` environment variable: + +```json +{ + "hooks": { + "PostToolUse": [ + { + "matcher": "Write|Edit", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/pre-write-validation.sh" + } + ] + } + ] + } +} +``` + +## Documentation Structure + +### README.md (Required) + +User-facing documentation: + +```markdown +# Plugin Name + +Brief description + +## Installation + +[How to install] + +## Usage + +[Commands, examples] + +## Configuration + +[If applicable] +``` + +### Additional Docs + +For complex plugins: + +``` +docs/ +├── getting-started.md +├── api-reference.md +├── troubleshooting.md +└── examples/ + ├── basic.md + └── advanced.md +``` + +## Size Guidelines + +### Keep Components Focused + +- **Commands**: 50-200 lines (including examples) +- **Skills**: SKILL.md < 500 lines, plus support files +- **Agents**: 100-400 lines +- **Hooks**: Keep scripts fast (< 1 second runtime) + +### When to Split + +Consider splitting when: +- Single skill > 500 lines → Create multiple skills +- Many related commands → Create separate plugins +- Complex logic → Move to support files with progressive disclosure + +## Common Patterns + +### Multi-Component Plugin + +Combines multiple component types: + +``` +my-dev-tools/ +├── .claude-plugin/plugin.json +├── commands/ # Quick actions +│ ├── format.md +│ └── lint.md +├── agents/ # Deep analysis +│ └── code-reviewer.md +├── skills/ # Ambient guidance +│ └── code-review/SKILL.md +└── hooks/ # Automation + ├── hooks.json + └── scripts/ +``` + +### Command-Only Plugin + +Simple plugins with just commands: + +``` +utility-commands/ +├── .claude-plugin/plugin.json +├── commands/ +│ ├── command1.md +│ ├── command2.md +│ └── command3.md +└── README.md +``` + +### Skill-Focused Plugin + +Domain expertise plugins: + +``` +framework-expert/ +├── .claude-plugin/plugin.json +├── skills/ +│ └── framework-guidance/ +│ ├── SKILL.md +│ ├── schemas/ +│ ├── templates/ +│ └── examples/ +└── README.md +``` + +## Versioning + +### Plugin Versioning + +Use **SemVer** in `plugin.json`: +- **Major** (1.0.0): Breaking changes +- **Minor** (0.1.0): New features, backward compatible +- **Patch** (0.0.1): Bug fixes + +### Change Documentation + +Maintain `CHANGELOG.md`: + +```markdown +# Changelog + +## [1.1.0] - 2024-01-15 +### Added +- New command: validate-all + +### Changed +- Improved error messages + +## [1.0.0] - 2024-01-01 +### Added +- Initial release +``` + +## Testing Organization + +### Test Structure + +``` +tests/ +├── commands/ +│ ├── test-command1.sh +│ └── test-command2.sh +├── hooks/ +│ ├── test-validation.sh +│ └── test-formatting.sh +└── integration/ + └── test-workflow.sh +``` + +### Validation Scripts + +Keep in `scripts/` for reuse: + +``` +scripts/ +├── validate-plugin.sh # Used by hooks +├── validate-commands.sh # Used by tests +└── validate-manifest.sh # Used by CI +``` + +## Anti-Patterns + +### ❌ Don't: Components in .claude-plugin/ + +``` +.claude-plugin/ +├── plugin.json +├── commands/ # Wrong! +└── hooks.json # Wrong! +``` + +### ✅ Do: Components at Plugin Root + +``` +.claude-plugin/ +└── plugin.json # Only manifest +commands/ # At root +hooks/ # At root +``` + +### ❌ Don't: Specify Default Paths in Manifest + +```json +{ + "name": "my-plugin", + "commands": "./commands/", + "agents": "./agents/" +} +``` + +### ✅ Do: Omit Component Fields When Using Default Directories + +```json +{ + "name": "my-plugin" +} +``` + +When using standard directories (`commands/`, `agents/`, `skills/`, `hooks/`), they are automatically discovered and you don't need to specify them in `plugin.json`. Only use component fields (`commands`, `agents`, etc.) when: +1. Using non-standard directory names (e.g., `./custom-commands/`) +2. Including specific individual files (e.g., `["./commands/special.md"]`) +3. Combining custom paths with default paths + +### ❌ Don't: Absolute Paths + +```json +{ + "commands": ["/Users/you/plugins/my-plugin/commands/cmd.md"] +} +``` + +### ✅ Do: Relative Paths (for custom paths only) + +```json +{ + "commands": ["./custom/cmd.md"] +} +``` + +### ❌ Don't: Monolithic Skills + +```markdown +# SKILL.md (3000 lines) +[Everything in one file...] +``` + +### ✅ Do: Progressive Disclosure + +```markdown +# SKILL.md (400 lines) +Quick Links: +- [Details](./details.md) +- [Examples](./examples/) +``` + +## Summary Checklist + +``` +□ Manifest isolated in .claude-plugin/ +□ Components at plugin root (not inside .claude-plugin/) +□ Default directories (commands/, agents/, skills/, hooks/) are automatically discovered +□ Component fields in plugin.json only when using custom paths +□ Kebab-case naming throughout +□ Relative paths in all configs (start with ./) +□ Skills use progressive disclosure +□ Commands are focused (< 200 lines) +□ Scripts are executable +□ Hooks reference scripts using ${CLAUDE_PLUGIN_ROOT} +□ README.md documents usage +□ Version follows SemVer +□ CHANGELOG.md tracks changes +``` diff --git a/skills/plugin-authoring/examples/simple-plugin.md b/skills/plugin-authoring/examples/simple-plugin.md new file mode 100644 index 0000000..7d3d144 --- /dev/null +++ b/skills/plugin-authoring/examples/simple-plugin.md @@ -0,0 +1,135 @@ +# Example: Simple Plugin + +This example shows a minimal but complete Claude Code plugin. + +## Directory Structure + +``` +my-greeting-plugin/ +├── .claude-plugin/ +│ └── plugin.json +├── commands/ +│ └── greet.md +└── README.md +``` + +## plugin.json + +```json +{ + "name": "my-greeting-plugin", + "version": "1.0.0", + "description": "A simple greeting plugin", + "author": { + "name": "Your Name" + }, + "license": "MIT", + "keywords": ["greeting", "example"] +} +``` + +**Note**: No `commands` field needed since we're using the standard `commands/` directory. + +## commands/greet.md + +```markdown +--- +description: Greet the user with a personalized message +argument-hint: [name] +--- + +# Greet Command + +Provide a warm, friendly greeting to the user. + +## Instructions + +1. If the user provided a name via `$ARGUMENTS`, greet them personally +2. If no name provided, use a generic friendly greeting +3. Add a fun emoji to make it welcoming + +## Examples + +**Input**: `/my-greeting-plugin:greet Alice` +**Output**: "Hello, Alice! 👋 Great to see you!" + +**Input**: `/my-greeting-plugin:greet` +**Output**: "Hello there! 👋 How can I help you today?" +``` + +## README.md + +```markdown +# My Greeting Plugin + +A simple example plugin that demonstrates Claude Code plugin basics. + +## Installation + +From a marketplace: +```bash +/plugin install my-greeting-plugin@marketplace-name +``` + +## Usage + +```bash +/my-greeting-plugin:greet [name] +``` + +## Examples + +- `/my-greeting-plugin:greet World` - Greet with a name +- `/my-greeting-plugin:greet` - Generic greeting +``` + +## Adding to a Marketplace + +In your marketplace's `.claude-plugin/marketplace.json`: + +```json +{ + "plugins": [ + { + "name": "my-greeting-plugin", + "description": "A simple greeting plugin", + "version": "1.0.0", + "author": { + "name": "Your Name" + }, + "source": "./plugins/my-greeting-plugin", + "category": "examples", + "tags": ["greeting", "example"] + } + ] +} +``` + +## Testing Locally + +1. Create the plugin structure +2. Create a dev marketplace: + ```bash + mkdir -p dev-marketplace/.claude-plugin + ``` +3. Create `dev-marketplace/.claude-plugin/marketplace.json` (see above) +4. Add marketplace: + ```bash + /plugin marketplace add ./dev-marketplace + ``` +5. Install plugin: + ```bash + /plugin install my-greeting-plugin@dev-marketplace + ``` +6. Test command: + ```bash + /my-greeting-plugin:greet World + ``` + +## Key Takeaways + +- **Minimal structure**: Only `.claude-plugin/plugin.json` and `commands/` are required +- **Frontmatter**: Commands need `description` (and optionally `argument-hint`) +- **Namespacing**: Commands are called with `/plugin-name:command-name` +- **Arguments**: Access via `$ARGUMENTS` or `$1`, `$2`, etc. +- **Standard paths**: No need to specify component fields in `plugin.json` when using standard directories diff --git a/skills/plugin-authoring/examples/testing-workflow.md b/skills/plugin-authoring/examples/testing-workflow.md new file mode 100644 index 0000000..9cc2d5c --- /dev/null +++ b/skills/plugin-authoring/examples/testing-workflow.md @@ -0,0 +1,233 @@ +# Testing Workflow + +A step-by-step guide to testing plugins locally during development. + +## Overview + +Testing plugins locally uses a **dev marketplace** that points to your working plugin directory. This allows you to: +- Test changes without publishing +- Iterate quickly +- Validate before distribution + +## Setup: One-Time + +### 1. Create Dev Marketplace Structure + +```bash +# From your project root +mkdir -p dev-marketplace/.claude-plugin +``` + +### 2. Create marketplace.json + +Create `dev-marketplace/.claude-plugin/marketplace.json`: + +```json +{ + "name": "dev-marketplace", + "owner": { + "name": "Developer" + }, + "metadata": { + "description": "Local development marketplace", + "version": "0.1.0" + }, + "plugins": [ + { + "name": "my-plugin", + "description": "Plugin under development", + "source": "../plugins/my-plugin" + } + ] +} +``` + +**Key**: `source` points to your plugin directory (relative path from marketplace). + +### 3. Add Marketplace to Claude Code + +```bash +claude +/plugin marketplace add ./dev-marketplace +``` + +Verify: +```bash +/plugin marketplace list +``` + +You should see `dev-marketplace` listed. + +## Iteration Loop + +### Install Plugin + +```bash +/plugin install my-plugin@dev-marketplace +``` + +### Test Commands + +```bash +/my-plugin:command-name args +``` + +Or test via `/help` to see if commands appear. + +### Make Changes + +Edit your plugin files (commands, skills, etc.). + +### Reinstall + +```bash +/plugin uninstall my-plugin@dev-marketplace +/plugin install my-plugin@dev-marketplace +``` + +**Note**: You must uninstall/reinstall to pick up changes. + +### Repeat + +Continue the edit → reinstall → test cycle. + +## Validation + +Before each test cycle, validate your plugin: + +```bash +/plugin-development:validate +``` + +This checks: +- `plugin.json` exists and is valid JSON +- Component directories exist +- Paths are correct +- No common mistakes + +## Debugging + +### Plugin Not Loading + +1. Check `plugin.json` exists at `.claude-plugin/plugin.json` +2. Verify JSON syntax: `cat .claude-plugin/plugin.json | jq .` +3. Check paths are relative: `./commands/` not `/absolute/path/` + +### Commands Not Showing + +1. Verify `commands` field in `plugin.json` points to `./commands/` +2. Check command files have `.md` extension +3. Verify frontmatter has `description` field +4. Reinstall the plugin + +### Hooks Not Running + +1. Check `hooks` field in `plugin.json` points to correct path +2. Verify `hooks.json` is valid JSON +3. Make scripts executable: `chmod +x scripts/*.sh` +4. Test script directly: `./scripts/validate-plugin.sh` +5. Use `claude --debug` to see hook execution + +### Skills Not Triggering + +1. Check `skills` field in `plugin.json` (if specified) +2. Verify `SKILL.md` has frontmatter with `name` and `description` +3. Ensure `name` matches directory name (lowercase, hyphenated) +4. Check `description` includes clear trigger conditions + +## Advanced: Debug Mode + +Run Claude Code in debug mode to see detailed plugin loading: + +```bash +claude --debug +``` + +This shows: +- Plugin registration +- Component discovery +- Hook execution +- Tool usage + +Look for errors related to your plugin in the output. + +## Multiple Plugins + +You can test multiple plugins from one dev marketplace: + +```json +{ + "plugins": [ + { + "name": "plugin-one", + "source": "../plugins/plugin-one" + }, + { + "name": "plugin-two", + "source": "../plugins/plugin-two" + } + ] +} +``` + +Install each separately: +```bash +/plugin install plugin-one@dev-marketplace +/plugin install plugin-two@dev-marketplace +``` + +## Clean Up + +### Uninstall Plugin + +```bash +/plugin uninstall my-plugin@dev-marketplace +``` + +### Remove Marketplace + +```bash +/plugin marketplace remove dev-marketplace +``` + +## Best Practices + +1. **Validate first**: Always run `/plugin-development:validate` before testing +2. **Small changes**: Test incrementally, don't make many changes at once +3. **Check logs**: Use `--debug` when troubleshooting +4. **Script testing**: Test hook scripts directly before adding to hooks.json +5. **Clean installs**: Uninstall fully before reinstalling to avoid cache issues + +## Troubleshooting Checklist + +``` +□ plugin.json exists and is valid JSON +□ All paths are relative (start with ./) +□ Component directories exist (commands/, etc.) +□ Command files have .md extension +□ Scripts are executable (chmod +x) +□ marketplace.json plugin name matches plugin.json name +□ Reinstalled after making changes +``` + +## Example Session + +```bash +# One-time setup +mkdir -p dev-marketplace/.claude-plugin +# ... create marketplace.json ... +/plugin marketplace add ./dev-marketplace + +# Development loop +/plugin install my-plugin@dev-marketplace +/my-plugin:test-command + +# Make changes to plugin files... + +/plugin-development:validate +/plugin uninstall my-plugin@dev-marketplace +/plugin install my-plugin@dev-marketplace +/my-plugin:test-command + +# Repeat... +``` diff --git a/skills/plugin-authoring/schemas/hooks-schema.md b/skills/plugin-authoring/schemas/hooks-schema.md new file mode 100644 index 0000000..df3aa74 --- /dev/null +++ b/skills/plugin-authoring/schemas/hooks-schema.md @@ -0,0 +1,333 @@ +# Hooks Schema + +Hooks allow you to run commands at specific lifecycle events. Define them in `hooks/hooks.json`. + +## Location + +`hooks/hooks.json` (at plugin root, referenced in `plugin.json`) + +## Structure + +```json +{ + "description": "Optional description of what these hooks do", + "hooks": { + "EventName": [ + { + "matcher": "pattern", + "hooks": [ + { + "type": "command", + "command": "path/to/script.sh", + "timeout": 30 + } + ] + } + ] + } +} +``` + +## Event Types + +### PreToolUse + +Runs **before** Claude uses a tool. Can block tool execution. + +```json +{ + "PreToolUse": [ + { + "matcher": "Write|Edit", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh", + "timeout": 30 + } + ] + } + ] +} +``` + +**Matcher**: Regex pattern matching tool names (e.g., `Write`, `Read`, `Bash.*`) + +**Exit codes**: +- `0`: Allow (stdout visible to Claude) +- `2`: **Block** (stderr shown to Claude as feedback) +- Other: Warning (non-blocking) + +### PostToolUse + +Runs **after** a tool completes. Cannot block. + +```json +{ + "PostToolUse": [ + { + "matcher": "Write|Edit", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh", + "timeout": 30 + } + ] + } + ] +} +``` + +### SessionStart + +Runs when Claude Code session starts. + +```json +{ + "SessionStart": [ + { + "matcher": "startup", + "hooks": [ + { + "type": "command", + "command": "echo 'Plugin loaded!'" + } + ] + } + ] +} +``` + +**Matchers**: +- `startup` - Invoked from startup +- `resume` - Invoked from `--resume`, `--continue`, or `/resume` +- `clear` - Invoked from `/clear` +- `compact` - Invoked from auto or manual compact + +**Note**: SessionStart stdout is added to context automatically for Claude. + +### SessionEnd + +Runs when a Claude Code session ends. + +```json +{ + "SessionEnd": [ + { + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/cleanup.sh" + } + ] + } + ] +} +``` + +### UserPromptSubmit + +Runs when user submits a prompt. Can block prompt processing. + +```json +{ + "UserPromptSubmit": [ + { + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/context-injector.sh" + } + ] + } + ] +} +``` + +**Exit codes**: +- `0`: Allow (stdout added to context) +- `2`: **Block** (stderr shown to user) + +### Stop / SubagentStop + +Runs when Claude attempts to stop (main agent or subagent). + +```json +{ + "Stop": [ + { + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/check-continuation.sh" + } + ] + } + ] +} +``` + +## Environment Variables + +Available in hook commands: + +- `${CLAUDE_PLUGIN_ROOT}`: Absolute path to plugin root +- `${CLAUDE_PROJECT_DIR}`: Project root directory (where Claude Code started) +- Standard shell environment variables + +## Timeouts + +- Default: No timeout +- Recommended: 10-30 seconds for validation +- Max: Keep under 60 seconds for good UX + +## Common Patterns + +### Validation Hook (Blocking) + +```json +{ + "PreToolUse": [ + { + "matcher": "Write|Edit", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh", + "timeout": 30 + } + ] + } + ] +} +``` + +**validate.sh**: +```bash +#!/usr/bin/env bash +if [ validation_fails ]; then + echo "Error: validation failed" >&2 + exit 2 # Block the tool +fi +exit 0 # Allow +``` + +**Advanced JSON output** (alternative to exit codes): +```json +{ + "permissionDecision": "deny", + "permissionDecisionReason": "File violates security policy", + "suppressOutput": true +} +``` + +### Formatting Hook (Non-blocking) + +```json +{ + "PostToolUse": [ + { + "matcher": "Write|Edit", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh", + "timeout": 30 + } + ] + } + ] +} +``` + +### Startup Message + +```json +{ + "SessionStart": [ + { + "matcher": "startup", + "hooks": [ + { + "type": "command", + "command": "echo '✓ My Plugin loaded'" + } + ] + } + ] +} +``` + +## Best Practices + +- **Use `${CLAUDE_PLUGIN_ROOT}`** for portable paths +- **Set timeouts** to prevent hanging (10-30 seconds recommended) +- **Exit code 2** to block (PreToolUse/UserPromptSubmit) +- **Keep scripts fast** (< 1 second ideally) +- **Make scripts executable** (`chmod +x`) +- **Test hooks** before distributing +- **Handle JSON output** for advanced control (see advanced examples) + +## Common Mistakes + +❌ **Absolute paths** (not portable) +```json +{ + "command": "/Users/you/plugin/scripts/validate.sh" +} +``` + +✅ **Plugin-relative paths** +```json +{ + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh" +} +``` + +❌ **No timeout** on slow operations +```json +{ + "command": "npm install" + // Missing timeout! +} +``` + +✅ **Set appropriate timeout** +```json +{ + "command": "npm install", + "timeout": 300000 +} +``` + +❌ **Missing required matcher** +```json +{ + "SessionStart": [ + { + "hooks": [...] // No matcher! + } + ] +} +``` + +✅ **Include appropriate matcher** +```json +{ + "SessionStart": [ + { + "matcher": "startup", + "hooks": [...] + } + ] +} +``` + +## Debugging + +Use `claude --debug` to see: +- Hook registration +- Hook execution timing +- Exit codes and output +- Blocking decisions diff --git a/skills/plugin-authoring/schemas/marketplace-schema.md b/skills/plugin-authoring/schemas/marketplace-schema.md new file mode 100644 index 0000000..e9c61c4 --- /dev/null +++ b/skills/plugin-authoring/schemas/marketplace-schema.md @@ -0,0 +1,359 @@ +# Marketplace Schema + +The `marketplace.json` file defines a collection of plugins that users can install. + +## Location + +`.claude-plugin/marketplace.json` (at marketplace root) + +## Structure + +```json +{ + "name": "marketplace-name", + "owner": { + "name": "Your Organization", + "email": "team@your-org.com" + }, + "metadata": { + "description": "Marketplace description", + "version": "1.0.0" + }, + "plugins": [ + { + "name": "plugin-name", + "description": "What the plugin does", + "version": "1.0.0", + "author": { + "name": "Author Name" + }, + "source": "./plugins/plugin-name", + "category": "utilities", + "tags": ["tag1", "tag2"], + "keywords": ["keyword1", "keyword2"] + } + ] +} +``` + +## Required Fields + +### Marketplace Level + +- **name**: kebab-case string, unique marketplace identifier +- **owner**: Object with `name` (required) and optional `email` +- **plugins**: Array of plugin entries + +### Plugin Entry + +- **name**: Plugin name (must match `plugin.json`) +- **source**: Relative path to plugin directory OR git URL + +## Optional Fields + +### Marketplace Level + +- **metadata**: Object with: + - **description**: Brief marketplace description + - **version**: Marketplace version + - **pluginRoot**: Base path for relative plugin sources (allows resolving relative plugin paths) + +### Plugin Entry + +**Standard metadata fields:** + +- **description**: Brief description +- **version**: SemVer version +- **author**: String or object with `name`, `email`, `url` +- **category**: Category string (e.g., "utilities", "productivity") +- **tags**: Array of tags for filtering +- **keywords**: Array of keywords for search +- **homepage**: Plugin homepage URL +- **repository**: Plugin repository URL +- **license**: License identifier (e.g., "MIT") +- **strict**: Boolean (default: true) - Require plugin.json in plugin folder + +**Component configuration fields:** + +- **commands**: String or array - Custom paths to command files or directories +- **agents**: String or array - Custom paths to agent files +- **hooks**: String or object - Custom hooks configuration or path to hooks file +- **mcpServers**: String or object - MCP server configurations or path to MCP config + +## Source Types + +### Local Path (Development) + +```json +{ + "source": "./plugins/my-plugin" +} +``` + +### Git Repository + +Simple string format: + +```json +{ + "source": "https://github.com/user/repo" +} +``` + +Object format for advanced configuration: + +```json +{ + "source": { + "source": "github", + "repo": "owner/plugin-repo" + } +} +``` + +### Git URL Source + +```json +{ + "source": { + "source": "url", + "url": "https://gitlab.com/team/plugin.git" + } +} +``` + +### Git with Subdirectory + +```json +{ + "source": "https://github.com/user/repo/tree/main/plugins/my-plugin" +} +``` + +## Examples + +### Local Dev Marketplace + +```json +{ + "name": "dev-marketplace", + "owner": { + "name": "Developer", + "email": "dev@localhost" + }, + "metadata": { + "description": "Local development marketplace", + "version": "0.1.0" + }, + "plugins": [ + { + "name": "my-plugin", + "description": "Plugin in development", + "source": "../my-plugin" + } + ] +} +``` + +### Team Marketplace + +```json +{ + "name": "acme-tools", + "owner": { + "name": "ACME Corp", + "email": "tools@acme.com" + }, + "metadata": { + "description": "ACME internal tools for Claude Code", + "version": "1.0.0" + }, + "plugins": [ + { + "name": "code-review", + "description": "ACME code review standards", + "version": "2.1.0", + "author": { + "name": "DevTools Team" + }, + "source": "./plugins/code-review", + "category": "development", + "tags": ["code-review", "standards"], + "keywords": ["review", "quality", "standards"] + }, + { + "name": "deploy-tools", + "description": "Deployment automation", + "version": "1.5.0", + "author": { + "name": "DevOps Team" + }, + "source": "./plugins/deploy-tools", + "category": "devops", + "tags": ["deployment", "automation"], + "keywords": ["deploy", "ci", "cd"] + } + ] +} +``` + +### Advanced Plugin Entry + +Plugin entries can override default component locations and provide inline configuration: + +```json +{ + "name": "enterprise-tools", + "source": { + "source": "github", + "repo": "company/enterprise-plugin" + }, + "description": "Enterprise workflow automation tools", + "version": "2.1.0", + "author": { + "name": "Enterprise Team", + "email": "enterprise@company.com" + }, + "homepage": "https://docs.company.com/plugins/enterprise-tools", + "repository": "https://github.com/company/enterprise-plugin", + "license": "MIT", + "keywords": ["enterprise", "workflow", "automation"], + "category": "productivity", + "commands": [ + "./commands/core/", + "./commands/enterprise/", + "./commands/experimental/preview.md" + ], + "agents": [ + "./agents/security-reviewer.md", + "./agents/compliance-checker.md" + ], + "hooks": "./config/hooks.json", + "mcpServers": { + "enterprise-db": { + "command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server", + "args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"] + } + }, + "strict": false +} +``` + + +**Schema relationship**: Plugin entries are based on the *plugin manifest schema* (with all fields made optional) plus marketplace-specific fields (`source`, `strict`, `category`, `tags`). This means any field valid in a `plugin.json` file can also be used in a marketplace entry. When `strict: false`, the marketplace entry serves as the complete plugin manifest if no `plugin.json` exists. When `strict: true` (default), marketplace fields supplement the plugin's own manifest file. + + + +**Environment variables**: Use `${CLAUDE_PLUGIN_ROOT}` in hooks and mcpServers configurations. This variable resolves to the plugin's installation directory and ensures paths work correctly regardless of where the plugin is installed. + + +## Usage + +### Add Marketplace (Local) + +```bash +/plugin marketplace add /path/to/marketplace +``` + +### Add Marketplace (GitHub) + +```bash +/plugin marketplace add your-org/your-repo +``` + +### Install Plugin from Marketplace + +```bash +/plugin install plugin-name@marketplace-name +``` + +### Team Auto-Install + +In project `.claude/settings.json`: + +```json +{ + "extraKnownMarketplaces": { + "team-tools": { + "source": { + "source": "github", + "repo": "your-org/marketplace-repo" + } + } + }, + "enabledPlugins": { + "plugin-name@team-tools": true + } +} +``` + +## Testing Workflow + +1. Create dev marketplace: + ```bash + mkdir -p dev-marketplace/.claude-plugin + # Create marketplace.json pointing to ../your-plugin + ``` + +2. Add to Claude Code: + ```bash + /plugin marketplace add ./dev-marketplace + ``` + +3. Install plugin: + ```bash + /plugin install your-plugin@dev-marketplace + ``` + +4. After changes, reinstall: + ```bash + /plugin uninstall your-plugin@dev-marketplace + /plugin install your-plugin@dev-marketplace + ``` + +## Best Practices + +- **Use kebab-case** for marketplace and plugin names +- **Keep descriptions concise** (< 100 chars) +- **Add meaningful tags** for discoverability +- **Version consistently** using SemVer +- **Test locally** before publishing to GitHub +- **Document plugins** in their README files + +## Common Mistakes + +❌ **Plugin name mismatch** +```json +// marketplace.json +{ "name": "my-plugin", "source": "./plugins/other-plugin" } + +// plugin.json (in other-plugin/) +{ "name": "other-plugin" } // Names don't match! +``` + +✅ **Names must match** +```json +// marketplace.json +{ "name": "my-plugin", "source": "./plugins/my-plugin" } + +// plugin.json +{ "name": "my-plugin" } // Matches! +``` + +❌ **Absolute source paths** +```json +{ + "source": "/Users/you/plugins/my-plugin" +} +``` + +✅ **Relative source paths** +```json +{ + "source": "./plugins/my-plugin" +} +``` + +## Validation + +Use `/plugin-development:validate` to check marketplace structure. diff --git a/skills/plugin-authoring/schemas/plugin-manifest.md b/skills/plugin-authoring/schemas/plugin-manifest.md new file mode 100644 index 0000000..8b8a6a4 --- /dev/null +++ b/skills/plugin-authoring/schemas/plugin-manifest.md @@ -0,0 +1,258 @@ +# Plugin Manifest Schema + +The `plugin.json` file in `.claude-plugin/` defines your plugin's metadata and optionally custom component paths. + +## Location + +`.claude-plugin/plugin.json` (at plugin root) + +## Required Fields + +```json +{ + "name": "plugin-name" +} +``` + +- **name**: kebab-case string, unique identifier (REQUIRED) + +## Optional Fields + +### Standard Metadata + +```json +{ + "version": "1.0.0", + "description": "What your plugin does", + "author": { + "name": "Your Name", + "email": "you@example.com", + "url": "https://github.com/your-username" + }, + "homepage": "https://your-plugin-homepage.com", + "repository": "https://github.com/your-org/your-repo", + "license": "MIT", + "keywords": ["tag1", "tag2"] +} +``` + +- **version**: Semantic version format (optional metadata) +- **description**: Brief explanation of plugin purpose (optional metadata) +- **author**: Can be string or object with name, email, url +- **homepage**: Documentation URL (optional metadata) +- **repository**: Source code URL (optional metadata) +- **license**: License identifier like "MIT" (optional metadata) +- **keywords**: Array of tags for discovery (optional metadata) + +### Component Configuration (Custom Paths Only) + +**IMPORTANT**: Only include these fields if you're using **non-standard** paths. If using standard directory structure (`commands/`, `agents/`, `skills/`, `hooks/`), omit these fields entirely. + +```json +{ + "commands": ["./custom/path/cmd1.md", "./custom/path/cmd2.md"], + "agents": ["./custom/agents/reviewer.md", "./custom/agents/tester.md"], + "hooks": "./custom/hooks/hooks.json", + "mcpServers": { + "server-name": { + "command": "node", + "args": ["path/to/server.js"] + } + } +} +``` + +### Component Path Rules + +- **commands**: Array of paths to individual `.md` command files, OR string path to a directory +- **agents**: Array of paths to individual `.md` agent files (NOT a directory path) +- **hooks**: Path to `hooks.json` configuration file OR inline hooks object +- **mcpServers**: MCP server configurations object OR path to MCP config file + +All paths must be **relative to plugin root** (where `.claude-plugin/` lives) and start with `./` + +**Note**: Custom paths supplement default directories - they don't replace them. If `commands/` exists, it's loaded in addition to custom command paths. + +### Skills Configuration + +For Skills (Agent Skills) provided by your plugin, you can restrict which tools Claude can use: + +```json +{ + "name": "my-skill-plugin", + "skills": [ + { + "name": "safe-reader", + "allowed-tools": ["Read", "Grep", "Glob"] + } + ] +} +``` + +However, the recommended approach is to specify `allowed-tools` directly in the `SKILL.md` frontmatter: + +```yaml +--- +name: safe-reader +description: Read files without making changes +allowed-tools: Read, Grep, Glob +--- +``` + +### Environment Variables + +**`${CLAUDE_PLUGIN_ROOT}`** is a special environment variable available in your plugin that contains the absolute path to your plugin directory. Use this in hooks, MCP servers, and scripts to ensure correct paths regardless of installation location. + +```json +{ + "name": "my-plugin", + "hooks": "./hooks/hooks.json" +} +``` + +Where `hooks/hooks.json` contains: + +```json +{ + "hooks": { + "PostToolUse": [ + { + "matcher": "Write|Edit", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/format-code.sh" + } + ] + } + ] + } +} +``` + +Or inline hooks: + +```json +{ + "name": "my-plugin", + "hooks": { + "PostToolUse": [ + { + "matcher": "Write|Edit", + "hooks": [ + { + "type": "command", + "command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh" + } + ] + } + ] + } +} +``` + +Use `${CLAUDE_PLUGIN_ROOT}` for: +- Scripts executed by hooks +- MCP server paths +- Config files referenced by components +- Any file paths in your plugin configuration + +## Examples + +### Standard Directory Structure (Recommended) + +```json +{ + "name": "my-dev-tools" +} +``` + +**Minimal plugin** - The simplest possible plugin. Claude Code automatically discovers `commands/`, `agents/`, `skills/`, and `hooks/` directories. + +```json +{ + "name": "my-dev-tools", + "version": "1.2.0", + "description": "Developer productivity tools for Claude Code", + "author": { + "name": "Dev Team", + "email": "dev@company.com" + }, + "license": "MIT", + "keywords": ["productivity", "tools"] +} +``` + +**With metadata** - Adding optional metadata for better discovery and documentation. + +### Custom Paths + +```json +{ + "name": "enterprise-plugin", + "description": "Enterprise development tools", + "author": { + "name": "Your Name" + }, + "commands": [ + "./specialized/deploy.md", + "./utilities/batch-process.md" + ], + "agents": [ + "./custom-agents/reviewer.md", + "./custom-agents/tester.md" + ] +} +``` + +**Note**: Using custom paths to organize components. The `description` and `author` fields are optional metadata. + +## Common Mistakes + +❌ **Wrong**: Including component fields with standard paths +```json +{ + "name": "my-plugin", + "commands": "./commands/", + "agents": "./agents/" +} +``` + +✅ **Correct**: Omit component fields for standard paths +```json +{ + "name": "my-plugin" +} +``` + +❌ **Wrong**: agents as directory path +```json +{ + "agents": "./agents/" +} +``` + +✅ **Correct**: agents as array of file paths +```json +{ + "agents": ["./agents/reviewer.md", "./agents/tester.md"] +} +``` + +❌ **Wrong**: Absolute paths +```json +{ + "commands": "/Users/you/plugins/my-plugin/commands/" +} +``` + +✅ **Correct**: Relative paths +```json +{ + "commands": ["./custom/cmd.md"] +} +``` + +## Validation + +Use `/plugin-development:validate` to check your manifest structure. diff --git a/skills/plugin-authoring/templates/agent-template.md b/skills/plugin-authoring/templates/agent-template.md new file mode 100644 index 0000000..fe61174 --- /dev/null +++ b/skills/plugin-authoring/templates/agent-template.md @@ -0,0 +1,51 @@ +--- +description: What this agent specializes in and when to invoke it (third person). +capabilities: ["capability-1", "capability-2", "capability-3"] +--- + +# Agent Name + +[Brief introduction to the agent's purpose and specialization] + +## What This Agent Does + +[Detailed description of the agent's responsibilities] + +## Capabilities + +1. **Capability 1**: [Description] +2. **Capability 2**: [Description] +3. **Capability 3**: [Description] + +## When to Use This Agent + +Invoke this agent when: +- [Scenario 1] +- [Scenario 2] +- [Scenario 3] + +## How It Proceeds + +[Step-by-step workflow the agent follows] + +1. **Analyze**: [What it reads/examines] +2. **Evaluate**: [How it assesses the situation] +3. **Report**: [What it returns to the main conversation] + +## Output Format + +[What kind of report or recommendations the agent provides] + +Example: +- Critical issues (must fix) +- Warnings (should fix) +- Suggestions (nice to have) +- Summary of findings + +## Tool Access + +[What tools this agent has access to and why] + +## Notes + +[Any limitations, constraints, or important considerations] diff --git a/skills/plugin-authoring/templates/command-template.md b/skills/plugin-authoring/templates/command-template.md new file mode 100644 index 0000000..bf1e677 --- /dev/null +++ b/skills/plugin-authoring/templates/command-template.md @@ -0,0 +1,32 @@ +--- +description: Brief, third-person description of what this command does +argument-hint: [arg1] [arg2] +--- + +# Command Name + +[Detailed instructions for Claude on how to execute this command] + +## Context + +[When and why to use this command] + +## Instructions + +1. [Step 1: What to do first] +2. [Step 2: Next action] +3. [Step 3: Final step] + +## Arguments + +- `$ARGUMENTS` or `$1`, `$2`, etc.: [Explain what each argument means] + +## Example Usage + +**Command**: `/namespace:command-name arg1 arg2` + +**Expected behavior**: [Describe what should happen] + +## Notes + +[Any additional context, warnings, or tips] diff --git a/skills/plugin-authoring/templates/marketplace-manifest.json b/skills/plugin-authoring/templates/marketplace-manifest.json new file mode 100644 index 0000000..0e00f27 --- /dev/null +++ b/skills/plugin-authoring/templates/marketplace-manifest.json @@ -0,0 +1,25 @@ +{ + "name": "MARKETPLACE-NAME", + "owner": { + "name": "Your Organization", + "email": "team@your-org.com" + }, + "metadata": { + "description": "A curated collection of Claude Code plugins", + "version": "1.0.0" + }, + "plugins": [ + { + "name": "plugin-name", + "description": "What the plugin does", + "version": "1.0.0", + "author": { + "name": "Author Name" + }, + "source": "./plugins/plugin-name", + "category": "utilities", + "tags": ["tag1", "tag2"], + "keywords": ["keyword1", "keyword2"] + } + ] +} diff --git a/skills/plugin-authoring/templates/plugin-manifest.json b/skills/plugin-authoring/templates/plugin-manifest.json new file mode 100644 index 0000000..72bd653 --- /dev/null +++ b/skills/plugin-authoring/templates/plugin-manifest.json @@ -0,0 +1,14 @@ +{ + "name": "PLUGIN-NAME", + "version": "0.1.0", + "description": "Brief description of what this plugin does", + "author": { + "name": "Your Name", + "email": "you@example.com", + "url": "https://github.com/your-username" + }, + "homepage": "https://github.com/your-org/your-repo", + "repository": "https://github.com/your-org/your-repo", + "license": "MIT", + "keywords": ["keyword1", "keyword2"] +} diff --git a/skills/plugin-authoring/templates/skill-template.md b/skills/plugin-authoring/templates/skill-template.md new file mode 100644 index 0000000..3797ba3 --- /dev/null +++ b/skills/plugin-authoring/templates/skill-template.md @@ -0,0 +1,49 @@ +--- +name: skill-name +description: What the Skill does and WHEN to use it (third person). Be specific about triggers. +# allowed-tools: Read, Grep, Glob # Optional: Only add if you want to restrict available tools +--- + +# Skill Name + +[Brief introduction to what this Skill provides] + +## Purpose + +[Explain the Skill's role and capabilities] + +## When to Activate + +[Describe specific contexts or patterns that should trigger this Skill] + +Examples: +- When the user mentions [specific topic] +- When files matching [pattern] are present +- When working with [technology/framework] + +## Capabilities + +[What this Skill can help with] + +1. [Capability 1] +2. [Capability 2] +3. [Capability 3] + +## Quick Links + +[Link to sibling files for progressive disclosure] + +- [Reference 1](./reference1.md) +- [Reference 2](./reference2.md) + +## Workflow + +[Step-by-step approach this Skill follows] + +1. [Analyze/Read relevant files] +2. [Propose actions] +3. [Execute via commands or provide guidance] + +## Notes + +[Any constraints, best practices, or important information]