Han Plugin Development
This skill provides comprehensive guidance for developing Han plugins.
Plugin Types
Han supports several plugin categories:
- Language/Validation - Skills and validation hooks for languages/tools
- Discipline - Specialized agents for specific domains
- Service/Tool - MCP servers for external integrations
Directory Structure
Every plugin must follow this structure:
my-plugin/ ├── .claude-plugin/ │ └── plugin.json # Plugin metadata (required) ├── han-plugin.yml # Hook configuration (optional) ├── skills/ # Skills directory (optional) │ └── my-skill/ │ └── SKILL.md # Skill definition ├── commands/ # Commands directory (optional) │ └── my-command.md # Slash command ├── hooks/ # Hook scripts (optional) │ └── my-hook.sh # Hook implementation └── README.md # Documentation
plugin.json (Required)
The plugin.json file defines metadata:
json{ "name": "my-plugin-name", "version": "1.0.0", "description": "What the plugin does", "author": { "name": "Author Name", "url": "https://author-website.com" }, "license": "MIT", "keywords": ["keyword1", "keyword2"] }
Required fields:
name- Must match directory nameversion- Semantic versioning
han-plugin.yml (Hooks)
Define validation hooks that run at lifecycle events:
yamlhooks: my-validation: event: Stop # When to run command: bash "hooks/my-hook.sh" description: What this hook does # Optional filters: if_changed: # Only run if these files changed - "**/*.ts" dirs_with: # Only run in dirs containing - "package.json"
Hook Events
Setup- Plugin installationSessionStart- Session beginsUserPromptSubmit- User sends messagePreToolUse- Before tool executionPostToolUse- After tool executionStop- Work completion (validation)SubagentStop- Subagent completion
Hook Environment Variables
Scripts receive:
CLAUDE_PLUGIN_ROOT- Plugin directory pathHAN_SESSION_ID- Current session IDHAN_PROJECT_DIR- Project directoryHAN_FILES- Changed files (space-separated)
Skills (SKILL.md)
Skills provide domain expertise:
markdown--- name: skill-name description: When to use this skill allowed-tools: [Read, Write, Edit, Bash, Glob, Grep] --- # Skill Title Skill content with guidance, examples, and best practices.
Required frontmatter:
name- Skill identifierdescription- When Claude should use this skill
Commands (Slash Commands)
Commands provide slash command functionality:
markdown--- description: What the command does --- Command implementation content...
Invoke with: /plugin-name:command-name
Validation
Before publishing, validate your plugin:
bashcd my-plugin han plugin validate
This checks:
- Required files exist
- JSON/YAML syntax is valid
- Frontmatter is correct
- No misplaced files
Best Practices
Hook Scripts
- Use
set -e- Exit on first error - Quote variables -
"${HAN_FILES}"not$HAN_FILES - Clear error messages - Write to stderr on failure
- Exit codes - 0 for success, non-zero for failure
Skills
- Specific descriptions - Help Claude know when to use
- Practical examples - Show real usage patterns
- Progressive detail - Start simple, add complexity
- Troubleshooting - Include common issues
General
- Follow naming conventions - short names matching directory
- Include README - Installation and usage docs
- Version properly - Use semantic versioning
- Test locally - Install via path before publishing
Local Installation
Test your plugin locally:
bash# Install from local path han plugin install /path/to/my-plugin --scope project # Or add to .claude/settings.json manually
Publishing
Share your plugin:
- Push to a git repository
- Add to the Han marketplace (optional)
- Users install via:
han plugin install github:user/repo
Troubleshooting
Hook Not Running
- Check
eventmatches lifecycle point - Verify
commandpath is correct - Check
if_changed/dirs_withfilters
Validation Fails
- Run
han plugin validatefor specific errors - Check plugin.json syntax
- Verify skill frontmatter
Skill Not Found
- Check SKILL.md path and naming
- Verify frontmatter has required fields
- Skill name should match directory name

