1
0
Fork 0
My dot files organized via chezmoi
Find a file
rain 05e75bc41e sway: extract start-swayidle.sh as single source of truth (fix caffeine)
caffeine.sh click was silently breaking idle lock. Two bugs that
compounded:

1. caffeine.sh inlined its own swayidle command (with swaylock -f -i
   , not lock-fancy.sh), drifted out of sync with sway/config
   which used lock-fancy.sh. Toggle off would restart swayidle with a
   different lock command than the rest of the session.

2. WAYLAND_DISPLAY isn't set in waybar's on-click context. When
   caffeine.sh called 'swaymsg output * power off' (part of the
   restart command) and later called swaylock / grim (via lock-fancy),
   those failed silently. swayidle itself can run without
   WAYLAND_DISPLAY but it can't actually monitor input/output, so it
   exits immediately. Result: user clicks caffeine off, flag clears,
   icon goes back to 'inactive', but auto-lock is silently dead.
   The user thinks they turned caffeine off. They didn't. They're
   just unprotected.

Fix:
- new start-swayidle.sh holds the canonical swayidle command
- sway/config: exec $HOME/.config/sway/start-swayidle.sh
- caffeine.sh: killall swayidle; start-swayidle.sh &
- start-swayidle.sh probes /proc/*/environ for a Wayland client's
  env (mako always has it) and exports WAYLAND_DISPLAY /
  DBUS_SESSION_BUS_ADDRESS / XDG_RUNTIME_DIR / DISPLAY if missing
  before exec'ing swayidle

Single source of truth + env restoration = click works on every box
that has the same Wayland-capable process tree (mako, swaybar, etc.),
no matter who/what is calling the script.

Verified on tadbit: pre-fix toggle off killed swayidle permanently.
Post-fix: toggle off restarts swayidle successfully, env inherited
from mako's /proc/PID/environ.
2026-06-23 21:51:09 -04:00
dot_config sway: extract start-swayidle.sh as single source of truth (fix caffeine) 2026-06-23 21:51:09 -04:00
dot_local/bin Fix neovim symlink target: was basename(tarball), now explicit NVIM_EXTRACT_DIR 2026-06-21 21:31:44 -04:00
dot_omp/agent omp models.yml: rename to private_ prefix (chmod 600 on decrypt) 2026-06-23 19:44:09 -04:00
.chezmoi.yaml.tmpl Add tadbit (Gentoo laptop) to age recipients + re-encrypt secrets 2026-06-23 15:57:13 -04:00
.chezmoiignore Initial chezmoi-managed dotfiles with bootstrap scripts 2026-06-21 18:10:54 -04:00
dot_gitconfig.tmpl Initial chezmoi-managed dotfiles with bootstrap scripts 2026-06-21 18:10:54 -04:00
dot_tmux.conf Initial chezmoi-managed dotfiles with bootstrap scripts 2026-06-21 18:10:54 -04:00
dot_zshrc.tmpl Add /opt/rocm/bin to PATH in zshrc when it exists 2026-06-22 19:16:31 -04:00
README.md README: document omp zai-coding provider quirk + models.yml encrypted 2026-06-23 19:47:19 -04:00
run_once_00-install-bootstrap-tools.sh.tmpl Gentoo bootstrap: fix ambiguous package names + early-return on os_family mismatch 2026-06-23 16:18:54 -04:00
run_once_05-install-hosts.sh.tmpl Make run_once scripts sudo-prompt-free when packages already present 2026-06-22 15:10:49 -04:00
run_once_10-add-chaotic-aur.sh.tmpl Guard run_once_10 with os_family conditional + sudo everywhere 2026-06-21 20:17:39 -04:00
run_once_10-add-gentoo-overlays.sh.tmpl Gentoo bootstrap: fix ambiguous package names + early-return on os_family mismatch 2026-06-23 16:18:54 -04:00
run_once_20-install-user-packages-gentoo.sh.tmpl Font install check: anchor to exact family 'Maple Mono NF' 2026-06-23 20:31:33 -04:00
run_once_20-install-user-packages.sh.tmpl Font install check: anchor to exact family 'Maple Mono NF' 2026-06-23 20:31:33 -04:00
run_once_40-install-sway-gentoo.sh.tmpl Gentoo emerge: use --autounmask-continue (auto-apply + continue) 2026-06-23 17:51:56 -04:00
run_once_40-install-sway.sh.tmpl Gentoo bootstrap: fix ambiguous package names + early-return on os_family mismatch 2026-06-23 16:18:54 -04:00
run_onchange_30-ensure-cargo.sh.tmpl Add Gentoo support with GURU overlay requirement 2026-06-23 15:55:28 -04:00
run_onchange_35-ensure-omp-models-perms.sh.tmpl Add run_onchange to chmod 600 ~/.omp/agent/models.yml 2026-06-23 19:45:03 -04:00

gnu-plus-dotfiles

Chezmoi-managed dotfiles synced across all your linux boxes. Source of truth: ~/.local/share/chezmoi on your main workstation. Remote: https://git.melonbread.xyz/rain/gnu-plus-dotfiles.git (HTTPS for bootstrap, SSH from your main workstation for push — see Onboarding below).

Branches

  • main — current, bootstrap-enabled. All active work.
  • legacy-2025 — frozen snapshot of the pre-chezmoi-bootstrap config. Read-only.

What's in here

.chezmoi.yaml.tmpl              os_family detection (debian | arch | gentoo)
dot_zshrc.tmpl                  zsh config with os_family-conditional aliases
dot_tmux.conf                   tmux + tpm + gruvbox plugin stack
dot_gitconfig.tmpl              git + delta
dot_config/
  bat/                          bat config
  btop/                         btop theme + options
  ghostty/                      ghostty terminal + gruvbox themes
  kitty/                        kitty terminal + gruvbox themes
  nvim/                         LazyVim + custom plugins
  paru/                         (arch-only) paru config
  sway/                         sway + wofi + foot configs (desktops only)
  foot/                         foot terminal config
  wofi/                         wofi launcher configs + CSS
  waybar/                       waybar status bar
  mako/                         (arch-only) mako notification daemon

run_once_00-install-bootstrap-tools.sh.tmpl   age, curl, git, base-devel (pacman/apt/emerge)
run_once_05-install-hosts.sh.tmpl             merge LAN host entries into /etc/hosts
run_once_10-add-chaotic-aur.sh.tmpl           (arch-only) chaotic-aur + paru
run_once_10-add-gentoo-overlays.sh.tmpl       (gentoo-only) enable GURU overlay
run_once_20-install-user-packages.sh.tmpl     (arch+debian) user package set
run_once_20-install-user-packages-gentoo.sh.tmpl  (gentoo-only) user package set via emerge
run_onchange_30-ensure-cargo.sh.tmpl          rustup + bat/topgrade/cargo-update (all 3 OSes)
run_once_40-install-sway.sh.tmpl              (arch+debian) sway + wofi + foot
run_once_40-install-sway-gentoo.sh.tmpl      (gentoo-only) sway stack via emerge

Gentoo notes

Gentoo support was added 2026-06-23 with the GURU overlay requirement. Key differences from arch/debian:

  • No binary packages by defaultemerge compiles from source. The bootstrap scripts set --ask=n --nospinner --quiet-build --keep-going so installs don't prompt and don't abort on a single failure.
  • USE flags matterrun_once_20-install-user-packages-gentoo.sh writes to /etc/portage/package.use/zz-gentoo-bootstrap BEFORE emerging, so the right features are enabled for eza, foot, waybar, etc.
  • GURU overlay is requiredrun_once_10-add-gentoo-overlays.sh runs eselect repository enable guru + emaint sync -r guru. Many user packages (eza, lazygit, topgrade) live in GURU; the main tree alone won't suffice.
  • Per-machine os-release parsing — Gentoo's /etc/os-release uses single-quoted values (e.g. ID='gentoo'), and the parser doesn't strip them, so the os_family template strips them with trimAll "'". Without that fix, .chezmoi.osRelease.id returns 'gentoo' (with literal quotes), and the eq "gentoo" test fails.
  • bun is not in any gentoo overlay — the official curl installer (curl -fsSL https://bun.sh/install | bash) is the fallback path, just like debian.

Onboarding a new box

One command. Copy/paste this on a fresh debian-stable or arch-base install:

sh -c "$(curl -fsSL https://raw.githubusercontent.com/...")" -- -b "$HOME/.local/bin" \
  && export PATH="$HOME/.local/bin:$PATH" \
  && chezmoi init --apply https://git.melonbread.xyz/rain/gnu-plus-dotfiles.git

Or as a heredoc that installs chezmoi then runs the bootstrap (more verbose, easier to read):

export PATH="$HOME/.local/bin:$PATH"
sh -c "$(curl -fsSL get.chezmoi.io)" -- -b "$HOME/.local/bin"
chezmoi init --apply https://git.melonbread.xyz/rain/gnu-plus-dotfiles.git

The bootstrap scripts run automatically as part of chezmoi init --apply. They will:

  1. run_once_00: install age, git, curl, ca-certificates via the OS package manager
  2. run_once_05: merge LAN host entries (miche.local, kaiser.local, etc.) into /etc/hosts so omp/curl can resolve them
  3. run_once_10 (arch only): add Chaotic-AUR repo + signing key, install paru
  4. run_once_20: install zsh, tmux, neovim (binary tarball, arch-aware URL), oh-my-zsh + plugins (autosuggestions, syntax-highlighting, history-substring-search, fzf-tab), tpm, all modern CLI tools (bat via cargo or PM, btop, eza, fzf, fd, ripgrep, zoxide, starship, lazygit, yt-dlp, jq, etc.), set zsh as login shell (via sudo chsh), install Maple Mono NF font (GitHub release zip)
  5. run_onchange_30: ensure rustup/cargo; install topgrade (pacman on arch via chaotic-aur, cargo on debian) and cargo-update

After bootstrap completes (~5-10 min on x86_64, longer on aarch64 with cargo install bat):

exec zsh

fastfetch will run on shell start, starship prompt active, all tools on PATH.

Per-machine age key (required to decrypt secrets)

The repo contains encrypted secrets (~/.omp/agent/zai.key, ~/.omp/agent/.env, ~/.omp/agent/models.yml) that only your per-machine age key can decrypt. After bootstrap, generate the key on this box:

age-keygen -o ~/.config/chezmoi/key.txt
# Paste the printed public key into ~/.local/share/chezmoi/.chezmoi.yaml.tmpl
# under the recipients list, then:
cd ~/.local/share/chezmoi
git pull
# (You'll be prompted to add --force if you have local changes)
chezmoi apply

If you skip this step, the omp config files will still land (they're not encrypted), but zai.key and .env will be missing and omp won't be able to authenticate against providers.

Why models.yml is encrypted (and not in zai.key)

omp v16.1.16 has a quirk: the built-in zai provider routes to https://api.z.ai/api/anthropic (Anthropic-compatible endpoint) which requires x-api-key. omp only sends Authorization: Bearer, so the built-in provider always 401s on real Z.ai API keys.

Workaround: define a custom zai-coding provider in ~/.omp/agent/models.yml pointing at the OpenAI-compatible endpoint https://api.z.ai/api/coding/paas/v4 (which DOES accept Authorization: Bearer).

Gotcha: omp's apiKey: field in custom providers expects a literal key value — NOT an env var name. apiKey: ZAI_CODING_API_KEY was being treated as the literal string ZAI_CODING_API_KEY and sent as Authorization: Bearer ZAI_CO...KEY → 401. The encrypted models.yml in this repo contains the literal Z.ai API key in apiKey: (same key that's in zai.key).

run_onchange_35-ensure-omp-models-perms.sh chmod 600s the decrypted file so the literal key isn't world-readable (matches zai.key's tighter perms).

Sway / Wayland desktop stack

Sway + wofi + foot + waybar + swaybg/lock/idle + grim/slurp + wl-clipboard is opt-in at bootstrap time. The user decides per-box.

Bootstrap prompt: when you run chezmoi init for the first time on a new box, you'll be asked:

sway_setup (default false)? [y/N]

Answer y to install the packages + write the configs. Answer N (or just press enter) to skip. The answer is captured in data.sway_setup in the rendered ~/.config/chezmoi/chezmoi.yaml and never re-asked.

Subsequent flips (per box, takes precedence over the bootstrap answer):

# Enable sway after the fact:
touch ~/.config/chezmoi/features/sway
chezmoi apply

# Disable sway (e.g. running a desktop headless as a server):
touch ~/.config/chezmoi/features/no-sway
rm -f ~/.config/chezmoi/features/sway
chezmoi apply

Migration from hostname-allowlist: the previous design auto-enabled sway on hostnames matching miche/byte/kaiser. That was removed. Existing desktops that already had sway installed kept the ~/.config/chezmoi/features/sway marker, which now serves as the override-on signal — so they still have sway_setup: true without re-prompting.

Migration of chezmoi.yaml: if you ran the new template via SSH (no TTY), the prompt fails with "could not open a new TTY". Run it interactively (chezmoi init) from a real terminal, OR pass --promptBool sway_setup=true|false to set the value without prompting.

The run_once_40-install-sway.sh script:

  • exits 0 with no side effects on non-sway boxes
  • installs sway wofi foot swaybg swaylock swayidle grim slurp waybar wl-clipboard via pacman (arch) or apt (debian)
  • adds dunst instead of mako on debian (mako isn't packaged for debian)
  • creates the ~/.config/chezmoi/features/sway marker so subsequent applies know it's enabled

The configs in dot_config/{sway,foot,wofi,waybar,mako}/ are placed unconditionally — they're harmless on Pis (no tools to read them).

Sway is NOT auto-launched. It's installed as a tool you run manually from a TTY (sway from TTY1) for light desktops. The install and configs sit ready; launching is your call.

Editing dotfiles

chezmoi edit ~/.zshrc          # opens in $EDITOR, auto-applies on save
chezmoi diff                   # see what's pending
chezmoi apply                  # apply pending changes
chezmoi cd                     # jump to the source repo

From inside ~/.local/share/chezmoi, you can git status, git diff, git push like any normal repo.

Common gotchas

  • Neovim too old on Debian: run_once_20 detects this and installs the official binary. If you see "Edit: command not found" inside LazyVim, neovim <0.9.
  • zsh plugins not loading: check ~/.oh-my-zsh/custom/plugins/ exists. Bootstrap installs them.
  • paru 404 on arch: Chaotic-AUR mirrors occasionally lag. Re-run sudo pacman -Syu then chezmoi apply.
  • fastfetch not running: command not found, install via package manager. Debian needs apt install fastfetch (bookworm+).
  • Maple Mono NF font warning in nvim: bootstrap should have installed it. Verify with fc-list | grep -i maple. If missing, see runbook skill chezmoi-bootstrap-runbook for manual install.

Out of scope (intentionally not in repo)

  • ~/.config/zsh/functions.zsh — host-specific (reads ~/AI/llama.cpp/key.txt). Recreate per host.
  • KDE plasma configs (kwinrc, kdeglobals, etc.) — live state, varies wildly per host.
  • Alacritty, foot, fish — not in use, drop if you want.
  • mpv, topgrade, mako — out of scope unless re-added.