diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..ce2bbc6 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,32 @@ +# Agent Instructions + +## Platform-agnostic development + +Everything in this repository MUST work on every agent runtime, not only on +the one developing it: Claude Code, Codex, Gemini CLI, Hermes, OpenClaw and +any other that reads skills. The same holds for operating systems and +distributions. + +- **Logic in scripts**: behaviour lives in `python3` or `bash` scripts that + any runtime can call. Hooks, plugins and settings of one runtime are thin + adapters over those scripts, never the only path to a feature. +- **Skills stay portable**: a `SKILL.md` that uses a runtime-specific tool + (`AskUserQuestion`, `SendMessage`, a slash command) says what the step + needs, so another runtime can use its own equivalent. +- **Installs reach every runtime**: install into the cross-runtime locations + (`~/.agents/skills`) or through an installer that configures every + detected agent; runtime-specific locations are mirrors. Of a tool that + ships both, take the agent-agnostic integration over one runtime's plugin, + and never both: the same server would run twice. +- **No single package manager**: an install never depends on one OS or + distribution's package manager; prefer upstream or statically linked + release builds. +- **One instruction file**: rules live here and nowhere else; no + `CLAUDE.md`, `CLAUDE.local.md` or `GEMINI.md`. Claude Code reads this file + natively from v2.1.277; Gemini CLI once its `context.fileName` setting + lists `AGENTS.md`. + +## Code questions + +Ask the codebase-memory-mcp graph first (`search_graph`, `trace_path`, +`get_architecture`); grep only after it. diff --git a/skills/kvb-agent-optimize/SKILL.md b/skills/kvb-agent-optimize/SKILL.md index ddc0ca8..8dc04a5 100644 --- a/skills/kvb-agent-optimize/SKILL.md +++ b/skills/kvb-agent-optimize/SKILL.md @@ -15,8 +15,8 @@ scope: the current one, or those `kvb-optimize` hands over. ## Step 1: inventory `${CLAUDE_SKILL_DIR}/scripts/agents.py --repo ` prints one line per -check: AGENTS.md, whether CLAUDE.md and GEMINI.md point to it, dead relative -links in it, whether it names the index, whether the index binary is +check: AGENTS.md, any runtime-specific instruction file beside it, dead +relative links in it, whether it names the index, whether the index binary is installed, and the state of the shared snapshot `.codebase-memory/graph.db.zst`. @@ -48,8 +48,11 @@ installed, and the state of the shared snapshot ## Step 3: instructions -- AGENTS.md is the single source; CLAUDE.md and GEMINI.md only point to it - (`@AGENTS.md`). +- AGENTS.md is the only instruction file: fold any `CLAUDE.md`, + `.claude/CLAUDE.md`, `CLAUDE.local.md` or `GEMINI.md` into it and remove + them. Claude Code reads AGENTS.md natively (v2.1.277+) but skips it while a + `CLAUDE.md` is on the path; Gemini CLI reads it once `context.fileName` + lists it. - AGENTS.md sends code questions to the graph first (`search_graph`, `trace_path`, `get_architecture`) and to grep only after it. - `/claude-api prompt-audit` over AGENTS.md and the files it references finds diff --git a/skills/kvb-agent-optimize/scripts/agents.py b/skills/kvb-agent-optimize/scripts/agents.py index 511aa57..57f44f9 100755 --- a/skills/kvb-agent-optimize/scripts/agents.py +++ b/skills/kvb-agent-optimize/scripts/agents.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -"""Report how ready a repository is for agents: instructions, pointers, code index. +"""Report how ready a repository is for agents: instructions, runtime-specific files, code index. Args: --repo: path of the repository. @@ -21,7 +21,7 @@ import subprocess import sys from pathlib import Path -POINTERS = ("CLAUDE.md", "GEMINI.md") +RUNTIME_FILES = ("CLAUDE.md", ".claude/CLAUDE.md", "CLAUDE.local.md", "GEMINI.md") INDEX = "codebase-memory-mcp" SNAPSHOT = ".codebase-memory/graph.db.zst" LINK = re.compile(r"\]\(([^)\s#]+)") @@ -50,11 +50,11 @@ def checks(repo: Path) -> list[tuple[str, str, str]]: agents = repo / "AGENTS.md" text = agents.read_text(encoding="utf-8") if agents.is_file() else "" rows = [("AGENTS.md", "ok" if text else "missing", "single source of the agent instructions")] - for name in POINTERS: - pointer = repo / name - if pointer.is_file(): - points = "AGENTS.md" in pointer.read_text(encoding="utf-8") - rows.append((name, "ok" if points else "drift", f"{'points' if points else 'does not point'} to AGENTS.md")) + rows.extend( + (name, "drift", "runtime-specific; fold into AGENTS.md and remove") + for name in RUNTIME_FILES + if (repo / name).is_file() + ) dead = sorted( { target diff --git a/tests/test_agent_optimize.py b/tests/test_agent_optimize.py index 668babe..7d270e7 100644 --- a/tests/test_agent_optimize.py +++ b/tests/test_agent_optimize.py @@ -1,4 +1,4 @@ -"""Exercise agents.py: instruction pointers, dead links, index pointer, binary and snapshot state.""" +"""Exercise agents.py: runtime-specific files, dead links, index pointer, binary and snapshot state.""" from __future__ import annotations @@ -48,6 +48,9 @@ class TestAgents(unittest.TestCase): ) (repo / "CLAUDE.md").write_text("@AGENTS.md\n", encoding="utf-8") (repo / "GEMINI.md").write_text("own rules\n", encoding="utf-8") + (repo / ".claude").mkdir() + (repo / ".claude" / "CLAUDE.md").write_text("x\n", encoding="utf-8") + (repo / "CLAUDE.local.md").write_text("x\n", encoding="utf-8") (repo / ".codebase-memory").mkdir() (repo / ".codebase-memory" / "graph.db.zst").write_bytes(b"x") (repo / ".gitignore").write_text(".codebase-memory/\n", encoding="utf-8") @@ -59,8 +62,10 @@ class TestAgents(unittest.TestCase): self._report(repo), { "AGENTS.md": ("ok", "single source of the agent instructions"), - "CLAUDE.md": ("ok", "points to AGENTS.md"), - "GEMINI.md": ("drift", "does not point to AGENTS.md"), + "CLAUDE.md": ("drift", "runtime-specific; fold into AGENTS.md and remove"), + ".claude/CLAUDE.md": ("drift", "runtime-specific; fold into AGENTS.md and remove"), + "CLAUDE.local.md": ("drift", "runtime-specific; fold into AGENTS.md and remove"), + "GEMINI.md": ("drift", "runtime-specific; fold into AGENTS.md and remove"), "links": ("drift", "docs/b.md"), "index-pointer": ("ok", "AGENTS.md names codebase-memory-mcp"), "index-binary": ("ok", "codebase-memory-mcp on PATH"),