mirror of
https://github.com/anthropics/claude-code.git
synced 2026-04-18 01:13:17 +00:00
feat: Add hookify plugin for custom hook rules via markdown
Adds the hookify plugin to public marketplace. Enables users to create custom hooks using simple markdown configuration files instead of editing JSON. Key features: - Define rules with regex patterns to warn/block operations - Create rules from explicit instructions or conversation analysis - Pattern-based matching for bash commands, file edits, prompts, stop events - Enable/disable rules dynamically without editing code - Conversation analyzer agent finds problematic behaviors Changes from internal version: - Removed non-functional SessionStart hook (not registered in hooks.json) - Removed all sessionstart documentation and examples - Fixed restart documentation to consistently state "no restart needed" - Changed license from "Internal Anthropic use only" to "MIT License" - Kept test blocks in core modules (useful for developers) Plugin provides: - 4 commands: /hookify, /hookify:list, /hookify:configure, /hookify:help - 1 agent: conversation-analyzer - 1 skill: writing-rules - 4 hook types: PreToolUse, PostToolUse, Stop, UserPromptSubmit - 4 example rules ready to use All features functional and suitable for public use. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
340
plugins/hookify/README.md
Normal file
340
plugins/hookify/README.md
Normal file
@@ -0,0 +1,340 @@
|
||||
# Hookify Plugin
|
||||
|
||||
Easily create custom hooks to prevent unwanted behaviors by analyzing conversation patterns or from explicit instructions.
|
||||
|
||||
## Overview
|
||||
|
||||
The hookify plugin makes it simple to create hooks without editing complex `hooks.json` files. Instead, you create lightweight markdown configuration files that define patterns to watch for and messages to show when those patterns match.
|
||||
|
||||
**Key features:**
|
||||
- 🎯 Analyze conversations to find unwanted behaviors automatically
|
||||
- 📝 Simple markdown configuration files with YAML frontmatter
|
||||
- 🔍 Regex pattern matching for powerful rules
|
||||
- 🚀 No coding required - just describe the behavior
|
||||
- 🔄 Easy enable/disable without restarting
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Create Your First Rule
|
||||
|
||||
```bash
|
||||
/hookify Warn me when I use rm -rf commands
|
||||
```
|
||||
|
||||
This analyzes your request and creates `.claude/hookify.warn-rm.local.md`.
|
||||
|
||||
### 2. Test It Immediately
|
||||
|
||||
**No restart needed!** Rules take effect on the very next tool use.
|
||||
|
||||
Ask Claude to run a command that should trigger the rule:
|
||||
```
|
||||
Run rm -rf /tmp/test
|
||||
```
|
||||
|
||||
You should see the warning message immediately!
|
||||
|
||||
## Usage
|
||||
|
||||
### Main Command: /hookify
|
||||
|
||||
**With arguments:**
|
||||
```
|
||||
/hookify Don't use console.log in TypeScript files
|
||||
```
|
||||
Creates a rule from your explicit instructions.
|
||||
|
||||
**Without arguments:**
|
||||
```
|
||||
/hookify
|
||||
```
|
||||
Analyzes recent conversation to find behaviors you've corrected or been frustrated by.
|
||||
|
||||
### Helper Commands
|
||||
|
||||
**List all rules:**
|
||||
```
|
||||
/hookify:list
|
||||
```
|
||||
|
||||
**Configure rules interactively:**
|
||||
```
|
||||
/hookify:configure
|
||||
```
|
||||
Enable/disable existing rules through an interactive interface.
|
||||
|
||||
**Get help:**
|
||||
```
|
||||
/hookify:help
|
||||
```
|
||||
|
||||
## Rule Configuration Format
|
||||
|
||||
### Simple Rule (Single Pattern)
|
||||
|
||||
`.claude/hookify.dangerous-rm.local.md`:
|
||||
```markdown
|
||||
---
|
||||
name: block-dangerous-rm
|
||||
enabled: true
|
||||
event: bash
|
||||
pattern: rm\s+-rf
|
||||
action: block
|
||||
---
|
||||
|
||||
⚠️ **Dangerous rm command detected!**
|
||||
|
||||
This command could delete important files. Please:
|
||||
- Verify the path is correct
|
||||
- Consider using a safer approach
|
||||
- Make sure you have backups
|
||||
```
|
||||
|
||||
**Action field:**
|
||||
- `warn`: Shows warning but allows operation (default)
|
||||
- `block`: Prevents operation from executing (PreToolUse) or stops session (Stop events)
|
||||
|
||||
### Advanced Rule (Multiple Conditions)
|
||||
|
||||
`.claude/hookify.sensitive-files.local.md`:
|
||||
```markdown
|
||||
---
|
||||
name: warn-sensitive-files
|
||||
enabled: true
|
||||
event: file
|
||||
action: warn
|
||||
conditions:
|
||||
- field: file_path
|
||||
operator: regex_match
|
||||
pattern: \.env$|credentials|secrets
|
||||
- field: new_text
|
||||
operator: contains
|
||||
pattern: KEY
|
||||
---
|
||||
|
||||
🔐 **Sensitive file edit detected!**
|
||||
|
||||
Ensure credentials are not hardcoded and file is in .gitignore.
|
||||
```
|
||||
|
||||
**All conditions must match** for the rule to trigger.
|
||||
|
||||
## Event Types
|
||||
|
||||
- **`bash`**: Triggers on Bash tool commands
|
||||
- **`file`**: Triggers on Edit, Write, MultiEdit tools
|
||||
- **`stop`**: Triggers when Claude wants to stop (for completion checks)
|
||||
- **`prompt`**: Triggers on user prompt submission
|
||||
- **`all`**: Triggers on all events
|
||||
|
||||
## Pattern Syntax
|
||||
|
||||
Use Python regex syntax:
|
||||
|
||||
| Pattern | Matches | Example |
|
||||
|---------|---------|---------|
|
||||
| `rm\s+-rf` | rm -rf | rm -rf /tmp |
|
||||
| `console\.log\(` | console.log( | console.log("test") |
|
||||
| `(eval\|exec)\(` | eval( or exec( | eval("code") |
|
||||
| `\.env$` | files ending in .env | .env, .env.local |
|
||||
| `chmod\s+777` | chmod 777 | chmod 777 file.txt |
|
||||
|
||||
**Tips:**
|
||||
- Use `\s` for whitespace
|
||||
- Escape special chars: `\.` for literal dot
|
||||
- Use `|` for OR: `(foo|bar)`
|
||||
- Use `.*` to match anything
|
||||
- Set `action: block` for dangerous operations
|
||||
- Set `action: warn` (or omit) for informational warnings
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Block Dangerous Commands
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: block-destructive-ops
|
||||
enabled: true
|
||||
event: bash
|
||||
pattern: rm\s+-rf|dd\s+if=|mkfs|format
|
||||
action: block
|
||||
---
|
||||
|
||||
🛑 **Destructive operation detected!**
|
||||
|
||||
This command can cause data loss. Operation blocked for safety.
|
||||
Please verify the exact path and use a safer approach.
|
||||
```
|
||||
|
||||
**This rule blocks the operation** - Claude will not be allowed to execute these commands.
|
||||
|
||||
### Example 2: Warn About Debug Code
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: warn-debug-code
|
||||
enabled: true
|
||||
event: file
|
||||
pattern: console\.log\(|debugger;|print\(
|
||||
action: warn
|
||||
---
|
||||
|
||||
🐛 **Debug code detected**
|
||||
|
||||
Remember to remove debugging statements before committing.
|
||||
```
|
||||
|
||||
**This rule warns but allows** - Claude sees the message but can still proceed.
|
||||
|
||||
### Example 3: Require Tests Before Stopping
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: require-tests-run
|
||||
enabled: false
|
||||
event: stop
|
||||
action: block
|
||||
conditions:
|
||||
- field: transcript
|
||||
operator: not_contains
|
||||
pattern: npm test|pytest|cargo test
|
||||
---
|
||||
|
||||
**Tests not detected in transcript!**
|
||||
|
||||
Before stopping, please run tests to verify your changes work correctly.
|
||||
```
|
||||
|
||||
**This blocks Claude from stopping** if no test commands appear in the session transcript. Enable only when you want strict enforcement.
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Multiple Conditions
|
||||
|
||||
Check multiple fields simultaneously:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: api-key-in-typescript
|
||||
enabled: true
|
||||
event: file
|
||||
conditions:
|
||||
- field: file_path
|
||||
operator: regex_match
|
||||
pattern: \.tsx?$
|
||||
- field: new_text
|
||||
operator: regex_match
|
||||
pattern: (API_KEY|SECRET|TOKEN)\s*=\s*["']
|
||||
---
|
||||
|
||||
🔐 **Hardcoded credential in TypeScript!**
|
||||
|
||||
Use environment variables instead of hardcoded values.
|
||||
```
|
||||
|
||||
### Operators Reference
|
||||
|
||||
- `regex_match`: Pattern must match (most common)
|
||||
- `contains`: String must contain pattern
|
||||
- `equals`: Exact string match
|
||||
- `not_contains`: String must NOT contain pattern
|
||||
- `starts_with`: String starts with pattern
|
||||
- `ends_with`: String ends with pattern
|
||||
|
||||
### Field Reference
|
||||
|
||||
**For bash events:**
|
||||
- `command`: The bash command string
|
||||
|
||||
**For file events:**
|
||||
- `file_path`: Path to file being edited
|
||||
- `new_text`: New content being added (Edit, Write)
|
||||
- `old_text`: Old content being replaced (Edit only)
|
||||
- `content`: File content (Write only)
|
||||
|
||||
**For prompt events:**
|
||||
- `user_prompt`: The user's submitted prompt text
|
||||
|
||||
**For stop events:**
|
||||
- Use general matching on session state
|
||||
|
||||
## Management
|
||||
|
||||
### Enable/Disable Rules
|
||||
|
||||
**Temporarily disable:**
|
||||
Edit the `.local.md` file and set `enabled: false`
|
||||
|
||||
**Re-enable:**
|
||||
Set `enabled: true`
|
||||
|
||||
**Or use interactive tool:**
|
||||
```
|
||||
/hookify:configure
|
||||
```
|
||||
|
||||
### Delete Rules
|
||||
|
||||
Simply delete the `.local.md` file:
|
||||
```bash
|
||||
rm .claude/hookify.my-rule.local.md
|
||||
```
|
||||
|
||||
### View All Rules
|
||||
|
||||
```
|
||||
/hookify:list
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
This plugin is part of the Claude Code Marketplace. It should be auto-discovered when the marketplace is installed.
|
||||
|
||||
**Manual testing:**
|
||||
```bash
|
||||
cc --plugin-dir /path/to/hookify
|
||||
```
|
||||
|
||||
## Requirements
|
||||
|
||||
- Python 3.7+
|
||||
- No external dependencies (uses stdlib only)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Rule not triggering:**
|
||||
1. Check rule file exists in `.claude/` directory (in project root, not plugin directory)
|
||||
2. Verify `enabled: true` in frontmatter
|
||||
3. Test regex pattern separately
|
||||
4. Rules should work immediately - no restart needed
|
||||
5. Try `/hookify:list` to see if rule is loaded
|
||||
|
||||
**Import errors:**
|
||||
- Ensure Python 3 is available: `python3 --version`
|
||||
- Check hookify plugin is installed
|
||||
|
||||
**Pattern not matching:**
|
||||
- Test regex: `python3 -c "import re; print(re.search(r'pattern', 'text'))"`
|
||||
- Use unquoted patterns in YAML to avoid escaping issues
|
||||
- Start simple, then add complexity
|
||||
|
||||
**Hook seems slow:**
|
||||
- Keep patterns simple (avoid complex regex)
|
||||
- Use specific event types (bash, file) instead of "all"
|
||||
- Limit number of active rules
|
||||
|
||||
## Contributing
|
||||
|
||||
Found a useful rule pattern? Consider sharing example files via PR!
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- Severity levels (error/warning/info distinctions)
|
||||
- Rule templates library
|
||||
- Interactive pattern builder
|
||||
- Hook testing utilities
|
||||
- JSON format support (in addition to markdown)
|
||||
|
||||
## License
|
||||
|
||||
MIT License
|
||||
Reference in New Issue
Block a user