Use when creating or modifying Han plugins. Covers plugin structure, configuration, hooks, skills, and best practices.
This skill provides comprehensive guidance for developing Han plugins.
Han supports several plugin categories:
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
The plugin.json file defines metadata:
{
"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 versioningDefine validation hooks that run at lifecycle events:
hooks:
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"
Setup - Plugin installationSessionStart - Session beginsUserPromptSubmit - User sends messagePreToolUse - Before tool executionPostToolUse - After tool executionStop - Work completion (validation)SubagentStop - Subagent completionScripts receive:
CLAUDE_PLUGIN_ROOT - Plugin directory pathHAN_SESSION_ID - Current session IDHAN_PROJECT_DIR - Project directoryHAN_FILES - Changed files (space-separated)Skills provide domain expertise:
---
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 skillCommands provide slash command functionality:
---
description: What the command does
---
Command implementation content...
Invoke with: /plugin-name:command-name
Before publishing, validate your plugin:
cd my-plugin
han plugin validate
This checks:
set -e - Exit on first error"${HAN_FILES}" not $HAN_FILESTest your plugin locally:
# Install from local path
han plugin install /path/to/my-plugin --scope project
# Or add to .claude/settings.json manually
Share your plugin:
han plugin install github:user/repoevent matches lifecycle pointcommand path is correctif_changed/dirs_with filtershan plugin validate for specific errors