The first darwin-rebuild switch installs everything this repo declares: CLI tools, apps (casks, App Store apps, Nix apps), Homebrew itself, the dotfiles links in $HOME, and the System Settings in nix/macos.nix. This page is what comes before it, the switch itself, and what is left by hand after it.
For a Mac that was already set up by hand, read migrate-mac.md before the first switch.
App Store apps are installed by the switch with mas, which needs a signed-in App Store. An app that fails to install only prints a warning; switching again after signing in installs it.
They provide git, which cloning this repo needs.
xcode-select --installThe key is used to clone this repo and to fetch the private agent-skills input.
ssh-keygen -t ed25519 -C "babarot@gmail.com"
cat ~/.ssh/id_ed25519.pub | pbcopyPaste it at https://github.com/settings/ssh/new, then check that it works:
$ ssh -T git@github.com
Hi babarot! You've successfully authenticated, but GitHub does not provide shell access.Keep this exact path: the links into $HOME and the darwin-rebuild commands point at it.
git clone git@github.com:babarot/dotfiles.git ~/src/github.com/babarot/dotfilesThe switch picks its configuration by hostname, and stops with an error for a hostname that flake.nix does not list. Check it before installing Nix:
scutil --get LocalHostNameIf the name is in the host table in AGENTS.md, go on. Otherwise add it, starting from the Mac it is most like:
| This Mac is | Start from |
|---|---|
| private | pro23 |
| work | PC-M-2025-026 |
- Copy
nix/hosts/<base>.nixtonix/hosts/<hostname>.nix, andnix/hosts/<base>/tonix/hosts/<hostname>/if it exists. Drop what this Mac does not need. - Add
"<hostname>" = mkHost "<hostname>";todarwinConfigurationsin flake.nix. git addthe new files. Nix only sees files tracked by git.- Add the Mac to the host table in AGENTS.md.
- Commit and push once the first switch works.
Everything outside the host files applies to every host, so the new Mac gets the shared setup as it is.
With the Determinate Nix installer:
curl -fsSL https://install.determinate.systems/nix | sh -s -- installBuild the configuration as yourself first. agent-skills is fetched over SSH with your key, which root does not have; once it is in the Nix store, the sudo run finds it there.
nix build "$HOME/src/github.com/babarot/dotfiles#darwinConfigurations.$(scutil --get LocalHostName).system" --no-linkThen apply it. darwin-rebuild is not installed yet, so it runs through nix run. Quote the flake reference, since zsh treats # as a glob.
sudo /nix/var/nix/profiles/default/bin/nix run 'nix-darwin/master#darwin-rebuild' -- switch --flake ~/src/github.com/babarot/dotfilesNote
nix-darwin moves the existing /etc/zshrc, /etc/zshenv and /etc/bashrc aside as *.before-nix-darwin. home-manager does not move existing symlinks: remove any it reports as "would be clobbered" and run it again.
Restart the Mac when it finishes. Some of what was installed, such as Google Japanese Input, only works after a restart. Open a new terminal afterwards; until the switch, the shell was plain macOS zsh.
Copy these files from the old Mac with AirDrop, or with scp when Remote Login is on there. Shell history can hold tokens, so do not pass it through a gist or any other service.
| File | What it is |
|---|---|
~/.zsh_history |
zsh history |
~/.enhancd/enhancd.log |
directory history for enhancd |
~/.claude/vault.db |
the claude-recall archive of Claude Code sessions, including those whose transcripts Claude Code has deleted |
scp <old-mac>.local:.zsh_history ~/.zsh_history
scp <old-mac>.local:.enhancd/enhancd.log ~/.enhancd/enhancd.logThe archive is a SQLite database written while Claude Code runs, so copy a snapshot of it rather than the file itself. On the old Mac:
sqlite3 ~/.claude/vault.db ".backup '$HOME/vault.db'"On the new Mac, quit Claude Code and recall ui first, put the snapshot in place, then import the sessions the new Mac already has:
rm -f ~/.claude/vault.db-wal ~/.claude/vault.db-shm
mv ~/vault.db ~/.claude/vault.db
recall importThe old Mac's sessions can then be read and searched, and recalled into a new claude with c, but not resumed with claude -r: Claude Code resumes only from the transcripts in ~/.claude/projects, which are not copied.
These are not declared in nix/macos.nix.
Do not enable an input source with defaults write or the TIS API: macOS records the consent only when the source is added in System Settings, so a source enabled another way asks for consent again on every switch.
Apps marked "work" are only on the work Mac; the rest are on both.
| App | What to do |
|---|---|
| 1Password | Sign in with the Setup Code, then set the appearance. ![]() |
| Google Japanese Input | Settings: ![]() |
| Obsidian | Sign in, open the vault, enter the encryption password and run sync. Enable the Vimrc Support plugin and copy the vimrc: cp ~/src/github.com/babarot/dotfiles/home/.obsidian.vimrc ~/Documents/<vault>/ ![]() |
| Things 3 | Turn on Things Cloud. ![]() |
| CleanShot X | Settings: ![]() |
| PopClip | Install the Base64 and Translate Tab extensions. ![]() |
| Spark | Sign in. |
| Spotify | Sign in. |
| Hidden Bar | Settings: ![]() |
| Magnet | Settings: ![]() |
| MeetingBar (work) | Settings: ![]() |
| Paste | Settings: ![]() |
| Yoink | Settings: ![]() |
Apply changes with:
sudo darwin-rebuild switch --flake ~/src/github.com/babarot/dotfilesEach switch also uninstalls Homebrew casks and brews that no file declares, so an app installed with brew install by hand goes away; declare it instead (where-things-go.md).
Updating inputs (after an agent-skills update, build as yourself first) is in maintenance.md.




































