Quickstart: Hooks

Register a handler, fire an event, and confirm execution — all in under ten lines of code.

from hooks import HookRegistry, HookEvent

registry = HookRegistry()
registry.register(HookEvent.POST_TOOL, lambda ctx: print("fired:", ctx), description="my first hook")
results = registry.fire_sync(HookEvent.POST_TOOL, context={"tool": "bash"})
print(results)

Expected output:

fired: {'tool': 'bash'}
[{'tool': 'bash'}]

Step 1: Create a registry

from hooks import HookRegistry, HookConfig

registry = HookRegistry()

To load hooks from a YAML file instead, pass a config object:

config = HookConfig.from_yaml("hooks.yaml")
registry = HookRegistry(config=config)

Step 2: Register a handler

Call registry.register() with an event, a callable, and an optional description:

handler_id = registry.register(
    HookEvent.POST_TOOL,
    lambda ctx: {"logged": True},
    description="log tool completions",
    priority=0,
)
print(handler_id)  # "abc123..."

Save handler_id if you need to remove the handler later with registry.unregister(handler_id).

Step 3: Fire the event

Use fire_sync in synchronous code:

results = registry.fire_sync(HookEvent.POST_TOOL, context={"tool": "bash", "exit_code": 0})
print(results)

Expected output:

[{'logged': True}]

Each item in the list is the return value from one registered handler.

Step 4: Check the execution log

log = registry.get_execution_log(limit=5, event_filter=HookEvent.POST_TOOL)
print(log)

get_execution_log returns up to limit recent entries. Filter by event type to narrow the results.


Next: Add a HookMatcher to your register() call so the handler fires only when context meets a specific condition — see the hooks concept page for matcher patterns.

Unresolved references

Auto-generated by attune-author fact-check. Review and either fix the source code, fix this doc, or add an override.

Location Severity Issue
Line 15 (code fence) error from hooks import … — module not importable