Claude Transcripts docs GitHub
Work in progressUnder active development — not tested as ready for use. Breaking changes land without notice, stored data may need to be discarded between revisions, and there is no auth or security model.

<!-- GENERATED from the blueprint (@claude-transcripts/shared) by scripts/gen-hook-events.ts. Do NOT edit by hand — run bun run gen:hook-events. Edit the blueprint: packages/shared/src/blueprint/hooks.ts (events/order/summaries) and actions.ts (the "What we do" bindings). -->

Claude Code hook events — when they fire, payloads & fixtures

The authoritative catalogue of every Claude Code hook event, projected from the app blueprint (@claude-transcripts/shared HOOK_TYPES): the one-line trigger for each, a link to the official documentation, links to example payload fixtures under tests/mock/claude-code/hooks/ (the inputs Claude Code sends a hook on stdin — used for both these docs and test automation), and the action(s) we run.

This table is the payload/fixture reference. actions.md narrates the hook → action model, and hook.md covers the writer mechanics. A per-version list (which events each Claude Code version exposes) is planned as compatibility.json (compatibility.md, ADR 0025); its generator is still a stub, so until then the official reference below is the authority when this table and a given CC version disagree.

How to read this table

Events are ordered by session lifecycle: a session begins at the top and ends (or crashes) at the bottom.

Common payload fields

Every hook receives these on stdin; per-event fields are layered on top.

FieldTypeMeaning
session_idstringClaude Code's own session UUID — our stable key.
transcript_pathstringAbsolute path to the session transcript (JSONL) on disk.
cwdstringWorking directory at the time the event fired.
hook_event_namestringThe event name (e.g. PostToolUse) — mirrors the row.
permission_modestring?Present on tool-related events (default, plan, …).
effortobject?`{ "level": "low\medium\high\…" }` when applicable.

Session start & setup

HookFires whenDocsExamplesWhat we do
SessionStartA session begins, resumes, is cleared, or restarts after compaction — source ∈ startup/resume/clear/compact. The per-session entry point.refsession-start/seed-session-start · write-event-marker · announce-recording · inject-recall-policy
SetupThe CLI runs in init/maintenance mode (e.g. --init-only) — one-time environment setup.refsetup/ignored — Env/setup signal, not session activity.
InstructionsLoadedCLAUDE.md / .claude/rules/*.md instruction files are loaded — load_reason records why. Observability of which instructions applied.refinstructions-loaded/ignored — Instruction-load audit — out of Tier-1 scope.

Turn input

HookFires whenDocsExamplesWhat we do
UserPromptSubmitThe user submits a prompt, before Claude sees it. Can block or inject context.refuser-prompt-submit/write-event-marker · update-counts · flush-transcript-chunk
UserPromptExpansionA slash command / skill prompt is expanded/templated before use.refuser-prompt-expansion/ignored — Slash-command expansion — redundant with UserPromptSubmit.

Tool lifecycle

HookFires whenDocsExamplesWhat we do
PreToolUseBefore a tool executes — tool_name + tool_input available. Can block or modify the input.refpre-tool-use/ignored — Blocking pre-hook; an observe-only writer gains nothing — PostToolUse captures the outcome.
PermissionRequestA permission dialog is about to be shown for a tool call.refpermission-request/ignored — Permission-dialog control hook, not session history.
PermissionDeniedA tool call was denied (auto-classifier or user).refpermission-denied/ignored — Permission control event, not session history.
PostToolUseA tool succeeds — tool_output available. Can post-process the result.refpost-tool-use/write-event-marker · update-counts · flush-transcript-chunk
PostToolUseFailureA tool fails — error_message available.refpost-tool-use-failure/write-event-marker · update-counts · flush-transcript-chunk
PostToolBatchA batch of parallel tool calls resolves.refpost-tool-batch/ignored — Batch boundary; the individual PostToolUse events are already captured.

Subagents, teams & tasks

HookFires whenDocsExamplesWhat we do
SubagentStartA subagent is spawned — agent_type, agent_id, task_description.refsubagent-start/write-event-marker · update-counts
SubagentStopA subagent finishes — summary of its work.refsubagent-stop/write-event-marker · update-counts
TeammateIdleA team teammate goes idle.refteammate-idle/ignored — Team orchestration, not session history.
TaskCreatedA task is created via TaskCreate.reftask-created/ignored — Task orchestration, not session history.
TaskCompletedA task is marked complete.reftask-completed/ignored — Task orchestration, not session history.

Display, MCP & notifications

HookFires whenDocsExamplesWhat we do
MessageDisplayAn assistant message is streamed/displayed to the user.refmessage-display/ignored — UX event; the message content is already in the transcript.
ElicitationAn MCP server requests user input.refelicitation/ignored — MCP interaction control hook; an observe-only writer gains nothing.
ElicitationResultThe user responds to an elicitation.refelicitation-result/ignored — MCP interaction event; the content is in the transcript.
NotificationClaude Code emits a notification (permission_prompt, idle_prompt, auth_success, …).refnotification/ignored — UX notification, not session history.

Environment, config & files

HookFires whenDocsExamplesWhat we do
CwdChangedThe working directory changes during a session.refcwd-changed/ignored — Host signal, out of session scope.
FileChangedA watched file changes on disk.reffile-changed/ignored — Watcher signal, out of session scope.
ConfigChangeA settings/config/skills file changes during the session (user_settings, project_settings, …).refconfig-change/ignored — Config-change signal, out of session scope.

Worktrees

HookFires whenDocsExamplesWhat we do
WorktreeCreateA git worktree is created (--worktree).refworktree-create/ignored — Git-worktree lifecycle, irrelevant to session logging.
WorktreeRemoveA git worktree is removed.refworktree-remove/ignored — Git-worktree lifecycle, irrelevant to session logging.

Compaction

HookFires whenDocsExamplesWhat we do
PreCompactBefore context compaction — trigger ∈ manual/auto.refpre-compact/write-event-marker
PostCompactAfter compaction completes — trigger ∈ manual/auto.refpost-compact/write-event-marker

Turn end

HookFires whenDocsExamplesWhat we do
StopClaude finishes responding to a turn — turn_number, assistant_message.refstop/write-event-marker · flush-transcript-chunk
StopFailureA turn ends with an API error — rate_limit, overloaded, max_output_tokens, … A turn-level failure (see the crash note in the doc).refstop-failure/write-event-marker · update-counts

Session end

HookFires whenDocsExamplesWhat we do
SessionEndThe session terminates — reason ∈ clear/resume/logout/prompt_input_exit/bypass_permissions_disabled/other.refsession-end/flush-transcript-chunk · write-summary · upload-blobs

On crashes. There is no dedicated "session crashed" event. Abnormal termination surfaces in three ways, in increasing severity:

  1. StopFailure — the turn hit an API/runtime error but the session is alive.
  2. SessionEnd with reason: "other" — an orderly-but-non-standard shutdown.
  3. No SessionEnd at all — a hard crash / kill. The session is then detected as incomplete by derivation (see couchdb.md → status model) and finalised by the reconcile utility (tools.md). Fixtures for (1) and (2) live under stop-failure/ and session-end/; case (3) is exercised by leaving a started session with no end fixture.

Coverage vs. what we wire today

We currently bind actions to 11 of the 30 events — SessionStart, UserPromptSubmit, PostToolUse, PostToolUseFailure, SubagentStart, SubagentStop, PreCompact, PostCompact, Stop, StopFailure, SessionEnd. The rest are intentionally ignored — the "What we do" column gives the reason per event: a passive, observe-only writer gains nothing from blocking / UX / orchestration hooks, and every hook invocation costs a Bun startup, so we wire only the events that carry the session record (actions.md). Wiring an ignored event = add the action + binding in the blueprint, then regenerate hooks.json (bun run gen:hooks).

Field-shape caveat. Payload field names/casing follow the official reference at authoring time. Claude Code is upstream and evolving; when in doubt, capture a real payload (every hook just receives JSON on stdin — … | tee fixture.json) and reconcile against the official reference.