docs: update hooks.mdx with improved architecture diagrams and data flow representation
This commit is contained in:
@@ -9,30 +9,27 @@ Claude-Mem implements a **5-stage hook system** that captures development work a
|
|||||||
|
|
||||||
## Architecture Overview
|
## Architecture Overview
|
||||||
|
|
||||||
```
|
```mermaid
|
||||||
┌─────────────────────────────────────────────────────────────────────┐
|
flowchart TB
|
||||||
│ Claude Code IDE │
|
subgraph IDE["Claude Code IDE"]
|
||||||
├─────────────────────────────────────────────────────────────────────┤
|
SS[SessionStart] --> UPS[UserPromptSubmit] --> PTU[PostToolUse] --> ST[Stop] --> SE[SessionEnd]
|
||||||
│ SessionStart → UserPromptSubmit → PostToolUse → Stop → SessionEnd │
|
SS --> ctx["context"]
|
||||||
│ ↓ ↓ ↓ ↓ ↓ │
|
UPS --> new["new"]
|
||||||
│ [context] [new] [save] [summary] [cleanup] │
|
PTU --> save["save"]
|
||||||
│ ↓ ↓ ↓ ↓ ↓ │
|
ST --> sum["summary"]
|
||||||
│ └──────────────┴────────┬────────┴──────────┴─────────┘ │
|
SE --> clean["cleanup"]
|
||||||
│ ↓ │
|
end
|
||||||
│ HTTP (fire-and-forget) │
|
|
||||||
│ ↓ │
|
ctx & new & save & sum & clean --> HTTP["HTTP (fire-and-forget)"]
|
||||||
├─────────────────────────────────────────────────────────────────────┤
|
|
||||||
│ Worker Service (PM2) │
|
subgraph Worker["Worker Service (PM2)"]
|
||||||
│ ┌─────────────┐ ┌──────────────┐ ┌────────────────┐ │
|
SM[SessionMgr] ~~~ SA[SDK Agent] ~~~ DM[DatabaseMgr]
|
||||||
│ │ SessionMgr │ │ SDK Agent │ │ DatabaseMgr │ │
|
SA --> SDK["Claude Agent SDK"]
|
||||||
│ └─────────────┘ └──────────────┘ └────────────────┘ │
|
end
|
||||||
│ ↓ │
|
|
||||||
│ Claude Agent SDK │
|
HTTP --> Worker
|
||||||
│ ↓ │
|
SDK --> SQLite[(SQLite DB)]
|
||||||
│ ┌────────────────┴────────────────┐ │
|
SDK --> Chroma[(Chroma Vector DB)]
|
||||||
│ ↓ ↓ │
|
|
||||||
│ SQLite DB Chroma Vector DB │
|
|
||||||
└─────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## The 5 Lifecycle Stages
|
## The 5 Lifecycle Stages
|
||||||
@@ -373,58 +370,59 @@ Timeout: 2000ms
|
|||||||
|
|
||||||
## Data Flow Diagram
|
## Data Flow Diagram
|
||||||
|
|
||||||
```
|
```mermaid
|
||||||
1. USER SUBMITS PROMPT
|
flowchart TD
|
||||||
↓
|
subgraph step1["1. USER SUBMITS PROMPT"]
|
||||||
Claude Code → SessionStart hook
|
CC1[Claude Code] --> SS1[SessionStart hook]
|
||||||
├─ context-hook.js
|
SS1 --> CH[context-hook.js]
|
||||||
│ └─ GET /api/context/inject → returns context markdown
|
SS1 --> UMH[user-message-hook.js]
|
||||||
└─ user-message-hook.js
|
CH --> |"GET /api/context/inject"| CTX[returns context markdown]
|
||||||
└─ displays context info to user
|
UMH --> DISP[displays context info to user]
|
||||||
↓
|
|
||||||
Claude Code → UserPromptSubmit hook
|
CC1 --> UPS1[UserPromptSubmit hook]
|
||||||
├─ new-hook.js
|
UPS1 --> NH[new-hook.js]
|
||||||
│ ├─ db.createSDKSession(session_id, project, prompt)
|
NH --> |1| CREATE["db.createSDKSession()"]
|
||||||
│ ├─ db.incrementPromptCounter(sessionDbId)
|
NH --> |2| INC["db.incrementPromptCounter()"]
|
||||||
│ ├─ stripMemoryTagsFromPrompt(prompt)
|
NH --> |3| STRIP["stripMemoryTagsFromPrompt()"]
|
||||||
│ ├─ db.saveUserPrompt(session_id, promptNumber, cleaned)
|
NH --> |4| SAVE["db.saveUserPrompt()"]
|
||||||
│ └─ POST /sessions/{sessionDbId}/init → Worker
|
NH --> |5| INIT["POST /sessions/{id}/init"]
|
||||||
│ ↓
|
INIT --> W1[Worker]
|
||||||
│ Worker → SessionManager → SDK Agent
|
W1 --> SM1[SessionManager]
|
||||||
│ ↓
|
SM1 --> SA1[SDK Agent]
|
||||||
│ Claude SDK processes init prompt
|
end
|
||||||
│
|
|
||||||
2. CLAUDE USES A TOOL
|
subgraph step2["2. CLAUDE USES A TOOL"]
|
||||||
↓
|
CC2[Claude Code] --> PTU1[PostToolUse hook]
|
||||||
Claude Code → PostToolUse hook
|
PTU1 --> SH[save-hook.js]
|
||||||
├─ save-hook.js
|
SH --> |"Skip if in SKIP_TOOLS"| CHECK{Check tool}
|
||||||
│ ├─ Skip if tool in SKIP_TOOLS
|
CHECK --> |allowed| OBS["POST /api/sessions/observations"]
|
||||||
│ └─ POST /api/sessions/observations → Worker
|
OBS --> W2[Worker]
|
||||||
│ ↓
|
W2 --> SA2["SDK Agent → Claude compresses"]
|
||||||
│ Worker → SDK Agent → Claude compresses observation
|
SA2 --> STORE1["Store in SQLite + Chroma"]
|
||||||
│ ↓
|
STORE1 --> SSE[Broadcast to SSE clients]
|
||||||
│ Store in SQLite + Sync to Chroma
|
end
|
||||||
│ ↓
|
|
||||||
│ Broadcast to SSE clients (viewer UI)
|
subgraph step3["3. USER STOPS ASKING QUESTIONS"]
|
||||||
│
|
CC3[Claude Code] --> STOP1[Stop hook]
|
||||||
3. USER STOPS ASKING QUESTIONS
|
STOP1 --> SUMH[summary-hook.js]
|
||||||
↓
|
SUMH --> EXT[Extract last messages from transcript]
|
||||||
Claude Code → Stop hook
|
EXT --> SUM["POST /api/sessions/summarize"]
|
||||||
├─ summary-hook.js
|
SUM --> W3[Worker]
|
||||||
│ ├─ Extract last messages from transcript
|
W3 --> SA3["SDK Agent → Claude generates summary"]
|
||||||
│ └─ POST /api/sessions/summarize → Worker
|
SA3 --> STORE2["Store in SQLite + Chroma"]
|
||||||
│ ↓
|
end
|
||||||
│ Worker → SDK Agent → Claude generates summary
|
|
||||||
│ ↓
|
subgraph step4["4. SESSION CLOSES"]
|
||||||
│ Store in SQLite + Sync to Chroma
|
CC4[Claude Code] --> SE1[SessionEnd hook]
|
||||||
│
|
SE1 --> CLN[cleanup-hook.js]
|
||||||
4. SESSION CLOSES
|
CLN --> COMP["POST /api/sessions/complete"]
|
||||||
↓
|
COMP --> W4[Worker]
|
||||||
Claude Code → SessionEnd hook
|
W4 --> MARK["Mark session as 'completed'"]
|
||||||
└─ cleanup-hook.js
|
end
|
||||||
└─ POST /api/sessions/complete → Worker
|
|
||||||
↓
|
step1 --> step2
|
||||||
Mark session as 'completed' in database
|
step2 --> step3
|
||||||
|
step3 --> step4
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -433,23 +431,42 @@ Timeout: 2000ms
|
|||||||
|
|
||||||
The same `session_id` flows through ALL hooks in a conversation:
|
The same `session_id` flows through ALL hooks in a conversation:
|
||||||
|
|
||||||
```
|
```mermaid
|
||||||
SessionStart: session_id (from Claude Code)
|
flowchart TD
|
||||||
↓
|
SID["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
|
|
||||||
|
|
||||||
PostToolUse: session_id (same)
|
subgraph SS["SessionStart"]
|
||||||
├─ createSDKSession(session_id, '', '') returns sessionDbId
|
SS_ID["session_id"]
|
||||||
└─ All observations tagged with this sessionDbId
|
end
|
||||||
|
|
||||||
Stop: session_id (same)
|
subgraph UPS["UserPromptSubmit"]
|
||||||
└─ Summary tagged with same sessionDbId
|
UPS_ID["session_id (same)"]
|
||||||
|
UPS_CREATE["new-hook creates:<br/>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)
|
subgraph PTU["PostToolUse"]
|
||||||
└─ Mark sessionDbId as completed
|
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
|
||||||
```
|
```
|
||||||
|
|
||||||
<Warning>
|
<Warning>
|
||||||
|
|||||||
Reference in New Issue
Block a user