Share in-progress Claude Code sessions across multiple machines.
If you use Claude Code on more than one computer, you've probably hit this: you start a long task on your Linux desktop, walk to your Windows laptop, and now the context is stranded. The terminal is still open on the other machine but you can't see what you were doing.
This repo is a working implementation of a simple fix: auto-snapshot every open session to a shared git repo, keyed by hostname. From any machine, you can list the snapshots and pick up where any of your other machines left off.
# Monday on Linux — you're deep in a project, close the laptop, go to bed
# Tuesday on Windows — open a new Claude Code terminal
you: 未完成任务里有什么
claude: I see 2 active sessions:
1. [linux-desktop] "fixing the auth middleware bug"
last updated 14h ago
2. [windows-laptop] "refactoring the billing module"
last updated yesterday
you: 继续 1
claude: [reads the handoff prompt from linux-desktop's snapshot,
resumes the auth middleware work]
Each machine's Claude Code fires a Stop hook after every response. The
hook (snapshot-session.sh on Linux, snapshot-session.mjs on Windows)
does this:
- Reads the current session transcript from
~/.claude/projects/ - Calls
claude -p --model haikuto generate a structured summary in six sections (task, done, in-progress, next steps, files, handoff prompt) - Writes the summary to
<sync-repo>/tasks/<hostname>-<session-id>.md git pull --rebase && git add && git commit && git pushto the shared repo
Debounced so it only runs at most every 30 minutes per session (no spam
from chatty conversations). User can force an immediate snapshot by asking
Claude to "记一下这个" / "add to unfinished tasks" — this runs the script
with --force which bypasses both the snapshot debounce AND a separate
5-minute push debounce, so the state reaches the other machine within
seconds.
On normal terminal exit, a SessionEnd hook deletes the snapshot (the
terminal closing is the "task done" signal). On abnormal exit (power loss,
crash, closed laptop), the snapshot stays in the repo — so next time you
open Claude Code anywhere, you can see the unfinished work.
- Git handles sync for free. No custom server, no auth dance, no coordination protocol. Every machine pushes/pulls from the same remote.
- Different hostnames → different filenames → no write conflicts. Even if two machines push at the same second, they touch different files.
git pull --rebasebefore push handles the race cleanly; in practice collisions are rare.
Stop hook fires potentially every minute of active work. Running Sonnet or Opus would be expensive and slow. Haiku is fast, cheap, and the structured 6-section prompt keeps output quality consistent. Cost is negligible on a Claude Max subscription; see the script for the exact prompt.
- Claude Code installed on each machine
- A shared git repo you have push access to (e.g. a private GitHub repo)
git,bash, andclaudeCLI on each machinejqon Linux (Windows version is pure Node.js, no dependency)
gh repo create your-username/my-claude-sessions --private --cloneOr any repo that will hold a tasks/ directory.
# Linux
git clone git@github.com:your-username/my-claude-sessions.git ~/claude-context
# Windows (Git Bash)
git clone git@github.com:your-username/my-claude-sessions.git ~/claude-contextThe path ~/claude-context is hardcoded in the scripts — adjust to taste,
or make it an env var. For the rest of this guide we assume ~/claude-context.
Copy scripts/*.sh and scripts/*.mjs into ~/claude-context/scripts/ on
each machine:
cp scripts/*.sh scripts/*.mjs ~/claude-context/scripts/
chmod +x ~/claude-context/scripts/*Commit + push so the scripts live in your sync repo.
Linux (bash):
{
"hooks": {
"Stop": [{
"hooks": [{
"type": "command",
"command": "$HOME/claude-context/scripts/snapshot-session.sh"
}]
}],
"SessionEnd": [{
"hooks": [{
"type": "command",
"command": "$HOME/claude-context/scripts/cleanup-session.sh"
}]
}]
}
}Windows (Node.js — the .sh version won't work due to Windows hook
bugs; see claude-code-windows-hook
for the underlying pattern):
{
"hooks": {
"Stop": [{
"hooks": [{
"type": "command",
"command": "node C:/Users/YOU/claude-context/scripts/snapshot-session.mjs"
}]
}],
"SessionEnd": [{
"hooks": [{
"type": "command",
"command": "node C:/Users/YOU/claude-context/scripts/cleanup-session.mjs"
}]
}]
}
}In your global CLAUDE.md (or per-project), add instructions so Claude knows
what to do when you ask about unfinished tasks:
## Unfinished tasks (cross-machine)
Every Claude Code session is auto-snapshotted to `~/claude-context/tasks/
<hostname>-<session-id>.md` and synced via git.
**Trigger phrases**:
- "what's in my unfinished tasks?" / "未完成任务里有什么"
→ read `~/claude-context/tasks/*.md`, sort by frontmatter `updated`
descending, list title/machine/time
- user picks one → read the "## Handoff prompt" section, resume from there
- "add this to unfinished tasks" / "记一下这个"
→ run `~/claude-context/scripts/snapshot-session.sh --force`
(or `.mjs` on Windows) + confirm push
**Task complete = close the terminal.** The system does not support
"mark done but keep terminal open" — the next Stop hook would just
re-snapshot the session. To archive, /exit or close the terminal;
SessionEnd hook will clean up the snapshot automatically.That's it. Open a new Claude Code session on either machine and the snapshots start flowing.
The mental model that makes this system clean:
- One task = one terminal window
- Manually closing the terminal = task completed → cleanup deletes the snapshot
- Terminal still open when shutting down / crashing = task unfinished → snapshot stays
- Everything else is irrelevant (screen locking, laptop closing, switching windows, etc.)
If you violate this contract (e.g. use one terminal for multiple tasks back to back), the snapshots may misrepresent your current state. Works great if you adopt the contract.
- Cloud Claude sessions (claude.ai web, mobile app, API calls) — those don't have local transcript files or hook events, so they're outside the scope. They're already accessible from any device so they don't need this system anyway.
- Non-Claude-Code workflows — this is specifically for Claude Code CLI sessions. Not applicable to IDE plugins, VSCode extensions, etc.
- claude-code-windows-hook — The underlying Node.js hook template that makes the Windows side work. Claude Code's bash hooks have documented bugs on Windows; the Node.js pattern bypasses them. Extracted as a standalone utility.
MIT — use freely, modify, redistribute.
Found a design limitation or have an improvement? Open an issue or PR.