| bin/bin | ||
| extras | ||
| git | ||
| lsd/.config/lsd | ||
| oh-my-posh/.oh-my-posh | ||
| tmux | ||
| zsh | ||
| .gitignore | ||
| .gitmodules | ||
| AGENTS.md | ||
| check_deps.sh | ||
| install.sh | ||
| README.md | ||
| unstow.sh | ||
dotfiles
Personal dotfiles managed with GNU Stow. Each top-level directory is a stow package that mirrors the structure of $HOME. Running install.sh symlinks everything into place and safely backs up any pre-existing files that would conflict.
Requirements
Required
| Tool | Purpose |
|---|---|
bash 4+ |
Install and helper scripts |
stow |
Symlink management |
git |
Version control |
find / sort / awk |
Used by install script |
Strongly Recommended
| Tool | Purpose |
|---|---|
| mise | Runtime version manager (replaces nvm, rbenv, etc.) |
| oh-my-posh | Shell prompt |
| neovim | Editor (nvim) |
| lsd | Modern ls replacement |
| bat | Modern cat replacement |
| lazygit | Terminal UI for git |
| delta | Syntax-highlighting pager for git diffs |
| btop | System monitor |
| fastfetch | System info display |
| tmux + tpm | Terminal multiplexer + plugin manager |
| opencode | AI coding assistant (aliased via opentmux) |
| superfile | Terminal file manager (spf) |
| cliamp | Retro terminal music player |
| gh | GitHub CLI |
| gh-dash | GitHub dashboard TUI (gh extension) |
| neofetch | System info display |
Optional
| Tool | Purpose |
|---|---|
| LM Studio | Local LLM runner (macOS only; path configured in .zshrc) |
| Java (Temurin 17) | JAVA_HOME configured in .zshrc on macOS |
Run check_deps.sh to verify what is and isn't installed — it can also install missing tools automatically.
Installation
# 1. Clone the repo
git clone git@github.com:crueber/dotfiles.git ~/.dotfiles
cd ~/.dotfiles
# 2. (Optional) Check and install dependencies
./check_deps.sh
# or auto-install everything without prompts:
./check_deps.sh --yes
# 3. Stow all packages into $HOME
./install.sh
install.sh is safe to re-run at any time. It will never silently overwrite existing files — conflicts are renamed to <original>.bak.<timestamp> before stowing.
How It Works
Stow Layout
Each top-level directory is a stow package. The directory tree inside it mirrors $HOME, so stow knows exactly where to create symlinks:
dotfiles/
├── bin/
│ └── bin/ → ~/bin/
├── git/
│ ├── .gitconfig → ~/.gitconfig
│ └── .gitignore → ~/.gitignore
├── lsd/
│ └── .config/
│ └── lsd/ → ~/.config/lsd/
├── oh-my-posh/
│ └── .oh-my-posh/ → ~/.oh-my-posh/
├── tmux/
│ ├── .tmux.conf → ~/.tmux.conf
│ └── .tmux/ → ~/.tmux/
└── zsh/
├── .zshrc → ~/.zshrc
└── .aliases → ~/.aliases
Note on
bin/bin/double-nesting: Stow would normally symlink the entirebin/package directory as~/bin. The innerbin/bin/nesting causes stow to instead create~/bin/as a real directory and symlink each script individually inside it. This is intentional — it keeps~/bin/as a real directory that can safely contain non-stow-managed files alongside the symlinked scripts.
install.sh
The install script does the following:
- Discovers all stow packages dynamically (any top-level directory that isn't
.git,.github,node_modules, etc.) - Runs
stow --dry-runto detect conflicts without making any changes - Parses the dry-run output to find exactly which files would conflict
- Renames only those conflicting files to
<path>.bak.<timestamp> - Runs
stow -R(restow) to apply all packages
Backups are timestamped so re-runs never clobber previous backups. Symlinks that already point into the repo are skipped.
check_deps.sh
Checks for all required and recommended tools. Detects the available package manager (Homebrew, apt, pacman) and can install anything missing. Accepts --yes to skip confirmation prompts.
./check_deps.sh # interactive
./check_deps.sh --yes # auto-install all missing tools
Package Details
zsh/
.zshrc— Initializes oh-my-posh with theblue-owl-customtheme, activates mise, setsEDITOR/VISUALto nvim, configures PATH for~/bin, LM Studio, and opencode..aliases— Shell aliases:ls=lsd,vim=nvim,n=nvim,cat=bat,ll="ls -al",..="cd ..",lg=lazygit
Local overrides: Create ~/.zshrc.local for machine-specific settings (tokens, private paths, etc.). It is sourced automatically if it exists and is excluded from git via .gitignore.
git/
.gitconfig— User info, push default (current), useful aliases (aa,ap,ci,co,st,rebase-origin), delta as pager/difftool/mergetool (dark mode default; switch to light viaDELTA_FEATURES=+light), and a commit message template..gitignore— Global ignores:.DS_Store, editor swap files, common Rails and macOS artifacts.
tmux/
.tmux.conf— Loads tpm, tmux-sensible, and tmux-themepack with thepowerline/default/bluetheme. Mouse support andtmux-256colorterminal are enabled..tmux/plugins/tpm/— TPM is vendored directly in the repo so it's available immediately after stowing without a separate bootstrap step.
After stowing, install tmux plugins by pressing prefix + I inside a tmux session.
oh-my-posh/
Four prompt themes are included. The active theme is set in .zshrc:
| File | Notes |
|---|---|
blue-owl-custom.omp.json |
Active — customized version of blue-owl |
blue-owl.omp.json |
Upstream base theme |
microverse-power.omp.json |
Alternative |
tiwahu.omp.json |
Alternative |
To switch themes, update the --config path in zsh/.zshrc.
lsd/
config.yaml— Enables color always, sets a custom color theme.colors.yml— 256-color palette for file type coloring.
bin/
Scripts symlinked into ~/bin/ and available on $PATH:
| Script | Description |
|---|---|
aaxtractor.sh |
Convert Audible .aax/.aaxc files to .m4b |
align.sh |
Library: right_aligned() helper for terminal output (source, don't execute) |
convert.sh |
Batch convert .aax → .m4b via ffmpeg |
get-gh-repos-for.sh |
Clone or pull all repos for a GitHub user or org |
gh-web.sh |
Open the current repo's GitHub page in Brave Browser |
git-churn.sh |
Show most frequently changed files across all git history |
port-kill.sh |
Kill the process listening on a given TCP port |
port-what.sh |
Show the process listening on a given TCP port |
sync-to-git.sh |
Initialize/auto-commit a Syncthing-managed directory as a git repo |
update-repos.sh |
Pull master or main for every git repo in subdirectories |
xlsx-to-csv.sh |
Convert .xlsx to .csv using Nushell |
aaxclean-clinote: This binary is no longer vendored in the repo. Download the appropriate build for your platform from the aaxclean-cli releases page and place it in~/bin/manually.
Adding a New Package
- Create a top-level directory named after the package (e.g.,
ssh/) - Inside it, recreate the path structure as it should appear under
$HOME(e.g.,ssh/.ssh/config) - Re-run
./install.sh— the new package is picked up automatically
Secrets and Local Overrides
Never commit secrets or machine-specific configuration. Use ~/.zshrc.local instead:
# ~/.zshrc.local (not tracked in git)
export GH_TOKEN="your-token-here"
export SOME_API_KEY="..."
The .gitignore at the repo root excludes zsh/.zshrc.local and .zshrc.local to prevent accidental commits.