Implements an 8-event hook lifecycle compatible with Claude Code's hook system. Hooks intercept tool execution before and after, provide veto capability, and fire on session lifecycle events.
- PreToolUse hooks run before tool execution. Any hook may return modified arguments (dict) or raise
HookErrorto veto the call.Nonemeans "allow, no changes." - PostToolUse hooks run after tool execution. Any hook may return modified result (dict).
Nonemeans "keep original." - Session lifecycle hooks (SessionStart, SessionEnd, UserPromptSubmit, Stop, SubagentStop) receive
(session_id, context)and return nothing. Exceptions propagate. - PreCompact hooks receive and may return a modified compaction context.
- Hook chain is ordered — hooks run in registration order. First veto wins for PreToolUse.
config.enabled = Falseshort-circuits all hooks; all run_* methods returnNoneimmediately.
| Event | Type | Can veto? | Can modify? |
|---|---|---|---|
SessionStart |
SessionHookFn |
No | context dict |
UserPromptSubmit |
SessionHookFn |
No | context dict |
PreToolUse |
PreToolUseHookFn |
Yes (HookError) | arguments |
PostToolUse |
PostToolUseHookFn |
No | result dict |
PreCompact |
PreCompactHookFn |
No | compaction context |
Stop |
SessionHookFn |
No | — |
SubagentStop |
SessionHookFn |
No | — |
SessionEnd |
SessionHookFn |
No | — |
HookPermissionMode is distinct from teaagent.policy.PermissionMode:
HookPermissionMode.ALLOW— no restrictionHookPermissionMode.DENY— block all destructive toolsHookPermissionMode.ASK— block destructive tools indestructive_toolssetHookPermissionMode.AUTO— same as ASK (default)
This operates at the per-call level within PreToolUse, not the session permission policy.
- A
HookErrorfrom a pre-hook must prevent tool execution — the runner is responsible for catching it. - Hook registration is not thread-safe by default; register all hooks before the agent loop starts.
lint_check_hookis an alias forpost_lint_check_hook(same function, legacy name).shell_command_hookusesshlex.split+shell=Falseto prevent injection.