DAG-based persistent component memory for Claude AI sessions
Project description
cmem
DAG-based persistent component memory for Claude AI sessions.
The problem: how Claude currently remembers things
Claude Code has a built-in memory system based on a file called MEMORY.md, stored per-project at:
~/.claude/projects/<project-path>/memory/MEMORY.md
Claude reads this file at the start of every session and writes to it whenever it learns something worth keeping — key patterns, architectural decisions, recurring gotchas, workflow preferences. It works like a running notepad.
The limitations:
| Limitation | What it means |
|---|---|
| Flat file, ~200 line cap | Everything lives in one file. Old entries get compressed or dropped as it fills up. |
| Overwrite model | When something changes, the old entry is replaced. There's no record of what it used to be. |
| No structure | All components of a project share one file. A large codebase with 20+ components quickly becomes noise. |
| No history | Claude can tell you what a component does now, but not why it works this way or what changed. |
| No causality | "We switched from Redis pub/sub to SQS for ranking" — gone after the next overwrite. |
In practice, for any non-trivial project, Claude's memory degrades over time. It knows the current state but loses the archaeological record of how things evolved.
What cmem adds
cmem gives each component in your project its own immutable DAG — a chain of snapshots connected by annotated transitions.
~/.claude/memory/
my_project/
auth_service/
graph.toml ← DAG index: nodes, edges, HEAD pointer
snapshots/
N1.toml ← immutable: state of the component at a point in time
N2.toml
N3.toml
transitions/
N1-N2.toml ← what changed, why, and what was affected
N2-N3.toml
job_router/
graph.toml
snapshots/
transitions/
How it's different:
| Capability | MEMORY.md | cmem |
|---|---|---|
| Remembers current state | ✅ | ✅ |
| Per-component structure | ❌ | ✅ |
| Immutable history | ❌ | ✅ |
| "Why does this work this way?" | ❌ | ✅ — traverse transitions |
| Handles 20+ components | ❌ (hits 200-line cap) | ✅ — each component is independent |
| Causality chain | ❌ | ✅ — trigger + notes on every edge |
| DAG (branching/merging) | ❌ | ✅ — full directed acyclic graph |
The two systems work together, not against each other. MEMORY.md holds cross-cutting project facts (stack, URL patterns, workflow preferences). cmem holds the deep, per-component history. MEMORY.md points Claude to cmem for component-level context.
How Claude uses cmem autonomously
When you add a CLAUDE.md to your project (via cmem install-claude), Claude checkpoints components automatically — no user prompting needed.
At session start, when touching a known component:
cmem head my_project auth_service # load current state
cmem show my_project auth_service N3
After any meaningful change (bug fix, feature, refactor, discovery), Claude runs:
OLD=$(cmem head my_project auth_service | head -1)
# ... does the work ...
cmem snapshot my_project auth_service --file /tmp/snap.toml
NEW=$(cmem head my_project auth_service | head -1)
cmem transition my_project auth_service $OLD $NEW \
--trigger bug_fix \
--notes "Fixed ranking to use SQS queue instead of Redis pub/sub"
When asked "why does X work this way?", Claude runs:
cmem log my_project auth_service
and traces back through transitions to find the answer.
Install
pip install cmem-cli
Quick start
# 1. Initialize a component
cmem init my_project auth_service
# 2. Create first snapshot (opens $EDITOR)
cmem snapshot my_project auth_service
# 3. After a change, snapshot again and record the transition
cmem snapshot my_project auth_service
cmem transition my_project auth_service N1 N2
# 4. View history
cmem log my_project auth_service
# 5. ASCII DAG
cmem graph my_project auth_service
# 6. Wire up Claude to do all of this automatically
cmem install-claude my_project /path/to/project/root
Non-interactive use (for Claude)
Claude uses --file and --trigger/--notes to checkpoint without opening an editor:
cat > /tmp/snap.toml << 'EOF'
[state]
description = "Auth now uses JWT instead of session tokens"
key_files = ["auth/views.py", "auth/middleware.py"]
behavior = "Stateless JWT. Tokens expire in 24h. Refresh via /auth/refresh/."
open_questions = []
EOF
OLD=$(cmem head my_project auth_service | head -1)
cmem snapshot my_project auth_service --file /tmp/snap.toml
NEW=$(cmem head my_project auth_service | head -1)
cmem transition my_project auth_service $OLD $NEW \
--trigger refactor \
--notes "Switched to JWT to support stateless horizontal scaling"
Write CLAUDE.md into a project
cmem install-claude my_project /path/to/project/root
This writes a CLAUDE.md file instructing Claude to autonomously checkpoint components after every meaningful change — no user prompting required. Works with any project, any language.
Commands
| Command | Description |
|---|---|
cmem init <project> <component> |
Create new component graph |
cmem snapshot <project> <component> [--file] |
Append new snapshot node |
cmem transition <project> <component> <from> <to> [--trigger] [--notes] [--file] |
Record a transition edge |
cmem log <project> <component> |
Print DAG history with transition notes |
cmem show <project> <component> <node> |
Show a specific snapshot |
cmem head <project> <component> |
Print current HEAD node |
cmem list |
List all projects and components |
cmem graph <project> <component> |
ASCII DAG visualization |
cmem install-claude <project> <path> |
Write CLAUDE.md into project root |
Configuration
| Env var | Default | Description |
|---|---|---|
CMEM_ROOT |
~/.claude/memory |
Root directory for all memory files |
Transition triggers
bug_fix · feature · refactor · discovery · breaking_change
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cmem_cli-0.1.1.tar.gz.
File metadata
- Download URL: cmem_cli-0.1.1.tar.gz
- Upload date:
- Size: 14.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a8934bb1a63c5c939b380aa8d1bbf7f17c4af2c097417a02c1c884ed9ee4654
|
|
| MD5 |
3e8a5bc3a98a92a36b2336236c54f7d5
|
|
| BLAKE2b-256 |
0dd0e9e74783a069112fb2069128b6e7d584d6c7ca1cca6a3e554fb9be514a6a
|
File details
Details for the file cmem_cli-0.1.1-py3-none-any.whl.
File metadata
- Download URL: cmem_cli-0.1.1-py3-none-any.whl
- Upload date:
- Size: 14.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
54564907caf869e06fa212a92f6373049ac598ce53a5be839d4fb7e316db876e
|
|
| MD5 |
29e90518b31290c1191e711e609b5c9c
|
|
| BLAKE2b-256 |
694f0b496c2160fab8993c58777f5e1d98a30140e0b2bc249d0de020cd888ce5
|