Skip to content

bigwhite/cc-session-migrate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

83 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cc-session-migrate (csm)

中文文档

Cross-node migration and backup tool for Claude Code sessions. Migrate session data between development machines and back up to any S3-compatible storage.

The Problem

Claude Code stores session data on local disk (~/.claude/). When you start a session on your MacBook and switch to an Ubuntu server to continue, the context is lost — the session is locked to the original machine.

csm solves this with a Consul-style cluster model, making session data portable across nodes.

Architecture

                          ┌──────────────────────────┐
                          │    Server (Leader)        │
                          │                          │
                          │  · cluster topology       │
                          │  · WebSocket hub          │
                          │  · session relay          │
                          │  · S3 backup              │
                          │  HTTP + WS :9827          │
                          └─────┬──────────┬─────────┘
                         WS     │          │     WS
                    ┌───────────┘          └───────────┐
                    ▼                                  ▼
            ┌───────────────┐                  ┌───────────────┐
            │  Agent A      │                  │  Agent B      │
            │  (MacBook)    │                  │  (SVR1)       │
            │               │                  │               │
            │  session ops  │                  │  session ops  │
            │  S3 backup    │                  │  S3 backup    │
            │  (no listen)  │                  │  (no listen)  │
            └───────────────┘                  └───────────────┘

   Cluster mgmt:       agents → server (WebSocket)
   Session migration:  any node ↔ any node (relayed via server WebSocket)
   S3 backup:          per-node, independent storage

The server (Leader) runs an HTTP server with a WebSocket endpoint. All agents maintain persistent outbound WebSocket connections to the server — no inbound ports required on agent machines, solving NAT traversal issues.

  • Server mode — Cluster leader. Manages topology, accepts agent WebSocket connections, relays session operations between nodes.
  • Agent mode — Connects to the server via outbound WebSocket. Handles session commands relayed by the server. No port listening needed.
  • S3 backup — Optional. Each node independently configures R2/MinIO/any S3-compatible storage.

Quick Start

Install

Linux (recommended for server node):

make build
sudo ./scripts/install.sh --local ./bin/cc-session-migrate

This installs the binary to /usr/local/bin, sets up the csm alias, creates the systemd service, and generates a default config at /etc/cc-session-migrate/env.

macOS / Windows:

go install github.com/bigwhite/cc-session-migrate@latest

Then create a csm alias so the examples below work:

# macOS / Linux (add to ~/.zshrc or ~/.bashrc)
alias csm='cc-session-migrate'

# Windows PowerShell (add to $PROFILE)
Set-Alias csm cc-session-migrate

Set Up a Cluster

Tip: Run the server (leader) node on a Linux server that is always online. Agent nodes on your laptop or other machines can join and leave freely.

Step 1 — Start the server node:

# Linux
sudo sed -i 's/CSM_AGENT_ROLE=agent/CSM_AGENT_ROLE=server/' /etc/cc-session-migrate/env
sudo systemctl enable --now cc-session-migrate
cat ~/.csm/config.yaml    # view the generated cluster-id and auth-token
# macOS / Windows (run in tmux or a dedicated terminal)
csm agent --server --name server-01

Step 2 — On each agent machine, join the cluster:

# Linux
make build && sudo ./scripts/install.sh --local ./bin/cc-session-migrate
sudo sed -i 's/# CSM_CLUSTER_SERVER_ADDR=/CSM_CLUSTER_SERVER_ADDR=<server-ip>:9827/' /etc/cc-session-migrate/env
sudo sed -i 's/# CSM_CLUSTER_AUTH_TOKEN=/CSM_CLUSTER_AUTH_TOKEN=<token>/' /etc/cc-session-migrate/env
sudo systemctl enable --now cc-session-migrate
# macOS / Windows (run in tmux or a dedicated terminal)
csm agent --server-addr <server-ip>:9827 --auth-token <token> --name my-macbook

Step 3 — Verify cluster status:

csm cluster list

Migrate Sessions

# List sessions on a remote node
csm session list --node macbook-pro

# Pull a session (supports ID prefix matching, minimum 8 characters)
csm session pull cebea1f8 --from macbook-pro --project /home/user/my-project

# Push a session
csm session push cebea1f8 --to server-01

# Batch migrate all sessions
csm session pull --from macbook-pro --all

# Resume development after migration
# NOTE: claude --resume requires the FULL session ID (not a prefix).
# Use `csm session list` to find the full ID from the SESSION ID column.
claude --resume 47f57b56-48b3-4405-b01d-3b8591874fe2

S3 Backup

# Configure S3 storage
csm backup config \
  --endpoint https://xxx.r2.cloudflarestorage.com \
  --bucket csm-backups \
  --access-key $ACCESS_KEY \
  --secret-key $SECRET_KEY

# Back up all sessions
csm backup create

# List backups
csm backup list

# Restore a specific session
csm backup restore --node server-01 --session <session-id> --project /home/user/project

# Restore the latest backup
csm backup restore --node server-01 --session <session-id>

In daemon mode, automatic scheduled backups are available (incremental, based on file mtime). Expired backups are cleaned up automatically (30-day retention by default, minimum 3 copies retained per session).

CLI Reference

Global Flags

Flag Default Description
--config ~/.csm/config.yaml Config file path
--verbose / -v false Verbose output

csm agent — Run Daemon

Flag Default Description
--server false Run in server (leader) mode
--server-addr Leader address for agent mode (host:port)
--auth-token Cluster auth token (agent mode)
--bind 0.0.0.0:9827 HTTP listen address (server mode only)
--name hostname Node name
--data-dir ~/.claude Claude Code data directory

csm cluster — Cluster Management

Subcommand Description
leave Leave the cluster (--force for forced leave)
list List cluster nodes (--format table|json)

csm session — Session Operations

Subcommand Description
list List sessions (--node for remote query, --format table|json)
pull Pull a session (--from source node, --project path mapping, --all batch)
push Push a session (--to target node, --project path mapping, --all batch)

csm backup — Backup Management

Subcommand Description
config Configure S3 storage (--endpoint + --bucket required)
create Create backups (--session for single, all by default)
list List backups (--node / --session filter, --format table|json)
restore Restore a backup (--node + --session required, --timestamp optional)

csm version — Version Info

Prints version, build time, Go version, and OS/Arch.

Configuration

Config file at ~/.csm/config.yaml, auto-generated on first run:

node:
  name: "server-01"
  data_dir: "~/.claude"

agent:
  role: "server"
  bind: "0.0.0.0:9827"

cluster:
  id: "a1b2c3d4-..."
  auth_token: "e5f6a7b8..."
  server_addr: ""

s3:
  endpoint: ""
  bucket: ""
  region: "auto"
  access_key: ""
  secret_key: ""

backup:
  auto_enabled: true
  interval: "0 3 * * *"
  retention_days: 30

All config values can be overridden via CSM_-prefixed environment variables (e.g., CSM_AGENT_ROLE=server). Config file permissions are automatically set to 0600.

Development

Dependencies

Dependency Purpose
spf13/cobra CLI framework
spf13/viper Configuration (YAML + env vars)
gorilla/websocket WebSocket connections (hub-and-spoke)
aws/aws-sdk-go-v2 S3 client (R2/MinIO compatible)
robfig/cron/v3 Scheduled backup
schollz/progressbar/v3 Transfer progress bar

Build & Test

# Build (with version info injection)
make build

# Run all tests
make test

# Clean build artifacts
make clean

Project Structure

cc-session-migrate/
├── cmd/                # CLI commands (cobra)
├── internal/
│   ├── agent/          # Daemon core (server / agent modes)
│   ├── cluster/        # Cluster topology management
│   ├── session/        # Session scanning, packing, path mapping, ID matching
│   ├── ws/             # WebSocket protocol, hub (server), agent client
│   ├── api/            # HTTP API types, server, and client
│   ├── store/          # S3 client wrapper
│   ├── backup/         # Backup create, restore, list, scheduler
│   ├── config/         # Configuration (viper)
│   └── log/            # Logging (slog)
├── scripts/            # Install script, systemd unit
└── doc/                # PRD, Feature Specs, Plan, Tasks

Design Highlights

  • Session ID prefix matching — Git-style, minimum 8 characters, errors on ambiguity
  • Atomic migration — Writes to staging directory first, atomic move after SHA256 verification
  • Streaming transfer — 64KB chunked streaming, bounded memory usage
  • Path mapping — Text replacement in JSONL content for cross-machine project path differences
  • WebSocket keepalive — Persistent WebSocket connections with ping/pong, automatic reconnection with exponential backoff
  • Hub-and-spoke relay — Session data relayed through the server, no direct node-to-node connections needed (NAT-friendly)
  • Incremental backup — Based on file mtime, only backs up changed sessions
  • Expiration cleanup — 30-day retention by default, minimum 3 copies per session

Platform Support

Platform Architecture
Linux amd64, arm64
macOS amd64, arm64
Windows amd64, arm64

Donate

If you find csm useful, consider buying me a coffee!

PayPal: Donate with PayPal

WeChat Pay / Alipay:

WeChat Pay Alipay

License

MIT

About

Cross-node session migration and S3 backup for Claude Code.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors