Bootstrap a new machine
Bootstrap applies managed files, installs the selected runtimes, then runs small selected-tool checks. Start from a checkout when you want an interactive name/email prompt or an auditable revision.
One-liner
Section titled “One-liner”curl -fsSL https://raw.githubusercontent.com/cadebrown/dotfiles/main/bootstrap.sh | \Piping consumes stdin, so provide DF_NAME and DF_EMAIL; chezmoi caches them
in ~/.config/chezmoi/chezmoi.toml for later runs.
Interactive (prompts for name + email)
Section titled “Interactive (prompts for name + email)”git clone https://github.com/cadebrown/dotfiles ~/dotfiles~/dotfiles/bootstrap.shExpected result: a final selected-tool verification and, if applicable, a degradation summary to repair. It does not prove cloud credentials, GUI privacy grants, or running local services.
Upgrade mode prints bootstrap complete only after its version audit returns
success; the audit is strict by default (DF_STRICT_UPGRADE=0 selects report-only
mode). Informational source-build timing notices and the independently verified
rust-docs-mcp GitHub diagnostic exception remain visible without being counted
as failed installations.
~/dotfiles/bootstrap.sh # install~/dotfiles/bootstrap.sh update # refresh a clean checkout; skips scratch setup~/dotfiles/bootstrap.sh upgrade # update plus managed runtime upgradesupgrade enables Homebrew upgrades; it does not update the operating system.
update refuses a non-fast-forward pull. See the lifecycle
for stage order and recovery behavior.
Requirements
Section titled “Requirements”| Requirement | How to satisfy it |
|---|---|
| macOS 13+ | Ventura or later |
| Xcode Command Line Tools | xcode-select --install, or Homebrew’s prompt |
| Internet access | required for package sources |
One sudo authentication per run
Section titled “One sudo authentication per run”From an interactive terminal, run bootstrap normally:
~/dotfiles/bootstrap.sh upgradeOn macOS, bootstrap authenticates with sudo -v before starting the work and
refreshes the sudo timestamp while it runs. Enter your password at
most once while renewal succeeds; an existing valid timestamp may mean
no prompt. Homebrew still runs as your user and requests privileges only for
operations that need them. Cask and Mac App Store upgrades can use that session
even after lengthy formula builds. Before cask, App Store, and TeX package
updates, the installer checks the credential again. If it has expired, an
interactive macOS run visibly asks for authentication at that point. Unattended
runs still skip the affected update instead of prompting. DF_SUDO=0 disables
this recovery prompt as well as the renewal helper.
The refresh process stops when bootstrap exits or is interrupted. Bootstrap
does not erase the existing sudo timestamp; it expires normally.
DF_SUDO=0 disables bootstrap’s authentication and refresh helper; it does not
disable privileged operations or prompts inside individual installers. Unattended
runs never prompt through this helper; they can refresh an already valid
timestamp. Linux remains rootless.
This covers sudo authentication, not App Store sign-in, macOS privacy dialogs,
or installers using a separate authorization mechanism. A custom sudo policy
that disables caching, or manually invalidating the timestamp during the run,
can prevent renewal and is reported with sudo’s error. The keeper continues
noninteractive renewal attempts, allowing a foreground recovery to restore the
session without a background password prompt. The existing
macOS settings installer configures a shared, 60-minute timestamp; sudo’s
unmodified default is five minutes per terminal. The refresh helper uses the
installed policy without changing it.
See the installed man sudo and man sudoers, or the upstream
sudo manual, for timestamp semantics.
What gets installed
Section titled “What gets installed”| Area | Managed result |
|---|---|
| Configuration | chezmoi applies home/ templates and login profiles |
| Packages | Homebrew packages/casks, uv, nvm, Rust, Go, Lean, TeX, and selected CLIs |
| Agent tooling | Claude, Codex, MCP configuration, skills, optional memory and local-LLM tools |
| Desktop integration | macOS settings, services, Cursor/VS Code, and optional Blender MCP |
Installers call the root LOCAL_PLAT; a managed login shell exposes the same
root as $_LOCAL_PLAT (~/.local by default). Executables land in its bin/.
DF_START_LOCAL_SERVICES=1 opts in to starting Colima, Ollama,
and mlxserve at login; otherwise start a needed service manually. See
package ownership and the
macOS workflow for operational checks.
| macOS-specific choice | Effect |
|---|---|
| Homebrew Rustup | code-signed toolchain path for current macOS linker rules |
DF_PROFILE=core | keeps Rustup/rust-analyzer but omits optional Cargo tools |
| service default | Colima/Ollama are left manual; mlxserve is stopped/disabled so a hand-start does not survive bootstrap |
Requirements
Section titled “Requirements”| Requirement | Notes |
|---|---|
| x86_64 or aarch64 | supported host architectures |
git, curl, python3 | normally preinstalled |
| Internet access | required for package sources |
No sudo is required. Homebrew installs under $_LOCAL_PLAT/brew in a managed
login shell; Linux setup
does not require Docker or Podman. An enabled NVIDIA overlay may have its own
container requirement.
What gets installed
Section titled “What gets installed”The same configuration, language, agent, and optional-workflow layers as macOS, with rootless Linux Homebrew, TinyTeX, and Linux-specific package handling. Cursor and VS Code default off on Linux; set their gates only where the CLI is available. Inspect the exact owner in package setup.
| Linux-specific choice | Effect |
|---|---|
| Homebrew | rootless native prefix; no container runtime required |
| TeX | TinyTeX under the runtime root; missing packages install through tlmgr |
| editors | Cursor/VS Code default off; selecting a missing CLI or extension fails bootstrap |
Skipping steps
Section titled “Skipping steps”Pass DF_DO_<AREA>=0 for an optional stage; DF_DO_AUTH=1 opts into the token
walk. A skipped stage is not an uninstall, and final verification skips the
same selected check.
| Gate | Default | Stage |
|---|---|---|
DF_DO_SCRATCH, DF_DO_DIRS | install: on; update/upgrade scratch: off | scratch links; home directories |
DF_DO_PACKAGES, DF_DO_LLDB, DF_DO_QUARTO | on | Homebrew/package bundle; debugger; Quarto |
DF_DO_ZSH, DF_DO_NODE, DF_DO_RUST, DF_DO_PYTHON, DF_DO_GO | on | shell plugins and language runtimes |
DF_DO_JULIA, DF_DO_LEAN, DF_DO_LATEX | on | Julia, Lean, TeX |
DF_DO_CLAUDE, DF_DO_CODEX, DF_DO_OPENCODE | on | coding-agent CLIs/configuration |
DF_DO_CLAUDE_DESKTOP, DF_DO_CODEX_DESKTOP, DF_DO_LINEARMOUSE | on, macOS | tracked desktop preferences |
DF_DO_MACOS_SERVICES, DF_DO_MACOS_SETTINGS, DF_DO_MACOS_QUICK_ACTIONS | on, macOS | services, system settings, Finder actions |
DF_START_LOCAL_SERVICES | off | start Colima, Ollama, mlxserve at login |
DF_DO_CURSOR, DF_DO_VSCODE | macOS: on; Linux: off | editor extension/settings integration; Cursor also merges CLI config and loads the My Machines worker |
DF_DO_CMAKE, DF_DO_LOCAL_LLM, DF_DO_MEMORY, DF_DO_SKILLS | on (LOCAL_LLM: full profile) | toolchains, model tooling, qmd/cass, skills |
DF_DO_BLENDER_MCP | macOS: on; Linux: off | Blender add-on |
DF_DO_AUTH, DF_DO_OVERLAYS | auth: off; overlays: on | token walk; sibling overlays |
DF_USE_PLAT, DF_BREW_UPGRADE, DF_STRICT_UPGRADE | off; brew off except upgrade; strict upgrade on | runtime layout and upgrade policy |
DF_BREW_UPGRADE_CASKS, DF_BREW_UPGRADE_MAS | auto | permit GUI/MAS upgrades only with a cached sudo ticket |
DF_SUDO | auto | authenticate once on interactive macOS and maintain sudo until exit; 0 disables the helper |
# narrow command-line machineDF_PROFILE=core DF_DO_AUTH=0 DF_DO_LOCAL_LLM=0 ./bootstrap.sh
# configuration without common language/agent runtimesDF_DO_PACKAGES=0 DF_DO_ZSH=0 DF_DO_NODE=0 DF_DO_RUST=0 \DF_DO_PYTHON=0 DF_DO_CLAUDE=0 ./bootstrap.shDF_PROFILE is core or full; core defaults local-LLM setup off and
full defaults it on. The complete, revision-matched comments are in the
bootstrap.sh header and the environment-variable
reference.
Debug mode
Section titled “Debug mode”DF_DEBUG=1 ~/dotfiles/bootstrap.shThis adds command and elapsed-time diagnostics. Keep the complete output when reporting a failed stage.
Shared home directories (NFS/GPFS)
Section titled “Shared home directories (NFS/GPFS)”DF_USE_PLAT=1 ~/dotfiles/bootstrap.shUse this only when one home is shared across incompatible CPU architectures.
It places each machine’s compiled state in ~/.local/$PLAT; text configuration
remains shared. PLAT isolation explains the layouts and safe
decommissioning.
Scratch space (large quota environments)
Section titled “Scratch space (large quota environments)”DF_SCRATCH=/scratch/$USER ~/dotfiles/bootstrap.shBootstrap links selected heavy state into $DF_SCRATCH/.paths before installs.
~/.claude and ~/.codex remain real chezmoi-managed directories; only their
unmanaged heavy children move. See scratch space before
running it on an existing machine.
Auth (API tokens)
Section titled “Auth (API tokens)”bash ~/dotfiles/install/auth.sh statusDF_DO_AUTH=1 ~/dotfiles/bootstrap.shThe guided registry stores opted-in values in owner-only env files. Read auth for service selection and file handling.