5.1 KiB
5.1 KiB
AGENTS.md
A guide for AI coding agents working in this Nix flake repository.
Project Overview
Multi-host Nix flake managing NixOS desktops, macOS via nix-darwin, and a home server cluster — all sharing a common Home Manager configuration. Secrets are encrypted with sops-nix + age.
Key Commands
# Apply config on current host (works on any machine)
nix-switch # alias for: sudo nixos-rebuild switch --flake ~/.config/nix#(hostname -s)
# or: sudo darwin-rebuild switch --flake .#(hostname -s)
# Check flake without building (NixOS) / eval toplevel (macOS)
nix-check
# Validate flake inputs and locks
nix flake check --no-build
# Format Nix files
nixfmt <file> # managed via nixvim, runs nixfmt
# Enter dev shell if defined
nix develop
Repo Layout
flake.nix # Entry point — defines all hosts via mkSystem
hosts/<hostname>/ # Per-host configuration.nix + hardware-configuration.nix
nixos/ # Shared NixOS system modules (audio, fonts, sops, tailscale…)
nixos/roles/ # Optional services (Gitea, Matrix, Vaultwarden, AdGuard…)
darwin/ # macOS-only system modules (fonts, homebrew, yabai, sketchybar)
home/ # Shared Home Manager config (all hosts, both platforms)
home/desktop/ # Desktop-only home modules — Linux (hyprland/niri, waybar, rofi…)
home/desktop/sketchybar/ # macOS-only bar config
home/neovim/ # nixvim configuration split by plugin
assets/ # Wallpapers and avatar images — do not modify programmatically
secrets/ # age-encrypted secrets — never edit .age files directly
Hosts
| Hostname | Platform | Type | Notes |
|---|---|---|---|
| cyper-desktop | NixOS x86_64 | Desktop | Primary Linux workstation |
| cyper-mac | macOS x86_64 | Desktop | nix-darwin + Homebrew |
| cyper-controller | NixOS x86_64 | Server | Runs all roles/services |
| cyper-node-1 | NixOS x86_64 | Server | isServer = true |
| cyper-node-2 | NixOS x86_64 | Server | isServer = true |
mkSystem Convention
All hosts are built via mkSystem in flake.nix. Key flags:
isDarwin = true→ usesdarwin.lib.darwinSystem+ darwin modulesisServer = true→ skips desktop/GUI modules; both flags are passed asspecialArgsto all modules viasharedSpecialArgs
Guard platform-specific code with:
if isDarwin then { ... } else { ... }
if isServer then { ... } else { ... }
Home Manager
A single home/ tree is shared by all hosts. Desktop-only modules live under home/desktop/ and are conditionally included. The isDarwin and isServer flags are available as specialArgs inside Home Manager modules.
Secrets
Managed with sops-nix + age encryption.
- Never edit
.agefiles directly — usesops secrets/secrets.yaml - Age key must exist at
~/.config/sops/age/keys.txton every host - Public keys are declared in
secrets/keys.txt.ageand.sops.yaml(if present) - Secrets are referenced in Nix via
config.sops.secrets.<name>.path
Conventions
- Formatter:
nixfmt(run via nixvim; apply before committing) - No
hardware-configuration.nixedits — these are machine-generated; regenerate withnixos-generate-configif needed - Homebrew is managed declaratively via
darwin/homebrew.nix— do not runbrew installmanually - Catppuccin theming is applied system-wide via
home/catppuccin.nixandnixos/catppuccin.nix; keep theme tokens consistent across modules - Shell is Fish — shell aliases and functions live in
home/shell.nix; use fish syntax
Adding a New Host
- Create
hosts/<hostname>/configuration.nix(andhardware-configuration.nixfor NixOS) - Add an entry to
nixosConfigurations(ordarwinConfigurations) inflake.nixviamkSystem - Add the host to the machines table in
README.mdand this file
Adding a New Role/Service
- Create
nixos/roles/<service>.nix - Import it in the relevant host's
configuration.nixor innixos/default.nixbehind anisServerguard - Add any required secrets to
secrets/secrets.yamlviasops
PR Checklist
nix flake check --no-buildpassesnixfmtapplied to changed.nixfiles- No hardcoded paths or usernames — use
primaryUser/hostNamefromspecialArgs - Secrets referenced via sops, not inlined
hardware-configuration.nixuntouched unless intentional- README and AGENTS.md updated if hosts, roles, or structure changed
Gotchas
primaryUseris defined inflake.nixand injected everywhere viasharedSpecialArgs— never hardcode the usernamehome-manager.backupFileExtension = "backup"is set globally; conflicts create.backupfiles rather than erroring- The
lfish function calls a Groq LLM (llama-3.3-70b-versatile) and pipes output throughglow— it requires$GROQ_API_KEYto be set as a file path - sketchybar lives under
home/desktop/sketchybar/but is macOS-only; hyprland/niri are Linux-only nix-switchuseshostname -sat runtime — the hostname must match a key innixosConfigurations/darwinConfigurations