Follow Discord
Sweep 28 Sep 2026 · 18:16Z Build v2.1.284 505 read Stable v2.1.277 Latest v2.1.284 Next v2.1.284 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · claude-code

Automate actions with hooks changedhooks-guide

Nearest release: v2.1.284, published 16 hours after upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Upstream edited this page at 28 Sep 2026 00:42 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 28 Sep 2026 23:37 UTC.

Upstream edited
Recorded here
Lines+84added
Lines−84removed
From line 177 where the diff opens
First seen 14 Aug 2026 this site's first read of the page
Recorded edits24to this page, all time

The whole hunk

from line 177, old and new numbered
/
lines
from line 177
177177 
178178The empty `matcher` fires on all notification types. To fire only on specific events, set it to one of these values:
179179 
180| Matcher | Fires when |
181| :--------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
182| `permission_prompt` | Claude needs you to approve a tool use or a sandboxed command's [network request](/docs/en/sandboxing#network-isolation), and the prompt has waited about six seconds |
183| `idle_prompt` | Claude finished responding about 60 seconds ago and you haven't typed since |
184| `auth_success` | Authentication completes |
185| `elicitation_dialog` | An MCP server opens an elicitation form and you haven't typed for about six seconds |
186| `elicitation_url_dialog` | An MCP server asks you to open a browser URL and you haven't typed for about six seconds |
187| `elicitation_complete` | An MCP server reports that a [URL-mode elicitation](/docs/en/hooks#elicitation-input) is complete |
188| `elicitation_response` | An MCP elicitation response is sent back to the server |
189| `agent_needs_input` | A background session starts waiting on your input while [agent view](/docs/en/agent-view) is open, or the current session asks you an [agent team teammate's terminal setup question](/docs/en/agent-teams#choose-a-display-mode) and you haven't typed for about six seconds |
190| `agent_completed` | A background session finishes or fails. Fires only while [agent view](/docs/en/agent-view) is open |
191| `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) |
192| `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 |
180| Matcher | Fires when |
181| :- | :- |
182| `permission_prompt` | Claude needs you to approve a tool use or a sandboxed command's [network request](/docs/en/sandboxing#network-isolation), and the prompt has waited about six seconds |
183| `idle_prompt` | Claude finished responding about 60 seconds ago and you haven't typed since |
184| `auth_success` | Authentication completes |
185| `elicitation_dialog` | An MCP server opens an elicitation form and you haven't typed for about six seconds |
186| `elicitation_url_dialog` | An MCP server asks you to open a browser URL and you haven't typed for about six seconds |
187| `elicitation_complete` | An MCP server reports that a [URL-mode elicitation](/docs/en/hooks#elicitation-input) is complete |
188| `elicitation_response` | An MCP elicitation response is sent back to the server |
189| `agent_needs_input` | A background session starts waiting on your input while [agent view](/docs/en/agent-view) is open, or the current session asks you an [agent team teammate's terminal setup question](/docs/en/agent-teams#choose-a-display-mode) and you haven't typed for about six seconds |
190| `agent_completed` | A background session finishes or fails. Fires only while [agent view](/docs/en/agent-view) is open |
191| `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) |
192| `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 |
193193| `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** |
194194 
195195Claude Code times `permission_prompt` differently in a terminal and in Claude Desktop, the VS Code extension, and other hosts that answer permission requests through the Agent SDK. See [when each notification type fires](/docs/en/hooks#notification) for both timings.
from line 475
475475 
476476Claude Code fires hook events at specific points in its lifecycle. When an event fires, Claude Code runs all matching hooks in parallel; see [Hook handler fields](/docs/en/hooks#hook-handler-fields) for how duplicate handlers are treated. The table below shows each event and when it triggers:
477477 
478| Event | When it fires |
479| :-------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
480| `SessionStart` | When a session begins or resumes |
481| `Setup` | When you start Claude Code with `--init-only`, or with `--init` or `--maintenance` in `-p` mode. For one-time preparation in CI or scripts |
482| `UserPromptSubmit` | When you submit a prompt, before Claude processes it |
483| `UserPromptExpansion` | When a user-typed command expands into a prompt, before it reaches Claude. Can block the expansion |
484| `PreToolUse` | Before a tool call executes. Can block it |
485| `PermissionRequest` | When a tool call needs a permission decision |
486| `PermissionDenied` | When auto mode denies a tool call, including denials without a classifier verdict. Use JSON `hookSpecificOutput.retry: true` to tell the model it may retry the denied tool call. Claude Code ignores `retry` when the classifier produced no verdict |
487| `PostToolUse` | After a tool call succeeds |
488| `PostToolUseFailure` | After a tool call fails |
489| `PostToolBatch` | After a full batch of parallel tool calls resolves, before the next model call |
490| `Notification` | When Claude Code sends a notification |
491| `MessageDisplay` | While assistant message text is displayed |
492| `SubagentStart` | When a subagent is spawned |
493| `SubagentStop` | When a subagent finishes |
494| `TaskCreated` | When a task is being created via `TaskCreate` |
495| `TaskCompleted` | When a task is being marked as completed |
496| `Stop` | When Claude finishes responding |
497| `StopFailure` | When the turn ends due to an API error |
498| `TeammateIdle` | When an [agent team](/docs/en/agent-teams) teammate is about to go idle |
499| `InstructionsLoaded` | When a CLAUDE.md or `.claude/rules/*.md` file is loaded into context. Fires at session start and when files are lazily loaded during a session |
500| `ConfigChange` | When a configuration file changes during a session |
501| `CwdChanged` | When the working directory changes, for example when Claude executes a `cd` command. Useful for reactive environment management with tools like direnv |
502| `DirectoryAdded` | When a working directory is added mid-session via `/add-dir` or the SDK `register_repo_root` control request |
503| `FileChanged` | When a watched file changes on disk. The `matcher` field specifies which filenames to watch |
504| `WorktreeCreate` | When a worktree is being created via `--worktree`, `isolation: "worktree"`, or for a background session. Replaces default git behavior |
505| `WorktreeRemove` | When a worktree is being removed at session exit, when a subagent finishes, or when you delete a background session |
506| `PreCompact` | Before context compaction |
507| `PostCompact` | After context compaction completes |
508| `PreModelSwitch` | Before Claude Code applies a model switch that you or a client requested. Can block the switch |
509| `PostModelSwitch` | After the session's model changes, including changes Claude Code makes on its own, such as restoring the model when you resume a session |
510| `Elicitation` | When an MCP server requests user input during a tool call |
511| `ElicitationResult` | After a user responds to an MCP elicitation, before the response is sent back to the server |
512| `SessionEnd` | When a session terminates |
478| Event | When it fires |
479| :- | :- |
480| `SessionStart` | When a session begins or resumes |
481| `Setup` | When you start Claude Code with `--init-only`, or with `--init` or `--maintenance` in `-p` mode. For one-time preparation in CI or scripts |
482| `UserPromptSubmit` | When you submit a prompt, before Claude processes it |
483| `UserPromptExpansion` | When a user-typed command expands into a prompt, before it reaches Claude. Can block the expansion |
484| `PreToolUse` | Before a tool call executes. Can block it |
485| `PermissionRequest` | When a tool call needs a permission decision |
486| `PermissionDenied` | When auto mode denies a tool call, including denials without a classifier verdict. Use JSON `hookSpecificOutput.retry: true` to tell the model it may retry the denied tool call. Claude Code ignores `retry` when the classifier produced no verdict |
487| `PostToolUse` | After a tool call succeeds |
488| `PostToolUseFailure` | After a tool call fails |
489| `PostToolBatch` | After a full batch of parallel tool calls resolves, before the next model call |
490| `Notification` | When Claude Code sends a notification |
491| `MessageDisplay` | While assistant message text is displayed |
492| `SubagentStart` | When a subagent is spawned |
493| `SubagentStop` | When a subagent finishes |
494| `TaskCreated` | When a task is being created via `TaskCreate` |
495| `TaskCompleted` | When a task is being marked as completed |
496| `Stop` | When Claude finishes responding |
497| `StopFailure` | When the turn ends due to an API error |
498| `TeammateIdle` | When an [agent team](/docs/en/agent-teams) teammate is about to go idle |
499| `InstructionsLoaded` | When a CLAUDE.md or `.claude/rules/*.md` file is loaded into context. Fires at session start and when files are lazily loaded during a session |
500| `ConfigChange` | When a configuration file changes during a session |
501| `CwdChanged` | When the working directory changes, for example when Claude executes a `cd` command. Useful for reactive environment management with tools like direnv |
502| `DirectoryAdded` | When a working directory is added mid-session via `/add-dir` or the SDK `register_repo_root` control request |
503| `FileChanged` | When a watched file changes on disk. The `matcher` field specifies which filenames to watch |
504| `WorktreeCreate` | When a worktree is being created via `--worktree`, `isolation: "worktree"`, or for a background session. Replaces default git behavior |
505| `WorktreeRemove` | When a worktree is being removed at session exit, when a subagent finishes, or when you delete a background session |
506| `PreCompact` | Before context compaction |
507| `PostCompact` | After context compaction completes |
508| `PreModelSwitch` | Before Claude Code applies a model switch that you or a client requested. Can block the switch |
509| `PostModelSwitch` | After the session's model changes, including changes Claude Code makes on its own, such as restoring the model when you resume a session |
510| `Elicitation` | When an MCP server requests user input during a tool call |
511| `ElicitationResult` | After a user responds to an MCP elicitation, before the response is sent back to the server |
512| `SessionEnd` | When a session terminates |
513513 
514514Each hook has a `type` that determines how it runs. Most hooks use `"type": "command"`, which runs a shell command. Four other types are available:
515515 
from line 682
682682 
683683Each event type matches on a specific field:
684684 
685| Event | What the matcher filters | Example matcher values |
686| :-------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
687| `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest`, `PermissionDenied` | tool name | `Bash`, `Edit\|Write`, `mcp__.*` |
688| `SessionStart` | how the session started | `startup`, `resume`, `clear`, `compact`, `fork` |
689| `Setup` | which CLI flag triggered setup | `init`, `maintenance` |
690| `SessionEnd` | why the session ended | `clear`, `resume`, `logout`, `prompt_input_exit`, `other` |
691| `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` |
692| `SubagentStart` | agent type | `general-purpose`, `Explore`, `Plan`, or custom agent names |
693| `PreCompact`, `PostCompact` | what triggered compaction | `manual`, `auto` |
694| `PreModelSwitch`, `PostModelSwitch` | canonical name of the model the session switches to, as described under [PreModelSwitch](/docs/en/hooks#premodelswitch) | `claude-opus-5`, `claude-opus-4-6\|claude-opus-5`, `.*opus.*` |
695| `SubagentStop` | agent type | same values as `SubagentStart` |
696| `ConfigChange` | configuration source | `user_settings`, `project_settings`, `local_settings`, `policy_settings`, `skills` |
697| `DirectoryAdded` | how the directory was added | `slash_command`, `register_repo_root` |
698| `StopFailure` | error type | `rate_limit`, `overloaded`, `authentication_failed`, `oauth_org_not_allowed`, `account_on_hold`, `billing_error`, `invalid_request`, `model_not_found`, `server_error`, `max_output_tokens`, `cloud_credential_error`, `unknown` |
699| `InstructionsLoaded` | load reason | `session_start`, `nested_traversal`, `path_glob_match`, `include`, `compact` |
700| `Elicitation` | MCP server name | your configured MCP server names |
701| `ElicitationResult` | MCP server name | same values as `Elicitation` |
702| `FileChanged` | literal filenames to watch (see [FileChanged](/docs/en/hooks#filechanged)) | `.envrc\|.env` |
703| `UserPromptExpansion` | command name | your skill or command names |
704| `UserPromptSubmit`, `PostToolBatch`, `Stop`, `TeammateIdle`, `TaskCreated`, `TaskCompleted`, `WorktreeCreate`, `WorktreeRemove`, `CwdChanged`, `MessageDisplay` | no matcher support | always fires on every occurrence |
685| Event | What the matcher filters | Example matcher values |
686| :- | :- | :- |
687| `PreToolUse`, `PostToolUse`, `PostToolUseFailure`, `PermissionRequest`, `PermissionDenied` | tool name | `Bash`, `Edit\|Write`, `mcp__.*` |
688| `SessionStart` | how the session started | `startup`, `resume`, `clear`, `compact`, `fork` |
689| `Setup` | which CLI flag triggered setup | `init`, `maintenance` |
690| `SessionEnd` | why the session ended | `clear`, `resume`, `logout`, `prompt_input_exit`, `other` |
691| `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` |
692| `SubagentStart` | agent type | `general-purpose`, `Explore`, `Plan`, or custom agent names |
693| `PreCompact`, `PostCompact` | what triggered compaction | `manual`, `auto` |
694| `PreModelSwitch`, `PostModelSwitch` | canonical name of the model the session switches to, as described under [PreModelSwitch](/docs/en/hooks#premodelswitch) | `claude-opus-5`, `claude-opus-4-6\|claude-opus-5`, `.*opus.*` |
695| `SubagentStop` | agent type | same values as `SubagentStart` |
696| `ConfigChange` | configuration source | `user_settings`, `project_settings`, `local_settings`, `policy_settings`, `skills` |
697| `DirectoryAdded` | how the directory was added | `slash_command`, `register_repo_root` |
698| `StopFailure` | error type | `rate_limit`, `overloaded`, `authentication_failed`, `oauth_org_not_allowed`, `account_on_hold`, `billing_error`, `invalid_request`, `model_not_found`, `server_error`, `max_output_tokens`, `cloud_credential_error`, `unknown` |
699| `InstructionsLoaded` | load reason | `session_start`, `nested_traversal`, `path_glob_match`, `include`, `compact` |
700| `Elicitation` | MCP server name | your configured MCP server names |
701| `ElicitationResult` | MCP server name | same values as `Elicitation` |
702| `FileChanged` | literal filenames to watch (see [FileChanged](/docs/en/hooks#filechanged)) | `.envrc\|.env` |
703| `UserPromptExpansion` | command name | your skill or command names |
704| `UserPromptSubmit`, `PostToolBatch`, `Stop`, `TeammateIdle`, `TaskCreated`, `TaskCompleted`, `WorktreeCreate`, `WorktreeRemove`, `CwdChanged`, `MessageDisplay` | no matcher support | always fires on every occurrence |
705705 
706706The tabs below show a few more matchers on different event types.
707707 
from line 802
802802 
803803Whether your hook command runs depends on the shape of your `if` pattern and the Bash command Claude is invoking:
804804 
805| `if` pattern | Bash command | Hook runs? | Why |
806| :----------------- | :--------------------- | :--------- | :-------------------------------------------------------------------------------------------------- |
807| `Bash(git *)` | `git push` | yes | command name matches |
808| `Bash(git *)` | `npm test && git push` | yes | each subcommand is checked; `git push` matches |
809| `Bash(git *)` | `echo $(git log)` | yes | commands inside `$()` and backticks are checked; `git log` matches |
810| `Bash(git *)` | `echo $(date)` | no | no subcommand matches `git *` |
811| `Bash(git push *)` | `echo $(date)` | yes | patterns that specify more than the command name run the hook anyway on `$()`, backticks, or `$VAR` |
805| `if` pattern | Bash command | Hook runs? | Why |
806| :- | :- | :- | :- |
807| `Bash(git *)` | `git push` | yes | command name matches |
808| `Bash(git *)` | `npm test && git push` | yes | each subcommand is checked; `git push` matches |
809| `Bash(git *)` | `echo $(git log)` | yes | commands inside `$()` and backticks are checked; `git log` matches |
810| `Bash(git *)` | `echo $(date)` | no | no subcommand matches `git *` |
811| `Bash(git push *)` | `echo $(date)` | yes | patterns that specify more than the command name run the hook anyway on `$()`, backticks, or `$VAR` |
812812 
813813When Claude Code can't determine which commands the Bash input runs, it runs your hook regardless of the pattern. The [Bash matching table](/docs/en/hooks#bash-if-matching) covers the command shapes Claude Code can and can't narrow by subcommand. Because the filter is best-effort, use the [permission system](/docs/en/permissions) rather than a hook to enforce a hard allow or deny.
814814 
from line 820
820820 
821821Where you add a hook determines its scope:
822822 
823| Location | Scope | Shareable |
824| :------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------ | :---------------------------------------------------- |
825| `~/.claude/settings.json` | All your projects | No, local to your machine |
826| `.claude/settings.json` | Single project | Yes, can be committed to the repo |
827| `.claude/settings.local.json` | Single project | No, gitignored when Claude Code saves a setting to it |
828| Managed policy settings | Organization-wide | Yes, admin-controlled |
829| [Plugin](/docs/en/plugins/overview) `hooks/hooks.json` | When plugin is enabled | Yes, bundled with the plugin |
830| [Skill](/docs/en/skills) frontmatter | The rest of the session once the skill is invoked. See [Hooks in skills and agents](/docs/en/hooks#hooks-in-skills-and-agents) | Yes, defined in the skill file |
831| [Subagent](/docs/en/sub-agents) frontmatter | While that subagent is running | Yes, defined in the subagent file |
823| Location | Scope | Shareable |
824| :- | :- | :- |
825| `~/.claude/settings.json` | All your projects | No, local to your machine |
826| `.claude/settings.json` | Single project | Yes, can be committed to the repo |
827| `.claude/settings.local.json` | Single project | No, gitignored when Claude Code saves a setting to it |
828| Managed policy settings | Organization-wide | Yes, admin-controlled |
829| [Plugin](/docs/en/plugins/overview) `hooks/hooks.json` | When plugin is enabled | Yes, bundled with the plugin |
830| [Skill](/docs/en/skills) frontmatter | The rest of the session once the skill is invoked. See [Hooks in skills and agents](/docs/en/hooks#hooks-in-skills-and-agents) | Yes, defined in the skill file |
831| [Subagent](/docs/en/sub-agents) frontmatter | While that subagent is running | Yes, defined in the subagent file |
832832 
833833Run [`/hooks`](/docs/en/hooks#the-%2Fhooks-menu) in Claude Code to browse all configured hooks grouped by event.
834834 
Feedback