Files
millerson-overlay.nix/AGENTS.md
Alexander Miroshnichenko fb5db6e302 Initialize Nix overlay repository with blueprint, goose-cli, and docs
Add the complete overlay structure using numtide/blueprint with:
- Two overlay strategies (default and shared-nixpkgs)
- goose-cli package with custom librusty_v8 fetcher
- Interactive package launcher via fzf
- Flake input caching utility
- Comprehensive README and AGENTS.md documentation
2026-04-29 16:04:58 +03:00

274 lines
7.4 KiB
Markdown

# 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/<package-name>/
├── 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/<package-name>`
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 .#<package-name>
nix run .#<package-name>
```
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 .#<package-name>`
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"
```