This repository declares personal macOS machines. Each machine has one nix-darwin configuration.
- Nix applies the system configuration. This includes the macOS settings, the user account and
the files in
/etc. - Homebrew installs all packages. Homebrew uses
masto install the App Store apps. - Each configuration file in the home directory is a symbolic link to a file in this checkout. A change to a file applies in the next shell. You do not have to build again.
Before you start:
- Install the Xcode Command Line Tools. These tools supply
git. The firstgitcommand asks you to install them. - Sign in to the App Store. If you do not sign in, the install stops when
masinstalls the App Store apps.
Enter these commands:
git clone https://github.com/jshvn/dotfiles.git ~/Git/personal/dotfiles
cd ~/Git/personal/dotfiles
./bootstrap.zsh <machine>Replace <machine> with the name of a file in machines/, without .nix. All links point into
the clone. To clone to a different path, first set dotfiles.checkout to that path in
machines/<machine>.nix. task install stops when it runs from any other clone.
After the install:
- Open a new terminal.
- Sign in to 1Password.
- Turn on the 1Password SSH agent.
- Enter
update.
The jshvn/ai and jshvn/vscode-title-buttons repositories clone over SSH. The first install
cannot clone them and shows a warning. Run update after configuring 1Password to install them.
updateupdate is an alias for task install. You can use it in any directory.
If the install or the update stops before it completes, correct the cause. Then enter the same command again. You can do the install or the update more than one time. The result is the same.
| Command | Purpose |
|---|---|
task setup -- <machine> |
Saves the machine selection. |
task install |
Updates the checkout and applies the configuration. Updates the zsh plugin bundles. Lists the packages that are not declared, but does not remove them. Shows a warning for each pinned version that is out of date, because the install does not update it. The warning gives the update procedure. |
task prune |
Removes each package that the configuration does not declare. Brew shows the list and asks first. This includes Mac App Store apps, VS Code extensions, and go, cargo, uv, npm and krew installs. |
task rollback |
Activates the previous generation. |
task show |
Shows the evaluated configuration as JSON. |
task diff |
Shows the changes that task install will make. The Nix closure diff shows first. The new Homebrew packages show second. |
task validate |
Compares the live system with the configuration. Exits with code 1 if they are different. |
task audit |
Shows the state that is not in the configuration. Shows known CVEs. |
task check |
Evaluates each machine and each profile in the pinned Nix image. |
task lint |
Checks the zsh scripts, the Nix format and the menu. tasks/lint.zsh contains the rules. |
task fmt |
Formats the Nix files. |
task test |
Does the smoke tests and the negative evaluations. On a Mac, it also measures the cold start time of an interactive zsh. The limit is 500 ms. |
The check, lint, fmt and test tasks operate in the pinned Nix image. These tasks need
Apple container or Docker. If the Apple container daemon is on, the Taskfile uses it. If
not, the Taskfile uses Docker. To always use Docker, set ENGINE=docker.
Enter task to show the menu. The menu groups the tasks by their effect on the Mac. Enter
task --list to show the generated list.
docs/DECISIONS.mdcontains the locked decisions and the scope.docs/SECURITY.mddescribes the trust chain of the bootstrap.docs/MACHINES.mddescribes the purpose and the hardware of each machine.- The README in each top-level directory tells what belongs in that directory.
CLAUDE.mdlists the constraints that the files do not show.