# Multi-Agent Portability OSK is agent-agnostic at the skill layer. Every `osk-*` skill is pure markdown plus frontmatter with no SDK dependency. Hook execution is shared too: the same bash scripts under `.claude/hooks/`, wired by one config file per supported agent. A few features are Claude Code only; they are listed below. This note documents which agents are supported, what is portable, and what differs per agent. `AGENTS.md` keeps a one-line pointer to here so it does not carry this weight on every session. ## Supported agents | Agent | Conventions file | Hook config | Project-dir env var | Status | |---|---|---|---|---| | Claude Code | `CLAUDE.md` then `AGENTS.md` | `.claude/settings.json` | `$CLAUDE_PROJECT_DIR` | Primary. Fully tested in the OSK author's vault. | | Codex CLI | `AGENTS.md` (read natively) | `.codex/hooks.json` (hooks), `.codex/config.toml` (MCP servers, hooks feature flag) | `$CODEX_PROJECT_DIR` | Configs shipped. Not author-tested. | | Gemini CLI | `GEMINI.md` then `AGENTS.md` | `.gemini/settings.json` | `$GEMINI_PROJECT_DIR` | Configs shipped. Not author-tested. | | GitHub Copilot (IDE) | `AGENTS.md` (read natively in supported IDEs) | none | none | Conventions only. No hook surface. | ## What is portable - Skills under `.claude/skills/`. Markdown plus frontmatter only. Loaded by all agents that support skill catalogs (Claude Code today; Codex and Gemini as their skill mechanisms mature). - Hooks: built into `osk-cli` (`osk-cli hook <name>`), which the OSK plugin ships for every platform, and called through one POSIX `sh` wrapper, `.claude/hooks/osk-hook.sh`. No bash, `jq`, Node or Python dependency. Each agent's hook config calls the same wrapper; Codex and Gemini add `--exit-code` so a deny is exit code 2 with the reason on stderr, which they understand, instead of Claude Code's JSON. - Vault conventions in `AGENTS.md`. Read natively by Claude Code (via `CLAUDE.md`), Codex, Gemini (via `GEMINI.md`), and Copilot in supported IDEs. - Receptionist plus capability registry. Agent-agnostic. Skill names and capabilities never embed an agent identity. - Agent memory write-back. Part of the activation protocol on every agent CLI, not a hook: `osk-agent-activate` step 9 makes each activated agent end its turn by appending to `Agents/<Role>/memory/YYYY-MM-DD.md` (and promoting stable facts to `MEMORY.md`), a plain markdown append that works with the `obsidian` CLI or a direct file write, so Claude Code, Codex, Gemini and Copilot all satisfy it the same way. ## What differs per agent | Surface | Claude Code | Codex CLI | Gemini CLI | Copilot (IDE) | |---|---|---|---|---| | Conventions file | `CLAUDE.md` then `AGENTS.md` | `AGENTS.md` (native) | `GEMINI.md` then `AGENTS.md` | `AGENTS.md` (native) | | Session start event | `SessionStart` | `SessionStart` | `SessionStart` | none | | Pre-tool event | `PreToolUse` | `PreToolUse` | `BeforeTool` | none | | Pre-compaction event | `PreCompact` | `PreCompact` | `PreCompress` | none | | Hook timeout units | seconds | seconds | milliseconds | none | | MCP servers | `.mcp.json` | `.codex/config.toml` (`[mcp_servers.*]`, mirrors `.mcp.json`) | none configured | the IDE's own MCP settings | | ARD mode (skill discovery through the registry) | yes | no | no | no | | Folder guard (`folder-guard`) | yes | no | no | none | | Native dependencies | none | none | none | none | Adding a new hook means writing a script once under `.claude/hooks/` (strict POSIX `sh`, no `jq`; or a new `osk-cli hook` subcommand for a hook that ships with OSK), then wiring it into each agent's config file. The script does not care which agent invoked it. Claude, Codex, and Gemini all pass the same JSON payload shape on stdin (`session_id`, `transcript_path`, `tool_input`, and so on). ## Cross-agent caveats - Hook event names and timeout units differ. Copy-pasting between configs without translation will fail silently. - ARD mode is Claude Code only. It is switched on in `.claude/settings.json` (the `Skill` tool is denied) and by the `ard-mode` SessionStart hook, which injects the discovery protocol. Codex, Gemini and Copilot keep no such deny and get no protocol; they find skills by reading `.claude/skills/*/SKILL.md` when `AGENTS.md` points them to one. Codex has the `ard` server in `.codex/config.toml`, so its tools are callable there, but nothing routes through it by default. - The folder guard (`folder-guard`, blocks commands that reference numbered folders the vault does not have) is wired only in `.claude/settings.json`. Under Codex and Gemini the guard does not run, so the runtime path-resolution rule in `AGENTS.md` is the only protection. - Gemini has no MCP servers configured: `.gemini/settings.json` carries hooks only. To use the vault's servers, add an `mcpServers` object to that file, one entry per server in `.mcp.json` (`httpUrl` plus an `Authorization` header for the HTTP servers, `command` and `args` for the local ones), and keep ports and tokens in sync with `.mcp.json`. - Gemini's `BeforeTool` does not have an exact `if: "Bash(git *)"` matcher equivalent in some versions. Under Gemini the git guard then runs on every shell command, which is fine: it only blocks the dangerous git patterns. - The PreCompact backup hook works across Claude, Codex, and Gemini because the hook reads `transcript_path` from the payload, which all three agents emit (Gemini emits it under the `PreCompress` event). - GitHub Copilot has no hook surface. IDEs do not expose session, compaction, or tool-use lifecycle events to Copilot. Vault conventions via `AGENTS.md` work; the PreCompact backup, dangerous-git blocker, and other automation do not. If you need hook-driven automation, run Copilot alongside Claude Code, Codex, or Gemini, not as a replacement. - Codex, Gemini, and Copilot configs are shipped but not regression-tested in the OSK author's vault. The OSK author runs Claude Code. Verification happens on customer vaults running other agents. Report breakage via the Knowii community channels. ## Adding a new agent When a new CLI agent emerges with hook support: 1. Identify its event name conventions (pre-tool, post-tool, session-start, pre-compaction equivalents) and timeout units. 2. Identify its conventions file (for example `<AGENT>.md`, or whether it reads `AGENTS.md` natively). 3. Identify its project-dir env var. 4. Write a config file mirroring `.codex/hooks.json` or `.gemini/settings.json` shape, mapping event names and reusing the same `.claude/hooks/*.sh` script paths. 5. If the agent does not read `AGENTS.md` natively, create a one-line `<AGENT>.md` that delegates to `AGENTS.md`. 6. Add a row to the tables above. 7. Update `AGENTS.md` only if the one-line pointer needs to change. Keep the meat here. ## Related - [[AI Assistant Architecture]] - [[AI Assistant Capabilities]] - The vault root `AGENTS.md` keeps a one-line pointer here so it does not carry this weight on every session. - [[APM (AI)]]