My personal config, symlinked into $HOME.
home/ -> files linked into ~/ (e.g. home/.zshrc -> ~/.zshrc)
config/ -> files linked into ~/.config/ (e.g. config/git/ignore -> ~/.config/git/ignore)
os/<platform>/ -> OS-specific overlay, layered on top of the shared configs
os/macos/... -> linked when uname is Darwin
os/linux/... -> linked when uname is Linux
setup.sh idempotent symlink installer
setup.sh detects the platform (uname) and, after linking the shared
home/ and config/ trees, layers os/<platform>/{home,config} on top.
Overlay files link last, so they win for same-named paths.
This is how 1Password commit signing stays macOS-only: the shared
home/.gitconfig ends with [include] path = ~/.config/git/signing.conf, and
the overlay supplies that file —
os/macos/config/git/signing.conf— SSH signing via the 1Password agentos/linux/config/git/signing.conf— no 1Password; signing disabled
On a Linux box, ./setup.sh links the Linux fragment instead, so nothing
references 1Password.
git clone <repo-url> ~/Source/dots
cd ~/Source/dots
./setup.sh --dry-run # preview
./setup.sh # linkExisting real files are moved to ~/.dotfiles-backup/<timestamp>/ before linking.
Re-running only touches things that are out of date.
- Move it into the repo, mirroring its path under
$HOME:~/.foorc->home/.foorc~/.config/foo/bar->config/foo/bar
- Run
./setup.shto link it.
os/macos/bootstrap.sh(run bysetup.sh) installs Homebrew if missing, then ensuresclaudeandcodexare installed (via their install scripts).
home/.zshrc,home/.zprofile,home/.zshenvhome/.gitconfighome/.claude/settings.jsonhome/.codex/config.tomlconfig/git/ignoreskills/— universal skills linked into both~/.claude/skillsand~/.codex/skills