Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

claude-mem — Administrator & Developer Guide

Generated May 2026 from thedotmack/claude-mem at c2d033c

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

1. Architecture Overview

claude-mem is a persistent memory compression framework for AI coding assistants. It intercepts IDE lifecycle events (session start, tool usage, file reads, session end), processes them through an AI observation extraction agent, stores structured observations in a local SQLite database, and re-injects compressed context into future sessions. The system operates as a local daemon with no cloud dependencies beyond the AI provider API.

The architecture follows a hook-driven event pipeline: IDE hooks capture events → Express HTTP worker processes them → SDK agent extracts observations → SQLite stores them → context builder compresses and injects them back. All state is local to the user's machine.

Architecture Diagram

┌─────────────────────────────────────────────────────────────────────┐
│  IDE (Claude Code / Cursor / Gemini CLI / 10+ others)              │
│                                                                     │
│  Hooks:                                                             │
│    SessionStart ──→ context-hook ──→ inject timeline context        │
│    UserPromptSubmit ──→ session-init ──→ create/resume session      │
│    PostToolUse(*) ──→ observation ──→ queue for SDK extraction      │
│    PreToolUse:Read ──→ file-context ──→ inject file observations    │
│    Stop ──→ summarize ──→ generate session summary                  │
│    SessionEnd ──→ session-complete ──→ cleanup                      │
└───────────────────────────┬─────────────────────────────────────────┘
                            │ HTTP (port 37777)
                            ▼
┌─────────────────────────────────────────────────────────────────────┐
│  Worker Daemon (Express + Bun runtime)                              │
│                                                                     │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐              │
│  │ SessionMgr   │  │ SearchMgr    │  │ ContextBuilder│             │
│  │ (sessions,   │  │ (SQLite FTS, │  │ (timeline,    │             │
│  │  queue)      │  │  Chroma,     │  │  token econ)  │             │
│  └──────┬───────┘  │  hybrid)     │  └───────────────┘             │
│         │          └──────────────┘                                  │
│         ▼                                                            │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐              │
│  │ SDKAgent     │  │ GeminiAgent  │  │ OpenRouter   │              │
│  │ (Claude SDK) │  │ (REST API)   │  │  Agent       │              │
│  └──────┬───────┘  └──────────────┘  └──────────────┘              │
│         │                                                            │
│  ┌──────▼───────┐  ┌──────────────┐  ┌──────────────┐              │
│  │ Supervisor   │  │ PendingMsg   │  │ SSE          │              │
│  │ (ProcessReg, │  │  Store       │  │  Broadcaster  │             │
│  │  health chk) │  │ (queue)      │  │ (live UI)    │              │
│  └──────────────┘  └──────────────┘  └──────────────┘              │
│                                                                     │
│  ┌──────────────────────────────────────────────────────────┐       │
│  │ SQLite (WAL mode)     │  Chroma (optional)               │      │
│  │ observations, sessions│  Vector embeddings for            │      │
│  │ summaries, prompts,   │  semantic search                  │      │
│  │ pending_messages,     │                                   │      │
│  │ schema_versions       │                                   │      │
│  └───────────────────────┴───────────────────────────────────┘      │
└─────────────────────────────────────────────────────────────────────┘
                            │
                            ▼
┌─────────────────────────────────────────────────────────────────────┐
│  MCP Server (stdio transport)                                       │
│  12+ tools: search, timeline, get_observations, smart_search,       │
│  smart_unfold, smart_outline, build_corpus, list_corpora,           │
│  prime_corpus, query_corpus, rebuild_corpus, reprime_corpus,        │
│  __IMPORTANT                                                        │
│  Parent heartbeat for orphan detection                              │
└─────────────────────────────────────────────────────────────────────┘

Component Inventory

Component Path Role
NPX CLI src/npx-cli/ Install, update, uninstall, runtime commands
CLI Handlers src/cli/handlers/ 8 hook event handlers
CLI Adapters src/cli/adapters/ IDE-specific input normalization (Claude Code, Cursor, Gemini CLI, Raw, Windsurf)
Worker Service src/services/worker-service.ts Worker lifecycle management (start/stop/restart)
Worker HTTP Routes src/services/worker/http/routes/ 11 route classes: Chroma, Corpus, Data, Logs, Memory, Search, Session, Settings, Viewer
Worker Core src/services/worker/ SDKAgent, GeminiAgent, OpenRouterAgent, SessionManager, SearchManager, DatabaseManager, BranchManager, SSEBroadcaster, RestartGuard, FormattingService, TimelineService, PaginationHelper
SQLite Layer src/services/sqlite/ Database, SessionStore, SessionSearch, PendingMessageStore, migrations
Context Engine src/services/context/ ContextBuilder, ContextConfigLoader, ObservationCompiler, TokenCalculator
Supervisor src/supervisor/ ProcessRegistry, HealthChecker, env-sanitizer, shutdown cascade
SDK Prompts src/sdk/ XML prompt builders, response parser
MCP Server src/servers/mcp-server.ts Model Context Protocol server with 12+ tools
Shared Utilities src/shared/ EnvManager, SettingsDefaultsManager, paths, worker-utils, hook-constants, timeline-formatting, transcript-parser
Plugin Hooks plugin/hooks/ hooks.json defining IDE lifecycle event bindings
Plugin Modes plugin/modes/ 35 JSON mode files (code + 30 localized + chill)
Plugin Skills plugin/skills/ Pathfinder, timeline-report, version-bump, smart-explore, knowledge-agent, mem-search, make-plan, do
Plugin UI plugin/ui/ Bundled viewer (React SPA)
IDE Integrations src/services/integrations/ CodexCliInstaller, CursorHooksInstaller, GeminiCliHooksInstaller, McpIntegrations, OpenCodeInstaller, TelegramNotifier, WindsurfHooksInstaller
Infrastructure src/services/infrastructure/ WorktreeAdoption
Transcripts src/services/transcripts/ TranscriptWatcher, TranscriptEventProcessor, config
Server src/services/server/ Express Server base, ErrorHandler
Sync src/services/sync/ ChromaSync
Domain src/services/domain/ ModeManager
OpenClaw openclaw/ Standalone extension package (@openclaw/claude-mem)
Docker docker/claude-mem/ build.sh, entrypoint.sh, run.sh
Evals evals/swebench/ SWE-bench evaluation harness

Technology Stack

Layer Technology
Runtime Bun ≥ 1.0.0 (required for bun:sqlite)
Language TypeScript (compiled to ESM)
HTTP Server Express 5
Database SQLite (via bun:sqlite) with WAL mode
Vector DB Chroma (optional, via subprocess)
AI SDK @anthropic-ai/claude-agent-sdk ^0.2.119
MCP @modelcontextprotocol/sdk ^1.29.0
UI React 19 + DOMPurify
Templating Handlebars (for context templates)
Schema Validation Zod 4
Code Parsing tree-sitter (20+ language grammars)
Build esbuild, custom build scripts
Package Management npm + Bun
License AGPL-3.0

Data Flow: Observation Extraction

1. User invokes tool in IDE (e.g., Edit file)
2. PostToolUse hook fires → observation handler
3. Handler sends tool_name + tool_input + tool_response + cwd to worker
4. Worker's SessionManager enqueues a PendingMessage (status=pending)
5. Worker claims message (status=processing, stamps worker_pid)
6. SDKAgent (or Gemini/OpenRouter agent) receives observation prompt
7. Agent returns XML: <observation> with title, subtitle, narrative, facts, type, concepts, files
8. Parser validates XML → discriminated union: observation[] | summary | invalid
9. Observations stored in SQLite + synced to Chroma (if enabled)
10. PendingMessage confirmed (deleted from queue)
11. SSEBroadcaster notifies connected viewer clients

Data Flow: Context Injection

1. SessionStart hook fires → context-hook handler
2. ContextBuilder queries SQLite for recent observations + summaries
3. ObservationCompiler applies type/concept filtering per mode config
4. TokenCalculator computes read vs. discovery token economics
5. Compressed timeline returned as hookSpecificOutput → additionalContext
6. IDE injects timeline into the AI's system context
7. AI now knows what happened in previous sessions

2. System Requirements

Hardware

Resource Minimum Recommended
CPU 1 core 2+ cores
RAM 256 MB (worker) 512 MB+ (worker + Chroma)
Disk 100 MB (install) + growing DB 500 MB+
Network Local only (provider API calls) Low-latency to AI provider

Software

Dependency Version Required Notes
Node.js ≥ 20.0.0 Yes For npx CLI
Bun ≥ 1.0.0 Yes Worker runtime (bun:sqlite)
Git Any Recommended For worktree adoption, CLAUDE.md generation
Git Bash Any Windows only Required for hook shell execution
Docker Any Optional For containerized deployment

Supported Platforms

Platform Status Notes
macOS (Apple Silicon) Full support Primary development platform
macOS (Intel) Full support
Linux (x86_64) Full support
Windows 11 Partial support Known issues: #2109, #2111, #2114, #2123, #2131
Windows 10 Partial support Same Windows caveats apply
Docker (Linux) Supported See Docker deployment section

Note

Windows support has several known issues around path handling (spaces in usernames), shell detection (Git Bash requirement), and port management (stale sockets). macOS and Linux provide the most reliable experience.


3. Configuration Reference

Configuration Precedence

Settings are resolved in this order (first match wins):

  1. Environment variables (e.g., CLAUDE_MEM_WORKER_PORT=37778)
  2. Settings file (~/.claude-mem/settings.json)
  3. Built-in defaults (in SettingsDefaultsManager)

File Locations

File Path Format Purpose
Settings ~/.claude-mem/settings.json JSON Primary configuration
Credentials ~/.claude-mem/.env Key=Value AI provider API keys
Database ~/.claude-mem/claude-mem.db SQLite Observation storage
Logs ~/.claude-mem/logs/worker-{date}.log Text Daily rotating logs
Vector DB ~/.claude-mem/vector-db/ Chroma Semantic search index
Observer Sessions ~/.claude-mem/observer-sessions/ Directory SDK subprocess session data
Transcript Watch ~/.claude-mem/transcript-watch.json JSON Transcript watcher config
Cursor Registry ~/.claude-mem/cursor-projects.json JSON Cursor project tracking
Plugin Cache ~/.claude/plugins/marketplaces/thedotmack/ Directory Installed plugin files

All Settings

Setting Type Default Description
CLAUDE_MEM_WORKER_PORT string "37777" Worker HTTP port
CLAUDE_MEM_MODE string "code" Observation mode
CLAUDE_MEM_LOG_LEVEL string "info" Log level: debug, info, warn, error
CLAUDE_MEM_MODEL string (provider default) AI model for observation extraction
CLAUDE_MEM_PROVIDER string "claude" AI provider: claude, gemini, openrouter
CLAUDE_MEM_CHROMA_ENABLED string "true" Enable Chroma vector DB
CLAUDE_MEM_CHROMA_* string (various) Chroma-specific configuration
CLAUDE_MEM_DATA_DIR string ~/.claude-mem Data directory override
CLAUDE_MEM_HEALTH_TIMEOUT_MS string "3000" Health check timeout in ms
CLAUDE_MEM_MANAGED string — Set by worker to indicate managed mode
CLAUDE_MEM_TELEGRAM_BOT_TOKEN string — Telegram notification bot token
CLAUDE_MEM_TELEGRAM_CHAT_ID string — Telegram target chat ID
CLAUDE_MEM_GEMINI_API_KEY string — Gemini API key
CLAUDE_MEM_OPENROUTER_API_KEY string — OpenRouter API key
CLAUDE_MEM_OPENROUTER_API_KEY (alt) env — Alias: OPENROUTER_API_KEY

Important

The CLAUDE_MEM_DATA_DIR setting changes the root for all data files (database, logs, vector DB, observer sessions). Set this before first run if you need a non-default location — migrating later requires moving the database file manually.

Hook Timeouts

Defined in src/shared/hook-constants.ts:

Constant Value Used By
DEFAULT_TIMEOUT 300s (5 min) General hook timeout
HEALTH_CHECK_TIMEOUT 3s Worker health check
Hook exit code 0 SUCCESS Continue processing
Hook exit code 1 FAILURE Non-blocking failure
Hook exit code 2 BLOCKING_ERROR Blocks the IDE operation

Hooks Configuration

The plugin's hooks.json defines the complete hook lifecycle:

{
  "hooks": {
    "Setup": ["smart-install"],
    "SessionStart": {
      "triggers": ["startup", "clear", "compact"],
      "commands": ["smart-install", "worker start", "context hook"]
    },
    "UserPromptSubmit": ["session-init hook"],
    "PostToolUse": {
      "triggers": ["*"],
      "commands": ["observation hook"]
    },
    "PreToolUse": {
      "triggers": ["Read"],
      "commands": ["file-context hook"]
    },
    "Stop": ["summarize hook"],
    "SessionEnd": ["session-complete hook"]
  }
}

SQLite Configuration

Applied on database initialization (in ClaudeMemDatabase and DatabaseManager):

Pragma Value Purpose
journal_mode WAL Write-Ahead Logging for concurrent reads
synchronous NORMAL Balance safety vs. performance
foreign_keys ON Enforce referential integrity
temp_store memory In-memory temp tables
mmap_size 256 MB Memory-mapped I/O
cache_size 10,000 pages Page cache

4. Deployment & Scaling

Local Deployment (Standard)

The standard deployment is a single-user local installation:

npx claude-mem install   # Interactive IDE setup
npx claude-mem start     # Start worker daemon

All data lives in ~/.claude-mem/. The worker binds to localhost:37777. No external network access required except AI provider API calls.

Docker Deployment

Build:

cd docker/claude-mem
./build.sh    # Runs npm build + docker build

Run (macOS with Keychain):

./run.sh

The run.sh script:

  1. Extracts OAuth credentials from the macOS Keychain
  2. Mounts ~/.claude-mem as a persistent volume
  3. Runs the container interactively

Run (Linux / manual credentials):

docker run -it \
  -v ~/.claude-mem:/home/user/.claude-mem \
  -v ~/.claude/.credentials.json:/tmp/claude-creds.json:ro \
  -e CLAUDE_CREDENTIALS_FILE=/tmp/claude-creds.json \
  claude-mem/claude-mem:latest

Or use an API key directly:

docker run -it \
  -v ~/.claude-mem:/home/user/.claude-mem \
  -e ANTHROPIC_API_KEY=sk-ant-... \
  claude-mem/claude-mem:latest

The entrypoint.sh seeds credentials from the mounted file or environment variable into the container's credential store.

Warning

The Docker image expects the ~/.claude-mem volume for persistent storage. Without it, all observations are lost when the container stops.

Multi-Account Isolation

Running multiple accounts (work + personal) on the same machine requires separate data directories (#2101):

# Account 1
CLAUDE_MEM_DATA_DIR=~/.claude-mem-work CLAUDE_MEM_WORKER_PORT=37777 npx claude-mem start

# Account 2
CLAUDE_MEM_DATA_DIR=~/.claude-mem-personal CLAUDE_MEM_WORKER_PORT=37778 npx claude-mem start

Each instance gets its own database, logs, and observer sessions. Configure IDE hooks to point to the correct port.

Scaling Considerations

claude-mem is designed for single-user, single-machine operation. Scaling limits:

Resource Limit Impact
SDK subprocesses Hard cap: 10 ProcessRegistry rejects spawns beyond this
Concurrent sessions Soft limit via subprocess cap Each session needs an SDK process
Database size Unlimited (SQLite) Performance degrades at ~100K+ observations without index tuning
Chroma index Depends on available RAM Large indices may slow semantic search
PendingMessage queue No hard limit Self-healing reclaim keeps queue bounded

5. Operations

Worker Lifecycle

The worker daemon is the central component. All operations flow through it.

Start/Stop/Restart:

npx claude-mem start     # Start in background
npx claude-mem stop      # Graceful shutdown (SIGTERM → 5s → SIGKILL)
npx claude-mem restart   # Stop then start
npx claude-mem status    # Check if running

Auto-start: The SessionStart hook calls ensureWorkerRunning() which lazy-spawns the worker if it's not already running. The mechanism uses a health check (/health endpoint) with a configurable timeout.

Fail-loud counter: If the worker is unreachable, executeWithWorkerFallback increments a fail counter. After a threshold, hooks stop attempting to contact the worker and fail immediately (reducing hook latency when the worker is down).

Tip

Monitor worker health by polling GET /health or GET /api/readiness. The readiness endpoint includes database connectivity status.

Process Management

Supervisor: The Supervisor singleton validates the worker PID file and manages SDK subprocess lifecycle. It uses start-token verification to detect PID reuse (stale PID files pointing to a different process).

ProcessRegistry: Manages all SDK subprocesses with:

  • PID tracking and POSIX process groups (pgid)
  • Session reaping for cleanup
  • SDK spawn factory with pre-spawn cleanup
  • Pool slot waiting (backpressure when at capacity)
  • Hard cap of 10 processes
  • Health checker: 30-second interval pruning dead processes

Shutdown cascade:

  1. SIGTERM sent to all registered processes
  2. Wait 5 seconds for graceful termination
  3. SIGKILL for any remaining processes
  4. On Windows: uses tree-kill (optional dependency) for process tree termination

Note

On Linux, the Supervisor uses POSIX process groups (pgid) for reliable child cleanup. On Windows, it falls back to tree-kill which traverses the process tree via the Win32 API.

Log Management

Logs are written to ~/.claude-mem/logs/worker-{YYYY-MM-DD}.log with daily rotation.

# View recent logs
npm run worker:logs      # Last 50 lines

# Tail in real-time
npm run worker:tail

# Via API
curl http://localhost:37777/api/logs

# Clear logs
curl -X POST http://localhost:37777/api/logs/clear

The Logger class (src/utils/logger.ts) supports levels: debug, info, warn, error. Set via CLAUDE_MEM_LOG_LEVEL.

Queue Management

The PendingMessageStore is the persistent work queue:

# Check queue status
npm run queue

# Process pending messages
npm run queue:process

# Clear all failed messages
npm run queue:clear

Self-healing: The claimNextMessage() query automatically reclaims messages from crashed workers by checking worker_pid against the live-pids set. No timer-based reaper — liveness is the truth.

Failed message cleanup: On worker startup, clearFailedOlderThan() deletes stale failed messages to keep the queue bounded and claim queries fast.

Tip

If you see the queue growing with failed messages, check the worker logs for SDK agent errors (model rate limits, credential issues, or XML parse failures).

Database Operations

Backup:

cp ~/.claude-mem/claude-mem.db ~/.claude-mem/claude-mem.db.backup

SQLite WAL mode means you should also copy the -wal and -shm files if they exist, or use .backup command via SQLite CLI for a consistent snapshot.

Migrations: The MigrationRunner runs all pending schema migrations on startup. Migrations are versioned and tracked in the schema_versions table. You don't need to run migrations manually — they're applied automatically.

Direct query access:

sqlite3 ~/.claude-mem/claude-mem.db "SELECT COUNT(*) FROM observations"

Health Monitoring

Endpoint Purpose
GET /health Basic liveness check
GET /api/health Detailed health with uptime
GET /api/readiness Health + database status
GET /api/version Current version
GET /api/admin/doctor Full diagnostic report
GET /api/stats Database statistics
GET /api/processing-status Active processing state

Admin Endpoints

Endpoint Purpose
POST /api/admin/restart Restart the worker
POST /api/admin/shutdown Graceful shutdown
GET /api/admin/doctor Diagnostic report
POST /api/settings Update settings
GET /api/settings Read current settings
POST /api/mcp/toggle Enable/disable MCP server
GET /api/mcp/status MCP server status
GET /api/branch/status Current branch info
POST /api/branch/switch Switch branches
POST /api/branch/update Pull latest branch updates

6. Performance

Token Economics

claude-mem tracks two metrics for every observation:

  • Discovery tokens: The estimated size of the raw tool usage (input + response) that was observed
  • Read tokens: The compressed observation size (title + subtitle + narrative + facts)

The TokenCalculator (src/services/context/) computes savings percentages and formats the economics display. Estimation uses 4 characters per token.

Context Injection Optimization

The ContextBuilder compresses observations for injection:

  • ObservationCompiler applies SQL filters by type, concept, and mode configuration
  • Multi-project support for worktrees — queries both the main project and worktree-adopted observations
  • Token budgeting — the context builder tracks cumulative injection size
  • Deduplication — the file-context handler deduplicates observations by session ID and applies specificity scoring

Search Performance

The SearchManager delegates to modular strategies:

Strategy When Used Performance
SQLiteSearchStrategy Filter-only queries (type, date, file) Fast — indexed queries
ChromaSearchStrategy Semantic queries Depends on index size
HybridSearchStrategy Metadata filter + semantic ranking Combined latency

Pagination: The PaginationHelper uses the LIMIT+1 trick to detect hasMore without a COUNT(*) query.

Database Performance Tuning

The SQLite database is configured for maximum read performance:

  • WAL mode: Allows concurrent readers during writes
  • Memory-mapped I/O: 256 MB mmap reduces syscall overhead
  • Page cache: 10,000 pages in memory
  • In-memory temp store: Temporary tables don't hit disk

For large installations (10K+ observations), consider periodic VACUUM:

sqlite3 ~/.claude-mem/claude-mem.db "VACUUM"

Worker Resource Usage

Component Typical Memory Notes
Worker (Express) ~50-100 MB Base process
SDK subprocess ~100-200 MB each Up to 10 concurrent
Chroma subprocess ~200-500 MB Vector index in memory
SQLite ~10-50 MB Page cache + mmap

Warning

With Chroma enabled and multiple active sessions, peak memory can reach 2+ GB. On memory-constrained systems, disable Chroma (CLAUDE_MEM_CHROMA_ENABLED=false) and limit concurrent sessions.


7. Security

Credential Isolation

The EnvManager (src/shared/EnvManager.ts) provides credential isolation:

  • Credentials stored separately in ~/.claude-mem/.env
  • Blocklist approach: ANTHROPIC_API_KEY and CLAUDECODE* variables are stripped from subprocess environments
  • buildIsolatedEnv() constructs a clean environment for SDK subprocesses
  • getCredential() provides read access to stored credentials

Subprocess Environment Sanitization

The env-sanitizer (src/supervisor/env-sanitizer.ts) strips additional sensitive variables:

  • CLAUDECODE_* variables (all)
  • CLAUDE_CODE_* variables (all)
  • Preserved: OAUTH_TOKEN and GIT_BASH_PATH (needed for operation)

Caution

Proxy environment variables (HTTP_PROXY, HTTPS_PROXY, ALL_PROXY) are NOT stripped by the sanitizer. Worker subprocesses inherit them, which can cause stalls when the proxy is unreachable (#2115). Unset these before starting the worker if your network uses a proxy.

Input Validation

  • Branch names: BranchManager.isValidBranchName() validates against ^[a-zA-Z0-9][a-zA-Z0-9._/-]*$ and rejects .. sequences (prevents command injection via git operations)
  • File paths: Adapter layers validate cwd input — AdapterRejectedInput error for invalid working directories
  • Hook responses: Standard { continue: true, suppressOutput: true } JSON response prevents hook output from leaking into IDE output
  • JSON integrity: json-utils.ts refuses to overwrite corrupt JSON files — detection before write prevents silent data loss

Privacy

  • <private>...</private> tags: Content wrapped in privacy tags is stripped before observation extraction
  • Observer session isolation: Observer agent sessions are tracked separately (OBSERVER_SESSIONS_DIR) and filtered from user-facing queries
  • Project exclusion: Configurable project exclusion prevents observations from specific directories

Network Exposure

The worker binds to localhost only — it is not accessible from other machines on the network. External access requires explicit port forwarding or reverse proxy configuration.

The only external network calls are:

  1. AI provider API calls (Claude/Gemini/OpenRouter) for observation extraction
  2. Telegram API calls (if configured)
  3. GitHub API calls (viewer version check)

Warning

The worker's HTTP API has no authentication. Anyone with local access to the machine can query and modify observations. This is by design for single-user operation, but be aware in shared-machine scenarios.


8. Developer Internals

Repository Structure

claude-mem/
├── src/
│   ├── cli/
│   │   ├── adapters/          # IDE input normalization (claude-code, cursor, gemini-cli, raw, windsurf)
│   │   ├── handlers/          # 8 hook event handlers (context, session-init, observation, file-context, summarize, session-complete, user-message, file-edit)
│   │   └── claude-md-commands.ts  # CLAUDE.md generation/cleanup
│   ├── hooks/
│   │   └── hook-response.ts   # Standard hook response constant
│   ├── integrations/
│   │   └── opencode-plugin/   # OpenCode plugin entry point
│   ├── npx-cli/
│   │   ├── commands/          # install, runtime, uninstall, ide-detection
│   │   ├── utils/             # bun-resolver
│   │   └── index.ts           # CLI entry point
│   ├── sdk/
│   │   ├── parser.ts          # XML response parser (observation[], summary, invalid)
│   │   └── prompts.ts         # XML prompt builders (init, observation, summary, continuation)
│   ├── servers/
│   │   └── mcp-server.ts      # MCP server with 12+ tools
│   ├── services/
│   │   ├── context/           # ContextBuilder, ContextConfigLoader, ObservationCompiler, TokenCalculator
│   │   ├── domain/            # ModeManager
│   │   ├── infrastructure/    # WorktreeAdoption
│   │   ├── integrations/      # 7 IDE installers + TelegramNotifier + McpIntegrations
│   │   ├── server/            # Express Server base, ErrorHandler
│   │   ├── sqlite/            # Database, SessionStore, SessionSearch, PendingMessageStore, migrations
│   │   ├── sync/              # ChromaSync
│   │   ├── transcripts/       # TranscriptWatcher, TranscriptEventProcessor
│   │   ├── worker/            # Core worker: SDKAgent, GeminiAgent, OpenRouterAgent, SessionManager, SearchManager, etc.
│   │   └── worker-service.ts  # Worker lifecycle management (1365+ lines)
│   ├── shared/                # EnvManager, SettingsDefaultsManager, paths, worker-utils, hook-constants
│   ├── supervisor/            # ProcessRegistry, health-checker, env-sanitizer, shutdown
│   ├── types/                 # Shared type definitions
│   ├── ui/
│   │   └── viewer/            # React SPA (App.tsx, components, hooks, utils)
│   └── utils/                 # Logger, json-utils, cursor-utils, claude-md-utils
├── plugin/
│   ├── hooks/                 # hooks.json
│   ├── modes/                 # 35 JSON mode files
│   ├── scripts/               # worker-service.cjs, mcp-server.cjs, smart-install
│   ├── skills/                # 8 skills: pathfinder, timeline-report, version-bump, smart-explore, knowledge-agent, mem-search, make-plan, do
│   ├── ui/                    # Bundled viewer assets
│   └── .mcp.json              # MCP server declaration
├── openclaw/                  # @openclaw/claude-mem extension package
├── ragtime/                   # Ragtime transcript processor
├── cursor-hooks/              # Cursor-specific hook scripts
├── docker/claude-mem/         # Docker build/run scripts
├── evals/swebench/            # SWE-bench evaluation harness
├── scripts/                   # Build scripts, translation, bug-report tool
├── tests/                     # Comprehensive test suite
│   ├── cli/                   # Handler tests, adapter tests
│   ├── context/               # Context builder tests
│   ├── infrastructure/        # Plugin-disabled check
│   ├── integration/           # Integration tests
│   ├── sdk/                   # Parser tests
│   ├── server/                # Server tests
│   ├── services/              # SQLite, queue, sync tests
│   ├── shared/                # Settings, utils tests
│   ├── sqlite/                # Database tests
│   ├── supervisor/            # Supervisor tests
│   ├── utils/                 # Utility tests
│   └── worker/                # Worker tests (agents, routes, middleware, search)
├── docs/
│   ├── public/                # MDX documentation site
│   ├── i18n/                  # 31 language README translations
│   ├── reports/               # Bug investigation reports
│   └── context/               # Context documentation
├── install/                   # Installation page/assets
└── PATHFINDER-*/              # Architecture exploration documents

Module Deep-Dive: SDK Agent Pipeline

The SDK agent pipeline is the core observation extraction mechanism:

1. Prompt Construction (src/sdk/prompts.ts):

  • buildInitPrompt(mode) — Initial system prompt establishing the observer role, XML output format, mode-specific type/concept definitions
  • buildObservationPrompt(toolName, toolInput, toolResponse, mode) — Observation extraction prompt for a specific tool use
  • buildSummaryPrompt(lastAssistantMessage, mode) — Session summary prompt
  • buildContinuationPrompt(mode) — Continuation prompt when the agent needs to generate more observations

All prompts are mode-aware — the ModeManager loads the active mode's JSON file and injects customized placeholders, footer text, and language requirements.

2. Agent Execution:

Three agent implementations share the same XML observation format:

  • SDKAgent — Uses @anthropic-ai/claude-agent-sdk's query() function to spawn a Claude subprocess. Event-driven (no polling). Managed by the ProcessRegistry.
  • GeminiAgent — Direct REST calls to https://generativelanguage.googleapis.com/v1/models. Handles free-tier RPM limits per model.
  • OpenRouterAgent — REST calls to https://openrouter.ai/api/v1/chat/completions. OpenAI-compatible message format. Default context limit: 20 messages / 100K estimated tokens.

3. Response Parsing (src/sdk/parser.ts):

parseAgentXml() returns a discriminated union:

  • { kind: 'observation', observations: Observation[] } — One or more extracted observations
  • { kind: 'summary', summary: SessionSummary } — Session progress summary
  • { kind: 'invalid', reason: string } — Parse failure
  • Handles <skip_summary/> as a first-class case (agent decided no summary needed)

4. Storage and Sync:

Parsed observations are:

  1. Stored in SQLite via SessionStore.storeObservation()
  2. Synced to Chroma via ChromaSync (if enabled)
  3. SSE-broadcast to connected viewer clients

Module Deep-Dive: PendingMessageStore

The PendingMessageStore (src/services/sqlite/PendingMessageStore.ts) is the persistence layer for the observation queue:

Lifecycle:

  1. enqueue() — INSERT OR IGNORE (tool_use_id UNIQUE constraint prevents duplicates)
  2. claimNextMessage() — Atomic UPDATE ... WHERE id = (subselect) with worker PID stamping
  3. confirmProcessed() — DELETE after successful storage
  4. Self-healing: claimNextMessage reclaims rows where worker_pid NOT IN (live_pids)

Key design decisions:

  • No timer-based reaping — liveness is checked at claim time, not by a background process
  • PID-based crash detection — LiveWorkerPidsProvider returns the set of alive worker PIDs
  • Idempotent enqueue — INSERT OR IGNORE on the (content_session_id, tool_use_id) UNIQUE index
  • Max retries: 3 per message (configurable)
  • Terminal states: failed (narrow: only processing rows), abandoned (wide: pending + processing)

Module Deep-Dive: Context Builder

The context system (src/services/context/) compresses observation history for injection:

  • ContextBuilder — Orchestrator that queries SQLite and formats the timeline
  • ContextConfigLoader — Loads settings with mode-based filtering (type/concept exclusions)
  • ObservationCompiler — SQL query builder with:
    • Type filtering per mode config
    • Concept filtering
    • Multi-project support (main project + adopted worktree observations)
    • Date range filtering
  • TokenCalculator — Computes read tokens vs. discovery tokens, savings percentage

Module Deep-Dive: Search Infrastructure

The search system uses a strategy pattern:

SearchManager (facade)
  └── SearchOrchestrator (strategy selection)
       ├── SQLiteSearchStrategy  — Filter-only queries
       ├── ChromaSearchStrategy  — Vector semantic search
       └── HybridSearchStrategy  — Filters + semantic ranking

Additional components:

  • ResultFormatter — Consistent output formatting
  • TimelineBuilder — Chronological timeline construction
  • FormattingService — Table format matching context-generator style

Module Deep-Dive: IDE Integration Installers

Each supported IDE has a dedicated installer in src/services/integrations/:

Installer IDE Method
Built-in (hooks.json) Claude Code Native lifecycle hooks
CursorHooksInstaller Cursor hooks.json + MCP config + project registry + .cursor/rules
GeminiCliHooksInstaller Gemini CLI Hook mapping + GEMINI.md context
OpenCodeInstaller OpenCode Plugin hooks
WindsurfHooksInstaller Windsurf hooks.json merging
CodexCliInstaller Codex CLI Transcript watching (no hooks)
McpIntegrations Various MCP server configuration
TelegramNotifier N/A Push notifications

Cursor specifics:

  • Project registry at ~/.claude-mem/cursor-projects.json
  • Auto-updates .cursor/rules after summary generation via updateCursorContextForProject()
  • MCP server script at plugin/scripts/mcp-server.cjs
  • Detects Bun executable across macOS, Linux, and Windows paths

Codex CLI specifics:

  • Transcript-only approach — no hooks, watches ~/.codex/sessions/**/*.jsonl
  • Merges watch config into ~/.claude-mem/transcript-watch.json (preserves other watches)
  • Context via workspace-local AGENTS.md files
  • Legacy global ~/.codex/AGENTS.md context is cleaned up on install

Code Patterns and Conventions

Module organization:

  • Named re-export facades (e.g., Search.ts re-exports ./search/index.js)
  • Route classes extend BaseRouteHandler
  • Singleton patterns: Supervisor, DatabaseManager (legacy), Logger
  • New code uses ClaudeMemDatabase class (deprecating singleton DatabaseManager)

Error handling:

  • AppError extends Error with HTTP status codes
  • asyncHandler wraps Express route handlers for promise rejection
  • AdapterRejectedInput for invalid IDE input
  • DryRunRollback for worktree adoption dry runs

TypeScript patterns:

  • ESM modules ("type": "module")
  • bun:sqlite for database access (Bun-specific)
  • Zod 4 for runtime validation
  • Discriminated unions for parse results
  • Strict null checks

Build system:

  • scripts/build-hooks.js — esbuild bundles for hooks
  • scripts/sync-plugin-manifests.js — Syncs version across package.json files
  • scripts/sync-marketplace.cjs — Copies plugin to marketplace directory
  • esbuild for all bundling

Testing Strategy

Tests use Bun's built-in test runner (bun test):

bun test                    # All tests
bun test tests/sqlite/      # SQLite layer tests
bun test tests/worker/      # Worker tests
bun test tests/context/     # Context builder tests
bun test tests/server/      # Server tests
bun test tests/sdk/         # Parser tests

Test organization mirrors source structure:

  • tests/cli/handlers/ — Hook handler tests
  • tests/cli/adapters/ — IDE adapter tests
  • tests/worker/agents/ — Agent tests
  • tests/worker/search/ — Search strategy tests
  • tests/worker/http/routes/ — HTTP route tests
  • tests/worker/middleware/ — Middleware tests
  • tests/sqlite/ — Database layer tests
  • tests/services/sqlite/observations/ — Observation storage tests
  • tests/services/queue/ — Queue tests
  • tests/services/sync/ — Chroma sync tests
  • tests/context/formatters/ — Context formatter tests
  • tests/shared/ — Shared utility tests
  • tests/infrastructure/ — Plugin state tests
  • tests/supervisor/ — Supervisor tests

Type checking:

npm run typecheck          # Root + Viewer
npm run typecheck:root     # Root tsconfig only
npm run typecheck:viewer   # Viewer tsconfig only

Potential Improvements

Based on open GitHub issues and code patterns:

  1. Windows reliability — Multiple open issues (#2109, #2111, #2114, #2123, #2131) around path handling, port management, and shell detection. A comprehensive Windows test suite would catch regressions.

  2. Session timeout configurability — Currently hardcoded MAX_SESSION_WALL_CLOCK_MS at 4 hours (#2098, #2127). Should be exposed as a setting.

  3. Chroma subprocess lifecycle — The MCP retry logic can spawn multiple Chroma subprocesses without killing previous ones (#2102). Needs proper subprocess lifecycle management.

  4. Observer session isolation — Observer prompts leaking into user_prompts (#2104) and SSE events (#2118) indicate incomplete session boundary enforcement.

  5. PreToolUse:Read hook timeout — The 2000-second timeout (#2100) should be reduced to prevent blocking the IDE when the worker hangs.

  6. Environment variable filtering — Configurable whitelist requested (#2099) instead of the current blocklist approach, which can miss proxy variables (#2115).

  7. Multi-account support — No built-in isolation for work/personal accounts (#2101). The current workaround (separate DATA_DIR) is manual.


9. Integration Points

MCP Server

The MCP server (src/servers/mcp-server.ts) exposes claude-mem's capabilities to any MCP-compatible client via stdio transport.

Server declaration (plugin/.mcp.json):

{
  "mcpServers": {
    "mcp-search": {
      "type": "stdio",
      "command": "bun",
      "args": ["${CLAUDE_PLUGIN_ROOT}/scripts/mcp-server.cjs"]
    }
  }
}

Available tools:

Tool Parameters Purpose
__IMPORTANT topic: workflow, search_params, examples, all Workflow guide and onboarding
search query, obs_type, dateStart, dateEnd, orderBy, limit, offset, concept Search observations
timeline query, dateStart, dateEnd Chronological timeline
get_observations ids (array) Batch fetch by ID
smart_search query Semantic search via Chroma
smart_unfold id Expand observation context
smart_outline query Structured outline from results
build_corpus name, query Create knowledge corpus
list_corpora — List all corpora
prime_corpus name AI-analyze corpus
query_corpus name, query Query a corpus
rebuild_corpus name Rebuild corpus index
reprime_corpus name Re-analyze corpus

Orphan detection: The MCP server uses a parent heartbeat mechanism to detect when the IDE process has died, allowing clean self-termination.

Worker HTTP API Reference

Complete API surface extracted from route definitions:

Health & Admin:

Method Path Purpose
GET /health Liveness check
GET /api/health Detailed health
GET /api/readiness Health + DB status
GET /api/version Version info
GET /api/instructions Worker instructions
POST /api/admin/restart Restart worker
POST /api/admin/shutdown Shutdown worker
GET /api/admin/doctor Full diagnostic

Data & Observations:

Method Path Purpose
GET /api/observations List observations (paginated)
GET /api/observation/:id Single observation
GET /api/observations/by-file By file path
POST /api/observations/batch Batch fetch
GET /api/summaries List summaries
GET /api/prompts List prompts
GET /api/prompt/:id Single prompt
GET /api/stats Database statistics
GET /api/projects Project list
GET /api/processing-status Active processing
POST /api/processing Submit processing task
POST /api/import Bulk import

Search:

Method Path Purpose
GET /api/search Full-text search
GET /api/timeline Timeline view
GET /api/decisions Decision observations
GET /api/changes Change observations
GET /api/how-it-works How-it-works content
GET /api/search/observations Search observations
GET /api/search/sessions Search sessions
GET /api/search/prompts Search prompts
GET /api/search/by-concept By concept
GET /api/search/by-file By file
GET /api/search/by-type By type
GET /api/search/help Search help
GET /api/timeline/by-query Timeline filtered by query

Context:

Method Path Purpose
GET /api/context/recent Recent context
GET /api/context/timeline Context timeline
GET /api/context/preview Context preview
GET /api/context/inject Context injection payload
POST /api/context/semantic Semantic context query

Sessions:

Method Path Purpose
GET /sessions/:id/status Session status
DELETE /sessions/:id Delete session
POST /sessions/:id/complete Complete session
GET /api/sessions/status All sessions status
POST /api/sdk-sessions/batch Batch SDK session operations

Settings & Configuration:

Method Path Purpose
GET /api/settings Read settings
POST /api/settings Update settings
GET /api/mcp/status MCP status
POST /api/mcp/toggle Toggle MCP
GET /api/branch/status Git branch info
POST /api/branch/switch Switch branches
POST /api/branch/update Pull branch updates

Memory:

Method Path Purpose
POST /api/memory/save Save manual memory

Corpus:

Method Path Purpose
POST /api/corpus Create corpus
GET /api/corpus List corpora
GET /api/corpus/:name Get corpus
DELETE /api/corpus/:name Delete corpus
POST /api/corpus/:name/rebuild Rebuild corpus
POST /api/corpus/:name/prime Prime corpus
POST /api/corpus/:name/query Query corpus
POST /api/corpus/:name/reprime Re-prime corpus

Chroma:

Method Path Purpose
GET /api/chroma/status Chroma status

Logs:

Method Path Purpose
GET /api/logs Read logs
POST /api/logs/clear Clear logs

Viewer & SSE:

Method Path Purpose
GET / Viewer SPA
GET /stream SSE event stream

Transcript Watcher Integration

For IDEs without hook support, claude-mem offers transcript watching:

Configuration (~/.claude-mem/transcript-watch.json):

{
  "version": 1,
  "schemas": {
    "codex": { "version": 1, "format": "jsonl" }
  },
  "watches": [
    {
      "name": "codex",
      "glob": "~/.codex/sessions/**/*.jsonl",
      "schema": "codex"
    }
  ],
  "stateFile": "~/.claude-mem/transcript-watch-state.json"
}

Components:

  • TranscriptWatcher — FileTailer that monitors glob patterns for new JSONL/JSON content
  • TranscriptEventProcessor — Processes transcript events and maps them to observation ingestion
  • Supports Codex CLI JSONL and Gemini CLI JSON formats

OpenClaw Extension

The openclaw/ directory contains a standalone extension package (@openclaw/claude-mem) that integrates with the OpenClaw platform:

  • Communicates via SSE stream to the worker
  • Runs as a private npm package
  • Built and tested independently (tsc + node --test)

Plugin Skills

The plugin includes 8 skills in plugin/skills/:

Skill Purpose
pathfinder Architecture exploration and analysis
timeline-report Generate timeline reports
version-bump Version bump automation with scripts
smart-explore Intelligent codebase exploration
knowledge-agent Knowledge base management
mem-search Memory search interface
make-plan Planning assistance
do Task execution

Ragtime

The ragtime/ directory contains a transcript processor that:

  • Reads from RAGTIME_CORPUS_PATH
  • Connects to worker on CLAUDE_MEM_WORKER_PORT
  • Processes transcripts with configurable max age, file limits, and session delays
  • Supports mode-aware observation extraction

Troubleshooting (Admin)

Worker Won't Start

  1. Check port availability:
    lsof -i :37777   # macOS/Linux
    netstat -an | grep 37777   # Windows
    
  2. Check Bun installation: bun --version
  3. Check logs: cat ~/.claude-mem/logs/worker-$(date +%Y-%m-%d).log
  4. Check PID file: cat ~/.claude-mem/worker.pid

Database Corruption

Symptoms: SQLITE_CORRUPT, SQLITE_NOTADB, unexpected query errors.

  1. Stop the worker
  2. Back up the database: cp ~/.claude-mem/claude-mem.db ~/.claude-mem/claude-mem.db.corrupt
  3. Attempt recovery:
    sqlite3 ~/.claude-mem/claude-mem.db ".recover" | sqlite3 ~/.claude-mem/claude-mem-recovered.db
    
  4. Replace the database and restart

SDK Agent Not Extracting Observations

  1. Check provider credentials:
    • Claude: OAuth token valid? (~/.claude/.credentials.json)
    • Gemini: API key set? (CLAUDE_MEM_GEMINI_API_KEY)
    • OpenRouter: API key set? (CLAUDE_MEM_OPENROUTER_API_KEY)
  2. Check process count: GET /api/processing-status
  3. Check for hard cap: logs show "Hard cap exceeded" if at 10 processes
  4. Check PendingMessage queue: npm run queue

Caution

If the SDK agent fails repeatedly, messages accumulate in the pending queue. The clearFailedOlderThan() method cleans up on restart, but a persistent failure (e.g., expired credentials) will keep generating failed messages. Fix the root cause before restarting.

High Memory Usage

  1. Check Chroma: GET /api/chroma/status — disable if leaking (#2102)
  2. Count SDK processes: check logs for ProcessRegistry spawn count
  3. Check for restart loops: RestartGuard logs will show trip conditions
  4. Consider reducing MAX_CONCURRENT (default context limit: 20 messages per agent)

Migration Failures

If a migration fails on startup:

  1. Check the schema_versions table for the last successful version
  2. Examine the migration runner logs
  3. The migration runner is idempotent — restarting will retry failed migrations
  4. In extreme cases, back up and recreate the database

Quick Reference

npm Scripts

Script Purpose
npm run build Build hooks and sync manifests
npm run dev Build + sync marketplace + restart worker
npm run test Run all tests (bun test)
npm run typecheck TypeScript type checking
npm run worker:start Start worker via bun
npm run worker:stop Stop worker
npm run worker:restart Restart worker
npm run worker:status Worker status
npm run worker:logs View recent logs
npm run queue Check queue status
npm run queue:process Process pending messages
npm run queue:clear Clear failed messages
npm run claude-md:regenerate Regenerate CLAUDE.md files
npm run claude-md:dry-run Preview CLAUDE.md changes
npm run cursor:install Install Cursor integration
npm run cursor:uninstall Remove Cursor integration
npm run cursor:status Cursor integration status
npm run translate-readme Translate README to other languages
npm run bug-report Generate bug report
npm run release:patch Release patch version
npm run release:minor Release minor version

npx CLI Commands

Command Purpose
npx claude-mem install Interactive installation
npx claude-mem update / upgrade Update to latest
npx claude-mem uninstall / remove Remove installation
npx claude-mem start Start worker
npx claude-mem stop Stop worker
npx claude-mem restart Restart worker
npx claude-mem status Worker status
npx claude-mem search Search observations
npx claude-mem adopt Adopt worktree observations
npx claude-mem transcript watch Start transcript watcher
npx claude-mem version Show version
npx claude-mem help Show help

Key File Paths

Path Purpose
~/.claude-mem/ Data directory root
~/.claude-mem/claude-mem.db SQLite database
~/.claude-mem/settings.json Configuration
~/.claude-mem/.env Credentials
~/.claude-mem/logs/ Daily rotating logs
~/.claude-mem/vector-db/ Chroma vector index
~/.claude-mem/observer-sessions/ SDK subprocess data
~/.claude-mem/transcript-watch.json Transcript watcher config
~/.claude-mem/cursor-projects.json Cursor project registry
~/.claude/plugins/marketplaces/thedotmack/ Installed plugin

Key Constants

Constant Value Source
Default port 37777 SettingsDefaultsManager
Hook timeout 300s hook-constants.ts
Health check timeout 3s hook-constants.ts
Process hard cap 10 process-registry.ts
Health check interval 30s health-checker.ts
Restart window 60s RestartGuard.ts
Max windowed restarts 10 RestartGuard.ts
Max consecutive failures 5 RestartGuard.ts
Decay after success 5 min RestartGuard.ts
SQLite mmap size 256 MB Database.ts
SQLite cache pages 10,000 Database.ts
Max pending retries 3 PendingMessageStore.ts
Shutdown grace period 5s shutdown.ts
Git command timeout 300s BranchManager.ts
npm install timeout 600s BranchManager.ts
Token estimate 4 chars/token Multiple files