Files
dotfiles/AGENTS.md
servius 9607e8f3a4
Some checks failed
Flake checker / Build Nix targets (push) Has been cancelled
feat: Added agents.md
2026-02-01 18:30:57 +05:30

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 alejandra formatter (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 mkIf for config options
  • Use lib.optionalAttrs for attribute sets
  • Use lib.optionals for lists
  • Prefer inline if-then-else for 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

  1. NEVER create new markdown files unless explicitly requested
  2. DO NOT add helper scripts or shell scripts - use Nix expressions
  3. DO NOT add example snippets or sample code files
  4. All configurations must use Nix expressions when possible
  5. Follow existing naming conventions and directory structure
  6. 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

  1. Determine location: modules/nixos/, modules/darwin/, or modules/home/
  2. Create file with proper structure
  3. Add to modules/default.nix imports
  4. 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.isDarwin
  • device.isServer, device.hasGui
  • device.isDesktopLinux
  • device.name, device.user, device.home

Error Handling

  • Use mkIf to 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

  1. Build the configuration first: just build or nixos-rebuild build --flake .
  2. Check for errors with --show-trace flag
  3. Test on non-production systems first
  4. Use sudo nixos-rebuild test for temporary activation on Linux

Version Information

  • Nix Version: 2.32+
  • Flakes: Enabled (required)
  • Formatter: alejandra
  • State Version: 23.11+ (varies by machine)