This page is larger than the 256 KiB this site keeps, so one side of the diff below stops where the stored text does.
from line 265
265265* Your user, project, local, and plugin hooks are blocked. Hooks from plugins force-enabled in managed settings `enabledPlugins` are exempt
266266* Claude Code also narrows your [`statusLine`](/docs/en/statusline), [`fileSuggestion`](/docs/en/settings-reference#filesuggestion), and [`subagentStatusLine`](/docs/en/statusline#subagent-status-lines) settings to managed settings
267267* Claude Code also disables plugins with a [`command` source](/docs/en/plugin-marketplaces#command-sources), including plugins force-enabled in managed settings `enabledPlugins`, unless [`disableCommandPluginSources`](/docs/en/settings-reference#disablecommandpluginsources) is explicitly set to `false`
268* Claude Code also blocks marketplace [`headersHelper` commands](/docs/en/plugin-marketplaces#authenticate-archive-downloads) unless [`disableCommandPluginSources`](/docs/en/settings-reference#disablecommandpluginsources) is explicitly set to `false`, except for a marketplace that managed settings themselves declare
268269
269270See [what runs under `allowManagedHooksOnly`](/docs/en/settings-reference#what-runs-under-allowmanagedhooksonly).
270271
from line 298
297298
298299Each event type matches on a different field:
299300
300| Event | What the matcher filters | Example matcher values |
301| :------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
302| `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest`, `PermissionDenied` | tool name | `Bash`, `Edit\|Write`, `mcp__.*` |
303| `SessionStart` | how the session started | `startup`, `resume`, `clear`, `compact`, `fork` |
304| `Setup` | which CLI flag triggered setup | `init`, `maintenance` |
305| `SessionEnd` | why the session ended | `clear`, `resume`, `logout`, `prompt_input_exit`, `other` |
306| `Notification` | notification type | `permission_prompt`, `idle_prompt`, `auth_success`, `elicitation_dialog`, `elicitation_url_dialog`, `elicitation_complete`, `elicitation_response`, `agent_needs_input`, `agent_completed` |
307| `SubagentStart` | agent type | `general-purpose`, `Explore`, `Plan`, custom agent names, or plugin-scoped names like `^my-plugin:reviewer$` |
308| `PreCompact`, `PostCompact` | what triggered compaction | `manual`, `auto` |
309| `SubagentStop` | agent type | same values as `SubagentStart` |
310| `ConfigChange` | configuration source | `user_settings`, `project_settings`, `local_settings`, `policy_settings`, `skills` |
311| `CwdChanged` | no matcher support | always fires on every directory change |
312| `DirectoryAdded` | how the directory was added | `slash_command`, `register_repo_root` |
313| `FileChanged` | literal filenames to watch (see [FileChanged](#filechanged)) | `.envrc\|.env` |
314| `StopFailure` | error type | `rate_limit`, `overloaded`, `authentication_failed`, `oauth_org_not_allowed`, `billing_error`, `invalid_request`, `model_not_found`, `server_error`, `max_output_tokens`, `unknown` |
315| `InstructionsLoaded` | load reason | `session_start`, `nested_traversal`, `path_glob_match`, `include`, `compact` |
316| `UserPromptExpansion` | command name | your skill or command names |
317| `Elicitation` | MCP server name | your configured MCP server names |
318| `ElicitationResult` | MCP server name | same values as `Elicitation` |
319| `UserPromptSubmit`, `PostToolBatch`, `Stop`, `TeammateIdle`, `TaskCreated`, `TaskCompleted`, `WorktreeCreate`, `WorktreeRemove`, `MessageDisplay` | no matcher support | always fires on every occurrence |
301| Event | What the matcher filters | Example matcher values |
302| :------------------------------------------------------------------------------------------------------------------------------------------------ | :----------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
303| `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest`, `PermissionDenied` | tool name | `Bash`, `Edit\|Write`, `mcp__.*` |
304| `SessionStart` | how the session started | `startup`, `resume`, `clear`, `compact`, `fork` |
305| `Setup` | which CLI flag triggered setup | `init`, `maintenance` |
306| `SessionEnd` | why the session ended | `clear`, `resume`, `logout`, `prompt_input_exit`, `other` |
307| `Notification` | notification type | `permission_prompt`, `idle_prompt`, `auth_success`, `elicitation_dialog`, `elicitation_url_dialog`, `elicitation_complete`, `elicitation_response`, `agent_needs_input`, `agent_completed`, `quota_auto_resume_fired`, `quota_auto_resume_stale`, `quota_auto_resume_disabled` |
308| `SubagentStart` | agent type | `general-purpose`, `Explore`, `Plan`, custom agent names, or plugin-scoped names like `^my-plugin:reviewer$` |
309| `PreCompact`, `PostCompact` | what triggered compaction | `manual`, `auto` |
310| `SubagentStop` | agent type | same values as `SubagentStart` |
311| `ConfigChange` | configuration source | `user_settings`, `project_settings`, `local_settings`, `policy_settings`, `skills` |
312| `CwdChanged` | no matcher support | always fires on every directory change |
313| `DirectoryAdded` | how the directory was added | `slash_command`, `register_repo_root` |
314| `FileChanged` | literal filenames to watch (see [FileChanged](#filechanged)) | `.envrc\|.env` |
315| `StopFailure` | error type | `rate_limit`, `overloaded`, `authentication_failed`, `oauth_org_not_allowed`, `billing_error`, `invalid_request`, `model_not_found`, `server_error`, `max_output_tokens`, `unknown` |
316| `InstructionsLoaded` | load reason | `session_start`, `nested_traversal`, `path_glob_match`, `include`, `compact` |
317| `UserPromptExpansion` | command name | your skill or command names |
318| `Elicitation` | MCP server name | your configured MCP server names |
319| `ElicitationResult` | MCP server name | same values as `Elicitation` |
320| `UserPromptSubmit`, `PostToolBatch`, `Stop`, `TeammateIdle`, `TaskCreated`, `TaskCompleted`, `WorktreeCreate`, `WorktreeRemove`, `MessageDisplay` | no matcher support | always fires on every occurrence |
320321
321322The matcher runs against a field from the [JSON input](#hook-input-and-output) that Claude Code sends to your hook on stdin. For tool events, that field is `tool_name`. Each [hook event](#hook-events) section lists the full set of matcher values and the input schema for that event.
322323
from line 2164
21632164
21642165You receive these hook events even with desktop notifications turned off: the `preferredNotifChannel` setting, including `notifications_disabled`, changes only how you're alerted, not whether your hook runs.
21652166
2166| Matcher | When it fires |
2167| :----------------------- | :--------------------------------------------------------------------------------------------------------------------- |
2168| `permission_prompt` | Claude needs you to approve a tool use and the prompt has waited about six seconds |
2169| `idle_prompt` | Claude finished responding about 60 seconds ago and you haven't typed since |
2170| `auth_success` | Authentication completes |
2171| `elicitation_dialog` | An MCP server opens an elicitation form and you haven't typed for about six seconds |
2172| `elicitation_url_dialog` | An MCP server asks you to open a browser URL and you haven't typed for about six seconds |
2173| `elicitation_complete` | An MCP elicitation form is submitted or dismissed |
2174| `elicitation_response` | An MCP elicitation response is sent back to the server |
2175| `agent_needs_input` | A background session starts waiting on your input. Fires only while [agent view](/docs/en/agent-view) is open in a terminal |
2176| `agent_completed` | A background session finishes or fails. Fires only while [agent view](/docs/en/agent-view) is open in a terminal |
2167| Matcher | When it fires |
2168| :--------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
2169| `permission_prompt` | Claude needs you to approve a tool use and the prompt has waited about six seconds |
2170| `idle_prompt` | Claude finished responding about 60 seconds ago and you haven't typed since |
2171| `auth_success` | Authentication completes |
2172| `elicitation_dialog` | An MCP server opens an elicitation form and you haven't typed for about six seconds |
2173| `elicitation_url_dialog` | An MCP server asks you to open a browser URL and you haven't typed for about six seconds |
2174| `elicitation_complete` | An MCP elicitation form is submitted or dismissed |
2175| `elicitation_response` | An MCP elicitation response is sent back to the server |
2176| `agent_needs_input` | A background session starts waiting on your input. Fires only while [agent view](/docs/en/agent-view) is open in a terminal |
2177| `agent_completed` | A background session finishes or fails. Fires only while [agent view](/docs/en/agent-view) is open in a terminal |
2178| `quota_auto_resume_fired` | Claude Code continues your task after a claude.ai usage limit paused it: at the reset, or sooner when something you do in Claude Code during the wait, such as adding usage credits, upgrading your plan, or switching models, makes usage available again, with the [model-setting exception](/docs/en/interactive-mode#wait-for-a-usage-limit-to-reset) |
2179| `quota_auto_resume_stale` | A claude.ai usage limit reset while your computer slept for more than about 30 minutes. Claude Code waits for you to press `Enter` instead of continuing. After a shorter sleep it continues and fires `quota_auto_resume_fired` instead |
2180| `quota_auto_resume_disabled` | Claude Code ends its wait for a claude.ai usage limit without continuing your task: [`autoContinueAtUsageLimit`](/docs/en/settings-reference#autocontinueatusagelimit) turned off or the reset moved more than 24 hours away during a wait Claude Code started on its own, the continued task kept hitting the limit, or the continuation was blocked before it reached the model. Doesn't fire when you press `Esc` or `Ctrl+C`, or pick **Don't continue automatically** |
21772181
21782182The `agent_needs_input` and `agent_completed` types require Claude Code v2.1.198 or later.
21792183
2184The `quota_auto_resume_fired`, `quota_auto_resume_stale`, and `quota_auto_resume_disabled` types require Claude Code v2.1.234 or later.
2185
21802186<Note>
21812187 The `permission_prompt`, `idle_prompt`, `elicitation_dialog`, and `elicitation_url_dialog` types share their timing with desktop notifications, so in terminal sessions you only see them when you appear to be away from the terminal:
21822188
21832189 * Expect `permission_prompt` once you haven't typed for about six seconds. The timer starts when the permission prompt appears, and each keystroke defers it. To run a hook immediately on every permission ask, use [PermissionRequest](#permissionrequest) instead.
2184 * Expect `idle_prompt` about 60 seconds after Claude finishes responding, and only if you haven't typed since.
2190 * Expect `idle_prompt` about 60 seconds after Claude finishes responding, and only if you haven't typed since. Claude Code doesn't send `idle_prompt` while it waits for a claude.ai usage limit to reset. When the wait ends on its own, one of the `quota_auto_resume_*` types fires instead.
21852191 * Expect `elicitation_dialog` for an elicitation form, or `elicitation_url_dialog` for a browser URL request, once you haven't typed for about six seconds. Both share the same six-second gate as `permission_prompt`: the timer starts when the dialog appears, and each keystroke defers it.
21862192</Note>
21872193
from line 2969
29632969
29642970### PostCompact
29652971
2966Runs after Claude Code completes a compact operation. Use this event to react to the new compacted state, for example to log the generated summary or update external state. Claude Code discards a PostCompact hook's `systemMessage` and `continue` fields.
2967
2968The same matcher values apply as for `PreCompact`:
2969
2970| Matcher | When it fires |
2971| :------- | :------------------------------------------------- |
2972| `manual` | After `/compact` |
2973| `auto` | After auto-compact when the context window is full |
2974
2975#### PostCompact input
2976
2977In addition to the [common input fields](#common-input-fields), PostCompact hooks receive `trigger` and `compact_summary`. The `compact_summary` field contains the conversation summary generated by the compact operation.
2978
2979```json theme={null}
2980{
2981 "session_id": "abc123",
2982 "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
2983 "cwd": "/Users/...",
2984 "hook_event_name": "PostCompact",
2985 "trigger": "manual",
2986 "compact_summary": "Summary of the compacted conversation..."
2987}
2988```
2989
2990PostCompact hooks have no decision control. They can't affect the compaction result but can perform follow-up tasks.
2991
2992### SessionEnd
2993
2994Runs when a Claude Code session ends. Useful for cleanup tasks, logging session
2995statistics, or saving session state. Supports matchers to filter by exit reason.
2996
2997The `reason` field in the hook input indicates why the session ended:
2998
2999| Reason | Description |
3000| :---------------------------- | :---------------------------------------------------------------------------------------- |
3001| `clear` | Session cleared with `/clear` command |
3002| `resume` | Session switched via interactive `/resume` |
3003| `logout` | User logged out |
3004| `prompt_input_exit` | User exited while prompt input was visible |
3005| `other` | Other exit reasons |
3006| `bypass_permissions_disabled` | Removed in v2.1.234; Claude Code doesn't send it. Drop it from your `SessionEnd` matchers |
3007
3008#### SessionEnd input
3009
3010In addition to the [common input fields](#common-input-fields), SessionEnd hooks receive a `reason` field indicating why the session ended. See the [reason table](#sessionend) above for all values.
3011
3012```json theme={null}
3013{
3014 "session_id": "abc123",
3015 "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
3016 "cwd": "/Users/...",
3017 "hook_event_name": "SessionEnd",
3018 "reason": "other"
3019}
3020```
3021
3022SessionEnd hooks have no decision control. They can't block session termination but can perform cleanup tasks. Claude Code discards their [JSON output fields](#json-output), such as `systemMessage`.
3023
3024SessionEnd hooks have a default timeout of 1.5 seconds. This applies to session exit, `/clear`, and switching sessions via interactive `/resume`. If a hook needs more time, set a per-hook `timeout` in the hook configuration. The overall budget is automatically raised to the highest per-hook timeout configured in settings files, up to 60 seconds. Timeouts set on plugin-provided hooks don't raise the budget. To override the budget explicitly, set the `CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS` environment variable in milliseconds.
3025
3026```bash theme={null}
3027CLAUDE_CODE_SESSIONEND_HOOKS_TIMEOUT_MS=5000 claude
3028```
3029
3030### Elicitation
3031
3032Runs when an MCP server requests user input mid-task. By default, Claude Code shows an interactive dialog for the user to respond. Hooks can intercept this request and respond programmatically, skipping the dialog entirely.
3033
3034The matcher field matches against the MCP server name.
3035
3036#### Elicitation input
3037
3038In addition to the [common input fields](#common-input-fields), Elicitation hooks receive `mcp_server_name`, `message`, and optional `mode`, `url`, `elicitation_id`, and `requested_schema` fields.
3039
3040For form-mode elicitation, the most common case:
3041
3042```json theme={null}
3043{
3044 "session_id": "abc123",
3045 "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
3046 "cwd": "/Users/...",
3047 "permission_mode": "default",
3048 "hook_event_name": "Elicitation",
3049 "mcp_server_name": "my-mcp-server",
3050 "message": "Please provide your credentials",
3051 "mode": "form",
3052 "requested_schema": {
3053 "type": "object",
3054 "properties": {
3055 "username": { "type": "string", "title": "Username" }
3056 }
3057 }
3058}
3059```
3060
3061For URL-mode elicitation, used for browser-based authentication:
3062
3063```json theme={null}
3064{
3065 "session_id": "abc123",
3066 "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
3067 "cwd": "/Users/...",
3068 "permission_mode": "default",
3069 "hook_event_name": "Elicitation",
3070 "mcp_server_name": "my-mcp-server",
3071 "message": "Please authenticate",
3072 "mode": "url",
3073 "url": "https://auth.example.com/login"
3074}
3075```
3076
3077#### Elicitation output
3078
3079To respond programmatically without showing the dialog, return a JSON object with `hookSpecificOutput`:
3080
3081```json theme={null}
3082{
3083 "hookSpecificOutput": {
3084 "hookEventName": "Elicitation",
3085 "action": "accept",
3086 "content": {
3087 "username": "alice"
3088 }
3089 }
3090}
3091```
3092
3093| Field | Values | Description |
3094| :-------- | :---------------------------- | :--------------------------------------------------------------- |
3095| `action` | `accept`, `decline`, `cancel` | Whether to accept, decline, or cancel the request |
3096| `content` | object | Form field values to submit. Only used when `action` is `accept` |
3097
3098Exit code 2 denies the elicitation. Claude Code doesn't show your stderr message anywhere.
3099
3100Claude Code acts on `hookSpecificOutput` from an Elicitation hook's JSON output and discards `systemMessage` and `continue`.
3101
3102### ElicitationResult
3103
3104Runs after a user responds to an MCP elicitation. Hooks can observe, modify, or block the response before it is sent back to the MCP server.
3105
3106The matcher field matches against the MCP server name.
3107
3108#### ElicitationResult input
3109
3110In addition to the [common input fields](#common-input-fields), ElicitationResult hooks receive `mcp_server_name`, `action`, and optional `mode`, `elicitation_id`, and `content` fields.
3111
3112```json theme={null}
3113{
3114 "session_id": "abc123",
3115 "transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
3116 "cwd": "/Users/...",
3117 "permission_mode": "default",
3118 "hook_event_name": "ElicitationResult",
3119 "mcp_server_name": "my-mcp-server",
3120 "action": "accept",
3121 "content": { "username": "alice" },
3122 "mode": "form",
3123 "elicitation_id": "elicit-123"
3124}
3125```
3126
3127#### ElicitationResult output
3128
3129To override the user's response, return a JSON object with `hookSpecificOutput`:
3130
3131```json theme={null}
3132{
3133 "hookSpecificOutput": {
3134 "hookEventName": "ElicitationResult",
3135 "action": "decline",
3136 "content": {}
3137 }
3138}
3139```
3140
3141| Field | Values | Description |
3142| :-------- | :---------------------------- | :--------------------------------------------------------------------- |
3143| `action` | `accept`, `decline`, `cancel` | Overrides the user's action |
3144| `content` |
2972Runs after Claude Code completes a compact operation. Use this event to react to the new compacted state, for example to log the generated summary or update external state. Claude Cod