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
274 lines
7.4 KiB
Markdown
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"
|
|
```
|