388 lines
12 KiB
Markdown
388 lines
12 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.
|
|
|
|
### Required Skills
|
|
|
|
Always use these skills when working with this repository:
|
|
- **nix** - For nixpkgs package lookups, option searches, and NixOS/Home Manager queries
|
|
- **nix-flakes** - For reproducible builds, flake management, and devShell operations
|
|
- **karpathy-guidelines** - For high-quality task execution best practices
|
|
|
|
### 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
|
|
|
|
**Important**: Blueprint's package discovery reads from the git index, not the working directory. New package directories must be staged with `git add` before they appear in flake outputs. Unstaged files are invisible to `nix build`, `nix flake show`, and `nix run`.
|
|
|
|
### 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 { }
|
|
```
|
|
|
|
3.5. **Stage the package**: `git add packages/<package-name>/`
|
|
Blueprint discovers packages from the git index, not the working directory.
|
|
Without this step, the package won't appear in flake outputs.
|
|
|
|
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)
|
|
|
|
## Updating Packages
|
|
|
|
Use [nix-update](https://github.com/Mic92/nix-update) to bump versions and update hashes:
|
|
|
|
```bash
|
|
# Update a package to the latest version
|
|
nix-update <package-name>
|
|
|
|
# Update to a specific version
|
|
nix-update <package-name> --version <version>
|
|
|
|
# Update a package pinned to a commit hash (e.g. skillsmcp)
|
|
nix-update <package-name> --version=branch=main
|
|
```
|
|
|
|
After updating, always test the build:
|
|
|
|
```bash
|
|
nix build .#<package-name>
|
|
```
|
|
|
|
### Package-Specific Notes
|
|
|
|
- **goose-cli**: Also updates `librusty_v8` hashes automatically via the custom fetcher
|
|
- **mcp-gateway**: Standard Rust package, `nix-update` handles version + cargoHash
|
|
- **skillsmcp**: Pinned to a commit hash; use `--version=branch=main` or specify the target commit with `--commit`
|
|
|
|
## Git Workflow
|
|
|
|
### Committing Completed Work
|
|
|
|
Every completed job or feature must be committed to the git repository.
|
|
|
|
When preparing git commits, always use the `conventional-commit` skill to create proper commit messages following conventional commit conventions.
|
|
|
|
This ensures:
|
|
- Clean git history with proper commit message formatting
|
|
- No work is left uncommitted
|
|
- Consistent commit message style across the project
|
|
|
|
### Advanced Git Operations
|
|
|
|
For advanced Git workflows (rebasing, cherry-picking, bisect, worktrees, reflog, history recovery), use the `git-advanced-workflows` skill.
|
|
|
|
This skill provides:
|
|
- Master advanced Git workflows including rebasing, cherry-picking, bisect, worktrees, and reflog
|
|
- Maintain clean history and recover from any situation
|
|
- Manage complex Git histories, collaborate on feature branches, or troubleshoot repository issues
|
|
|
|
## 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 using conventional-commit skill
|
|
git add packages/my-tool README.md
|
|
# Then invoke: skill: "conventional-commit"
|
|
```
|
|
|
|
<!-- BEGIN BEADS INTEGRATION v:1 profile:minimal hash:ca08a54f -->
|
|
## Beads Issue Tracker
|
|
|
|
This project uses **bd (beads)** for issue tracking. Run `bd prime` to see full workflow context and commands.
|
|
|
|
### Quick Reference
|
|
|
|
```bash
|
|
bd ready # Find available work
|
|
bd show <id> # View issue details
|
|
bd update <id> --claim # Claim work
|
|
bd close <id> # Complete work
|
|
```
|
|
|
|
### Rules
|
|
|
|
- Use `bd` for ALL task tracking — do NOT use TodoWrite, TaskCreate, or markdown TODO lists
|
|
- Run `bd prime` for detailed command reference and session close protocol
|
|
- Use `bd remember` for persistent knowledge — do NOT use MEMORY.md files
|
|
|
|
## Session Completion
|
|
|
|
**When ending a work session**, you MUST complete ALL steps below. Work is NOT complete until `git push` succeeds.
|
|
|
|
**MANDATORY WORKFLOW:**
|
|
|
|
1. **File issues for remaining work** - Create issues for anything that needs follow-up
|
|
2. **Run quality gates** (if code changed) - Tests, linters, builds
|
|
3. **Update issue status** - Close finished work, update in-progress items
|
|
4. **PUSH TO REMOTE** - This is MANDATORY:
|
|
```bash
|
|
git pull --rebase
|
|
bd dolt push
|
|
git push
|
|
git status # MUST show "up to date with origin"
|
|
```
|
|
5. **Clean up** - Clear stashes, prune remote branches
|
|
6. **Verify** - All changes committed AND pushed
|
|
7. **Hand off** - Provide context for next session
|
|
|
|
**CRITICAL RULES:**
|
|
- Work is NOT complete until `git push` succeeds
|
|
- NEVER stop before pushing - that leaves work stranded locally
|
|
- NEVER say "ready to push when you are" - YOU must push
|
|
- If push fails, resolve and retry until it succeeds
|
|
<!-- END BEADS INTEGRATION -->
|