feat: Update AGENTS.md
Some checks failed
Flake checker / Build Nix targets (push) Has been cancelled
Some checks failed
Flake checker / Build Nix targets (push) Has been cancelled
This commit is contained in:
241
AGENTS.md
241
AGENTS.md
@@ -1,50 +1,33 @@
|
|||||||
# Agent Guidelines for NixOS/nix-darwin Dotfiles
|
# 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.
|
This repository contains NixOS, nix-darwin, and Home Manager configurations in Nix. You are a sysadmin managing server configurations and deployments.
|
||||||
|
|
||||||
## Identity
|
|
||||||
|
|
||||||
You are a sysadmin that manages server configurations and deployments in NixOS/nix-darwin using the Nix language.
|
|
||||||
|
|
||||||
## Build, Test, and Deployment Commands
|
## Build, Test, and Deployment Commands
|
||||||
|
|
||||||
### Building Configurations
|
### Build and Apply Configurations
|
||||||
|
|
||||||
**Linux (NixOS):**
|
**Linux (NixOS):**
|
||||||
```bash
|
```bash
|
||||||
# Build configuration
|
just build # Build configuration
|
||||||
nixos-rebuild build --flake . --show-trace
|
just install cores='32' # Apply with 32 cores
|
||||||
just build
|
sudo nixos-rebuild test --fast --flake . # Test without activation
|
||||||
|
sudo nixos-rebuild switch --rollback --flake . # Rollback
|
||||||
# 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):**
|
**macOS (nix-darwin):**
|
||||||
```bash
|
```bash
|
||||||
# Build configuration
|
just build # Build configuration
|
||||||
nix run nix-darwin -- build --flake . --show-trace
|
just install # Apply configuration
|
||||||
just build
|
|
||||||
|
|
||||||
# Apply configuration
|
|
||||||
nix run nix-darwin -- switch --flake .
|
|
||||||
just install
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Home Manager:**
|
**Home Manager:**
|
||||||
```bash
|
```bash
|
||||||
nix --extra-experimental-features "nix-command flakes" run home-manager/master -- switch --flake . --show-trace
|
|
||||||
just home
|
just home
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deployment to Remote Machines
|
### Deploy to Remote Machines (deploy-rs)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Deploy to specific machine (uses deploy-rs)
|
|
||||||
deploy -s .#ryu # Desktop (x86_64-linux)
|
deploy -s .#ryu # Desktop (x86_64-linux)
|
||||||
deploy -s .#tako # Server (x86_64-linux)
|
deploy -s .#tako # Server (x86_64-linux)
|
||||||
deploy -s .#tsuba # Raspberry Pi (aarch64-linux)
|
deploy -s .#tsuba # Raspberry Pi (aarch64-linux)
|
||||||
@@ -52,64 +35,23 @@ deploy -s .#kuro # MacBook M4 Pro (aarch64-darwin)
|
|||||||
deploy -s .#shiro # Mac Mini M4 (aarch64-darwin)
|
deploy -s .#shiro # Mac Mini M4 (aarch64-darwin)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Validation and Checking
|
### Validation and Formatting
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Check flake for errors
|
nix flake check --show-trace # Check flake for errors
|
||||||
nix flake check
|
alejandra fmt . # Format all files
|
||||||
|
alejandra fmt <file>.nix # Format single file
|
||||||
# Check deployment configuration
|
|
||||||
nix flake check --show-trace
|
|
||||||
|
|
||||||
# Validate specific output
|
|
||||||
nix eval .#nixosConfigurations.ryu.config.system.build.toplevel
|
|
||||||
```
|
|
||||||
|
|
||||||
### Formatting
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Format Nix files with alejandra
|
|
||||||
alejandra fmt <file>.nix
|
|
||||||
|
|
||||||
# Format all files in directory
|
|
||||||
alejandra fmt .
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Directory Structure
|
## Directory Structure
|
||||||
|
|
||||||
```
|
- `flake.nix` - Main entry point, device definitions
|
||||||
.
|
- `nixos/` - NixOS machine configs (ryu, tako, tsuba)
|
||||||
├── flake.nix # Main flake entry point
|
- `darwin/` - macOS machine configs (kuro, shiro)
|
||||||
├── overlays.nix # Package overlays
|
- `home/` - Home Manager modules (programs/, services/, apps/)
|
||||||
├── deploy.nix # deploy-rs configuration
|
- `modules/` - Custom modules (nixos/, darwin/, home/)
|
||||||
├── sops.nix # Secrets management
|
- `secrets/` - SOPS encrypted secrets
|
||||||
├── stylix.nix # Styling configuration
|
- `overlays.nix`, `deploy.nix`, `sops.nix`, `stylix.nix` - Config files
|
||||||
├── 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
|
## Code Style Guidelines
|
||||||
|
|
||||||
@@ -117,88 +59,41 @@ alejandra fmt .
|
|||||||
|
|
||||||
**File Structure:**
|
**File Structure:**
|
||||||
```nix
|
```nix
|
||||||
{
|
{inputs, config, pkgs, lib, device, ...}: {
|
||||||
inputs,
|
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
device,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
# Configuration here
|
# Configuration here
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Imports:**
|
**Imports:**
|
||||||
- List all parameter imports at the top
|
|
||||||
- Order: `inputs`, `config`, `pkgs`, `lib`, `device`, custom params, `...`
|
- Order: `inputs`, `config`, `pkgs`, `lib`, `device`, custom params, `...`
|
||||||
- Use set destructuring for clarity
|
- Use set destructuring for clarity
|
||||||
|
|
||||||
**Formatting:**
|
**Formatting:**
|
||||||
- Use `alejandra` formatter (maintained in the repo)
|
- Use `alejandra` formatter (run before committing)
|
||||||
- 2-space indentation
|
- 2-space indentation
|
||||||
- Keep lines under 100 characters when reasonable
|
- Trailing commas in lists and attribute sets
|
||||||
- Use trailing commas in lists and attribute sets
|
|
||||||
|
|
||||||
**Naming Conventions:**
|
**Naming Conventions:**
|
||||||
- Files: lowercase with hyphens (e.g., `my-module.nix`)
|
- Files: lowercase-with-hyphens (e.g., `my-module.nix`)
|
||||||
- Attributes: camelCase (e.g., `enableMyFeature`)
|
- Attributes: camelCase (e.g., `enableMyFeature`)
|
||||||
- Functions: camelCase (e.g., `mkDevice`)
|
- Functions: camelCase (e.g., `mkDevice`)
|
||||||
- Constants: UPPER_SNAKE_CASE (e.g., `API_KEY`)
|
- Constants: UPPER_SNAKE_CASE (e.g., `API_KEY`)
|
||||||
- Device names: lowercase (e.g., `ryu`, `tako`, `kuro`)
|
- Device names: lowercase (e.g., `ryu`, `tako`)
|
||||||
|
|
||||||
**Let Expressions:**
|
**Let Expressions:**
|
||||||
```nix
|
```nix
|
||||||
with lib; let
|
with lib; let
|
||||||
cfg = config.programs.myProgram;
|
cfg = config.programs.myProgram;
|
||||||
myHelper = x: y: x + y;
|
|
||||||
in {
|
in {
|
||||||
options = { ... };
|
options = { ... };
|
||||||
config = mkIf cfg.enable { ... };
|
config = mkIf cfg.enable { ... };
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Options:**
|
|
||||||
```nix
|
|
||||||
options = {
|
|
||||||
programs.myProgram = {
|
|
||||||
enable = mkEnableOption "my program";
|
|
||||||
package = mkPackageOption pkgs "myProgram" {};
|
|
||||||
|
|
||||||
settings = mkOption {
|
|
||||||
type = types.attrs;
|
|
||||||
default = {};
|
|
||||||
description = "Configuration settings";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
**Conditionals:**
|
**Conditionals:**
|
||||||
- Use `mkIf` for config options
|
- Use `mkIf` for config options
|
||||||
- Use `lib.optionalAttrs` for attribute sets
|
- Use `lib.optionalAttrs` for attribute sets
|
||||||
- Use `lib.optionals` for lists
|
- Use `lib.optionals` for lists
|
||||||
- Prefer inline `if-then-else` for simple expressions
|
|
||||||
|
|
||||||
**String Interpolation:**
|
|
||||||
```nix
|
|
||||||
# Good
|
|
||||||
"${pkgs.package}/bin/command"
|
|
||||||
"${config.home.homeDirectory}/.config"
|
|
||||||
|
|
||||||
# Avoid unnecessary interpolation
|
|
||||||
"simple string" # not "${''simple string''}"
|
|
||||||
```
|
|
||||||
|
|
||||||
**Comments:**
|
|
||||||
```nix
|
|
||||||
# Single-line comments for brief explanations
|
|
||||||
# Use above the line being explained
|
|
||||||
|
|
||||||
/* Multi-line comments
|
|
||||||
for longer explanations
|
|
||||||
or documentation blocks */
|
|
||||||
```
|
|
||||||
|
|
||||||
### Module Patterns
|
### Module Patterns
|
||||||
|
|
||||||
@@ -211,72 +106,40 @@ options = {
|
|||||||
|
|
||||||
**Program Configuration Module:**
|
**Program Configuration Module:**
|
||||||
```nix
|
```nix
|
||||||
{
|
{config, pkgs, lib, ...}:
|
||||||
config,
|
|
||||||
pkgs,
|
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
with lib; let
|
with lib; let
|
||||||
cfg = config.programs.myProgram;
|
cfg = config.programs.myProgram;
|
||||||
in {
|
in {
|
||||||
options.programs.myProgram = {
|
options.programs.myProgram = {
|
||||||
enable = mkEnableOption "myProgram";
|
enable = mkEnableOption "myProgram";
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf cfg.enable {
|
config = mkIf cfg.enable {
|
||||||
home.packages = [pkgs.myProgram];
|
home.packages = [pkgs.myProgram];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Service Module:**
|
**Device-Specific Logic:**
|
||||||
```nix
|
```nix
|
||||||
{
|
home.packages = lib.optionals device.isLinux [pkgs.linuxPackage]
|
||||||
config,
|
++ lib.optionals device.isDarwin [pkgs.macPackage];
|
||||||
lib,
|
|
||||||
...
|
|
||||||
}: {
|
|
||||||
services.myService = {
|
|
||||||
enable = true;
|
|
||||||
settings = {
|
|
||||||
# Configuration here
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Device-Specific Logic
|
sessionVariables.BROWSER = if device.isDarwin then "open" else "xdg-open";
|
||||||
|
|
||||||
```nix
|
|
||||||
# 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
|
## Important Rules
|
||||||
|
|
||||||
1. **NEVER create new markdown files** unless explicitly requested
|
1. **NEVER create markdown files** unless explicitly requested
|
||||||
2. **DO NOT add helper scripts or shell scripts** - use Nix expressions
|
2. **DO NOT add shell scripts** - use Nix expressions
|
||||||
3. **DO NOT add example snippets or sample code files**
|
3. **All configurations must use Nix expressions** when possible
|
||||||
4. **All configurations must use Nix expressions** when possible
|
4. **Follow existing naming conventions** and directory structure
|
||||||
5. **Follow existing naming conventions** and directory structure
|
|
||||||
6. **Ensure new files match the structure** of existing similar files
|
|
||||||
|
|
||||||
## Secrets Management
|
## Secrets Management
|
||||||
|
|
||||||
- Secrets are managed with SOPS (Secrets OPerationS)
|
- Secrets are managed with SOPS in `secrets/` directory
|
||||||
- Encrypted secrets in `secrets/` directory
|
- Encrypted secrets in `secrets/` directory
|
||||||
- Configuration in `.sops.yaml`
|
- Configuration in `.sops.yaml`
|
||||||
- Access secrets via `config.sops.secrets."secret/value".path` which corresponds to following in yaml.
|
- Access via `config.sops.secrets."secret/value".path`
|
||||||
```yaml
|
```yaml
|
||||||
foo:
|
foo:
|
||||||
bar: somesecret
|
bar: somesecret
|
||||||
@@ -295,10 +158,7 @@ sessionVariables = {
|
|||||||
### Adding a New Program
|
### Adding a New Program
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Use the justfile recipe
|
just add program myprogram # Creates home/programs/myprogram.nix and adds import
|
||||||
just add program myprogram
|
|
||||||
|
|
||||||
# This creates home/programs/myprogram.nix and adds import
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Creating a Module
|
### Creating a Module
|
||||||
@@ -306,44 +166,27 @@ just add program myprogram
|
|||||||
1. Determine location: `modules/nixos/`, `modules/darwin/`, or `modules/home/`
|
1. Determine location: `modules/nixos/`, `modules/darwin/`, or `modules/home/`
|
||||||
2. Create file with proper structure
|
2. Create file with proper structure
|
||||||
3. Add to `modules/default.nix` imports
|
3. Add to `modules/default.nix` imports
|
||||||
4. Use the module in appropriate device configuration
|
|
||||||
|
|
||||||
### Device Configuration
|
### Device Configuration
|
||||||
|
|
||||||
Devices are defined in `flake.nix` using `mkDevice`:
|
Devices are defined in `flake.nix` using `mkDevice`. Properties available:
|
||||||
```nix
|
- `device.isLinux`, `device.isDarwin`, `device.isArm`
|
||||||
ryu = mkDevice {
|
- `device.isServer`, `device.hasGui`, `device.isDesktopLinux`
|
||||||
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`
|
- `device.name`, `device.user`, `device.home`
|
||||||
|
|
||||||
## Error Handling
|
## Error Handling
|
||||||
|
|
||||||
- Use `mkIf` to conditionally enable configurations
|
- 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
|
- Handle both Linux and macOS cases when adding cross-platform features
|
||||||
|
|
||||||
## Testing Changes
|
## Testing Changes
|
||||||
|
|
||||||
1. Build the configuration first: `just build` or `nixos-rebuild build --flake .`
|
1. Build first: `just build` or `nixos-rebuild build --flake .`
|
||||||
2. Check for errors with `--show-trace` flag
|
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
|
## Version Information
|
||||||
|
|
||||||
- Nix Version: 2.32+
|
- Nix Version: 2.32+
|
||||||
- Flakes: Enabled (required)
|
- Flakes: Enabled (required)
|
||||||
- Formatter: alejandra
|
- Formatter: alejandra
|
||||||
- State Version: 23.11+ (varies by machine)
|
- State Version: (varies by machine & never change this)
|
||||||
|
|||||||
Reference in New Issue
Block a user