Skip to content

Instantly share code, notes, and snippets.

@denniswon
Created March 19, 2026 00:08
Show Gist options
  • Select an option

  • Save denniswon/584283a34ef44f493d297c153bede47e to your computer and use it in GitHub Desktop.

Select an option

Save denniswon/584283a34ef44f493d297c153bede47e to your computer and use it in GitHub Desktop.
Migrating development environment
MacBook migration is a surprisingly deep problem — it's not just copying files. You have layered state: dotfiles, package managers,
language runtimes, auth tokens (which can't just be copied), MCP server configs, IDE state, and agent memories scattered across
~/.claude/, ~/.config/, keychains, and more. Getting this right upfront saves days of "why doesn't X work on my new machine."
★ Insight ─────────────────────────────────────
Your environment is substantial — 176 Homebrew formulae, 74 casks, 5 language version managers, blockchain toolchains (Foundry, SP1,
RISC0), Claude Code with 9 plugins, 6 MCP servers, and API keys hardcoded in .zshrc. The biggest risk areas are: (1) secrets
management (API keys in plaintext), (2) auth tokens that can't be copied (need re-auth), and (3) the order of installation (version
managers before languages before tools).
─────────────────────────────────────────────────
Great — I've done a thorough audit of your current machine. Here's what I found at a high level:
Current Environment Summary
┌─────────────────┬──────────────────────────────────────────────────────────────────────────────────────┐
│ Category │ What's There │
├─────────────────┼──────────────────────────────────────────────────────────────────────────────────────┤
│ Shell │ Zsh + Zprezto (wikimatze theme), 5 config files, extensive aliases │
├─────────────────┼──────────────────────────────────────────────────────────────────────────────────────┤
│ Terminal │ WezTerm with custom Lua config │
├─────────────────┼──────────────────────────────────────────────────────────────────────────────────────┤
│ Git │ 65+ custom aliases, delta pager, LFS, interactive rebase tool │
├─────────────────┼──────────────────────────────────────────────────────────────────────────────────────┤
│ Package Manager │ Homebrew: 176 formulae + 74 casks (no Brewfile exists yet) │
├─────────────────┼──────────────────────────────────────────────────────────────────────────────────────┤
│ Languages │ fnm (Node), pyenv (Python), rbenv (Ruby), rustup (Rust + ZK toolchains), Go (system) │
├─────────────────┼──────────────────────────────────────────────────────────────────────────────────────┤
│ Blockchain/ZK │ Foundry, SP1, RISC0, Wasmer, Circom │
├─────────────────┼──────────────────────────────────────────────────────────────────────────────────────┤
│ Claude Code │ 9 plugins (OMC, superpowers, supermemory, etc.), 6 MCP servers, custom HUD │
├─────────────────┼──────────────────────────────────────────────────────────────────────────────────────┤
│ IDEs │ Cursor (primary), Windsurf, VS Code Insiders │
├─────────────────┼──────────────────────────────────────────────────────────────────────────────────────┤
│ Cloud │ gcloud SDK, Azure CLI, GitHub CLI, Granted (AWS) │
├─────────────────┼──────────────────────────────────────────────────────────────────────────────────────┤
│ Keys/Auth │ SSH (ed25519 + GCP + PEM keys), 1Password integration │
├─────────────────┼──────────────────────────────────────────────────────────────────────────────────────┤
│ Secrets │ ~12 API keys hardcoded in .zshrc │
├─────────────────┼──────────────────────────────────────────────────────────────────────────────────────┤
│ Dotfile mgmt │ stow installed but not configured; no active dotfile repo │
├─────────────────┼──────────────────────────────────────────────────────────────────────────────────────┤
│ Projects │ ~15 repos in ~/projects/, plus ~/magic/ │
└─────────────────┴──────────────────────────────────────────────────────────────────────────────────────┘
@denniswon

Copy link
Copy Markdown
Author

MacBook Migration Implementation Plan

For agentic workers: This is a system administration runbook, not a code implementation plan. Steps are shell commands executed across two physical machines. Use superpowers:executing-plans to track progress. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Migrate full development environment from MacBook Pro (M1 Pro, 16GB) to MacBook Pro (M1 Max, 64GB, 16") with zero data loss and a working dev environment on day one.

Architecture: Hybrid approach — Migration Assistant for macOS layer (apps, prefs, documents), scripted Homebrew + stow for dev tools, rsync for project repos.

Spec: docs/superpowers/specs/2026-03-18-macbook-migration-design.md


Phase 1: Prepare Old Machine

All tasks in Phase 1 run on the current (old) MacBook.


Task 1: Generate Brewfile

Machine: Old MacBook
Files:

  • Create: ~/.dotfiles/homebrew/Brewfile

  • Step 1: Create dotfiles directory structure

mkdir -p ~/.dotfiles/homebrew
mkdir -p ~/.dotfiles/setup
  • Step 2: Dump current Homebrew state
brew bundle dump --file=~/.dotfiles/homebrew/Brewfile --force

Expected: File created with brew, cask, and tap entries.

  • Step 3: Verify Brewfile contents
wc -l ~/.dotfiles/homebrew/Brewfile
grep -c '^brew' ~/.dotfiles/homebrew/Brewfile
grep -c '^cask' ~/.dotfiles/homebrew/Brewfile

Expected: ~250+ lines, ~176 brew entries, ~74 cask entries.

  • Step 4: Verify vfox is included
grep 'vfox' ~/.dotfiles/homebrew/Brewfile

Expected: A line with brew "vfox" or similar. If missing, add it manually:

echo 'brew "vfox"' >> ~/.dotfiles/homebrew/Brewfile
  • Step 5: Review and trim Brewfile (optional)

Open in editor and remove any packages you no longer use:

cursor ~/.dotfiles/homebrew/Brewfile

Task 2: Split Secrets from .zshrc

Machine: Old MacBook
Files:

  • Create: ~/.zsh_secrets

  • Modify: ~/.zshrc

  • Step 1: Identify all secret exports in .zshrc

grep -n 'export.*\(API_KEY\|TOKEN\|SECRET\|REDIS_URL\|DD_APP\)' ~/.zshrc

Expected: ~12 lines with API keys, tokens, and secrets.

  • Step 2: Create ~/.zsh_secrets with the secret exports

Extract all secret lines from .zshrc into ~/.zsh_secrets. The file should look like:

# API Keys and Secrets - DO NOT COMMIT TO GIT
export RECALL_API_KEY="..."
export RECALL_REDIS_URL="..."
export ANTHROPIC_API_KEY="..."
export OPENAI_API_KEY="..."
export XAI_API_KEY="..."
export TELEGRAM_BOT_TOKEN="..."
export TELEGRAM_CHAT_ID="..."
export SUPERMEMORY_CC_API_KEY="..."
export SUPERMEMORY_OPENCLAW_API_KEY="..."
export GITHUB_PERSONAL_ACCESS_TOKEN="..."
export DD_API_KEY="..."
export DD_APP_KEY="..."
  • Step 3: Replace secret lines in .zshrc with source command

Remove the individual export lines from .zshrc and add this in their place:

# Secrets (not version-controlled)
[[ -f ~/.zsh_secrets ]] && source ~/.zsh_secrets
  • Step 4: Verify shell still works
source ~/.zshrc
echo $ANTHROPIC_API_KEY  # should print the key value

Expected: Key prints correctly, no errors on source.


Task 3: Fix Known .zshrc Issues

Machine: Old MacBook
Files:

  • Modify: ~/.zshrc

  • Step 1: Fix duplicate LDFLAGS/CPPFLAGS

Find the two conflicting sets (postgresql@16 and llvm) and combine them into one:

export LDFLAGS="-L/opt/homebrew/opt/postgresql@16/lib -L/opt/homebrew/opt/llvm/lib"
export CPPFLAGS="-I/opt/homebrew/opt/postgresql@16/include -I/opt/homebrew/opt/llvm/include"
  • Step 2: Remove duplicate Windsurf PATH entry

Find and remove one of the two identical lines adding ~/.codeium/windsurf/bin to PATH.

  • Step 3: Verify shell still loads cleanly
source ~/.zshrc

Expected: No errors.


Task 4: Create Dotfiles Repo with Stow

Machine: Old MacBook
Files:

  • Create: ~/.dotfiles/ (entire stow structure)

  • Step 1: Initialize git repo

cd ~/.dotfiles
git init
  • Step 2: Create .gitignore
cat > ~/.dotfiles/.gitignore << 'EOF'
.zsh_secrets
*.pem
id_*
google_compute_engine
google_compute_engine.pub
.DS_Store
EOF
  • Step 3: Create stow package directories
mkdir -p ~/.dotfiles/zsh
mkdir -p ~/.dotfiles/git
mkdir -p ~/.dotfiles/wezterm
mkdir -p ~/.dotfiles/ssh/.ssh
mkdir -p ~/.dotfiles/karabiner/.config/karabiner
mkdir -p ~/.dotfiles/claude/.claude
mkdir -p ~/.dotfiles/bin/bin
mkdir -p ~/.dotfiles/gh/.config/gh
  • Step 4: Copy zsh files into stow package
cp ~/.zshrc ~/.dotfiles/zsh/
cp ~/.zpreztorc ~/.dotfiles/zsh/
cp ~/.zprofile ~/.dotfiles/zsh/
cp ~/.zshenv ~/.dotfiles/zsh/
cp ~/.zlogin ~/.dotfiles/zsh/
# Copy .zfunc if it exists
[ -d ~/.zfunc ] && cp -r ~/.zfunc ~/.dotfiles/zsh/
  • Step 5: Copy git config
cp ~/.gitconfig ~/.dotfiles/git/
  • Step 6: Copy WezTerm config
cp ~/.wezterm.lua ~/.dotfiles/wezterm/
  • Step 7: Copy SSH config (not private keys)
cp ~/.ssh/config ~/.dotfiles/ssh/.ssh/
cp ~/.ssh/azure_known_hosts ~/.dotfiles/ssh/.ssh/
cp ~/.ssh/google_compute_known_hosts ~/.dotfiles/ssh/.ssh/
  • Step 8: Copy Karabiner config
cp ~/.config/karabiner/karabiner.json ~/.dotfiles/karabiner/.config/karabiner/
  • Step 9: Copy Claude Code config (excluding ephemeral files)
# Core config files
cp ~/.claude/CLAUDE.md ~/.dotfiles/claude/.claude/
cp ~/.claude/settings.json ~/.dotfiles/claude/.claude/
[ -f ~/.claude/settings.local.json ] && cp ~/.claude/settings.local.json ~/.dotfiles/claude/.claude/
cp ~/.claude/recall-mcp-setup.md ~/.dotfiles/claude/.claude/
cp ~/.claude/recall-proxy.mjs ~/.dotfiles/claude/.claude/

# Directories (excluding cache and ephemeral)
cp -r ~/.claude/projects/ ~/.dotfiles/claude/.claude/projects/
cp -r ~/.claude/agents/ ~/.dotfiles/claude/.claude/agents/
cp -r ~/.claude/commands/ ~/.dotfiles/claude/.claude/commands/
cp -r ~/.claude/skills/ ~/.dotfiles/claude/.claude/skills/
cp -r ~/.claude/hud/ ~/.dotfiles/claude/.claude/hud/

# Plugins (manifests only, not cache)
mkdir -p ~/.dotfiles/claude/.claude/plugins
# Copy plugin list/config but not the cache directory
rsync -a --exclude='cache/' ~/.claude/plugins/ ~/.dotfiles/claude/.claude/plugins/
  • Step 10: Copy bin scripts
cp ~/bin/sync-claude.sh ~/.dotfiles/bin/bin/
cp ~/bin/pull-claude.sh ~/.dotfiles/bin/bin/
cp ~/bin/smart-sync-claude.sh ~/.dotfiles/bin/bin/
cp ~/bin/vim ~/.dotfiles/bin/bin/
  • Step 11: Copy gh config
cp ~/.config/gh/config.yml ~/.dotfiles/gh/.config/gh/
cp ~/.config/gh/hosts.yml ~/.dotfiles/gh/.config/gh/
  • Step 12: Verify stow structure
find ~/.dotfiles -type f | head -40

Expected: Files organized under package directories matching home directory structure.


Task 5: Export Language Runtime State

Machine: Old MacBook
Files:

  • Create: ~/.dotfiles/setup/ (version snapshots)

  • Step 1: Export Node.js state

fnm list > ~/.dotfiles/setup/node-versions.txt
fnm default >> ~/.dotfiles/setup/node-versions.txt
npm list -g --depth=0 > ~/.dotfiles/setup/node-globals.txt
  • Step 2: Export Python state
pyenv versions > ~/.dotfiles/setup/python-versions.txt
pipx list --short > ~/.dotfiles/setup/pipx-packages.txt
  • Step 3: Export Ruby state
rbenv versions > ~/.dotfiles/setup/ruby-versions.txt
  • Step 4: Export Rust state
rustup toolchain list > ~/.dotfiles/setup/rust-toolchains.txt
cargo install --list > ~/.dotfiles/setup/cargo-packages.txt
  • Step 5: Export Go state
go version > ~/.dotfiles/setup/go-version.txt
  • Step 6: Verify exports
ls -la ~/.dotfiles/setup/
cat ~/.dotfiles/setup/node-versions.txt

Expected: 7+ files in setup directory, Node versions listed.


Task 6: Commit and Push Dotfiles

Machine: Old MacBook

  • Step 1: Add remote and push

The repo denniswon/mbp-migrate already exists (private).

cd ~/.dotfiles
git add -A
git commit -m "Initial dotfiles snapshot for MacBook migration"
git remote add origin git@github.com:denniswon/mbp-migrate.git
git push -u origin main
  • Step 2: Verify push succeeded
git log --oneline -1
git remote -v

Expected: Commit hash shown, remote points to GitHub.


Phase 2: Migration Assistant

Task 7: Run Migration Assistant

Machine: New MacBook (first boot)

  • Step 1: Unbox and power on new MacBook

During initial macOS setup, select "Transfer Information to This Mac" when prompted.

  • Step 2: Choose transfer method

Options (in order of speed):

  1. Thunderbolt cable (fastest — use a USB-C cable between both machines)
  2. Wi-Fi Direct (slower, no cable needed)
  • Step 3: Select what to transfer

Transfer everything — Migration Assistant handles: apps, system preferences, documents, photos, keychain, 1Password, Raycast, Karabiner, fonts, user account.

  • Step 4: Wait for transfer to complete

Expected: 1-3 hours depending on data size and connection method.

  • Step 5: Verify macOS layer
- 1Password: opens and unlocks ✓
- Raycast: launches with extensions ✓
- Karabiner: app present (config applied later via stow) ✓
- Cursor: launches ✓
- Docker Desktop: launches ✓
- System preferences: keyboard, trackpad, display settings correct ✓
  • Step 6: Back up and remove Homebrew remnants
ls /opt/homebrew/  # check what Migration Assistant copied
sudo mv /opt/homebrew /opt/homebrew.bak

Expected: Old Homebrew directory moved to backup. Will delete after Phase 3 succeeds.


Phase 3: Dev Environment Setup

All tasks in Phase 3 run on the new MacBook.


Task 8: Install Foundation (Xcode + Homebrew)

Machine: New MacBook

  • Step 1: Install Xcode Command Line Tools
xcode-select --install

Expected: Dialog appears, click Install. Wait for completion (~5 min).

  • Step 2: Install Homebrew
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  • Step 3: Add Homebrew to PATH for current session
eval "$(/opt/homebrew/bin/brew shellenv)"
  • Step 4: Verify Homebrew
brew --version
which brew

Expected: Homebrew version printed, path is /opt/homebrew/bin/brew.


Task 9: Transfer SSH Keys and Secrets

Machine: New MacBook (receiving from old MacBook)

SSH keys must be transferred before cloning the dotfiles repo (which requires SSH auth).

  • Step 1: AirDrop SSH private keys from old MacBook

From old MacBook, AirDrop these files:

  • ~/.ssh/id_ed25519

  • ~/.ssh/id_ed25519.pub

  • ~/.ssh/google_compute_engine

  • ~/.ssh/google_compute_engine.pub

  • ~/.ssh/newton.pem

  • ~/.ssh/tdx-prover-temp.pem

  • Step 2: AirDrop secrets file

From old MacBook, AirDrop:

  • ~/.zsh_secrets (rename to zsh_secrets before sending — macOS Finder hides dot-prefixed files)

Note: If dot-files don't appear in Finder, use terminal: ls -la ~/Downloads/ or check Finder > Go > AirDrop.

  • Step 3: Move files to correct locations
mkdir -p ~/.ssh
# Move SSH keys from Downloads (where AirDrop puts them)
mv ~/Downloads/id_ed25519 ~/.ssh/
mv ~/Downloads/id_ed25519.pub ~/.ssh/
mv ~/Downloads/google_compute_engine ~/.ssh/
mv ~/Downloads/google_compute_engine.pub ~/.ssh/
mv ~/Downloads/newton.pem ~/.ssh/
mv ~/Downloads/tdx-prover-temp.pem ~/.ssh/
# Move secrets (rename back if sent without dot prefix)
mv ~/Downloads/zsh_secrets ~/.zsh_secrets 2>/dev/null || mv ~/Downloads/.zsh_secrets ~/.zsh_secrets
  • Step 4: Fix permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 600 ~/.ssh/google_compute_engine
chmod 600 ~/.ssh/newton.pem
chmod 600 ~/.ssh/tdx-prover-temp.pem
chmod 644 ~/.ssh/*.pub
  • Step 5: Verify SSH works
ssh -T git@github.com

Expected: Hi dennis-won! You've successfully authenticated...


Task 10: Clone Dotfiles and Install Homebrew Packages

Machine: New MacBook

  • Step 1: Clone dotfiles repo (SSH keys are now in place)
git clone git@github.com:denniswon/mbp-migrate.git ~/.dotfiles
  • Step 2: Install all packages from Brewfile
brew bundle install --file=~/.dotfiles/homebrew/Brewfile

Expected: All 176 formulae + 74 casks install. Some casks may prompt for password. This step takes 15-30 minutes.

  • Step 3: Verify key packages installed
brew list | grep -E 'fnm|pyenv|rbenv|stow|direnv|git-delta|fzf|vfox|gh'

Expected: All listed packages appear.


Task 11: Stow Dotfiles

Machine: New MacBook

  • Step 1: Remove config files Migration Assistant may have copied

Stow will refuse to create symlinks if real files already exist. Clean them up first:

rm -f ~/.zshrc ~/.zpreztorc ~/.zprofile ~/.zshenv ~/.zlogin ~/.gitconfig ~/.wezterm.lua
# Check if ~/.claude/ exists as a real directory (not from stow)
ls -la ~/.claude/ 2>/dev/null && echo "WARNING: ~/.claude/ exists — back up if needed, then: rm -rf ~/.claude/"
  • Step 2: Run stow for all packages
cd ~/.dotfiles
stow zsh git wezterm ssh karabiner claude bin gh

Expected: No errors. Symlinks created in home directory.

  • Step 3: Verify symlinks created
ls -la ~/.zshrc        # should point to .dotfiles/zsh/.zshrc
ls -la ~/.gitconfig    # should point to .dotfiles/git/.gitconfig
ls -la ~/.wezterm.lua  # should point to .dotfiles/wezterm/.wezterm.lua
ls -la ~/.ssh/config   # should point to .dotfiles/ssh/.ssh/config
ls -la ~/.claude/CLAUDE.md  # should point to .dotfiles/claude/.claude/CLAUDE.md

Expected: All files are symlinks to ~/.dotfiles/....

  • Step 4: Verify SSH config paths
grep '/Users/' ~/.ssh/config

Expected: All paths reference /Users/dennis.won/. If the username is different on the new machine, update the paths.

  • Step 5: Ensure bin scripts are executable
chmod +x ~/bin/*

Task 12: Install Zprezto

Machine: New MacBook

  • Step 1: Clone Zprezto
git clone --recursive https://github.com/sorin-ionescu/prezto.git "${ZDOTDIR:-$HOME}/.zprezto"
  • Step 2: Restart shell

Close and reopen terminal (or run exec zsh).

  • Step 3: Verify prompt

Expected: Zprezto wikimatze theme renders with git info, colored prompt.

  • Step 4: Verify aliases work
type cpush
type ezc

Expected: Alias definitions printed.


Task 13: Install Language Runtimes

Machine: New MacBook

  • Step 1: Install Node.js versions via fnm
eval "$(fnm env)"
fnm install 22.22.0
fnm default 22.22.0
fnm install 20.10.0
fnm install 24.11.1
  • Step 2: Verify Node
node -v

Expected: v22.22.0

  • Step 3: Install Python via pyenv
eval "$(pyenv init -)"
pyenv install 3.13.11
pyenv global 3.13.11
  • Step 4: Verify Python
python --version

Expected: Python 3.13.11

  • Step 5: Install Ruby via rbenv
eval "$(rbenv init -)"
rbenv install 3.3.5
rbenv global 3.3.5
  • Step 6: Verify Ruby
ruby -v

Expected: ruby 3.3.5

  • Step 7: Install Rust via rustup
rustup-init -y
source "$HOME/.cargo/env"
rustup toolchain install stable
rustup toolchain install nightly

Review ~/.dotfiles/setup/rust-toolchains.txt for specialized toolchains (risc0, succinct) and install as needed.

  • Step 8: Verify Rust
rustc --version
cargo --version

Expected: Stable toolchain version printed.

  • Step 9: Verify Go (installed via Homebrew in Task 9)
go version

Expected: go1.23.x darwin/arm64 or newer.


Task 14: Install Global Packages

Machine: New MacBook

  • Step 1: Install Node globals
npm install -g openclaw corepack
  • Step 2: Enable pnpm via corepack
corepack enable
  • Step 3: Verify pnpm
pnpm --version

Expected: Version string.

  • Step 4: Generate OpenClaw completions
mkdir -p ~/.openclaw/completions
openclaw completions zsh > ~/.openclaw/completions/openclaw.zsh
  • Step 5: Install Python tools via pipx
pipx install poetry
pipx install jupyter-lab
pipx install towncrier
  • Step 6: Install Cargo tools from exported list
# Use the exported list for accuracy
cat ~/.dotfiles/setup/cargo-packages.txt | grep -E '^\w' | awk '{print $1}' | tr -d ':' | xargs cargo install

Or install manually if the parsing is tricky:

cargo install cargo-edit cargo-pgrx cargo-shear circom cocogitto cross just svm-rs sqlx-cli

Expected: Each tool compiles and installs. This step takes 10-20 minutes.


Task 15: Install Blockchain Toolchains

Machine: New MacBook

  • Step 1: Install Foundry
curl -L https://foundry.paradigm.xyz | bash
source ~/.zshrc  # load foundryup into PATH
foundryup
  • Step 2: Verify Foundry
forge --version
cast --version
anvil --version

Expected: Version strings for all three tools.

  • Step 3: Install SP1
curl -L https://sp1.succinct.xyz | bash
source ~/.zshrc
sp1up
  • Step 4: Install RISC0
curl -L https://risczero.com/install | bash
source ~/.zshrc
rzup install
  • Step 5: Install Wasmer
curl https://get.wasmer.io -sSfL | sh

Note: Any Wasmer packages from the old machine need to be reinstalled separately.

  • Step 6: Check if installers modified .zshrc

Foundry, SP1, and RISC0 installers may append lines to .zshrc. Since .zshrc is a symlink to the dotfiles repo, these changes modify the stowed file directly. Check and commit:

cd ~/.dotfiles
git diff
# If changes look correct:
git add -A && git commit -m "Add blockchain toolchain PATH entries from installers"

Task 16: Install Claude Code

Machine: New MacBook

  • Step 1: Install Claude Code CLI
curl -fsSL https://claude.ai/install.sh | sh
  • Step 2: Verify stow placed configs
ls -la ~/.claude/CLAUDE.md
ls -la ~/.claude/settings.json

Expected: Both are symlinks to ~/.dotfiles/claude/.claude/....

  • Step 3: Install plugins
claude plugins install oh-my-claudecode
claude plugins install superpowers
claude plugins install claude-supermemory
claude plugins install claude-md-management
claude plugins install claude-code-setup
claude plugins install plugin-dev
claude plugins install skill-creator
claude plugins install learning-output-style
claude plugins install rust-analyzer-lsp
  • Step 4: Verify MCP servers
claude mcp list

Expected: 6 servers listed (context7, exa, github, slack, cloudflare, recall).

  • Step 5: Verify Claude Code launches
claude --version

Expected: Version 2.x.


Task 17: Install Google Cloud SDK

Machine: New MacBook

  • Step 1: Install SDK
curl https://sdk.cloud.google.com | bash

Follow prompts. Install to ~/google-cloud-sdk/ (default).

  • Step 2: Restart shell
exec zsh
  • Step 3: Initialize and authenticate
gcloud init
gcloud auth login
gcloud auth application-default login

Task 18: Re-Authenticate Services

Machine: New MacBook

  • Step 1: GitHub CLI
gh auth login

Select: GitHub.com → SSH → existing key.

  • Step 2: Azure CLI
az login
  • Step 3: Launch Docker Desktop

Open Docker Desktop from Applications. Wait for it to fully start (whale icon in menu bar stops animating). This regenerates ~/.docker/completions/ which was lost when Homebrew was wiped.

  • Step 4: Docker Hub
docker login
  • Step 5: Verify Docker completions
ls ~/.docker/completions/

Expected: Completion files present (created by Docker Desktop on launch).

  • Step 6: Slack MCP (if needed)

Re-authenticate via Claude Code — the OAuth token doesn't transfer.


Phase 4: rsync Projects

Task 19: Transfer Project Repos

Machine: Both (old provides, new receives)

  • Step 1: Enable Remote Login on old MacBook

On old MacBook: System Settings → General → Sharing → Remote Login → ON

  • Step 2: Find old MacBook's IP

On old MacBook:

ifconfig | grep "inet " | grep -v 127.0.0.1

Note the IP address (e.g., 192.168.1.xxx).

  • Step 3: rsync projects (from new MacBook)
rsync -aH --progress dennis.won@<OLD_IP>:~/projects/ ~/projects/

Expected: All repos transfer with git state intact. Time depends on total size.

  • Step 4: rsync magic directory
rsync -aH --progress dennis.won@<OLD_IP>:~/magic/ ~/magic/
  • Step 5: rsync Go workspace
rsync -aH --progress dennis.won@<OLD_IP>:~/go/ ~/go/
  • Step 6: Verify a project's git state
cd ~/projects
ls
cd <any-project>
git status
git log --oneline -3
git stash list

Expected: Working tree, history, and stashes all intact.


Phase 5: Verification

Task 20: Full Verification Checklist

Machine: New MacBook

  • Step 1: Shell and tools
Check Command Expected
Shell prompt Open new terminal Zprezto wikimatze theme renders
Zsh aliases type cpush Shows alias definition
Secrets loaded echo $ANTHROPIC_API_KEY Key value prints
direnv cd into project with .envrc Loads environment
vfox vfox --version Version string
  • Step 2: Language runtimes
Check Command Expected
Node.js node -v v22.22.0
pnpm pnpm --version Version string
Python python --version 3.13.11
Ruby ruby -v 3.3.5
Rust rustc --version stable
Go go version 1.23.x+
  • Step 3: Dev tools
Check Command Expected
Git identity git config user.email jhwon0820@gmail.com
Git delta git log --oneline -5 (in any repo) Colored delta output
SSH auth ssh -T git@github.com "Hi dennis-won!"
Foundry forge --version Version string
Docker docker --version 29.x
  • Step 4: Claude Code
Check Command Expected
CLI claude --version 2.x
MCP servers claude mcp list 6 servers listed
Plugins claude plugins list 9 plugins
  • Step 5: Apps and GUI
Check Action Expected
WezTerm Open WezTerm Custom config loads
Windsurf windsurf --version Version string
Karabiner Check remappings Active
GitHub CLI gh auth status Authenticated
OpenClaw completions ls ~/.openclaw/completions/ openclaw.zsh exists
Docker completions ls ~/.docker/completions/ Files present
  • Step 6: Clean up Homebrew backup

Once everything is verified working:

sudo rm -rf /opt/homebrew.bak

Summary

Phase Tasks Estimated Time
Phase 1: Prepare old machine Tasks 1-6 30-60 min
Phase 2: Migration Assistant Task 7 1-3 hours
Phase 3: Dev environment setup Tasks 8-18 1-2 hours
Phase 4: rsync projects Task 19 30-60 min
Phase 5: Verification Task 20 20-30 min
Total 20 tasks 3-7 hours

Rollback: Old machine remains untouched. If anything fails, the old MacBook is still fully functional and you can re-run any phase independently.

@denniswon

Copy link
Copy Markdown
Author

Here's the condensed step-by-step for migration day:

Phase 2: Migration Assistant

  1. Unbox, power on, select "Transfer from another Mac" during setup
  2. Connect via Thunderbolt cable (fastest) or Wi-Fi
  3. Transfer everything — wait 1-3 hours
  4. Verify: 1Password, Raycast, Karabiner, Cursor, Docker Desktop all launch
  5. Back up and remove old Homebrew: sudo mv /opt/homebrew /opt/homebrew.bak

Phase 3: Dev Environment (run in Terminal)

Foundation:
6. xcode-select --install
7. /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
8. eval "$(/opt/homebrew/bin/brew shellenv)"

SSH + Secrets (before cloning repo):
9. Download .ssh/ and .zsh_secrets from Google Drive
10. Place them: mkdir -p ~/.ssh && cp -r ~/Downloads/.ssh/* ~/.ssh/ && mv ~/Downloads/.zsh_secrets ~/
11. Fix permissions: chmod 700 ~/.ssh && chmod 600 ~/.ssh/id_ed25519 ~/.ssh/google_compute_engine ~/.ssh/.pem && chmod 644
~/.ssh/
.pub
12. Test: ssh -T git@github.com

Dotfiles + Packages:
13. git clone git@github.com:denniswon/mbp-migrate.git /.dotfiles
14. brew bundle install --file=
/.dotfiles/homebrew/Brewfile (15-30 min)
15. Remove conflicting files: rm -f ~/.zshrc ~/.zpreztorc ~/.zprofile ~/.zshenv ~/.zlogin ~/.gitconfig ~/.wezterm.lua
16. cd ~/.dotfiles && stow zsh git wezterm ssh karabiner claude bin gh
17. Verify SSH paths: grep '/Users/' ~/.ssh/config (update if username differs)

Zprezto:
18. git clone --recursive https://github.com/sorin-ionescu/prezto.git ~/.zprezto
19. exec zsh — verify prompt renders

Languages:
20. fnm install 22.22.0 && fnm default 22.22.0 && fnm install 20.10.0 && fnm install 24.11.1
21. pyenv install 3.13.11 && pyenv global 3.13.11
22. rbenv install 3.3.5 && rbenv global 3.3.5
23. rustup-init -y && source ~/.cargo/env && rustup toolchain install stable nightly

Global packages:
24. npm install -g openclaw corepack && corepack enable
25. mkdir -p ~/.openclaw/completions && openclaw completions zsh > ~/.openclaw/completions/openclaw.zsh
26. pipx install poetry && pipx install jupyter-lab && pipx install towncrier
27. cat ~/.dotfiles/setup/cargo-packages.txt | grep -E '^\w' | awk '{print $1}' | tr -d ':' | xargs cargo install

Blockchain:
28. curl -L https://foundry.paradigm.xyz | bash && source ~/.zshrc && foundryup
29. curl -L https://sp1.succinct.xyz | bash && source ~/.zshrc && sp1up
30. curl -L https://risczero.com/install | bash && source ~/.zshrc && rzup install
31. curl https://get.wasmer.io -sSfL | sh
32. Check if installers modified .zshrc: cd ~/.dotfiles && git diff — commit if so

Claude Code:
33. curl -fsSL https://claude.ai/install.sh | sh
34. Install plugins (9 commands — see plan file)
35. claude mcp list — verify 6 servers

Google Cloud + Auth:
36. curl https://sdk.cloud.google.com | bash && exec zsh && gcloud init && gcloud auth login
37. gh auth login
38. az login
39. Launch Docker Desktop, then docker login

Phase 4: rsync Projects

  1. Enable Remote Login on old MacBook (System Settings → General → Sharing)
  2. From new MacBook:
    rsync -aH --progress dennis.won@<OLD_IP>:~/projects/ /projects/
    rsync -aH --progress dennis.won@<OLD_IP>:
    /magic/ /magic/
    rsync -aH --progress dennis.won@<OLD_IP>:
    /go/ ~/go/

Phase 5: Verify

  1. Run through the verification checklist in the plan file
  2. Clean up: sudo rm -rf /opt/homebrew.bak

@denniswon

Copy link
Copy Markdown
Author

⏺ ★ Insight ─────────────────────────────────────
The bootstrapping problem: Claude Code needs Homebrew, Node.js, and shell config to run — but those are what you're trying to install.
You need to do a minimal manual bootstrap first, then let Claude Code handle the rest.
─────────────────────────────────────────────────

Here's the minimum you need to do manually before Claude Code can take over:

Manual Bootstrap (10-15 min)

1. Migration Assistant (already done at this point)

2. Back up old Homebrew

sudo mv /opt/homebrew /opt/homebrew.bak

3. Xcode CLI tools

xcode-select --install

4. Homebrew

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
eval "$(/opt/homebrew/bin/brew shellenv)"

5. SSH keys + secrets from Google Drive

Download from: https://drive.google.com/drive/u/0/folders/1yZ4vZSQ7IH6zVTjtLyvMMYikKaPQm1Iq

mkdir -p ~/.ssh
cp -r ~/Downloads/.ssh/* ~/.ssh/
mv ~/Downloads/.zsh_secrets ~/
chmod 700 ~/.ssh && chmod 600 ~/.ssh/id_ed25519 ~/.ssh/google_compute_engine ~/.ssh/.pem && chmod 644 ~/.ssh/.pub

6. Clone dotfiles (needs SSH key in place)

git clone git@github.com:denniswon/mbp-migrate.git ~/.dotfiles

7. Install Claude Code

curl -fsSL https://claude.ai/install.sh | sh

Then Hand It Off to Claude Code

claude

Once inside Claude, say:

▎ Follow the migration plan at ~/.dotfiles/../docs/superpowers/plans/2026-03-18-macbook-migration.md — start from Task 10 Step 2 (brew
bundle install). I've already done Tasks 7-10 Step 1 manually. Execute the remaining tasks through Phase 5.

Claude Code will then handle: Brewfile install, stow, Zprezto, all language runtimes, global packages, blockchain toolchains, plugin
installs, MCP server verification, Google Cloud SDK, re-authentication prompts, and the full verification checklist.

Note: A few steps will still need your manual input:

  • gh auth login, az login, gcloud auth login — browser-based OAuth flows
  • Docker Desktop — needs to be launched from Applications
  • rsync from old machine — needs the old MacBook's IP

But Claude Code can orchestrate everything else and prompt you when it hits those steps.

@denniswon

Copy link
Copy Markdown
Author

On old MacBook: System Settings → General → Sharing → Remote Login → ON

On old machine:

ifconfig | grep "inet " | grep -v 127.0.0.1

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