Files
2026-08-03 11:04:49 +01:00

7.0 KiB

Doloro's Dotfiles

NixOS dotfiles managed via flake-parts + den (custom flake framework). Multi-host: desktop, laptop, WSL, RPi5 server.

Architecture

dotfiles/
├── flake.nix              # Entry point: `outputs = inputs.flake-parts.lib.mkFlake { inherit inputs; } (inputs.import-tree ./config);`
├── .sops.yaml             # Age-encrypted secrets (6 keys: desktop/laptop user+system, rpi5)
├── config/
│   ├── dendritic.nix      # Root config import
│   ├── inputs.nix         # Flake input definitions
│   ├── namespace.nix      # Namespace setup
│   ├── defaults.nix       # Default values
│   ├── hosts/
│   │   ├── computers.nix  # desktop (x86_64), laptop (aarch64), wsl (aarch64), doloro-bootable
│   │   ├── servers.nix    # rpi5 (aarch64)
│   │   └── aspects/       # Host-specific configurations
│   │       ├── doloro-shared.nix    # Common to all doloro hosts (nixvim, tmux, git, ssh, hyfetch)
│   │       ├── doloro-desktop/      # Desktop-specific (disko, hardware, home, host)
│   │       ├── doloro-laptop/       # Laptop-specific (disko, hardware, home, host, power-management)
│   │       ├── doloro-wsl/          # WSL-specific (home, host)
│   │       ├── doloro-bootable/     # Bootable USB (home, host)
│   │       └── servers/rpi5.nix     # Raspberry Pi 5
│   └── modules/           # Reusable configuration modules
│       ├── ai/            # AI tools (pi-coding-agent, OpenMeteo)
│       ├── gaming/        # Steam, gamemode, gamepad
│       ├── hyprland/      # Window manager
│       ├── niri/          # Alternative WM
│       ├── nixvim/        # Neovim config
│       ├── power-management/  # TLP, auto-cpufreq, battery targets
│       ├── secrets/       # SOPS-managed secrets
│       ├── services/      # Caddy, DDNS, Home Assistant, Traefik, RTMP
│       └── ...

Hosts

Host Arch Type Key Modules
desktop x86_64 NixOS + HM Hyprland, gaming, disko, full stack
laptop aarch64 NixOS + HM Power management, Hyprland
wsl aarch64 NixOS WSL setup
doloro-bootable x86_64 NixOS Bootable USB recovery
rpi5 aarch64 NixOS Server, no GUI

Key Tools & Stack

  • Window Manager: Hyprland (primary), Niri (alternative)
  • Editor: Nixvim (Neovim) — Gruvbox Material, LSP (rust-analyzer, nixd, tsserver), Treesitter, Lualine, Telescope, LazyGit
  • Shell: Fish
  • AI: Pi Coding Agent v0.81.1 (LiteLLM via scuggo proxy)
    • Models: meow (litellm), claude-opus-4-8, gpt-5.5, gpt-5.4-mini (recap/title)
    • Skills: pi-lens, pi-lean-ctx, pi-vitals, pi-spark, pi-caveman, pi-pretty, pi-context-engineering
  • Terminal: Kitty
  • Browser: Zen Browser, Helium
  • Music: Spicetify (Spotify)
  • Aurora: Stylix (themes), NixOS-Hardware
  • Container: Podman
  • Flatpak: nix-flatpak
  • Secrets: SOPS + Age (6 keys for desktop/laptop user+system, rpi5)
  • Nerd Fonts: Custom patched (Doloro1978/nix-nerd-fonts-patcher)

Conventions

  1. Never edit flake.nix directly — run nix run .#write-flake to regenerate
  2. Secrets live in config/modules/secrets/ — encrypted via SOPS age keys in .sops.yaml
  3. Modules are modular: split by concern (ai, gaming, hyprland, power-management, services)
  4. Hosts split into computers.nix and servers.nix — each host gets aspect references
  5. Shared config lives in doloro-shared.nix — imported by all doloro hosts
  6. Disko handles disk layouts for desktop/laptop
  7. Power management is laptop-specific: TLP, auto-cpufreq, battery AC targets, Intel GPU, TDP
  8. CachyOS kernel available as module for desktop

Common Operations

# Apply configuration
sudo nixos-rebuild switch --flake .#desktop

# Home Manager (doloro user)
home-manager switch --flake .#doloro-desktop

# Update flake inputs
nix flake update

# Write regenerated flake.nix
nix run .#write-flake

# Encrypt a secret
nix run .#sops-encrypt <file>

# Enter development shell
nix develop

Validating Config Changes

Standard validation sequence before relying on any edit to a .nix module (used for opencode, ai, and other module changes):

  1. Parse check (fast, catches syntax/brace errors):
    nix-instantiate --parse config/modules/ai/ai.nix >/dev/null && echo "PARSE OK"
    
  2. Hash verification for any downloaded file pinned via pkgs.fetchurl — compute the sha256 locally and confirm it matches the sha256 in the module:
    nix hash file token-tracker.tsx   # or: sha256sum token-tracker.tsx
    
  3. Flake evaluation — full nix flake check may fail on unrelated pre-existing issues (e.g. <den/primary-user> not on NIX_PATH in pure mode). Distinguish pre-existing failures from edit-induced ones before touching the code. nix flake show --impure lists the configuration names (nixosConfigurations: desktop, doloro-bootable, laptop, rpi5, wsl).
  4. Runtime output check — the generated config is a home-manager symlink into /nix/store. After a rebuild, confirm the live files actually contain the change:
    readlink -f ~/.config/opencode/opencode.json   # → /nix/store/...-opencode.json
    rg -n "my-change" "$(readlink -f ~/.config/opencode/opencode.json)"
    
    Also verify supporting files that the change depends on (plugins dir, extra packages, etc.):
    ls -la ~/.config/opencode/plugins/ && readlink -f ~/.config/opencode/plugins/*.tsx
    
  5. Cache check for npm-resolved opencode plugins — confirm opencode actually downloaded the package into its plugin cache:
    ls ~/.cache/opencode/packages/ | rg "plugin-name"
    
    If the package is absent or an old version, the plugin won't load regardless of config.
  6. Log check — search opencode's log for plugin-load errors, filtering out your own tool-call noise:
    rg -i "plugin" ~/.local/share/opencode/log/opencode.log | rg -v "evaluated permission" | tail -30
    
  7. Config is loaded once at startup — a running opencode session keeps the config it loaded at launch. After changing any config file, restart opencode (and run a home-manager rebuild first) before expecting the change to take effect.

Important Notes

  • allowUnfree = true globally for proprietary packages (Steam, Spotify, etc.)
  • Multiple cachix substitutes configured for speed (hyprland, nix-community, niri, raspberrypi, cuda)
  • Pi coding agent uses scuggo LiteLLM proxy at https://9f5db439.fwds.scug.io
  • API key via env var $SCUG_IO_API_KEY
  • WSL host uses nixos-wsl flake input
  • RPi5 uses nixos-raspberrypi and raspberry-pi-nix

File Rules

  • .gitignore: exclude nix/result, result, nvim, tmux/plugins, modules/quickshell/quickshell/.qmlls.ini
  • .new file exists (empty) — likely a marker
  • .claude/ directory present (Claude Code config)