# AGENTS.md - Instructions for AI Agents This file provides guidance to AI agents (such as Claude, GPT, Goose, etc.) when working with this Nix overlay repository. ## Project Overview This is a **Nix flake overlay** repository that provides additional packages for Nix/NixOS users. It uses [numtide/blueprint](https://github.com/numtide/blueprint) as its foundation, which simplifies flake development by providing sensible defaults and automatic package discovery. **Repository URL**: `git+https://git.millerson.name/alex/millerson-overlay.nix.git` ## Key Concepts ### Blueprint Framework This project uses `numtide/blueprint` which: - Automatically discovers packages in the `packages/` directory - Provides `perSystem` outputs for multi-system builds - Handles formatting, checking, and devShell generation - Exposes `mkPackagesFor` function to build packages against any nixpkgs instance ### Two Overlay Strategies 1. **`overlays.default`** - Binary-cache-friendly - Uses packages built against this flake's nixpkgs revision - Better for binary cache hits when using the same nixpkgs 2. **`overlays.shared-nixpkgs`** - Dependency-sharing - Builds packages against the consumer's nixpkgs (`final`) - Shares dependencies with the rest of the system - No second nixpkgs evaluation - Trade-off: binary cache only hits when consumer's nixpkgs matches ours ## Repository Structure ``` nix-overlay/ ├── flake.nix # Main flake definition with inputs and outputs ├── overlays/ │ ├── default.nix # Overlay using pre-built packages (binary cache friendly) │ └── shared-nixpkgs.nix # Overlay building against consumer's nixpkgs ├── packages/ │ ├── default/ # Meta-package listing all visible packages │ │ ├── default.nix │ │ └── package.nix │ ├── goose-cli/ # Example package: Goose AI agent CLI │ │ ├── default.nix │ │ ├── package.nix # Main package definition │ │ ├── fetchers.nix # Custom fetchers (if needed) │ │ ├── librusty_v8.nix # V8 library pre-built binary │ │ └── update.py # Update script for version bumps │ └── flake-inputs/ # Utility to cache all flake inputs │ └── default.nix ├── README.md # User-facing documentation ├── AGENTS.md # This file - AI agent instructions ├── LICENSE └── flake.lock ``` ## Package Definition Pattern ### Standard Package Structure Each package should follow this structure: ``` packages// ├── default.nix # Wrapper that receives blueprint args (pkgs, perSystem, etc.) └── package.nix # Actual package definition using pkgs.callPackage pattern ``` ### `default.nix` Pattern ```nix { pkgs, perSystem, ... }: pkgs.callPackage ./package.nix { # Pass any extra arguments here } ``` ### `package.nix` Pattern ```nix { lib, stdenv, # ... package-specific dependencies }: stdenv.mkDerivation rec { pname = "my-package"; version = "1.0.0"; src = fetchFromGitHub { owner = "user"; repo = "repo"; rev = "v${version}"; hash = "sha256-..."; }; # ... build instructions meta = with lib; { description = "Brief description"; homepage = "https://..."; license = licenses.mit; maintainers = with maintainers; [ ]; platforms = platforms.all; mainProgram = "program-name"; }; } ``` ### Rust Packages For Rust packages, use `rustPlatform.buildRustPackage`: ```nix { lib, rustPlatform, fetchFromGitHub, ... }: rustPlatform.buildRustPackage rec { pname = "my-rust-app"; version = "1.0.0"; src = fetchFromGitHub { ... }; cargoHash = "sha256-..."; # ... build instructions meta = { ... }; } ``` ## Adding a New Package When adding a new package: 1. **Create the directory**: `mkdir -p packages/` 2. **Create `package.nix`** with the actual derivation 3. **Create `default.nix`** as a wrapper: ```nix { pkgs, ... }: pkgs.callPackage ./package.nix { } ``` 4. **Test the package**: ```bash nix build .# nix run .# ``` 5. **Update README.md** to document the new package in the Available Packages table 6. **Set appropriate metadata**: - `meta.description` - Required, shown in package listings - `meta.mainProgram` - Set for packages providing a CLI executable - `meta.passthru.category` - Optional, used for organization (e.g., "AI Coding Agents") - `meta.passthru.hideFromDocs` - Set to `true` to exclude from documentation ## Common Tasks ### Updating a Package Version 1. Update `version` in `package.nix` 2. Update `src.hash` (use `nix-prefetch-github` or let Nix tell you the correct hash) 3. Update `cargoHash` for Rust packages (build will fail and tell you the correct hash) 4. Test: `nix build .#` 5. Update README if needed ### Testing Changes ```bash # Build specific package nix build .#goose-cli # Build all packages for current system nix build .#packages # Enter dev shell nix develop # Check formatting nix flake check ``` ### Working with Overlays When modifying overlay behavior: - **`overlays/default.nix`**: Receives `packages` from blueprint outputs, maps them to `final.stdenv.hostPlatform.system` - **`overlays/shared-nixpkgs.nix`**: Receives `mkPackagesFor`, uses it to build against consumer's `final` ## Important Notes ### Do's - ✅ Use `pkgs.callPackage` pattern for package definitions - ✅ Set proper `meta` attributes (description, license, homepage) - ✅ Test packages with `nix build` before committing - ✅ Use `passthru.category` for organizational grouping - ✅ Follow Nixpkgs conventions for package naming and structure ### Don'ts - ❌ Don't modify `flake.lock` manually - use `nix flake update` - ❌ Don't hardcode system-specific paths or assumptions - ❌ Don't forget to set `meta.mainProgram` for CLI tools - ❌ Don't use `with pkgs;` at top level (can cause scope issues) - ❌ Don't commit packages that don't build ## Debugging Tips ### Package Doesn't Build 1. Check the error message carefully 2. Verify all dependencies are listed 3. Check if the source hash is correct 4. For Rust packages, verify `cargoHash` matches ### Overlay Not Working 1. Verify the overlay is correctly imported 2. Check if the package exists in `packages` output 3. For `shared-nixpkgs`, ensure `mkPackagesFor` is available ### Binary Cache Issues - The `default` overlay is more likely to get cache hits - The `shared-nixpkgs` overlay builds from source unless nixpkgs revisions match ## Resources - [Nixpkgs Manual](https://nixos.org/manual/nixpkgs/stable/) - [Blueprint Documentation](https://github.com/numtide/blueprint) - [Nix Flake Patterns](https://github.com/NixOS/flake-patterns) - [Rust in Nixpkgs](https://nixos.org/manual/nixpkgs/stable/#rust) ## Example Workflow: Adding a New Package ```bash # 1. Create package directory mkdir -p packages/my-tool # 2. Create package.nix (use appropriate template above) # 3. Create default.nix wrapper cat > packages/my-tool/default.nix << 'EOF' { pkgs, ... }: pkgs.callPackage ./package.nix { } EOF # 4. Test build nix build .#my-tool # 5. If build fails, fix issues, then retry # 6. Update README.md with new package info # 7. Commit changes git add packages/my-tool README.md git commit -m "Add my-tool package" ```