Skip to main content

Sync Claude Code sessions across Windows, macOS, and Linux

Project description

日本語 | English

claude-session-sync

Python 3.9+ License: MIT

What is this?

claude-session-sync is a CLI tool that syncs Claude Code session history across Windows, macOS, and Linux.

  • Continue any conversation on any machine — pick up exactly where you left off
  • Uses a private GitHub repository as the sync backend (no third-party servers)
  • Automatic path conversion: OS-specific paths are replaced with portable placeholders (e.g., /home/user/projects{{PROJECTS}}C:\projects)

How it works

Ubuntu                         GitHub                          Mac
claude-session-sync push  →  Private Repo  →  claude-session-sync pull
/home/user/projects       →  {{PROJECTS}}  →  /Users/user/projects

Session files (.jsonl) are stored under ~/.claude/projects/ by Claude Code. This tool copies them into a private GitHub repository, translating machine-specific paths to shared placeholders on push, and back to local paths on pull.

Memory files stored under ~/.claude/projects/*/memory/ are also synced. All machines share a single set of memory files — the last push becomes the source of truth. On pull, local memory is completely replaced with the shared version. Changes are tracked through git commit history.

Features

  • Cross-machine session resume — open any session from any registered machine
  • Automatic path conversion with user-defined placeholders
  • Session locking — prevents two machines from editing the same session simultaneously
  • Background daemon — periodic push backup while Claude Code is running
  • Selective sync — only sessions under configured directories are shared
  • Windows / macOS / Linux support
  • Memory & CLAUDE.md sync — project memory files and global CLAUDE.md are synced across machines automatically during push/pull
  • Shared memory model — all machines use the same memory files, git tracks change history
  • git push retry — automatic pull-and-retry (up to 3 times) when push is rejected due to concurrent updates
  • Duplicate daemon prevention — the resume command checks for existing daemons before starting a new one
  • Last-editing machine display — the session list shows which machine last edited each session, not just where it was created

Quick Start

# Install
pip install claude-session-sync

Development install

# Development install
git clone https://github.com/tsubome/claude-session-sync.git
cd claude-session-sync
pip install -e .
# Setup — first machine (creates a new private GitHub repo)
claude-session-sync init

# Setup — additional machines (connects to the existing repo)
claude-session-sync init

# Daily usage — `ccsync` is a short alias for `claude-session-sync`
ccsync resume
# Pulls the latest sessions, lets you pick one interactively,
# launches Claude Code, then pushes and releases the lock on exit.

Commands

Command Description
resume [SESSION_ID] Main command. Pull → select session interactively → launch Claude Code → push + release lock on exit. Pass SESSION_ID to skip the list.
resume --latest Automatically selects the most recently updated session.
resume --from MACHINE_ID Show only sessions from a specific machine.
resume --all Show all sessions, ignoring sync_directories filter.
init Register this machine and create or connect to the shared GitHub repository.
push [--dry-run] Manually push local sessions to the remote repository.
pull [--dry-run] [--force] Manually pull sessions from the remote repository.
update Push sessions and release any locks left behind after an abnormal exit.
status Show the current sync status (last push/pull time, machine ID, etc.).
list [--remote] [--format table|json] List local (or remote) sessions.
lock show Show all current locks.
lock release [SESSION_ID] Release a lock. Omit SESSION_ID to release all locks on this machine.
lock cleanup Delete all expired locks.
config show Show the current configuration.
config add-placeholder NAME=PATH Add a new placeholder mapping for this machine.
config set-path NAME MACHINE_ID PATH Set a path for a specific machine in shared_placeholders.json.
daemon [--interval SECONDS] [--push-only] [--stop] Run a background sync daemon (default interval: 300 s / 5 min).

Configuration

The local config file is stored at ~/.claude-session-sync/config.json.

Placeholder mappings shared across all machines are stored in the GitHub repository as shared_placeholders.json.

Example config

{
  "machine_id": "ubuntu-work",
  "github_owner": "your-username",
  "github_repo": "claude-sessions",
  "sync_directories": [
    "/home/your-username/projects"
  ],
  "custom_placeholders": {
    "PROJECTS": "/home/your-username/projects"
  }
}

sync_directories controls which sessions are visible in resume. Only sessions whose working directory falls under one of these paths are shown. Sessions outside them are ignored unless you pass --all.

Custom Placeholders

Placeholders let the same session be opened on machines with different filesystem layouts.

Adding during init:

claude-session-sync init --add-placeholder PROJECTS=/home/user/projects

Adding afterwards:

claude-session-sync config add-placeholder PROJECTS=/home/user/projects

Setting the path for another machine:

claude-session-sync config set-path PROJECTS macbook /Users/user/projects
claude-session-sync config set-path PROJECTS windows C:\projects

When the same session is pulled on macOS, {{PROJECTS}} is automatically expanded to /Users/user/projects. On Windows it becomes C:\projects.

Session Locking

When you resume a session, claude-session-sync acquires a lock in the shared repository so that no other machine can open the same session at the same time.

Detail Value
Lock TTL 10 minutes (default)
Heartbeat Background daemon refreshes the lock while Claude Code is running
Crash recovery Locks auto-expire after TTL — no manual cleanup needed in most cases
Manual release claude-session-sync lock release

If a session is locked by another machine, you are shown a warning and asked whether to take over the lock. This is safe if the other machine crashed or was closed without a proper exit.

Concurrent Operation

Multiple machines can work on different sessions simultaneously. Each session has its own lock, so editing CrossClip on Linux while editing WhisperApp on Windows is fully supported.

If two machines push at the same time, the tool automatically retries with pull-and-push (up to 3 attempts).

Troubleshooting

"Session is locked by another machine"

The previous Claude Code session likely exited abnormally. You can:

  1. Select the locked session → confirm the takeover prompt (y)
  2. Or run claude-session-sync update on the machine that holds the lock (if still reachable)
  3. Or run claude-session-sync lock release SESSION_ID to force-release it

"No sessions found"

Run claude-session-sync pull first to download sessions from the remote repository, then try resume again.

Windows: daemon does not stop

The daemon uses a stop-file mechanism on Windows (instead of signals). Run claude-session-sync daemon --stop to request a graceful shutdown.

Sessions from another machine are not visible

Make sure sync_directories on both machines point to the same placeholder (e.g., both mapped to {{PROJECTS}}). Run claude-session-sync config show to verify, and use config set-path to add missing machine entries.

Requirements

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

claude_session_sync-0.2.3.tar.gz (93.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

claude_session_sync-0.2.3-py3-none-any.whl (63.6 kB view details)

Uploaded Python 3

File details

Details for the file claude_session_sync-0.2.3.tar.gz.

File metadata

  • Download URL: claude_session_sync-0.2.3.tar.gz
  • Upload date:
  • Size: 93.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for claude_session_sync-0.2.3.tar.gz
Algorithm Hash digest
SHA256 83e1579250d1e1604aa55119bc550a712eb4915acc9e1816e3cd5bbfd8dcd797
MD5 572f9f4d849c3d8d020e07b56bad3c7f
BLAKE2b-256 4e423fd147f6c0a451e0ee81586a83d74510e7d1d1ee4f0a5bbcc10063986999

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_session_sync-0.2.3.tar.gz:

Publisher: publish.yml on tsubome/claude-session-sync

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file claude_session_sync-0.2.3-py3-none-any.whl.

File metadata

File hashes

Hashes for claude_session_sync-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 5666e6c74820d05d16330677f38aa7056f401f02ffb1303086264c08e013cb26
MD5 cd2a7751d9816d557d9fc9adc34210d2
BLAKE2b-256 253d479ed87f5e50ba453c92410710a374eea859ce4c9eec1cf51057a2c22d2d

See more details on using hashes here.

Provenance

The following attestation bundles were made for claude_session_sync-0.2.3-py3-none-any.whl:

Publisher: publish.yml on tsubome/claude-session-sync

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page