Model: claude-opus-4-6 (anthropic/claude-opus-4-6) Generated: 2026-04-03 Book: Claude Code VS OpenCode: Architecture, Design and The Road Ahead 章节: 第12章 — 解剖一个13万行代码的插件 Token Usage: ~120,000 input + ~6,500 output
12.7 Claude Code 兼容层
核心问题:用户的旧资产怎么办?
假设你在 Claude Code 里积累了大量 commands、agents、MCP 配置和插件。想试 OMO 时面临的第一个问题:“是不是要从头再来?”
OMO 的回答:尽量不用。你的旧资产可以直接带过来。
flowchart LR
subgraph CC["Claude Code Assets"]
C1["commands/"]
C2["agents/"]
C3[".mcp.json"]
C4["plugins/"]
end
subgraph Loaders["4 Loaders"]
L1["Command Loader"]
L2["Agent Loader"]
L3["MCP Loader"]
L4["Plugin Loader"]
end
subgraph OC["OpenCode World"]
O1["CommandDefinition"]
O2["AgentConfig"]
O3["MCP Server Config"]
O4["Plugin Components"]
end
C1 --> L1 --> O1
C2 --> L2 --> O2
C3 --> L3 --> O3
C4 --> L4 --> O4
1. 命令兼容(Command Loader)
📁 文件说明:
src/features/claude-code-command-loader/loader.ts从四个目录加载命令文件,解析 markdown + frontmatter,转换成 OpenCode CommandDefinition。
flowchart TD
D1["~/.claude/commands/"] --> Merge["Merge All"]
D2[".claude/commands/"] --> Merge
D3["OC global command/"] --> Merge
D4[".opencode/command/"] --> Merge
Merge --> Parse["Parse MD + Frontmatter"]
Parse --> Convert["Convert to CommandDefinition"]
命令文件格式:Markdown + YAML frontmatter。Loader 把 frontmatter 中的元数据和正文组装成统一模板。
2. 智能体兼容(Agent Loader)
📁 文件说明:
src/features/claude-code-agent-loader/loader.ts从 Claude Code agent 目录读取 markdown 定义,转换成 OpenCode AgentConfig。
flowchart TD
D1["~/.claude/agents/"] --> Parse["Parse MD Agents"]
D2[".claude/agents/"] --> Parse
Parse --> Body["Body = System Prompt"]
Parse --> FM["Frontmatter = Tools/Permissions"]
Body --> Config["AgentConfig<br/>mode: subagent"]
FM --> Config
⚠️ 注意:当前源码没有实现
.opencode/agents/的对称 Loader。兼容层不是每类资产都完全对称。
3. MCP 兼容(MCP Loader)——最完整的模块
📁 文件说明:
src/features/claude-code-mcp-loader/loader.ts从多个位置读取 MCP 配置,支持环境变量展开。
flowchart TD
D1["~/.claude.json"] --> Read["Read All MCP Configs"]
D2["~/.claude/.mcp.json"] --> Read
D3[".mcp.json"] --> Read
D4[".claude/.mcp.json"] --> Read
Read --> Each["For Each Server"]
Each --> Type{Type?}
Type -->|Remote| R["type: remote<br/>Keep URL + auth"]
Type -->|Stdio| L["type: local<br/>Build command array"]
R --> Env["expandEnvVarsInObject()"]
L --> Env
Env --> Final["OC MCP Server Config"]
环境变量展开:expandEnvVarsInObject() 递归处理 ${VAR} 和 ${VAR:-default} 语法。
flowchart LR
Input["${OPENAI_API_KEY}"] --> Expand["expandEnvVars()"]
Expand --> Output["sk-abc123..."]
Input2["${PORT:-3000}"] --> Expand2["expandEnvVars()"]
Expand2 --> Output2["3000 (if PORT not set)"]
兼容层不只认文件格式,还保留了 Claude Code 生态常见的变量替换习惯。
4. 插件兼容(Plugin Loader)——最复杂
📁 文件说明:
src/features/claude-code-plugin-loader/discovery.ts插件发现。从~/.claude/plugins/installed_plugins.json读取安装数据库。
📁 文件说明:
src/features/claude-code-plugin-loader/plugin-components-loader.ts并行加载每个插件的 commands、skills、agents、MCP、hooks。
flowchart TD
Start["Read installed_plugins.json"] --> Filter["Filter Enabled Plugins"]
Filter --> Each["For Each Plugin"]
Each --> Read["Read Plugin Directory"]
Read --> Manifest["Parse plugin.json"]
Manifest --> Parallel["Parallel Load"]
Parallel --> P1["commands/"]
Parallel --> P2["agents/"]
Parallel --> P3["skills/"]
Parallel --> P4[".mcp.json"]
Parallel --> P5["hooks/hooks.json"]
${CLAUDE_PLUGIN_ROOT} 路径替换:
flowchart LR
Input["${CLAUDE_PLUGIN_ROOT}/bin/server"] --> Replace["Path Replace"]
Replace --> Absolute["/home/user/.claude/plugins/my-plugin/bin/server"]
Absolute --> EnvExpand["Env Var Expand"]
EnvExpand --> Final["Final Config"]
⚠️ Claude Code 插件发现路径是
~/.claude/plugins安装数据库,不是.opencode/plugins/。
命名空间和冲突管理
flowchart TD
subgraph Conflict["Without Namespace"]
P1A["Plugin A: build"] --- P2A["Plugin B: build"]
P1A -.->|"CONFLICT!"| P2A
end
subgraph Safe["With Namespace"]
P1B["pluginA:build"]
P2B["pluginB:build"]
P1B -.->|"No conflict"| P2B
end
- 插件资产加
pluginName:前缀 - MCP 保留用户显式禁用状态
- 优先级规则解决同名资产
精细化控制
每类资产有独立开关:
flowchart TD
CC["claude_code config"] --> SW1["plugins: true/false"]
CC --> SW2["commands: true/false"]
CC --> SW3["agents: true/false"]
CC --> SW4["skills: true/false"]
CC --> SW5["mcp: true/false"]
CC --> SW6["plugins_override: {...}"]
CC --> SW7["plugin_load_timeout_ms: 5000"]
用户可以说“只要命令和 MCP,不要智能体和插件“。
为什么做兼容层?——迁移路径策略
graph LR
subgraph Without["Without Compat Layer"]
W1["User has CC assets"] --> W2["Must rebuild from scratch"]
W2 --> W3["High switching cost"]
W3 --> W4["User stays with CC"]
end
subgraph With["With Compat Layer"]
A1["User has CC assets"] --> A2["Bring assets to OMO"]
A2 --> A3["Add OMO features on top"]
A3 --> A4["Low switching cost"]
end
style Without fill:#ffcdd2
style With fill:#c8e6c9
💡 工具生态的胜出往往不靠“谁功能最强“,而靠“谁迁移最平滑“。
本节要点
- 四个 Loader:command、agent、mcp、plugin 各负责一类资产“翻译“
- 环境变量展开:保留
${VAR}和${CLAUDE_PLUGIN_ROOT}替换习惯 - 命名空间管理:插件资产加前缀避免冲突
- 精细化控制:每类资产有独立开关
- 迁移路径策略:降低用户切换成本是核心价值
- 并非完全对称:有些迁移路径更成熟,有些还在演进