Ianfr13

Plugin Structure

0
0
# Install this skill:
npx skills add Ianfr13/claude-code-plugins --skill "Plugin Structure"

Install specific skill from multi-skill repository

# Description

This skill should be used when the user asks to "create a plugin", "scaffold a plugin", "understand plugin structure", "organize plugin components", "set up plugin.json", "use ${CLAUDE_PLUGIN_ROOT}", "add commands/agents/skills/hooks", "configure auto-discovery", or needs guidance on plugin directory layout, manifest configuration, component organization, file naming conventions, or Claude Code plugin architecture best practices.

# SKILL.md


name: Plugin Structure
description: This skill should be used when the user asks to "create a plugin", "scaffold a plugin", "understand plugin structure", "organize plugin components", "set up plugin.json", "use ${CLAUDE_PLUGIN_ROOT}", "add commands/agents/skills/hooks", "configure auto-discovery", or needs guidance on plugin directory layout, manifest configuration, component organization, file naming conventions, or Claude Code plugin architecture best practices.
version: 0.1.0


Plugin Structure for Claude Code

Overview

Claude Code plugins follow a standardized directory structure with automatic component discovery. Understanding this structure enables creating well-organized, maintainable plugins that integrate seamlessly with Claude Code.

Key concepts:
- Conventional directory layout for automatic discovery
- Manifest-driven configuration in .claude-plugin/plugin.json
- Component-based organization (commands, agents, skills, hooks)
- Portable path references using ${CLAUDE_PLUGIN_ROOT}
- Explicit vs. auto-discovered component loading

Directory Structure

Every Claude Code plugin follows this organizational pattern:

plugin-name/
β”œβ”€β”€ .claude-plugin/
β”‚   └── plugin.json          # Required: Plugin manifest
β”œβ”€β”€ commands/                 # Slash commands (.md files)
β”œβ”€β”€ agents/                   # Subagent definitions (.md files)
β”œβ”€β”€ skills/                   # Agent skills (subdirectories)
β”‚   └── skill-name/
β”‚       └── SKILL.md         # Required for each skill
β”œβ”€β”€ hooks/
β”‚   └── hooks.json           # Event handler configuration
β”œβ”€β”€ .mcp.json                # MCP server definitions
└── scripts/                 # Helper scripts and utilities

Critical rules:

  1. Manifest location: The plugin.json manifest MUST be in .claude-plugin/ directory
  2. Component locations: All component directories (commands, agents, skills, hooks) MUST be at plugin root level, NOT nested inside .claude-plugin/
  3. Optional components: Only create directories for components the plugin actually uses
  4. Naming convention: Use kebab-case for all directory and file names

Plugin Manifest (plugin.json)

The manifest defines plugin metadata and configuration. Located at .claude-plugin/plugin.json:

Required Fields

{
  "name": "plugin-name"
}

Name requirements:
- Use kebab-case format (lowercase with hyphens)
- Must be unique across installed plugins
- No spaces or special characters
- Example: code-review-assistant, test-runner, api-docs

{
  "name": "plugin-name",
  "version": "1.0.0",
  "description": "Brief explanation of plugin purpose",
  "author": {
    "name": "Author Name",
    "email": "[email protected]",
    "url": "https://example.com"
  },
  "homepage": "https://docs.example.com",
  "repository": "https://github.com/user/plugin-name",
  "license": "MIT",
  "keywords": ["testing", "automation", "ci-cd"]
}

Version format: Follow semantic versioning (MAJOR.MINOR.PATCH)
Keywords: Use for plugin discovery and categorization

Component Path Configuration

Specify custom paths for components (supplements default directories):

{
  "name": "plugin-name",
  "commands": "./custom-commands",
  "agents": ["./agents", "./specialized-agents"],
  "hooks": "./config/hooks.json",
  "mcpServers": "./.mcp.json"
}

Important: Custom paths supplement defaultsβ€”they don't replace them. Components in both default directories and custom paths will load.

Path rules:
- Must be relative to plugin root
- Must start with ./
- Cannot use absolute paths
- Support arrays for multiple locations

Component Organization

Commands

Location: commands/ directory
Format: Markdown files with YAML frontmatter
Auto-discovery: All .md files in commands/ load automatically

Example structure:

commands/
β”œβ”€β”€ review.md        # /review command
β”œβ”€β”€ test.md          # /test command
└── deploy.md        # /deploy command

File format:

---
name: command-name
description: Command description
---

Command implementation instructions...

Usage: Commands integrate as native slash commands in Claude Code

Agents

Location: agents/ directory
Format: Markdown files with YAML frontmatter
Auto-discovery: All .md files in agents/ load automatically

Example structure:

agents/
β”œβ”€β”€ code-reviewer.md
β”œβ”€β”€ test-generator.md
└── refactorer.md

File format:

---
description: Agent role and expertise
capabilities:
  - Specific task 1
  - Specific task 2
---

Detailed agent instructions and knowledge...

Usage: Users can invoke agents manually, or Claude Code selects them automatically based on task context

Skills

Location: skills/ directory with subdirectories per skill
Format: Each skill in its own directory with SKILL.md file
Auto-discovery: All SKILL.md files in skill subdirectories load automatically

Example structure:

skills/
β”œβ”€β”€ api-testing/
β”‚   β”œβ”€β”€ SKILL.md
β”‚   β”œβ”€β”€ scripts/
β”‚   β”‚   └── test-runner.py
β”‚   └── references/
β”‚       └── api-spec.md
└── database-migrations/
    β”œβ”€β”€ SKILL.md
    └── examples/
        └── migration-template.sql

SKILL.md format:

---
name: Skill Name
description: When to use this skill
version: 1.0.0
---

Skill instructions and guidance...

Supporting files: Skills can include scripts, references, examples, or assets in subdirectories

Usage: Claude Code autonomously activates skills based on task context matching the description

Hooks

Location: hooks/hooks.json or inline in plugin.json
Format: JSON configuration defining event handlers
Registration: Hooks register automatically when plugin enables

Example structure:

hooks/
β”œβ”€β”€ hooks.json           # Hook configuration
└── scripts/
    β”œβ”€β”€ validate.sh      # Hook script
    └── check-style.sh   # Hook script

Configuration format:

{
  "PreToolUse": [{
    "matcher": "Write|Edit",
    "hooks": [{
      "type": "command",
      "command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate.sh",
      "timeout": 30
    }]
  }]
}

Available events: PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification

Usage: Hooks execute automatically in response to Claude Code events

MCP Servers

Location: .mcp.json at plugin root or inline in plugin.json
Format: JSON configuration for MCP server definitions
Auto-start: Servers start automatically when plugin enables

Example format:

{
  "mcpServers": {
    "server-name": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/servers/server.js"],
      "env": {
        "API_KEY": "${API_KEY}"
      }
    }
  }
}

Usage: MCP servers integrate seamlessly with Claude Code's tool system

Portable Path References

${CLAUDE_PLUGIN_ROOT}

Use ${CLAUDE_PLUGIN_ROOT} environment variable for all intra-plugin path references:

{
  "command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/run.sh"
}

Why it matters: Plugins install in different locations depending on:
- User installation method (marketplace, local, npm)
- Operating system conventions
- User preferences

Where to use it:
- Hook command paths
- MCP server command arguments
- Script execution references
- Resource file paths

Never use:
- Hardcoded absolute paths (/Users/name/plugins/...)
- Relative paths from working directory (./scripts/... in commands)
- Home directory shortcuts (~/plugins/...)

Path Resolution Rules

In manifest JSON fields (hooks, MCP servers):

"command": "${CLAUDE_PLUGIN_ROOT}/scripts/tool.sh"

In component files (commands, agents, skills):

Reference scripts at: ${CLAUDE_PLUGIN_ROOT}/scripts/helper.py

In executed scripts:

#!/bin/bash
# ${CLAUDE_PLUGIN_ROOT} available as environment variable
source "${CLAUDE_PLUGIN_ROOT}/lib/common.sh"

File Naming Conventions

Component Files

Commands: Use kebab-case .md files
- code-review.md β†’ /code-review
- run-tests.md β†’ /run-tests
- api-docs.md β†’ /api-docs

Agents: Use kebab-case .md files describing role
- test-generator.md
- code-reviewer.md
- performance-analyzer.md

Skills: Use kebab-case directory names
- api-testing/
- database-migrations/
- error-handling/

Supporting Files

Scripts: Use descriptive kebab-case names with appropriate extensions
- validate-input.sh
- generate-report.py
- process-data.js

Documentation: Use kebab-case markdown files
- api-reference.md
- migration-guide.md
- best-practices.md

Configuration: Use standard names
- hooks.json
- .mcp.json
- plugin.json

Auto-Discovery Mechanism

Claude Code automatically discovers and loads components:

  1. Plugin manifest: Reads .claude-plugin/plugin.json when plugin enables
  2. Commands: Scans commands/ directory for .md files
  3. Agents: Scans agents/ directory for .md files
  4. Skills: Scans skills/ for subdirectories containing SKILL.md
  5. Hooks: Loads configuration from hooks/hooks.json or manifest
  6. MCP servers: Loads configuration from .mcp.json or manifest

Discovery timing:
- Plugin installation: Components register with Claude Code
- Plugin enable: Components become available for use
- No restart required: Changes take effect on next Claude Code session

Override behavior: Custom paths in plugin.json supplement (not replace) default directories

Best Practices

Organization

  1. Logical grouping: Group related components together
  2. Put test-related commands, agents, and skills together
  3. Create subdirectories in scripts/ for different purposes

  4. Minimal manifest: Keep plugin.json lean

  5. Only specify custom paths when necessary
  6. Rely on auto-discovery for standard layouts
  7. Use inline configuration only for simple cases

  8. Documentation: Include README files

  9. Plugin root: Overall purpose and usage
  10. Component directories: Specific guidance
  11. Script directories: Usage and requirements

Naming

  1. Consistency: Use consistent naming across components
  2. If command is test-runner, name related agent test-runner-agent
  3. Match skill directory names to their purpose

  4. Clarity: Use descriptive names that indicate purpose

  5. Good: api-integration-testing/, code-quality-checker.md
  6. Avoid: utils/, misc.md, temp.sh

  7. Length: Balance brevity with clarity

  8. Commands: 2-3 words (review-pr, run-ci)
  9. Agents: Describe role clearly (code-reviewer, test-generator)
  10. Skills: Topic-focused (error-handling, api-design)

Portability

  1. Always use ${CLAUDE_PLUGIN_ROOT}: Never hardcode paths
  2. Test on multiple systems: Verify on macOS, Linux, Windows
  3. Document dependencies: List required tools and versions
  4. Avoid system-specific features: Use portable bash/Python constructs

Maintenance

  1. Version consistently: Update version in plugin.json for releases
  2. Deprecate gracefully: Mark old components clearly before removal
  3. Document breaking changes: Note changes affecting existing users
  4. Test thoroughly: Verify all components work after changes

Common Patterns

Minimal Plugin

Single command with no dependencies:

my-plugin/
β”œβ”€β”€ .claude-plugin/
β”‚   └── plugin.json    # Just name field
└── commands/
    └── hello.md       # Single command

Complete plugin with all component types:

my-plugin/
β”œβ”€β”€ .claude-plugin/
β”‚   └── plugin.json
β”œβ”€β”€ commands/          # User-facing commands
β”œβ”€β”€ agents/            # Specialized subagents
β”œβ”€β”€ skills/            # Auto-activating skills
β”œβ”€β”€ hooks/             # Event handlers
β”‚   β”œβ”€β”€ hooks.json
β”‚   └── scripts/
β”œβ”€β”€ .mcp.json          # External integrations
└── scripts/           # Shared utilities

Skill-Focused Plugin

Plugin providing only skills:

my-plugin/
β”œβ”€β”€ .claude-plugin/
β”‚   └── plugin.json
└── skills/
    β”œβ”€β”€ skill-one/
    β”‚   └── SKILL.md
    └── skill-two/
        └── SKILL.md

Troubleshooting

Component not loading:
- Verify file is in correct directory with correct extension
- Check YAML frontmatter syntax (commands, agents, skills)
- Ensure skill has SKILL.md (not README.md or other name)
- Confirm plugin is enabled in Claude Code settings

Path resolution errors:
- Replace all hardcoded paths with ${CLAUDE_PLUGIN_ROOT}
- Verify paths are relative and start with ./ in manifest
- Check that referenced files exist at specified paths
- Test with echo $CLAUDE_PLUGIN_ROOT in hook scripts

Auto-discovery not working:
- Confirm directories are at plugin root (not in .claude-plugin/)
- Check file naming follows conventions (kebab-case, correct extensions)
- Verify custom paths in manifest are correct
- Restart Claude Code to reload plugin configuration

Conflicts between plugins:
- Use unique, descriptive component names
- Namespace commands with plugin name if needed
- Document potential conflicts in plugin README
- Consider command prefixes for related functionality


For detailed examples and advanced patterns, see files in references/ and examples/ directories.

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.