Never lose your Claude Code work — memories, rules, and code, backed up automatically.
Claude Code quietly builds up things you'd hate to lose:
- its memories (
~/.claude/projects/*/memory/) — knowledge it accumulates over months, - your growing
CLAUDE.md— your rules and hard-won context, - files it generates, and code spread across many repos.
By default none of it is backed up. One disk failure, one bad edit, or one forgotten unpushed branch = lost work. memvault makes that impossible, without you thinking about it:
- Code → stays in git (private repos, pushed).
- Everything else durable (memories, notes, generated files) → mirrored to your cloud drive, and on to your NAS.
- A quiet watchdog warns you the moment code isn't pushed or something lands in the wrong place.
- Claude Code, any project.
- macOS (the clever bit below is macOS-specific; it also runs on Linux, even more simply).
- Any cloud drive that syncs a local folder — Google Drive, iCloud, Dropbox, or an rclone mount. If your cloud mirrors to a NAS (e.g. Synology Cloud Sync), your work lands on your own hardware too.
git clone https://github.com/Beennnn/memvault.git && cd memvault
cp config.example.sh config.sh # set your cloud folder (VAULT_DIR)
./install.sh # idempotent — safe to re-runOr just open Claude Code in the repo and say “set up memvault for me” — it reads its own
CLAUDE.md and installs itself.
Everything you touch is sorted into 3 tiers, each with one backup path:
| Tier | What | Where | Backup |
|---|---|---|---|
| 1 | Code | ~/dev/ — git repos only, private, pushed |
the git remote |
| 2 | Everything durable non-code | your cloud vault | cloud → NAS |
| 3 | The rest (transcripts, cache…) | ~/.claude/ — disposable |
none needed |
Memories and CLAUDE.md must live in tier 3 (Claude reads them there) but are durable — so
they stay local and are mirrored to the vault. That mirroring runs from Claude Code hooks:
| When | Hook | Does |
|---|---|---|
| The instant a memory is written | PostToolUse |
mirror it now — a long response never waits |
| After every response | Stop |
on-the-fly backup |
| At session start | SessionStart |
catch-up + mirror your repo hierarchy into the vault + move any stray non-git into its matching group folder |
| Between sessions | launchd watchdog |
passively flag unpushed repos / stray files (notification) |
The vault mirrors your code tree. memvault keeps the vault's top-level structure in step with
~/dev (same groups — music/, work/, …). A non-git file that drifts into ~/dev/music/ is
moved to vault/music/, so your durable files are organized exactly like your repos, and both
sides evolve together. Files loose at the ~/dev root (no group) go to vault/_relocated/.
Nothing is ever deleted.
The obvious way to back up to your Drive is a scheduled job (cron/launchd). On macOS it
doesn't work: the privacy system (TCC) blocks background jobs from writing to cloud
folders —
rsync: … /Google Drive/…: open: Operation not permitted
— unless you grant Full Disk Access to /bin/bash, which hands every shell script on your
machine access to all your private data. Bad trade.
memvault's trick: do the backup from a Claude Code hook. A hook runs inside Claude Code, which already has Full Disk Access — so it can write the vault with no new permission and no new risk. The launchd watchdog stays permission-less on purpose: it only reads local git state and flags; the hooks do the writing.
Full design + the TCC/FDA deep-dive: docs/architecture.md.
Set SURVEY_ROOTS="$HOME" and a SessionStart hook scans (once/day) for anything not backed
up — durable files outside every backed-up zone and git repos anywhere that are uncommitted or
unpushed. It only reports, grouped by folder; Claude then asks you, per finding, which
strategy to use: (a) relocate into the vault, (b) have your cloud
client back the folder up in place (great for ~/Downloads, ~/Desktop, ~/Documents), or
(c) symlink a fixed-location folder into the vault. Add folders your cloud already mirrors to
BACKED_UP_ZONES so they stop being flagged.
What the survey treats as "not user data" comes from two community lists —
rules/ignore-dirs.txt and
rules/ignore-paths.txt — that anyone can extend by PR.
Set AUTO_PUSH=true and the watchdog + relocator push your repos automatically (git push is
network-only, so it works from launchd):
- committed work on a non-protected branch →
origin/<branch>(main/master are skipped, to honour "never push to main directly"); - uncommitted work (tracked + untracked) → snapshotted to
refs/backup/<branch>without touching your working tree — a custom ref, so no CI is triggered and no branch clutters your repo, yet it's fully recoverable:git fetch origin 'refs/backup/*:refs/backup/*' git log refs/backup/<branch> # inspect / checkout / cherry-pick
Set GIT_SSH_KEY to your key so launchd (which has no ssh-agent) can push over SSH.
memvault gets smarter as people feed back the special cases they hit on real machines — usually a one-line addition to a rules file. See CONTRIBUTING.md. The golden rule: never add anything that could hide irreplaceable user data, and relocations are quarantine-only (nothing is ever deleted).
MIT — see LICENSE.