From 8da92c656950bfe7f2686f3f32c73ab50c37f6f7 Mon Sep 17 00:00:00 2001 From: Alex Newman Date: Mon, 8 Dec 2025 21:54:48 -0500 Subject: [PATCH] docs: update hooks.mdx with improved architecture diagrams and data flow representation --- docs/public/architecture/hooks.mdx | 197 ++++++++++++++++------------- 1 file changed, 107 insertions(+), 90 deletions(-) diff --git a/docs/public/architecture/hooks.mdx b/docs/public/architecture/hooks.mdx index b64056b1..b8f389ab 100644 --- a/docs/public/architecture/hooks.mdx +++ b/docs/public/architecture/hooks.mdx @@ -9,30 +9,27 @@ Claude-Mem implements a **5-stage hook system** that captures development work a ## Architecture Overview -``` -┌─────────────────────────────────────────────────────────────────────┐ -│ Claude Code IDE │ -├─────────────────────────────────────────────────────────────────────┤ -│ SessionStart → UserPromptSubmit → PostToolUse → Stop → SessionEnd │ -│ ↓ ↓ ↓ ↓ ↓ │ -│ [context] [new] [save] [summary] [cleanup] │ -│ ↓ ↓ ↓ ↓ ↓ │ -│ └──────────────┴────────┬────────┴──────────┴─────────┘ │ -│ ↓ │ -│ HTTP (fire-and-forget) │ -│ ↓ │ -├─────────────────────────────────────────────────────────────────────┤ -│ Worker Service (PM2) │ -│ ┌─────────────┐ ┌──────────────┐ ┌────────────────┐ │ -│ │ SessionMgr │ │ SDK Agent │ │ DatabaseMgr │ │ -│ └─────────────┘ └──────────────┘ └────────────────┘ │ -│ ↓ │ -│ Claude Agent SDK │ -│ ↓ │ -│ ┌────────────────┴────────────────┐ │ -│ ↓ ↓ │ -│ SQLite DB Chroma Vector DB │ -└─────────────────────────────────────────────────────────────────────┘ +```mermaid +flowchart TB + subgraph IDE["Claude Code IDE"] + SS[SessionStart] --> UPS[UserPromptSubmit] --> PTU[PostToolUse] --> ST[Stop] --> SE[SessionEnd] + SS --> ctx["context"] + UPS --> new["new"] + PTU --> save["save"] + ST --> sum["summary"] + SE --> clean["cleanup"] + end + + ctx & new & save & sum & clean --> HTTP["HTTP (fire-and-forget)"] + + subgraph Worker["Worker Service (PM2)"] + SM[SessionMgr] ~~~ SA[SDK Agent] ~~~ DM[DatabaseMgr] + SA --> SDK["Claude Agent SDK"] + end + + HTTP --> Worker + SDK --> SQLite[(SQLite DB)] + SDK --> Chroma[(Chroma Vector DB)] ``` ## The 5 Lifecycle Stages @@ -373,58 +370,59 @@ Timeout: 2000ms ## Data Flow Diagram -``` -1. USER SUBMITS PROMPT - ↓ - Claude Code → SessionStart hook - ├─ context-hook.js - │ └─ GET /api/context/inject → returns context markdown - └─ user-message-hook.js - └─ displays context info to user - ↓ - Claude Code → UserPromptSubmit hook - ├─ new-hook.js - │ ├─ db.createSDKSession(session_id, project, prompt) - │ ├─ db.incrementPromptCounter(sessionDbId) - │ ├─ stripMemoryTagsFromPrompt(prompt) - │ ├─ db.saveUserPrompt(session_id, promptNumber, cleaned) - │ └─ POST /sessions/{sessionDbId}/init → Worker - │ ↓ - │ Worker → SessionManager → SDK Agent - │ ↓ - │ Claude SDK processes init prompt - │ -2. CLAUDE USES A TOOL - ↓ - Claude Code → PostToolUse hook - ├─ save-hook.js - │ ├─ Skip if tool in SKIP_TOOLS - │ └─ POST /api/sessions/observations → Worker - │ ↓ - │ Worker → SDK Agent → Claude compresses observation - │ ↓ - │ Store in SQLite + Sync to Chroma - │ ↓ - │ Broadcast to SSE clients (viewer UI) - │ -3. USER STOPS ASKING QUESTIONS - ↓ - Claude Code → Stop hook - ├─ summary-hook.js - │ ├─ Extract last messages from transcript - │ └─ POST /api/sessions/summarize → Worker - │ ↓ - │ Worker → SDK Agent → Claude generates summary - │ ↓ - │ Store in SQLite + Sync to Chroma - │ -4. SESSION CLOSES - ↓ - Claude Code → SessionEnd hook - └─ cleanup-hook.js - └─ POST /api/sessions/complete → Worker - ↓ - Mark session as 'completed' in database +```mermaid +flowchart TD + subgraph step1["1. USER SUBMITS PROMPT"] + CC1[Claude Code] --> SS1[SessionStart hook] + SS1 --> CH[context-hook.js] + SS1 --> UMH[user-message-hook.js] + CH --> |"GET /api/context/inject"| CTX[returns context markdown] + UMH --> DISP[displays context info to user] + + CC1 --> UPS1[UserPromptSubmit hook] + UPS1 --> NH[new-hook.js] + NH --> |1| CREATE["db.createSDKSession()"] + NH --> |2| INC["db.incrementPromptCounter()"] + NH --> |3| STRIP["stripMemoryTagsFromPrompt()"] + NH --> |4| SAVE["db.saveUserPrompt()"] + NH --> |5| INIT["POST /sessions/{id}/init"] + INIT --> W1[Worker] + W1 --> SM1[SessionManager] + SM1 --> SA1[SDK Agent] + end + + subgraph step2["2. CLAUDE USES A TOOL"] + CC2[Claude Code] --> PTU1[PostToolUse hook] + PTU1 --> SH[save-hook.js] + SH --> |"Skip if in SKIP_TOOLS"| CHECK{Check tool} + CHECK --> |allowed| OBS["POST /api/sessions/observations"] + OBS --> W2[Worker] + W2 --> SA2["SDK Agent → Claude compresses"] + SA2 --> STORE1["Store in SQLite + Chroma"] + STORE1 --> SSE[Broadcast to SSE clients] + end + + subgraph step3["3. USER STOPS ASKING QUESTIONS"] + CC3[Claude Code] --> STOP1[Stop hook] + STOP1 --> SUMH[summary-hook.js] + SUMH --> EXT[Extract last messages from transcript] + EXT --> SUM["POST /api/sessions/summarize"] + SUM --> W3[Worker] + W3 --> SA3["SDK Agent → Claude generates summary"] + SA3 --> STORE2["Store in SQLite + Chroma"] + end + + subgraph step4["4. SESSION CLOSES"] + CC4[Claude Code] --> SE1[SessionEnd hook] + SE1 --> CLN[cleanup-hook.js] + CLN --> COMP["POST /api/sessions/complete"] + COMP --> W4[Worker] + W4 --> MARK["Mark session as 'completed'"] + end + + step1 --> step2 + step2 --> step3 + step3 --> step4 ``` --- @@ -433,23 +431,42 @@ Timeout: 2000ms The same `session_id` flows through ALL hooks in a conversation: -``` -SessionStart: session_id (from Claude Code) - ↓ -UserPromptSubmit: session_id (same) - ├─ new-hook creates: sdk_sessions.claude_session_id = session_id - ├─ returns: sessionDbId (primary key) - └─ All subsequent operations use sessionDbId +```mermaid +flowchart TD + SID["session_id (from Claude Code)"] -PostToolUse: session_id (same) - ├─ createSDKSession(session_id, '', '') returns sessionDbId - └─ All observations tagged with this sessionDbId + subgraph SS["SessionStart"] + SS_ID["session_id"] + end -Stop: session_id (same) - └─ Summary tagged with same sessionDbId + subgraph UPS["UserPromptSubmit"] + UPS_ID["session_id (same)"] + UPS_CREATE["new-hook creates:
sdk_sessions.claude_session_id = session_id"] + UPS_RET["returns: sessionDbId (primary key)"] + UPS_ALL["All subsequent operations use sessionDbId"] + UPS_ID --> UPS_CREATE --> UPS_RET --> UPS_ALL + end -SessionEnd: session_id (same) - └─ Mark sessionDbId as completed + subgraph PTU["PostToolUse"] + PTU_ID["session_id (same)"] + PTU_GET["createSDKSession() returns sessionDbId"] + PTU_OBS["All observations tagged with sessionDbId"] + PTU_ID --> PTU_GET --> PTU_OBS + end + + subgraph STOP["Stop"] + STOP_ID["session_id (same)"] + STOP_SUM["Summary tagged with sessionDbId"] + STOP_ID --> STOP_SUM + end + + subgraph SEND["SessionEnd"] + SEND_ID["session_id (same)"] + SEND_MARK["Mark sessionDbId as completed"] + SEND_ID --> SEND_MARK + end + + SID --> SS --> UPS --> PTU --> STOP --> SEND ```