tawanorg/claude-sync
tawanorg/claude-sync · 1 plugin
Marketplace Sync Claude Code sessions across devices using Cloudflare R2 with end-to-end encryption
Install
The repo has no one-line install. Follow its README.
Plugins 1
After adding the marketplace, install one with /plugin install <name>@claude-sync.
- 1claude-syncSync Claude Code sessions across devices with encrypted cloud storage
/plugin install claude-sync@claude-sync
Files
Encrypted with age • R2 / S3 / GCS / WebDAV supported
Quick Start • Setup Guide • Commands • Shell Integration • Security
Features
- Cross-device sync: Continue Claude Code conversations on any laptop
- Multi-provider storage: Cloudflare R2, AWS S3, Google Cloud Storage, S3-compatible (Backblaze B2, MinIO, Wasabi), or WebDAV (Nextcloud, ownCloud)
- End-to-end encryption: All files encrypted with age before upload
- Passphrase-based keys: Same passphrase = same key on any device (no file copying)
- Selective sync: Choose
--scope sessionsto sync only conversation data (skip plugins/node_modules) - Interactive wizard: Arrow-key driven setup with validation
- Secure self-updating:
claude-sync updatedownloads and verifies SHA256 checksums - Simple CLI:
push,pull,status,diff,conflictscommands - Compression: Gzip compression before encryption for faster syncs
- Shell integration: Optional shell hooks for automatic push/pull
Quick Start
First Device
# Install
npm install -g @tawandotorg/claude-sync
# Set up (interactive wizard)
claude-sync init
# Push your sessions
claude-sync pushSecond Device
# Install
npm install -g @tawandotorg/claude-sync
# Set up with SAME storage credentials
claude-sync init
# Select same provider (R2/S3/GCS/WebDAV)
# Enter same bucket name and credentials
# Choose "Passphrase" for encryption
# Enter the SAME passphrase as first device
# ✓ Encryption key verified <-- confirms passphrase matches!
# Preview what would be synced
claude-sync pull --dry-run
# Pull sessions (creates backup if you have existing files)
claude-sync pullSame passphrase = same encryption key. The init verifies your passphrase can decrypt remote files before completing.
Setup Guide
Step 1: Choose a Storage Provider
| Provider | Free Tier | Best For |
|---|---|---|
| Cloudflare R2 | 10GB storage | Personal use (recommended) |
| AWS S3 | 5GB (12 months) | AWS users |
| Google Cloud Storage | 5GB | GCP users |
| S3-compatible | varies | Backblaze B2, MinIO, Wasabi, DigitalOcean Spaces, self-hosted |
| WebDAV | Self-hosted (unlimited) | Nextcloud/ownCloud users |
Step 2: Create a Bucket
Cloudflare R2 (recommended)
- Go to Cloudflare Dashboard → R2 Object Storage
- Click "Create bucket" → name it
claude-sync - Go to "Manage R2 API Tokens" → "Create API Token"
- Select Object Read & Write permission → Create
You'll need: Account ID, Access Key ID, Secret Access Key
AWS S3
- Go to S3 Console → Create bucket
- Go to IAM Security Credentials
- Create Access Keys
You'll need: Access Key ID, Secret Access Key, Region
Google Cloud Storage
- Go to Cloud Storage → Create bucket
- Go to Service Accounts → Create service account
- Grant "Storage Object Admin" role → Create JSON key
You'll need: Project ID, Service Account JSON file (or use gcloud auth application-default login)
S3-compatible (Backblaze B2, MinIO, Wasabi, DigitalOcean Spaces, ...)
Any provider exposing an S3-compatible API works through the S3-compatible (custom endpoint) option. Create a bucket and an application key with your provider, then supply its S3 endpoint URL.
Example (Backblaze B2):
claude-sync init --provider s3-compatible --endpoint https://s3.us-west-004.backblazeb2.comYou'll need: Endpoint URL, Access Key ID, Secret Access Key, Bucket. The signing region is auto-detected from the endpoint (e.g. us-west-004); for providers that ignore it, auto is used.
For servers that don't resolve buckets as subdomains (e.g. Ceph RGW, or MinIO without wildcard DNS), add --use-path-style to address objects as endpoint/bucket/key instead of bucket.endpoint/key:
claude-sync init --provider s3-compatible --endpoint https://ceph.example.com --use-path-styleIt's off by default and unnecessary for Backblaze B2, Wasabi, and DigitalOcean Spaces, which all support virtual-hosted addressing.
Custom endpoints automatically relax the AWS SDK's default integrity-checksum headers, which some S3-compatible providers reject. AWS S3 behavior is unchanged.
WebDAV (Nextcloud, ownCloud, etc.)
No bucket to create — just point at your existing WebDAV server.
- Nextcloud: Go to Settings → Security → Devices & sessions → Create app password
- Note your WebDAV URL:
https://your-server/remote.php/dav/files/USERNAME/
You'll need: WebDAV URL, Username, App password
The wizard will create a claude-sync subdirectory automatically.
Step 3: Run Init
claude-sync initThe interactive wizard will guide you through:
- Select storage provider (R2, S3, GCS, or WebDAV)
- Enter credentials (provider-specific)
- Choose encryption method:
- Passphrase (recommended) - same passphrase on all devices = same key
- Random key - must copy
~/.claude-sync/age-key.txtto other devices
- Test the connection to verify everything works
Step 4: Push and Pull
# Upload local changes
claude-sync push
# Download remote changes
claude-sync pullWhat Gets Synced
| Path | Content |
|---|---|
~/.claude/projects/ |
Session files, auto-memory |
~/.claude/plans/ |
Implementation plans from plan mode |
~/.claude/tasks/ |
Task tracking state |
~/.claude/history.jsonl |
Command history |
~/.claude/agents/ |
Custom agents |
~/.claude/skills/ |
Custom skills |
~/.claude/plugins/ |
Plugins |
~/.claude/rules/ |
Custom rules |
~/.claude/settings.json |
Settings |
~/.claude/settings.local.json |
Local settings |
~/.claude/CLAUDE.md |
Global instructions |
Sync scope
init asks whether to sync everything or just conversation data; you can also set it with --scope:
| Scope | Syncs | Use when |
|---|---|---|
full (default) |
everything in the table above | you want settings, skills, agents, and plugins mirrored too |
sessions |
projects/, history.jsonl, tasks/, plans/ only |
you just want claude --resume to work across machines |
claude-sync init --scope sessionsWhy sessions exists: full includes plugins/, whose plugin caches bundle node_modules and Python .venv trees — thousands of large, machine-/arch-specific files that are regenerated on demand and should not be synced. sessions skips them, keeping syncs small, fast, and portable. The scope is saved in ~/.claude-sync/config.yaml and applies to every push/pull.
Cross-Device Path Mapping
Claude Code indexes project sessions by absolute filesystem path:
/Users/alice/my-app → ~/.claude/projects/-Users-alice-my-app/
/Users/bob/my-app → ~/.claude/projects/-Users-bob-my-app/
Synced verbatim, those would be different projects and claude --resume on the second machine would never find the first machine's sessions. claude-sync solves this by translating paths during sync:
-
Home directories are mapped automatically. Sessions are stored remotely under a portable
${HOME}token (in both remote keys and transcript content), then rewritten to each device's real home on pull. Different usernames across machines just work. -
Other layout differences are configurable. If one machine keeps projects in
~/workand another in~/Projects, point both at the same token in~/.claude-sync/config.yaml:# machine 1 path_map: ~/work: WORK
# machine 2 path_map: ~/Projects: WORK
Sessions under either directory sync to the shared
${WORK}namespace and resume correctly on both machines.
Upgrading from an older version? Run claude-sync migrate once on each device to convert existing remote data to portable keys. Paths the current device doesn't own are left for the other device's migrate run.
Commands
claude-sync init # Set up configuration (interactive wizard)
claude-sync push # Upload local changes to cloud storage
claude-sync pull # Download remote changes from cloud storage
claude-sync status # Show pending local changes
claude-sync diff # Show differences between local and remote
claude-sync conflicts # List and resolve conflicts
claude-sync rebuild-history # Rebuild ~/.claude/history.jsonl from session files
claude-sync reset # Reset configuration (forgot passphrase)
claude-sync migrate # Convert legacy remote keys to portable path-mapped keys
claude-sync update # Update to latest version (verifies release checksums)
claude-sync changelog # Show release history
claude-sync --help # Show all commandsPull Options
claude-sync pull # Normal pull (prompts if existing files)
claude-sync pull --dry-run # Preview what would change
claude-sync pull --force # Skip confirmation prompts
claude-sync pull --rebuild-history # Also rebuild history.jsonl after pullingRebuilding Prompt History
history.jsonl is synced as a single file, so pushes from two devices are
last-writer-wins and one device's prompt-history entries can be lost — which
breaks the /resume session picker. Session files sync cleanly (one file per
session), so the history can always be reconstructed from them:
claude-sync rebuild-history # One-off rebuild
claude-sync pull --rebuild-history # Rebuild automatically after a pullEvery existing entry is preserved, recovered prompts are merged in and sorted by
timestamp, and the previous file is kept as history.jsonl.bak.
Init Options
claude-sync init # Full setup wizard
claude-sync init --passphrase # Re-enter passphrase only (keeps storage config)
claude-sync init --force # Reset everything, start freshQuiet Mode
claude-sync push -q # No output (for scripts)
claude-sync pull -qCheck for Updates
claude-sync update --check # Check without installing
claude-sync update # Download and install latest versionChangelog
claude-sync changelog # Show recent releases
claude-sync changelog --limit 5 # Show last 5 releasesExclude Patterns
Skip specific files or directories during sync by adding exclude patterns to your config (~/.claude-sync/config.yaml):
exclude:
- "*.tmp"
- "projects/*/node_modules/*"
- "projects/*/.git/*"Patterns use glob syntax and are matched against paths relative to ~/.claude.
Shell Integration
Add to ~/.zshrc or ~/.bashrc:
# Auto-pull on shell start
if command -v claude-sync &> /dev/null; then
# Run in a subshell so the job is detached from the parent shell's
# job table — avoids interactive `[1] 12345` / `[1] + done` noise.
(claude-sync pull -q &) >/dev/null 2>&1
fi
# Auto-push on shell exit
trap 'claude-sync push -q' EXITNote: The subshell wrapper
(cmd &)prevents zsh/bash from printing job control
messages ([1] 12345on start and[1] + done cmdon completion) every time you open
a terminal. A plainclaude-sync pull -q &works but produces noisy shell prompts.
Pulling with Existing Files
When you pull on a device that already has ~/.claude files, claude-sync will:
- Show what would change - files that would be overwritten, kept, or downloaded
- Ask for confirmation - choose to backup, overwrite, or abort
- Create a backup - saves existing files to
~/.claude.backup.{timestamp}
# Preview first
claude-sync pull --dry-run
# Pull with prompts
claude-sync pull
# Skip prompts (for scripts)
claude-sync pull --forceConflict Resolution
When both local and remote files change, the remote version is saved as .conflict:
claude-sync conflicts # Interactive resolution
claude-sync conflicts --list # Just list conflicts
claude-sync conflicts --keep local # Keep all local versions
claude-sync conflicts --keep remote # Keep all remote versionsInteractive options:
- [l] Keep local (delete conflict file)
- [r] Keep remote (replace local)
- [d] Show diff
- [s] Skip
- [q] Quit
Wrong Passphrase?
If you entered the wrong passphrase on a new device:
# Re-enter passphrase (keeps your storage config)
claude-sync init --passphraseThe init will verify your passphrase can decrypt remote files before completing.
Forgot Passphrase?
The passphrase is never stored. If you forget it:
- Your encrypted files cannot be recovered
- Reset and start fresh:
claude-sync reset --remote # Delete remote files and local config
claude-sync init # Set up again with new passphrase
claude-sync push # Re-upload from this deviceSecurity
- Files compressed with gzip, then encrypted with age before upload
- Passphrase-derived keys use Argon2 (memory-hard KDF)
- Passphrase is never stored - only the derived key at
~/.claude-sync/age-key.txt - Cloud storage is private (API key/IAM auth)
- Config files and downloads stored with 0600/0700 permissions (user-only)
- Self-update verifies SHA256 checksums before installing new binaries
- Backward compatible: can read both compressed and uncompressed remote files
Cost
Claude sessions typically use < 50MB. Syncing is effectively free on any provider:
| Provider | Free Tier |
|---|---|
| Cloudflare R2 | 10GB storage, 1M writes, 10M reads/month |
| AWS S3 | 5GB for 12 months (then ~$0.023/GB) |
| Google Cloud Storage | 5GB, 5K writes, 50K reads/month |
| WebDAV | Self-hosted — no limits, no cost beyond your own server |
Installation Options
npm (recommended)
Prerequisite: Node.js 14+ (no Go required - downloads pre-compiled binary)
# Global install
npm install -g @tawandotorg/claude-sync
# Or one-time use
npx @tawandotorg/claude-sync initGitHub Packages
Prerequisite: Node.js 14+
# Add to ~/.npmrc
echo "@tawanorg:registry=https://npm.pkg.github.com" >> ~/.npmrc
# Install
npm install -g @tawanorg/claude-syncDownload Binary
Prerequisite: None
# macOS ARM (M1/M2/M3)
curl -L https://github.com/tawanorg/claude-sync/releases/latest/download/claude-sync-darwin-arm64 -o claude-sync
chmod +x claude-sync
sudo mv claude-sync /usr/local/bin/See GitHub Releases for all platforms.
Go Install
Prerequisite: Go 1.21+ (for developers)
go install github.com/tawanorg/claude-sync/cmd/claude-sync@latestBuild from Source
Prerequisite: Go 1.21+
git clone https://github.com/tawanorg/claude-sync
cd claude-sync
make build
./bin/claude-sync --versionDevelopment
make test # Run tests
make fmt # Format code
make check # Run all pre-commit checks
make build-all # Build for all platforms
make setup-hooks # Enable git pre-commit hooksLicense
MIT
{
"name": "claude-sync",
"owner": {
"name": "tawanorg"
},
"plugins": [
{
"name": "claude-sync",
"description": "Sync Claude Code sessions across devices with encrypted cloud storage",
"source": "./claude-code-plugin"
}
]
}Facts
- Kind
- Marketplace
- Repo
- tawanorg/claude-sync
- Group
- Uncategorized
- Marketplace name
- claude-sync
- Owner
- tawanorg
- Language
- Go
- Created
- 2026-02-07
- Forks
- 51
- Plugins
- 1
- 1f/prompts.chatf/prompts.chatf.k.a. Awesome ChatGPT Prompts. Share, discover, and collect prompts from the community. Free and open source — self-host for your organization with complete privacy.
- 2affaan-m/everything-claude-codeaffaan-m/everything-claude-codeThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.
- 3obra/superpowersobra/superpowersAn agentic skills framework & software development methodology that works.
- 4anthropics/skillsanthropics/skillsPublic repository for Agent Skills
- 5anthropics/claude-codeanthropics/claude-codeClaude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.
- 6nextlevelbuilder/ui-ux-pro-max-skillnextlevelbuilder/ui-ux-pro-max-skillAn AI skill that provides design intelligence for building professional UI/UX across multiple platforms.
