# Multi-Agent Portability
OSK is agent-agnostic at the skill layer. Every `osk-*` skill is pure markdown plus frontmatter with no SDK dependency. v4.0.2 makes that real for hook execution too: same bash scripts under `.claude/hooks/`, three different config files per supported agent.
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` | `$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).
- Hook scripts under `.claude/hooks/`. Bash plus `jq`. No Node or Python runtime dependency. Each agent's hook config calls these same scripts.
- 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.
## 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 |
| Native dependencies | none | none | none | none |
Adding a new hook means writing the bash script once under `.claude/hooks/`, 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.
- Gemini's `BeforeTool` does not have an exact `if: "Bash(git *)"` matcher equivalent in some versions. The git-block hook may need a re-implemented gate inside the script body when running under Gemini.
- The PreCompact backup hook works across Claude, Codex, and Gemini because the hook script 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.