# `ClaudeAgentSDK.Hooks`
[🔗](https://github.com/nshkrdotcom/claude_agent_sdk/blob/v0.15.0/lib/claude_agent_sdk/hooks/hooks.ex#L1)

Type definitions and utilities for Claude Code Hooks.

Hooks are callback functions invoked by the Claude Code CLI at specific
lifecycle events during agent execution. They enable:

- Intercepting tool calls before/after execution
- Adding contextual information automatically
- Controlling execution flow based on runtime conditions
- Implementing security policies and validation
- Monitoring and auditing agent behavior

## Hook Events

- `:pre_tool_use` - Before a tool executes
- `:post_tool_use` - After a tool executes
- `:post_tool_use_failure` - After a tool execution fails
- `:user_prompt_submit` - When user submits a prompt
- `:stop` - When the agent finishes
- `:subagent_start` - When a subagent spawns
- `:subagent_stop` - When a subagent finishes
- `:pre_compact` - Before context compaction
- `:notification` - When agent sends a notification
- `:permission_request` - When a permission dialog would be shown
- `:session_start` - When a session begins
- `:session_end` - When a session ends

## Examples

    # Define a hook callback
    def check_bash(input, _tool_use_id, _context) do
      case input do
        %{"tool_name" => "Bash", "tool_input" => %{"command" => cmd}} ->
          if String.contains?(cmd, "rm -rf") do
            Output.deny("Dangerous command blocked")
          else
            Output.allow()
          end
        _ -> %{}
      end
    end

    # Configure hooks
    hooks = %{
      pre_tool_use: [
        Matcher.new("Bash", [&check_bash/3])
      ]
    }

See: https://docs.anthropic.com/en/docs/claude-code/hooks

# `hook_callback`

```elixir
@type hook_callback() :: (hook_input(), String.t() | nil, hook_context() -&gt;
                      hook_output())
```

# `hook_config`

```elixir
@type hook_config() :: %{required(hook_event()) =&gt; [ClaudeAgentSDK.Hooks.Matcher.t()]}
```

Hook configuration map.

Maps hook events to lists of matchers.

## Example

    %{
      pre_tool_use: [
        %Matcher{matcher: "Bash", hooks: [&check_bash/3]},
        %Matcher{matcher: "Write|Edit", hooks: [&check_files/3]}
      ],
      post_tool_use: [
        %Matcher{matcher: "*", hooks: [&log_usage/3]}
      ]
    }

# `hook_context`

```elixir
@type hook_context() :: %{
  optional(:signal) =&gt; ClaudeAgentSDK.AbortSignal.t(),
  optional(atom()) =&gt; term()
}
```

Context information passed to hook callbacks.

Currently contains:
- `signal` - Optional abort signal reference for cooperative cancellation

Note: Can be an empty map initially.

# `hook_event`

```elixir
@type hook_event() ::
  :pre_tool_use
  | :post_tool_use
  | :post_tool_use_failure
  | :user_prompt_submit
  | :stop
  | :subagent_start
  | :subagent_stop
  | :pre_compact
  | :notification
  | :permission_request
  | :session_start
  | :session_end
```

Hook event types supported by the SDK.

# `hook_input`

```elixir
@type hook_input() :: %{
  :hook_event_name =&gt; String.t(),
  :session_id =&gt; String.t(),
  :transcript_path =&gt; String.t(),
  :cwd =&gt; String.t(),
  optional(:tool_name) =&gt; String.t(),
  optional(:tool_input) =&gt; map(),
  optional(:tool_response) =&gt; term(),
  optional(:tool_use_id) =&gt; String.t(),
  optional(:agent_id) =&gt; String.t(),
  optional(:agent_transcript_path) =&gt; String.t(),
  optional(:agent_type) =&gt; String.t(),
  optional(:error) =&gt; String.t(),
  optional(:is_interrupt) =&gt; boolean(),
  optional(:message) =&gt; String.t(),
  optional(:title) =&gt; String.t(),
  optional(:notification_type) =&gt; String.t(),
  optional(:permission_suggestions) =&gt; [map()],
  optional(:permission_mode) =&gt; String.t(),
  optional(:source) =&gt; String.t(),
  optional(:reason) =&gt; String.t(),
  optional(:prompt) =&gt; String.t(),
  optional(:trigger) =&gt; String.t(),
  optional(:custom_instructions) =&gt; String.t(),
  optional(:stop_hook_active) =&gt; boolean(),
  optional(atom()) =&gt; term()
}
```

Input data passed to hook callbacks.

The structure varies by hook event. Common fields:
- `hook_event_name` - String name of the event
- `session_id` - Session identifier
- `transcript_path` - Path to conversation transcript
- `cwd` - Current working directory

Event-specific fields:
- PreToolUse/PostToolUse/PostToolUseFailure/PermissionRequest: `tool_name`, `tool_input`
- PostToolUse: `tool_response`
- PostToolUseFailure: `error`, `is_interrupt`
- UserPromptSubmit: `prompt`
- Stop/SubagentStop: `stop_hook_active`
- SubagentStart/SubagentStop: `agent_id`, `agent_type`, `agent_transcript_path`
- Notification: `message`, `title`, `notification_type`
- PermissionRequest: `permission_suggestions`, `permission_mode`
- SessionStart: `source`
- SessionEnd: `reason`
- PreCompact: `trigger`, `custom_instructions`

# `hook_output`

```elixir
@type hook_output() :: ClaudeAgentSDK.Hooks.Output.t() | term()
```

Hook callback function signature.

Receives:
1. Input data (varies by event)
2. Tool use ID (for tool-related hooks, nil otherwise)
3. Context with abort signal

Returns:
- Hook output map controlling behavior (see `Output`)

# `all_valid_events`

```elixir
@spec all_valid_events() :: [hook_event()]
```

Returns all valid hook event atoms.

## Examples

    iex> events = ClaudeAgentSDK.Hooks.all_valid_events()
    iex> :pre_tool_use in events
    true
    iex> length(events)
    12

# `event_to_string`

```elixir
@spec event_to_string(hook_event()) :: String.t()
```

Converts an Elixir hook event atom to CLI string format.

## Examples

    iex> ClaudeAgentSDK.Hooks.event_to_string(:pre_tool_use)
    "PreToolUse"

    iex> ClaudeAgentSDK.Hooks.event_to_string(:post_tool_use)
    "PostToolUse"

# `string_to_event`

```elixir
@spec string_to_event(String.t()) :: hook_event() | nil
```

Converts a CLI hook event string to Elixir atom.

Returns `nil` for unknown event strings.

## Examples

    iex> ClaudeAgentSDK.Hooks.string_to_event("PreToolUse")
    :pre_tool_use

    iex> ClaudeAgentSDK.Hooks.string_to_event("UnknownEvent")
    nil

# `validate_config`

```elixir
@spec validate_config(hook_config()) :: :ok | {:error, String.t()}
```

Validates a hook configuration.

Returns `:ok` if valid, `{:error, reason}` otherwise.

## Examples

    iex> matcher = %ClaudeAgentSDK.Hooks.Matcher{
    ...>   matcher: "Bash",
    ...>   hooks: [fn _, _, _ -> %{} end]
    ...> }
    iex> ClaudeAgentSDK.Hooks.validate_config(%{pre_tool_use: [matcher]})
    :ok

    iex> ClaudeAgentSDK.Hooks.validate_config(%{invalid_event: []})
    {:error, "Invalid hook event: invalid_event"}

---

*Consult [api-reference.md](api-reference.md) for complete listing*
