Skip to content

Instantly share code, notes, and snippets.

@gwpl
Created June 2, 2025 19:38
Show Gist options
  • Save gwpl/e0b78a711b4a6b2fc4b594c9b9fa2c4c to your computer and use it in GitHub Desktop.
Save gwpl/e0b78a711b4a6b2fc4b594c9b9fa2c4c to your computer and use it in GitHub Desktop.
Claude Code `--continue` after Directory `mv` move - Migration Guide and Internal Mechanics explanation

Claude Code Continue Functionality: Directory Migration Guide ( Claude Code --continue after Directory mv move - Migration Guide and Internal Mechanics explanation )

This guide explains how to preserve Claude Code's --continue functionality when moving project directories, along with the underlying mechanics.

Note: Claude Code currently lacks built-in directory migration features. Each directory maintains independent conversation sessions, and history doesn't automatically transfer when projects are moved.

Quick Fix: Steps to Maintain Continue History

When you move a project directory and want to preserve your conversation history:

1. Identify the Old and New Encoded Paths

Claude encodes directory paths by replacing forward slashes with hyphens:

# Original path
/home/user/projects/myapp

# Encoded path
-home-user-projects-myapp

2. Locate Your History Directory

Your conversation history is stored in:

~/.claude/projects/[encoded-directory-path]/

3. Rename the History Directory

After moving your project, rename the history directory to match:

# If you moved from:
/home/user/old-location/project
# To:
/home/user/new-location/project

# Run:
cd ~/.claude/projects/
mv -- -home-user-old-location-project -home-user-new-location-project

# Note: Use -- to prevent mv from interpreting the hyphen as an option

4. Verify

Navigate to your new project directory and run:

claude --continue

Your conversation history should be restored.

Alternative Approaches

Symbolic Links for History Preservation

If you frequently move directories, create a symbolic link:

# Create a stable location
mkdir -p ~/.claude/projects/stable-links
ln -s ~/.claude/projects/-actual-encoded-path ~/.claude/projects/stable-links/myproject

# When moving, just update the symlink
ln -sfn ~/.claude/projects/-new-encoded-path ~/.claude/projects/stable-links/myproject

Git Worktrees for Parallel Sessions

For maintaining separate conversation contexts on the same codebase:

# From your original repository
cd ~/path/foo
git worktree add ~/path/bar feature-branch

# Each worktree maintains independent Claude sessions
cd ~/path/bar && claude

This provides the cleanest separation while avoiding shared conversation state complexity.

How Claude's Continue System Works

Storage Architecture

Claude CLI uses a file-based storage system with the following structure:

~/.claude/
├── projects/
│   └── [encoded-directory-paths]/
│       ├── [session-uuid].jsonl     # Full conversation history
│       └── [summary-uuid].jsonl     # Conversation summaries
├── settings.json                     # Global user preferences
├── .credentials.json                 # Authentication
└── statsig/                         # Analytics and session tracking

Project-specific files (in your project directory):

project-root/
├── .claude/
│   ├── settings.json                 # Project settings
│   ├── settings.local.json          # Local overrides (gitignored)
│   └── commands/                    # Custom commands
├── CLAUDE.md                        # Project memory/context
└── .mcp.json                       # MCP server configuration

Session Files (JSONL Format)

Each conversation is stored in JSONL (JSON Lines) format, where each line represents a single event:

{"type":"user","message":{"role":"user","content":"Hello"},"timestamp":"2025-06-02T18:46:59.937Z"}
{"type":"assistant","message":{"role":"assistant","content":[{"type":"text","text":"Hi!"}]},"timestamp":"2025-06-02T18:47:06.267Z"}

Each session file includes:

  • parentUuid: Links messages in conversation threads
  • sessionId: Unique identifier for the conversation session
  • cwd: Working directory at message time
  • version: Claude Code version
  • timestamp: ISO 8601 timestamp

Directory Path Encoding

The encoding algorithm:

  1. Take the absolute path of your working directory
  2. Replace all / characters with -
  3. This becomes the directory name under ~/.claude/projects/

Example transformations:

  • /home/alice/code/project-home-alice-code-project
  • /Users/bob/Documents/work-Users-bob-Documents-work
  • /var/www/app-var-www-app

Continue Resolution Process

When you run claude --continue:

  1. Get Current Directory: Claude reads your current working directory (pwd)
  2. Encode Path: Transforms the path using the encoding rules
  3. Find History: Looks for ~/.claude/projects/[encoded-path]/
  4. Load Sessions: Reads all JSONL files in that directory
  5. Resume: Reconstructs the conversation state from the most recent session

Session Management Commands

  • claude --continue: Resumes the most recent conversation in current directory
  • claude --resume: Shows picker to select from previous sessions
  • claude --continue --print "prompt": Continues with specific prompt
  • /compact: Compresses conversation history to save context window

Headless automation:

claude -p "continue our previous work" --output-format stream-json

File Types

  1. Session Files ([uuid].jsonl):

    • Contains complete message history
    • Includes tool uses and results
    • Preserves exact conversation flow
  2. Summary Files ([uuid].jsonl):

    • Contains conversation summaries
    • Used for context when sessions get long
    • Helps with continuation across multiple sessions

Complete Migration Procedure

Step 1: Migrate Configuration Files

After moving from ~/path/foo to ~/path/bar, copy all Claude-specific files:

# Copy project-specific Claude files
cp -r ~/path/foo/.claude ~/path/bar/
cp ~/path/foo/CLAUDE.md ~/path/bar/
cp ~/path/foo/.mcp.json ~/path/bar/

# Update absolute paths in configuration files
sed -i 's|/path/foo|/path/bar|g' ~/path/bar/.claude/settings.json
sed -i 's|/path/foo|/path/bar|g' ~/path/bar/.mcp.json

Step 2: Migrate Conversation History

# Calculate encoded paths
OLD_ENCODED=$(echo "/path/foo" | sed 's/\//-/g')
NEW_ENCODED=$(echo "/path/bar" | sed 's/\//-/g')

# Move history directory
mv ~/.claude/projects/$OLD_ENCODED ~/.claude/projects/$NEW_ENCODED

Best Practices

1. Before Moving Directories

# Check your current encoded path
pwd | sed 's/\//-/g'

# List your existing Claude history
ls ~/.claude/projects/

2. Use Version Control for History

# Back up your Claude history
cd ~/.claude/projects/
git init
git add .
git commit -m "Backup Claude conversation history"

3. Clean Up Old Histories

# Remove histories older than 30 days
find ~/.claude/projects/ -type f -name "*.jsonl" -mtime +30 -delete

# Remove empty project directories
find ~/.claude/projects/ -type d -empty -delete

4. Project-Specific Instructions

Claude reads CLAUDE.md files in your project root for additional context. These move with your project automatically.

5. Automate Migration

Create a migration script:

#!/bin/bash
# claude-migrate.sh
OLD_PATH="$1"
NEW_PATH="$2"

# Encode paths
OLD_ENCODED=$(echo "$OLD_PATH" | sed 's/\//-/g')
NEW_ENCODED=$(echo "$NEW_PATH" | sed 's/\//-/g')

# Move history
if [ -d "$HOME/.claude/projects/$OLD_ENCODED" ]; then
    mv "$HOME/.claude/projects/$OLD_ENCODED" "$HOME/.claude/projects/$NEW_ENCODED"
    echo "Migrated conversation history"
fi

# Copy configuration
for file in .claude CLAUDE.md .mcp.json; do
    if [ -e "$OLD_PATH/$file" ]; then
        cp -r "$OLD_PATH/$file" "$NEW_PATH/"
    fi
done

Troubleshooting

Continue Not Finding History

  1. Verify the encoded path matches:

    echo "Current encoded: $(pwd | sed 's/\//-/g')"
    ls ~/.claude/projects/ | grep "$(basename $(pwd))"
  2. Check for multiple similar directories:

    ls ~/.claude/projects/ | grep -i "$(basename $(pwd))"

Permission Issues

Ensure proper permissions:

chmod -R 700 ~/.claude/

Corrupted History

If history appears corrupted:

  1. Back up the directory
  2. Validate JSONL files:
    for file in ~/.claude/projects/*/**.jsonl; do
      jq empty "$file" 2>/dev/null || echo "Invalid: $file"
    done

Current Limitations

The Claude Code community has actively requested better session persistence features. Current limitations:

  • No automatic session migration between directories
  • Each directory maintains completely independent conversation history
  • No built-in export/import functionality for conversations
  • Manual configuration transfer required when moving projects
  • No cross-directory continuation support

Security Considerations

  • History files may contain sensitive information
  • Set appropriate permissions (700) on ~/.claude/ directory
  • Consider encrypting ~/.claude/ if working with sensitive data
  • Exclude ~/.claude/ from backups if necessary
  • JSONL files contain full conversation content including code snippets

Advanced Tips

Debugging Path Encoding

# View all Claude project histories
ls -la ~/.claude/projects/ | grep "^d"

# Find history for current directory
CURRENT_ENCODED=$(pwd | sed 's/\//-/g')
ls -la ~/.claude/projects/$CURRENT_ENCODED/

# Check latest session
ls -t ~/.claude/projects/$CURRENT_ENCODED/*.jsonl | head -1 | xargs tail -1 | jq

Session File Analysis

# Count messages in a session
wc -l ~/.claude/projects/$CURRENT_ENCODED/*.jsonl

# Extract all user messages
grep '"type":"user"' ~/.claude/projects/$CURRENT_ENCODED/*.jsonl | jq -r '.message.content'

# Find sessions by date
find ~/.claude/projects/ -name "*.jsonl" -newermt "2025-06-01" -ls

Further Reading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment