Files
nixpkgs/AGENTS.md
sascha.koenig 57ebad1358 refactor: remove legacy mkOpencodeRules alias and opencode-rules compat entry
- Remove mkOpencodeRules backward-compat alias from lib/coding-rules.nix
- Remove opencode-rules alias from lib/default.nix
- Update shells/opencode.nix to use mkCodingRules / coding-rules
- Remove backward-compat test from tests/lib/coding-rules-test.nix
- Update AGENTS.md and modules/home-manager/AGENTS.md docs
- Apply nix fmt formatting to shared-options.nix
2026-04-20 19:16:22 +02:00

8.3 KiB

m3ta-nixpkgs Knowledge Base

Generated: 2026-02-14 Commit: dc2f3b6 Branch: master

OVERVIEW

Personal Nix flake: custom packages, overlays, NixOS/Home Manager modules, dev shells. Flakes-only (no channels).

STRUCTURE

.
├── flake.nix              # Entry: packages, overlays, modules, shells, lib
├── pkgs/                  # Custom packages (one dir each, callPackage registry)
├── modules/
│   ├── nixos/             # System modules (ports.nix)
│   └── home-manager/      # User modules by category (cli/, coding/, ports.nix)
├── lib/                   # Shared utilities (ports.nix)
├── shells/                # Dev environments (default, python, devops)
├── overlays/mods/         # Package modifications (n8n version bump)
├── templates/             # Boilerplate for new packages/modules
├── examples/              # Usage examples
└── .gitea/workflows/     # CI/CD workflows (nix-update automation)

WHERE TO LOOK

Task Location Notes
Add package pkgs/<name>/default.nix Register in pkgs/default.nix
Add NixOS module modules/nixos/<name>.nix Import in modules/nixos/default.nix
Add HM module modules/home-manager/<category>/ Category: cli, coding, or root
Override nixpkgs pkg overlays/mods/<name>.nix Import in overlays/mods/default.nix
Add dev shell shells/<name>.nix Register in shells/default.nix
Use port management config.m3ta.ports.get "service" Host-specific via hostOverrides
CI/CD workflows .gitea/workflows/<name>.yml Automated package updates (nix-update)

CONVENTIONS

Formatter: nix fmt before commit (alejandra)

Naming:

  • Packages: lowercase-hyphen (e.g., hyprpaper-random)
  • Variables: camelCase (e.g., portHelpers)
  • Module options: m3ta.* namespace

Imports: Multi-line, trailing commas:

{
  lib,
  stdenv,
  fetchFromGitHub,
}:

Modules: Standard pattern:

{ config, lib, pkgs, ... }:
with lib; let
  cfg = config.m3ta.myModule;
in {
  options.m3ta.myModule = {
    enable = mkEnableOption "description";
  };
  config = mkIf cfg.enable { ... };
}

Meta: Always include all fields:

meta = with lib; {
  description = "...";
  homepage = "...";
  license = licenses.mit;
  platforms = platforms.linux;
  mainProgram = "...";
};

PACKAGE PATTERNS

Rust: rustPlatform.buildRustPackage rec { cargoLock.lockFile = src + "/Cargo.lock"; }

Shell: writeShellScriptBin "name" ''script'' or mkDerivation with custom installPhase

AppImage: appimageTools.wrapType2 { ... }

Custom fetcher: fetchFromGitea { domain = "code.m3ta.dev"; owner = "m3tam3re"; ... }

MODULE PATTERNS

Simple: options.cli.name = { enable = mkEnableOption "..."; }; config = mkIf cfg.enable { ... };

Multiple: config = mkMerge [ (mkIf cfg.x.enable { ... }) (mkIf cfg.y.enable { ... }) ];

Shared lib: portsLib = import ../../lib/ports.nix { inherit lib; }; portHelpers = portsLib.mkPortHelpers { ... };

LIBRARY FUNCTIONS

lib.ports

Port management utilities. See Port Management.

lib.agents

Harness-agnostic agent management. Reads canonical agent.toml + system-prompt.md from the AGENTS flake input and renders tool-specific configs.

Functions:

Function Purpose
loadCanonical { agentsInput } Load canonical agents from AGENTS flake
renderForOpencode { pkgs, canonical, modelOverrides } Render to OpenCode file-based agents
renderForClaudeCode { pkgs, canonical, modelOverrides } Render to Claude Code agents + settings.json
renderForPi { pkgs, canonical, modelOverrides, primaryAgent } Render to Pi AGENTS.md + SYSTEM.md + agents/
renderForTool { pkgs, agentsInput, tool, modelOverrides } Dispatch to correct renderer by tool name
shellHookForTool { pkgs, agentsInput, tool, modelOverrides } Generate devShell shellHook (symlinks rendered files)

lib.coding-rules

Coding rules injection. Generates coding-rules.json + symlinks rules from the AGENTS repository.

Function Purpose
mkCodingRules { agents, languages, concerns, frameworks, rulesDir } Generate rules config + shellHook. rulesDir defaults to .opencode-rules

PORT MANAGEMENT

Central port management: config.m3ta.ports.get "service" with host-specific via hostOverrides

Generated: /etc/m3ta/ports.json (NixOS), ~/.config/m3ta/ports.json (HM)

COMMANDS

nix flake check              # Validate flake
nix fmt                      # Format (alejandra)
nix build .#<pkg>            # Build package
nix flake show               # List outputs
nix develop                  # Enter dev shell
nix develop .#python         # Python shell
nix develop .#devops         # DevOps shell

# In dev shell only:
statix check .               # Lint
deadnix .                    # Find dead code

ANTI-PATTERNS

Don't Do Instead
lib.fakeHash in commits Get real hash: nix build, copy from error
Flat module files Organize by category (cli/, coding/)
Hardcode ports Use m3ta.ports module
Skip meta fields Include all: description, homepage, license, platforms, mainProgram
with pkgs; in modules Explicit pkgs.package or with pkgs; [ ... ] in lists only

COMMIT FORMAT

type: brief description

Types: feat, fix, docs, style, refactor, chore

NOTES

  • Hash fetching: Use lib.fakeHash initially, build to get real hash
  • HM modules: Category subdirs (cli/, coding/) have own default.nix aggregators
  • Ports module: Different for NixOS vs HM (HM adds generateEnvVars option)
  • Overlays: modifications overlay uses {prev}: pattern, not {final, prev}:
  • Dev shell tools: statix, deadnix only available inside nix develop
  • Automated package updates: Packages are automatically updated weekly via Gitea Actions using nix-update. Review PRs from the automation before merging. For urgent updates, manually run the workflow or update manually.

Task Management

td is an optional task-tracking package. See docs/packages/td.md for details.

Agent System Architecture

The agent system uses harness-agnostic canonical definitions stored as agent.toml + system-prompt.md in the AGENTS repository. Renderers in lib/agents.nix transform these into tool-specific configs at build time.

How it works

  1. Canonical definitions live in the AGENTS repo as agent.toml files (one per agent) with shared fields: name, description, mode, systemPrompt, permissions, skills.
  2. loadCanonical reads all agent definitions from the AGENTS flake input.
  3. Renderers produce tool-specific output:
    • renderForOpencode*.md files with YAML frontmatter for .opencode/agents/
    • renderForClaudeCode.claude/agents/*.md + .claude/settings.json with permission rules
    • renderForPiAGENTS.md, SYSTEM.md, agents/*.md for Pi's subagent format
  4. renderForTool dispatches to the correct renderer by tool name ("opencode", "claude-code", or "pi").
  5. shellHookForTool generates a devShell shellHook that symlinks rendered files into the project directory.
  6. HM modules in modules/home-manager/coding/agents/ handle per-tool Home Manager integration.

Key files in this repo

  • lib/agents.nix — renderers, dispatcher, shellHook generator
  • lib/coding-rules.nix — coding rules injection (mkCodingRules)
  • modules/home-manager/coding/agents/ — per-tool HM sub-modules (opencode, claude-code, pi)
  • modules/home-manager/coding/opencode.nix — OpenCode HM module (slimmed, agents handled separately)