Behavioral Differences Between Primary and Subagent Modes in the Compound Engineering Plugin
Primary mode exposes agents as standalone callable entities, while subagent mode treats them as orchestrated skills invoked through the Pi compatibility extension's subagent tool.
The Compound Engineering plugin converts Claude agents into OpenCode-compatible agents with distinct behavioral profiles depending on their operating mode. Understanding these behavioral differences between primary and subagent modes is critical for architecting agent workflows, as the choice determines invocation patterns, file output locations, and runtime orchestration capabilities.
Configuration and Type Definitions
The operating mode is defined as a discriminated union type in src/types/opencode.ts at lines 14-17:
export interface OpenCodeAgentConfig {
// ... other properties
mode?: "primary" | "subagent";
}
This optional property defaults to subagent when not explicitly specified during conversion. The mode value is injected into the generated agent's front-matter by src/converters/claude-to-opencode.ts at lines 88-95, ensuring the runtime environment recognizes how to handle the agent.
CLI Installation and Conversion Behavior
The Compound Engineering plugin CLI exposes the behavioral choice through the --agent-mode flag in both src/commands/convert.ts (lines 52-89) and src/commands/install.ts (lines 54-89). The default value is explicitly set to "subagent":
// From src/commands/convert.ts
const agentMode = flags["agent-mode"] ?? "subagent";
When --agent-mode primary is passed, the converter writes mode: "primary" into the agent's YAML front-matter. When omitted or set to subagent, it writes mode: "subagent", triggering the skill-based orchestration pathway.
Runtime Invocation Patterns
The behavioral differences between primary and subagent modes manifest most clearly in how agents are invoked at runtime:
Primary mode agents function as top-level entities that users call directly via the Claude CLI: claude agent <agent-name>. These agents operate independently and do not require orchestration through other agents.
Subagent mode agents are treated as skills that must be invoked through the subagent extension tool. As documented in src/targets/pi.ts at lines 20-23, Claude Task(agent, args) calls are mapped to this tool:
// Pi compatibility mapping
Task(agent, args) -> subagent tool invocation
This allows a single Claude prompt to orchestrate multiple agents in parallel or chain them sequentially through the Pi runtime.
File Output and Directory Structure
The Compound Engineering plugin emits different file structures depending on the selected mode:
Primary mode outputs standard OpenCode agent files (agents/*.md) to the primary output root (e.g., ~/.config/opencode/agents/ or a local .opencode/agents/ folder). These are standalone markdown files with YAML front-matter containing mode: "primary".
Subagent mode emits agents as generated skills under the skills/ directory rather than as standalone agents. The Pi compatibility extension (PI_COMPAT_EXTENSION_SOURCE in src/templates/pi/compat-extension.ts) registers the subagent tool that executes these skills via:
const prompt = "/skill:" + agent + " " + taskText;
const script = "cd " + shellEscape(cwd) + " && pi --no-session -p " + shellEscape(prompt);
The primary output root receives the extension files rather than a standalone agent file, effectively hiding the agent behind the skill interface.
Pi Compatibility and Task Orchestration
The subagent implementation in src/templates/pi/compat-extension.ts (lines 90-108) provides sophisticated orchestration capabilities through the runSingleSubagent function:
// Subagent execution implementation
async function runSingleSubagent(agent: string, taskText: string, cwd: string, timeoutMs: number, signal: AbortSignal) {
const prompt = "/skill:" + agent + " " + taskText;
const script = "cd " + shellEscape(cwd) + " && pi --no-session -p " + shellEscape(prompt);
const result = await pi.exec("bash", ["-lc", script], { signal, timeout: timeoutMs });
return result;
}
This implementation enables parallel execution and chaining of multiple subagents from within a single Claude prompt, a capability not available with primary mode agents which operate in isolation.
Implementation Examples
When converting a Claude agent using primary mode, the generated OpenCode agent file contains:
// Generated agent front-matter (primary mode)
---
description: "Converted from Claude agent repo-research-analyst"
mode: "primary"
---
# Agent body follows...
When using subagent mode, the Pi target transforms Claude Task calls:
// src/converters/claude-to-pi.ts transformation
// Input: Task(agent="repo-research-analyst", args="feature_description")
// Output: Run subagent with agent="repo-research-analyst" and task="feature_description".
The test suite in tests/converter.test.ts (lines 89-100) validates these behaviors by asserting that the generated front-matter contains the correct mode value based on the agentMode parameter passed to the converter.
Summary
- Primary mode creates standalone OpenCode agents in
agents/*.mdthat users invoke directly viaclaude agent <name>, operating as top-level entities without orchestration dependencies. - Subagent mode emits agents as generated skills under
skills/, requiring invocation through the Pi compatibility extension'ssubagenttool, enabling complex parallel and chained workflows from within Claude prompts. - The Compound Engineering plugin defaults to subagent mode via the
--agent-modeCLI flag, with the mode value persisted in agent front-matter and validated through the test suite intests/converter.test.ts.
Frequently Asked Questions
What is the default operating mode when converting Claude agents?
The Compound Engineering plugin defaults to subagent mode when the --agent-mode flag is omitted during conversion or installation. This is explicitly set in src/commands/convert.ts and src/commands/install.ts where the flag defaults to "subagent", ensuring agents are treated as orchestratable skills unless specified otherwise.
Can primary mode agents be called from within other Claude prompts?
No, primary mode agents are designed as standalone entities invoked directly via claude agent <agent-name>. They cannot be orchestrated from within other Claude prompts using the Task() function. Only subagent mode agents support this behavior, as they are mapped to the subagent tool in the Pi compatibility extension, enabling nested invocation.
How does the Pi compatibility extension handle subagent execution?
The Pi compatibility extension implements subagent execution in src/templates/pi/compat-extension.ts through the runSingleSubagent function (lines 90-108). It constructs a Pi command using /skill:<agent> syntax, executes it via pi --no-session, and manages timeouts and signals. This allows Claude's Task(agent, args) calls to transparently invoke subagent-mode skills with full support for parallel and chained execution.
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 →