This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is claude-code-sync, a tool for synchronizing Claude Code conversations across multiple machines using git with optional encryption.
Claude Code stores conversations locally in ~/.claude/, which means:
- Conversations are machine-locked by default
- No built-in sync between computers
- Loss of conversations if machine fails
- Cannot share conversations with team members
This tool solves these problems by providing git-based sync with encryption support.
Configuration System (lib-claude-sync.sh)
- Two-layer configuration: env vars > local config
- Defaults hardcoded in
load_config(), overridable via.claude-sync-config.local - Validates required settings before operations
show_version()function reads from VERSION file
Sync Scripts
claude-sync-init- Clones conversations repo from remote, handles encryption unlockclaude-sync-push- Merges local conversations to git remoteclaude-sync-pull- Pulls and merges remote conversations locallyclaude-sync-status- Shows configuration and sync state
Backup System
claude-backup- Creates timestamped tar.gz backupsclaude-restore- Restores from backup with safety measuresclaude-backup-list- Lists available backups- Auto-cleanup based on retention policy
Security/Encryption
claude-enable-encryption- Sets up git-crypt for transparent encryptionclaude-restore-encryption-key- Helps restore keys from KeePass/password manager- Base64 key export for easy storage
Configuration
claude-config- Interactive wizard for first-time setup.claude-sync-config.local- Machine-specific settings (gitignored).claude-sync-config.example- Template with full documentation
Release Management
claude-release- Bumps version (patch/minor/major), updates VERSION and CHANGELOG.mdVERSION- Single source of truth for version number
~/.claude/ conversations/ Git Remote
├── projects/ ├── projects/ (GitHub/Bitbucket)
├── file-history/ <---> ├── file-history/ <---> (encrypted)
├── todos/ ├── todos/
└── history.jsonl └── history.jsonl
Sync Strategy:
claude-sync-initclones from remote (or initializes fresh if empty)claude-sync-pushpulls latest first, then usesrsync --updateto merge (newer files win, never delete)- All machines accumulate conversations from all other machines
- Git commits track which machine contributed which conversations
Why rsync --update?
- Preserves newer files based on mtime
- Never deletes conversations from other machines
- Simple merge strategy that works across machines
Why git-crypt?
- Transparent encryption (files encrypted on remote, decrypted locally)
- No workflow changes after initial setup
- Standard tool, widely trusted
Why local backups?
- Safety net before first sync attempt
- Quick rollback if sync goes wrong
- Not synced to remote (local only)
- Configurable retention policy
Why two-layer config?
- Environment variables for temporary testing/overrides
- Local config for machine-specific settings (gitignored)
- Defaults in
lib-claude-sync.shensure scripts work out of the box
When adding new commands:
- Source
lib-claude-sync.shfor configuration - Add
--versionflag handling usingshow_version "$SCRIPT_DIR" "command-name" - Save/restore
ORIGINAL_DIR(return user to starting directory) - Use
$CLAUDE_DATA_DIRnot hardcoded~/.claude - Make executable with
chmod +x - Update README.md Commands Reference section
Always use these variables from config:
$CLAUDE_DATA_DIR- Claude's data directory$CLAUDE_SYNC_REMOTE- Git remote URL$CLAUDE_SYNC_BRANCH- Git branch$CLAUDE_SYNC_ENCRYPTION- Encryption enabled?$CLAUDE_BACKUP_RETENTION_DAYS- Backup retention$CLAUDE_SYNC_VERBOSE- Verbose output
- Add default to
load_config()inlib-claude-sync.sh - Add to
.claude-sync-config.examplewith documentation - Update
show_config()to display it - Update
claude-configwizard if user-facing - Document in CONFIGURATION.md and README.md
- Use
set -efor automatic error handling - Validate config with
validate_configbefore operations - Return to original directory on all exit paths
Test on multiple machines:
- Fresh install (no ~/.claude exists)
- Existing conversations (merge scenario)
- After encryption enabled
- With non-standard CLAUDE_DATA_DIR
# See what config is active
claude-sync-status
# Test with verbose output
CLAUDE_SYNC_VERBOSE="true" claude-sync-push
# Check config loading
bash -x ./claude-sync-push 2>&1 | grep -A5 "load_config"- Scripts:
claude-*(no extension, executable) - Configs:
.claude-sync-config* - Docs:
*.md(uppercase for top-level docs) - Library:
lib-claude-sync.sh
For sync commits (automated):
Sync conversations - YYYY-MM-DD HH:MM:SS - hostname
For development commits, use conventional commits:
feat: add retention policy for backups
fix: correct tar exclusion for custom data dir
docs: update configuration examples
./claude-release patch # or minor, major
# Edit CHANGELOG.md with release notes
git push origin master --tagsSee CONTRIBUTING.md for full release process.