# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Overview This is a NixOS flake-based configuration repository managing both system configurations (NixOS) and user environments (home-manager). The repository follows a modular architecture with separate host configurations for physical machines, VMs, and standalone home-manager setups. ## Essential Commands ### Building and Testing ```bash # Build a NixOS system configuration nix build -L '.#nixosConfigurations..config.system.build.toplevel' # Build and run a VM with disko nix build -L '.#nixosConfigurations.vm.config.system.build.vmWithDisko' ./result/bin/disko-vm # Build home-manager configuration nix build -L '.#homeConfigurations.work.activationPackage' # Build the custom neovim package nix build -L '.#nvim.packages.x86_64-linux.nvim' ``` ### Development ```bash # Update flake inputs nix flake update # Check flake for errors nix flake check # Show flake outputs nix flake show # Enter development shell for neovim cd dots/.config/nvim && nix develop ``` ## Architecture ### Repository Structure The repository is organized into distinct layers: - **`flake.nix`**: Root flake defining inputs and outputs. Uses `utils.dirNames` to automatically discover host directories. - **`hosts/`**: NixOS system configurations (andromache, astyanax, vm). Each host has its own directory with `default.nix` and hardware configuration. - **`home/`**: home-manager configurations, split into `hosts/` (per-host configs) and `modules/` (reusable user-level modules). - **`modules/`**: Reusable NixOS modules for system-level configuration (audio, networking, fonts, etc.). - **`dots/`**: Dotfiles and configurations, including a complete neovim flake at `dots/.config/nvim/`. - **`utils/`**: Helper functions like `dirNames` for discovering directories. ### Key Architectural Patterns **Host Discovery**: The flake uses `lib.genAttrs hostDirNames` to automatically generate `nixosConfigurations` from directories in `hosts/`. Adding a new host only requires creating a directory with a `default.nix`. **Secrets Management**: Uses sops-nix with age encryption. Secrets are stored in a separate private repository (`nix-secrets`) referenced as a flake input. The `modules/secrets/default.nix` module provides options and templates for injecting secrets into configurations. **Disk Management**: Uses disko for declarative disk partitioning. The `modules/disko.zfs-encrypted-root.nix` module provides a reusable ZFS-on-root setup with encryption, taking a `device` parameter. **Neovim as Flake**: The neovim configuration at `dots/.config/nvim/` is a standalone flake using nixCats. It's referenced as a flake input in the root and included in system packages. This allows independent development and version control. **Home Manager Integration**: Each NixOS host can include home-manager configuration through `home-manager.users.`, which imports from `home/hosts/`. Standalone home-manager configurations (like `work`) are also available for non-NixOS systems. **Module Parameterization**: Modules like `networking.nix` and `secrets/default.nix` accept parameters and expose options, making them reusable across hosts with different settings. ### Input Dependencies - **nixpkgs**: Main package source (nixos-unstable) - **nixos-hardware**: Hardware-specific configurations - **disko**: Declarative disk partitioning - **sops-nix**: Secrets management with age/sops - **nix-secrets**: Private repository with encrypted secrets (git+ssh) - **home-manager**: User environment management - **nixgl**: OpenGL wrapper for non-NixOS systems - **firefox-addons**: Firefox extension packages - **nvim**: Local flake at `dots/.config/nvim/` ## Working with Hosts ### Adding a New NixOS Host 1. Create a new directory in `hosts//` 2. Add `default.nix` with imports and host-specific configuration 3. Add `hard.nix` for hardware configuration (generated by nixos-generate-config) 4. The host will automatically be discovered by the flake ### Adding a New Home Manager Host 1. Create directory in `home/hosts//` 2. Add `default.nix` importing desired modules from `home/modules/` 3. For standalone (non-NixOS) configs, add entry to `homeConfigurations` in root `flake.nix` ## Secrets Workflow Secrets are managed with sops-nix and stored in the private `nix-secrets` repository: 1. Secrets are encrypted with age using keys at `~/.config/sops/age/keys.txt` 2. The `modules/secrets/default.nix` module reads from `${nix-secrets}/secrets.yaml` 3. Secrets are exposed as files in `/run/secrets/` with proper ownership 4. Templates can combine multiple secrets (see taskwarrior sync configuration) ## Common Patterns ### Import Patterns Modules use different import patterns based on their needs: ```nix # Simple module (no parameters) imports = [ ../../modules/audio.nix ]; # Parameterized module (function call) imports = [ (import ../../modules/networking.nix { hostName = "andromache"; }) ]; # Module with all parameters imports = [ (import ../../modules/secrets { inherit lib inputs config; }) ]; ``` ### Special Args - `inputs`: Flake inputs, passed as `specialArgs` to NixOS and `extraSpecialArgs` to home-manager - `lib`, `config`, `pkgs`: Standard NixOS/home-manager module arguments ### Username Handling Each host defines a `username` variable (either "h" or "hektor") used for: - User creation in NixOS - Home directory paths - Secrets ownership - Home-manager configuration