-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture Evaluation
Make opencode-environment-bootstrap more scalable by splitting it into three layers:
- Agent system — generic, works with any AI coding CLI
- OpenCode integration — the default CLI that consumes the generic config
- Adapters — extendable to also install for Claude Code CLI or Copilot CLI
The current codebase bundles everything into one opencode-shaped box:
| Problem | What it means |
|---|---|
| All agent skills and MCP configs live inside opencode-specific templates | You can't reuse the agent methodology with another CLI |
| MCP servers (context7, firecrawl, etc.) are only defined in opencode.json format | Every new CLI target means re-declaring them manually |
| The installer hardcodes opencode CLI's install URL and config path | No option to pick a different CLI at install time |
Verification only checks for the opencode binary |
Won't detect if other CLIs are configured |
Generic config (agent rules + MCP definitions)
↓
Adapter per CLI (translates to that CLI's format)
↓
Installed config (~/.config/opencode/, ~/.claude/, ~/.copilot/)
CLI-agnostic markdown files describing what each agent role does (planner, coder, reviewer, etc.), how sessions work, and what rules to follow. No references to any specific CLI's APIs.
One YAML file per MCP server (context7, firecrawl, duckdb, etc.) as the single source of truth. Each file declares {command, args, type, env, enabled}.
A small Python script per CLI that reads Layers 1 + 2 and generates the CLI's native config format:
-
cli/opencode/→opencode.json(agents + MCPs + commands + plugins) -
cli/claude/→.claude/agents/*.agent.md+CLAUDE.md+.mcp.json -
cli/copilot/→~/.copilot/agents/*.agent.md+mcp-config.json+copilot-instructions.md
All three CLIs support MCP servers with very similar schemas. Translation is just renaming keys:
| OpenCode | Claude CLI | Copilot CLI |
|---|---|---|
{ type: "local", command: ["npx", ...], environment: {...} } |
{ type: "stdio", command: "npx", args: [...], env: {...} } |
{ type: "local", command: "npx", args: [...], env: {...} } |
{ type: "remote", url, headers } |
{ type: "http", url, headers } |
{ type: "http", url, headers } |
Reference:
Each CLI has its own way of defining agents:
| CLI | Format | Where agents live |
|---|---|---|
| OpenCode | JSON block in opencode.json
|
opencode.json agent key |
| Claude CLI | YAML frontmatter + Markdown body | ~/.claude/agents/*.agent.md |
| Copilot CLI | YAML frontmatter + Markdown body | ~/.copilot/agents/*.agent.md |
The concepts overlap (description, tools allowed/denied, model selection, system prompt), so the adapter maps generic config → CLI-specific format. The main gotchas:
-
Model names differ — need a translation table:
opencode-go/deepseek-v4-pro→sonnet(Claude) →gpt-5.2(Copilot) - Copilot has a 30,000 character limit per agent prompt — long role files may need trimming
-
Writing to
~/.claude.jsonis risky — Anthropic treats it as an auto-managed state file. Better to use.mcp.json(project-scoped) instead.
Reference:
This is the one thing that can't be replicated outside OpenCode. Here's why:
The /delegate command is a custom OpenCode command (commands/delegate.md). It works because OpenCode provides a task() tool that lets the running agent programmatically spawn sub-agents and chain them in a DAG (planner → coder → reviewer → tester). The primary agent parses annotations like @planner and calls task(subagent_type: "planner") with full context injection.
| What it needs | OpenCode | Claude CLI | Copilot CLI |
|---|---|---|---|
| Agent A spawns Agent B programmatically | ✅ task() tool |
❌ Subagents can't nest — hard limit | ❌ Delegation is model-driven (AI decides), not user-directed |
| Custom DAG workflow | ✅ /delegate command |
❌ No custom slash commands | ❌ No user-defined workflow |
| Context injection into sub-agents | ✅ Automatic via prompt injection | ❌ Manual file passing | ❌ Not user-controllable |
This is not a translation problem — it's a capability gap. The runtimes simply don't expose the same primitives.
Three approaches to bridge the gap:
| Approach | What it does | Works for | Fidelity |
|---|---|---|---|
| A. Simplified single-agent | Install MCPs + agent roles but no orchestration. User picks role at launch (claude --agent planner) |
Claude, Copilot | Medium — no DAG, but all tools/rules work |
| B. Shell wrapper | A script that runs claude --agent planner "..." && claude --agent coder "..." passing context between steps |
Claude | Medium — sequential but no interactivity |
| C. ACP orchestrator | A daemon that implements DAG logic externally, driving Copilot via Agent Client Protocol | Copilot | High — ACP is built for this |
Recommendation: Ship Approach A as the default for Claude/Copilot. The DAG workflow stays OpenCode-native — that's a feature differentiator, not a bug.
| What | Is it worth building? | Effort |
|---|---|---|
| MCP catalog + translation | ✅ Yes — single source of truth, all three CLIs support it | ~20 lines per adapter |
| Agent role extraction | ✅ Yes — makes the methodology reusable | ~50 lines per adapter |
| OpenCode adapter | ✅ Yes — cleaner architecture, same output | ~150 lines |
| Claude adapter | ✅ Yes — config generation is straightforward | ~250 lines |
| Copilot adapter | ✅ Yes — same approach, plus ACP for future orchestration | ~300 lines |
| DAG orchestration | ❌ Can't port — OpenCode native capability | N/A |
Bottom line: The three-layer architecture is a clear improvement. It cleans up the monolithic structure, creates a single source of truth for MCP servers, and makes the agent methodology available to other CLIs. The adapters are all feasible for config generation. The honest limitation is that the multi-agent DAG workflow (/delegate) stays OpenCode-native — Claude and Copilot get the same agent rules and MCP tools, but running in simplified single-agent mode.