SKILL.md
Chezmoi Dotfiles Management
This skill helps manage dotfiles using chezmoi in this repository.
Repository Location
All dotfiles are managed in ~/.local/share/chezmoi which is a git repository synced to GitHub at https://github.com/craigtkhill/dotfiles.git.
Critical Workflow
When creating or modifying dotfiles, you MUST follow this exact order:
- Check for drift before every new task — no exceptions
Run this before starting any new task in this repo, not just once per session — other processes (e.g. Obsidian) edit tracked files live and can create drift mid-session:
``bash chezmoi status ``
Empty output → proceed. Any output → re-add every drifted file immediately (paths from chezmoi status are home-relative), regardless of whether it's related to the current task:
``bash chezmoi status | awk '{print $2}' | while read -r f; do chezmoi re-add ~/"$f"; done ``
The pre-commit hook blocks commits when home directory files differ from the chezmoi source. Never wait to be asked or reminded.
- Navigate to chezmoi source directory
``bash cd ~/.local/share/chezmoi ``
- Create or edit files using chezmoi naming conventions
- Use dot prefix for dotfiles (e.g., dotgitconfig → ~/.gitconfig) - Preserve directory structure (e.g., dot_config/fish/functions/ → ~/.config/fish/functions/) - You can edit directly in ~/.local/share/chezmoi or use chezmoi edit <target-path>
- Apply changes to home directory
``bash chezmoi apply # or for specific file: chezmoi apply ~/.config/fish/functions/myfile.fish ``
- Commit and push to GitHub
``bash cd ~/.local/share/chezmoi git add . git commit -m "your message" git push origin main ``
- Verify it's managed
``bash chezmoi managed | grep myfile ``
Common Commands
chezmoi status- Show what has changedchezmoi diff- Show detailed differenceschezmoi managed- List all managed fileschezmoi apply- Apply changes from dotfiles to home directorychezmoi apply --force- Force apply, overriding conflictschezmoi add <file>- Add a file to chezmoi trackingchezmoi re-add <file>- Re-add a tracked file
Fish Shell Specifics
Fish automatically loads functions from ~/.config/fish/functions/. Each function must be in its own file named functionname.fish.
After adding new fish functions:
- Copy to
~/.config/fish/functions/ - Functions are immediately available (fish auto-loads them)
- No need to source or reload
Adding Existing Files to Chezmoi
If you want to add an existing file from your home directory to chezmoi:
chezmoi add ~/.config/fish/functions/myfile.fish
This will copy the file to ~/.local/share/chezmoi with proper naming and make it managed.
Package Manager Policy
Tools are split across two files:
- Brewfile — preferred for macOS. Use when Homebrew version is equal to or newer than Cargo.
- Cargofile — use only when Cargo has a newer version than Homebrew, or when there is no Homebrew equivalent (e.g.
cargo-update).
When adding a new CLI tool:
- Check Homebrew version:
brew info <tool> --json | python3 -c "import sys,json; print(json.load(sys.stdin)[0]['versions']['stable'])" - Check Cargo version:
curl -s https://crates.io/api/v1/crates/<tool> | python3 -c "import sys,json; print(json.load(sys.stdin)['crate']['newest_version'])" - If versions are equal → Brewfile
- If Cargo is newer → Cargofile
- If no Homebrew equivalent → Cargofile
Common Mistakes
❌ DON'T: Edit files directly in ~/.config/fish/ without updating chezmoi
- Changes will be lost when chezmoi applies source files
❌ DON'T: Forget to commit and push changes to GitHub
- Your dotfiles won't be backed up or available on other machines
❌ DON'T: Retry git commit immediately after a hook failure without re-running chezmoi apply
- Hooks like
end-of-file-fixerrewrite files in the working tree on failure, silently re-creating drift against home. Alwayschezmoi apply && chezmoi status(must be empty) before retrying.
❌ DON'T: Trust what's staged after a failed commit attempt
- A prior
git add -Acan leave unrelated files staged, bundling them into your next, supposedly-separate commit. Rungit diff --cached --statand confirm only intended paths before committing.
❌ DON'T: Write the commit message before your final check of what's staged
- A hook or
chezmoi applyrunning between staging and committing can change the staged diff, making an earlier-drafted message stale. Rungit diff --cached --statimmediately beforegit commitand confirm it still matches the message — if not, stop and reconcile before committing.
✅ DO: Edit in ~/.local/share/chezmoi → Apply → Commit → Push