Documentation Index
Fetch the complete documentation index at: https://docs.devinenterprise.com/llms.txt
Use this file to discover all available pages before exploring further.
Each hook event fires at a specific point in the agent’s lifecycle. Use the matcher field (a regex matched against the hook event’s tool_name) to filter which tool invocations trigger your hook.
Fires before a tool executes. Use this to block, modify, or add context to tool calls.
Stdin data:
| Field | Description | Example |
|---|
tool_name | Name of the tool being called | exec, edit, mcp__github__create_issue |
tool_input | Arguments passed to the tool | { "command": "rm -rf /", "shell_id": "main" } |
Example — Block destructive commands:
{
"PreToolUse": [
{
"matcher": "exec",
"hooks": [
{
"type": "command",
"command": "python3 -c \"import sys, json; data = json.load(sys.stdin); cmd = data.get('tool_input', {}).get('command', ''); sys.exit(2 if 'rm -rf' in cmd else 0)\""
}
]
}
]
}
Example — Require confirmation for writes outside src/:
Use a script that inspects the tool input and returns a decision:
{
"PreToolUse": [
{
"matcher": "edit",
"hooks": [
{
"type": "command",
"command": "./scripts/check-edit-path.sh",
"timeout": 5
}
]
}
]
}
PostToolUse
Fires after a tool finishes executing. Use this for logging, validation, or triggering follow-up actions.
Stdin data:
| Field | Description |
|---|
tool_name | Name of the tool that ran |
tool_input | Arguments that were passed |
tool_response | Object with success (boolean), output (string), and error (string or null) |
Example — Log all shell commands:
{
"PostToolUse": [
{
"matcher": "exec",
"hooks": [
{
"type": "command",
"command": "sh -c 'cat >> ~/.devin-command-log'"
}
]
}
]
}
PermissionRequest
Fires when the agent needs a permission decision. Use this to implement custom approval logic.
Stdin data:
| Field | Description |
|---|
tool_name | Tool requesting permission |
tool_input | Arguments for the tool call |
Example — Auto-approve git commands:
{
"PermissionRequest": [
{
"matcher": "exec",
"hooks": [
{
"type": "command",
"command": "python3 -c \"import sys, json; data = json.load(sys.stdin); cmd = data.get('tool_input', {}).get('command', ''); print(json.dumps({'decision': 'approve'})) if cmd.startswith('git ') else sys.exit(0)\""
}
]
}
]
}
UserPromptSubmit
Fires when the user submits a message. Use this to add context or trigger workflows.
Stdin data:
| Field | Description |
|---|
prompt | The user’s message text |
Example — Add project context for deploy-related prompts:
{
"UserPromptSubmit": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "./scripts/add-deploy-context.sh"
}
]
}
]
}
Stop
Fires when the agent decides to stop (finish its turn). Use this to add follow-up instructions or prevent premature stopping.
Stdin data:
| Field | Description |
|---|
stop_hook_active | Whether a stop hook is already active |
Example — Remind agent to run tests:
{
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "echo '{\"decision\": \"block\", \"reason\": \"Please run the test suite before stopping.\"}'"
}
]
}
]
}
Be careful with stop hooks that block — they can cause the agent to loop if the condition isn’t eventually satisfied.
PostCompaction
Fires after context compaction completes successfully. Use this for logging, triggering follow-up actions, or re-injecting context that may have been lost during compaction.
Stdin data:
| Field | Description |
|---|
summary | Summary text produced by the compactor (may be null if no summary was generated) |
Example — Log compaction events:
{
"PostCompaction": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "sh -c 'cat >> ~/.devin-compaction-log'"
}
]
}
]
}
SessionStart
Fires when a new session begins. Use this for initialization, logging, or environment setup.
Stdin data:
| Field | Description |
|---|
source | How the session was started |
Example — Run setup script:
{
"SessionStart": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "./scripts/dev-setup.sh",
"timeout": 10
}
]
}
]
}
SessionEnd
Fires when a session ends. Use this for cleanup or final logging.
Stdin data:
| Field | Description |
|---|
reason | Why the session ended |
Matching Multiple Events
A single hooks file can define hooks for multiple events:
{
"PreToolUse": [
{
"matcher": "",
"hooks": [
{ "type": "command", "command": "./scripts/audit.sh" }
]
}
],
"PostToolUse": [
{
"matcher": "",
"hooks": [
{ "type": "command", "command": "./scripts/audit.sh" }
]
}
]
}
Using the Matcher
The matcher field is a regex matched against the hook event’s tool_name. It is available for tool-related events: PreToolUse, PostToolUse, and PermissionRequest.
For non-tool events (UserPromptSubmit, Stop, PostCompaction, SessionStart, and SessionEnd), there is no tool_name; use "" or omit the matcher to run the hook for every event of that type.
The matcher is not a permission glob. Patterns like mcp__github__* are useful in permissions, but hook matchers are regexes. Use mcp__github__.* in a hook matcher.
| Matcher | Matches |
|---|
"" (empty) or omitted | All tool names for tool events |
"exec" | Tool names containing exec |
"^exec$" | Only the exec tool |
"^(exec|edit)$" | Only exec or edit |
"^mcp__.*" | All MCP tools |
"^mcp__github__.*" | All tools from the github MCP server |
"^mcp__github__create_issue$" | The create_issue tool from the github MCP server |
Hook matchers run against the same externally-visible tool names that hook scripts receive in stdin as tool_name. The exact tool names available can vary by CLI mode, model, and enabled integrations.
The most common public core tool names are:
MCP server tools appear as mcp__<server>__<tool>. For example, a github MCP server tool named create_issue appears as mcp__github__create_issue.
For other tools, match the exact tool_name shown in hook stdin. To confirm the complete set available in your current session, add a temporary PostToolUse hook with matcher: "" and log the stdin payload.