8.2 KiB
8.2 KiB
Agent Guidelines for NixOS/nix-darwin Dotfiles
This repository contains NixOS, nix-darwin, and Home Manager configurations written in the Nix language. This document provides essential information for AI coding agents working in this codebase.
Identity
You are a sysadmin that manages server configurations and deployments in NixOS/nix-darwin using the Nix language.
Build, Test, and Deployment Commands
Building Configurations
Linux (NixOS):
# Build configuration
nixos-rebuild build --flake . --show-trace
just build
# Apply configuration
sudo nixos-rebuild switch --flake . --builders '' --max-jobs 1 --cores 32
just install cores='32'
# Test configuration (no activation)
sudo nixos-rebuild test --fast --flake .
macOS (nix-darwin):
# Build configuration
nix run nix-darwin -- build --flake . --show-trace
just build
# Apply configuration
nix run nix-darwin -- switch --flake .
just install
Home Manager:
nix --extra-experimental-features "nix-command flakes" run home-manager/master -- switch --flake . --show-trace
just home
Deployment to Remote Machines
# Deploy to specific machine (uses deploy-rs)
deploy -s .#ryu # Desktop (x86_64-linux)
deploy -s .#tako # Server (x86_64-linux)
deploy -s .#tsuba # Raspberry Pi (aarch64-linux)
deploy -s .#kuro # MacBook M4 Pro (aarch64-darwin)
deploy -s .#shiro # Mac Mini M4 (aarch64-darwin)
Validation and Checking
# Check flake for errors
nix flake check
# Check deployment configuration
nix flake check --show-trace
# Validate specific output
nix eval .#nixosConfigurations.ryu.config.system.build.toplevel
Formatting
# Format Nix files with alejandra
alejandra fmt <file>.nix
# Format all files in directory
alejandra fmt .
Directory Structure
.
├── flake.nix # Main flake entry point
├── overlays.nix # Package overlays
├── deploy.nix # deploy-rs configuration
├── sops.nix # Secrets management
├── stylix.nix # Styling configuration
├── nixos/ # NixOS configurations
│ ├── default.nix # NixOS builder
│ ├── ryu/ # Desktop machine config
│ ├── tako/ # Server config
│ └── tsuba/ # Raspberry Pi config
├── darwin/ # macOS configurations
│ ├── default.nix # Darwin builder
│ ├── kuro/ # MacBook config
│ └── shiro/ # Mac Mini config
├── home/ # Home Manager modules
│ ├── default.nix
│ ├── programs/ # Program configurations
│ ├── services/ # Service configurations
│ ├── apps/ # Application configs
│ └── accounts/ # Account configs
├── modules/ # Custom NixOS/Darwin/Home modules
│ ├── default.nix
│ ├── nixos/ # NixOS-specific modules
│ ├── darwin/ # Darwin-specific modules
│ └── home/ # Home Manager modules
├── builders/ # Machine builder definitions
├── packages/ # Custom packages
├── scripts/ # Helper scripts
├── secrets/ # SOPS secrets (encrypted)
└── patches/ # Package patches
Code Style Guidelines
Nix Language Conventions
File Structure:
{
inputs,
config,
pkgs,
lib,
device,
...
}: {
# Configuration here
}
Imports:
- List all parameter imports at the top
- Order:
inputs,config,pkgs,lib,device, custom params,... - Use set destructuring for clarity
Formatting:
- Use
alejandraformatter (maintained in the repo) - 2-space indentation
- Keep lines under 100 characters when reasonable
- Use trailing commas in lists and attribute sets
Naming Conventions:
- Files: lowercase with hyphens (e.g.,
my-module.nix) - Attributes: camelCase (e.g.,
enableMyFeature) - Functions: camelCase (e.g.,
mkDevice) - Constants: UPPER_SNAKE_CASE (e.g.,
API_KEY) - Device names: lowercase (e.g.,
ryu,tako,kuro)
Let Expressions:
with lib; let
cfg = config.programs.myProgram;
myHelper = x: y: x + y;
in {
options = { ... };
config = mkIf cfg.enable { ... };
}
Options:
options = {
programs.myProgram = {
enable = mkEnableOption "my program";
package = mkPackageOption pkgs "myProgram" {};
settings = mkOption {
type = types.attrs;
default = {};
description = "Configuration settings";
};
};
};
Conditionals:
- Use
mkIffor config options - Use
lib.optionalAttrsfor attribute sets - Use
lib.optionalsfor lists - Prefer inline
if-then-elsefor simple expressions
String Interpolation:
# Good
"${pkgs.package}/bin/command"
"${config.home.homeDirectory}/.config"
# Avoid unnecessary interpolation
"simple string" # not "${''simple string''}"
Comments:
# Single-line comments for brief explanations
# Use above the line being explained
/* Multi-line comments
for longer explanations
or documentation blocks */
Module Patterns
Simple Package Module:
{pkgs, ...}: {
home.packages = [pkgs.myPackage];
}
Program Configuration Module:
{
config,
pkgs,
lib,
...
}:
with lib; let
cfg = config.programs.myProgram;
in {
options.programs.myProgram = {
enable = mkEnableOption "myProgram";
};
config = mkIf cfg.enable {
home.packages = [pkgs.myProgram];
};
}
Service Module:
{
config,
lib,
...
}: {
services.myService = {
enable = true;
settings = {
# Configuration here
};
};
}
Device-Specific Logic
# Check device properties
home.packages = lib.optionals device.isLinux [
pkgs.linuxPackage
] ++ lib.optionals device.isDarwin [
pkgs.macPackage
];
# Or use conditionals
sessionVariables = {
BROWSER = if device.isDarwin then "open" else "xdg-open";
};
Important Rules
- NEVER create new markdown files unless explicitly requested
- DO NOT add helper scripts or shell scripts - use Nix expressions
- DO NOT add example snippets or sample code files
- All configurations must use Nix expressions when possible
- Follow existing naming conventions and directory structure
- Ensure new files match the structure of existing similar files
Secrets Management
- Secrets are managed with SOPS (Secrets OPerationS)
- Encrypted secrets in
secrets/directory - Configuration in
.sops.yaml - Access secrets via
config.sops.secrets."path/to/secret".path
Common Patterns
Adding a New Program
# Use the justfile recipe
just add program myprogram
# This creates home/programs/myprogram.nix and adds import
Creating a Module
- Determine location:
modules/nixos/,modules/darwin/, ormodules/home/ - Create file with proper structure
- Add to
modules/default.niximports - Use the module in appropriate device configuration
Device Configuration
Devices are defined in flake.nix using mkDevice:
ryu = mkDevice {
name = "ryu";
system = "x86_64-linux";
user = "servius";
isNix = true;
monitors = { ... };
};
Properties available:
device.isLinux,device.isDarwindevice.isServer,device.hasGuidevice.isDesktopLinuxdevice.name,device.user,device.home
Error Handling
- Use
mkIfto conditionally enable configurations - Check for required options before using them
- Validate paths and files exist when referencing external resources
- Handle both Linux and macOS cases when adding cross-platform features
Testing Changes
- Build the configuration first:
just buildornixos-rebuild build --flake . - Check for errors with
--show-traceflag - Test on non-production systems first
- Use
sudo nixos-rebuild testfor temporary activation on Linux
Version Information
- Nix Version: 2.32+
- Flakes: Enabled (required)
- Formatter: alejandra
- State Version: 23.11+ (varies by machine)