Files
nixos-config/AGENTS.md
2026-03-05 15:45:08 +00:00

153 lines
4.2 KiB
Markdown

# AGENTS.md
## Build Commands
### Local Development
```bash
nix run .#build # Build current host config
nix run .#build -- <hostname> # Build specific host (chidi, jason, michael, tahani)
nix run .#apply # Build and apply locally (darwin-rebuild/nixos-rebuild switch)
nix flake check # Validate flake
```
### Remote Deployment (NixOS only)
```bash
nix run .#deploy # Deploy to all NixOS hosts
nix run .#deploy -- .#michael # Deploy to specific NixOS host
nix run .#deploy -- .#tahani # Deploy to specific NixOS host
```
When you're on tahani and asked to apply, that means running `nix run .#deploy`.
### Formatting
```bash
alejandra . # Format all Nix files
```
## Code Style
### Formatter
- **Tool**: Alejandra
- **Config**: `alejandra.toml` specifies tabs for indentation
- **Command**: Run `alejandra .` before committing
### File Structure
- **Modules**: `modules/` - All configuration (flake-parts modules, auto-imported by import-tree)
- `_lib/` - Utility functions (underscore = ignored by import-tree)
- `_darwin/` - Darwin-specific sub-modules
- `_neovim/` - Neovim plugin configs
- `_opencode/` - OpenCode agent/command/skill configs
- `_hosts/` - Host-specific sub-files (disk-config, hardware, etc.)
- **Apps**: `apps/` - Per-system app scripts (Nushell)
- **Secrets**: `secrets/` - SOPS-encrypted secrets (`.sops.yaml` for config)
### Architecture
**Framework**: den (vic/den) — every .nix file in `modules/` is a flake-parts module
**Pattern**: Feature/aspect-centric, not host-centric
**Aspects**: `den.aspects.<name>.<class>` where class is:
- `nixos` - NixOS-only configuration
- `darwin` - macOS-only configuration
- `homeManager` - Home Manager configuration
- `os` - Applies to both NixOS and darwin
**Hosts**: `den.hosts.<system>.<name>` defined in `modules/hosts.nix`
**Defaults**: `den.default.*` defined in `modules/defaults.nix`
**Imports**: Auto-imported by import-tree; underscore-prefixed dirs (`_lib/`, `_darwin/`, etc.) are excluded from auto-import
**Deployment**: deploy-rs for NixOS hosts (michael, tahani); darwin hosts (chidi, jason) are local-only
### Nix Language Conventions
**Function Arguments**:
```nix
{inputs, pkgs, lib, ...}:
```
Destructure arguments on separate lines. Use `...` to capture remaining args.
**Attribute Sets**:
```nix
den.aspects.myfeature.os = {
enable = true;
config = "value";
};
```
One attribute per line with trailing semicolons.
**Lists with Packages**:
```nix
with pkgs;
[
age
alejandra
ast-grep
]
```
Use `with pkgs;` for package lists, one item per line.
**Aspect Definition**:
```nix
{
config,
lib,
pkgs,
...
}:
with lib; let
cfg = config.den.aspects.myfeature;
in {
options.den.aspects.myfeature = {
enable = mkEnableOption "Feature description";
};
config = mkIf cfg.enable {
# configuration
};
}
```
- Destructure args on separate lines
- Use `with lib;` for brevity with NixOS lib functions
- Define `cfg` for config options
- Use `mkIf`, `mkForce`, `mkDefault` appropriately
**Conditional Platform-Specific Code**:
```nix
++ lib.optionals stdenv.isDarwin [
_1password-gui
dockutil
]
++ lib.optionals stdenv.isLinux [
lm_sensors
]
```
### Naming Conventions
- **Aspect names**: `den.aspects.<name>.<class>` for feature configuration
- **Hostnames**: Lowercase, descriptive (e.g., `michael`, `tahani`, `chidi`, `jason`)
- **Module files**: Descriptive, lowercase with hyphens (e.g., `neovim-config.nix`)
### Secrets Management
- Use SOPS for secrets (see `.sops.yaml`)
- Never commit unencrypted secrets
- Secret definitions live in per-host modules (`modules/michael.nix`, `modules/tahani.nix`, etc.)
- Shared SOPS defaults (module imports, key paths) in `modules/secrets.nix`
### Aspect Composition
Use `den.aspects.<name>.includes` to compose aspects:
```nix
den.aspects.myfeature.includes = [
"other-aspect"
"another-aspect"
];
```
### Key Conventions
- No `specialArgs` — den batteries handle input passing
- No hostname string comparisons in shared aspects
- Host-specific config goes in `den.aspects.<hostname>.*`
- Shared config uses `os` class (applies to both NixOS and darwin)
- Non-module files go in `_`-prefixed subdirs