The hook system is the automatic capture layer of the Claude Memory Compiler. Three hooks fire at key moments in the Claude Code session lifecycle:Documentation Index
Fetch the complete documentation index at: https://mintlify.com/coleam00/claude-memory-compiler/llms.txt
Use this file to discover all available pages before exploring further.
SessionStart injects accumulated knowledge into every new conversation, SessionEnd extracts the transcript when a session closes, and PreCompact acts as a safety net before Claude Code discards context during auto-compaction. None of the hooks make API calls directly — they are designed to complete in under ten seconds and hand off heavy work to the background flush.py process.
Configuration
Hooks are registered in.claude/settings.json at the project root. Claude Code reads this file automatically when you open the project.
matcher string causes each hook to fire on every matching event, regardless of the prompt or tool involved. Commands use relative paths from the project root.
SessionStart — hooks/session-start.py
SessionStart fires when Claude Code opens a new session. It is the only hook that produces output Claude reads directly; the other two hooks exist purely to capture data.
Trigger
Claude Code emits aSessionStart event at the beginning of every new conversation in the project.
I/O contract
Stdin: none —session-start.py does not read from stdin.
Stdout: a JSON object in the exact format Claude Code expects for context injection:
additionalContext string is prepended to Claude’s context window, so Claude “remembers” the knowledge base index and recent activity before the user types anything.
What it reads
The hook assembles its context from two sources:knowledge/index.md— the master catalog of every compiled article. This is the primary retrieval mechanism: Claude reads it to decide which articles are relevant to the current task.- The most recent daily log — today’s
daily/YYYY-MM-DD.mdif it exists, otherwise yesterday’s. Only the lastMAX_LOG_LINES(30) lines are included to keep the payload small.
Limits and truncation
...(truncated) suffix appended.
Performance
No API calls are made. The hook is pure local file I/O and completes well under one second. The 15-secondtimeout in settings.json is a generous safety margin.
SessionEnd — hooks/session-end.py
SessionEnd fires when the user closes or exits a Claude Code session. It extracts the conversation transcript and hands it to flush.py for background processing.
Trigger
Claude Code emits aSessionEnd event when a session terminates normally.
Recursion guard
At the top of the script, before any other logic:flush.py calls the Claude Agent SDK, the SDK may spin up its own Claude Code subprocess. That subprocess would fire session-end.py again, creating an infinite loop. The guard breaks it: flush.py sets CLAUDE_INVOKED_BY=memory_flush in its environment before it starts, so any hook fired by its subprocess exits immediately.
I/O contract
Stdin: a JSON object from Claude Code:scripts/flush.log.
What it does
Parse stdin
Reads the JSON payload from stdin. Handles Windows path escaping quirks (unescaped backslashes) with a regex fix before parsing.
Extract context
Reads the JSONL transcript file, extracts up to 30 message turns, and serializes them as a plain-markdown string (at most 15,000 characters, trimmed to a clean turn boundary).
Write temp file
Writes the extracted context to a temp file in
scripts/. session-end.py names it session-flush-<session_id>-<timestamp>.md; pre-compact.py names it flush-context-<session_id>-<timestamp>.md. The background process reads this file; writing it in the hook avoids passing large data through process arguments.Skip conditions
The hook exits without spawningflush.py when:
transcript_pathis absent or empty in the stdin payload- The transcript file does not exist on disk
- The extracted context is empty after parsing
- Fewer than 1 turn is present in the transcript
PreCompact — hooks/pre-compact.py
PreCompact fires immediately before Claude Code auto-compacts the context window. Its architecture is identical to SessionEnd — the same recursion guard, the same JSONL parsing, the same temp-file-then-spawn pattern.
Trigger
Claude Code emits aPreCompact event when the context window approaches its limit and Claude Code is about to summarize and discard accumulated context.
Why PreCompact exists alongside SessionEnd
Long sessions may trigger multiple auto-compactions before the user ever closes the session. Each compaction discards the raw message history for the compacted portion. By the timeSessionEnd fires at the end of a long session, the transcript may contain only the final summary rather than the full detail.
PreCompact captures the raw context before each compaction, ensuring nothing is lost. The 60-second deduplication window in flush.py prevents multiple flushes from the same burst.
Bug guard — empty transcript path
transcript_path is sometimes an empty string in the PreCompact payload. The hook checks for this and exits cleanly rather than crashing.
Difference from SessionEnd
The only behavioral difference is the minimum-turn threshold:| Hook | MIN_TURNS_TO_FLUSH |
|---|---|
session-end.py | 1 |
pre-compact.py | 5 |
PreCompact requires at least 5 turns before flushing. Compactions can fire early in a session with very little content; the higher threshold avoids flushing nearly-empty transcripts.
JSONL transcript format
Claude Code stores conversations as newline-delimited JSON (.jsonl) files. Each line is one event. Messages are nested under a message key:
user and assistant roles are extracted. Tool calls, system messages, and other event types are silently ignored.
Hook summary
| Hook | File | Timeout | Makes API calls | Produces output |
|---|---|---|---|---|
| SessionStart | hooks/session-start.py | 15 s | No | Yes (JSON to stdout) |
| SessionEnd | hooks/session-end.py | 10 s | No | No |
| PreCompact | hooks/pre-compact.py | 10 s | No | No |