Files
my-pkgs/AGENTS.md

5.4 KiB

AGENTS.md

Guide for AI coding agents working in this repository.

Project Overview

This is a pure Nix flake project that exposes custom Nix packages, a development shell, checks, and a nixpkgs overlay. All source files are written in the Nix expression language (.nix files). There is no traditional programming language involved -- this is purely Nix infrastructure/packaging code.

Repository Structure

flake.nix              # Main flake entry point (inputs, outputs, nixConfig)
flake.lock             # Pinned flake dependency versions
.envrc                 # direnv integration ("use flake")
.gitignore             # Ignores result, result-*, .direnv
pkgs/
  default.nix          # Package set aggregator (barrel file)
  example-a/default.nix
  example-b/default.nix
checks/
  default.nix          # Flake checks (formatting enforcement)
devshells/
  default.nix          # Development shell with tooling
overlays/
  default.nix          # Nixpkgs overlay re-exporting packages

Every directory uses default.nix as its entry point -- this is the Nix equivalent of index/barrel files. The top-level flake.nix imports each module via import ./pkgs, import ./checks, etc.

Build / Check / Format Commands

# Build the default package
nix build

# Build a specific package
nix build .#example-a
nix build .#example-b

# Run all flake checks (currently: formatting validation)
nix flake check

# Format all Nix files (MUST pass before committing)
nixfmt flake.nix pkgs checks devshells overlays

# Check formatting without modifying files
nixfmt --check flake.nix pkgs checks devshells overlays

# Enter the development shell (provides nixfmt, nil, nix-tree)
nix develop

# View the dependency tree of a package
nix-tree .#example-a

# Update flake inputs
nix flake update

Testing

There are no unit/integration tests. The only check is formatting validation via nix flake check, which runs nixfmt --check against all .nix files. Always run nix flake check before committing to ensure formatting is correct.

Code Style Guidelines

Formatter

nixfmt-rfc-style is enforced via nix flake check. Always format files with nixfmt before committing. The formatter is available in the dev shell.

Indentation and Whitespace

  • 2 spaces for indentation (no tabs)
  • Opening brace on the same line as context
  • Trailing semicolons on all attribute definitions

Naming Conventions

Entity Convention Examples
Files / directories kebab-case example-a, example-b
Entry point files default.nix Always default.nix per directory
Attributes/variables camelCase installPhase, buildInputs
Package names kebab-case example-a, nixfmt-rfc-style

Function Parameters

Always list parameters one per line with a trailing comma, enclosed in braces:

{
  lib,
  stdenv,
}:

Imports and Dependency Injection

  • Use relative path imports: import ./pkgs { inherit pkgs; }
  • Pass dependencies via function arguments (dependency injection), never globals
  • Use inherit to concisely forward bindings: { inherit pkgs system; }
  • Use pkgs.callPackage to auto-inject dependencies into package definitions

Package Definition Template

Every package follows this pattern:

{
  lib,
  stdenv,
}:
stdenv.mkDerivation {
  pname = "package-name";
  version = "0.1.0";
  src = ./.;

  installPhase = ''
    # build/install commands
  '';

  meta = {
    description = "Short description of the package";
    license = lib.licenses.mit;
    platforms = lib.platforms.all;
  };
}

Module / Barrel File Pattern

Aggregator files (pkgs/default.nix) collect sub-packages and define a default:

{ pkgs }:
let
  self = {
    example-a = pkgs.callPackage ./example-a { };
    example-b = pkgs.callPackage ./example-b { };
  };
in
self // { default = self.example-a; }

Overlay Pattern

Overlays use inherit to selectively re-export packages:

final: prev:
let
  customPkgs = import ../pkgs { pkgs = final; };
in
{
  inherit (customPkgs) example-a example-b;
}

Comments

  • Prefer self-documenting code via description attributes in meta blocks
  • Inline comments are used sparingly and only when the intent is non-obvious
  • No JSDoc or similar documentation patterns -- Nix is declarative

Error Handling

  • Nix is a purely functional language; errors are build-time evaluation failures
  • Use assert for preconditions when needed
  • Use lib.warn or lib.info for non-fatal diagnostics
  • Use builtins.throw for fatal errors with descriptive messages

Flake Outputs

Follow the standard flake output schema:

  • packages.<system>.<name> -- built packages
  • packages.<system>.default -- the default package
  • devShells.<system>.default -- development shell
  • checks.<system>.<name> -- CI checks
  • overlays.default -- nixpkgs overlay

The flake uses flake-utils.lib.eachDefaultSystem for multi-platform support.

Dev Environment

  • direnv auto-activates the dev shell (.envrc contains use flake)
  • nil (Nix LSP) is available in the dev shell for editor integration
  • nix-tree is available for inspecting dependency trees
  • Binary cache: nix-community.cachix.org is configured as an extra substituter