Skip to content

Repository files navigation

claude-code-server-syncer

Bidirectional project sync between macOS and a remote dev server, with Claude Code session sync built-in.

Built for a workflow where you develop on a Mac, sometimes SSH into the server from your phone, and never work on both at the same time. Everything stays in sync automatically — no buttons, no confirmations, no friction.

How it works

  OPEN LID (wake)              CLOSE LID (sleep)           EVERY 15 MIN
  ┌─────────────┐              ┌──────────────┐            ┌──────────────┐
  │ Sync:       │              │ Sync:        │            │ Sync:        │
  │ mac↔server  │              │ mac↔server   │            │ mac↔server   │
  │             │              │              │            │              │
  │ + dashboard │              │ caffeinate   │            │ silent       │
  │ + restic    │              │ (headless)   │            │ (headless)   │
  │ + auto-close│              │              │            │              │
  └─────────────┘              └──────────────┘            └──────────────┘

Open the lid — a Terminal window pops up showing a dashboard: server status, pending changes, last backup. If there are changes, it syncs bidirectionally and closes. If everything is up to date, it shows status for 3 seconds and closes.

Close the lid — silently syncs in both directions before the Mac sleeps. Uses caffeinate to prevent sleep until the sync completes.

Every 15 minutes — a LaunchAgent runs a silent bidirectional sync in the background, so you're never more than 15 minutes behind.

Features

  • Bidirectional rsync with --update (newer file always wins)
  • Claude Code session sync — sessions and file history follow you between machines, with automatic path remapping (-opt-project-Users-name-path-project)
  • Restic backups — encrypted, deduplicated snapshots on every interactive sync (7 daily, 4 weekly, 6 monthly)
  • Lock file — prevents concurrent syncs from stepping on each other
  • Smart dashboard — auto-syncs when changes exist, auto-closes when done
  • sleepwatcher integration — triggers on lid open/close events

Files

File Purpose
sync-projects.sh Main sync script (dashboard, bidirectional sync, Claude sessions)
sleep.sh Triggered on lid close — bidirectional sync
wakeup.sh Triggered on lid open — opens dashboard
com.n0mads.sync-projects.plist LaunchAgent for 15-min background sync

Installation

Prerequisites

brew install sleepwatcher restic rsync
brew services start sleepwatcher

Setup

  1. Clone the repo and symlink everything:
git clone https://github.com/mad0ps/claude-code-server-syncer.git \
  ~/Documents/pr0j3cts/claude-code-server-syncer

# Symlink scripts
ln -s ~/Documents/pr0j3cts/claude-code-server-syncer/sync-projects.sh ~/.sync-projects.sh
ln -s ~/Documents/pr0j3cts/claude-code-server-syncer/sleep.sh ~/.sleep
ln -s ~/Documents/pr0j3cts/claude-code-server-syncer/wakeup.sh ~/.wakeup

# Add to PATH for easy access
ln -s ~/.sync-projects.sh /opt/homebrew/bin/sync-projects
  1. Configure SSH access to your server in ~/.ssh/config:
Host projects
    HostName YOUR_SERVER_IP
    User YOUR_USER
    IdentityFile ~/.ssh/your_key
  1. Create your .env from the template and fill in your values:
cp .env.example .env
# Edit .env with your server IP, paths, etc.
  1. Generate the LaunchAgent plist with your home directory:
sed "s|__HOME__|$HOME|g" com.n0mads.sync-projects.plist > ~/Library/LaunchAgents/com.n0mads.sync-projects.plist
launchctl load ~/Library/LaunchAgents/com.n0mads.sync-projects.plist
  1. Initialize the restic repo:
restic -r ~/Backups/server-repo init

Usage

sync-projects                # Interactive dashboard with menu
sync-projects --force        # Bidirectional sync with UI
sync-projects --sync         # Silent bidirectional sync (used by automation)
sync-projects --status       # Dashboard without menu

How Claude Code sessions sync

Claude Code stores sessions per-project with path-encoded directory names:

  • Server: ~/.claude/projects/-opt-myproject/
  • Mac: ~/.claude/projects/-Users-name-Documents-projects-myproject/

The syncer remaps these paths automatically, syncs session JSONL files, and deletes sessions-index.json on the receiving side (Claude Code regenerates it on next launch). File history (~/.claude/file-history/) is UUID-based and syncs without conflicts.

License

MIT

About

Bidirectional project sync between macOS and a remote dev server with Claude Code session sync. Sleepwatcher-powered: pull on lid open, push on lid close.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages