Personal macOS setup: zsh, git, Homebrew, mise, macOS defaults, and a workspace for running coding agents (Claude Code, oh-my-pi, herdr).
- macOS only, Apple Silicon and Intel.
- Idempotent — every script is safe to re-run.
- Modular — each top-level directory is a module with its own
setup.sh.
Important
Clone to ~/.dotfiles. The path is hardcoded in zsh/zshenv; anywhere else
will not work.
On a new machine:
- Install the Xcode command line tools:
xcode-select --install. git clone https://github.com/khoi-truong/dotfiles.git ~/.dotfiles && cd ~/.dotfiles./setup.sh— installs Homebrew, links dotfiles, runs the default modules (includingmise installfor the pinned runtimes).macos/asks for a computer name; leave it blank to keep the current one.- Sign in to the App Store, then re-run
sh brew/setup.shso themasentries install. - Import the GPG key and trust it. Commits are signed (
commit.gpgSign = true), so git refuses to commit until this is done.git/setup.shhas already writtengpg.programand asked foruser.name/user.email. - Unlock 1Password,
gh auth login, then re-runsh ai/setup.sh. This writesai/env.local.zsh, installs the herdr integrations, and installs each herdr plugin at its pinned tag — approve every manifest preview it prints. - Log in to Claude Code, omp and Copilot (their tokens are never versioned).
./setup.sh --allif this machine needs VS Code, Xcode or Terminal.app.
setup.sh installs Homebrew if missing, asks for sudo once, links the shell
dotfiles into $HOME, then runs each module's setup.sh:
./setup.sh # default modules
./setup.sh --all # default + opt-in modules
./setup.sh vscode git # only the named modules, in the order given
./setup.sh --list # show what's availableHow files are linked, where secrets come from, and troubleshooting: Installation.
| Module | What it sets up | Default | Docs |
|---|---|---|---|
zsh/ |
Shell: antidote plugins, aliases, functions, cached inits | always | Shell |
git/ |
gitconfig, gitleaks pre-commit hook, worktree helpers, delta, lazygit | ✓ | Git |
gh/ |
GitHub CLI settings and aliases | ✓ | Git |
brew/ |
Brewfile: formulae, casks, fonts, App Store apps |
✓ | Apps |
mise/ |
Global runtime pins: python, node, ruby, go, java | ✓ | Shell |
macos/ |
defaults write preferences |
✓ | Apps |
gpg/ |
gpg.conf, gpg-agent.conf (commit signing) |
✓ | Git |
iterm/ |
iTerm2 preferences | ✓ | Apps |
ai/ |
Claude Code, oh-my-pi, Copilot CLI, herdr, shared skills | ✓ | AI, herdr |
misc/ |
Small apps (Stats menu-bar monitor) | ✓ | Apps |
vscode/ |
Settings, keybindings, snippets, extensions | opt-in | Apps |
xcode/ |
Colour themes, file templates | opt-in | Apps |
terminal/ |
Terminal.app theme | opt-in | Apps |
ssh/ curl/ tmux/ vim/ |
Single config files, linked by the root setup.sh |
always | Shell |
lib/ scripts/ |
Shared shell helpers, CI scripts | — | Contributing |
Opt-in modules need a GUI app that may not be installed, or only matter on some machines.
| Command | Does |
|---|---|
update |
brew upgrade + mise upgrade (--system adds softwareupdate) |
reload |
Restart the login shell |
git wta <branch> / wt |
Add a worktree under ~/.worktrees / jump to one with fzf |
git dft |
Structural diff with difftastic |
cc / ccd |
Claude Code on the Pro login / on DeepSeek |
omp |
oh-my-pi coding agent |
herdr |
Agent workspace manager (attach / reattach) |
ZSH_PROFILE=1 zsh -i -c exit |
Profile shell startup |
| Guide | Covers |
|---|---|
| Installation | Bootstrap internals, how files get linked, secrets, updating, troubleshooting |
| Shell | zsh load order, plugins, startup time, aliases, mise, tmux |
| Git | Config, signing, hooks, worktrees, diff and review tools |
| Apps | Homebrew, macOS defaults, iTerm2, VS Code, Xcode, Stats |
| AI tooling | Claude Code providers, which model to use, quota routing, oh-my-pi, Copilot |
| herdr | Agent workspace, keys, plugins, usage meters |
| Agent teams | team.sh: agents in parallel worktrees, dispatch and collect |
| Contributing | Workflow, script conventions, linting, CI |
- One version manager. mise owns every language runtime.
- Startup time is a feature. The shell starts in about 350 ms; CI fails a warm start over 1.5 s.
- Secrets never land in the repo. Keys live in 1Password and are generated into gitignored files.
- Dual-arch. Paths key off
brew_prefix, never a hardcoded Homebrew prefix.