Personal macOS bootstrap + dotfiles + shell tooling, managed with
chezmoi. Dotfiles live under home/ in chezmoi's
source format and are applied with chezmoi apply. In symlink mode, managed
files become symlinks back into this repo, so you can edit either side — while
still getting templating, per-machine config, and setup scripts.
On a brand-new Mac (installs Xcode CLT, installs chezmoi, then clones + applies):
bash <(curl -fsSL https://raw.githubusercontent.com/adrianolisboa/macforge/master/bootstrap.sh)Or directly with chezmoi:
sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply adrianolisboa/macforgechezmoi asks "Is this a work machine?" (and, if yes, your work git name/email), lays down every dotfile, then runs the setup scripts (Homebrew, Brewfile, macOS defaults, iTerm2, git hooks).
Agent + contributor rules (including "keep MIGRATION.md in sync") live in AGENTS.md. New-Mac migration steps live in MIGRATION.md.
.chezmoiroot → "home" (chezmoi's source root)
home/
.chezmoi.toml.tmpl prompts (work machine?) + symlink mode
.chezmoiignore skip work identity on non-work machines
dot_zshrc, dot_gitconfig… dotfiles (dot_ → ~/.)
dot_config/nvim, gh, atuin → ~/.config/{nvim,gh,atuin}
dot_config/macforge/shell → ~/.config/macforge/shell (zsh loader)
dot_config/macforge/{bin,iterm2,Brewfile*} → ~/.config/macforge/* (scripts, iTerm2, packages)
dot_gitconfig-professional.tmpl work identity (rendered from prompt)
run_once_* / run_onchange_* setup scripts
scripts/install-git-hooks.sh gitleaks + docs-sync hooks
docs/ plans/notes
chezmoi apply # apply changes (symlinks + templates + scripts)
chezmoi diff # preview what would change
chezmoi edit ~/.zshrc # edit a managed file's source (or just edit ~/.zshrc — it's a symlink)
chezmoi cd # shell in the source repo
chezmoi update # git pull + apply
chezmoi doctor # health check
chezmoi init # re-run prompts (e.g. to flip work machine)home/dot_config/macforge/Brewfile→ applied to~/.config/macforge/Brewfile.- A
run_onchangescript re-runsbrew bundleautomatically whenever it changes. - Optional set:
brew bundle --file ~/.config/macforge/Brewfile.optional.
~/.zshrc sources ~/.config/macforge/shell/load, which pulls in everything
under shell/{aliases,common,functions,optional}. Machine-local/private
config belongs in ~/.config/macforge/secrets.zsh (sourced at the end if present).
Applied to ~/.config/nvim (lazy.nvim, LSP, telescope, conform, claudecode.nvim);
lazy.nvim bootstraps itself on first launch. See home/dot_config/nvim/README.md.
config.yml is managed; the auth token in ~/.config/gh/hosts.yml is not
tracked — run gh auth login per machine.
Recommended — 1Password references (no plaintext on disk). Fill in op://
references and run tools through the oprun helper:
cp ~/.config/macforge/secrets.env.example "$HOME/.config/macforge/secrets.env"
# edit it: VAR=op://Vault/Item/field (Copy Secret Reference from the 1Password app)
oprun mix phx.server # secrets injected at runtime, nothing on diskLegacy — machine-local file: ~/.config/macforge/secrets.zsh (chmod 600), sourced by .zshrc.
On chezmoi init, answering "work machine? = yes" prompts for your work git
name/email; ~/.gitconfig-professional is then rendered from those answers
(stored machine-locally in ~/.config/chezmoi/chezmoi.toml, never in the repo).
On non-work machines the file is skipped. ~/.gitconfig includes it for repos
under ~/Projects/.
macforge is the source of truth. On the machine where you changed config,
git push from the source (chezmoi cd). On another machine, chezmoi update
(git pull + apply).
./scripts/install-git-hooks.sh # or the run_once script does it on first apply- pre-push —
gitleaks; blocks the push if secrets are detected. - pre-commit — non-blocking reminder to update
MIGRATION.md/README.mdwhen managed config changes.