{"id":51219449,"url":"https://github.com/seangsisg/claude-code-backup","last_synced_at":"2026-06-30T08:00:26.429Z","repository":{"id":366907027,"uuid":"1278427792","full_name":"seanGSISG/claude-code-backup","owner":"seanGSISG","description":"Automatic backup of all Claude Code settings (incl. WSL stores from Windows) to GitHub, with cross-OS restore","archived":false,"fork":false,"pushed_at":"2026-06-24T03:15:34.000Z","size":1985,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-28T06:25:05.296Z","etag":null,"topics":["ai","anthropic","backup","claude","claude-code","cli","cross-platform","developer-tools","dotfiles","linux","macos","mcp","nodejs","restore","settings","skills","sync","windows","wsl"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/seanGSISG.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"ROADMAP.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-23T19:28:01.000Z","updated_at":"2026-06-24T03:15:30.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/seanGSISG/claude-code-backup","commit_stats":null,"previous_names":["seangsisg/claude-code-backup"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/seanGSISG/claude-code-backup","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seanGSISG%2Fclaude-code-backup","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seanGSISG%2Fclaude-code-backup/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seanGSISG%2Fclaude-code-backup/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seanGSISG%2Fclaude-code-backup/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/seanGSISG","download_url":"https://codeload.github.com/seanGSISG/claude-code-backup/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/seanGSISG%2Fclaude-code-backup/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34916411,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-29T02:00:05.398Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","anthropic","backup","claude","claude-code","cli","cross-platform","developer-tools","dotfiles","linux","macos","mcp","nodejs","restore","settings","skills","sync","windows","wsl"],"created_at":"2026-06-28T06:03:52.207Z","updated_at":"2026-06-29T07:00:56.087Z","avatar_url":"https://github.com/seanGSISG.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/seanGSISG/claude-code-backup/main/.media/image.png\" alt=\"Claude Code Backup — back up and transport your Claude settings across Windows, WSL, Linux \u0026 macOS\" width=\"640\"\u003e\n\u003c/p\u003e\n\n# Claude Code Backup\n\nAutomatic backup of all your Claude Code settings to GitHub. One command to set up, then it runs on boot/logon and every few hours. Works on **Linux, macOS, and Windows 11**.\n\n## What gets backed up\n\nEverything Claude Code stores across your machine, not just `~/.claude/`:\n\n- **Memories** (across every scope)\n- **Skills** (full directories, recursively)\n- **MCP server configs** (every `.mcp.json`, `.claude.json`, settings-embedded servers)\n- **Rules, Agents, Commands** (`.md` files)\n- **CLAUDE.md files** (global + every project, including `.claude/CLAUDE.md`)\n- **Settings** (`settings.json`, `settings.local.json`, project `.claude/` settings)\n- **Plans** (`.md` files)\n- **Sessions** (`.jsonl` conversation files)\n- **Plugins** (cached plugin directories)\n\nIt uses the same scanner as [Claude Code Organizer](https://github.com/mcpware/claude-code-organizer) to discover items across all scopes (global + every project directory you've ever opened Claude Code in).\n\n## Multiple environments (Windows + WSL)\n\nWindows-native Claude Code and Claude Code running inside WSL are **separate\ninstalls** with separate `~/.claude` stores that never merge. When you run a\nbackup on Windows, it automatically discovers your WSL distros (via `wsl.exe`),\nreads each distro's `~/.claude` over the `\\\\wsl.localhost\\\u003cdistro\u003e\\…` share, and\nbacks them up alongside the Windows store as distinct environments:\n\n```\nlatest/win-DESKTOP/…          ← Windows-native store\nlatest/wsl-Ubuntu-DESKTOP/…   ← WSL Ubuntu store\n```\n\nInteractive runs (`init`, `run`) wake a stopped distro briefly to back it up;\nscheduled background runs leave stopped distros asleep and capture WSL only when\nit's already running.\n\n## One repo, many machines\n\nA single private repo holds **every machine you back up** — each environment\nlives under its own `latest/\u003cenvId\u003e/` folder, where `envId` is\n`\u003ckind\u003e[-\u003cdistro\u003e]-\u003cuuid8\u003e` (the first 8 hex of a per-machine UUID stored locally\nin `~/.claude-backups/machine-id.json`, never committed), so machines with the\nsame hostname never collide:\n\n```\nlatest/win-550e8400/…           ← machine 1, Windows store\nlatest/wsl-Ubuntu-550e8400/…    ← machine 1, WSL store\nlatest/mac-a1b2c3d4/…           ← machine 2, macOS store\n```\n\nThe **first machine** creates the repo; **later machines join** by cloning it,\nand each `run` only rewrites its own env folders (and `git pull --rebase`es\nbefore pushing), so machines never overwrite each other's backups. If a run\nwould overwrite an env dir owned by a different machine's UUID, it aborts rather\nthan clobber it (`--confirm-collision` to override).\n\n## Security \u0026 secrets\n\nThis backup is intentionally **complete and restorable**, so it keeps real\nsecrets — MCP server keys (command/args/env), `settings.local.json`, `.claude.json`,\nand session transcripts. Nothing is silently dropped. Therefore:\n\n- **Always use a PRIVATE repo.** Pushing to a public GitHub remote is **blocked**\n  unless you pass `--allow-public`. `status` re-checks and reports the remote's\n  visibility every time; a non-GitHub remote can't be verified, so it's treated\n  as **unknown** and you should confirm it's private yourself.\n- Each `run` does a quick **secret scan** of what it just backed up and prints a\n  one-line reminder if anything looks like a key/token — a nudge to keep the\n  repo private, not a blocker.\n- **If your backup repo was ever exposed** (public, or a leaked clone), rotate\n  the affected credentials: regenerate MCP server API keys/tokens, and rotate any\n  tokens stored in `settings.local.json` / `.claude.json`.\n\n### Keeping machines separate (optional, local config)\n\nThree optional files in `~/.claude-backups/` are **local to each machine** and\nnever committed:\n\n- **`exclude.json`** — keep things out of *this* machine's backup entirely\n  (e.g. personal projects off a work machine, or drop sessions/`settings.local.json`):\n  `{ \"excludeCategories\": [\"session\"], \"projectFilter\": { \"mode\": \"exclude\", \"patterns\": [\"*personal*\"] } }`.\n- **`sync-config.json`** — declare **sync groups** of machines that may share\n  config. Once any group exists, `restore` refuses to copy one machine's config\n  onto another unless they share a group (prevents leaking work config to home).\n  With no file present, cross-machine restore works as usual.\n- **`machine-id.json`** — this machine's stable identity (UUID, label, role);\n  created automatically. Never share or copy it between machines.\n\nWhen restoring, you can also filter per run: `--exclude-labels sensitive`\n(drops MCP/sessions/`settings.local.json`), `--only-categories skill,agent`,\n`--exclude-categories session`, etc.\n\n## Quick start\n\n```bash\nnpx @seangsisg/claude-code-backup init\n```\n\nThis walks a guided script:\n1. Discover your environments (Windows-native + any WSL distros) and show what it found\n2. Ask this machine's **label** and **role** (work/home/shared) — shown wherever machines are listed\n3. On Windows, ask **which WSL distros** to back up (default: all; the choice is honored by every later run)\n4. Ask whether this is your **first machine** (creates a private repo — via the [`gh` CLI](https://cli.github.com/) if available, else asks for a URL) or **joining an existing backup** (clones the repo another machine already uses)\n5. Confirm a **private-repo acknowledgment** when the remote is public or its visibility can't be verified (backups hold secrets)\n6. Ask your backup interval from a menu (1h / 4h / 8h / 24h / manual)\n7. Install or update a scheduled job — systemd timer (Linux), LaunchAgent (macOS), or Task Scheduler task (Windows) — unless you chose manual\n8. Offer to run the first backup immediately\n\n## Manual backup\n\n```bash\nnpx @seangsisg/claude-code-backup run\n```\n\n## Check status\n\n```bash\nnpx @seangsisg/claude-code-backup status            # single-screen: remote, branch sync, machines, warnings\nnpx @seangsisg/claude-code-backup status --verbose  # also prints the raw scheduler output\n```\n\n## List machines \u0026 diagnose\n\n```bash\nnpx @seangsisg/claude-code-backup list      # every machine/env in the backup, with counts + last-backup age\nnpx @seangsisg/claude-code-backup doctor    # health check: repo, remote visibility, scheduler, freshness, index\n```\n\n## Remove scheduler\n\n```bash\nnpx @seangsisg/claude-code-backup uninstall\n```\n\nThis only removes the scheduled task. Your backup data stays in `~/.claude-backups/`.\n\n## How it works\n\n```\n~/.claude-backups/\n├── .git/                       ← tracked by git, pushed to your private repo\n├── .gitignore\n├── .gitattributes              ← marks all files binary (no line-ending rewrites)\n├── latest/\n│   ├── win-DESKTOP/            ← one dir per environment (omitted when there's only one)\n│   │   ├── env.json            ← environment identity (kind, home, osPlatform)\n│   │   ├── manifest.json       ← per-item originalPath/repoRoot/isDir (drives restore)\n│   │   ├── backup-summary.json\n│   │   ├── global/\n│   │   │   ├── memory/  skill/  mcp/  config/  rule/  plan/  agent/  command/  plugin/\n│   │   │   └── …\n│   │   └── C--Users-you-myproject/\n│   │       ├── memory/  skill/  config/\n│   │       └── session/        ← conversation history\n│   ├── wsl-Ubuntu-DESKTOP/     ← WSL store, same structure\n│   │   └── …\n│   └── backup-summary.json     ← top-level index of all environments\n├── config.json\n└── backup.log\n```\n\nEvery backup uses the per-environment layout (`latest/\u003cenvId\u003e/…`), even on a\nsingle machine, so machines can share one repo without colliding. Each `run`\nrewrites only its own env folders, so git tracks just the diff — your git\nhistory is your version history. Files are committed byte-for-byte\n(`core.autocrlf=false` + `.gitattributes`), so restores match the originals\nexactly on every platform.\n\n\u003e On Windows, `~/.claude-backups/` resolves to `%USERPROFILE%\\.claude-backups`.\n\n## Restore\n\n```bash\ngit clone \u003cyour-backup-repo\u003e ~/.claude-backups   # on the new machine\nnpx @seangsisg/claude-code-backup restore             # dry-run: shows exactly what would be written\nnpx @seangsisg/claude-code-backup restore --apply     # perform the restore\nnpx @seangsisg/claude-code-backup restore --interactive  # guided: pick source → dest → preview → confirm\n```\n\nRestore reads each environment's `manifest.json` and maps every file back to its\nreal location on the current machine. It handles:\n\n- **Same machine / new username** — rewrites the home prefix.\n- **Cross-OS** — translates path separators and **re-encodes** project-dir names\n  (e.g. a Linux backup's `-home-you-app` becomes `C--Users-you-app` on Windows).\n- **Restoring into WSL from Windows** — writes through the `\\\\wsl.localhost\\…` share.\n- **MCP configs** — merged into the destination's host JSON; an existing,\n  differing server is **skipped** unless you pass `--force`.\n- **Conflict preview** — if a destination file (or anything inside a backed-up\n  folder) was modified *after* the backup was taken, restore flags it as a\n  conflict. In dry-run it's listed; `--apply` **aborts** rather than overwrite\n  newer local edits unless you pass `--force`. (Detection is mtime-based, so it\n  can't compare across machines whose clocks differ — the dry-run default and\n  `--force` keep you in control.)\n\nFlags: `--from \u003cenvId\u003e` / `--to \u003cenvId\u003e` choose source/destination environments\n(defaults match by OS kind); `--scope \u003cid\u003e` restores a single scope; `--force`\noverwrites conflicts/MCP servers; `--verbose` lists skipped items. Restore is\n**dry-run by default**, refuses to write outside the destination home, never\ntouches enterprise-managed dirs, and renames any overwritten file to `*.bak` first.\n\n## Scheduler details\n\n**Linux (systemd):** User-level timer with `Persistent=true`. Runs on boot (5 min delay) and at your configured interval. Catches up missed runs if the machine was off.\n\n**macOS (launchd):** LaunchAgent with `RunAtLoad=true`. Same behavior.\n\n**Windows (Task Scheduler):** A task named `ClaudeCodeBackup`, registered via `schtasks`. Runs at logon (5 min delay) and repeats at your configured interval, with \"start when available\" so missed runs catch up — the same behavior as `Persistent`/`RunAtLoad`. It runs as the current user at the lowest privilege level, so `init` needs **no administrator elevation**. Inspect or remove it from the Task Scheduler GUI, or:\n\n```powershell\nschtasks /Query  /TN ClaudeCodeBackup /V /FO LIST   # inspect\nschtasks /Run    /TN ClaudeCodeBackup               # run now\nschtasks /Delete /TN ClaudeCodeBackup /F            # remove\n```\n\n## Requirements\n\n- Node.js 18+\n- Git\n  - On Windows, use [Git for Windows](https://git-scm.com/download/win); its bundled OpenSSH handles SSH remotes. Long paths are handled automatically via `core.longpaths`.\n- A GitHub repo. The [`gh` CLI](https://cli.github.com/) (if installed and authenticated) creates a private one for you during `init`; otherwise create one first and provide its URL (SSH or HTTPS).\n- For WSL backup: WSL 2 with the `\\\\wsl.localhost` (or legacy `\\\\wsl$`) share — standard on Windows 10 2004+ / Windows 11.\n\n## Built with\n\nScanner extracted from [@mcpware/claude-code-organizer](https://github.com/mcpware/claude-code-organizer).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseangsisg%2Fclaude-code-backup","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fseangsisg%2Fclaude-code-backup","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fseangsisg%2Fclaude-code-backup/lists"}