Files
millerson-overlay.nix/AGENTS.md
Alexander Miroshnichenko 69a34cb819 Add skillsmcp MCP server package
Update documentation in README.md and AGENTS.md
Refresh flake.lock for nixpkgs and flake-parts
Disable fastmcp checks to avoid version conflicts
2026-05-06 10:15:17 +03:00

279 lines
7.6 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
1. Don't assume. Don't hide confusion. Surface tradeoffs.
2. Minimum code that solves the problem. Nothing speculative.
3. Touch only what you must. Clean up only your own mess.
4. Define success criteria. Loop until verified.
### 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"
```