Personal dotfiles managed by chezmoi. Provides a consistent dev environment across macOS, Linux, WSL, and Windows.
One curl command on a fresh machine and you walk away with a tuned shell, a modern CLI toolkit, your editors and Git already configured, secrets decrypted, and a Claude Code setup that knows how to scaffold any new language project — all kept in sync across every machine you own with two short commands.
Works on macOS, Ubuntu/Debian Linux, WSL, and Windows from the same
source of truth. Pick a tier at install time (personal / work /
minimal) so a work laptop doesn't get Steam and a minimal VM doesn't get
the full kitchen sink.
Zsh + Oh My Zsh with quality-of-life add-ons:
zsh-autosuggestions— fish-style as-you-type history suggestionszsh-syntax-highlighting— commands turn green/red before you press Entercolored-man-pages,command-not-found,extract(one command for any archive),copypath,copyfile- Starship prompt with transient-prompt collapse so scrollback stays clean
- fzf wired for
Ctrl-Rhistory search and fuzzy file pickers - zoxide so
z projjumps to your most-used folder without typing the path - Bitwarden SSH agent auto-wired, telemetry opted out,
~/.zshrc.localescape hatch for per-machine tweaks
- Better core tools —
bat,fd,ripgrep,git-delta,jq/yq,fzf,zoxide - Git + dev —
gh,lazygit,pre-commit,gitleaks - Languages — Go, .NET, OpenJDK +
jenv,nvm,uv(Python), Rust - Cloud / infra —
gcloud,awscli,azure-cli,tenv+tflint,checkov,trivy,semgrep,podman - Personal-tier GUI apps — VS Code, Ghostty, Bitwarden, Rectangle, Chrome, JetBrains Mono Nerd Font, Claude Desktop, and more
You don't need to remember chezmoi or brew incantations:
dotup— pull latest dotfiles, update Oh My Zsh + plugins, refresh nano syntax, update Starship (Linux), then reload aliases/functions in the current shellbrewup—brew update+ install everything in your Brewfile +brew upgrade+rustup update, in one stepdotclaude— interactive Claude Code MCP server setup (GitHub MCP wired to yourghauth token, Google Developer Knowledge keyed from Bitwarden)dotstatus— machine type, source path, last applied, and any pending changesdotfuncs— list every custom function with its one-line description so you can rediscover what's available afterdotup
note "anything"(aliasn) — append a timestamped bullet to~/notes/<project>.md, where project is the git repo basename (or cwd basename outside a repo). No args → print the current project's notes.note -e— open the current project's notes file in$EDITORnotes— list all note files across projectsnotes grep <pattern>(or justnotes <pattern>) — case-insensitive search across every project's notes
Every machine gets the same ~/.claude/ config — sourced from a separate
repo,
agentic-coding-config,
mounted into ~/.claude/ via chezmoi externals. One
dotup pulls both repos and applies.
- Curated permission allowlist so common dev/build/lint/GitHub commands don't prompt every time, but destructive things still do
- Slash commands to bootstrap any project —
/setup-python,/setup-go,/setup-rust,/setup-node,/setup-typescript,/setup-java,/setup-ruby,/setup-php,/setup-dotnet,/setup-shell,/setup-markdown,/setup-docker,/setup-terraform— each wires formatter + linter + type checks + pre-commit hooks consistently - Repo helpers —
/setup-repo(branch protection, Dependabot auto-merge),/setup-common(pre-commit + gitleaks) - Session helpers —
/end-session,/retrospective - Auto-fix hooks — Terraform formatted on save, pre-commit enforced before
git push
age-based encryption — secrets live in the repo encrypted, decrypt on
first run with your key. No plaintext credentials in version control.
CI runs lint + full install tests on macOS, Ubuntu, and Windows on every
push to main, so a broken bootstrap is caught before it hits your laptop.
validate-installation.sh (and .ps1 for Windows) sanity-checks a fresh
install.
sh -c "$(curl -fsSL https://raw.githubusercontent.com/pmgledhill102/dotfiles/main/install.sh)"winget install --id twpayne.chezmoi
chezmoi init --apply pmgledhill102This installs chezmoi, packages (Homebrew/apt/winget), shell config (Zsh + Oh My Zsh or PowerShell), Starship prompt, git-delta, lazygit, tmux, VS Code settings, JetBrains Mono Nerd Font, and platform-specific defaults.
A few one-time bootstrap steps that aren't auto-run on first apply because they're heavy or workflow-specific.
The Brewfile installs podman + podman-compose, but on macOS the podman
machine VM still needs to be initialised once before the CLI is usable:
podman machine init # ~800 MB image download
podman machine start
podman info # verifyLinux uses the host kernel directly — no podman machine step needed.
| macOS | Linux / WSL | Windows | |
|---|---|---|---|
| Shell | Zsh + Oh My Zsh | Zsh + Oh My Zsh | PowerShell Core |
| Terminal | Ghostty | (host terminal) | Windows Terminal |
| Package source | Brewfile |
apt package list |
winget JSON |
| Platform tweaks | Developer defaults | — | Long Paths + Developer Mode |
During chezmoi init you choose a machine type that controls which packages
are installed:
| Type | Brew formulas | Brew casks | Description |
|---|---|---|---|
personal |
Full (cloud CLIs, runtimes, build tools) | All GUI apps | Full dev workstation |
work |
Core CLI + key runtimes | Font, Ghostty, Rectangle | Work essentials |
minimal |
Core CLI only | None | Headless / CI server |
To change later, edit machine_type in ~/.config/chezmoi/chezmoi.toml and
run chezmoi apply.
dotup # Pull latest dotfiles + update OMZ, plugins, Starship
brewup # brew update + install Brewfile + brew upgrade + rustup update
dotclaude # Interactive Claude Code MCP server setup
dotstatus # Machine type, source path, last applied, pending changes
dotfuncs # List all custom shell functions with descriptionsnote "fixed the auth bug" # Append a timestamped bullet to ~/notes/<project>.md
n "another shorthand" # 'n' is an alias for 'note'
note # Print the current project's notes
note -e # Open the current project's notes in $EDITOR
notes # List all note files
notes grep <pattern> # Search across every project's notes
notes <pattern> # Shorthand for 'notes grep'chezmoi diff # Preview pending changes
chezmoi apply -v # Apply changes
chezmoi edit ~/.zshrc # Edit a managed file
chezmoi add ~/.foo # Start managing a new file# macOS — packages auto-install when Brewfile changes
brew bundle
# Linux — apt packages live under [data.packages.apt] in
# home/.chezmoi.toml.tmpl; the rendered ~/.config/ubuntu_pkglist
# regenerates from it, and changes auto-install on the next apply.
chezmoi init --apply
# npm globals — declared under [data.packages.npm] in
# home/.chezmoi.toml.tmpl. run_onchange_after_install-npm-globals
# sources nvm, ensures NodeJS LTS is installed, then `npm install -g`
# each entry. Re-runs whenever the list changes.This repo uses age to encrypt sensitive files. chezmoi decrypts them
automatically on apply.
age-keygen -o ~/.config/chezmoi/key.txtStore this key in Bitwarden. Place it at ~/.config/chezmoi/key.txt on each
machine.
chezmoi edit --encrypted ~/.config/secret-file
chezmoi applyHighly sensitive secrets (API keys, passwords) belong in Bitwarden, not here.
- macOS (Sonoma and later)
- Ubuntu 22.04+ / Debian 11+
- WSL (Windows Subsystem for Linux)
- Windows 10/11 (PowerShell path)
- CONTRIBUTING.md — development workflow and code style
- docs/TESTING.md — CI pipeline and validation scripts
- docs/TROUBLESHOOTING.md — common issues and fixes
Personal configuration. Feel free to fork and adapt for your own use.