dotfiles-setup
Skill0 starsChanged 3 months agoMITView on GitHub
Creates or restores a dotfiles repository on macOS - chezmoi by default (Stow or bare-git alternatives), adopting existing config without overwriting, secrets hygiene, Brewfile tracking. Use for "set up dotfiles", "version control my zshrc/gitconfig", "sync config between Macs", "restore dotfiles on a new machine". Not for shell config content, Brewfile generation, git identity, or backups.
- Reads credentials
- Installs packages
In this repository21 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- add-skillSkill
- publish-repoSkill
- ai-dev-toolsSkill
- cloud-dev-setupSkill
- dev-cli-toolsSkill
- docker-on-macSkill
- editor-setupSkill
- git-ssh-identitySkill
- homebrew-setupSkill
- language-runtimesSkill
- mac-dev-appsSkill
- mac-maintenanceSkill
- macos-defaultsSkill
- macos-dev-setupSkill
- macos-security-baselineSkill
- macos-system-prepSkill
- mobile-dev-setupSkill
- web-dev-setupSkill
- zsh-setupSkill
The file
We split this skill into the rules it gives an agent
1 rule. About 0 are common, 1 is distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 44
Default to chezmoi unless the user already has a Stow repo or asks for simplicity.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Dotfiles Setup
Puts machine configuration under version control and makes it restorable on the next Mac — without the classic failure modes: clobbering live config during adopt/deploy, and committing secrets on day one.
When NOT to use
- The content of
.zshrc→zsh-setup; of.gitconfig→git-ssh-identity - Generating/refreshing the Brewfile →
homebrew-setup(this skill only tracks that file) - Whole-machine setup →
macos-dev-setup - Backups of data → Time Machine, out of scope
Safety rails
- Never overwrite live config. Deploying onto a machine with existing
files: diff first, back up collisions (
mv X X.bak), then link — every time, no exceptions. - Secrets scan before first commit (and before publishing an existing
repo): grep the candidate set for keys/tokens;
~/.ssh/,~/.aws/,~/.kube/,.env*,*history,.netrcnever go in. Treat the repo as public even if private. - Bootstrap scripts are idempotent and fail-fast. They check for core
prerequisites (Homebrew) and stop if missing; they may install their own
tooling (stow) and delegate packages to
brew bundle— they never bootstrap Homebrew itself.
Choose a manager (once)
| Best for | Model | |
| chezmoi (default) | most setups: multi-machine, work/personal templating, secrets via 1Password/Keychain, one-command restore | source state + chezmoi apply (dry-run diffs built in) |
| GNU Stow | one machine, want dead-simple symlinks | symlink farm: ~/dotfiles/zsh/.zshrc → ~/.zshrc |
| bare git | no extra tool, comfortable with git plumbing | git --git-dir=~/.dotfiles.git --work-tree=$HOME |
Default to chezmoi unless the user already has a Stow repo or asks for simplicity; an existing manager always stays.
Workflow — create (chezmoi default)
brew install chezmoi
chezmoi init # creates ~/.local/share/chezmoi as a git repo
chezmoi add ~/.zshrc ~/.zprofile ~/.gitconfig ~/.config/starship.toml 2>/dev/null
chezmoi add ~/Brewfile 2>/dev/null # track the Brewfile (generated via homebrew-setup)
chezmoi cd # inspect; then run the secrets scan below before committingchezmoi copies files into its source state (originals stay in place) —
edits go via chezmoi edit <file> + chezmoi apply, or chezmoi re-add
after editing live files; chezmoi diff previews every change before
apply. Machine-specific bits use its templates
({{ .chezmoi.hostname }}), and secrets stay out via its 1Password/
Keychain template functions instead of committed values. Restore on the
next Mac is one command: chezmoi init --apply <repo-url> (run chezmoi
diff first on a non-fresh machine).
Workflow — create (Stow variant, on request)
# A non-empty ~/dotfiles means someone already has a repo there - STOP and
# switch to the restore/merge flow instead of initializing over it:
[ -e ~/dotfiles ] && { ls -la ~/dotfiles; echo "exists - use restore flow"; }
mkdir -p ~/dotfiles/{zsh,git,config}
cd ~/dotfiles && git init
# ADOPT existing files: move real file in, link back out - per file, after
# showing the plan, and only when the repo slot is empty (no silent clobber):
[ ! -e ~/dotfiles/zsh/.zshrc ] && mv ~/.zshrc ~/dotfiles/zsh/.zshrc
[ ! -e ~/dotfiles/git/.gitconfig ] && mv ~/.gitconfig ~/dotfiles/git/.gitconfig
mkdir -p ~/dotfiles/config/.config
[ -f ~/.config/starship.toml ] && [ ! -e ~/dotfiles/config/.config/starship.toml ] && \
mv ~/.config/starship.toml ~/dotfiles/config/.config/
brew install stow
cd ~/dotfiles && stow --simulate -v --target="$HOME" zsh git config # preflight - read the plan
cd ~/dotfiles && stow --target="$HOME" zsh git config # then link for real
# Track the Brewfile (generated via homebrew-setup's dump workflow)
[ -f ~/Brewfile ] && [ ! -e ~/dotfiles/Brewfile ] && cp ~/Brewfile ~/dotfiles/BrewfileLayout that scales:
dotfiles/
├── Brewfile # tracked; regenerated via homebrew-setup
├── bootstrap.sh
├── zsh/.zshrc · zsh/.zprofile
├── git/.gitconfig · git/.gitignore_global
└── config/.config/starship.toml (mirrors ~/.config)Secrets pass before the first commit — use a real scanner (pattern greps miss modern token formats and a grep error looks like "clean"):
brew install gitleaks
gitleaks dir ~/dotfiles --no-banner # non-zero exit = findings OR failure; read the output
printf '%s\n' '.env*' '*.pem' '*_history' >> ~/dotfiles/.gitignoreThen make it a repository the user can actually restore from (the user runs these — commits are theirs):
git -C ~/dotfiles add -A && git -C ~/dotfiles commit -m "initial dotfiles"
git -C ~/dotfiles remote add origin <their-new-private-repo-url> && git -C ~/dotfiles push -u origin mainBare-git variant (no tool, higher foot-gun factor — $HOME is the work
tree, so hide untracked noise or git status becomes useless):
git init --bare ~/.dotfiles.git
alias dot='git --git-dir=$HOME/.dotfiles.git --work-tree=$HOME'
dot config status.showUntrackedFiles no
dot add ~/.zshrc ~/.gitconfig && dot commit -m "initial"Workflow — restore on a new machine
git clone <repo-url> ~/dotfiles
cd ~/dotfiles && stow --simulate -v --target="$HOME" zsh git config # preflight: lists every collision
# For EVERY collision the simulate run reports: diff, then timestamped backup
diff ~/.zshrc ~/dotfiles/zsh/.zshrc 2>/dev/null
[ -f ~/.zshrc ] && [ ! -L ~/.zshrc ] && mv ~/.zshrc ~/.zshrc.bak.$(date +%Y%m%d%H%M%S)
cd ~/dotfiles && stow --target="$HOME" zsh git config
brew bundle install --file=~/dotfiles/Brewfile # packages backchezmoi one-liner equivalent: chezmoi init --apply <repo-url> — but run
chezmoi diff first on a non-fresh machine.
Bootstrap script (tracked as bootstrap.sh)
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")"
command -v brew >/dev/null || { echo "Homebrew missing - run homebrew-setup first"; exit 1; }
command -v stow >/dev/null || brew install stow
for pkg in zsh git config; do
# stow REFUSES to overwrite real files (its safety feature) and set -e
# stops us there - back the collision up by hand, then re-run.
stow --target="$HOME" --restow "$pkg" # --restow = idempotent re-runs
done
[ -f Brewfile ] && brew bundle install --file=Brewfile
echo "dotfiles applied - open a new terminal"Verify
Links resolve (ls -l ~/.zshrc shows -> dotfiles/...), a new shell
starts clean, git -C ~/dotfiles status is clean, and the secrets grep
reports nothing.
Output spec
Done means: repo exists with the layout above, live files replaced by links only after diff+backup, secrets scan clean, Brewfile tracked, bootstrap re-runs without changes. Report the link map (file → repo path).
Gotchas
- Stow refuses to overwrite real files ("existing target is not owned by
stow") — that's the safety feature working; adopt (
mvin) or back up, don't--override. - Symlinked
.zshrc+ Oh My Zsh installer: OMZ moves the link aside on reinstall — re-stow afterwards. stow --restowprunes stale links on re-runs; plain repeat runs are no-ops. Deleted a file from the repo?--restowcleans its dead link.- Machine-specific bits (work proxy, different email) don't fork the repo:
source an untracked
~/.zshrc.localat the end of.zshrc, or graduate to chezmoi templates. - chezmoi copies (not links) by design — edits go via
chezmoi edit/re-addor they drift; that's the price of its templating power.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

