Personal configuration files, managed with GNU Stow.
git clone git@github.com:danielcopper/dotfiles.git ~/dotfiles
cd ~/dotfiles
./bootstrap.sh <class>Where <class> is one of arch, steamdeck, wsl-arch.
bootstrap.sh is the only command needed — same call on a fresh machine and after pulling changes. The whole pipeline is idempotent: pacman runs with --needed, brew skips already-installed packages and upgrades new versions, flatpak's --noninteractive is a no-op on installed apps, and stow re-links while moving any genuinely conflicting $HOME files into a timestamped backup under ~/.dotfiles-pre-stow.<ts>/.
| path | purpose |
|---|---|
bash/, git/, nvim/, tmux/, wezterm/, … |
Stow packages — one per app. Each mirrors the target tree under $HOME. |
host-<class>/ |
Per-host packages holding .local addenda (.bashrc.local, .gitconfig.local) and class-specific overrides where merge isn't possible (e.g. Claude settings.json, the NVIDIA wireplumber tweak on arch). |
packages/common.pkglist, packages/<class>.pkglist |
Pacman lists for the arch and wsl-arch classes. Blank lines and # comments ignored. |
packages/steamdeck.brewlist |
Linuxbrew list — SteamOS root is read-only, so steamdeck uses brew instead of pacman. install-packages.sh bootstraps brew if missing. |
packages/steamdeck.flatpaklist |
Flatpak app list for steamdeck — for apps that ship as macOS-only Homebrew Casks (wezterm) and need a Linux install path. Installed user-scope from flathub. |
install-packages.sh <class> |
Install / update OS packages (pacman on arch / wsl-arch, brew + flatpak on steamdeck). |
install-dotfiles.sh <class> |
Symlink the relevant stow packages into $HOME. Worktree-aware; backs up real conflicts. |
bootstrap.sh <class> |
Wrapper that runs both install-packages.sh and install-dotfiles.sh. |
samples/ |
Snapshots that aren't dotfiles and aren't stow-managed (SDDM theme + login wallpapers — they live under /usr/share/sddm/, manual root deploy). Kept in repo as a record. |
.stowrc |
Default stow flags (--target=~, ignores install-*.sh, bootstrap.sh, packages/, samples/, host-*/). |
Shared across all hosts:
mv ~/.config/<app>/<file> <app>/.config/<app>/<file>
cd ~/dotfiles && stow -R <app>New stow package:
- Create the package directory at repo root, mirroring the target path:
<pkg>/.config/<pkg>/…(or<pkg>/.<file>for$HOME-level dotfiles). - Add
<pkg>toinstall-dotfiles.sh'scommon_pkgsarray, or to a class-specificclass_pkgsif it should only land on certain hosts. cd ~/dotfiles && stow -R <pkg>to symlink it immediately.
Class-specific tweak to a mostly-shared file:
printf '\nexport PATH="$HOME/extra:$PATH"\n' >> host-arch/.bashrc.local
stow -R host-archherdr shows each Claude session's state (working / idle / blocked) in its
sidebar via a hook that herdr integration install claude installs. That
command does not compose with this repo: it bakes an absolute $HOME
path into ~/.claude/settings.json (a stowed symlink into the repo) and
rewrites the whole file alphabetically — both fight the single, shared
settings.json. So the integration is vendored by hand instead:
- The hook script is committed at
claude/.claude/hooks/herdr-agent-state.shand stows to every host. It is portable — a no-op unless run inside a herdr pane (HERDR_ENV/HERDR_SOCKET_PATH/HERDR_PANE_ID) — and carries aHERDR_INTEGRATION_VERSIONmarker. - Its
SessionStartentry insettings.jsonuses$HOME, not an absolute path, so it works on every machine. Hand-maintained — don't letherdr integration installown it.
Do not run herdr integration install claude during setup; mise install
(the herdr entry) plus a normal stow is all a machine needs. Only re-run it to
regenerate the script when herdr integration status reports stale (herdr
bumped the integration version), then:
- It rewrites the script through the symlink — the repo copy updates, good —
and reformats
settings.json. git restore claude/.claude/settings.jsonto drop the reformat.- Re-apply the one-line
$HOMEhook path if it was lost, then commit the updated script.
- Pre-stow conflict backups are created at
~/.dotfiles-pre-stow.<timestamp>/wheneverinstall-dotfiles.shfinds existing$HOMEfiles that would clash with the stow run. - Pre-stow snapshot of the WSL machine: branch
archive/wsl-2026-04-24on origin. - Pre-yadm per-machine history: tags
archive/pre-yadm/{main,arch,wsl,steamdeck,windows}.
Pull a single file from an archive tag:
git show archive/pre-yadm/windows:Microsoft.PowerShell_profile.ps1 \
> ~/Documents/PowerShell/Microsoft.PowerShell_profile.ps1