mmemsaga
Version control for Claude Code

Your AI agent's memory, kept as history.

Claude Code writes what it learns about you and your projects into files, next to your instructions and skills. None of it has history. memsaga commits every change to a git repository you own, names each commit after the conversation that made it, and brings back the edits you make anywhere else.

Free and open source (MIT) · macOS and Linux · your data stays in your own repository

Background

How Claude Code remembers

Two kinds of Markdown files, both on your machine. Auto memory and your global CLAUDE.md have no history, and live only on the machine that wrote them; a CLAUDE.md inside a repository is versioned with that repository. Anthropic's docs

CLAUDE.md

You write it, or Claude does when you ask ("add this to CLAUDE.md"): ~/.claude/CLAUDE.md for every project, and CLAUDE.md in a repository. Loaded whole in every session.

Auto memory

Claude Code's own name for the notes Claude writes: when you ask it to remember something, and on its own from your corrections. A MEMORY.md index and one file per memory, under ~/.claude/projects/<project>/memory/. The index is loaded in every session, each memory file when Claude needs it.

An example

you:     Remember that the API
         tests need a local Redis.
Claude:  writes api_tests.md
         Saved 1 memory

you:     No, we only deploy on
         Fridays, from a git tag.
Claude:  decides to keep it,
         writes deploy_rules.md
         Saved 1 memory

Next week a session loads the index and reads these files when they matter. A later session can also rewrite them, with no way back.

See it

Every change, and the conversation behind it

Find the conversation behind any change

Each commit carries the session's title and ID. Go from a line in CLAUDE.md to the conversation that wrote it, or from a conversation to everything it changed, and reopen it with claude --resume.

git log -S 'run the tests first'
git log --grep 'Session-Title: .*login'

Recorded on example data. The same history on GitHub

Who it is for

Anyone whose Claude Code knows things worth keeping

Claude Code is used for more than code. If it keeps notes for you, the notes deserve a history.

You write code across many projects
"Why is this rule in CLAUDE.md, and who added it?"

git blame names the commit, and the commit names the conversation. Undo a bad edit with memsaga restore, after reading the diff.

You write, research or plan with Claude
"It rewrote my style guide. What did it say on Monday?"

Your instructions, the facts Claude saved about your work, and any file you point memsaga at, such as ~/notes/plan.md, are kept like drafts of a manuscript. Every earlier draft is still there.

You work on two machines, or two accounts
"I taught it this on my laptop. Does my desktop know?"

Memory, skills and hooks reach the other machine the next time you use Claude there. A work account and a personal account each keep their own folder in one repository.

You let Claude tidy its own memory
"Merge the duplicates, drop what is stale. I will review."

The clean-up lands as ordinary commits under one conversation. Keep what helps, and roll back the rest with memsaga restore --all.

What goes in

One repository, filled from three places

Nothing moves. Claude Code keeps reading and writing its files where it always has, and memsaga keeps every version of them.

1

Claude Code's config directory

What Claude Code reads and writes in ~/.claude, in every account you run.

CLAUDE.mdmemoryskillssubagentscommandshooksmods, if you add them
2

Files elsewhere that you choose

A plan in your home directory, a notes file, another tool's config. Whoever edits it, you or Claude, the change is committed.

notesplansother tools' configs
3

Content only in the repository

It is a normal git repository. Add your own notes, translations of other repositories' docs, anything. memsaga commits it and never deletes it.

notescompanion docsanything you add
How it runs

On its own, after every reply

There is nothing to remember to run. The work happens in the background and takes well under a second.

  1. Claude changes a file

    A memory, CLAUDE.md, a skill, or a file you listed.

  2. The reply ends

    Everything that changed becomes one commit, named after the conversation.

  3. It is pushed

    To your private GitHub repository, at most every ten minutes and when the session ends.

  4. Your other machine has it

    The next time you start a session there, or a prompt or two later in one already open.

Two-way sync

Fix a memory from your phone

The repository syncs both ways. An edit made on GitHub, on another machine or in the local copy reaches the file Claude reads. A conversation that already read the old text is told what changed.

  1. On your phone · GitHub
    memories / claude / memory / HOME-git-webapp / deploys.md
    Staging deploys on merge to main.
    Production deploys from a tag.
    Production deploys every Friday from a tag.
    Commit changes

    You correct a memory in GitHub's web editor.

  2. On your laptop · next session or prompt
    ~/.claude/projects/…/memory/deploys.md
    Staging deploys on merge to main.
    Production deploys every Friday from a tag.
    ↓ from GitHub

    memsaga writes the edit into the file Claude reads. Lines you changed on the laptop meanwhile are kept too.

  3. In Claude Code
    How does webapp deploy to production?
    Read deploys.md
    Every Friday, from a git tag.

    Claude reads the file and answers from your correction. Had it already read the old text, it would be told what changed.

The same thing, in a real session

Just before this session, deploys.md was edited on GitHub. Asked how webapp deploys, Claude reads the file and answers from the new text.

Changed the same line in both places? Nothing is overwritten: memsaga leaves both versions as they are and tells you, so you can pick one. How two-way sync works

Companion docs

Notes that belong with a repository, but not in it

A translation of a project's docs, your annotated copy of a design, a draft written before the real document exists. Some notes must not be committed to the repository they are about, for example when it belongs to your employer or a client. Ask Claude for one, in any language, and it is filed in your data repository under the source's own path.

~/git/webappthe project · not yours to commit to
  • docs/
  • architecture.md
  • review-process.md
  • README.md
companion/webappin your data repository
  • _notes/
  • pr-2107-review.md note
  • docs/
  • architecture.zh-tw.md translation
  • new-design.zh-tw.md draft, no source yet
/companions webapp
stable  webapp/_notes/pr-2107-review.md    ~ docs/review-process.md, acme/webapp#2107
stable  webapp/docs/architecture.zh-tw.md  <- ~/git/webapp/docs/architecture.md
draft   webapp/docs/new-design.zh-tw.md    (no source yet)

Ask in your own words

The companion-docs skill starts when you ask for a version of a document in another language (中文版, 日本語版, en français) or for a note about a repository. Claude writes it at the path that mirrors the source.

Found again by its path

Before Claude summarises or translates a document, it checks whether a companion exists, so the next conversation builds on the last one instead of starting over.

Drafts before the source

Write a design in your own language first. It waits at the path the real document will have, marked as a draft.

One list of them all

The companions skill adds /companions to Claude Code; memsaga companions prints the same list in a terminal: status, path and source.

Both skills come with memsaga install --skills. Companions are committed, pushed and synced like everything else, so you can read them on GitHub from anywhere. These three, in the example repository

Built to be trusted

It keeps history. It does not take over.

Your files stay where they are

The repository holds copies. memsaga writes Claude's files only when you restore one, or when an edit you made elsewhere arrives.

Every version can come back

Restore one file, or all of them, from any point in history. A restore shows the diff and waits for your yes. No git needed: after memsaga install --skills, ask Claude what CLAUDE.md or a memory file said last week.

It stays out of Claude's way

If something fails, Claude Code carries on as usual, and memsaga status tells you what happened.

What you add stays

Files you put in the repository yourself are committed and never removed by memsaga.

Credential files stay out

Not copied: ~/.claude.json, credentials, transcripts and caches. settings.json only if you ask. The files that are copied are not scanned, so keep secrets out of them.

You own the repository

Plain git, on your disk and in your own private GitHub repository. No service to sign up for, no telemetry.

Install

Set it up once

Easiest: let Claude Code do it. Paste this prompt into Claude Code. It checks what you have, then runs the steps below and asks before each one, including where the data repository goes. It follows INSTALL-WITH-CLAUDE.md.

Claude Code prompt
Install memsaga for me. Follow
https://raw.githubusercontent.com/grimmerk/memsaga/main/INSTALL-WITH-CLAUDE.md
and ask me before each step that changes my machine.

Or by hand, running the terminal commands one at a time:

  1. The installer puts a prebuilt memsaga in ~/.cargo/bin, for Macs (Apple silicon and Intel) and Linux (x86_64 and arm64), and adds that folder to your PATH for new terminals: open one before the next step. With Homebrew instead (macOS or Linux): brew install grimmerk/tap/memsaga, on your PATH at once. You need git. To build from source instead (Rust 1.88 or later): cargo install memsaga --locked from crates.io, or cargo install --git https://github.com/grimmerk/memsaga memsaga --locked for the latest main.
  2. init creates the data repository and replays the edits your recent conversations recorded, so the history starts weeks back. It is a folder named memories inside the first of ~/git, ~/code, ~/src, ~/Projects and ~/dev that exists (for example ~/git/memories), or ~/memories when none of them does; an existing memsaga repository named memories in one of those places is used first. --repo picks another place, and --dry-run shows the choice first. A project to keep out entirely, such as client work, goes in exclude_projects before init, since what init commits stays in the history (step 2 of the README).
  3. install connects memsaga to Claude Code. With --skills, Claude can also answer questions about the history.
  4. gh repo create is optional. With a private GitHub repository, pushes and two-way sync happen on their own.

A second machine for a data repository you already have? Follow Setting up another machine instead; running init there would start a second, separate history.

Keep the data repository private. Memory holds whatever Claude learned while working with you, which often includes details of your work.

terminal · one command at a time
$ curl --proto '=https' --tlsv1.2 -LsSf \
https://github.com/grimmerk/memsaga/releases/latest/download/memsaga-installer.sh | sh# then open a new terminal (or run: source ~/.cargo/env)# or, with Homebrew instead of the two lines above:$ brew install grimmerk/tap/memsaga$ memsaga init --dry-run   # what would be imported$ memsaga init$ memsaga install --skills$ gh repo create memories --private --push \
    --source "$(memsaga repo)"   # optional: a private remote$ memsaga status
# to try it on example data first (after the install line):# your real Claude Code config is never read or written;# open a new terminal afterwards to leave the demo$ git clone https://github.com/grimmerk/memsaga$ memsaga/demo/setup.sh && source /tmp/memsaga-demo/env.sh
Out of scope

What memsaga leaves alone, and what to use instead

WhatWhy it is left outInstead
Conversation transcriptsLarge, and mostly your work rather than configurationRaise cleanupPeriodDays in settings.json to keep them longer
Marketplace pluginsPackages you can install again, not files you wroteInstall them again; a mirrored settings.json lists which
Credentials and login stateSecrets must never enter a repositoryYour system keychain or a password manager
Fast-changing settings (model, effortLevel)Rewritten on every /model and /effortNothing: each machine keeps its own

Status: early, in daily use by its author on macOS, tested in CI on Linux. Claude Code is the only agent today; others are on the roadmap.