ClaudeAgentSDK.Hooks.Registry (claude_agent_sdk v0.11.0)

Copy Markdown View Source

Hook callback registration and ID management.

Maintains bidirectional mapping between callback functions and unique IDs for use with the Claude Code CLI hooks system.

Purpose

  • Assigns unique IDs to callback functions for CLI initialization
  • Enables lookup of callbacks by ID when CLI triggers hooks
  • Provides idempotent registration (re-registering same callback returns same ID)

Usage

This module is primarily used internally by ClaudeAgentSDK.Client, but can be used directly for testing hooks or building custom integrations.

registry = Registry.new()
callback = fn _input, _id, _ctx -> Output.allow() end

registry = Registry.register(registry, callback)
id = Registry.get_id(registry, callback)  # => "hook_0"

{:ok, ^callback} = Registry.get_callback(registry, id)

Summary

Types

t()

Registry state containing callback mappings.

Functions

Returns all registered callbacks.

Returns count of registered callbacks.

Gets callback function by ID.

Gets ID for a callback function.

Creates a new empty registry.

Registers a callback and returns updated registry.

Types

t()

@type t() :: %ClaudeAgentSDK.Hooks.Registry{
  callbacks: %{required(String.t()) => ClaudeAgentSDK.Hooks.hook_callback()},
  counter: non_neg_integer(),
  reverse_map: %{required(ClaudeAgentSDK.Hooks.hook_callback()) => String.t()}
}

Registry state containing callback mappings.

Fields:

  • callbacks - Map from ID string to callback function
  • reverse_map - Map from callback function to ID string (for quick lookup)
  • counter - Next ID number to assign

Functions

all_callbacks(registry)

@spec all_callbacks(t()) :: %{
  required(String.t()) => ClaudeAgentSDK.Hooks.hook_callback()
}

Returns all registered callbacks.

Parameters

  • registry - Registry to query

Returns

Map from ID string to callback function.

Examples

registry = Registry.new()
registry = Registry.register(registry, fn _, _, _ -> %{} end)

Registry.all_callbacks(registry)
# => %{"hook_0" => #Function<...>}

count(registry)

@spec count(t()) :: non_neg_integer()

Returns count of registered callbacks.

Parameters

  • registry - Registry to query

Returns

Non-negative integer count.

Examples

registry = Registry.new()
Registry.count(registry)
# => 0

registry = Registry.register(registry, fn _, _, _ -> %{} end)
Registry.count(registry)
# => 1

get_callback(registry, id)

@spec get_callback(t(), String.t()) ::
  {:ok, ClaudeAgentSDK.Hooks.hook_callback()} | :error

Gets callback function by ID.

Parameters

  • registry - Registry to query
  • id - Callback ID string (e.g., "hook_0")

Returns

  • {:ok, callback} if ID found
  • :error if ID not found

Examples

registry = Registry.new()
callback = fn _, _, _ -> %{} end
registry = Registry.register(registry, callback)

{:ok, retrieved} = Registry.get_callback(registry, "hook_0")
retrieved == callback
# => true

Registry.get_callback(registry, "hook_999")
# => :error

get_id(registry, callback)

@spec get_id(t(), ClaudeAgentSDK.Hooks.hook_callback()) :: String.t() | nil

Gets ID for a callback function.

Parameters

  • registry - Registry to query
  • callback - Callback function to look up

Returns

  • ID string if callback registered
  • nil if callback not found

Examples

registry = Registry.new()
callback = fn _, _, _ -> %{} end
registry = Registry.register(registry, callback)

Registry.get_id(registry, callback)
# => "hook_0"

other_callback = fn _, _, _ -> %{other: :callback} end
Registry.get_id(registry, other_callback)
# => nil

new()

@spec new() :: t()

Creates a new empty registry.

Examples

iex> registry = Registry.new()
iex> Registry.count(registry)
0

register(registry, callback)

@spec register(t(), ClaudeAgentSDK.Hooks.hook_callback()) :: t()

Registers a callback and returns updated registry.

If the callback is already registered, returns the existing registry without modification (idempotent operation).

Parameters

  • registry - Current registry state
  • callback - Callback function to register (must be 3-arity function)

Returns

Updated registry with callback registered.

Examples

registry = Registry.new()
callback = fn _input, _tool_use_id, _context -> %{} end

registry = Registry.register(registry, callback)
Registry.get_id(registry, callback)
# => "hook_0"

# Registering again is idempotent
registry = Registry.register(registry, callback)
Registry.count(registry)
# => 1