Episode 4: Lifecycle Hooks — How Claude-Mem Takes Notes Behind Your Back

⏱ Est. reading time: 12 min Updated on 5/7/2026

This episode's scenario: You ask Claude to fix a comment bug in the blog project. In those 5 minutes, Claude-Mem fires hooks dozens of times and records multiple Observations. How does it know when to act?


4.1 What's a Lifecycle Hook?

A Lifecycle Hook is a mechanism in Claude Code's plugin system:

When a specific event occurs inside Claude Code, automatically run a registered script.

Like phone automation shortcuts — when you arrive home (event) → lights turn on (script). In Claude-Mem, when Claude performs an action (event) → notes are taken (script).


4.2 The Five Lifecycle Events

graph TD
    subgraph "Session Lifecycle"
        A["🟢 SessionStart"] -->|"You open Claude Code"| B["📝 UserPromptSubmit"]
        B -->|"You send a message"| C["🔧 PostToolUse"]
        C -->|"Claude uses a tool"| C
        C --> D["⏸ Stop"]
        D -->|"Claude stops activity"| E["🔴 SessionEnd"]
    end

    F["⚙️ Smart Install
(helper script)"] -.->|"Runs at install"| A style A fill:#10b981,color:#fff style B fill:#6366f1,color:#fff style C fill:#f59e0b,color:#000 style D fill:#94a3b8,color:#000 style E fill:#ef4444,color:#fff style F fill:#64748b,color:#fff

1️⃣ SessionStart — Session Opens

Triggers when: You launch Claude Code

What it does:

  • Sends GET /api/context to the Worker
  • Worker queries SQLite for Observations and Summaries from the last 10 sessions
  • Injects those historical notes into Claude's initial context

Effect: Claude "recalls" your previous work before you even say your first word.

2️⃣ UserPromptSubmit — You Send a Message

Triggers when: Every time you press Enter to send a message

What it does: Sends your prompt to the Worker, which stores it in the user_prompts table.

3️⃣ PostToolUse — After Tool Execution (🔑 The Most Important Hook!)

Triggers when: Every time Claude uses a tool (Read, Write, Bash, Search, etc.)

What it does:

  1. Captures tool input and output
  2. POSTs raw data to the Worker
  3. Worker uses Claude Agent SDK for AI compression
  4. Generates a structured Observation (title, narrative, facts, concepts, type)
  5. Stores in SQLite + ChromaDB

This is Claude-Mem's core engine.

4️⃣ Stop — Pause

Triggers when: Claude stops active work (waiting for your next message)

What it does: Lightweight state sync to ensure all in-flight Observations are committed.

5️⃣ SessionEnd — Session Closes

Triggers when: You close Claude Code or end the session

What it does:

  1. Notifies Worker the session is ending
  2. Worker reviews all Observations from this session
  3. Generates a Session Summary (request, investigated, completed, next_steps)
  4. Stores in session_summaries table

Key: The next_steps field gets read and injected at the next SessionStart — that's the secret to cross-session continuity.


4.3 Hook Script Locations

~/.claude/plugins/marketplaces/thedotmack/plugin/hooks/
├── session-start.sh
├── user-prompt.sh
├── post-tool-use.sh
├── stop.sh
├── session-end.sh
└── pre-hook.sh           # Smart Install (helper)

4.4 Complete Call Chain

This sequence diagram is Claude-Mem's most important reference. It traces the entire data flow from session open to session close:

sequenceDiagram
    participant User as 👤 User
    participant CC as 💻 Claude Code
    participant Hook as 🪝 Hook Script
    participant Worker as ⚙️ Worker (37777)
    participant SDK as 🤖 Claude Agent SDK
    participant DB as 💾 SQLite + ChromaDB

    Note over User,DB: ── Session Start ──

    User->>CC: Open Claude Code
    CC->>Hook: Trigger SessionStart
    Hook->>Worker: GET /api/context
    Worker->>DB: Query last 10 sessions
    DB-->>Worker: Return Observations + Summaries
    Worker-->>Hook: Return context data
    Hook-->>CC: Inject history into Claude

    Note over User,DB: ── User Starts Working ──

    User->>CC: "Fix the comment bug"
    CC->>Hook: Trigger UserPromptSubmit
    Hook->>Worker: POST /api/prompt
    Worker->>DB: Store in user_prompts

    Note over User,DB: ── Claude Operates ──

    CC->>CC: Read src/api/comments.ts
    CC->>Hook: Trigger PostToolUse (tool=Read)
    Hook->>Worker: POST /api/observation (raw file content)
    Worker->>SDK: Compress & distill
    SDK-->>Worker: {title, narrative, facts, type}
    Worker->>DB: INSERT observation + update vector index

    CC->>CC: Modify src/api/comments.ts
    CC->>Hook: Trigger PostToolUse (tool=Write)
    Hook->>Worker: POST /api/observation (changes)
    Worker->>SDK: Compress & distill
    SDK-->>Worker: {title:"Fix comment FK", type:"bugfix"}
    Worker->>DB: INSERT observation + update vector index

    CC->>CC: Run npm test
    CC->>Hook: Trigger PostToolUse (tool=Bash)
    Hook->>Worker: POST /api/observation (test output)
    Worker->>SDK: Compress & distill
    Worker->>DB: INSERT observation

    Note over User,DB: ── Session End ──

    User->>CC: Close Claude Code
    CC->>Hook: Trigger SessionEnd
    Hook->>Worker: POST /api/session/end
    Worker->>Worker: Review all session Observations
    Worker->>SDK: Generate Session Summary
    SDK-->>Worker: {request, investigated, completed, next_steps}
    Worker->>DB: INSERT session_summary

4.5 Why Async Compression?

Won't AI compression after every tool call be slow?

No, because it's asynchronous.

graph LR
    A["Claude acts"] --> B["Hook sends HTTP"]
    B --> C["Worker receives"]
    C --> D["Returns 200 OK immediately"]
    D --> E["Claude continues working
(doesn't wait)"] C --> F["Background async compression
(Agent SDK)"] F --> G["Done → store in DB"] style D fill:#10b981,color:#fff style E fill:#6366f1,color:#fff style F fill:#f59e0b,color:#000

The Hook fires and returns immediately — never blocks Claude's workflow. The Worker compresses and stores in the background.


Hands-On Exercise

  1. Start a new Claude Code session on the blog project
  2. Have Claude: read a file, modify a file, run a command
  3. In another terminal, watch Worker logs in real time:
tail -f ~/.claude-mem/logs/worker.log
  1. Observe processing records appearing after each Claude action
  2. After ending the session, check session_summaries for the generated summary

Coming Up Next

Hooks capture data, but the Worker handles compression, storage, and search. Next episode, we go inside the Worker — running on localhost:37777, powered by Bun, serving 10 API endpoints.

➡️ Episode 5: Worker Service — Claude-Mem's Heart