{"id":47036709,"url":"https://github.com/kodrunhq/claudefy","last_synced_at":"2026-04-01T19:36:30.774Z","repository":{"id":343479247,"uuid":"1177277654","full_name":"kodrunhq/claudefy","owner":"kodrunhq","description":"Sync your Claude Code environment (~/.claude) across machines — git-backed, encrypted, automatic","archived":false,"fork":false,"pushed_at":"2026-03-29T22:53:43.000Z","size":1014,"stargazers_count":0,"open_issues_count":7,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-30T01:04:10.133Z","etag":null,"topics":["claude","claude-code","cli","developer-tools","devtools","dotfiles","encryption","multi-machine","sync","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kodrunhq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/security.md","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:52:10.000Z","updated_at":"2026-03-29T22:53:46.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/kodrunhq/claudefy","commit_stats":null,"previous_names":["kodrunhq/claudefy"],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/kodrunhq/claudefy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kodrunhq%2Fclaudefy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kodrunhq%2Fclaudefy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kodrunhq%2Fclaudefy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kodrunhq%2Fclaudefy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kodrunhq","download_url":"https://codeload.github.com/kodrunhq/claudefy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kodrunhq%2Fclaudefy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31291151,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-01T13:12:26.723Z","status":"ssl_error","status_checked_at":"2026-04-01T13:12:25.102Z","response_time":53,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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","claude-code","cli","developer-tools","devtools","dotfiles","encryption","multi-machine","sync","typescript"],"created_at":"2026-03-12T01:38:46.358Z","updated_at":"2026-04-01T19:36:30.736Z","avatar_url":"https://github.com/kodrunhq.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/npm/v/@kodrunhq/claudefy?color=blue\u0026label=npm\" alt=\"npm version\" /\u003e\n  \u003cimg src=\"https://img.shields.io/github/actions/workflow/status/kodrunhq/claudefy/ci.yml?branch=main\u0026label=CI\" alt=\"CI\" /\u003e\n  \u003cimg src=\"https://img.shields.io/node/v/@kodrunhq/claudefy\" alt=\"node version\" /\u003e\n  \u003cimg src=\"https://img.shields.io/github/license/kodrunhq/claudefy\" alt=\"license\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/TypeScript-strict-blue?logo=typescript\u0026logoColor=white\" alt=\"TypeScript\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/logo.svg\" alt=\"claudefy logo\" width=\"120\" height=\"120\" /\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eclaudefy\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eSync your Claude Code environment across every machine you work on.\u003c/strong\u003e\u003cbr/\u003e\n  Git-backed \u0026bull; Encrypted \u0026bull; Automatic\n\u003c/p\u003e\n\n---\n\nclaudefy keeps your `~/.claude` directory — CLAUDE.md, MEMORY.md, commands, skills, agents, hooks, rules, plans, plugins, settings, and project configs — in sync across all your machines through a private git repository. It also selectively syncs MCP server configurations from `~/.claude.json`. It encrypts sensitive content with AES-256-SIV, normalizes machine-specific paths, deep-merges settings, and can run fully automatically via Claude Code hooks.\n\n## Why claudefy?\n\n- **One config, every machine.** Stop manually copying files between your laptop, desktop, and servers.\n- **Safe by design.** Credentials never leave your machine. Secrets are detected and encrypted before push. Remote hooks are stripped on pull to prevent injection.\n- **Set it and forget it.** With auto-sync hooks, `pull` runs when Claude Code starts and `push` runs when it ends. No manual steps.\n- **Conflict-free.** Per-machine git branches prevent collisions. Deep merge resolves settings.json at the key level, preserving local permission rules.\n- **Preview before you sync.** `claudefy diff` shows exactly what would change. `--dry-run` on push/pull lets you verify before committing.\n\n## Quick Start\n\n**Install:**\n\n```bash\nnpm install -g @kodrunhq/claudefy\n```\n\n**First machine — initialize:**\n\n```bash\n# Point to an existing private repo\nclaudefy init --backend git@github.com:you/claude-sync.git --hooks\n\n# Or auto-create a GitHub repo\nclaudefy init --create-repo --hooks\n```\n\n**Other machines — join:**\n\n```bash\nclaudefy join --backend git@github.com:you/claude-sync.git --hooks\n```\n\nThat's it. With `--hooks`, sync is automatic from now on.\n\n**Manual sync (if you skip hooks):**\n\n```bash\nclaudefy push     # push local changes\nclaudefy pull     # pull remote changes\nclaudefy status   # see what would sync\nclaudefy diff     # preview what push/pull would change\n```\n\n## How It Works\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/architecture.svg\" alt=\"claudefy architecture\" width=\"720\" /\u003e\n\u003c/p\u003e\n\nEach machine gets its own git branch (`machines/\u003cid\u003e`). Push merges into `main`; pull merges `main` back into the machine branch. No conflicts, no data loss.\n\n## What Gets Synced\n\n| | Items | Notes |\n|---|-------|-------|\n| **Always synced** | CLAUDE.md, MEMORY.md, commands, agents, skills, hooks, rules, plans, plugins, agent-memory, projects, settings.json, history.jsonl, package.json | Core config that travels with you |\n| **Selectively synced** | `~/.claude.json` mcpServers (opt-in), theme, notification preferences | Requires `claudeJson.syncMcpServers: true` for MCP servers |\n| **Never synced** | cache, backups, file-history, shell-snapshots, paste-cache, session-env, tasks, .credentials.json, settings.local.json, statsig, telemetry, ide, debug, todos, stats-cache.json | Machine-local, ephemeral, or sensitive |\n| **Unknown** | Anything else | Synced to separate dir, always encrypted when encryption is enabled |\n\n\u003e **Note:** `settings.local.json` is hardcoded as never-synced — it cannot be overridden even with a custom allowlist. This follows Claude Code's `.local.` convention for non-shared files.\n\n## Commands\n\n### Core\n\n| Command | Description |\n|---------|-------------|\n| `claudefy init --backend \u003curl\u003e` | Initialize on the first machine |\n| `claudefy join --backend \u003curl\u003e` | Join from another machine |\n| `claudefy push` | Push local changes to remote |\n| `claudefy pull` | Pull remote changes to local |\n| `claudefy diff` | Preview what push/pull would change |\n| `claudefy override --confirm` | Wipe remote, push local as source of truth |\n| `claudefy status` | Show file classification |\n\n### Project Links\n\n| Command | Description |\n|---------|-------------|\n| `claudefy link \u003calias\u003e \u003cpath\u003e` | Map a local project path to a portable ID |\n| `claudefy unlink \u003calias\u003e` | Remove a mapping |\n| `claudefy links` | List all mappings |\n\n### Management\n\n| Command | Description |\n|---------|-------------|\n| `claudefy hooks install` | Install auto-sync hooks |\n| `claudefy hooks remove` | Remove auto-sync hooks |\n| `claudefy machines` | List registered machines |\n| `claudefy restore` | Restore from a backup |\n| `claudefy doctor` | Diagnose sync health |\n| `claudefy config get/set` | View or update config (with schema validation) |\n| `claudefy logs` | Show recent sync operations |\n| `claudefy export --output \u003cpath\u003e` | Create a portable backup archive |\n| `claudefy rotate-passphrase` | Re-encrypt all files with a new passphrase |\n| `claudefy uninstall` | Remove claudefy hooks, config, and store |\n| `claudefy completion` | Output bash/zsh/fish shell completion scripts |\n\n### Push/Pull Options\n\n| Option | Description |\n|--------|-------------|\n| `-q, --quiet` | Suppress output |\n| `--skip-encryption` | Skip encryption (testing only, prints warning) |\n| `--skip-secret-scan` | Skip secret scanning on push |\n| `--dry-run` | Preview changes without writing |\n| `--only \u003citem\u003e` | Sync only a specific item (e.g., `--only commands`) |\n| `--force` | Push: skip pull-before-push step |\n\n## Encryption\n\nclaudefy uses **AES-256-SIV** deterministic encryption via `@noble/ciphers`.\n\n- **Deterministic** — same plaintext always produces the same ciphertext, so unchanged files produce zero git diff.\n- **JSONL files** — encrypted line-by-line, preserving git's ability to diff and merge individual lines.\n- **Other files** — encrypted as whole files.\n- **Key derivation** — PBKDF2-SHA256 with 600,000 iterations. Salt is derived from the backend URL, so SSH and HTTPS URLs for the same repo produce the same key.\n\n### Encryption modes\n\n| Mode | Behavior |\n|------|----------|\n| `reactive` (default) | Only files where the secret scanner detects a match are encrypted. Unknown-tier files are always encrypted. Clean allowlisted files stay in plaintext. |\n| `full` | All files are encrypted regardless of scanner results. Maximum security, larger git diffs. |\n\nSet mode: `claudefy config set encryption.mode full`\n\n**Passphrase resolution order:**\n1. `CLAUDEFY_PASSPHRASE` environment variable (recommended)\n2. OS keychain (if configured)\n\nInteractive prompts occur during `claudefy init`, `claudefy join`, `claudefy rotate-passphrase`, and `claudefy uninstall` (unless `--confirm` is passed).\n\n\u003e See [docs/encryption.md](docs/encryption.md) for the full technical deep-dive.\n\n## Security\n\n- `.credentials.json` and `settings.local.json` are **never** synced (hardcoded deny, cannot be overridden).\n- Remote `hooks`, `mcpServers`, `env`, `permissions`, `allowedTools`, and `apiKeyHelper` keys are **stripped** from settings.json on pull — prevents code injection from the remote.\n- MCP server sync via `~/.claude.json` requires explicit opt-in (`syncMcpServers: true`). Server commands are validated for shell metacharacters and args are checked for injection patterns.\n- Path traversal protection on `@@HOME@@` sentinel expansion — resolved paths must stay within the home directory.\n- Secret scanner checks 15 built-in patterns (API keys, tokens, credentials) before push, plus user-defined custom patterns. Secrets trigger encryption; if encryption is disabled, the push is blocked.\n- Symlinks are skipped during sync and diff operations to prevent path traversal.\n- Concurrent operations are protected by a PID-based lockfile with 10-minute timeout.\n- Passphrases are never stored in plaintext on disk.\n\n\u003e See [docs/security.md](docs/security.md) for the full security model.\n\n## Configuration\n\nConfig lives at `~/.claudefy/config.json`:\n\n```json\n{\n  \"version\": 1,\n  \"backend\": { \"type\": \"git\", \"url\": \"git@github.com:you/claude-sync.git\" },\n  \"encryption\": { \"enabled\": true, \"useKeychain\": false, \"cacheDuration\": \"0\", \"mode\": \"reactive\" },\n  \"claudeJson\": { \"sync\": true, \"syncMcpServers\": false },\n  \"secretScanner\": { \"customPatterns\": [] },\n  \"backups\": { \"maxCount\": 10, \"maxAgeDays\": 30 },\n  \"machineId\": \"hostname-abc12345\"\n}\n```\n\n### Custom secret patterns\n\nAdd patterns to detect organization-specific secrets:\n\n```bash\nclaudefy config set secretScanner.customPatterns '[{\"name\":\"Internal Token\",\"regex\":\"MYCO_[A-Za-z0-9]{32}\"}]'\n```\n\n## Documentation\n\n| Document | Description |\n|----------|-------------|\n| [Architecture](docs/architecture.md) | System design, module map, data flows |\n| [Encryption](docs/encryption.md) | AES-SIV, PBKDF2, line-level encryption |\n| [Security](docs/security.md) | Threat model, hook stripping, secret scanning |\n| [Hooks \u0026 Auto-Sync](docs/hooks.md) | SessionStart/SessionEnd hooks, automatic sync |\n| [Override \u0026 Restore](docs/override-and-restore.md) | Override flow, backup system, restore |\n| [Path Mapping](docs/path-mapping.md) | Cross-machine path normalization |\n\n## Multi-Machine Workflow\n\n1. **First machine:** `claudefy init --backend \u003curl\u003e --hooks`\n2. **Other machines:** `claudefy join --backend \u003curl\u003e --hooks`\n3. **Auto-sync:** hooks handle push/pull at session boundaries\n4. **Preview changes:** `claudefy diff` to see pending changes\n5. **Override:** `claudefy override --confirm` when one machine should be the source of truth (other machines auto-detect and create a backup before applying)\n\n## Contributing\n\n```bash\ngit clone https://github.com/kodrunhq/claudefy.git\ncd claudefy\nnpm install\nnpm run lint \u0026\u0026 npm run format:check \u0026\u0026 npm run build \u0026\u0026 npm test\n```\n\n## License\n\n[MIT](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkodrunhq%2Fclaudefy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkodrunhq%2Fclaudefy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkodrunhq%2Fclaudefy/lists"}