Skip to content

ryzs/sync-claude-memory

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

sync-claude-memory

Portable, git-backed cross-machine sync for Claude Code per-project memory.

The problem: Claude Code stores memory at ~/.claude/projects/<encoded-absolute-path>/memory/. The encoded path embeds your username, so the same project resolves to a different directory on every machine. You cannot just sync ~/.claude/projects/ across devices.

This tool: decouples a stable project key from the per-machine encoded path, and symlinks the encoded memory/ directory to a shared, portable git store. Claude keeps writing where it always writes. Your machines stay in sync.

See docs/why.md for the open Claude Code GitHub issues this addresses, and docs/encoding.md for how the path encoding actually works.

What you get

  • A sync-claude-memory CLI with sync and doctor subcommands
  • Two Claude Code hooks: auto-pull on SessionStart, auto-commit + push on Stop
  • An installer that wires everything up idempotently

Install

Quick install (clones the repo to ~/sync-claude-memory for you):

curl -fsSL https://raw.githubusercontent.com/ryzs/sync-claude-memory/main/install.sh | bash

Or do it manually if you want to read the script first:

git clone https://github.com/ryzs/sync-claude-memory.git ~/sync-claude-memory
cd ~/sync-claude-memory
./install.sh

Either way produces the same result. To update later: cd ~/sync-claude-memory && git pull && ./install.sh.

Override the clone location with SYNC_CLAUDE_MEMORY_DIR=/some/path if you don't want it at ~/sync-claude-memory.

The installer:

  1. Symlinks bin/sync-claude-memory -> ~/.local/bin/sync-claude-memory
  2. Symlinks hooks/*.sh -> ~/.claude/hooks/
  3. Optionally scaffolds an empty ~/claude-memory/ git store with a starter memory-map.toml
  4. Prints the JSON snippet to paste into ~/.claude/settings.json to wire up the hooks

It does not edit your settings.json - paste the snippet yourself so you can see what changes.

Tip: if any of this is unfamiliar, just hand the install steps to Claude Code (or another AI coding assistant) running in this repo and ask it to walk you through setup. It can clone the repo, run install.sh, paste the hook snippet into your ~/.claude/settings.json, create the private memory store repo via gh, and add your first memory-map.toml entries. Try a prompt like:

"Set up sync-claude-memory on this machine. Create a private GitHub repo for my memory store, wire up the hooks in ~/.claude/settings.json, and add entries for the projects under ~/code/."

Set up your memory store

The store is a separate repo you own. Treat it as private - it contains your actual project memory, which often includes client details, internal notes, and other context you do not want public.

# 1. Create a private repo on GitHub (or your host of choice)
gh repo create my-claude-memory --private

# 2. Point the local store at it
cd ~/claude-memory          # scaffolded by install.sh
git remote add origin git@github.com:<you>/my-claude-memory.git

# 3. Edit memory-map.toml to list your projects
$EDITOR memory-map.toml

# 4. Run the sync
sync-claude-memory

memory-map.toml looks like:

[my-project]
path = "code/my-project"          # relative to $HOME

[work-thing]
path = "work/work-thing"

["dotted.project"]                # quote keys with dots
path = "code/dotted.project"

Daily workflow

With the hooks installed, you do nothing. Each Claude session pulls on start and pushes on stop. To switch machines, just open a session and the latest memory pulls before Claude reads it.

To do it manually:

sync-claude-memory          # sync + doctor (default)
sync-claude-memory sync     # symlinks only
sync-claude-memory doctor   # health-check only

Per-machine path overrides

If a project lives at different paths on different machines (code/foo on one, work/foo on another), create memory-map.local.toml beside the main map. Same TOML shape. Local entries override the main map for that machine only. The file is gitignored, so it never spreads.

# ~/claude-memory/memory-map.local.toml (this machine only)
[my-project]
path = "work/my-project"

A cleaner pattern: keep paths uniform across machines so you never need an override. Worth doing if you can.

Adding a new project

# 1. Open Claude Code in the project once (creates ~/.claude/projects/<encoded>/)
cd ~/code/my-new-thing && claude

# 2. Add an entry to the map
$EDITOR ~/claude-memory/memory-map.toml
# add:
#   [my-new-thing]
#   path = "code/my-new-thing"

# 3. Sync (migrates existing memory into the store, then symlinks)
sync-claude-memory

# 4. Commit
cd ~/claude-memory && git add . && git commit -m "add my-new-thing" && git push

Troubleshooting

Symptom Likely cause Fix
memory store not found Store dir missing Re-run install.sh and accept the scaffold prompt
store already has content for <key> Local memory exists for a project the store also tracks Inspect both, merge by hand, then re-run
Symlink looks correct but Claude isn't reading memory Project not actually at the mapped path on this machine Check $HOME/<map.path> matches reality, or add a memory-map.local.toml override
New project's memory not syncing Forgot to add to memory-map.toml Add it, run sync
Encoded directory has unexpected name Path contains /, _, or . All three encode to -. Verify: printf '%s' "<path>" | tr '/_.' '---'

How it differs from thedotmack/claude-mem

claude-mem is an in-session memory persistence plugin (tree-sitter parsers, MCP). It enriches what Claude remembers on one machine.

sync-claude-memory is a cross-machine sync layer for the per-project memory directory. It works alongside claude-mem, or alone with vanilla Claude Code.

Different problem. Different layer. Complementary.

License

MIT. See LICENSE.

About

Cross-machine sync for Claude Code per-project memory via stable project keys and symlinks

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages