Cross-platform shell, terminal, and tool configs — one repo, eight hosts, zero conditionals.
Powered by GNU Stow. Layered like CSS. Boring on purpose.
macOS · WSL · Ubuntu · Fedora · Stanford Sherlock HPC · Marlowe · Windows
git clone https://github.com/FridrichMethod/dotfiles.git ~/dotfiles
cd ~/dotfiles && git submodule update --init --recursive
./stow-all.sh mac # or: wsl-ubuntu, lab-ubuntu, sherlock, marlowe, fedora, ubuntu, win- One command to install everything on a fresh machine —
./stow-all.sh <host>. - Layered configs:
common/is the baseline;<host>/overrides where machines differ. - No templating, no conditionals — Stow symlinks the right files into
$HOME. - Self-healing: a shell hook checks for upstream changes once per login session and fast-forwards behind branches.
- Skill sync: a weekly background hook keeps
~/.claude/skills/and~/.codex/skills/aligned with awesome-skills (~1,668 skills). - CI-checked: every push runs
shellcheck,shfmt,stylua, and hygiene hooks — same as the local pre-commit. - HPC-aware: Stanford Sherlock and Marlowe overlays handle login-node quirks, module systems, and SLURM-friendly defaults.
1. Clone with submodules:
git clone --recurse-submodules https://github.com/FridrichMethod/dotfiles.git ~/dotfiles
cd ~/dotfiles2. Stow your host (always stows common/ first, then the overlay):
./stow-all.sh mac3. Reload your shell:
exec $SHELL -l
.stowrcsets--target=~so every package links into$HOME. Stow runs with--restow --no-folding, so re-running the installer is safe and idempotent.
| Layout | common/ + 8 host overlays |
| Shells | Zsh, Bash, POSIX sh, tcsh, xonsh |
| Terminals | WezTerm, Kitty |
| Editor | Vim |
| Submodule | PyMOLScripts — auto-updated daily by GitHub Actions |
| Install | One command: ./stow-all.sh <host> |
| Update | On every login (throttled to once per session) |
| CI | shellcheck · shfmt · stylua · YAML/JSON/TOML hygiene |
┌──────────────────────────┐
│ ~/.dotfiles │
│ (this repo) │
└────────────┬─────────────┘
│
┌────────────────────────┼────────────────────────┐
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ common/ │ │ <host>/ │ │ stow-all.sh │
│ shared layer │ │ overlay layer │ │ installer │
└────────┬────────┘ └────────┬────────┘ └────────┬────────┘
│ │ │
└──────────┬─────────────┘ │
│ stow --restow --no-folding ◀─────┘
▼
┌───────────┐
│ $HOME │
│ symlinks │
└───────────┘
Full directory tree
dotfiles/
├── common/ shared defaults (stowed first)
│ ├── aria2/ download client
│ ├── bash/ .bashrc, .bash_aliases, .bash_profile
│ ├── conda/ .condarc
│ ├── git/ .gitconfig (with [include] ~/.gitconfig_local)
│ ├── kitty/ Kitty terminal
│ ├── pymol/PyMOLScripts/ submodule — daily auto-update via Actions
│ ├── sh/ POSIX .profile + .aliases (sourced by bash/zsh)
│ ├── ssh/ minimal ~/.ssh/config + Include config.d/*.conf
│ ├── tcsh/ .tcshrc
│ ├── vim/ .vimrc
│ ├── wezterm/ .wezterm.lua
│ ├── xonsh/ .xonshrc
│ └── zsh/ .zshrc, .zshenv, .zprofile, .p10k.zsh
│
├── mac/ macOS overrides
├── wsl-ubuntu/ WSL 2 Ubuntu overrides
├── lab-ubuntu/ lab Ubuntu (includes Fcitx5 IME config)
├── sherlock/ Stanford Sherlock HPC
├── marlowe/ Marlowe HPC
├── fedora/ Fedora overrides
├── ubuntu/ Ubuntu desktop overrides
├── win/ Windows-side (.wezterm.lua, .wslconfig)
│
├── .github/workflows/ ci.yml + daily submodule sync
├── .pre-commit-config.yaml shellcheck · shfmt · stylua · hygiene
├── .stowrc Stow defaults (--target=~, ignores)
├── stow-all.sh one-command installer
├── dotfiles-update.sh session-once auto-pull on shell login
├── awesome-skills-update.sh weekly Claude/Codex skill sync
├── CLAUDE.md guidance for Claude Code
└── AGENTS.md guidance for OpenAI Codex / other agents
| Category | Tools |
|---|---|
| Shell | Zsh (with Powerlevel10k), Bash, POSIX sh, tcsh, xonsh |
| Terminal | Kitty, WezTerm |
| Editor | Vim |
| Version Control | Git, SSH |
| Science | Conda (.condarc), PyMOL scripts (submodule) |
| Utilities | Aria2 |
| Input (Linux) | Fcitx5 (lab-ubuntu only) |
| Host | Platform | Overlay packages | Files |
|---|---|---|---|
mac/ |
macOS | bash, git, sh, ssh, zsh |
7 |
wsl-ubuntu/ |
WSL 2 | bash, git, sh, ssh, zsh |
6 |
lab-ubuntu/ |
Ubuntu (lab) | bash, fcitx5, git, sh, ssh, zsh |
9 |
sherlock/ |
Stanford HPC | bash, sh, zsh |
4 |
marlowe/ |
Marlowe HPC | bash, sh, zsh |
4 |
fedora/ |
Fedora | bash, zsh (placeholders) |
— |
ubuntu/ |
Ubuntu desktop | bash, zsh (placeholders) |
— |
win/ |
Windows | wezterm, wsl |
3 |
common/ |
shared baseline | 13 packages | 37 |
common/zsh/.zshrc ──stow──▶ ~/.zshrc (baseline)
common/git/.gitconfig ──stow──▶ ~/.gitconfig (baseline)
mac/git/.gitconfig_local ──stow──▶ ~/.gitconfig_local (host override, [include]'d)
mac/ssh/.ssh/config.d/* ──stow──▶ ~/.ssh/config.d/* (host-specific endpoints)
common/is stowed first — every package, every host. Shared baseline.<host>/is stowed second — overrides where the machine differs.stow --no-foldingsymlinks individual files, not whole directories, so the two layers compose cleanly.- SSH permissions are re-asserted on every run (
700on~/.ssh,600onconfigfiles) sosshdstays happy.
Git overrides flow through
[include] path = ~/.gitconfig_local— the shared.gitconfigincludes the host file if it exists. SSH overrides flow throughInclude ~/.ssh/config.d/*.conf— the shared root config delegates to per-concern fragments.
Two small shell hooks run on each interactive shell login. Both are session-throttled, so subshells and tmux panes never re-run them.
dotfiles-update.sh — pulls this repo when behind
Fetches the remote, fast-forwards if behind, then nudges you to re-stow and reload the shell. Sourced from common/zsh/.zshrc (zsh) and common/sh/.profile (bash/POSIX login shells).
[dotfiles] 2 new commit(s) available — pulling...
[dotfiles] Pulled successfully.
[dotfiles] Run stow-all.sh to re-stow, then exec zsh to load updated config.| Variable | Default | Effect |
|---|---|---|
DOTFILES_AUTO_UPDATE |
1 |
set to 0 to disable |
DOTFILES_DIR |
~/dotfiles |
repo path |
Session marker: _DOTFILES_CHECKED — exported so subshells skip instantly; a fresh SSH session (clean env) triggers a new check.
awesome-skills-update.sh — weekly Claude/Codex skill sync
Keeps ~/.claude/skills/ and ~/.codex/skills/ in sync with FridrichMethod/awesome-skills — a curated collection of ~1,668 Claude Code / Codex skills for AI4Protein, bioinformatics, AI development, and academic writing.
Behavior
| Aspect | Default |
|---|---|
| First-time install | Foreground (you see the curl progress) |
| Refresh interval | Every 7 days |
| Subsequent refreshes | Background — never blocks shell startup |
| Lockfile | $XDG_CACHE_HOME/awesome-skills/in-progress.pid |
| Log | $XDG_CACHE_HOME/awesome-skills/last.log |
| Failure handling | Stamp not advanced → retries next shell session |
| Manual trigger | sync-skills alias |
Requirements — bash, curl, tar, rsync. The hook silently no-ops if curl is missing; the installer errors clearly if tar/rsync are missing. All four are pre-installed on macOS and most Linux desktop distros. Minimal Linux boxes usually just need rsync:
| Platform | Install command |
|---|---|
| Debian / Ubuntu / WSL Ubuntu | sudo apt-get install -y curl tar rsync |
| Fedora / RHEL | sudo dnf install -y curl tar rsync |
| Arch | sudo pacman -S --needed curl tar rsync |
| macOS (Homebrew) | brew install rsync (curl/tar/bash are built-in) |
| Stanford Sherlock | module load system rsync |
| Conda envs | conda install -c conda-forge rsync curl tar |
Env knobs
| Variable | Default | Effect |
|---|---|---|
AWESOME_SKILLS_AUTO_UPDATE |
1 |
set to 0 to disable entirely |
AWESOME_SKILLS_REFRESH_DAYS |
7 |
change the throttle window |
AWESOME_SKILLS_FORCE |
0 |
set to 1 to bypass throttle once |
AWESOME_SKILLS_BG |
1 |
set to 0 to run synchronously |
AWESOME_SKILLS_INSTALLER_URL |
upstream install.sh |
point at a fork or branch |
Force a sync:
sync-skillsOptional but recommended — same tools CI runs.
pip install pre-commit # or: brew install pre-commit
pre-commit install
pre-commit run --all-files| Hook | Scope |
|---|---|
| shellcheck | .sh, .bash*, .profile, .alias(es) |
| shfmt | .sh, .bash*, .zsh* (4-space indent, indented case, language-aware) |
| stylua | *.lua, *.luau |
| hygiene | trailing whitespace, EOF, merge conflicts, YAML/JSON/TOML, large files |
| File | Audience |
|---|---|
CLAUDE.md |
Claude Code |
AGENTS.md |
OpenAI Codex and any agent following the AGENTS.md convention |
Both files are self-contained and cover repo scope, required conventions, working commands, verification, and per-topic conventions (shell, Git/SSH, Stow, workflows). Editor-specific tooling configs (such as .cursor/) are local-only and not tracked.
# 1. Mirror the $HOME path inside common/ (or under a host overlay)
mkdir -p common/newtool/.config/newtool
# 2. Add your config
cp ~/.config/newtool/config.toml common/newtool/.config/newtool/
# 3. Stow it
stow --restow --no-folding -d common newtool
# 4. (Or: re-run the installer, which picks up all packages automatically)
./stow-all.sh <host>- Keep secrets out of version control — use
*_localfiles referenced by[include]chains. - Stow order is sacred:
common/first, host second. - POSIX vs Bash vs Zsh: shared logic lives in
common/sh/; Bash/Zsh-specific syntax stays in matching shell files. - CI mirrors local: every commit is checked with the same
shellcheck/shfmt/styluayou run viapre-commit. - Verification: after edits, run
pre-commit run --all-filesbefore committing.
MIT — see the file for the full text.