Skip to content

ot2i7ba/ClaudeMover

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 

Repository files navigation

ClaudeMover

ClaudeMover moves a whole Claude Code project from one Linux machine to another — not just your project files, but the entire session state that Claude Code keeps under ~/.claude. It packs everything into a single ZIP archive with a checksummed manifest, and on the other machine it fixes up every absolute path so that claude --resume picks up right where you left off. You can drive it from an interactive terminal menu or straight from the command line.

Why ClaudeMover?!

When you work on a project with Claude Code, the model gradually builds up a lot of context: it reads through your files, runs commands, works out a plan, keeps notes in memory, and records checkpoints as it edits. All of that exploration costs tokens, and on a subscription it counts against your usage. Start again from scratch on a new machine and Claude has to redo the whole thing — re-read the code, re-analyse it, rebuild its understanding — and you pay for that groundwork a second time.

The frustrating part is that the work is already saved on disk; it just isn't in one place and it can't simply be copied. Claude Code spreads a project's state across ~/.claude/projects/, file-history/, session-env/, tasks/, a shared history.jsonl, and the global ~/.claude.json — and every one of those is tied to the absolute path of the working directory. Move the project to a different folder or a different user account and Claude Code no longer finds any of it.

ClaudeMover gathers all of those pieces into one archive, and on import it rewrites the path-encoded directory names and every absolute path buried inside the files so the session lines up with its new home. The payoff is that you resume instead of restart: the conversation, the plans, the file history and the memory are all still there, so you skip the re-onboarding and the tokens that come with it.

One thing worth being clear about: this preserves the session, not the prompt cache. Claude Code's cache is tied to a single machine and working directory — the system prompt has your path, OS and shell baked in — so it stays behind. The first message after you resume on the new machine sends the conversation once without a cache hit; from there caching works as usual again. The saving is in not having to rebuild what Claude already knew, not in carrying the cache across.

If you find this tool useful, I'm glad to hear it. Feel free to improve upon it.

Table of Contents

Note

Credentials and machine-specific bits are never put in the archive: .credentials.json (your OAuth tokens), backups/, shell-snapshots/, sessions/, cache/, and the account fields of ~/.claude.json (oauthAccount, userID, machineID) all stay on the source machine. There's an extra check while collecting files that refuses to continue if any of them slips through.

Warning

Anthropic treats the session file format as internal, and it can change between Claude Code releases. ClaudeMover records the version in the manifest and warns you if it differs, but I can't promise a session made with one version will always resume cleanly under another. Also keep in mind the prompt-cache point above: the first message after resuming re-sends the whole conversation, so it's a little slower and costs a bit more than a normal turn.

Features

  • Interactive menu
    arrow keys or number shortcuts, a tidy screen, and spinners and progress bars so you can see what's happening on the longer steps
  • Works from the command line too
    every action has a subcommand (export, import, list, info), safe to pipe or script — the screen is only cleared in the menu
  • Grabs the whole state
    session transcripts, subagent logs, tool results, project memory, file checkpoints, session environment, tasks, and the plans and pasted snippets the session refers to
  • Manifest with checksums
    manifest.json holds a SHA-256 for every file, where the archive came from, the Claude Code version, and the real project path
  • Path rewriting
    the project path, your home directory and their encoded forms are all replaced in one pass, so nothing gets rewritten twice — and it works on the JSON structure, never on your actual file contents
  • Merges instead of overwriting
    the history.jsonl lines and the ~/.claude.json project entry are folded into whatever is already on the target, and the write is atomic
  • Handles collisions
    if there's already state on the target, --force moves it into ~/.claude/claudemover-backups/<timestamp>/ first rather than replacing it outright
  • Dry run
    --dry-run shows exactly what an import would do — the rewrite rules, any conflicts, the file counts — without touching anything
  • Won't step on a live session
    it refuses to export or import while Claude Code is running in that project, so you never capture or overwrite a half-written state (export can override this with --force)
  • Sets up its own dependencies
    if a required library is missing it installs it quietly on first run (user pip, with a fallback for newer Debian/Ubuntu, or pacman / apt-get) — one line on screen, the details go to the log
  • Keeps exports tidy
    archives go into movethis/ as YYYYMMDD_<project>.zip, and an existing file is never clobbered (_2, _3, … is added instead)
  • Logging
    everything is written to ClaudeMover.log; the console stays short and readable

What gets exported

Source Content Included
~/.claude/projects/<encoded>/ Session transcripts, subagents, tool results, memory
~/.claude/file-history/<uuid>/ File checkpoints per session
~/.claude/session-env/<uuid>/ Session environment state
~/.claude/tasks/<uuid>/ Task state per session
~/.claude/plans/*.md Plans referenced by the sessions
~/.claude/paste-cache/* Pasted content referenced by the sessions
~/.claude/history.jsonl Only the lines belonging to the project ✓ (filtered)
~/.claude.json Only the projects["<path>"] fragment ✓ (extracted)
Project working directory Complete, including hidden files and symlinks
~/.claude/.credentials.json OAuth tokens ✗ never
~/.claude/backups/, shell-snapshots/, sessions/, cache/ Machine-specific / sensitive ✗ never

Requirements

  • Python 3.9 or higher
  • Linux (developed and tested on CachyOS/Arch, Ubuntu, and Debian)
  • Claude Code installed on both machines (ideally the same version — the manifest records it and the import warns if they differ)

Python dependencies (installed automatically on first run if missing):

rich
prompt_toolkit

Installation

  1. Clone the repository
git clone https://github.com/ot2i7ba/ClaudeMover.git
cd ClaudeMover
  1. Run the application
python3 ClaudeMover.py

That's it. Any missing library is installed on first run — a user pip install where that works, otherwise the system package manager (pacman on CachyOS/Arch, apt-get on Ubuntu/Debian). If none of that succeeds, it prints the one command you need to run by hand.

Usage

python3 ClaudeMover.py

The interactive menu opens:

╭──────────────────────────────────────────────────────────────────────────╮
│ ClaudeMover v1.4.1 - backup or move Claude Code projects between systems │
│ Copyright (c) 2026 ot2i7ba · https://github.com/ot2i7ba                  │
╰──────────────────────────────────────────────────────────────────────────╯
Main menu
Arrows/digits to choose, Enter to confirm, Esc/q to cancel

 ❯ 1. Export a project to a ZIP archive
   2. Import a project from a ZIP archive
   3. List Claude Code projects on this system
   4. Inspect an archive (manifest)
   5. Quit

Navigation: arrow keys (or j/k) move the selection, digits 15 pick directly, Enter confirms, Esc/q cancels.

Typical workflow

  1. On the source machine: close the Claude Code session in the project (ClaudeMover won't export a running one), then run 1 → Export — the archive lands in movethis/YYYYMMDD_<project>.zip
  2. Move the ZIP across however you like — USB stick, scp, cloud drive
  3. On the target machine: run 2 → Import and confirm or change the target path; if it's different, the paths are fixed up for you
  4. cd <project> && claude --resume — and carry on where you stopped

Tip

Run python3 ClaudeMover.py import <archive> --dry-run first to see what an import would do — the rewrite rules, any conflicts, the file counts — without writing a thing.

CLI reference

python3 ClaudeMover.py list                                  # list projects with Claude state
python3 ClaudeMover.py export /path/to/project               # → movethis/YYYYMMDD_<name>.zip
python3 ClaudeMover.py export /path/to/project -o /tmp/x.zip # custom output path
python3 ClaudeMover.py export /path/to/project --force       # export despite a running session
python3 ClaudeMover.py info movethis/20260711_MyProject.zip  # show archive manifest
python3 ClaudeMover.py import <archive> --dry-run            # show the import plan
python3 ClaudeMover.py import <archive>                      # import to the original path
python3 ClaudeMover.py import <archive> --target /new/path   # import to a different path
python3 ClaudeMover.py import <archive> --force              # back up and replace existing state
python3 ClaudeMover.py --version                             # version and copyright

Global flags: --claude-dir PATH (point at a different ~/.claude, mainly for testing) and --verbose (extra detail in ClaudeMover.log).

Menu structure

1  Export a project to a ZIP archive
     (select project → confirm output path → progress → summary)

2  Import a project from a ZIP archive
     (select an archive from movethis/ or enter a path → confirm target
      path → checksum verification → conflict check with backup option →
      restore → verification)

3  List Claude Code projects on this system
     (path, session count, state size, last activity, active flag)

4  Inspect an archive (manifest)
     (select an archive from movethis/ or enter a path → source host,
      Claude Code version, sessions, entry statistics)

5  Quit

Archive structure

20260711_MyProject.zip
├── manifest.json                      # versions, source identity, SHA-256 per entry
├── claude/
│   ├── projects/<encoded>/            # transcripts, subagents, tool results, memory
│   ├── file-history/<session-uuid>/   # file checkpoints
│   ├── session-env/<session-uuid>/    # session environment
│   ├── tasks/<session-uuid>/          # task state
│   ├── plans/*.md                     # referenced plans
│   ├── paste-cache/*                  # referenced paste blobs
│   ├── history.export.jsonl           # filtered global history lines
│   └── project-config.json            # ~/.claude.json project fragment
└── workdir/                           # the complete working directory

Path rewriting

Claude Code keys everything on the absolute project path, encoded by turning every non-alphanumeric character into - (so /home/user/AIKI/MyProject becomes -home-user-AIKI-MyProject). On import, ClaudeMover replaces four things — the old project path, your old home directory, and the encoded form of each — all in one pass, so a replacement can't be caught and mangled by a later rule.

Content Rewritten
Session transcripts (*.jsonl) ✓ per line, on the JSON
Metadata and config (*.json) ✓ on the JSON
Tool results, plans, memory (*.txt, *.md) ✓ as text
Working directory files ✗ left untouched
File-history checkpoints ✗ left untouched (has to match what the transcript recorded)
Paste-cache blobs ✗ left untouched (named by content hash)

After the import, a check confirms that every session transcript is there, the old path is gone and the new one is present. If the rewriting ever went wrong, the import stops and says so rather than leaving you with a project that looks fine but quietly isn't.

Project structure

ClaudeMover/
├── movethis/              # Default export directory (created on demand)
├── ClaudeMover.py         # The application (one file)
├── ClaudeMover.log        # Log file (created on demand)
├── LICENSE                # MIT license
└── README.md              # This file

License

This project is licensed under the MIT license, providing users with flexibility and freedom to use and modify the software according to their needs.

Contributing

Contributions are welcome! Please fork the repository and submit a pull request for review.

Disclaimer

This project is provided without warranties of any kind. The Claude Code session format is internal to Anthropic and may change with any release — always test a migrated project (a --dry-run first, and a glance at the verification output, go a long way) before you delete anything on the source machine. You are responsible for how you use whatever this tool produces.

Conclusion

This one started with a plain annoyance: switching machines meant losing the context of a session and paying, in tokens, to teach Claude a project it already knew inside out. ClaudeMover packs the whole state into one ZIP, moves it, fixes the paths, and checks its own work — you stay in control, nothing is overwritten without a backup first, and everything ends up in the log. Greetings to my dear colleagues who avoid scripts like the plague and think consoles and Bash are some sort of dark magic — the menu will spare you the console kung-fu. For everyone else: clone, run, move. 😉

About

ClaudeMover moves a whole Claude Code project from one Linux machine to another — not just your project files.

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Contributors

Languages