Merge pull request 'refactor/remove-pi-agent-cleanup' (#14) from refactor/remove-pi-agent-cleanup into master
Some checks failed
Update Nix Packages with nix-update / nix-update (push) Failing after 4m2s
Some checks failed
Update Nix Packages with nix-update / nix-update (push) Failing after 4m2s
Reviewed-on: #14
This commit was merged in pull request #14.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -43,3 +43,5 @@ flake.lock.bak
|
||||
.sidecar-start.sh
|
||||
.sidecar-base
|
||||
.td-root
|
||||
.pi-lens
|
||||
.cache
|
||||
|
||||
4
.pi-lens/cache/session-start-guidance.json
vendored
4
.pi-lens/cache/session-start-guidance.json
vendored
@@ -1,3 +1 @@
|
||||
{
|
||||
"content": "📌 pi-lens active — as you work on this project, fix any errors you encounter (including pre-existing). Prefer: lsp_navigation for definitions/references, ast_grep_search for code patterns, grep for text/TODO search."
|
||||
}
|
||||
null
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"timestamp": "2026-04-11T04:21:36.939Z"
|
||||
"timestamp": "2026-04-19T15:52:39.989Z"
|
||||
}
|
||||
2
.pi-lens/cache/todo-baseline.meta.json
vendored
2
.pi-lens/cache/todo-baseline.meta.json
vendored
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"timestamp": "2026-04-11T04:21:36.940Z"
|
||||
"timestamp": "2026-04-19T15:42:10.963Z"
|
||||
}
|
||||
74
AGENTS.md
74
AGENTS.md
@@ -1,10 +1,5 @@
|
||||
# m3ta-nixpkgs Knowledge Base
|
||||
|
||||
## MANDATORY: Use td for Task Management
|
||||
|
||||
You must run td usage --new-session at conversation start (or after /clear) to see current work.
|
||||
Use td usage -q for subsequent reads.
|
||||
|
||||
**Generated:** 2026-02-14
|
||||
**Commit:** dc2f3b6
|
||||
**Branch:** master
|
||||
@@ -114,8 +109,8 @@ Port management utilities. See [Port Management](#port-management).
|
||||
|
||||
### `lib.agents`
|
||||
|
||||
Harness-agnostic agent management. Reads canonical `agent.toml` from the AGENTS
|
||||
flake input and renders tool-specific configs.
|
||||
Harness-agnostic agent management. Reads canonical `agent.toml` +
|
||||
`system-prompt.md` from the AGENTS flake input and renders tool-specific configs.
|
||||
|
||||
**Functions:**
|
||||
|
||||
@@ -124,17 +119,18 @@ flake input and renders tool-specific configs.
|
||||
| `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 }` | Render to Pi AGENTS.md + SYSTEM.md |
|
||||
| `renderForTool { pkgs, agentsInput, tool, modelOverrides }` | Dispatch to correct renderer |
|
||||
| `shellHookForTool { pkgs, agentsInput, tool, modelOverrides }` | Generate devShell shellHook |
|
||||
| `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 (renamed from `lib.opencode-rules`). The old name still works.
|
||||
Coding rules injection. Generates `coding-rules.json` + symlinks rules from
|
||||
the AGENTS repository. The old `lib.opencode-rules` name still works.
|
||||
|
||||
| Function | Purpose |
|
||||
|----------|--------|
|
||||
| `mkCodingRules { agents, languages, concerns, frameworks }` | Generate rules config + shellHook |
|
||||
| `mkCodingRules { agents, languages, concerns, frameworks, rulesDir }` | Generate rules config + shellHook. `rulesDir` defaults to `.opencode-rules` |
|
||||
| `mkOpencodeRules` | Backward-compat alias for `mkCodingRules` |
|
||||
|
||||
## PORT MANAGEMENT
|
||||
@@ -188,38 +184,34 @@ Types: `feat`, `fix`, `docs`, `style`, `refactor`, `chore`
|
||||
|
||||
## Task Management
|
||||
|
||||
This project uses **td** for tracking tasks across AI coding sessions.
|
||||
Run `td usage --new-session` at conversation start to see current work.
|
||||
Use `td usage -q` for subsequent reads.
|
||||
**td** is an optional task-tracking package. See `docs/packages/td.md` for details.
|
||||
|
||||
**Quick reference:**
|
||||
## Agent System Architecture
|
||||
|
||||
- `td usage --new-session` - Start new session and view tasks
|
||||
- `td usage -q` - Quick view of current tasks (subsequent reads)
|
||||
- `td version` - Check version
|
||||
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.
|
||||
|
||||
For full workflow details, see the [td documentation](./docs/packages/td.md).
|
||||
### How it works
|
||||
|
||||
## MIGRATION: Agent System (OpenCode → Canonical TOML)
|
||||
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
|
||||
- `renderForPi` → `AGENTS.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.
|
||||
|
||||
The agent system was migrated from embedded `agents.json` to harness-agnostic
|
||||
canonical `agent.toml` + `system-prompt.md` in the AGENTS repo. Renderers in
|
||||
`lib/agents.nix` generate tool-specific configs.
|
||||
### Key files in this repo
|
||||
|
||||
### What changed in this repo
|
||||
|
||||
- **`lib/agents.nix`**: New — 3 renderers (OpenCode, Claude Code, Pi) + dispatcher + shellHook
|
||||
- **`lib/coding-rules.nix`**: Renamed from `opencode-rules.nix`, `mkCodingRules` replaces `mkOpencodeRules`
|
||||
- **`modules/home-manager/coding/agents/`**: New — per-tool HM sub-modules
|
||||
- **`modules/home-manager/coding/opencode.nix`**: Slimmed — no longer handles agents/skills/context
|
||||
- **`flake.nix`**: Exports new `agents` HM module
|
||||
|
||||
### What the user must do
|
||||
|
||||
See `modules/home-manager/AGENTS.md` for the full migration guide. Summary:
|
||||
|
||||
1. Move `agentsInput`/`externalSkills` from `coding.opencode` to `coding.agents.opencode`
|
||||
2. Add `modelOverrides` with previously hardcoded model strings
|
||||
3. Run `home-manager switch`
|
||||
4. Remove legacy `agents.json` + `prompts/*.txt` from AGENTS repo
|
||||
5. Remove `lib.agentsJson` backward-compat bridge from AGENTS `flake.nix`
|
||||
- `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)
|
||||
|
||||
107
CHANGELOG.md
Normal file
107
CHANGELOG.md
Normal file
@@ -0,0 +1,107 @@
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Changed
|
||||
- Remove duplicate opencode-rules.nix (backward-compat alias preserved)
|
||||
- Tool-agnostic naming in coding-rules lib internals
|
||||
- Remove redundant overlay entries for non-existent flake inputs
|
||||
- Remove redundant 'additions' overlay (identical to 'default')
|
||||
|
||||
### Removed
|
||||
- Dead overlay entries for non-existent flake inputs
|
||||
|
||||
## [0.4.0] - 2026-04-15
|
||||
|
||||
### Added
|
||||
- Pi-agent wrapper with systemd sandbox and per-host-user policy
|
||||
- Containerized Pi agent
|
||||
- `lib.agents.nix` with loadCanonical, renderers (OpenCode, Claude Code, Pi), and shellHook
|
||||
- `lib.coding-rules` helper for per-project rule injection (renamed from opencode-rules)
|
||||
- Home Manager modules for coding agents: `claude-code`, `opencode`, `pi`
|
||||
- Agents rework with canonical TOML format and harness-agnostic renderers
|
||||
- `vibetyper` and `eigent` packages
|
||||
- `openspec` package
|
||||
- `basecamp-cli` package
|
||||
- `openshell` package (0.0.14 through 0.0.23)
|
||||
- `openwork` package
|
||||
- Opencode config moved into m3ta-nixpkgs
|
||||
- Opencode dev shell with mkCodingRules demo
|
||||
|
||||
### Changed
|
||||
- OpenCode flake input updated through v1.1.65 to v1.3.6
|
||||
- Switched from local opencode package to upstream flake input
|
||||
- Removed opencode-desktop (awaiting upstream fix), later re-enabled
|
||||
- Nix eval warnings resolved
|
||||
- Flake inputs updated throughout
|
||||
|
||||
### Fixed
|
||||
- Pi settings sync
|
||||
- Remove openwork sidecars in preFixup to prevent .opencode-wrapped conflict
|
||||
- Remove sidecar binaries from openwork $out/bin to fix buildEnv conflict
|
||||
- Vibetyper .desktop entry
|
||||
- Opencode module formatting
|
||||
- Formatting opencode module
|
||||
|
||||
## [0.3.0] - 2026-02-20
|
||||
|
||||
### Added
|
||||
- `notesmd-cli` package with flake checks
|
||||
- `sidecar` and `td` packages
|
||||
- `opencode-desktop` package with Wayland support
|
||||
- `mem0` package (1.0.2 through 1.0.9)
|
||||
- `kestracli` / `kestractl` package (1.0.0 to 1.2.2)
|
||||
|
||||
### Changed
|
||||
- Nix-update CI workflow optimized with caching and parallel processing
|
||||
- Restructured n8n version handling for nix-update compatibility
|
||||
- Switched formatter from nixpkgs-fmt to alejandra
|
||||
- Replace local opencode with upstream flake input v1.1.27
|
||||
|
||||
### Fixed
|
||||
- n8n build error
|
||||
- n8n pnpm hash
|
||||
- n8n update script
|
||||
- Gitea runner opencode.url flake input
|
||||
- nix-update workflow: YAML syntax, jobs indentation, PR body formatting
|
||||
- Arithmetic increment failing with set -e in nix-update workflow
|
||||
- Removed magic-nix-cache-action causing platform mapping error
|
||||
- Opencode bun version requirement patched to match upstream lockfile
|
||||
- Deprecated opencode update logic removed
|
||||
- nix fmt without arg in workflow
|
||||
- Extra Lua config renamed initLua
|
||||
- Stt-ptt use pkill for better process management
|
||||
|
||||
## [0.2.0] - 2026-01-13
|
||||
|
||||
### Added
|
||||
- Gitea Actions workflow for automated package updates with nix-update
|
||||
- `n8n`, `beads`, and `opencode` packages
|
||||
- `stt-ptt` package with auto-language detection
|
||||
- `rofi-project-opener` for rofi-based project launching
|
||||
- Hierarchical AGENTS.md knowledge base
|
||||
- Dev shell structure with python and devops shells
|
||||
- Port management modules (NixOS + Home Manager)
|
||||
- Port helper library (`lib/ports.nix`)
|
||||
|
||||
### Changed
|
||||
- Beads updated through v0.49.1
|
||||
- N8n updated through v2.8.1
|
||||
- Opencode updated through v1.1.18
|
||||
- Documentation expanded with comprehensive patterns and HM module docs
|
||||
|
||||
### Fixed
|
||||
- Python env version fix for marimo
|
||||
|
||||
## [0.1.0] - 2025-10-04
|
||||
|
||||
### Added
|
||||
- Initial flake setup with packages, overlays, modules, and shells
|
||||
- NixOS and Home Manager module infrastructure
|
||||
- `lib/` shared utilities
|
||||
- `overlays/mods/` for package modifications
|
||||
- `templates/` for new packages/modules
|
||||
- `examples/` for usage documentation
|
||||
@@ -1,117 +0,0 @@
|
||||
# notesmd-cli
|
||||
|
||||
Obsidian CLI (Community) - Interact with Obsidian in the terminal.
|
||||
|
||||
## Description
|
||||
|
||||
notesmd-cli is a command-line interface for interacting with Obsidian, the popular knowledge management and note-taking application. It allows you to create, search, and manipulate notes directly from the terminal.
|
||||
|
||||
## Features
|
||||
|
||||
- 📝 **Note Creation**: Create new notes from the command line
|
||||
- 🔍 **Search**: Search through your Obsidian vault
|
||||
- 📂 **Vault Management**: Interact with your vault structure
|
||||
- 🔗 **WikiLink Support**: Work with Obsidian's WikiLink format
|
||||
- 🏷️ **Tag Support**: Manage and search by tags
|
||||
- ⚡ **Fast**: Lightweight Go binary with no external dependencies
|
||||
|
||||
## Installation
|
||||
|
||||
### Via Overlay
|
||||
|
||||
```nix
|
||||
{pkgs, ...}: {
|
||||
environment.systemPackages = with pkgs; [
|
||||
notesmd-cli
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### Direct Reference
|
||||
|
||||
```nix
|
||||
{pkgs, ...}: {
|
||||
environment.systemPackages = with pkgs; [
|
||||
inputs.m3ta-nixpkgs.packages.${pkgs.system}.notesmd-cli
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### Run Directly
|
||||
|
||||
```bash
|
||||
nix run git+https://code.m3ta.dev/m3tam3re/nixpkgs#notesmd-cli
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic Commands
|
||||
|
||||
```bash
|
||||
# Show help
|
||||
notesmd-cli --help
|
||||
|
||||
# Create a new note
|
||||
notesmd-cli new "My Note Title"
|
||||
|
||||
# Search notes
|
||||
notesmd-cli search "search term"
|
||||
|
||||
# List notes
|
||||
notesmd-cli list
|
||||
```
|
||||
|
||||
### Working with Vaults
|
||||
|
||||
```bash
|
||||
# Specify vault path
|
||||
notesmd-cli --vault /path/to/vault new "Note Title"
|
||||
|
||||
# Open a note in Obsidian
|
||||
notesmd-cli open "Note Name"
|
||||
```
|
||||
|
||||
### Advanced Usage
|
||||
|
||||
```bash
|
||||
# Search with tags
|
||||
notesmd-cli search --tag "project"
|
||||
|
||||
# Append to existing note
|
||||
notesmd-cli append "Note Name" "Additional content"
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
- `OBSIDIAN_VAULT`: Default vault path
|
||||
|
||||
### Command Line Options
|
||||
|
||||
Run `notesmd-cli --help` for a complete list of options.
|
||||
|
||||
## Build Information
|
||||
|
||||
- **Version**: 0.3.0
|
||||
- **Language**: Go
|
||||
- **License**: MIT
|
||||
- **Source**: [GitHub](https://github.com/Yakitrak/notesmd-cli)
|
||||
- **Vendor Hash**: null (no external dependencies)
|
||||
|
||||
## Platform Support
|
||||
|
||||
- Linux
|
||||
- macOS (Unix systems)
|
||||
|
||||
## Notes
|
||||
|
||||
- No vendor dependencies (pure Go stdlib)
|
||||
- The binary is named `notesmd-cli` (not `notesmd`)
|
||||
- This is the community CLI, not the official Obsidian CLI
|
||||
|
||||
## Related
|
||||
|
||||
- [Obsidian](https://obsidian.md) - The Obsidian application
|
||||
- [Adding Packages](../guides/adding-packages.md) - How to add new packages
|
||||
- [Quick Start](../QUICKSTART.md) - Getting started guide
|
||||
637
docs/plans/2026-04-15-nixpkgs-cleanup-and-improvements.md
Normal file
637
docs/plans/2026-04-15-nixpkgs-cleanup-and-improvements.md
Normal file
@@ -0,0 +1,637 @@
|
||||
# m3ta-nixpkgs: Cleanup & Improvements Plan
|
||||
|
||||
> **For Hermes:** Use subagent-driven-development skill to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Address 10 issues identified in codebase review — reduce duplication, improve naming consistency, extract inline scripts, add testing, and update documentation.
|
||||
|
||||
**Architecture:** Incremental improvements across lib/, modules/, overlays/, docs/, and CI. Each change is self-contained and can be merged independently. No breaking changes to public API (backward-compat aliases preserved where needed).
|
||||
|
||||
**Repo:** `gitea@code.m3ta.dev:m3tam3re/nixpkgs.git` (master branch)
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Deduplication & Naming (Low Risk)
|
||||
|
||||
### Task 1: Remove duplicate opencode-rules.nix file
|
||||
|
||||
**Objective:** Eliminate the duplicate file import. The `coding-rules.nix` is the canonical source; `opencode-rules.nix` is an identical copy. Make the alias a one-liner in `lib/default.nix`.
|
||||
|
||||
**Files:**
|
||||
- Delete: `lib/opencode-rules.nix`
|
||||
- Modify: `lib/default.nix`
|
||||
|
||||
**Step 1: Update lib/default.nix to alias directly**
|
||||
|
||||
```nix
|
||||
{lib}: {
|
||||
ports = import ./ports.nix {inherit lib;};
|
||||
|
||||
coding-rules = import ./coding-rules.nix {inherit lib;};
|
||||
|
||||
# Backward-compat alias: opencode-rules → coding-rules
|
||||
opencode-rules = import ./coding-rules.nix {inherit lib;};
|
||||
opencode = import ./coding-rules.nix {inherit lib;};
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Delete the duplicate file**
|
||||
|
||||
```bash
|
||||
git rm lib/opencode-rules.nix
|
||||
```
|
||||
|
||||
**Step 3: Verify nothing breaks**
|
||||
|
||||
```bash
|
||||
nix flake check
|
||||
```
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git commit -m "refactor: remove duplicate opencode-rules.nix, use alias in default.nix"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2: Tool-agnostic naming in coding-rules.nix internals
|
||||
|
||||
**Objective:** Rename internal variables and output artifacts in `coding-rules.nix` from opencode-specific names to generic names, while keeping the backward-compat alias `mkOpencodeRules`.
|
||||
|
||||
**Files:**
|
||||
- Modify: `lib/coding-rules.nix`
|
||||
|
||||
**Step 1: Rename internal symbols**
|
||||
|
||||
In `lib/coding-rules.nix`, rename:
|
||||
- `rulesDir` stays `.opencode-rules` (this is a filesystem path used by existing projects, changing it would break)
|
||||
- `opencodeConfig` → `rulesConfig`
|
||||
- `opencode.json` output → `coding-rules.json` (add a comment noting it was renamed)
|
||||
- Add `rulesDir` option to function signature with default `.opencode-rules`
|
||||
|
||||
Updated function:
|
||||
|
||||
```nix
|
||||
{lib}: let
|
||||
mkCodingRules = {
|
||||
agents,
|
||||
languages ? [],
|
||||
concerns ? [
|
||||
"coding-style"
|
||||
"naming"
|
||||
"documentation"
|
||||
"testing"
|
||||
"git-workflow"
|
||||
"project-structure"
|
||||
],
|
||||
frameworks ? [],
|
||||
extraInstructions ? [],
|
||||
rulesDir ? ".opencode-rules",
|
||||
}: let
|
||||
instructions =
|
||||
(map (c: "${rulesDir}/concerns/${c}.md") concerns)
|
||||
++ (map (l: "${rulesDir}/languages/${l}.md") languages)
|
||||
++ (map (f: "${rulesDir}/frameworks/${f}.md") frameworks)
|
||||
++ extraInstructions;
|
||||
|
||||
rulesConfig = {
|
||||
"$schema" = "https://opencode.ai/config.json";
|
||||
inherit instructions;
|
||||
};
|
||||
in {
|
||||
inherit instructions;
|
||||
|
||||
shellHook = ''
|
||||
# Create/update symlink to AGENTS rules directory
|
||||
ln -sfn ${agents}/rules ${rulesDir}
|
||||
|
||||
# Generate coding-rules configuration file
|
||||
cat > coding-rules.json <<'RULES_EOF'
|
||||
${builtins.toJSON rulesConfig}
|
||||
RULES_EOF
|
||||
'';
|
||||
};
|
||||
|
||||
# Backward-compat alias
|
||||
mkOpencodeRules = mkCodingRules;
|
||||
in {
|
||||
inherit mkCodingRules mkOpencodeRules;
|
||||
};
|
||||
```
|
||||
|
||||
**Step 2: Update shellHook comment in AGENTS.md**
|
||||
|
||||
In `AGENTS.md`, update the coding-rules section to mention the new `rulesDir` parameter and the `coding-rules.json` output file.
|
||||
|
||||
**Step 3: Verify**
|
||||
|
||||
```bash
|
||||
nix flake check
|
||||
```
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git commit -m "refactor: tool-agnostic naming in coding-rules.nix internals"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3: Remove redundant overlays entry in flake.nix
|
||||
|
||||
**Objective:** The `default` and `additions` overlays in `flake.nix` produce identical output. Remove `additions` if not referenced elsewhere, or document why both exist.
|
||||
|
||||
**Files:**
|
||||
- Modify: `flake.nix`
|
||||
- Check: all consumer repos for references to `overlays.additions`
|
||||
|
||||
**Step 1: Search for consumers of overlays.additions**
|
||||
|
||||
```bash
|
||||
# Check nixos-config and other repos
|
||||
grep -r "overlays.additions" /data/.hermes/repos/nixos-config/
|
||||
grep -r "additions" /data/.hermes/repos/nixos-config/ --include="*.nix" | grep overlay
|
||||
```
|
||||
|
||||
**Step 2: If no consumers found, remove additions**
|
||||
|
||||
In `flake.nix`, simplify overlays to:
|
||||
|
||||
```nix
|
||||
overlays = {
|
||||
default = final: prev:
|
||||
import ./pkgs {
|
||||
pkgs = final;
|
||||
inputs = inputs;
|
||||
};
|
||||
|
||||
modifications = final: prev: import ./overlays/mods {inherit prev;};
|
||||
};
|
||||
```
|
||||
|
||||
**Step 3: Verify**
|
||||
|
||||
```bash
|
||||
nix flake check
|
||||
```
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git commit -m "refactor: remove redundant 'additions' overlay (identical to 'default')"
|
||||
```
|
||||
|
||||
**Note:** If `additions` IS used elsewhere, add a comment explaining the convention and skip this task.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Extract Inline Scripts (Medium Risk)
|
||||
|
||||
### Task 4: Extract pi-agent runner script to standalone file
|
||||
|
||||
**Objective:** Move the ~200-line inline bash script in `modules/nixos/pi-agent.nix` (the `runner` variable) to a separate file `modules/nixos/pi-agent-runner.sh` that gets imported via `builtins.readFile` + `pkgs.writeShellApplication`.
|
||||
|
||||
**Files:**
|
||||
- Create: `modules/nixos/pi-agent-runner.sh`
|
||||
- Modify: `modules/nixos/pi-agent.nix`
|
||||
|
||||
**Step 1: Create the runner script file**
|
||||
|
||||
Extract the body of the `runner` script (everything inside the `pkgs.writeShellScriptBin cfg.wrapper.runnerName '' ... ''`) into `modules/nixos/pi-agent-runner.sh`.
|
||||
|
||||
The script uses Nix-style variable interpolation (`${...}`). We need to keep Nix template variables as `${...}` and convert runtime bash variables to use `$` prefix. Since the script already uses Nix `escapeShellArg` and `escapeShellArg` calls, the cleanest approach is:
|
||||
|
||||
Create `modules/nixos/pi-agent-runner.sh` as a template that `pkgs.substituteAll` or `builtins.readFile` + string replacement can process. However, given the heavy Nix interpolation, the pragmatic approach is to use `pkgs.writeShellApplication` with the script body inline but extracted to a `let` binding:
|
||||
|
||||
```nix
|
||||
# In pi-agent.nix, replace the inline runner with:
|
||||
let
|
||||
runnerScript = builtins.readFile ./pi-agent-runner.sh;
|
||||
# ... or keep as let binding but move the body to a separate derivation
|
||||
```
|
||||
|
||||
**Important caveat:** The script has ~30 Nix variable interpolations (`${cfg.user}`, `${escapeShellArg ...}`, etc.). Full extraction to a .sh file would require either:
|
||||
- (a) `substituteAll` with `--replace` for each variable — unwieldy at 30+ substitutions
|
||||
- (b) Converting to env vars passed at runtime — cleaner but changes security posture
|
||||
- (c) Keeping the Nix interpolation but extracting to a `let` block in a separate `.nix` file
|
||||
|
||||
**Recommended approach: Option (c)** — Create `modules/nixos/pi-agent-runner.nix` as a function that takes `cfg` and returns the script:
|
||||
|
||||
```nix
|
||||
# modules/nixos/pi-agent-runner.nix
|
||||
{cfg, pkgs, lib, ...}:
|
||||
with lib; let
|
||||
# ... all the helper variables from pi-agent.nix ...
|
||||
in
|
||||
pkgs.writeShellScriptBin cfg.wrapper.runnerName ''
|
||||
# ... the script body ...
|
||||
'';
|
||||
```
|
||||
|
||||
Then in `pi-agent.nix`:
|
||||
```nix
|
||||
runner = import ./pi-agent-runner.nix {inherit cfg pkgs lib;};
|
||||
```
|
||||
|
||||
**Step 2: Similarly extract the wrapper script**
|
||||
|
||||
Create `modules/nixos/pi-agent-wrapper.nix` for the `wrapper` variable.
|
||||
|
||||
**Step 3: Verify**
|
||||
|
||||
```bash
|
||||
nix flake check
|
||||
# Also test in a nixos-rebuild if possible
|
||||
```
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add modules/nixos/pi-agent-runner.nix modules/nixos/pi-agent-wrapper.nix
|
||||
git commit -m "refactor: extract pi-agent runner and wrapper to separate files"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Testing (Higher Value)
|
||||
|
||||
### Task 5: Add basic lib function tests
|
||||
|
||||
**Objective:** Add `nix eval`-based tests for `lib/agents.nix` parseRule logic and `lib/coding-rules.nix` instruction generation.
|
||||
|
||||
**Files:**
|
||||
- Create: `tests/lib/agents-test.nix`
|
||||
- Create: `tests/lib/coding-rules-test.nix`
|
||||
- Modify: `flake.nix` (add checks)
|
||||
|
||||
**Step 1: Create test infrastructure**
|
||||
|
||||
```nix
|
||||
# tests/lib/default.nix
|
||||
{
|
||||
agents = import ./agents-test.nix;
|
||||
coding-rules = import ./coding-rules-test.nix;
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Write agents.nix parseRule test**
|
||||
|
||||
```nix
|
||||
# tests/lib/agents-test.nix
|
||||
let
|
||||
lib = import <nixpkgs/lib>;
|
||||
agentsLib = (import ../../lib {inherit lib;}).agents;
|
||||
|
||||
# Test parseRule helper
|
||||
test1 = let
|
||||
result = builtins.tryEval (
|
||||
let
|
||||
# We can't directly test parseRule since it's internal.
|
||||
# Instead, test the renderer with minimal input.
|
||||
canonical = {
|
||||
test-agent = {
|
||||
description = "Test agent";
|
||||
mode = "primary";
|
||||
systemPrompt = "You are a test.";
|
||||
permissions = {
|
||||
bash = { intent = "allow"; };
|
||||
edit = { intent = "ask"; rules = ["rm -rf *:deny"]; };
|
||||
};
|
||||
};
|
||||
};
|
||||
pkgs = import <nixpkgs> { system = "x86_64-linux"; };
|
||||
rendered = agentsLib.renderForOpencode {
|
||||
inherit pkgs canonical;
|
||||
};
|
||||
in
|
||||
# Verify the derivation builds
|
||||
builtins.pathExists "${rendered}/test-agent.md"
|
||||
);
|
||||
in assert result.value == true; true;
|
||||
|
||||
in {
|
||||
parseRule-basic = test1;
|
||||
}
|
||||
```
|
||||
|
||||
**Step 3: Write coding-rules test**
|
||||
|
||||
```nix
|
||||
# tests/lib/coding-rules-test.nix
|
||||
let
|
||||
lib = import <nixpkgs/lib>;
|
||||
codingRulesLib = (import ../../lib {inherit lib;}).coding-rules;
|
||||
|
||||
rules = codingRulesLib.mkCodingRules {
|
||||
agents = "/tmp/fake-agents";
|
||||
languages = ["python"];
|
||||
concerns = ["naming"];
|
||||
rulesDir = ".coding-rules";
|
||||
};
|
||||
|
||||
# Verify instructions are generated correctly
|
||||
test1 = assert rules.instructions == [
|
||||
".coding-rules/concerns/naming.md"
|
||||
".coding-rules/languages/python.md"
|
||||
]; true;
|
||||
|
||||
# Verify backward-compat alias exists
|
||||
test2 = assert codingRulesLib.mkOpencodeRules == codingRulesLib.mkCodingRules; true;
|
||||
|
||||
in {
|
||||
instructions-correct = test1;
|
||||
backward-compat = test2;
|
||||
}
|
||||
```
|
||||
|
||||
**Step 4: Add to flake.nix checks**
|
||||
|
||||
In `flake.nix`, extend the `checks` attribute:
|
||||
|
||||
```nix
|
||||
checks = forAllSystems (system: let
|
||||
pkgs = pkgsFor system;
|
||||
packages = import ./pkgs {inherit pkgs inputs;};
|
||||
in
|
||||
builtins.mapAttrs (name: pkg: pkgs.lib.hydraJob pkg) packages
|
||||
// {
|
||||
formatting = pkgs.runCommand "check-formatting" {} ''
|
||||
${pkgs.alejandra}/bin/alejandra --check ${./.}
|
||||
touch $out
|
||||
'';
|
||||
lib-tests = pkgs.runCommand "lib-tests" {} ''
|
||||
${pkgs.nix}/bin/nix-instantiate --eval ${./tests/lib/default.nix}
|
||||
touch $out
|
||||
'';
|
||||
});
|
||||
```
|
||||
|
||||
**Step 5: Verify**
|
||||
|
||||
```bash
|
||||
nix flake check
|
||||
```
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add tests/
|
||||
git commit -m "test: add basic lib function tests for agents and coding-rules"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 6: Add NixOS VM test for pi-agent module
|
||||
|
||||
**Objective:** Add a basic NixOS VM test that verifies the pi-agent module can be evaluated and the wrapper/runner scripts exist.
|
||||
|
||||
**Files:**
|
||||
- Create: `tests/nixos/pi-agent-test.nix`
|
||||
- Modify: `flake.nix` (add to checks)
|
||||
|
||||
**Step 1: Write the VM test**
|
||||
|
||||
```nix
|
||||
# tests/nixos/pi-agent-test.nix
|
||||
{pkgs, ...}: {
|
||||
name = "pi-agent";
|
||||
|
||||
nodes.machine = {config, ...}: {
|
||||
imports = [
|
||||
${(pkgs.path + "/nixos/modules/module-list.nix")}
|
||||
];
|
||||
|
||||
# Minimal pi-agent config
|
||||
m3ta.pi-agent = {
|
||||
enable = true;
|
||||
package = pkgs.writeScriptBin "pi-agent" ''
|
||||
#!/bin/sh
|
||||
echo "pi-agent mock"
|
||||
'';
|
||||
createUser = true;
|
||||
hostUsers = {
|
||||
testuser = {
|
||||
projectRoots = ["/tmp/test-project"];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
users.users.testuser = {
|
||||
isNormalUser = true;
|
||||
};
|
||||
};
|
||||
|
||||
testScript = ''
|
||||
machine.start()
|
||||
machine.wait_for_unit("multi-user.target")
|
||||
|
||||
# Verify user was created
|
||||
machine.succeed("id pi-agent")
|
||||
|
||||
# Verify wrapper exists
|
||||
machine.succeed("which pi")
|
||||
|
||||
# Verify state directory
|
||||
machine.succeed("test -d /var/lib/pi-agent")
|
||||
machine.succeed("test -d /var/lib/pi-agent/.pi")
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: Add to flake.nix checks**
|
||||
|
||||
```nix
|
||||
# In the checks attrset:
|
||||
pi-agent-vm-test = pkgs.nixosTest (import ./tests/nixos/pi-agent-test.nix {inherit pkgs;});
|
||||
```
|
||||
|
||||
**Step 3: Verify**
|
||||
|
||||
```bash
|
||||
nix build .#checks.x86_64-linux.pi-agent-vm-test
|
||||
```
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add tests/nixos/
|
||||
git commit -m "test: add NixOS VM test for pi-agent module"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Documentation (Low Risk, High Value)
|
||||
|
||||
### Task 7: Update AGENTS.md to reflect current state
|
||||
|
||||
**Objective:** Remove outdated migration sections, update function signatures, and align with current code.
|
||||
|
||||
**Files:**
|
||||
- Modify: `AGENTS.md`
|
||||
|
||||
**Step 1: Update the AGENTS REWORK migration section**
|
||||
|
||||
The section starting with `## MIGRATION: Agent System (OpenCode → Canonical TOML)` describes a completed migration. Convert it to a brief "Architecture" section that describes the current state, not the migration path.
|
||||
|
||||
**Step 2: Update lib.agents function table**
|
||||
|
||||
Verify that the function signatures and descriptions in the AGENTS.md table match the actual functions in `lib/agents.nix`. Specifically:
|
||||
- `loadCanonical` takes `{agentsInput}` — confirm docs match
|
||||
- `renderForPi` now has `primaryAgent` parameter — confirm documented
|
||||
- `shellHookForTool` exists — confirm documented
|
||||
|
||||
**Step 3: Update coding-rules documentation**
|
||||
|
||||
Replace references to `mkOpencodeRules` with `mkCodingRules` as primary, `mkOpencodeRules` as backward-compat alias. Document the new `rulesDir` parameter.
|
||||
|
||||
**Step 4: Update overlay documentation**
|
||||
|
||||
Remove or annotate the `additions` overlay depending on Task 3 outcome.
|
||||
|
||||
**Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git commit -m "docs: update AGENTS.md to reflect current codebase state"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 8: Add CHANGELOG.md
|
||||
|
||||
**Objective:** Create a changelog that captures recent work (from git log) so consumers can track changes.
|
||||
|
||||
**Files:**
|
||||
- Create: `CHANGELOG.md`
|
||||
|
||||
**Step 1: Generate changelog from git history**
|
||||
|
||||
```bash
|
||||
cd /data/.hermes/repos/nixpkgs-review
|
||||
git log --oneline --no-merges master | head -30
|
||||
```
|
||||
|
||||
**Step 2: Write CHANGELOG.md**
|
||||
|
||||
Structure as Keep a Changelog format:
|
||||
|
||||
```markdown
|
||||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.4.0] - 2026-04-15
|
||||
|
||||
### Added
|
||||
- Pi agent wrapper with per-host-user policy enforcement (`m3ta.pi-agent` NixOS module)
|
||||
- `coding.agents.pi` Home Manager module with settings, MCP, and skills support
|
||||
- `coding.agents.claude-code` Home Manager module with MCP integration
|
||||
- Automated package updates via Gitea Actions (`nix-update` workflow)
|
||||
- `lib.agents.renderForPi` with primaryAgent selection and pi-subagents format
|
||||
- `pkgs/td` - Task management CLI for AI coding sessions
|
||||
|
||||
### Changed
|
||||
- Renamed `lib.opencode-rules` → `lib.coding-rules` (backward-compat alias preserved)
|
||||
- Agent system migrated to harness-agnostic canonical format
|
||||
- Pi settings sync now merges host and Nix-managed values via deep_merge
|
||||
|
||||
### Fixed
|
||||
- Pi settings sync race condition on first run
|
||||
```
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git commit -m "docs: add CHANGELOG.md"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Phase 5: Minor Cleanups (Low Risk)
|
||||
|
||||
### Task 9: Clean up pkgs/default.nix unused `system` binding
|
||||
|
||||
**Objective:** The `system = pkgs.stdenv.hostPlatform.system;` binding in `pkgs/default.nix` is only used for the two input-pass-throughs. If those are the only consumers, it's fine, but add a clarifying comment.
|
||||
|
||||
**Files:**
|
||||
- Modify: `pkgs/default.nix`
|
||||
|
||||
**Step 1: Add clarifying comment**
|
||||
|
||||
```nix
|
||||
{
|
||||
pkgs,
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
# Only used for flake input pass-throughs below
|
||||
system = pkgs.stdenv.hostPlatform.system;
|
||||
in {
|
||||
...
|
||||
```
|
||||
|
||||
**Step 2: Commit**
|
||||
|
||||
```bash
|
||||
git commit -m "docs: clarify system binding in pkgs/default.nix"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 10: Remove commented-out overlay entries in overlays/default.nix
|
||||
|
||||
**Objective:** Clean up the large block of commented-out code in `overlays/default.nix` (nodejs_24, paperless-ngx, anytype-heart, hyprpanel, etc.). These belong in git history, not in active code.
|
||||
|
||||
**Files:**
|
||||
- Modify: `overlays/default.nix`
|
||||
|
||||
**Step 1: Remove commented-out blocks**
|
||||
|
||||
Remove:
|
||||
- The `rose-pine-hyprcursor` addition from `additions` (if it's unused — check with grep)
|
||||
- The commented-out `nodejs_24`, `paperless-ngx`, `anytype-heart`, `trezord`, `mesa`, `hyprpanel` blocks from `modifications`
|
||||
- The commented-out overlay inputs (`temp-packages`, `stable-packages`, `pinned-packages`, `locked-packages`, `master-packages`) if they reference inputs not in `flake.nix`
|
||||
|
||||
Actually, `nixpkgs-stable`, `nixpkgs-9e9486b`, `nixpkgs-9472de4`, `nixpkgs-locked`, `nixpkgs-master` are NOT in the current `flake.nix` inputs. These overlays will fail if referenced. They should either be removed or the inputs should be added.
|
||||
|
||||
**Action:**
|
||||
- Keep `master-packages` IF `nixpkgs-master` is in flake.nix inputs (it IS — good)
|
||||
- Remove `temp-packages`, `pinned-packages`, `locked-packages` (inputs don't exist)
|
||||
- Keep `stable-packages` IF `nixpkgs-stable` exists in inputs (check — it does NOT currently exist)
|
||||
- Keep `additions` with `rose-pine-hyprcursor` IF `rose-pine-hyprcursor` input exists (check)
|
||||
|
||||
**Step 2: Verify**
|
||||
|
||||
```bash
|
||||
nix flake check
|
||||
```
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git commit -m "chore: remove dead overlay entries for non-existent flake inputs"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Execution Order & Priority
|
||||
|
||||
| Task | Risk | Effort | Impact | Dependencies |
|
||||
|------|------|--------|--------|-------------|
|
||||
| T1: Remove opencode-rules.nix | Low | 5min | Clean | None |
|
||||
| T2: Tool-agnostic naming | Low | 15min | Consistency | None |
|
||||
| T3: Remove redundant overlay | Low | 10min | Clean | Check consumers |
|
||||
| T9: Clarify system binding | Low | 2min | Docs | None |
|
||||
| T10: Remove dead overlays | Low | 10min | Clean | None |
|
||||
| T7: Update AGENTS.md | Low | 20min | Docs | After T1, T2 |
|
||||
| T8: Add CHANGELOG.md | Low | 15min | Docs | None |
|
||||
| T4: Extract pi-agent scripts | Medium | 45min | Maintainability | None |
|
||||
| T5: Lib function tests | Medium | 30min | Quality | None |
|
||||
| T6: NixOS VM test | Medium | 45min | Quality | None |
|
||||
|
||||
**Recommended order:** T1 → T9 → T10 → T3 → T2 → T7 → T8 → T5 → T4 → T6
|
||||
|
||||
**Branching strategy:** Create a feature branch `chore/cleanup-review` from master, implement all tasks, open PR for review before merging.
|
||||
15
flake.nix
15
flake.nix
@@ -56,13 +56,6 @@
|
||||
inputs = inputs;
|
||||
};
|
||||
|
||||
# Individual overlays for more granular control
|
||||
additions = final: prev:
|
||||
import ./pkgs {
|
||||
pkgs = final;
|
||||
inputs = inputs;
|
||||
};
|
||||
|
||||
modifications = final: prev: import ./overlays/mods {inherit prev;};
|
||||
};
|
||||
|
||||
@@ -84,10 +77,7 @@
|
||||
};
|
||||
|
||||
# Library functions - helper utilities for your configuration
|
||||
lib = forAllSystems (system: let
|
||||
pkgs = pkgsFor system;
|
||||
in
|
||||
import ./lib {lib = pkgs.lib;});
|
||||
lib = forAllSystems (system: import ./lib {lib = nixpkgs.lib;});
|
||||
|
||||
# Development shells for various programming environments
|
||||
# Usage: nix develop .#<shell-name>
|
||||
@@ -111,6 +101,9 @@
|
||||
${pkgs.alejandra}/bin/alejandra --check ${./.}
|
||||
touch $out
|
||||
'';
|
||||
# Lib unit tests
|
||||
lib-agents = import ./tests/lib/agents-test.nix;
|
||||
lib-coding-rules = import ./tests/lib/coding-rules-test.nix;
|
||||
});
|
||||
|
||||
# Templates for creating new packages/modules
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# Opencode rules management utilities
|
||||
# Coding rules management utilities
|
||||
#
|
||||
# This module provides functions to configure Opencode agent rules across
|
||||
# multiple projects. Rules are defined in the AGENTS repository and can be
|
||||
@@ -26,7 +26,7 @@
|
||||
#
|
||||
# The shellHook creates:
|
||||
# - A `.opencode-rules/` symlink pointing to the AGENTS repository rules directory
|
||||
# - An `opencode.json` file with a $schema reference and instructions list
|
||||
# - A `coding-rules.json` file with a $schema reference and instructions list
|
||||
#
|
||||
# The instructions list contains paths relative to the project root, all prefixed
|
||||
# with `.opencode-rules/`, making them portable across different project locations.
|
||||
@@ -46,7 +46,7 @@
|
||||
#
|
||||
# Returns:
|
||||
# An attribute set containing:
|
||||
# - shellHook: Bash code to create symlink and opencode.json
|
||||
# - shellHook: Bash code to create symlink and coding-rules.json
|
||||
# - instructions: List of rule file paths (relative to project root)
|
||||
#
|
||||
# Example:
|
||||
@@ -82,9 +82,8 @@
|
||||
],
|
||||
frameworks ? [],
|
||||
extraInstructions ? [],
|
||||
rulesDir ? ".opencode-rules",
|
||||
}: let
|
||||
rulesDir = ".opencode-rules";
|
||||
|
||||
# Build instructions list by mapping concerns, languages, frameworks to their file paths
|
||||
# All paths are relative to project root via the rulesDir symlink
|
||||
instructions =
|
||||
@@ -93,8 +92,8 @@
|
||||
++ (map (f: "${rulesDir}/frameworks/${f}.md") frameworks)
|
||||
++ extraInstructions;
|
||||
|
||||
# Generate JSON configuration for Opencode
|
||||
opencodeConfig = {
|
||||
# Generate JSON configuration for coding rules
|
||||
rulesConfig = {
|
||||
"$schema" = "https://opencode.ai/config.json";
|
||||
inherit instructions;
|
||||
};
|
||||
@@ -102,15 +101,15 @@
|
||||
inherit instructions;
|
||||
|
||||
# Shell hook to set up rules in the project
|
||||
# Creates a symlink to the AGENTS rules directory and generates opencode.json
|
||||
# Creates a symlink to the AGENTS rules directory and generates coding-rules.json
|
||||
shellHook = ''
|
||||
# Create/update symlink to AGENTS rules directory
|
||||
ln -sfn ${agents}/rules ${rulesDir}
|
||||
|
||||
# Generate opencode.json configuration file
|
||||
cat > opencode.json <<'OPENCODE_EOF'
|
||||
${builtins.toJSON opencodeConfig}
|
||||
OPENCODE_EOF
|
||||
# Generate coding-rules.json configuration file
|
||||
cat > coding-rules.json <<'RULES_EOF'
|
||||
${builtins.toJSON rulesConfig}
|
||||
RULES_EOF
|
||||
'';
|
||||
};
|
||||
|
||||
|
||||
@@ -1,116 +0,0 @@
|
||||
# Opencode rules management utilities
|
||||
#
|
||||
# This module provides functions to configure Opencode agent rules across
|
||||
# multiple projects. Rules are defined in the AGENTS repository and can be
|
||||
# selectively included based on language, framework, and concerns.
|
||||
#
|
||||
# Usage in your configuration:
|
||||
#
|
||||
# # In your flake or configuration:
|
||||
# let
|
||||
# m3taLib = inputs.m3ta-nixpkgs.lib.${system};
|
||||
#
|
||||
# rules = m3taLib.opencode-rules.mkOpencodeRules {
|
||||
# agents = inputs.agents;
|
||||
# languages = [ "python" "typescript" ];
|
||||
# concerns = [ "coding-style" "naming" "documentation" ];
|
||||
# frameworks = [ "react" "fastapi" ];
|
||||
# };
|
||||
# in {
|
||||
# # Use in your devShell:
|
||||
# devShells.default = pkgs.mkShell {
|
||||
# shellHook = rules.shellHook;
|
||||
# inherit (rules) instructions;
|
||||
# };
|
||||
# }
|
||||
#
|
||||
# The shellHook creates:
|
||||
# - A `.opencode-rules/` symlink pointing to the AGENTS repository rules directory
|
||||
# - An `opencode.json` file with a $schema reference and instructions list
|
||||
#
|
||||
# The instructions list contains paths relative to the project root, all prefixed
|
||||
# with `.opencode-rules/`, making them portable across different project locations.
|
||||
{lib}: {
|
||||
# Create Opencode rules configuration from AGENTS repository
|
||||
#
|
||||
# Args:
|
||||
# agents: Path to the AGENTS repository (non-flake input)
|
||||
# languages: Optional list of language-specific rules to include
|
||||
# (e.g., [ "python" "typescript" "rust" ])
|
||||
# concerns: Optional list of concern rules to include
|
||||
# Default: [ "coding-style" "naming" "documentation" "testing" "git-workflow" "project-structure" ]
|
||||
# frameworks: Optional list of framework-specific rules to include
|
||||
# (e.g., [ "react" "fastapi" "django" ])
|
||||
# extraInstructions: Optional list of additional instruction paths
|
||||
# (for custom rules outside standard locations)
|
||||
#
|
||||
# Returns:
|
||||
# An attribute set containing:
|
||||
# - shellHook: Bash code to create symlink and opencode.json
|
||||
# - instructions: List of rule file paths (relative to project root)
|
||||
#
|
||||
# Example:
|
||||
# mkOpencodeRules {
|
||||
# agents = inputs.agents;
|
||||
# languages = [ "python" ];
|
||||
# frameworks = [ "fastapi" ];
|
||||
# }
|
||||
# # Returns:
|
||||
# # {
|
||||
# # shellHook = "...";
|
||||
# # instructions = [
|
||||
# # ".opencode-rules/concerns/coding-style.md"
|
||||
# # ".opencode-rules/concerns/naming.md"
|
||||
# # ".opencode-rules/concerns/documentation.md"
|
||||
# # ".opencode-rules/concerns/testing.md"
|
||||
# # ".opencode-rules/concerns/git-workflow.md"
|
||||
# # ".opencode-rules/concerns/project-structure.md"
|
||||
# # ".opencode-rules/languages/python.md"
|
||||
# # ".opencode-rules/frameworks/fastapi.md"
|
||||
# # ];
|
||||
# # }
|
||||
mkOpencodeRules = {
|
||||
agents,
|
||||
languages ? [],
|
||||
concerns ? [
|
||||
"coding-style"
|
||||
"naming"
|
||||
"documentation"
|
||||
"testing"
|
||||
"git-workflow"
|
||||
"project-structure"
|
||||
],
|
||||
frameworks ? [],
|
||||
extraInstructions ? [],
|
||||
}: let
|
||||
rulesDir = ".opencode-rules";
|
||||
|
||||
# Build instructions list by mapping concerns, languages, frameworks to their file paths
|
||||
# All paths are relative to project root via the rulesDir symlink
|
||||
instructions =
|
||||
(map (c: "${rulesDir}/concerns/${c}.md") concerns)
|
||||
++ (map (l: "${rulesDir}/languages/${l}.md") languages)
|
||||
++ (map (f: "${rulesDir}/frameworks/${f}.md") frameworks)
|
||||
++ extraInstructions;
|
||||
|
||||
# Generate JSON configuration for Opencode
|
||||
opencodeConfig = {
|
||||
"$schema" = "https://opencode.ai/config.json";
|
||||
inherit instructions;
|
||||
};
|
||||
in {
|
||||
inherit instructions;
|
||||
|
||||
# Shell hook to set up rules in the project
|
||||
# Creates a symlink to the AGENTS rules directory and generates opencode.json
|
||||
shellHook = ''
|
||||
# Create/update symlink to AGENTS rules directory
|
||||
ln -sfn ${agents}/rules ${rulesDir}
|
||||
|
||||
# Generate opencode.json configuration file
|
||||
cat > opencode.json <<'OPENCODE_EOF'
|
||||
${builtins.toJSON opencodeConfig}
|
||||
OPENCODE_EOF
|
||||
'';
|
||||
};
|
||||
}
|
||||
@@ -3,7 +3,9 @@
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
}: let
|
||||
shared = import ./shared-options.nix {inherit lib;};
|
||||
in
|
||||
with lib; let
|
||||
cfg = config.coding.agents.claude-code;
|
||||
mcpCfg = config.programs.mcp or null;
|
||||
@@ -11,34 +13,22 @@ in {
|
||||
options.coding.agents.claude-code = {
|
||||
enable = mkEnableOption "Claude Code agent management via canonical agent.toml definitions";
|
||||
|
||||
agentsInput = mkOption {
|
||||
type = types.nullOr types.anything;
|
||||
default = null;
|
||||
description = ''
|
||||
agentsInput = shared.mkAgentsInputOption ''
|
||||
The `agents` flake input (your personal AGENTS repo).
|
||||
When set, agents are rendered from canonical agent.toml files
|
||||
and symlinked to ~/.claude/agents/.
|
||||
'';
|
||||
};
|
||||
|
||||
modelOverrides = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
description = ''
|
||||
Per-agent model overrides. Maps agent slug to model alias or ID.
|
||||
Example: { chiron = "claude-sonnet-4-20250514"; }
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
chiron = "claude-sonnet-4-20250514";
|
||||
"chiron-forge" = "claude-sonnet-4-20250514";
|
||||
}
|
||||
'';
|
||||
};
|
||||
modelOverrides = shared.mkModelOverridesOption;
|
||||
|
||||
externalSkills = shared.externalSkillsOption;
|
||||
|
||||
mcpServers = mkOption {
|
||||
type = types.attrsOf types.anything;
|
||||
default = if mcpCfg != null then mcpCfg.servers else {};
|
||||
default =
|
||||
if mcpCfg != null
|
||||
then mcpCfg.servers
|
||||
else {};
|
||||
defaultText = literalExpression "config.programs.mcp.servers";
|
||||
description = ''
|
||||
MCP server configurations for Claude Code.
|
||||
@@ -82,6 +72,15 @@ in {
|
||||
source = "${rendered}/.claude/agents";
|
||||
};
|
||||
|
||||
# Skills (merged from personal AGENTS repo + optional external skills)
|
||||
home.file.".claude/skills" = mkIf (cfg.agentsInput != null) {
|
||||
source = cfg.agentsInput.lib.mkOpencodeSkills {
|
||||
inherit pkgs;
|
||||
customSkills = "${cfg.agentsInput}/skills";
|
||||
externalSkills = shared.mapExternalSkills cfg.externalSkills;
|
||||
};
|
||||
};
|
||||
|
||||
# Rendered settings.json with permissions + MCP servers
|
||||
home.file.".claude/settings.json" = mkIf (settingsJson != null) {
|
||||
source = "${settingsJson}";
|
||||
|
||||
@@ -3,80 +3,30 @@
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
cfg = config.coding.agents.opencode;
|
||||
in {
|
||||
}: let
|
||||
shared = import ./shared-options.nix {inherit lib;};
|
||||
in
|
||||
with lib; {
|
||||
options.coding.agents.opencode = {
|
||||
enable = mkEnableOption "OpenCode agent management via canonical agent.toml definitions";
|
||||
|
||||
agentsInput = mkOption {
|
||||
type = types.nullOr types.anything;
|
||||
default = null;
|
||||
description = ''
|
||||
agentsInput = shared.mkAgentsInputOption ''
|
||||
The `agents` flake input (your personal AGENTS repo).
|
||||
When set, agents are rendered from canonical agent.toml files
|
||||
and symlinked to ~/.config/opencode/agents/.
|
||||
'';
|
||||
|
||||
modelOverrides = shared.mkModelOverridesOption;
|
||||
|
||||
externalSkills = shared.externalSkillsOption;
|
||||
};
|
||||
|
||||
modelOverrides = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
description = ''
|
||||
Per-agent model overrides. Maps agent slug to model string.
|
||||
Example: { chiron = "anthropic/claude-sonnet-4"; }
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
chiron = "anthropic/claude-sonnet-4";
|
||||
"chiron-forge" = "anthropic/claude-sonnet-4";
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
externalSkills = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
src = mkOption {
|
||||
type = types.anything;
|
||||
description = "Flake input pointing to a skills repository root.";
|
||||
};
|
||||
skillsDir = mkOption {
|
||||
type = types.str;
|
||||
default = "skills";
|
||||
description = ''
|
||||
Subdirectory inside src that contains skill folders.
|
||||
'';
|
||||
};
|
||||
selectSkills = mkOption {
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
default = null;
|
||||
description = ''
|
||||
List of skill names to cherry-pick from this source.
|
||||
null means include every skill found in skillsDir.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = [];
|
||||
description = ''
|
||||
External skill sources passed to mkOpencodeSkills.
|
||||
Each entry maps directly to an element of the externalSkills
|
||||
list accepted by the AGENTS flake's lib.mkOpencodeSkills.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
[
|
||||
{ src = inputs.skills-anthropic; selectSkills = [ "claude-api" ]; }
|
||||
{ src = inputs.skills-vercel; }
|
||||
]
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
config = mkIf config.coding.agents.opencode.enable {
|
||||
# Rendered agent files symlinked to ~/.config/opencode/agents/
|
||||
xdg.configFile."opencode/agents" = mkIf (cfg.agentsInput != null) {
|
||||
xdg.configFile."opencode/agents" = let
|
||||
cfg = config.coding.agents.opencode;
|
||||
in
|
||||
mkIf (cfg.agentsInput != null) {
|
||||
source = (import ../../../../lib {inherit lib;}).agents.renderForOpencode {
|
||||
inherit pkgs;
|
||||
canonical = cfg.agentsInput.lib.loadAgents;
|
||||
@@ -85,28 +35,34 @@ in {
|
||||
};
|
||||
|
||||
# Skills (merged from personal AGENTS repo + optional external skills)
|
||||
xdg.configFile."opencode/skills" = mkIf (cfg.agentsInput != null) {
|
||||
xdg.configFile."opencode/skills" = let
|
||||
cfg = config.coding.agents.opencode;
|
||||
in
|
||||
mkIf (cfg.agentsInput != null) {
|
||||
source = cfg.agentsInput.lib.mkOpencodeSkills {
|
||||
inherit pkgs;
|
||||
customSkills = "${cfg.agentsInput}/skills";
|
||||
externalSkills =
|
||||
map (
|
||||
entry:
|
||||
{inherit (entry) src skillsDir;}
|
||||
// optionalAttrs (entry.selectSkills != null) {inherit (entry) selectSkills;}
|
||||
)
|
||||
cfg.externalSkills;
|
||||
externalSkills = shared.mapExternalSkills cfg.externalSkills;
|
||||
};
|
||||
};
|
||||
|
||||
# Static config dirs from AGENTS repo
|
||||
xdg.configFile."opencode/context" = mkIf (cfg.agentsInput != null) {
|
||||
xdg.configFile."opencode/context" = let
|
||||
cfg = config.coding.agents.opencode;
|
||||
in
|
||||
mkIf (cfg.agentsInput != null) {
|
||||
source = "${cfg.agentsInput}/context";
|
||||
};
|
||||
xdg.configFile."opencode/commands" = mkIf (cfg.agentsInput != null) {
|
||||
xdg.configFile."opencode/commands" = let
|
||||
cfg = config.coding.agents.opencode;
|
||||
in
|
||||
mkIf (cfg.agentsInput != null) {
|
||||
source = "${cfg.agentsInput}/commands";
|
||||
};
|
||||
xdg.configFile."opencode/prompts" = mkIf (cfg.agentsInput != null) {
|
||||
xdg.configFile."opencode/prompts" = let
|
||||
cfg = config.coding.agents.opencode;
|
||||
in
|
||||
mkIf (cfg.agentsInput != null) {
|
||||
source = "${cfg.agentsInput}/prompts";
|
||||
};
|
||||
};
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
}: let
|
||||
shared = import ./shared-options.nix {inherit lib;};
|
||||
in
|
||||
with lib; let
|
||||
cfg = config.coding.agents.pi;
|
||||
mcpCfg = config.programs.mcp or null;
|
||||
@@ -22,25 +24,13 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
agentsInput = mkOption {
|
||||
type = types.nullOr types.anything;
|
||||
default = null;
|
||||
description = ''
|
||||
agentsInput = shared.mkAgentsInputOption ''
|
||||
The `agents` flake input (your personal AGENTS repo).
|
||||
When set, the primary agent's system prompt is rendered as SYSTEM.md,
|
||||
all agents are listed in AGENTS.md, and subagent .md files are deployed.
|
||||
'';
|
||||
};
|
||||
|
||||
modelOverrides = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
description = ''
|
||||
Per-agent model overrides for Pi subagents.
|
||||
Maps agent slug to model string, e.g.:
|
||||
{ chiron = "anthropic/claude-sonnet-4"; chiron-forge = "anthropic/claude-sonnet-4"; }
|
||||
'';
|
||||
};
|
||||
modelOverrides = shared.mkModelOverridesOption;
|
||||
|
||||
primaryAgent = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
@@ -51,6 +41,8 @@ in {
|
||||
'';
|
||||
};
|
||||
|
||||
externalSkills = shared.externalSkillsOption;
|
||||
|
||||
settings = mkOption {
|
||||
type = types.submodule {
|
||||
freeformType = types.attrsOf types.anything;
|
||||
@@ -222,11 +214,12 @@ in {
|
||||
# ── Agents — pi-subagents .md files ────────────────────────────
|
||||
agentFiles
|
||||
|
||||
# ── Skills symlinked from AGENTS repo ──────────────────────────
|
||||
# ── Skills symlinked from AGENTS repo + external skills ────────
|
||||
(mkIf (cfg.agentsInput != null) {
|
||||
".pi/agent/skills".source = cfg.agentsInput.lib.mkOpencodeSkills {
|
||||
inherit pkgs;
|
||||
customSkills = "${cfg.agentsInput}/skills";
|
||||
externalSkills = shared.mapExternalSkills cfg.externalSkills;
|
||||
};
|
||||
})
|
||||
];
|
||||
|
||||
75
modules/home-manager/coding/agents/shared-options.nix
Normal file
75
modules/home-manager/coding/agents/shared-options.nix
Normal file
@@ -0,0 +1,75 @@
|
||||
# Shared option definitions for agent modules.
|
||||
# Prevents copy-pasting the externalSkills submodule across opencode/claude-code/pi.
|
||||
{lib}: let
|
||||
inherit (lib) mkOption mkEnableOption types literalExpression;
|
||||
in {
|
||||
# Common agentsInput option used by all agent modules.
|
||||
mkAgentsInputOption = description: mkOption {
|
||||
type = types.nullOr types.anything;
|
||||
default = null;
|
||||
inherit description;
|
||||
};
|
||||
|
||||
# Common modelOverrides option.
|
||||
mkModelOverridesOption = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
description = ''
|
||||
Per-agent model overrides. Maps agent slug to model string.
|
||||
Example: { chiron = "anthropic/claude-sonnet-4"; }
|
||||
'';
|
||||
example = literalExpression ''
|
||||
{
|
||||
chiron = "anthropic/claude-sonnet-4";
|
||||
"chiron-forge" = "anthropic/claude-sonnet-4";
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
# External skills submodule — used by opencode, claude-code, and pi modules.
|
||||
externalSkillsOption = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
src = mkOption {
|
||||
type = types.anything;
|
||||
description = "Flake input pointing to a skills repository root.";
|
||||
};
|
||||
skillsDir = mkOption {
|
||||
type = types.str;
|
||||
default = "skills";
|
||||
description = ''
|
||||
Subdirectory inside src that contains skill folders.
|
||||
'';
|
||||
};
|
||||
selectSkills = mkOption {
|
||||
type = types.nullOr (types.listOf types.str);
|
||||
default = null;
|
||||
description = ''
|
||||
List of skill names to cherry-pick from this source.
|
||||
null means include every skill found in skillsDir.
|
||||
'';
|
||||
};
|
||||
};
|
||||
});
|
||||
default = [];
|
||||
description = ''
|
||||
External skill sources passed to mkOpencodeSkills.
|
||||
Each entry maps directly to an element of the externalSkills
|
||||
list accepted by the AGENTS flake's lib.mkOpencodeSkills.
|
||||
'';
|
||||
example = literalExpression ''
|
||||
[
|
||||
{ src = inputs.skills-anthropic; selectSkills = [ "claude-api" ]; }
|
||||
{ src = inputs.basecamp; }
|
||||
]
|
||||
'';
|
||||
};
|
||||
|
||||
# Helper to map externalSkills from module config to mkOpencodeSkills format.
|
||||
mapExternalSkills = cfgEntries:
|
||||
map (
|
||||
entry:
|
||||
{inherit (entry) src skillsDir;}
|
||||
// lib.optionalAttrs (entry.selectSkills != null) {inherit (entry) selectSkills;}
|
||||
) cfgEntries;
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
{inputs, ...}: {
|
||||
# This one brings our custom packages from the 'pkgs' directory
|
||||
additions = final: prev:
|
||||
(import ../pkgs {pkgs = final;})
|
||||
# // (inputs.hyprpanel.overlay final prev)
|
||||
// {rose-pine-hyprcursor = inputs.rose-pine-hyprcursor.packages.${prev.stdenv.hostPlatform.system}.default;};
|
||||
|
||||
# This one contains whatever you want to overlay
|
||||
# You can change versions, add patches, set compilation flags, anything really.
|
||||
# https://nixos.wiki/wiki/Overlays
|
||||
modifications = final: prev:
|
||||
# Import all package modifications from mods directory
|
||||
(import ./mods/default.nix {inherit prev;})
|
||||
// {
|
||||
# Direct configuration overrides
|
||||
brave = prev.brave.override {
|
||||
commandLineArgs = "--password-store=gnome-libsecret";
|
||||
};
|
||||
|
||||
# nodejs_24 = inputs.nixpkgs-stable.legacyPackages.${prev.system}.nodejs_24;
|
||||
# paperless-ngx = inputs.nixpkgs-45570c2.legacyPackages.${prev.system}.paperless-ngx;
|
||||
# anytype-heart = inputs.nixpkgs-9e58ed7.legacyPackages.${prev.system}.anytype-heart;
|
||||
# trezord = inputs.nixpkgs-2744d98.legacyPackages.${prev.system}.trezord;
|
||||
# mesa = inputs.nixpkgs-master.legacyPackages.${prev.system}.mesa;
|
||||
# hyprpanel = inputs.hyprpanel.packages.${prev.system}.default.overrideAttrs (prev: {
|
||||
# version = "latest"; # or whatever version you want
|
||||
# src = final.fetchFromGitHub {
|
||||
# owner = "Jas-SinghFSU";
|
||||
# repo = "HyprPanel";
|
||||
# rev = "master"; # or a specific commit hash
|
||||
# hash = "sha256-l623fIVhVCU/ylbBmohAtQNbK0YrWlEny0sC/vBJ+dU=";
|
||||
# };
|
||||
# });
|
||||
};
|
||||
|
||||
temp-packages = final: _prev: {
|
||||
temp = import inputs.nixpkgs-9e9486b {
|
||||
system = final.stdenv.hostPlatform.system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
};
|
||||
|
||||
stable-packages = final: _prev: {
|
||||
stable = import inputs.nixpkgs-stable {
|
||||
system = final.stdenv.hostPlatform.system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
};
|
||||
|
||||
pinned-packages = final: _prev: {
|
||||
pinned = import inputs.nixpkgs-9472de4 {
|
||||
system = final.stdenv.hostPlatform.system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
};
|
||||
|
||||
locked-packages = final: _prev: {
|
||||
locked = import inputs.nixpkgs-locked {
|
||||
system = final.stdenv.hostPlatform.system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
};
|
||||
|
||||
master-packages = final: _prev: {
|
||||
master = import inputs.nixpkgs-master {
|
||||
system = final.stdenv.hostPlatform.system;
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
{prev}:
|
||||
prev.beads.overrideAttrs (oldAttrs: rec {
|
||||
version = "0.47.1";
|
||||
|
||||
src = prev.fetchFromGitHub {
|
||||
owner = "steveyegge";
|
||||
repo = "beads";
|
||||
tag = "v${version}";
|
||||
hash = "sha256-DwIR/r1TJnpVd/CT1E2OTkAjU7k9/KHbcVwg5zziFVg=";
|
||||
};
|
||||
|
||||
vendorHash = "sha256-pY5m5ODRgqghyELRwwxOr+xlW41gtJWLXaW53GlLaFw=";
|
||||
|
||||
# Tests require git worktree operations that fail in Nix sandbox
|
||||
doCheck = false;
|
||||
})
|
||||
@@ -2,9 +2,6 @@
|
||||
# Package modifications
|
||||
# This overlay contains package overrides and modifications
|
||||
|
||||
# n8n = import ./n8n.nix {inherit prev;};
|
||||
# beads = import ./beads.nix {inherit prev;};
|
||||
|
||||
# Add more modifications here as needed
|
||||
# example-package = prev.example-package.override { ... };
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
{prev}:
|
||||
prev.n8n.overrideAttrs (oldAttrs: rec {
|
||||
version = "2.4.1";
|
||||
|
||||
src = prev.fetchFromGitHub {
|
||||
owner = "n8n-io";
|
||||
repo = "n8n";
|
||||
rev = "n8n@${version}";
|
||||
hash = "sha256-EQP9ZI8kt30SUYE1+/UUpxQXpavzKqDu8qE24zsNifg=";
|
||||
};
|
||||
|
||||
pnpmDeps = prev.pnpm_10.fetchDeps {
|
||||
pname = oldAttrs.pname;
|
||||
inherit version src;
|
||||
fetcherVersion = 1;
|
||||
hash = "sha256-Q30IuFEQD3896Hg0HCLd38YE2i8fJn74JY0o95LKJis=";
|
||||
};
|
||||
})
|
||||
@@ -3,6 +3,7 @@
|
||||
inputs,
|
||||
...
|
||||
}: let
|
||||
# Used only for flake input pass-throughs (basecamp, openspec, opencode-desktop)
|
||||
system = pkgs.stdenv.hostPlatform.system;
|
||||
in {
|
||||
# Custom packages registry
|
||||
|
||||
@@ -8,10 +8,10 @@
|
||||
nix-update-script,
|
||||
}: let
|
||||
pname = "eigent";
|
||||
version = "0.0.89";
|
||||
version = "0.0.90";
|
||||
src = fetchurl {
|
||||
url = "https://github.com/eigent-ai/eigent/releases/download/v${version}/Eigent-${version}.AppImage";
|
||||
hash = "sha256-9KuiFjegfXhCu1W/FCinWX4ae/DsNPudeBcXFfW18Hc=";
|
||||
hash = "sha256-mwCBx+D6mgGqQa8bDuUpo3h49EwFVkwasJwaYc6aXFE=";
|
||||
};
|
||||
appimageContents = appimageTools.extractType2 {inherit pname version src;};
|
||||
in
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
node-gyp,
|
||||
cctools,
|
||||
xcbuild,
|
||||
dart-sass,
|
||||
libkrb5,
|
||||
libmongocrypt,
|
||||
libpq,
|
||||
@@ -25,20 +26,20 @@
|
||||
in
|
||||
stdenv.mkDerivation (finalAttrs: {
|
||||
pname = "n8n";
|
||||
version = "stable";
|
||||
version = "2.16.1";
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "n8n-io";
|
||||
repo = "n8n";
|
||||
tag = "${finalAttrs.version}";
|
||||
hash = "sha256-/atba0ymCqhh5Rt61UxwC2xf8SGrRsEKtlsDCIkg37Y=";
|
||||
tag = "n8n@${finalAttrs.version}";
|
||||
hash = "sha256-5y00RY8WWVgpxC3TNPFS9XxshgZKTlShpw+HiJVQvmM=";
|
||||
};
|
||||
|
||||
pnpmDeps = fetchPnpmDeps {
|
||||
inherit (finalAttrs) pname version src;
|
||||
pnpm = pnpm_10;
|
||||
fetcherVersion = 3;
|
||||
hash = "sha256-YGplNNvIOIY1BthWmejAzucXujq8AkgPJus774GmWCA=";
|
||||
hash = "sha256-qyD+zlsBiJLwrazEclVkDmUp+wAxvdH3P6oWpmiX5rc=";
|
||||
};
|
||||
|
||||
nativeBuildInputs =
|
||||
@@ -61,6 +62,17 @@ in
|
||||
libpq
|
||||
];
|
||||
|
||||
preBuild = ''
|
||||
# Force sass-embedded to use our dart-sass instead of bundled binaries.
|
||||
# The bundled Dart binary can't run in the Nix sandbox (no /lib64/ld-linux-x86-64.so.2).
|
||||
for dep in node_modules/.pnpm/sass-embedded@*; do
|
||||
substituteInPlace "$dep/node_modules/sass-embedded/dist/lib/src/compiler-path.js" \
|
||||
--replace-fail \
|
||||
'compilerCommand = (() => {' \
|
||||
'compilerCommand = (() => { return ["${lib.getExe dart-sass}"];'
|
||||
done
|
||||
'';
|
||||
|
||||
buildPhase = ''
|
||||
runHook preBuild
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
# Upstream is missing outputHashes for git dependencies
|
||||
# Also fix stale npm deps hash in upstream node_modules FOD
|
||||
fixedNodeModules = opencode.node_modules.overrideAttrs {
|
||||
outputHash = "sha256-LRhPPrOKCGUSCEWTpAxPdWKTKVNkg82WrvD25cP3jts=";
|
||||
outputHash = "sha256-285KZ7rZLRoc6XqCZRHc25NE+mmpGh/BVeMpv8aPQtQ=";
|
||||
};
|
||||
|
||||
opencode-desktop = rustPlatform.buildRustPackage (finalAttrs: {
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
lib,
|
||||
}: let
|
||||
pname = "vibetyper";
|
||||
version = "1.2.2";
|
||||
version = "1.2.3";
|
||||
src = fetchurl {
|
||||
url = "https://cdn.vibetyper.com/releases/linux/VibeTyper.AppImage";
|
||||
sha256 = "sha256-AUjrSVxyaI8Ok4pnoqaW4fGAd4GtSc0mEjDhkqdifY0=";
|
||||
sha256 = "sha256-6uGXw2nxb0sGkcMDTWBlL3PuwBfVodhgqfgZT1Ncs40=";
|
||||
};
|
||||
appimageContents = appimageTools.extractType2 {inherit pname version src;};
|
||||
in
|
||||
|
||||
26
tests/lib/agents-test.nix
Normal file
26
tests/lib/agents-test.nix
Normal file
@@ -0,0 +1,26 @@
|
||||
let
|
||||
lib = import <nixpkgs/lib>;
|
||||
agentsLib = (import ../../lib {inherit lib;}).agents;
|
||||
|
||||
# Test 1: renderForTool throws for unknown tools
|
||||
testUnknownTool = let
|
||||
result = builtins.tryEval (
|
||||
agentsLib.renderForTool {
|
||||
pkgs = {};
|
||||
agentsInput = {};
|
||||
tool = "unknown-tool";
|
||||
}
|
||||
);
|
||||
in
|
||||
assert result.success == false; {result = "pass";};
|
||||
|
||||
# Test 2: loadCanonical extracts loadAgents from input
|
||||
testLoadCanonical = let
|
||||
fakeInput = {lib.loadAgents = {test = {description = "test";};};};
|
||||
result = agentsLib.loadCanonical {agentsInput = fakeInput;};
|
||||
in
|
||||
assert result == {test = {description = "test";};}; {result = "pass";};
|
||||
in {
|
||||
unknown-tool-throws = testUnknownTool;
|
||||
load-canonical = testLoadCanonical;
|
||||
}
|
||||
48
tests/lib/coding-rules-test.nix
Normal file
48
tests/lib/coding-rules-test.nix
Normal file
@@ -0,0 +1,48 @@
|
||||
let
|
||||
lib = import <nixpkgs/lib>;
|
||||
codingRulesLib = (import ../../lib {inherit lib;}).coding-rules;
|
||||
|
||||
# Test 1: instructions are generated correctly with custom rulesDir
|
||||
testInstructions = let
|
||||
rules = codingRulesLib.mkCodingRules {
|
||||
agents = "/tmp/fake-agents";
|
||||
languages = ["python"];
|
||||
concerns = ["naming"];
|
||||
rulesDir = ".coding-rules";
|
||||
};
|
||||
in
|
||||
assert rules.instructions
|
||||
== [
|
||||
".coding-rules/concerns/naming.md"
|
||||
".coding-rules/languages/python.md"
|
||||
]; {result = "pass";};
|
||||
|
||||
# Test 2: default rulesDir is .opencode-rules
|
||||
testDefaultRulesDir = let
|
||||
rules = codingRulesLib.mkCodingRules {
|
||||
agents = "/tmp/fake-agents";
|
||||
};
|
||||
hasCorrectPrefix = builtins.all (s: builtins.substring 0 15 s == ".opencode-rules") rules.instructions;
|
||||
in
|
||||
assert hasCorrectPrefix == true; {result = "pass";};
|
||||
|
||||
# Test 3: backward-compat alias exists
|
||||
testBackwardCompat = assert codingRulesLib.mkOpencodeRules == codingRulesLib.mkCodingRules; {result = "pass";};
|
||||
|
||||
# Test 4: shellHook contains both the symlink command and the config generation
|
||||
testShellHook = let
|
||||
rules = codingRulesLib.mkCodingRules {
|
||||
agents = "/tmp/fake-agents";
|
||||
};
|
||||
hook = rules.shellHook;
|
||||
hasSymlink = builtins.match ".*ln -sfn.*" hook != null;
|
||||
hasConfigGen = builtins.match ".*coding-rules.json.*" hook != null;
|
||||
in
|
||||
assert hasSymlink;
|
||||
assert hasConfigGen; {result = "pass";};
|
||||
in {
|
||||
instructions-correct = testInstructions;
|
||||
default-rules-dir = testDefaultRulesDir;
|
||||
backward-compat = testBackwardCompat;
|
||||
shell-hook = testShellHook;
|
||||
}
|
||||
4
tests/lib/default.nix
Normal file
4
tests/lib/default.nix
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
coding-rules = import ./coding-rules-test.nix;
|
||||
agents = import ./agents-test.nix;
|
||||
}
|
||||
Reference in New Issue
Block a user