Memory Services
Claude Code has three complementary memory systems that persist context across and within sessions. Each uses the forked agent pattern (a sub-agent that shares the parent conversation's prompt cache) to extract and maintain knowledge without interrupting the main conversation.
Session Memory
Location: src/services/SessionMemory/sessionMemory.ts
Session Memory automatically maintains a markdown file with notes about the current conversation. It runs periodically in the background using a forked subagent, extracting key information from the conversation without interrupting the user.
How It Works
- A post-sampling hook fires after each model response
- The hook checks whether the conversation has grown enough to warrant extraction (based on message count and tool call thresholds)
- When thresholds are met, a forked agent reads the conversation and updates the session memory file
- The memory file is stored at a session-specific path under
~/.claude/
Configuration
Session Memory is controlled by a remote config (tengu_sm_config) with local defaults:
Minimum number of model-visible messages before the first extraction runs.
Minimum messages since the last extraction before a new one triggers.
Tool calls between extraction runs, providing a secondary trigger.
Extraction Flow
User query --> Model response --> Post-sampling hook
|
Check thresholds met?
|
Yes: Run forked agent
|
Read existing memory file
|
Update with new observations
|
Write session memory fileSession Memory is gated behind the tengu_session_memory feature flag. The feature uses cached (non-blocking) flag reads so it never delays the main conversation.
Session Memory and Compaction
Session Memory has a special relationship with the compact service. When auto-compact triggers, the system first attempts session memory compaction: replacing old messages with the session memory summary rather than running full LLM-based compaction. This is faster and preserves more structured context.
Auto-Memory (Extract Memories)
Location: src/services/extractMemories/extractMemories.ts
The auto-memory system extracts durable, cross-session memories at the end of each complete query loop. Unlike Session Memory (which tracks the current conversation), auto-memory captures learnings that should persist across future sessions.
Trigger Conditions
Auto-memory runs once when:
- The model produces a final response with no tool calls (end of query loop)
- The conversation has enough model-visible messages since the last extraction
- The feature is enabled via
isAutoMemoryEnabled()
Memory Storage
Extracted memories are written to the auto-memory directory:
~/.claude/projects/<project-path>/memory/The system uses scanMemoryFiles() and formatMemoryManifest() to:
- Scan existing memory files in the directory
- Build a manifest of current memories
- Let the forked agent decide what to add, update, or leave unchanged
Available Tools
The extraction agent has access to a limited set of tools for managing memory files:
FileRead: Read existing memory filesFileEdit: Update existing memoriesFileWrite: Create new memory filesBash: Execute commands if neededGlob/Grep: Search for relevant files
Auto-memory is distinct from the CLAUDE.md files that users manually maintain. Auto-memory files are machine-generated and stored in a separate directory to avoid polluting user-authored documentation.
Combined vs Auto-Only Extraction
The system supports two prompt modes:
Extracts both auto-memory and team-memory (when team memory sync is enabled) in a single forked agent call. Uses buildExtractCombinedPrompt().
Magic Docs
Location: src/services/MagicDocs/magicDocs.ts
Magic Docs is a system for automatically maintaining documentation files. When a markdown file with a special header is read during a conversation, Magic Docs periodically updates it with new learnings.
Header Pattern
A file is recognized as a Magic Doc when its first line matches:
# MAGIC DOC: Architecture Overview
_Focus on module boundaries and data flow patterns_The pattern # MAGIC DOC: [title] triggers registration. An optional italicized line immediately after the header provides instructions to guide the update agent.
Detection and Registration
const MAGIC_DOC_HEADER_PATTERN = /^#\s*MAGIC\s+DOC:\s*(.+)$/im
export function detectMagicDocHeader(content: string): {
title: string
instructions?: string
} | nullWhen FileReadTool reads a file, a listener checks for the Magic Doc header. If found, the file path is registered in a tracked set (trackedMagicDocs).
Update Cycle
- A file read listener detects Magic Doc headers when files are read
- A post-sampling hook fires after each model response
- If the model produced a final response (no pending tool calls), the hook checks all tracked Magic Docs
- For each tracked doc, a built-in agent reads the current file content, reviews the conversation, and updates the document
- The agent uses
FileReadandFileEdittools to modify the Magic Doc in place
function getMagicDocsAgent(): BuiltInAgentDefinition {
return {
// Agent with FileRead + FileEdit tools
// Uses buildMagicDocsUpdatePrompt() for instructions
}
}Use Cases
Architecture Documentation
Create a # MAGIC DOC: Architecture file in your project. As you discuss and modify the codebase with Claude, the doc automatically captures architectural decisions, module relationships, and design patterns.
Decision Log
A # MAGIC DOC: Decisions file tracks why certain approaches were chosen during development, building an automatic ADR (Architecture Decision Record).
API Reference
A # MAGIC DOC: API Reference file stays updated as endpoints are added or modified during the conversation.
Comparison
| Feature | Session Memory | Auto-Memory | Magic Docs |
|---|---|---|---|
| Scope | Current session | Cross-session | Per-file |
| Trigger | Periodic (threshold) | End of query loop | Post-sampling hook |
| Storage | ~/.claude/ session dir | ~/.claude/projects/*/memory/ | In-place (user's file) |
| Content | Conversation notes | Durable learnings | Structured documentation |
| Agent | Forked subagent | Forked subagent | Built-in agent |
| User-visible | No (internal) | No (internal) | Yes (user's file) |