Claude Code persistent memory plugin (v2.1) — anti-patch reconcile-on-write, forced PROGRESS.md handoff, FTS5 search, AI-judged extraction with Haiku + local Ollama fallback.
Claude Code compresses (compacts) conversations when the context window fills up, causing information loss: decisions, results, todos, and project knowledge disappear. Conversations that end normally (terminal closed) also lose context.
cc-memory captures structured memories at every conversation boundary AND forces the next session to read a handoff document before it starts work.
- Anti-patch writes. Every save goes through
llm.memory_writer.upsert_smart, which MERGES (overwrites a similar memory in place), SUPERSEDES (archives the old, links the new viasupersedes_id), or INSERTS — chosen by trigram-Jaccard similarity. No more stacked duplicates. See docs/MEMORY_RULES.md. - Forced handoff via PROGRESS.md.
memory/PROGRESS.mdis the single source of truth for session handoff, always full-rewritten from a SQL row, never appended. SessionStart emits a<system-reminder>block that requires the next Claude to Read it before responding. See docs/HANDOFF_PROTOCOL.md. - Auto-fresh MEMORY.md. Regenerated after every write — no more 50-day-stale index files.
- Idle reorg. Stop hook runs lightweight cleanup every 5 turns (no LLM).
- Clean subpackage layout.
cc_memory/{core,hooks,llm,cli,mcp,ui}/. - One installer, one skills location, one version number. Removed
.claude/skills/duplicate, removed the third copy ofsave-memories, removed dual installers.
claude /plugin marketplace add skymanbp/cc-memory
claude /plugin install cc-memoryclaude /plugin marketplace add /path/to/cc-memory
claude /plugin install cc-memory- Download
cc-memory-installer.exefrom Releases - Double-click → Install Plugin → Configure Hooks → done.
git clone https://github.com/skymanbp/cc-memory.git
python cc-memory/cc_memory/ui/installer.py # GUI
# or
python cc-memory/cc_memory/ui/installer.py --cli # CLIThe installer:
- Copies the subpackage tree to
~/.claude/hooks/cc-memory/. - Adds the 5 hook entries to
~/.claude/settings.json. - Auto-detects + upgrades any v2.0 flat-layout install.
Per-project initialization is automatic — the first user message creates
<project>/memory/ and the SQLite DB.
Hooks (registered in ~/.claude/settings.json):
UserPromptSubmit ─► turn count + first-prompt seeding of PROGRESS.md
auto-init memory/ on first contact
PostToolUse ─► insert one observation row per tool call (no LLM)
Stop ─► Haiku observer extracts memories from this turn
patch_progress(files_touched=...)
idle reorg every 5 turns
PreCompact ─► Haiku extracts memories from the full transcript
ALL writes go through llm.memory_writer.upsert_smart
FULL-REWRITE memory/PROGRESS.md from SQL row
archive session, regen MEMORY.md, maybe LLM-consolidate
SessionStart ─► inject context (topics + critical + timeline + PROGRESS preview)
emit FORCED <system-reminder>: "Read PROGRESS.md FIRST"
retroactive save of unsaved prior JSONLs
Per-project state lives at <project>/memory/:
memory/
├── memory.db SQLite WAL, see core/db.py for schema
├── MEMORY.md auto-generated index, refreshed every write
├── PROGRESS.md full-rewrite from `progress` row at every Stop+PreCompact
├── .last_save.json status from last PreCompact
├── .gitignore excludes DB + sessions
├── sessions/YYYY/MM/ per-session archives
└── topics/ reserved for future per-topic exports
| Category | What gets extracted | Default importance |
|---|---|---|
decision |
Explicit choices, design changes | 3 |
result |
Measured outcomes (numbers + units) | 3 |
config |
Hyperparameters, env vars, constants | 2 |
bug |
Identified+fixed problems, "NEVER do X" | 4 |
task |
Pending/blocked work items | 2 |
arch |
Module/pipeline structure, data flow | 3 |
note |
Everything else above noise | 1 |
Importance scale: 1=noise, 2=low, 3=normal, 4=important, 5=critical (never forget).
M="python ~/.claude/hooks/cc-memory/cc_memory/cli/mem.py --project ."
$M status # Full health check
$M stats # Memory + supersede-chain counts
$M list decisions # Recent memories by category
$M search "auth flow" # FTS5 search
$M topics # Topic summaries
$M progress # Regenerate memory/PROGRESS.md and print
$M supersedes 42 # Walk the supersede chain for memory #42
$M consolidate # Full LLM-backed consolidation
$M cleanup # Lightweight no-LLM cleanup
$M add decision "Chose X" --importance 4 --topic auth # Anti-patch upsertSlash command: /cc-mem <subcommand> does the same.
8 tools exposed via cc_memory/mcp/server.py:
| Tool | Purpose |
|---|---|
memory_search |
FTS5 search (compact results) |
memory_get_details |
Batch fetch full details by IDs |
memory_add |
Add via anti-patch upsert |
memory_stats |
Project statistics |
memory_topics |
List topic summaries |
memory_recent |
Recent memories with filters |
progress_get |
Read PROGRESS.md state (structured fields) |
progress_regenerate |
Force-rewrite memory/PROGRESS.md from SQL state |
Enable via ~/.claude/mcp.json (set cc_memory.mcp.auto_register=true in
cc_memory/config.json and re-install).
python ~/.claude/hooks/cc-memory/cc_memory/ui/dashboard.py
# or
cc-memory-dashboard.exe6 tabs: Memories · Plans · Sessions · Keywords · SQL Console · Stats.
python ~/.claude/hooks/cc-memory/cc_memory/cli/mem.py --project . serve
# opens http://127.0.0.1:9377 in your browserTask planning system using the same SQLite DB:
P="python ~/.claude/hooks/cc-memory/cc_memory/cli/plan.py --project ."
$P add "Task A" "Task B" "Task C"
$P list
$P evaluate # mark draft → evaluating; Claude evaluates feasibility
$P approve --all # evaluating → ready
$P exec --next # ready → executing (launches Claude Code CLI)
$P done 1 "Result" # mark complete
$P status # queue summary
$P clear # drop done/failed/skippedStatus flow: draft → evaluating → ready → executing → done/failed/skipped.
Edit ~/.claude/hooks/cc-memory/cc_memory/config.json:
extraction.*— extraction caps (sentences, metrics, todos, file changes)writer.*— anti-patch thresholds (high_similarity_threshold,mid_similarity_threshold)injection.*— SessionStart token budget and per-layer fractionsobservation.*— PostToolUse truncation limits, skip listsidle_reorg.interval_turns— N turns between idle reorg runs (default 5)consolidation.*— full LLM consolidation scheduleccl.*— Ollama fallback URL + modelmodes.default— default project mode (code/research/writing)
cc-memory auto-detects your Claude OAuth token from ~/.claude/.credentials.json.
No manual API key setup is needed if you're logged into Claude Code.
Resolution order: ANTHROPIC_API_KEY env var → Claude OAuth token.
pip install pyinstaller
python build_exe.py
# produces:
# dist/cc-memory-installer.exe
# dist/cc-memory-dashboard.exe- Python 3.8+ (stdlib only — no pip dependencies at runtime)
- Claude Code with hooks support
- PyInstaller (only for building the exe, not for running)
- docs/ARCHITECTURE.md — full architecture overview
- docs/MEMORY_RULES.md — anti-patch write contract
- docs/HANDOFF_PROTOCOL.md — PROGRESS.md spec
- CHANGELOG.md — version history
MIT