Prometheus

Maintenance — Brewfile, gitconfig, update, clean-node-modules, bigfiles

Declarative package lists, a global gitconfig with delta diffs, a one-command updater, a node_modules sweeper, a line-count refactor radar, and the modular installer.

Declarative package lists, a global gitconfig with delta diffs, a one-command updater, a worktree-friendly node_modules sweeper, a line-count ranker that exposes refactor candidates, and a background LaunchAgent that quietly sweeps ~/Downloads onto the NAS. Keeps the system reproducible, current, and tidy without thought.

Jump to:

Brewfile

Three declarative package lists at the repo root. install.sh runs brew bundle against the right one based on your WM choice. Adding a new tool is one line in a file instead of editing a shell script.

FileWhen appliedContents
BrewfileAlways

fish, starship, fastfetch, bat, eza, lsd, fzf, zoxide, thefuck, jq, git-delta, rbenv, nvm, fnm, openjdk@17, scrcpy, JetBrains Mono Nerd Font

Brewfile.omniwmIf WM = OmniWMomniwm, sketchybar, sf-symbols, codexbar
Brewfile.aerospaceIf WM = AeroSpaceaerospace, sketchybar, sf-symbols, codexbar
Apply manually
cd ~/dotfiles
brew bundle --file=Brewfile
brew bundle --file=Brewfile.aerospace   # or Brewfile.omniwm

Optional GUI apps (Ghostty, Cursor, Claude, Spotify) remain as prompts in install.sh — they’re not in any Brewfile so brew bundle doesn’t force every app on you.

~/.gitconfig

Symlinked from git/.gitconfig. Delta diffs in Tokyo Night, sensible defaults, and a tight alias set.

Defaults

  • init.defaultBranch = main
  • push.autoSetupRemote — no more --set-upstream
  • rebase.autoStash + autoSquash
  • fetch.prune + pruneTags
  • merge.conflictstyle = zdiff3
  • rerere.enabled — replay conflict resolutions
  • branch.sort = -committerdate — recent first

Delta integration

Syntax-highlighted, hyperlinked, line-numbered diffs in git diff / log / show.

  • Tokyo Night-tinted plus/minus backgrounds
  • n / N navigates between files
  • File paths are ⌘-click hyperlinks

Aliases

AliasExpands to
git sgit status -sb
git lggraph log with author, date, refs
git lastgit log -1 HEAD --stat
git whogit shortlog -sne — author leaderboard
git swc <name>git switch -c — new branch
git cm "msg"git commit -m
git amendgit commit --amend --no-edit
git undogit reset --soft HEAD~1
git unstagegit reset HEAD --
git pushfgit push --force-with-lease (safe force)
git cleanupDelete branches already merged into main
git aliasesList every alias in this file

Machine-specific overrides (work email, GPG key) go in ~/.gitconfig.local — it’s silently included if it exists.

bin/update

A single command that keeps the whole stack current. Symlinked to ~/.local/bin/update so it’s on your $PATH from anywhere.

Run weekly
update
StepWhat it does
Dotfilesgit pull --ff-only in ~/dotfiles (skips if dirty)
Homebrewbrew update + upgrade + upgrade --cask + bundle + cleanup
Bunbun upgrade
npm globalsnpm update -g
Claude CodeBest-effort claude update (Claude self-updates on launch anyway)

Safe to re-run. Each step is gated behind command -v so missing tools are quietly skipped instead of erroring.

bin/clean-node-modules

Reclaim disk space across your repo and its git worktrees. Scans $PWD recursively, lists every top-level node_modules with its size, then deletes them after a single confirmation. Nested node_modules inside another node_modules are pruned from the walk so the scan stays fast. Symlinked to ~/.local/bin/clean-node-modules so it’s on your $PATH in zsh and fish.

Interactive — recommended
clean-node-modules
FlagWhat it does
-n / --dry-runList matches and total size, delete nothing
-y / --yesSkip the confirmation prompt
-h / --helpShow usage
Preview before deleting
cd ~/code/some-monorepo
clean-node-modules -n
Sweep every worktree under a parent dir
cd ~/code/worktrees
clean-node-modules -y

Run from the directory you want to scan — the tool always uses $PWD as the root, never your home directory. npm install / bun install rebuilds node_modules from the existing lockfile, so deleting is safe on any committed project.

bin/bigfiles

Refactor radar. Ranks every source file under $PWD by line count, skipping the noise — node_modules, .git, build, dist, out, target, .next, .nuxt, .turbo, .expo, .yarn, .venv, __pycache__, .gradle, Pods, DerivedData, .dart_tool, vendor, lock files, minified bundles, source maps — so the ranking reflects code you actually wrote. Useful when an AI-assisted codebase grows quietly and a single file drifts past four-figure line counts. Symlinked to ~/.local/bin/bigfiles so it’s on $PATH in zsh and bash; a thin fish wrapper at ~/.config/fish/functions/bigfiles.fish exposes it as a fish function too.

Top 20 files in the current project
bigfiles
FlagWhat it does
-n <N> / --top <N>Show the top N files (default 20)
-t <N> / --threshold <N>Only files with at least N lines
-e <csv> / --ext <csv>Restrict to extensions, e.g. ts,tsx,js
-a / --allDon’t filter by extension — count every file
--clocDelegate to cloc with the same excludes — full code/comment/blank breakdown
-h / --helpShow usage
ColorLine count
red≥ 2,000 — split it
yellow≥ 1,000 — review
cyan≥ 500 — keep an eye on it
green< 500 — fine
Refactor radar — every file ≥ 500 lines
cd ~/code/my-app
bigfiles -t 500 -n 100
React Native / Next.js — just the TS sources
bigfiles -e ts,tsx -n 30
Full code/comment/blank breakdown via cloc
bigfiles --cloc

Counts physical lines (wc -l) — fast and good enough for “what should I split next?” The --cloc mode hands the same exclude list to cloc for a comments-vs-code breakdown when you need the nuance (brew install cloc).

bin/sort-downloads

Auto-sort for ~/Downloads — classify each file by extension, move to a matching folder on the NAS. Full documentation (LaunchAgent setup, category routing, screenshot caveat, atomic copy pattern) lives on the dedicated NAS Workflow page.

Installed only when ENABLE_SORT_DOWNLOADS=true in ~/.config/dotfiles/local.env. The wizard asks during ./install.sh setup.

install.sh — modular installer

install.sh at the repo root is a thin orchestrator (~190 lines). Each part of the install lives in its own file under install.d/, exposing one function: module_<name>(). The orchestrator parses flags, decides which modules to run, then sources and calls them in order. Different machines pick different combos — no more “all or nothing”.

The modules

ModuleRole
00-lib.shShared helpers — colors, logging, link, brew_install, npm_install, curl_install, prompt. Sourced by every module.
01-menu.shModule catalog + pure-bash interactive picker + --only/--skip/--yes flag parsing. Defines should_run <name>.
10-prereqsAlways runs. macOS check, Xcode CLT install, banner. Not in the picker — it’s a hard requirement.
20-homebrewHomebrew install + brew bundle of Brewfile + Node LTS (nvm) + Bun + WM-specific Brewfile + sketchybar font + fish in /etc/shells
30-wmWindow manager picker — OmniWM / AeroSpace / none. Sets $WM_CHOICE which other modules read.
40-shellsfzf-tab git clone (no brew formula for it)
50-appsOptional GUI apps — per-app Y/N prompts (Ghostty, Cursor, Claude, Codex CLI, Spotify, …)
60-symlinksEvery link <src> <dst> call — the actual dotfiles linking
70-launchdTime Machine monthly LaunchDaemon + Downloads-sort LaunchAgent + NAS auto-mount retry LaunchAgent (sed-templated for $HOME)
80-macosmacOS preferences — Dock, Finder, screenshots, Office telemetry, etc.
90-sketchybarRestart SketchyBar after packages + symlinks are in place

Picking what to install

Four ways to choose, in priority order:

Interactive — the default
./install.sh
# Shows a numbered menu. Type "1 3 5" to toggle items, 'a' for all,
# 'n' for none, Enter to confirm. Symlinks is pre-checked.
Exact set via --only
./install.sh --only=symlinks,macos
# Skips the menu entirely. Useful for scripted runs and CI.
Inverse selection via --skip
./install.sh --skip=wm,homebrew
# Runs everything except these. Useful on machines that
# already have Homebrew and don't want a WM.
Everything, auto-Yes
./install.sh --yes
# Runs all modules. Inside each module, Y/N prompts auto-answer Y.
Env var (CI-friendly equivalent of --only)
INSTALL_MODULES=symlinks,macos ./install.sh
FlagWhat it does
--dry-runPrint every action without making changes (combines with any other flag)
--yes / -yRun all modules; inside each, auto-answer Y to sub-prompts
--only=<csv>Run only the listed modules, skip the picker
--skip=<csv>Run everything except the listed modules
--modulesPrint the module list and exit
--manOpen the full man page (with a framed ASCII logo)
--help / -hShow short usage summary

Interactive picker keys

When no selection flag is given, the picker opens. Single-keystroke, no Enter needed for each key. The frame redraws atomically (one printf call building the whole frame as a string) so movement is smooth with no flicker.

KeyAction

/ k

Move cursor up

/ j

Move cursor down
SpaceToggle the highlighted module
aSelect all
nClear all
rReset to defaults (symlinks only)
EnterConfirm and run

q / Esc

Quit (clears selection, bails)

Footer shows a live Selected: X/8 counter so you can see what you’ve picked at a glance.

Man page

A real groff man page lives at man/install.1 — opens in your pager via ./install.sh --man. Includes a framed ASCII logo and full reference for every flag, every module, every interactive key, environment variables, exit codes, and example invocations.

Open the man page
./install.sh --man

Design notes

  • Pure-bash picker. No whiptail / dialog dependency — the menu works on a bare macOS install where nothing extra has been brewed.
  • Flicker-free redraw. The whole frame is built as a single bash string and emitted with one printf call. Each line ends with \033[K (clear-to-end-of-line) so leftover characters from the previous frame are wiped without a screen-clear flash. Color variables use ANSI-C quoting ($'\e[…m') so both echo -e and printf '%s' render correctly.
  • bash 3.2 compatible. Uses parallel indexed arrays instead of declare -A, so the script runs on macOS’s stock /bin/bash on a fresh machine before Homebrew has installed anything.
  • Mutually exclusive flags. --only and --skip can’t be combined — the orchestrator errors out cleanly if both are given.
  • Atomic curl bootstrap. All install.d/ files land in a single commit so curl … | bash users never see a half-modular state mid-clone.
  • Adding a new module. Drop install.d/NN-name.sh defining module_name(), append name|description to the catalog in 01-menu.sh, and add a should_run name && … && module_name block in install.sh. Three edits, one new file.

The public bootstrap at docs/install.sh (served from dotfiles.rafay99.com/install.sh) is unchanged — it still git-clones the repo and runs bash $TARGET/install.sh. The orchestrator handles everything from there.

On this page
Edit this page on GitHub Last updated

Built by rafay99-epic · MIT License

Tokyo Night · macOS · SketchyBar · AeroSpace · Ghostty · Zsh · Fish