Compare commits
2 Commits
bc41c9a428
...
57ebad1358
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57ebad1358 | ||
|
|
35f4821bc5 |
@@ -126,12 +126,11 @@ Harness-agnostic agent management. Reads canonical `agent.toml` +
|
|||||||
### `lib.coding-rules`
|
### `lib.coding-rules`
|
||||||
|
|
||||||
Coding rules injection. Generates `coding-rules.json` + symlinks rules from
|
Coding rules injection. Generates `coding-rules.json` + symlinks rules from
|
||||||
the AGENTS repository. The old `lib.opencode-rules` name still works.
|
the AGENTS repository.
|
||||||
|
|
||||||
| Function | Purpose |
|
| Function | Purpose |
|
||||||
|----------|--------|
|
|----------|--------|
|
||||||
| `mkCodingRules { agents, languages, concerns, frameworks, rulesDir }` | Generate rules config + shellHook. `rulesDir` defaults to `.opencode-rules` |
|
| `mkCodingRules { agents, languages, concerns, frameworks, rulesDir }` | Generate rules config + shellHook. `rulesDir` defaults to `.opencode-rules` |
|
||||||
| `mkOpencodeRules` | Backward-compat alias for `mkCodingRules` |
|
|
||||||
|
|
||||||
## PORT MANAGEMENT
|
## PORT MANAGEMENT
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/).
|
|||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
- Dead overlay entries for non-existent flake inputs
|
- Dead overlay entries for non-existent flake inputs
|
||||||
|
- Legacy `mkOpencodeRules` alias and `lib.opencode-rules` backward-compat entry (use `mkCodingRules` / `lib.coding-rules`)
|
||||||
|
|
||||||
## [0.4.0] - 2026-04-15
|
## [0.4.0] - 2026-04-15
|
||||||
|
|
||||||
|
|||||||
@@ -112,9 +112,6 @@
|
|||||||
RULES_EOF
|
RULES_EOF
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Backward-compat alias
|
|
||||||
mkOpencodeRules = mkCodingRules;
|
|
||||||
in {
|
in {
|
||||||
inherit mkCodingRules mkOpencodeRules;
|
inherit mkCodingRules;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,12 +7,9 @@
|
|||||||
# Port management utilities
|
# Port management utilities
|
||||||
ports = import ./ports.nix {inherit lib;};
|
ports = import ./ports.nix {inherit lib;};
|
||||||
|
|
||||||
# Coding rules injection utilities (renamed from opencode-rules)
|
# Coding rules injection utilities
|
||||||
coding-rules = import ./coding-rules.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;};
|
|
||||||
|
|
||||||
# Agent configuration management utilities
|
# Agent configuration management utilities
|
||||||
agents = import ./agents.nix {inherit lib;};
|
agents = import ./agents.nix {inherit lib;};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ The agent system was migrated from embedded `agents.json` to file-based canonica
|
|||||||
| `coding.opencode.externalSkills` | `coding.agents.opencode.externalSkills` |
|
| `coding.opencode.externalSkills` | `coding.agents.opencode.externalSkills` |
|
||||||
| Agents embedded in `config.json` | File-based `~/.config/opencode/agents/*.md` |
|
| Agents embedded in `config.json` | File-based `~/.config/opencode/agents/*.md` |
|
||||||
| Model hardcoded in `agents.json` | Per-machine `modelOverrides` |
|
| Model hardcoded in `agents.json` | Per-machine `modelOverrides` |
|
||||||
| `mkOpencodeRules` | `mkCodingRules` (old name still works) |
|
| `mkOpencodeRules` | `mkCodingRules` |
|
||||||
|
|
||||||
### Migration steps
|
### Migration steps
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,39 @@
|
|||||||
# Per-tool agent sub-modules
|
# Per-tool agent sub-modules
|
||||||
# Each module handles rendering canonical agent.toml definitions
|
# Each module handles rendering canonical agent.toml definitions
|
||||||
# for a specific AI coding tool.
|
# for a specific AI coding tool.
|
||||||
|
#
|
||||||
|
# Also provides the shared coding.agents.skills submodule that writes
|
||||||
|
# ~/.agents/skills — the central skills directory used by Pi, OpenCode, etc.
|
||||||
{
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
shared = import ./shared-options.nix {inherit lib;};
|
||||||
|
cfg = config.coding.agents.skills;
|
||||||
|
mkIf = lib.mkIf;
|
||||||
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
./opencode.nix
|
./opencode.nix
|
||||||
./claude-code.nix
|
./claude-code.nix
|
||||||
./pi.nix
|
./pi.nix
|
||||||
];
|
];
|
||||||
|
|
||||||
|
options.coding.agents.skills = {
|
||||||
|
agentsInput = shared.mkAgentsInputOption ''
|
||||||
|
The `agents` flake input (your personal AGENTS repo).
|
||||||
|
When set, skills are symlinked to ~/.agents/skills.
|
||||||
|
'';
|
||||||
|
|
||||||
|
externalSkills = shared.externalSkillsOption;
|
||||||
|
};
|
||||||
|
|
||||||
|
config = mkIf (cfg.agentsInput != null) {
|
||||||
|
home.file.".agents/skills".source = cfg.agentsInput.lib.mkOpencodeSkills {
|
||||||
|
inherit pkgs;
|
||||||
|
customSkills = "${cfg.agentsInput}/skills";
|
||||||
|
externalSkills = shared.mapExternalSkills cfg.externalSkills;
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,8 +17,6 @@ in
|
|||||||
'';
|
'';
|
||||||
|
|
||||||
modelOverrides = shared.mkModelOverridesOption;
|
modelOverrides = shared.mkModelOverridesOption;
|
||||||
|
|
||||||
externalSkills = shared.externalSkillsOption;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = mkIf config.coding.agents.opencode.enable {
|
config = mkIf config.coding.agents.opencode.enable {
|
||||||
@@ -34,18 +32,6 @@ in
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# Skills (merged from personal AGENTS repo + optional external skills)
|
|
||||||
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 = shared.mapExternalSkills cfg.externalSkills;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
# Static config dirs from AGENTS repo
|
# Static config dirs from AGENTS repo
|
||||||
xdg.configFile."opencode/context" = let
|
xdg.configFile."opencode/context" = let
|
||||||
cfg = config.coding.agents.opencode;
|
cfg = config.coding.agents.opencode;
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ in
|
|||||||
|
|
||||||
mcpServers = mkOption {
|
mcpServers = mkOption {
|
||||||
type = types.attrsOf types.anything;
|
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";
|
defaultText = literalExpression "config.programs.mcp.servers";
|
||||||
description = ''
|
description = ''
|
||||||
MCP server configurations for Pi (pi-mcp-adapter).
|
MCP server configurations for Pi (pi-mcp-adapter).
|
||||||
@@ -41,8 +44,6 @@ in
|
|||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
externalSkills = shared.externalSkillsOption;
|
|
||||||
|
|
||||||
settings = mkOption {
|
settings = mkOption {
|
||||||
type = types.submodule {
|
type = types.submodule {
|
||||||
freeformType = types.attrsOf types.anything;
|
freeformType = types.attrsOf types.anything;
|
||||||
@@ -156,8 +157,11 @@ in
|
|||||||
then let
|
then let
|
||||||
filtered = filterNulls v;
|
filtered = filterNulls v;
|
||||||
in
|
in
|
||||||
if filtered == {} then null else filtered
|
if filtered == {}
|
||||||
else v) attrs
|
then null
|
||||||
|
else filtered
|
||||||
|
else v)
|
||||||
|
attrs
|
||||||
);
|
);
|
||||||
|
|
||||||
piSettings = filterNulls cfg.settings;
|
piSettings = filterNulls cfg.settings;
|
||||||
@@ -177,17 +181,16 @@ in
|
|||||||
# Dynamic home.file entries for agent .md files
|
# Dynamic home.file entries for agent .md files
|
||||||
agentFiles =
|
agentFiles =
|
||||||
if cfg.agentsInput != null
|
if cfg.agentsInput != null
|
||||||
then
|
then let
|
||||||
let
|
agentNames = builtins.attrNames cfg.agentsInput.lib.loadAgents;
|
||||||
agentNames = builtins.attrNames cfg.agentsInput.lib.loadAgents;
|
in
|
||||||
in
|
builtins.listToAttrs (
|
||||||
builtins.listToAttrs (
|
map (name: {
|
||||||
map (name: {
|
name = ".pi/agent/agents/${name}.md";
|
||||||
name = ".pi/agent/agents/${name}.md";
|
value = {source = "${rendered}/agents/${name}.md";};
|
||||||
value = {source = "${rendered}/agents/${name}.md";};
|
})
|
||||||
})
|
agentNames
|
||||||
agentNames
|
)
|
||||||
)
|
|
||||||
else {};
|
else {};
|
||||||
in {
|
in {
|
||||||
home.file = mkMerge [
|
home.file = mkMerge [
|
||||||
@@ -213,15 +216,6 @@ in
|
|||||||
|
|
||||||
# ── Agents — pi-subagents .md files ────────────────────────────
|
# ── Agents — pi-subagents .md files ────────────────────────────
|
||||||
agentFiles
|
agentFiles
|
||||||
|
|
||||||
# ── 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;
|
|
||||||
};
|
|
||||||
})
|
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,12 @@
|
|||||||
inherit (lib) mkOption mkEnableOption types literalExpression;
|
inherit (lib) mkOption mkEnableOption types literalExpression;
|
||||||
in {
|
in {
|
||||||
# Common agentsInput option used by all agent modules.
|
# Common agentsInput option used by all agent modules.
|
||||||
mkAgentsInputOption = description: mkOption {
|
mkAgentsInputOption = description:
|
||||||
type = types.nullOr types.anything;
|
mkOption {
|
||||||
default = null;
|
type = types.nullOr types.anything;
|
||||||
inherit description;
|
default = null;
|
||||||
};
|
inherit description;
|
||||||
|
};
|
||||||
|
|
||||||
# Common modelOverrides option.
|
# Common modelOverrides option.
|
||||||
mkModelOverridesOption = mkOption {
|
mkModelOverridesOption = mkOption {
|
||||||
@@ -62,7 +63,7 @@ in {
|
|||||||
{ src = inputs.skills-anthropic; selectSkills = [ "claude-api" ]; }
|
{ src = inputs.skills-anthropic; selectSkills = [ "claude-api" ]; }
|
||||||
{ src = inputs.basecamp; }
|
{ src = inputs.basecamp; }
|
||||||
]
|
]
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
# Helper to map externalSkills from module config to mkOpencodeSkills format.
|
# Helper to map externalSkills from module config to mkOpencodeSkills format.
|
||||||
@@ -71,5 +72,6 @@ in {
|
|||||||
entry:
|
entry:
|
||||||
{inherit (entry) src skillsDir;}
|
{inherit (entry) src skillsDir;}
|
||||||
// lib.optionalAttrs (entry.selectSkills != null) {inherit (entry) selectSkills;}
|
// lib.optionalAttrs (entry.selectSkills != null) {inherit (entry) selectSkills;}
|
||||||
) cfgEntries;
|
)
|
||||||
|
cfgEntries;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# OpenCode development environment with AI coding rules
|
# OpenCode development environment with AI coding rules
|
||||||
# This shell demonstrates the mkOpencodeRules library provided by this repository
|
# This shell demonstrates the mkCodingRules library provided by this repository
|
||||||
# Usage: nix develop .#opencode
|
# Usage: nix develop .#opencode
|
||||||
#
|
#
|
||||||
# To enable OpenCode rules, add the agents input to your flake:
|
# To enable OpenCode rules, add the agents input to your flake:
|
||||||
@@ -13,16 +13,16 @@
|
|||||||
inputs ? null,
|
inputs ? null,
|
||||||
agents ? null,
|
agents ? null,
|
||||||
}: let
|
}: let
|
||||||
# Import the opencode-rules library
|
# Import the coding-rules library
|
||||||
m3taLib = import ../lib {lib = pkgs.lib;};
|
m3taLib = import ../lib {lib = pkgs.lib;};
|
||||||
|
|
||||||
# Import custom packages
|
# Import custom packages
|
||||||
customPackages = import ../pkgs {inherit pkgs inputs;};
|
customPackages = import ../pkgs {inherit pkgs inputs;};
|
||||||
|
|
||||||
# Create rules configuration only if agents input is provided
|
# Create rules configuration only if agents input is provided
|
||||||
# This demonstrates how to use mkOpencodeRules in a real project
|
# This demonstrates how to use mkCodingRules in a real project
|
||||||
rulesConfig = lib.optionalAttrs (agents != null) {
|
rulesConfig = lib.optionalAttrs (agents != null) {
|
||||||
rules = m3taLib.opencode-rules.mkOpencodeRules {
|
rules = m3taLib.coding-rules.mkCodingRules {
|
||||||
# Pass the AGENTS repository path
|
# Pass the AGENTS repository path
|
||||||
inherit agents;
|
inherit agents;
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ in
|
|||||||
shellHook = ''
|
shellHook = ''
|
||||||
echo "🤖 OpenCode Development Environment"
|
echo "🤖 OpenCode Development Environment"
|
||||||
echo ""
|
echo ""
|
||||||
echo "This environment demonstrates the mkOpencodeRules library"
|
echo "This environment demonstrates the mkCodingRules library"
|
||||||
echo "provided by the m3ta-nixpkgs repository."
|
echo "provided by the m3ta-nixpkgs repository."
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ in
|
|||||||
${
|
${
|
||||||
if (agents == null)
|
if (agents == null)
|
||||||
then ''
|
then ''
|
||||||
echo "💡 Using mkOpencodeRules in your project:"
|
echo "💡 Using mkCodingRules in your project:"
|
||||||
echo ""
|
echo ""
|
||||||
echo "Add to your flake.nix:"
|
echo "Add to your flake.nix:"
|
||||||
echo " inputs = {"
|
echo " inputs = {"
|
||||||
@@ -137,7 +137,7 @@ in
|
|||||||
echo " system = \"x86_64-linux\";"
|
echo " system = \"x86_64-linux\";"
|
||||||
echo " pkgs = nixpkgs.legacyPackages.''${system};"
|
echo " pkgs = nixpkgs.legacyPackages.''${system};"
|
||||||
echo " m3taLib = m3ta-nixpkgs.lib.''${system};"
|
echo " m3taLib = m3ta-nixpkgs.lib.''${system};"
|
||||||
echo " rules = m3taLib.opencode-rules.mkOpencodeRules {"
|
echo " rules = m3taLib.coding-rules.mkCodingRules {
|
||||||
echo " inherit agents;"
|
echo " inherit agents;"
|
||||||
echo " languages = [\"python\" \"typescript\"];"
|
echo " languages = [\"python\" \"typescript\"];"
|
||||||
echo " frameworks = [\"n8n\"];"
|
echo " frameworks = [\"n8n\"];"
|
||||||
|
|||||||
@@ -26,10 +26,7 @@ let
|
|||||||
in
|
in
|
||||||
assert hasCorrectPrefix == true; {result = "pass";};
|
assert hasCorrectPrefix == true; {result = "pass";};
|
||||||
|
|
||||||
# Test 3: backward-compat alias exists
|
# Test 3: shellHook contains both the symlink command and the config generation
|
||||||
testBackwardCompat = assert codingRulesLib.mkOpencodeRules == codingRulesLib.mkCodingRules; {result = "pass";};
|
|
||||||
|
|
||||||
# Test 4: shellHook contains both the symlink command and the config generation
|
|
||||||
testShellHook = let
|
testShellHook = let
|
||||||
rules = codingRulesLib.mkCodingRules {
|
rules = codingRulesLib.mkCodingRules {
|
||||||
agents = "/tmp/fake-agents";
|
agents = "/tmp/fake-agents";
|
||||||
@@ -43,6 +40,5 @@ let
|
|||||||
in {
|
in {
|
||||||
instructions-correct = testInstructions;
|
instructions-correct = testInstructions;
|
||||||
default-rules-dir = testDefaultRulesDir;
|
default-rules-dir = testDefaultRulesDir;
|
||||||
backward-compat = testBackwardCompat;
|
|
||||||
shell-hook = testShellHook;
|
shell-hook = testShellHook;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user