Personal development environment configuration.
Two deployment models are supported:
- Full workstation ownership (macOS, NixOS): GNU Stow symlinks the whole environment: shell, terminal, editor, Git, GPG, and agent tooling.
- Additive assets (Omarchy): the OS already owns the desktop and development environment; only curated personal integrations are linked in. See Omarchy Installation.
This repository contains dotfiles organized into Stow packages for easy symlinking and management. Configurations are split between:
~/(home directory) for traditional dotfiles~/.config/for XDG-compliant applications
- GNU Stow - Symlink manager for dotfiles
Option A: Using Nix-Darwin (Recommended)
If you're using nix-configs:
- All dependencies (Powerlevel10k, zsh plugins, tools, fonts, etc.) are installed via nix-darwin configuration
- GNU Stow is included in the nix configuration
Option B: Using Homebrew
-
Install Homebrew:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" -
Install dependencies:
brew install stow brew install powerlevel10k zsh-autosuggestions zsh-syntax-highlighting brew install bat eza fzf direnv herdr brew install neovim git gnupg brew install --cask font-meslo-lg-nerd-font
Option A: Using Nix Flakes (Recommended)
If you're using nix-configs:
- All dependencies (Powerlevel10k, zsh plugins, tools, fonts, etc.) are installed via NixOS configuration
- GNU Stow is included in the nix configuration
Option B: Manual System Configuration
Add the following packages to your configuration.nix:
environment.systemPackages = with pkgs; [
stow
zsh-powerlevel10k
zsh-autosuggestions
zsh-syntax-highlighting
bat
eza
fzf
direnv
(nerdfonts.override { fonts = [ "Meslo" ]; })
neovim
git
gnupg
pinentry-curses # or pinentry-gnome3, pinentry-qt
];Note: Some configurations may need local overrides:
~/.gnupg/gpg-agent.conf- Set correct pinentry program path for your system
From this repository's root directory:
stow . --dotfiles --target $HOME
./setup-platform-configs.shThis symlinks the dotfiles, configures platform-specific Alacritty settings, removes retired tmux links, and sets up the secrets directory.
Additional Manual Step:
GPG configuration - Link GPG agent config:
ln -s ~/code/dotfiles/dot-gnupg/gpg-agent.conf ~/.gnupg/gpg-agent.confOmarchy ships its own coherent Bash, Foot, Neovim, Git, and GPG configuration.
Do not run stow . or stow --adopt on an Omarchy host:
stow .conflicts with files Omarchy already owns and, where it would succeed, shadows Omarchy's XDG configs (e.g.~/.gitconfigover~/.config/git/config) with macOS/Nix-oriented settings.stow --adoptis worse: it moves Omarchy's live configuration files into this repository, corrupting both.
Use the dedicated additive entry point instead:
./scripts/setup-omarchy.sh --check # report what would change; mutates nothing
./scripts/setup-omarchy.sh --apply # perform the additive setupWhat it changes: per-tool symlinks for curated personal agent skills in
~/.claude/skills, ~/.config/opencode/skills, ~/.pi/agent/skills, and
~/.hermes/skills/personal, plus one marked source line appended to an
existing ~/.bashrc (Omarchy's designated personal-additions section) that
loads the portable aliases from dot-config/shell/aliases.sh, a separate
guarded Ble.sh source hook that becomes active when the blesh package is
installed, the Omarchy-specific Herdr configuration and Glyph Rail module
links, a repository-owned shell service that suspends after 45 minutes while
honoring Stay Awake and idle inhibitors, and the pinned Hindsight client
integration. It does not install packages or replace unrelated Omarchy-owned
application configuration.
What it intentionally leaves untouched: login shell selection, terminal, Neovim,
Git, GPG, Zed/OpenCode/Claude settings, installed packages, and everything under
/usr/share/omarchy. Omarchy-provided skill links (e.g. omarchy,
diagnose-crash) are preserved as-is.
Always run --check and review the report before running --apply.
If you're setting up this repo for the first time and want to migrate existing dotfiles:
stow . --adopt --dotfiles --target $HOMEThe --adopt flag will move any existing files in your home directory into the dotfiles repo. After adoption, review the changes and commit only the files you want to manage.
Warning: Be careful with --adopt as it will move existing files into the repo. Review changes before committing. Never use --adopt on an Omarchy host — it moves Omarchy-owned configuration into the repository.
dotfiles/
├── dot-config/ # XDG config directory (~/.config/)
│ ├── alacritty/ # Terminal emulator
│ ├── direnv/ # Direnv configuration with nix-direnv
│ ├── nvim/ # Neovim configuration (Lazy.nvim)
│ ├── opencode/ # OpenCode AI assistant
│ │ ├── AGENTS.md # Global agent instructions
│ │ └── opencode.json # Provider and model configuration
│ └── zsh/ # Modular zsh configuration (~/.config/zsh/)
│ ├── aliases.zsh # All aliases (git, tools, nix, navigation)
│ ├── env.zsh # Environment variables
│ ├── functions.zsh # Custom shell functions (worktree helpers, etc.)
│ ├── options.zsh # Zsh options, vi-mode, completion styles
│ └── plugins.zsh # Cross-platform plugin loading
├── dot-gnupg/ # GPG configuration (~/.gnupg/)
│ └── gpg-agent.conf # GPG agent settings
├── hermes/ # Curated Hermes skills, scripts, and cron definitions
├── omarchy/ # Additive personal Omarchy shell plugins (never stowed)
├── scripts/ # Repo-internal deployment scripts (never stowed)
│ ├── reconcile-agent-skills.sh # Canonical skill curation + per-tool linking
│ └── setup-omarchy.sh # Additive Omarchy entry point
├── tests/ # Integration tests for the deployment scripts
├── dot-gitconfig # Git configuration (~/.gitconfig)
├── dot-gitconfig.local # Git signing key (~/.gitconfig.local, not tracked)
├── dot-zshrc # Zsh shell loader (~/.zshrc) - sources modular configs
├── dot-p10k.zsh # Powerlevel10k theme (~/.p10k.zsh)
└── zsa-keyboard-layouts/ # ZSA keyboard firmware
- Powerlevel10k theme (no Oh My Zsh)
- Plugins: zsh-autosuggestions, zsh-syntax-highlighting
- Direnv integration for per-project environments
- Modular configuration in
~/.config/zsh/:aliases.zsh- Git, tools (bat/eza/nvim), navigationfunctions.zsh- Git, Obsidian, and host-guarded Nix update/upgrade helpersenv.zsh- EDITOR, GPG_TTY, paths, NODE_OPTIONSoptions.zsh- setopt, vi-mode, completion stylesplugins.zsh- Cross-platform plugin loading, direnv
update-<host>andupgrade-<host>identify the current machine, refuse a mismatched target, and require confirmation before rebuilding. On a matching host, Enter accepts the default;ncancels. Upgrade commands updateflake.lockonly after the host check and confirmation.
- GPU-accelerated terminal
- Custom theme and opacity
- MesloLGS NF font for Powerlevel10k
-
Persistent local and remote terminal workspaces
-
herdr-studioattaches to the Studio server -
theme.name = "terminal"makes the UI follow the host terminal's ANSI palette, so it stays native under Nightfly on macOS and under whichever Omarchy theme is live on Arch -
The tab bar's right edge is the Glyph Rail: one Nerd Font glyph per module, joined by a single Powerline soft divider (
) — Claude quota, OpenAI Codex subscription quota, account-wide rolling 24-hour OpenRouter spend, host identity, and the clock 14% ↻3:08 21% ↻1:01 $3.95 Studio 09:11 -
Codex usage reads the OpenAI OAuth credential from Hermes (
~/.hermes/auth.json), falling back to the Codex CLI credential (~/.codex/auth.json). It never refreshes or rotates credentials itself. The compact percentage and reset countdown come from the most-used base quota window, and the last successful value remains visible during transient failures. Without a credential or cached value, the module prints nothing and the rail drops the entry. -
The spend figure is account-wide, not per-machine: it comes from OpenRouter's analytics API over a trailing 24-hour window, so Studio and the MacBook show the same number. It needs a management key — an ordinary
sk-or-v1inference key is refused with403 Only management keys can access analytics:mkdir -p ~/.secrets/openrouter chmod 600 ~/.secrets/openrouter/management-key # after writing the key into it
Without that file the module prints nothing and the rail simply drops the entry.
-
Host identity glyphs come from hardware/OS, not a hostname list: server (Mac Studio), laptop (MacBook), Arch/Omarchy. See
dot-config/herdr/host-label.sh -
A Nerd Font is required for the rail to render (MesloLGS NF on macOS)
- Lazy.nvim plugin manager
- Custom keybindings and plugins
- LSP and completion setup
- GPG signing enabled
- Global gitignore for
.envrcand.direnv/ - Signing key stored in
~/.gitconfig.local(not tracked in git)
- GPG agent configuration for password caching
- pinentry-mac for GUI password prompts
- Cache TTL settings (10 min default, 2 hour max)
- direnv: Automatic environment switching with nix-direnv for fast Nix shell caching
- Config lives in
dot-config/opencode/opencode.json(tracked, stowed to~/.config/opencode/) - The default local model provider connects directly to Studio Ollama over Tailscale at
http://100.121.238.48:11434/v1 - The Ollama endpoint is available only inside the tailnet and does not require an API key
plugins/ollama-models.jsrefreshes the provider's model inventory from Studio whenever OpenCode starts- For repo-specific tweaks (extra docs, different permissions, etc.), create
.opencode/project.jsoninside the repo
hermes/preserves authored local skills, automation scripts, and declarative cron definitions.~/.hermesremains a real local runtime directory; it is intentionally not stowed because it contains credentials, databases, sessions, logs, caches, and Matrix encryption state.setup-platform-configs.shinstalls only manifest-listed assets on Studio, compiles native helpers locally, and reconciles named cron jobs through Hermes's API.- Built-in Hermes skills come from the Hermes installation rather than being copied into dotfiles.
- See
hermes/README.mdfor the managed boundary and restore process.
After modifying any dotfiles:
- Changes are automatically reflected (symlinks point to this repo)
- For shell changes:
source ~/.zshrc - For Herdr changes:
herdr server reload-config
To remove symlinks:
cd ~/code/dotfiles
stow -D . --dotfiles --target $HOMEThese dotfiles are designed to work on both macOS and NixOS with minimal platform-specific configuration.
Shell configuration (dot-zshrc) uses a "source if exists" pattern that checks multiple paths:
- macOS (Homebrew):
/opt/homebrew/share/... - NixOS (system):
/run/current-system/sw/share/... - Linux (standard):
/usr/share/...
Some settings require platform-specific handling:
- SSH Keychain (macOS only) -
dot-zshrcconditionally aliases SSH to use macOS keychain support - GPG Pinentry -
dot-gnupg/gpg-agent.confdefaults to macOS pinentry-mac; NixOS users should override locally - Alacritty Window Decorations -
setup-platform-configs.shautomatically configures:- macOS: No decorations (clean look, no traffic lights)
- Linux: Buttonless decorations (title bar for window management)
On NixOS, you may want to create local overrides for:
# Override GPG pinentry for NixOS
echo "pinentry-program /run/current-system/sw/bin/pinentry-curses" > ~/.gnupg/gpg-agent.conf.localOr manage these via your NixOS system configuration.
- nix-configs - Nix system configuration for both macOS and NixOS
- macOS: nix-darwin with declarative Homebrew package management
- NixOS: System configuration with flakes
- Per-project development environment shells (via flakes + direnv)
- System settings and package management
This repository syncs to multiple remotes. The primary repository is at git.snowboardtechie.com, with backups on Codeberg and GitHub.
- Stow uses relative symlinks by default
- The
--dotfilesflag convertsdot-prefix to.for files/folders - ZSA keyboard layouts are stored but not symlinked
- AGENTS.md is ignored by Stow via
.stow-local-ignoreto prevent symlinking documentation to the home directory - Repository files are ignored:
.git,README.md,.gitignore, and.stow-local-ignoreare excluded via.stow-local-ignoreto prevent symlinking repository metadata - GPG config files require manual symlinking: Since
~/.gnupg/contains sensitive unmanaged files (private keys, trustdb, sockets), stow cannot symlink the entire directory. Individual config files must be manually symlinked after running stow. - Package management: Dependencies managed via nix-configs for both macOS (nix-darwin) and NixOS (system configuration), or manually via Homebrew on macOS