Context: Working on claude-code-source-code-full (backup)

Claude Code Hook Event Telemetry

How hook telemetry works in the CLI

  • Hook lifecycle events are emitted as SDKSystemMessage entries in session.jsonl with three subtypes: hook_started, hook_progress, hook_response
  • Gated by setAllHookEventsEnabled() in src/utils/hooks/hookEvents.ts. Without it, only SessionStart and Setup hook events are emitted.
  • Enabled via --include-hook-events CLI flag (requires --output-format=stream-json) or automatically when CLAUDE_CODE_REMOTE=1

Python SDK consumer access

  • ClaudeAgentOptions in claude-agent-sdk-python has no first-class include_hook_events field
  • Workaround: use extra_args={"include-hook-events": None} to pass the CLI flag
  • The Python SDK’s primary hook mechanism is different: register HookCallback Python functions via the hooks field on ClaudeAgentOptions, which uses a bidirectional control protocol (SDKControlInitializeRequest / SDKHookCallbackRequest) rather than passively receiving stream events
  • Hook callbacks are defined per-event via HookMatcher with typed HookInput / HookJSONOutput

Key source files

  • src/utils/hooks.ts - main hook execution and telemetry (logEvent, startHookSpan)
  • src/utils/hooks/hookEvents.ts - event emission gating and lifecycle emitters
  • src/utils/telemetry/sessionTracing.ts - OpenTelemetry span creation (startHookSpan / endHookSpan)
  • src/entrypoints/sdk/coreSchemas.ts - SDK message schemas for hook events
  • src/cli/print.ts:628 - registerHookEventHandler converts internal events to SDK stream messages
  • Python SDK: src/claude_agent_sdk/types.py (ClaudeAgentOptions, HookMatcher, HookCallback)
  • Python SDK: src/claude_agent_sdk/_internal/transport/subprocess_cli.py (_build_command maps options to CLI args)