{"id":51034796,"url":"https://github.com/andrewle8/claude-code-sync","last_synced_at":"2026-06-22T04:30:47.185Z","repository":{"id":361288914,"uuid":"1177263866","full_name":"andrewle8/claude-code-sync","owner":"andrewle8","description":"Sync Claude Code CLI config across machines with Syncthing. Whitelist-based .stignore for selective sync of CLAUDE.md, skills, agents, memory, and rules across macOS, Linux, and Windows.","archived":false,"fork":false,"pushed_at":"2026-05-29T23:27:51.000Z","size":14,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-30T01:13:39.437Z","etag":null,"topics":["claude-code","cross-platform","dotfiles","syncthing"],"latest_commit_sha":null,"homepage":null,"language":null,"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/andrewle8.png","metadata":{"files":{"readme":"README.md","changelog":null,"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":null,"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-03-09T21:27:57.000Z","updated_at":"2026-05-29T23:27:54.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/andrewle8/claude-code-sync","commit_stats":null,"previous_names":["andrewle8/claude-code-sync"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/andrewle8/claude-code-sync","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewle8%2Fclaude-code-sync","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewle8%2Fclaude-code-sync/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewle8%2Fclaude-code-sync/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewle8%2Fclaude-code-sync/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andrewle8","download_url":"https://codeload.github.com/andrewle8/claude-code-sync/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andrewle8%2Fclaude-code-sync/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34635032,"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-22T02:00:06.391Z","response_time":106,"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":["claude-code","cross-platform","dotfiles","syncthing"],"created_at":"2026-06-22T04:30:44.904Z","updated_at":"2026-06-22T04:30:47.170Z","avatar_url":"https://github.com/andrewle8.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Claude Code Sync\n\nSync your [Claude Code](https://claude.com/claude-code) CLI config across machines with [Syncthing](https://syncthing.net/). macOS, Linux, Windows.\n\nClaude Code has no built-in sync (as of March 2026). This repo has a tested `.stignore` whitelist that syncs only the portable config files and skips runtime data.\n\n## What Syncs\n\n| Path | What |\n|------|------|\n| `CLAUDE.md` | Global instructions, loaded every conversation |\n| `skills/` | Custom slash commands (`/ship`, `/sync`, etc.) |\n| `agents/` | [Subagent](https://code.claude.com/docs/en/sub-agents) definitions |\n| `agent-memory/` | Persistent subagent memory (user scope) |\n| `rules/` | User-level [rules](https://code.claude.com/docs/en/memory) applied before project rules |\n| `keybindings.json` | Custom [keybindings](https://code.claude.com/docs/en/keybindings) |\n| `statusline.js` | Cross-platform Node.js statusline script (see note below) |\n| `memory/` | Global memory files |\n| `commands/` | Legacy commands (use `skills/` instead) |\n| `projects/*/memory/` | Per-project memory (MEMORY.md + topic files) |\n| `projects/*/CLAUDE.md` | Per-project instructions |\n| `CLAUDE.md.bak-*` | CLAUDE.md backups |\n\n## What Does NOT Sync\n\n| Path | Why |\n|------|-----|\n| `settings.json` | Per-machine plugins, env vars, MCP servers |\n| `settings.local.json` | Per-machine permissions |\n| `.credentials.json` | Auth tokens |\n| `history.jsonl` | Session transcripts (large) |\n| `plans/`, `tasks/`, `todos/` | Session-bound state |\n| `plugins/`, `teams/` | Per-machine runtime |\n| `statusline.sh` | OS-specific shell commands (use cross-platform `statusline.js` instead) |\n| `cache/`, `debug/`, `downloads/` | Runtime data |\n| `file-history/`, `backups/` | Auto-generated snapshots |\n| `session-env/`, `shell-snapshots/` | Ephemeral state |\n| `usage-data/`, `telemetry/` | Analytics (can be huge) |\n| `ide/`, `chrome/`, `paste-cache/` | Tool runtime |\n| `projects/**/*.jsonl`, `*.meta.json` | Conversation logs |\n| `projects/**/subagents/`, `tool-results/` | Subagent runtime |\n\n### Statusline note\n\n`statusline.js` syncs, but `settings.json` does not — so on each new machine you must also add this block to `~/.claude/settings.json` once:\n\n```json\n\"statusLine\": { \"type\": \"command\", \"command\": \"node ~/.claude/statusline.js\" }\n```\n\nThe script is portable across macOS, Linux, and Windows. Requires Node.js on PATH.\n\n## Setup\n\n### Prerequisites\n\n- [Syncthing](https://syncthing.net/) on all machines\n- [Claude Code CLI](https://claude.com/claude-code) on all machines\n\n### 1. Copy `.stignore` to every machine\n\nPut this at `~/.claude/.stignore`. Syncthing does **not** sync its own `.stignore`, so you need to copy it manually to each machine.\n\nA copy is in this repo: [`.stignore`](.stignore)\n\n```\n// Syncthing ignore file for ~/.claude/\n// Whitelist approach: first match wins.\n// Both !/dir and !/dir/** are needed: the first un-ignores\n// the directory itself, the second un-ignores its contents.\n//\n// SAFE to sync:\n!/CLAUDE.md\n!/CLAUDE.md.bak-*\n!/skills\n!/skills/**\n!/agents\n!/agents/**\n!/agent-memory\n!/agent-memory/**\n!/keybindings.json\n!/statusline.js\n!/memory\n!/memory/**\n!/commands\n!/commands/**\n!/rules\n!/rules/**\n!/.stignore\n//\n// Block runtime data inside projects (must come before !/projects)\nprojects/**/*.jsonl\nprojects/**/*.meta.json\nprojects/**/subagents\nprojects/**/subagents/**\nprojects/**/tool-results\nprojects/**/tool-results/**\n//\n// Allow project memory and CLAUDE.md only\n!/projects\n!/projects/*\n!/projects/*/memory\n!/projects/*/memory/**\n!/projects/*/CLAUDE.md\n//\n// Block everything else\n*\n```\n\nThe `*` at the bottom blocks everything not explicitly allowed. First match wins, so the project block rules must come before `!/projects`. New directories added by future Claude Code updates are blocked by default.\n\n### 2. Add the folder in Syncthing\n\nOpen `http://127.0.0.1:8384` and add a shared folder:\n\n| Setting | Value |\n|---------|-------|\n| Folder Label | `Claude Code Sync` |\n| Folder ID | `claude-code-sync` |\n| Folder Path | `~/.claude` (macOS/Linux) or `C:\\Users\\\u003cyou\u003e\\.claude` (Windows) |\n| File Versioning | Staggered, 30 days |\n| **Ignore Delete** | **`true`** |\n| Ignore Permissions | `true` |\n| File Pull Order | `smallestFirst` |\n| Watch for Changes | `true` |\n\nOn each additional machine:\n\n1. Add the remote device\n2. Accept the `claude-code-sync` folder, set path to `~/.claude`\n3. Set **Ignore Delete** to `true`\n4. Set **Staggered Versioning**, 30 days\n5. Copy `.stignore` to `~/.claude/.stignore`\n\n### 3. Verify\n\n```bash\n# macOS\nAPI_KEY=$(grep apikey ~/Library/Application\\ Support/Syncthing/config.xml | sed 's/.*\u003e\\(.*\\)\u003c.*/\\1/')\ncurl -s -X POST -H \"X-API-Key: $API_KEY\" \"http://127.0.0.1:8384/rest/db/scan?folder=claude-code-sync\"\n\n# Linux\nAPI_KEY=$(grep apikey ~/.local/state/syncthing/config.xml | sed 's/.*\u003e\\(.*\\)\u003c.*/\\1/')\ncurl -s -X POST -H \"X-API-Key: $API_KEY\" \"http://127.0.0.1:8384/rest/db/scan?folder=claude-code-sync\"\n```\n\nCheck the other machine:\n\n```bash\nls -la ~/.claude/CLAUDE.md\nls ~/.claude/skills/*/SKILL.md 2\u003e/dev/null\n```\n\n```cmd\n:: Windows\nif exist C:\\Users\\%USERNAME%\\.claude\\CLAUDE.md echo SYNCED\n```\n\n## Key Settings\n\n### Ignore Delete\n\nSet this to `true` on **every device**. If one machine's config gets wiped (Claude Code update, accidental delete), the others keep their copies. Without this, a delete on one machine cascades everywhere.\n\n### Staggered Versioning\n\nKeeps timestamped backups of changed/deleted files in `.stversions/` for 30 days.\n\n```bash\nls ~/.claude/.stversions/\ncp ~/.claude/.stversions/CLAUDE~20260307-080132.md ~/.claude/CLAUDE.md\n```\n\n### Why settings.json is excluded\n\nEach machine needs its own `settings.json`: plugins, env vars, status line commands, and MCP server configs all differ per OS and machine. Configure it separately everywhere.\n\n## CLAUDE.md Load Order\n\n1. Managed policy (enterprise)\n2. **`~/.claude/CLAUDE.md`** (user-level, this is what we sync)\n3. `CLAUDE.md` in project root (shared via git)\n4. `CLAUDE.local.md` (git-ignored, per-machine overrides)\n\n## Project Memory: Cross-OS Caveat\n\nProject memory paths are derived from absolute filesystem paths. The same repo gets different identifiers on different OSes (`-Users-andrew-repos-myapp` on macOS vs `F--projects-myapp` on Windows). Claude Code only reads the directory matching the local path.\n\nCross-OS project memory won't carry over automatically. Still worth syncing for:\n- Same-OS machines with matching paths (works directly)\n- Disaster recovery (rebuild a machine, memory is there)\n- Manual reference across machines\n\n## Directory Layout\n\n```\n~/.claude/\n├── CLAUDE.md                    SYNCED\n├── .stignore                    MANUAL (copy to each machine)\n├── keybindings.json             SYNCED\n├── statusline.js                SYNCED (needs settings.json registration)\n├── skills/                      SYNCED\n│   ├── ship/SKILL.md\n│   └── .../\n├── agents/                      SYNCED\n├── agent-memory/                SYNCED\n├── rules/                       SYNCED\n├── memory/                      SYNCED\n├── commands/                    SYNCED (legacy)\n├── projects/                    PARTIAL\n│   └── \u003cproject\u003e/\n│       ├── memory/              SYNCED\n│       ├── CLAUDE.md            SYNCED\n│       ├── *.jsonl              blocked\n│       └── subagents/           blocked\n├── settings.json                blocked (per-machine)\n├── settings.local.json          blocked (per-machine)\n├── .credentials.json            blocked (secrets)\n├── plans/                       blocked\n├── tasks/                       blocked\n├── plugins/                     blocked\n├── cache/, debug/, ...          blocked\n├── .stfolder/                   Syncthing marker\n└── .stversions/                 Syncthing backups\n```\n\n## Troubleshooting\n\n**Files not syncing:** Check connections in the Syncthing UI. Verify `.stignore` is identical on all machines (it's not auto-synced). Trigger a rescan with the curl commands above.\n\n**Files deleted everywhere:** Check `.stversions/` for timestamped backups. Copy the file back and Syncthing will propagate it.\n\n**Sync conflict files:** Files like `settings.sync-conflict-*.json` appear when two machines edit the same file. Safe to delete.\n\n**Windows: can't find `.claude`:** It's hidden. Use `dir /a` or `if exist C:\\Users\\\u003cyou\u003e\\.claude\\NUL echo EXISTS`.\n\n## Cross-OS Paths\n\n| OS | `~/.claude` | Syncthing Config |\n|----|-------------|------------------|\n| macOS | `/Users/\u003cyou\u003e/.claude` | `~/Library/Application Support/Syncthing/config.xml` |\n| Linux | `/home/\u003cyou\u003e/.claude` | `~/.local/state/syncthing/config.xml` |\n| Windows | `C:\\Users\\\u003cyou\u003e\\.claude` | `%LOCALAPPDATA%\\Syncthing\\config.xml` |\n\n## Alternatives\n\n| Approach | Tradeoff |\n|----------|----------|\n| **Syncthing** (this repo) | Real-time, selective, P2P, encrypted. Needs Syncthing everywhere. |\n| **Dropbox/iCloud + symlinks** | Simple but no selective sync, risk of corrupting runtime files. |\n| **[CCMS](https://github.com/miwidot/ccms)** | rsync over SSH. Manual, not real-time. |\n| **[claude-code-config-sync](https://www.npmjs.com/package/claude-code-config-sync)** | npm package. Extra dependency. |\n| **Git repo** | Version controlled. Manual commit/push/pull. |\n\n## Related\n\n- **[Claude Insights Merge](https://github.com/andrewle8/claude-insights-merge)** — Merge `/insights` data across multiple machines into a single combined report. Complements this tool: Sync handles config, Insights Merge handles analytics.\n\n## Security\n\n- All transfers are TLS encrypted\n- P2P by default. Relay servers are used as fallback but data is end-to-end encrypted (relay can't read it)\n- `.credentials.json` and `settings.local.json` are blocked by the catch-all rule\n- `settings.json` is excluded too (may contain MCP API keys)\n- Check your `CLAUDE.md` for internal paths before making it public\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewle8%2Fclaude-code-sync","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandrewle8%2Fclaude-code-sync","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandrewle8%2Fclaude-code-sync/lists"}