Hooks
Automate workflows with custom hooks
Hooks let you execute custom scripts at various points in Ripperdoc's lifecycle.
Hook Events
| Event | Description |
|---|---|
PreToolUse | Before a tool executes |
PostToolUse | After a tool completes |
PermissionRequest | When permission is requested |
UserPromptSubmit | When user submits a message |
Notification | For status notifications |
Stop | When the agent completes |
SessionStart | When a session begins |
SessionEnd | When a session ends |
Configuration Files
Hooks are configured in JSON files (loaded in order):
~/.ripperdoc/hooks.json- Global hooks.ripperdoc/hooks.json- Project hooks.ripperdoc/hooks.local.json- Local hooks (gitignored)
Hook Types
Command Hooks
Execute shell commands:
{
"hooks": [
{
"event": "PostToolUse",
"type": "command",
"matcher": {
"tool_name": "Bash"
},
"command": "echo 'Bash command completed' >> /tmp/ripperdoc.log"
}
]
}Prompt Hooks
Use an LLM to process the hook:
{
"hooks": [
{
"event": "PreToolUse",
"type": "prompt",
"matcher": {
"tool_name": "Edit"
},
"prompt": "Review this edit for security issues"
}
]
}Matchers
Control when hooks run:
{
"matcher": {
"tool_name": "Bash",
"tool_name_regex": "^(Bash|Edit)$",
"input_contains": "npm",
"path_pattern": "*.py"
}
}| Matcher | Description |
|---|---|
tool_name | Exact tool name |
tool_name_regex | Regex pattern for tool name |
input_contains | Input must contain string |
path_pattern | Glob pattern for file paths |
Hook Decisions
Hooks can return decisions to control execution:
{
"decision": "allow",
"message": "Approved by hook"
}| Decision | Effect |
|---|---|
allow | Proceed with operation |
deny | Block the operation |
ask | Prompt user for confirmation |
block | Block and stop processing |
Examples
Logging Tool Usage
{
"hooks": [
{
"event": "PostToolUse",
"type": "command",
"command": "echo '[$(date)] Tool: $TOOL_NAME' >> ~/.ripperdoc/tool.log"
}
]
}Protect Sensitive Files
{
"hooks": [
{
"event": "PreToolUse",
"type": "command",
"matcher": {
"tool_name": "Edit",
"path_pattern": "*.env*"
},
"command": "echo '{\"decision\": \"deny\", \"message\": \"Cannot edit .env files\"}'"
}
]
}Desktop Notifications
{
"hooks": [
{
"event": "Notification",
"type": "command",
"command": "notify-send 'Ripperdoc' '$MESSAGE'"
}
]
}Auto-format on Edit
{
"hooks": [
{
"event": "PostToolUse",
"type": "command",
"matcher": {
"tool_name": "Edit",
"path_pattern": "*.py"
},
"command": "black $FILE_PATH 2>/dev/null || true"
}
]
}Environment Variables
Hooks receive context via environment variables:
| Variable | Description |
|---|---|
TOOL_NAME | Name of the tool |
TOOL_INPUT | JSON-encoded tool input |
FILE_PATH | File path (for file operations) |
MESSAGE | Notification message |
SESSION_ID | Current session ID |
Managing Hooks
Use the /hooks command:
> /hooks list
> /hooks reloadBest Practices
- Test hooks carefully: Use logging to debug hook behavior
- Keep hooks fast: Slow hooks impact responsiveness
- Use local hooks for experiments:
.ripperdoc/hooks.local.jsonis gitignored - Handle errors gracefully: Hooks should not crash Ripperdoc