444 lines
8.1 KiB
Markdown
444 lines
8.1 KiB
Markdown
# Hooks and Plugins
|
|
|
|
Customize and extend Claude Code behavior with hooks and plugins.
|
|
|
|
## Hooks System
|
|
|
|
Hooks are shell commands that execute in response to events.
|
|
|
|
### Hook Types
|
|
|
|
**Pre-tool hooks**: Execute before tool calls
|
|
**Post-tool hooks**: Execute after tool calls
|
|
**User prompt submit hooks**: Execute when user submits prompts
|
|
|
|
### Configuration
|
|
|
|
Hooks are configured in `.claude/hooks.json`:
|
|
|
|
```json
|
|
{
|
|
"hooks": {
|
|
"pre-tool": {
|
|
"bash": "echo 'Running: $TOOL_ARGS'",
|
|
"write": "./scripts/validate-write.sh"
|
|
},
|
|
"post-tool": {
|
|
"write": "./scripts/format-code.sh",
|
|
"edit": "prettier --write $FILE_PATH"
|
|
},
|
|
"user-prompt-submit": "./scripts/validate-request.sh"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
Available in hook scripts:
|
|
|
|
**All hooks:**
|
|
- `$TOOL_NAME`: Name of the tool being called
|
|
- `$TOOL_ARGS`: JSON string of tool arguments
|
|
|
|
**Post-tool only:**
|
|
- `$TOOL_RESULT`: Tool execution result
|
|
|
|
**User-prompt-submit only:**
|
|
- `$USER_PROMPT`: User's prompt text
|
|
|
|
### Hook Examples
|
|
|
|
#### Pre-tool: Security Validation
|
|
```bash
|
|
#!/bin/bash
|
|
# .claude/scripts/validate-bash.sh
|
|
|
|
# Block dangerous commands
|
|
if echo "$TOOL_ARGS" | grep -E "rm -rf /|format|mkfs"; then
|
|
echo "❌ Dangerous command blocked"
|
|
exit 1
|
|
fi
|
|
|
|
echo "✓ Command validated"
|
|
```
|
|
|
|
**Configuration:**
|
|
```json
|
|
{
|
|
"hooks": {
|
|
"pre-tool": {
|
|
"bash": "./.claude/scripts/validate-bash.sh"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
#### Post-tool: Auto-format
|
|
```bash
|
|
#!/bin/bash
|
|
# .claude/scripts/format-code.sh
|
|
|
|
# Extract file path from tool args
|
|
FILE_PATH=$(echo "$TOOL_ARGS" | jq -r '.file_path')
|
|
|
|
# Format based on file type
|
|
case "$FILE_PATH" in
|
|
*.js|*.ts|*.jsx|*.tsx)
|
|
prettier --write "$FILE_PATH"
|
|
;;
|
|
*.py)
|
|
black "$FILE_PATH"
|
|
;;
|
|
*.go)
|
|
gofmt -w "$FILE_PATH"
|
|
;;
|
|
esac
|
|
```
|
|
|
|
**Configuration:**
|
|
```json
|
|
{
|
|
"hooks": {
|
|
"post-tool": {
|
|
"write": "./.claude/scripts/format-code.sh",
|
|
"edit": "./.claude/scripts/format-code.sh"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
#### User-prompt-submit: Cost Tracking
|
|
```bash
|
|
#!/bin/bash
|
|
# .claude/scripts/track-usage.sh
|
|
|
|
# Log prompt
|
|
echo "$(date): $USER_PROMPT" >> .claude/usage.log
|
|
|
|
# Estimate tokens (rough)
|
|
TOKEN_COUNT=$(echo "$USER_PROMPT" | wc -w)
|
|
echo "Estimated tokens: $TOKEN_COUNT"
|
|
```
|
|
|
|
**Configuration:**
|
|
```json
|
|
{
|
|
"hooks": {
|
|
"user-prompt-submit": "./.claude/scripts/track-usage.sh"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Hook Best Practices
|
|
|
|
**Performance**: Keep hooks fast (<100ms)
|
|
**Reliability**: Handle errors gracefully
|
|
**Security**: Validate all inputs
|
|
**Logging**: Log important actions
|
|
**Testing**: Test hooks thoroughly
|
|
|
|
### Hook Errors
|
|
|
|
When a hook fails:
|
|
- Pre-tool hook failure blocks tool execution
|
|
- Post-tool hook failure is logged but doesn't block
|
|
- User can configure strict mode to block on all failures
|
|
|
|
## Plugins System
|
|
|
|
Plugins are packaged collections of extensions.
|
|
|
|
### Plugin Structure
|
|
|
|
```
|
|
my-plugin/
|
|
├── plugin.json # Plugin metadata
|
|
├── commands/ # Slash commands
|
|
│ ├── my-command.md
|
|
│ └── another-command.md
|
|
├── skills/ # Agent skills
|
|
│ └── my-skill/
|
|
│ ├── skill.md
|
|
│ └── skill.json
|
|
├── hooks/ # Hook scripts
|
|
│ ├── hooks.json
|
|
│ └── scripts/
|
|
├── mcp/ # MCP server configurations
|
|
│ └── mcp.json
|
|
└── README.md # Documentation
|
|
```
|
|
|
|
### plugin.json
|
|
|
|
```json
|
|
{
|
|
"name": "my-plugin",
|
|
"version": "1.0.0",
|
|
"description": "Plugin description",
|
|
"author": "Your Name",
|
|
"homepage": "https://github.com/user/plugin",
|
|
"license": "MIT",
|
|
"commands": ["commands/*.md"],
|
|
"skills": ["skills/*/"],
|
|
"hooks": "hooks/hooks.json",
|
|
"mcpServers": "mcp/mcp.json",
|
|
"dependencies": {
|
|
"node": ">=18.0.0"
|
|
}
|
|
}
|
|
```
|
|
|
|
### Installing Plugins
|
|
|
|
#### From GitHub
|
|
```bash
|
|
claude plugin install gh:username/repo
|
|
claude plugin install gh:username/repo@v1.0.0
|
|
```
|
|
|
|
#### From npm
|
|
```bash
|
|
claude plugin install npm:package-name
|
|
claude plugin install npm:@scope/package-name
|
|
```
|
|
|
|
#### From Local Path
|
|
```bash
|
|
claude plugin install ./path/to/plugin
|
|
claude plugin install ~/plugins/my-plugin
|
|
```
|
|
|
|
#### From URL
|
|
```bash
|
|
claude plugin install https://example.com/plugin.zip
|
|
```
|
|
|
|
### Managing Plugins
|
|
|
|
#### List Installed Plugins
|
|
```bash
|
|
claude plugin list
|
|
```
|
|
|
|
#### Update Plugin
|
|
```bash
|
|
claude plugin update my-plugin
|
|
claude plugin update --all
|
|
```
|
|
|
|
#### Uninstall Plugin
|
|
```bash
|
|
claude plugin uninstall my-plugin
|
|
```
|
|
|
|
#### Enable/Disable Plugin
|
|
```bash
|
|
claude plugin disable my-plugin
|
|
claude plugin enable my-plugin
|
|
```
|
|
|
|
### Creating Plugins
|
|
|
|
#### Initialize Plugin
|
|
```bash
|
|
mkdir my-plugin
|
|
cd my-plugin
|
|
```
|
|
|
|
#### Create plugin.json
|
|
```json
|
|
{
|
|
"name": "my-plugin",
|
|
"version": "1.0.0",
|
|
"description": "My awesome plugin",
|
|
"author": "Your Name",
|
|
"commands": ["commands/*.md"],
|
|
"skills": ["skills/*/"]
|
|
}
|
|
```
|
|
|
|
#### Add Components
|
|
```bash
|
|
# Add slash command
|
|
mkdir -p commands
|
|
cat > commands/my-command.md <<EOF
|
|
# My Command
|
|
Do something awesome with {{input}}.
|
|
EOF
|
|
|
|
# Add skill
|
|
mkdir -p skills/my-skill
|
|
cat > skills/my-skill/skill.json <<EOF
|
|
{
|
|
"name": "my-skill",
|
|
"description": "Does something",
|
|
"version": "1.0.0"
|
|
}
|
|
EOF
|
|
```
|
|
|
|
#### Package Plugin
|
|
```bash
|
|
# Create archive
|
|
tar -czf my-plugin.tar.gz .
|
|
|
|
# Or zip
|
|
zip -r my-plugin.zip .
|
|
```
|
|
|
|
### Publishing Plugins
|
|
|
|
#### To GitHub
|
|
```bash
|
|
git init
|
|
git add .
|
|
git commit -m "Initial commit"
|
|
git tag v1.0.0
|
|
git push origin main --tags
|
|
```
|
|
|
|
#### To npm
|
|
```bash
|
|
npm init
|
|
npm publish
|
|
```
|
|
|
|
### Plugin Marketplaces
|
|
|
|
Organizations can create private plugin marketplaces.
|
|
|
|
#### Configure Marketplace
|
|
```json
|
|
{
|
|
"marketplaces": [
|
|
{
|
|
"name": "company-internal",
|
|
"url": "https://plugins.company.com/catalog.json",
|
|
"auth": {
|
|
"type": "bearer",
|
|
"token": "${COMPANY_PLUGIN_TOKEN}"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
#### Marketplace Catalog Format
|
|
```json
|
|
{
|
|
"plugins": [
|
|
{
|
|
"name": "company-plugin",
|
|
"version": "1.0.0",
|
|
"description": "Internal plugin",
|
|
"downloadUrl": "https://plugins.company.com/company-plugin-1.0.0.zip",
|
|
"checksum": "sha256:abc123..."
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
#### Install from Marketplace
|
|
```bash
|
|
claude plugin install company-internal:company-plugin
|
|
```
|
|
|
|
## Example Plugin: Code Quality
|
|
|
|
### Structure
|
|
```
|
|
code-quality-plugin/
|
|
├── plugin.json
|
|
├── commands/
|
|
│ ├── lint.md
|
|
│ └── format.md
|
|
├── skills/
|
|
│ └── code-review/
|
|
│ ├── skill.md
|
|
│ └── skill.json
|
|
└── hooks/
|
|
├── hooks.json
|
|
└── scripts/
|
|
└── auto-lint.sh
|
|
```
|
|
|
|
### plugin.json
|
|
```json
|
|
{
|
|
"name": "code-quality",
|
|
"version": "1.0.0",
|
|
"description": "Code quality tools and automation",
|
|
"commands": ["commands/*.md"],
|
|
"skills": ["skills/*/"],
|
|
"hooks": "hooks/hooks.json"
|
|
}
|
|
```
|
|
|
|
### commands/lint.md
|
|
```markdown
|
|
# Lint
|
|
|
|
Run linter on {{files}} and fix all issues automatically.
|
|
```
|
|
|
|
### hooks/hooks.json
|
|
```json
|
|
{
|
|
"hooks": {
|
|
"post-tool": {
|
|
"write": "./scripts/auto-lint.sh"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Security Considerations
|
|
|
|
### Hook Security
|
|
- Validate all inputs
|
|
- Use whitelists for allowed commands
|
|
- Implement timeouts
|
|
- Log all executions
|
|
- Review hook scripts regularly
|
|
|
|
### Plugin Security
|
|
- Verify plugin sources
|
|
- Review code before installation
|
|
- Use signed packages when available
|
|
- Monitor plugin behavior
|
|
- Keep plugins updated
|
|
|
|
### Best Practices
|
|
- Install plugins from trusted sources only
|
|
- Review plugin permissions
|
|
- Use plugin sandboxing when available
|
|
- Monitor resource usage
|
|
- Regular security audits
|
|
|
|
## Troubleshooting
|
|
|
|
### Hooks Not Running
|
|
- Check hooks.json syntax
|
|
- Verify script permissions (`chmod +x`)
|
|
- Check script paths
|
|
- Review logs in `.claude/logs/`
|
|
|
|
### Plugin Installation Failures
|
|
- Verify internet connectivity
|
|
- Check plugin URL/path
|
|
- Review error messages
|
|
- Clear cache: `claude plugin cache clear`
|
|
|
|
### Plugin Conflicts
|
|
- Check for conflicting commands
|
|
- Review plugin load order
|
|
- Disable conflicting plugins
|
|
- Update plugins to compatible versions
|
|
|
|
## See Also
|
|
|
|
- Creating slash commands: `references/slash-commands.md`
|
|
- Agent skills: `references/agent-skills.md`
|
|
- Configuration: `references/configuration.md`
|
|
- Best practices: `references/best-practices.md`
|