Files
gh-hyperskill-claude-code-m…/skills/plugin-authoring/best-practices/organization.md
2025-11-29 18:47:48 +08:00

9.0 KiB

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

---
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:

{
  "name": "my-plugin",
  "hooks": "./hooks/hooks.json"
}

Or inline configuration:

{
  "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:

{
  "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:

# 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:

# 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

{
  "name": "my-plugin",
  "commands": "./commands/",
  "agents": "./agents/"
}

Do: Omit Component Fields When Using Default Directories

{
  "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

{
  "commands": ["/Users/you/plugins/my-plugin/commands/cmd.md"]
}

Do: Relative Paths (for custom paths only)

{
  "commands": ["./custom/cmd.md"]
}

Don't: Monolithic Skills

# SKILL.md (3000 lines)
[Everything in one file...]

Do: Progressive Disclosure

# 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