Tool Name Conversion in the Compound Engineering Plugin: Mapping Claude Tools to OpenCode, Codex, and Pi
The Compound Engineering Plugin implements a three-step conversion pipeline that normalizes Claude-Code tool identifiers through a canonical mapping table, then generates target-specific definitions for OpenCode permissions, Codex documentation blocks, and Pi-compatible syntax via regex transformations.
The EveryInc/compound-engineering-plugin enables cross-platform compatibility for Claude-Code plugins by converting tool declarations into formats recognized by OpenCode, Codex, and Pi. Understanding this tool name conversion process is essential for developers maintaining multi-platform agent configurations and debugging cross-platform tool behavior.
The Three-Step Tool Name Conversion Pipeline
The plugin processes tool name conversion through a standardized pipeline implemented across three target-specific converters. Each stage ensures that Claude-Code tool references maintain semantic meaning while conforming to platform-specific naming conventions and permission structures.
Step 1: Normalizing Claude Tool Identifiers
The conversion begins in src/converters/claude-to-opencode.ts with the TOOL_MAP constant (lines 24‑39). This record maps raw Claude tool strings to canonical lower-case names that all target platforms recognize.
// src/converters/claude-to-opencode.ts
const TOOL_MAP: Record<string, string> = {
bash: "bash",
read: "read",
write: "write",
edit: "edit",
grep: "grep",
glob: "glob",
list: "list",
webfetch: "webfetch",
skill: "skill",
patch: "patch",
task: "task",
question: "question",
todowrite: "todowrite",
todoread: "todoread",
}
Each Claude identifier is lower-cased and mapped to the canonical name. If a tool is not present in this map, the conversion pipeline treats it as unsupported for cross-platform use.
Step 2: Generating Target-Specific Tool Definitions
After normalization, the pipeline branches into platform-specific generators that create the appropriate configuration structures for each target.
OpenCode Tool Mapping
For OpenCode targets, the applyPermissions function (located in src/converters/claude-to-opencode.ts) constructs a tools record and permission matrix. The normalized names from TOOL_MAP populate both the config.tools flag and the permission clauses (allow/deny), ensuring the OpenCode runtime recognizes which Claude tools correspond to which OpenCode capabilities.
Codex Tool Mapping
Codex conversion relies on static documentation blocks rather than runtime configuration. The ensureCodexAgentsFile function in src/utils/codex-agents.ts (lines 12‑23) generates a managed AGENTS.md block that documents the semantic mapping between Claude tools and Codex behaviors.
// src/utils/codex-agents.ts (excerpt)
Tool mapping:
- Read: use shell reads (cat/sed) or rg
- Write: create files via shell redirection or apply_patch
- Edit/MultiEdit: use apply_patch
- Bash: use shell_command
- Grep: use rg (fallback: grep)
- Glob: use rg --files or find
- LS: use ls via shell_command
- WebFetch/WebSearch: use curl or Context7 for library docs
- AskUserQuestion/Question: ask the user in chat
- Task/Subagent/Parallel: run sequentially in main thread; use multi_tool_use.parallel for tool calls
- TodoWrite/TodoRead: use file‑based todos in todos/ with file‑todos skill
- Skill: open the referenced SKILL.md and follow it
This block enables Codex agents to interpret Claude tool references correctly without native tool support.
Pi Tool Mapping
For Pi targets, the transformContentForPi function in src/converters/claude-to-pi.ts (lines 95‑108) performs regex-based replacements on the command or agent body. This transforms Claude-specific tokens into Pi-compatible syntax.
// src/converters/claude-to-pi.ts (excerpt)
result = result.replace(/\bAskUserQuestion\b/g, "ask_user_question")
result = result.replace(/\bTodoWrite\b/g, "file-based todos (todos/ + /skill:file-todos)")
result = result.replace(/\bTodoRead\b/g, "file-based todos (todos/ + /skill:file-todos)")
These replacements ensure that Pi runners encounter valid syntax when executing converted Claude plugins.
Step 3: Embedding Mappings in Conversion Output
The final stage inserts normalized tool names into platform-specific output structures. Each target converter—claude-to-opencode.ts, claude-to-codex.ts, and claude-to-pi.ts—uses the normalized name when building the final bundle.
- OpenCode: Normalized names populate
config.toolsand permission sections consumed by the OpenCode runtime. - Codex: The
AGENTS.mdblock lives alongside other Codex assets, providing runtime guidance for tool interpretation. - Pi: Transformed bodies with Pi-specific placeholders are written into Pi skill files, with compatibility notes appended when MCP references are detected.
Key Implementation Files
The tool name conversion logic is distributed across the following source files in the EveryInc/compound-engineering-plugin repository:
| Platform | File | Purpose |
|---|---|---|
| OpenCode | src/converters/claude-to-opencode.ts |
Contains the TOOL_MAP constant and applyPermissions function for generating OpenCode tool configurations. |
| Codex | src/utils/codex-agents.ts |
Manages the AGENTS.md block that documents Claude-to-Codex tool semantics (lines 12‑23). |
| Pi | src/converters/claude-to-pi.ts |
Implements transformContentForPi for regex-based body transformations (lines 95‑108). |
| Shared | src/utils/frontmatter.ts |
Formats converted front-matter that includes normalized tool entries across all targets. |
Summary
- The Compound Engineering Plugin uses a three-step pipeline to convert Claude-Code tool names for cross-platform compatibility.
- Normalization occurs via the
TOOL_MAPinsrc/converters/claude-to-opencode.ts, mapping raw identifiers to canonical lower-case names. - OpenCode targets receive tool definitions through the
applyPermissionsfunction, which builds runtime-compatible permission matrices. - Codex targets rely on static documentation in
AGENTS.md(managed bysrc/utils/codex-agents.ts) to interpret Claude tool semantics. - Pi targets undergo regex-based transformation via
transformContentForPiinsrc/converters/claude-to-pi.ts, replacing Claude-specific tokens with Pi-compatible syntax.
Frequently Asked Questions
How does the plugin handle unsupported Claude tools during conversion?
If a Claude tool identifier is not present in the TOOL_MAP constant located in src/converters/claude-to-opencode.ts, the conversion pipeline treats it as unsupported for cross-platform use. The normalization step returns null for unknown tools, and subsequent target-specific generators skip or warn on these entries to prevent invalid configurations in OpenCode, Codex, or Pi outputs.
What is the difference between OpenCode and Codex tool mapping approaches?
OpenCode mapping is dynamic and configuration-based: the applyPermissions function generates a tools record and permission matrix that the OpenCode runtime consumes directly. Codex mapping is static and documentation-based: the plugin writes a managed block to AGENTS.md that explains semantic equivalents (e.g., mapping Claude's Read to Codex's shell reads or rg), which Codex agents reference during execution rather than formal configuration files.
Why does the Pi converter use regex replacements instead of a mapping table?
The Pi converter in src/converters/claude-to-pi.ts uses regex replacements within transformContentForPi because Pi requires syntactic transformation of tool invocations within command bodies, not just identifier renaming. For example, AskUserQuestion must become ask_user_question in the actual content, and TodoWrite must expand to a file-based todo syntax string. A static mapping table would only handle name translation, whereas regex operations allow inline substitution of complex expressions and platform-specific placeholder syntax.
Where can I find the complete list of supported Claude tool mappings?
The canonical reference for supported Claude tool mappings is the TOOL_MAP constant defined in src/converters/claude-to-opencode.ts at lines 24‑39. This record contains all lower-cased canonical names (e.g., bash, read, write, edit, grep, glob, list, webfetch, skill, patch, task, question, todowrite, todoread) that the conversion pipeline recognizes and translates for OpenCode, Codex, and Pi targets.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →