# 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 managing three machines: desktop, laptop, and hyper-v. The configuration uses home-manager for user-level package and dotfile management, with a modular architecture separating system-level and user-level concerns. ## Common Commands ### Verify Changes (use this first) ```bash nix build ~/.config/nixos#nixosConfigurations.$(hostname).config.system.build.toplevel --no-link ``` Use this to catch evaluation and build errors without sudo or activating the system. ### Rebuild System ```bash sudo nixos-rebuild switch --flake ~/.config/nixos ``` Note: Claude Code cannot run this — it requires sudo. Ask the user to run it. ### Format Nix Files ```bash nixfmt .nix ``` ### Flake Operations ```bash nix flake update # Update all flake inputs nix flake lock --update-input # Update specific input nix flake show # Show flake outputs nix flake check # Validate flake ``` ### Build Specific Host ```bash sudo nixos-rebuild switch --flake ~/.config/nixos#desktop sudo nixos-rebuild switch --flake ~/.config/nixos#laptop sudo nixos-rebuild switch --flake ~/.config/nixos#hyper-v ``` ## Architecture ### Two-Layer Module System The configuration has a strict separation between **system-level modules** (in `modules/`) and **user-level modules** (in `modules/home/`): 1. **System-level modules** (`modules/*.nix`): - Import home-manager as a NixOS module - Configure system-wide settings - Import corresponding user-level modules via `home-manager.users.christian.imports` 2. **User-level modules** (`modules/home/*.nix`): - Contain home-manager configuration only - Installed via system-level module imports - Should NOT be directly imported into host configurations **Example pattern** (from `modules/llm.nix`): ```nix { imports = [ ./dev.nix # System-level dependency inputs.home-manager.nixosModules.home-manager ]; home-manager.users.christian = { imports = [ ./home/llm.nix ]; # User-level module }; } ``` ### Host Configuration Structure Each host imports: - `hardware-configuration.nix` (auto-generated, do not edit manually) - `modules/common.nix` (base system configuration) - Additional feature modules as needed (`modules/dev.nix`, `modules/llm.nix`) **Desktop** (`hosts/desktop/configuration.nix`): - Imports: `common.nix`, `llm.nix` - AMD GPU configuration for ROCm/Ollama - Wireless via iwd - ROCm acceleration for local LLMs with RX 6800 GPU **Laptop** (`hosts/laptop/configuration.nix`): - Imports: `common.nix`, `dev.nix`, `re.nix` - Laptop-specific: backlight control (`programs.light`), battery alias - Wireless via iwd - keyd for capslock → ctrl/esc overlay **Hyper-V** (`hosts/hyper-v/configuration.nix`): - Minimal configuration for virtual machine ### Common Base Configuration `modules/common.nix` provides: - home-manager integration with global packages and backup handling - XMonad window manager with xmobar - Core packages: git, wget, alacritty, dmenu, mosh - Docker virtualization - nix-index-database with comma tool - User "christian" with wheel, video, render, docker groups ### User Home Configuration `modules/home/christian.nix` (imported by common.nix): - Neovim configuration via `./nvim` - Custom dmenu with config override - Alacritty terminal (font size 8) - Git configuration (Christian, thechristiansoltermann@gmail.com) - direnv with nix-direnv integration - Firefox with uBlock Origin extension - xmobar configuration ### Feature Modules **dev.nix** (system + user): - Enables `nix-ld` for running non-NixOS binaries - User modules: VSCode with FHS environment, Claude Code, uv Python package manager - Adds `~/.local/bin` to PATH **llm.nix** (system + user): - Extends dev.nix (inherits all dev features) - User module adds Continue VSCode extension with Ollama proxy config - Desktop host configures Ollama service with ROCm acceleration **re.nix** (system + user): - Extends dev.nix (inherits all dev features) - User module (`modules/home/re.nix`) provides reverse engineering tools: binaryninja-free, avalonia-ilspy, imhex, ghidra (via `modules/home/ghidra.nix`) - `ghidra.nix` wraps Ghidra to launch in PyGhidra mode using the bundled pyghidra wheel - Used by: laptop ## Special Configurations ### AMD ROCm for Local LLMs (Desktop Only) The desktop uses unstable nixpkgs for Ollama with specific ROCm configuration for the RX 6800 GPU: - `rocmOverrideGfx = "10.3.0"` for RDNA 2 architecture - Environment variables to target discrete GPU only (`HIP_VISIBLE_DEVICES = "0"`) - `HSA_ENABLE_SDMA = "0"` for stability with large models (26B+) ### Window Manager (XMonad) XMonad configuration is in `modules/xmonad.hs`: - Mod key: Alt (mod1Mask) - Layouts: Tall, Mirror Tall, Full (all avoiding xmobar struts) - Focused border: #4eb4fa - Restart binding: Mod+Q - Status bar: xmobar via `mySB` integration ### Unstable Packages Desktop uses a separate unstable pkgs overlay for newer packages (currently Ollama): ```nix let unstable = import inputs.nixpkgs-unstable { system = "x86_64-linux"; config.allowUnfree = true; config.rocmSupport = true; }; in ``` ## Flake Inputs - `nixpkgs`: NixOS 25.11 stable - `nixpkgs-unstable`: Rolling release for bleeding-edge packages - `home-manager`: Release 25.11, follows nixpkgs - `nix-index-database`: For command-not-found functionality - `nur`: Nix User Repository (used for Firefox extensions) ## Important Conventions 1. **Always use the two-layer pattern** when creating new feature modules 2. **System-level modules** import home-manager and specify user imports 3. **User-level modules** contain pure home-manager configuration 4. **Hardware configuration files** are auto-generated - do not manually edit 5. **Use unstable overlay** when you need bleeding-edge versions of specific packages 6. **Verify changes** with `nix build` (see above) before committing 7. **Format code** with nixfmt before committing 7. **Commit messages** should be a single short sentence — no body, no bullet points, no co-author line