diff --git a/agents/README.md b/agents/README.md index f8b960fa..99d0eb51 100644 --- a/agents/README.md +++ b/agents/README.md @@ -33,6 +33,8 @@ Current targets: - Codex: `AGENTS.md` -> `${CODEX_HOME:-~/.codex}/AGENTS.md` - OpenCode: `AGENTS.md` -> `${XDG_CONFIG_HOME:-~/.config}/opencode/AGENTS.md` +- Pi: `AGENTS.md` -> `~/.pi/agent/AGENTS.md` +- OMP: `AGENTS.md` -> `~/.omp/agent/AGENTS.md` - Generic cross-tool (read by Kimi Code): `AGENTS.md` -> `~/.agents/AGENTS.md` Behavior: @@ -70,7 +72,7 @@ Ideas worth adopting once a concrete need appears; nothing here is implemented y scripts above do not cover it. - **Shared instructions and skills.** Deploy one rules body plus declared skills to every agent - (Codex, OpenCode, Kimi Code) instead of maintaining a copy per agent. Reference: `mirkolenz/infra` + instead of maintaining a copy per agent. Reference: `mirkolenz/infra` `options/home-manager/agents.nix` (custom `programs.agents`, follows the Agent Skills spec) and `khaneliman/khanelinix` `modules/common/ai-tools/`. - **Single-source permissions.** Keep allow/ask/deny command lists and agent role definitions in one diff --git a/agents/install-cli.md b/agents/install-cli.md index 519dad05..8e9a8115 100644 --- a/agents/install-cli.md +++ b/agents/install-cli.md @@ -10,6 +10,8 @@ Installed via Nix: - opencode - cursor-agent(cli) - kimi-code +- pi +- omp ## Optional tooling diff --git a/agents/install-rules.py b/agents/install-rules.py index 1e2357d1..2f7ab317 100644 --- a/agents/install-rules.py +++ b/agents/install-rules.py @@ -45,10 +45,14 @@ def main() -> int: codex_dir = Path(os.environ.get("CODEX_HOME", "~/.codex")).expanduser() xdg_config_home = Path(os.environ.get("XDG_CONFIG_HOME", "~/.config")).expanduser() opencode_dir = xdg_config_home / "opencode" + pi_dir = Path("~/.pi/agent").expanduser() + omp_dir = Path("~/.omp/agent").expanduser() agents_dir = Path("~/.agents").expanduser() targets = ( (codex_dir, "AGENTS.md"), (opencode_dir, "AGENTS.md"), + (pi_dir, "AGENTS.md"), + (omp_dir, "AGENTS.md"), (agents_dir, "AGENTS.md"), ) failed = False diff --git a/agents/test_install_rules.py b/agents/test_install_rules.py index 45710c43..956816e9 100644 --- a/agents/test_install_rules.py +++ b/agents/test_install_rules.py @@ -1,5 +1,6 @@ import importlib.util import io +import os import tempfile import unittest from pathlib import Path @@ -14,21 +15,44 @@ spec.loader.exec_module(installer) class InstallRulesTests(unittest.TestCase): + def test_main_links_all_supported_agent_targets(self): + with tempfile.TemporaryDirectory() as directory: + home = Path(directory) + target_names = ( + (home / ".codex", "AGENTS.md"), + (home / ".config" / "opencode", "AGENTS.md"), + (home / ".pi" / "agent", "AGENTS.md"), + (home / ".omp" / "agent", "AGENTS.md"), + (home / ".agents", "AGENTS.md"), + ) + for target_dir, _ in target_names: + target_dir.mkdir(parents=True) + + with patch.dict(os.environ, {"HOME": str(home)}, clear=True): + self.assertEqual(installer.main(), 0) + + for target_dir, target_name in target_names: + target = target_dir / target_name + self.assertTrue(target.is_symlink(), target) + self.assertEqual(target.resolve(), installer.Path(__file__).with_name("AGENTS.md")) + def test_target_failure_does_not_stop_remaining_targets(self): with ( patch.object( - installer, "install_one", side_effect=[PermissionError("denied"), None, None] + installer, + "install_one", + side_effect=[PermissionError("denied"), None, None, None, None], ) as install, patch("sys.stderr", new_callable=io.StringIO) as stderr, ): self.assertEqual(installer.main(), 1) - self.assertEqual(install.call_count, 3) + self.assertEqual(install.call_count, 5) self.assertIn("denied", stderr.getvalue()) def test_successful_targets_return_success(self): with patch.object(installer, "install_one") as install: self.assertEqual(installer.main(), 0) - self.assertEqual(install.call_count, 3) + self.assertEqual(install.call_count, 5) def test_existing_file_is_backed_up_without_overwriting_backup(self): with tempfile.TemporaryDirectory() as directory: diff --git a/home/base/gui/dev-tools.nix b/home/base/gui/dev-tools.nix index 49170382..0651c2b3 100644 --- a/home/base/gui/dev-tools.nix +++ b/home/base/gui/dev-tools.nix @@ -14,6 +14,8 @@ cursor-cli opencode kimi-code + pi + omp # Utilities rtk # CLI proxy that reduces LLM token consumption diff --git a/hosts/idols-ai/preservation.nix b/hosts/idols-ai/preservation.nix index 6768d5fc..fcd588d7 100644 --- a/hosts/idols-ai/preservation.nix +++ b/hosts/idols-ai/preservation.nix @@ -159,6 +159,8 @@ in ".config/agents" ".codex" ".kimi-code" + ".pi" + ".omp" ".config/opencode" ".local/share/opencode" ".local/state/opencode" diff --git a/hosts/idols-ruby/packages.nix b/hosts/idols-ruby/packages.nix index 345edbda..3c821f5b 100644 --- a/hosts/idols-ruby/packages.nix +++ b/hosts/idols-ruby/packages.nix @@ -86,6 +86,8 @@ cursor-cli opencode kimi-code + pi + omp # Utilities rtk # CLI proxy that reduces LLM token consumption