Move or rename Claude Code projects without losing session history and context
Project description
claudepath
Move or rename Claude Code projects without losing session history, memory, and context.
The Problem
When you move or rename a project directory, Claude Code loses all your session history because sessions are keyed to the absolute path of your project. You end up with orphaned data in ~/.claude/projects/ and a fresh start.
claudepath fixes this by updating all path references in Claude Code's data files after a move.
Installation
# With pipx (recommended — isolated install)
pipx install claudepath
# With pip
pip install claudepath
Homebrew (macOS/Linux)
brew tap Mahiler1909/tools
brew install claudepath
Usage
Move a project
Moves the directory on disk and updates all Claude Code references:
claudepath mv ~/old/location/my-project ~/new/location/my-project
Remap after a manual move
If you already moved the directory yourself, just update Claude's references:
claudepath remap ~/old/location/my-project ~/new/location/my-project
Preview changes (dry run)
See exactly what would change without modifying anything:
claudepath mv ~/old/path ~/new/path --dry-run
List tracked projects
claudepath list
Update claudepath
Update to the latest version — auto-detects whether you installed via Homebrew or pipx:
claudepath update
You can also force a specific method:
claudepath update --brew
claudepath update --pipx
claudepath update --pip
Restore from backup
List and restore from automatic backups:
claudepath restore --list # see available backups
claudepath restore # restore the latest backup
claudepath restore 20260227_145300 # restore a specific backup
Merge sessions when destination already has Claude data
If you opened Claude Code at the new location before running claudepath remap, Claude Code will have already created a new project directory there. Use --merge to combine the sessions from both directories:
claudepath remap ~/old/path ~/new/path --merge
Without --merge, claudepath will fail with a clear error suggesting you add the flag.
Full help
claudepath help
claudepath mv --help
What it updates
| File / Directory | What changes |
|---|---|
~/.claude/projects/{encoded-dir}/ |
Renamed to match new path |
sessions-index.json |
originalPath, projectPath, fullPath updated (proper JSON parsing) |
{session}.jsonl files |
cwd and file path references updated (line-by-line, handles large files) |
Subagent .jsonl files |
Same as above, recursive |
~/.claude/history.jsonl |
project field updated for all matching entries |
usage-data/session-meta/*.json |
project_path updated (token usage & analytics) |
Note:
file-history/,todos/,tasks/, andshell-snapshots/are keyed by session UUID, not by project path — they don't need updating.
Options
| Flag | Description |
|---|---|
--dry-run |
Preview all changes without writing anything |
--no-backup |
Skip creating a backup before modifying files |
--yes / -y |
Skip the confirmation prompt |
--merge |
Merge sessions when destination already has Claude data |
--verbose / -v |
Show detailed file-by-file processing output |
--claude-dir <path> |
Override the Claude data directory (default: ~/.claude) |
Environment Variables
| Variable | Description |
|---|---|
NO_COLOR |
Disable colored output (set to any value) |
FORCE_COLOR |
Force colored output even when not a TTY |
Backup & Rollback
By default, claudepath creates a backup before making any changes:
~/.claude/backups/claudepath/{timestamp}/
The backup includes:
- The full project data directory (
~/.claude/projects/{encoded}/) ~/.claude/history.jsonl- Affected
usage-data/session-meta/*.jsonfiles (token usage & analytics) - When using
--merge: both the source and destination project directories
If any step fails, claudepath automatically restores from the backup. Use --no-backup only if you already have your own backup or want to skip the extra time.
How Claude Code encodes paths
Claude Code stores project data in ~/.claude/projects/ using an encoded directory name: every / in the absolute path is replaced with -.
/Users/foo/my-project → -Users-foo-my-project
This means moving /Users/foo/old-name to /Users/foo/new-name requires:
- Renaming
-Users-foo-old-nameto-Users-foo-new-name - Updating all path strings inside the data files
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file claudepath-1.1.1.tar.gz.
File metadata
- Download URL: claudepath-1.1.1.tar.gz
- Upload date:
- Size: 30.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
428723ec64f9d3ab94cadc3c9ad463688669a5436fd130f57ff97c7c4ecaa8b0
|
|
| MD5 |
cb821a6e1e3c2305e09e311a8998188a
|
|
| BLAKE2b-256 |
87f1bbb20b577b4cc1cdbdc87b617e016dcdeea57247cfb887f9fdfc71ba456c
|
Provenance
The following attestation bundles were made for claudepath-1.1.1.tar.gz:
Publisher:
publish.yml on Mahiler1909/claudepath
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claudepath-1.1.1.tar.gz -
Subject digest:
428723ec64f9d3ab94cadc3c9ad463688669a5436fd130f57ff97c7c4ecaa8b0 - Sigstore transparency entry: 1044766894
- Sigstore integration time:
-
Permalink:
Mahiler1909/claudepath@e99d4669394f7be7b51d6db3fb60ae77f0a36106 -
Branch / Tag:
refs/tags/v1.1.1 - Owner: https://github.com/Mahiler1909
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e99d4669394f7be7b51d6db3fb60ae77f0a36106 -
Trigger Event:
push
-
Statement type:
File details
Details for the file claudepath-1.1.1-py3-none-any.whl.
File metadata
- Download URL: claudepath-1.1.1-py3-none-any.whl
- Upload date:
- Size: 21.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
68099589696c178c640fa33f2a9d3ef92e0239c5bb7c9cbb9ff7682047a75f3c
|
|
| MD5 |
7d7dbf47970f067cf1f2bb470eb7b1c5
|
|
| BLAKE2b-256 |
0417ac0acd3ec91ed26db0c575f1207baf69879fd429e7e5c52eab78b0017f3a
|
Provenance
The following attestation bundles were made for claudepath-1.1.1-py3-none-any.whl:
Publisher:
publish.yml on Mahiler1909/claudepath
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claudepath-1.1.1-py3-none-any.whl -
Subject digest:
68099589696c178c640fa33f2a9d3ef92e0239c5bb7c9cbb9ff7682047a75f3c - Sigstore transparency entry: 1044766947
- Sigstore integration time:
-
Permalink:
Mahiler1909/claudepath@e99d4669394f7be7b51d6db3fb60ae77f0a36106 -
Branch / Tag:
refs/tags/v1.1.1 - Owner: https://github.com/Mahiler1909
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e99d4669394f7be7b51d6db3fb60ae77f0a36106 -
Trigger Event:
push
-
Statement type: