diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..28220cc --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,159 @@ +# 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