OpenCode 中文文档
目录
- 第一部分:简介与快速开始
- 第二部分:安装与配置
- 第三部分:使用指南
- 第四部分:高级配置
- 第五部分:开发者文档
- 第六部分:故障排除与常见问题
第一部分:简介与快速开始
1.1 什么是 OpenCode?
OpenCode 是一个开源的 AI 编程助手(AI Coding Agent),可以理解成你身边的"智能程序员搭档"。它在终端、IDE 或桌面应用中运行,帮助你编写代码、查找文件、解答编程问题、修复 Bug 和添加新功能。
1.1.1 核心特性
- 完全开源 – 拥有 95,000+ GitHub stars,650+ 贡献者,8,500+ 次提交
- 隐私优先 – 不存储你的代码或上下文数据,适合隐私敏感环境
- 支持任何模型 – 75+ 个 AI 提供商,包括 Claude、GPT、Gemini 等
- 免费使用 – 内置免费模型,也可连接你自己的 API Key
- 多平台 – 终端界面、桌面应用、IDE 扩展都可用
- 多会话 – 可以在同一项目上并行启动多个代理
- 分享链接 – 可以分享会话链接用于参考或调试
- LSP 支持 – 自动加载适合 LLM 的语言服务器协议
1.1.2 为什么使用 OpenCode?
市面上有很多 AI 编程工具,但 OpenCode 的独特之处在于:
1.1.3 OpenCode 架构图
#mermaid-svg-CzIff02hD0cmCXcd{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CzIff02hD0cmCXcd .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CzIff02hD0cmCXcd .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CzIff02hD0cmCXcd .error-icon{fill:#552222;}#mermaid-svg-CzIff02hD0cmCXcd .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CzIff02hD0cmCXcd .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CzIff02hD0cmCXcd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CzIff02hD0cmCXcd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CzIff02hD0cmCXcd .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CzIff02hD0cmCXcd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CzIff02hD0cmCXcd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CzIff02hD0cmCXcd .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CzIff02hD0cmCXcd .marker.cross{stroke:#333333;}#mermaid-svg-CzIff02hD0cmCXcd svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CzIff02hD0cmCXcd p{margin:0;}#mermaid-svg-CzIff02hD0cmCXcd .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-CzIff02hD0cmCXcd .cluster-label text{fill:#333;}#mermaid-svg-CzIff02hD0cmCXcd .cluster-label span{color:#333;}#mermaid-svg-CzIff02hD0cmCXcd .cluster-label span p{background-color:transparent;}#mermaid-svg-CzIff02hD0cmCXcd .label text,#mermaid-svg-CzIff02hD0cmCXcd span{fill:#333;color:#333;}#mermaid-svg-CzIff02hD0cmCXcd .node rect,#mermaid-svg-CzIff02hD0cmCXcd .node circle,#mermaid-svg-CzIff02hD0cmCXcd .node ellipse,#mermaid-svg-CzIff02hD0cmCXcd .node polygon,#mermaid-svg-CzIff02hD0cmCXcd .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CzIff02hD0cmCXcd .rough-node .label text,#mermaid-svg-CzIff02hD0cmCXcd .node .label text,#mermaid-svg-CzIff02hD0cmCXcd .image-shape .label,#mermaid-svg-CzIff02hD0cmCXcd .icon-shape .label{text-anchor:middle;}#mermaid-svg-CzIff02hD0cmCXcd .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-CzIff02hD0cmCXcd .rough-node .label,#mermaid-svg-CzIff02hD0cmCXcd .node .label,#mermaid-svg-CzIff02hD0cmCXcd .image-shape .label,#mermaid-svg-CzIff02hD0cmCXcd .icon-shape .label{text-align:center;}#mermaid-svg-CzIff02hD0cmCXcd .node.clickable{cursor:pointer;}#mermaid-svg-CzIff02hD0cmCXcd .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-CzIff02hD0cmCXcd .arrowheadPath{fill:#333333;}#mermaid-svg-CzIff02hD0cmCXcd .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-CzIff02hD0cmCXcd .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-CzIff02hD0cmCXcd .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CzIff02hD0cmCXcd .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-CzIff02hD0cmCXcd .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CzIff02hD0cmCXcd .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-CzIff02hD0cmCXcd .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-CzIff02hD0cmCXcd .cluster text{fill:#333;}#mermaid-svg-CzIff02hD0cmCXcd .cluster span{color:#333;}#mermaid-svg-CzIff02hD0cmCXcd div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-CzIff02hD0cmCXcd .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-CzIff02hD0cmCXcd rect.text{fill:none;stroke-width:0;}#mermaid-svg-CzIff02hD0cmCXcd .icon-shape,#mermaid-svg-CzIff02hD0cmCXcd .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CzIff02hD0cmCXcd .icon-shape p,#mermaid-svg-CzIff02hD0cmCXcd .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-CzIff02hD0cmCXcd .icon-shape rect,#mermaid-svg-CzIff02hD0cmCXcd .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CzIff02hD0cmCXcd .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-CzIff02hD0cmCXcd .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-CzIff02hD0cmCXcd :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
用户
终端界面 TUI
Web 界面
IDE 扩展
OpenCode 服务器
AI 模型提供商Claude/GPT/Gemini/etc
LSP 服务器类型检查/补全
工具系统读写文件/执行命令
MCP 服务器外部工具集成
文件系统
Shell 命令
Git 操作
1.2 快速开始
1.2.1 安装方法
最简单的安装方法(推荐):
curl -fsSL https://opencode.ai/install | bash
其他安装方式:
使用 npm:
npm install -g opencode-ai
使用 Bun:
bun install -g opencode-ai
使用 pnpm:
pnpm install -g opencode-ai
使用 Yarn:
yarn global add opencode-ai
使用 Homebrew(macOS/Linux):
brew install anomalyco/tap/opencode
使用 Paru(Arch Linux):
paru -S opencode-bin
Windows 安装选项:
- 使用 Chocolatey:
choco install opencode
- 使用 Scoop:
scoop install opencode
- 使用 NPM:
npm install -g opencode-ai
- 使用 Mise:
mise use -g github:anomalyco/opencode
- 使用 Docker:
docker run -it –rm ghcr.io/anomalyco/opencode
1.2.2 系统要求
终端要求:
- 支持真彩色(24-bit color)的现代终端模拟器
- 推荐:WezTerm、Alacritty、Ghostty、Kitty
检查终端颜色支持:
echo $COLORTERM
应该输出 truecolor 或 24bit
API Keys: 需要为你想要使用的 LLM 提供商准备 API Keys。
1.3 配置 AI 提供商
OpenCode 需要连接到 AI 模型才能工作。你有几种选择:
1.3.1 使用 OpenCode Zen(推荐新手使用)
Zen 是 OpenCode 团队精心挑选的模型列表,已经过测试验证,适合编程任务。
设置步骤:
opencode
# 然后在界面中输入
/connect
1.3.2 使用其他提供商
你也可以使用其他提供商:
- OpenAI(ChatGPT Plus/Pro)
- Anthropic(Claude)
- Google(Gemini/Vertex AI)
- GitHub Copilot
- DeepSeek
- Groq
- Fireworks AI
- Together AI
- Cerebras
- Moonshot AI(Kimi)
- MiniMax
- Z.AI(GLM)
- xAI(Grok)
- OpenRouter
- Helicone
- Vercel AI Gateway
- Cloudflare AI Gateway
- 以及更多…
运行 /connect 命令,选择你想要的提供商即可。
1.3.3 使用本地模型
你也可以运行本地模型:
- Ollama
- LM Studio
- llama.cpp
1.4 初始化项目
进入你的项目目录,运行 OpenCode:
cd /path/to/your/project
opencode
然后运行初始化命令:
/init
这会创建一个 AGENTS.md 文件,帮助 OpenCode 理解你的项目结构和编码规范。
建议: 将 AGENTS.md 提交到 Git,这样团队成员也能使用相同的配置。
第二部分:安装与配置
2.1 配置文件详解
OpenCode 使用 JSON 配置文件,支持 JSON 和 JSONC(带注释的 JSON)。
2.1.1 配置文件位置(按优先级排序)
配置文件按以下顺序加载,后面的配置会覆盖前面的冲突项:
注意: 配置文件是合并的,不是替换的。非冲突的设置会从所有配置中保留。
2.1.3 配置层级示意图
#mermaid-svg-5N8DD3sot5TUoWQl{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5N8DD3sot5TUoWQl .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5N8DD3sot5TUoWQl .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5N8DD3sot5TUoWQl .error-icon{fill:#552222;}#mermaid-svg-5N8DD3sot5TUoWQl .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5N8DD3sot5TUoWQl .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5N8DD3sot5TUoWQl .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5N8DD3sot5TUoWQl .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5N8DD3sot5TUoWQl .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5N8DD3sot5TUoWQl .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5N8DD3sot5TUoWQl .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5N8DD3sot5TUoWQl .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5N8DD3sot5TUoWQl .marker.cross{stroke:#333333;}#mermaid-svg-5N8DD3sot5TUoWQl svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5N8DD3sot5TUoWQl p{margin:0;}#mermaid-svg-5N8DD3sot5TUoWQl .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-5N8DD3sot5TUoWQl .cluster-label text{fill:#333;}#mermaid-svg-5N8DD3sot5TUoWQl .cluster-label span{color:#333;}#mermaid-svg-5N8DD3sot5TUoWQl .cluster-label span p{background-color:transparent;}#mermaid-svg-5N8DD3sot5TUoWQl .label text,#mermaid-svg-5N8DD3sot5TUoWQl span{fill:#333;color:#333;}#mermaid-svg-5N8DD3sot5TUoWQl .node rect,#mermaid-svg-5N8DD3sot5TUoWQl .node circle,#mermaid-svg-5N8DD3sot5TUoWQl .node ellipse,#mermaid-svg-5N8DD3sot5TUoWQl .node polygon,#mermaid-svg-5N8DD3sot5TUoWQl .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5N8DD3sot5TUoWQl .rough-node .label text,#mermaid-svg-5N8DD3sot5TUoWQl .node .label text,#mermaid-svg-5N8DD3sot5TUoWQl .image-shape .label,#mermaid-svg-5N8DD3sot5TUoWQl .icon-shape .label{text-anchor:middle;}#mermaid-svg-5N8DD3sot5TUoWQl .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5N8DD3sot5TUoWQl .rough-node .label,#mermaid-svg-5N8DD3sot5TUoWQl .node .label,#mermaid-svg-5N8DD3sot5TUoWQl .image-shape .label,#mermaid-svg-5N8DD3sot5TUoWQl .icon-shape .label{text-align:center;}#mermaid-svg-5N8DD3sot5TUoWQl .node.clickable{cursor:pointer;}#mermaid-svg-5N8DD3sot5TUoWQl .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5N8DD3sot5TUoWQl .arrowheadPath{fill:#333333;}#mermaid-svg-5N8DD3sot5TUoWQl .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5N8DD3sot5TUoWQl .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5N8DD3sot5TUoWQl .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5N8DD3sot5TUoWQl .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5N8DD3sot5TUoWQl .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5N8DD3sot5TUoWQl .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5N8DD3sot5TUoWQl .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5N8DD3sot5TUoWQl .cluster text{fill:#333;}#mermaid-svg-5N8DD3sot5TUoWQl .cluster span{color:#333;}#mermaid-svg-5N8DD3sot5TUoWQl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5N8DD3sot5TUoWQl .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5N8DD3sot5TUoWQl rect.text{fill:none;stroke-width:0;}#mermaid-svg-5N8DD3sot5TUoWQl .icon-shape,#mermaid-svg-5N8DD3sot5TUoWQl .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5N8DD3sot5TUoWQl .icon-shape p,#mermaid-svg-5N8DD3sot5TUoWQl .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5N8DD3sot5TUoWQl .icon-shape rect,#mermaid-svg-5N8DD3sot5TUoWQl .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5N8DD3sot5TUoWQl .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5N8DD3sot5TUoWQl .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5N8DD3sot5TUoWQl :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
配置加载优先级
运行时环境变量OPENCODE_CONFIG_CONTENT
项目 .opencode/ 目录
项目配置文件./opencode.json
自定义配置路径OPENCODE_CONFIG
全局配置~/.config/opencode/opencode.json
远程配置.well-known/opencode
优先级说明: 从高到低,后面的配置会覆盖前面的冲突项。配置是合并的,非冲突设置会从所有配置中保留。
2.1.2 完整配置示例
{
"$schema": "https://opencode.ai/config.json",
// 使用的主题
"theme": "opencode",
// 主模型和小模型
"model": "anthropic/claude-sonnet-4-5",
"small_model": "anthropic/claude-haiku-4-5",
// 自动更新
"autoupdate": true,
// 提供商配置
"provider": {
"anthropic": {
"options": {
"timeout": 600000,
"setCacheKey": true
}
}
},
// TUI 设置
"tui": {
"scroll_speed": 3,
"scroll_acceleration": {
"enabled": true
},
"diff_style": "auto"
},
// 工具权限
"permission": {
"edit": "ask",
"bash": "ask",
"webfetch": "allow"
},
// 智能体配置
"agent": {
"code-reviewer": {
"description": "审查代码最佳实践和潜在问题",
"mode": "subagent",
"model": "anthropic/claude-sonnet-4-5",
"prompt": "你是一个代码审查员。关注安全性、性能和可维护性。",
"tools": {
"write": false,
"edit": false
}
}
},
// 自定义命令
"command": {
"test": {
"template": "运行完整的测试套件并生成覆盖率报告…",
"description": "运行测试",
"agent": "build"
}
},
// 分享设置
"share": "manual",
// 代码格式化器
"formatter": {
"prettier": {
"disabled": true
},
"custom-prettier": {
"command": ["npx", "prettier", "–write", "$FILE"],
"extensions": [".js", ".ts", ".jsx", ".tsx"]
}
},
// 文件监视器忽略模式
"watcher": {
"ignore": ["node_modules/**", "dist/**", ".git/**"]
},
// 上下文压缩
"compaction": {
"auto": true,
"prune": true
},
// MCP 服务器
"mcp": {
"sentry": {
"type": "remote",
"url": "https://mcp.sentry.dev/mcp",
"oauth": {}
}
},
// LSP 服务器
"lsp": {
"typescript": {
"disabled": false,
"initialization": {
"preferences": {
"importModuleSpecifierPreference": "relative"
}
}
}
},
// 插件
"plugin": ["opencode-helicone-session", "@my-org/custom-plugin"],
// 规则/说明文件
"instructions": ["CONTRIBUTING.md", "docs/guidelines.md", ".cursor/rules/*.md"],
// 禁用/启用提供商
"disabled_providers": ["openai"],
"enabled_providers": ["anthropic", "opencode"],
// 服务器设置
"server": {
"port": 4096,
"hostname": "0.0.0.0",
"mdns": true,
"cors": ["http://localhost:5173"]
},
// 按键绑定
"keybinds": {
"leader": "ctrl+x",
"app_exit": "ctrl+c,ctrl+d,<leader>q",
"editor_open": "<leader>e"
}
}
2.2 提供商详细配置
2.2.1 配置多个提供商
你可以在配置中同时设置多个提供商:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"anthropic": {
"options": {
"timeout": 600000,
"setCacheKey": true
}
},
"openai": {
"options": {
"timeout": 300000
}
},
"opencode": {
"options": {
"timeout": 300000
}
}
}
}
2.2.2 Amazon Bedrock 特殊配置
Amazon Bedrock 支持 AWS 特定的配置:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"amazon-bedrock": {
"options": {
"region": "us-east-1",
"profile": "my-aws-profile",
"endpoint": "https://bedrock-runtime.us-east-1.vpce-xxxxx.amazonaws.com"
}
}
}
}
认证优先级:
2.2.3 Azure OpenAI 配置
# 设置环境变量
export AZURE_RESOURCE_NAME=your-resource-name
或者在配置中:
{
"provider": {
"azure-openai": {
"options": {
"baseURL": "https://your-resource.openai.azure.com/"
}
}
}
}
2.2.4 自定义提供商
对于不在列表中的 OpenAI 兼容提供商:
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"myprovider": {
"npm": "@ai-sdk/openai-compatible",
"name": "My AI Provider",
"options": {
"baseURL": "https://api.myprovider.com/v1",
"apiKey": "{env:MY_API_KEY}",
"headers": {
"Authorization": "Bearer custom-token"
}
},
"models": {
"my-model-name": {
"name": "My Model",
"limit": {
"context": 200000,
"output": 65536
}
}
}
}
}
}
2.3 模型配置详解
2.3.1 选择模型
运行 /models 命令查看可用模型。
推荐的模型(按字母顺序):
- Claude Opus 4.5
- Claude Sonnet 4.5
- Gemini 3 Pro
- GPT 5.2
- GPT 5.1 Codex
- MiniMax M2.1
2.3.2 设置默认模型
{
"$schema": "https://opencode.ai/config.json",
"model": "opencode/gpt-5.1-codex",
"small_model": "opencode/gpt-5-nano"
}
格式为 provider_id/model_id。
2.3.3 模型变体
许多模型支持多个配置变体:
Anthropic:
- high – 高思考预算(默认)
- max – 最大思考预算
OpenAI:
- none – 无推理
- minimal / low / medium / high / xhigh – 不同推理强度
Google:
- low – 较低 Token 预算
- high – 较高 Token 预算
自定义变体:
{
"provider": {
"opencode": {
"models": {
"gpt-5": {
"variants": {
"high": {
"reasoningEffort": "high",
"textVerbosity": "low",
"reasoningSummary": "auto"
},
"low": {
"reasoningEffort": "low",
"textVerbosity": "low",
"reasoningSummary": "auto"
}
}
}
}
}
}
}
使用 variant_cycle 快捷键在变体间切换。
第三部分:使用指南
3.1 终端用户界面(TUI)
3.1.1 启动 TUI
opencode
或指定项目目录:
opencode /path/to/project
3.1.2 基本操作
引用文件: 使用 @ 键可以模糊搜索项目中的文件:
@packages/functions/src/api/index.ts 中的认证是怎么实现的?
运行 Bash 命令: 在消息前加 !:
!ls -la
!npm test
使用图片: 拖拽图片到终端,OpenCode 可以分析图片内容。
3.1.3 快捷键
OpenCode 使用 ctrl+x 作为 Leader 键(可配置)。
常用快捷键:
| ctrl+x h | /help | 显示帮助 |
| ctrl+x i | /init | 创建/更新 AGENTS.md |
| ctrl+x u | /undo | 撤销上一条消息 |
| ctrl+x r | /redo | 重做 |
| ctrl+x n | /new | 开始新会话 |
| ctrl+x l | /sessions | 列出并切换会话 |
| ctrl+x s | /share | 分享当前会话 |
| ctrl+x m | /models | 列出可用模型 |
| ctrl+x t | /themes | 列出可用主题 |
| ctrl+x c | /compact | 压缩当前会话 |
| ctrl+x e | /editor | 打开外部编辑器 |
| ctrl+x x | /export | 导出会话 |
| ctrl+x q | /exit | 退出 |
| ctrl+x d | /details | 切换工具执行详情 |
| Tab | – | 切换主要智能体 |
| ctrl+t | – | 循环切换模型变体 |
| ctrl+p | – | 打开命令列表 |
导航快捷键:
| PageUp / ctrl+alt+b | 消息页面向上 |
| PageDown / ctrl+alt+f | 消息页面向下 |
| ctrl+alt+y | 消息向上滚动一行 |
| ctrl+alt+e | 消息向下滚动一行 |
| ctrl+alt+u | 消息向上半页 |
| ctrl+alt+d | 消息向下半页 |
| ctrl+g / Home | 跳到第一条消息 |
| ctrl+alt+g / End | 跳到最后一条消息 |
| ctrl+x right | 切换到子会话 |
| ctrl+x left | 切换到父会话 |
3.1.4 编辑器设置
/editor 和 /export 命令使用 EDITOR 环境变量指定的编辑器。
Linux/macOS:
export EDITOR=vim
# 或 GUI 编辑器
export EDITOR="code –wait"
Windows (CMD):
set EDITOR=notepad
set EDITOR="code –wait"
Windows (PowerShell):
$env:EDITOR = "notepad"
$env:EDITOR = "code –wait"
3.2 智能体(Agents)
智能体是专门用于特定任务的 AI 助手。
3.2.1 智能体类型
主要智能体(Primary Agents):
按 Tab 键切换:
- 适合分析代码、提出修改建议、制定计划
子智能体(Subagents):
通过 @ 提及调用:
3.2.2 创建自定义智能体
方法 1:使用命令
opencode agent create
这会引导你完成创建过程。
方法 2:创建 Markdown 文件
在 .opencode/agents/ 或 ~/.config/opencode/agents/ 创建文件:
—
description: 审查代码质量和最佳实践
mode: subagent
model: anthropic/claude-sonnet-4-20250514
temperature: 0.1
tools:
write: false
edit: false
bash: false
—
你处于代码审查模式。关注:
– 代码质量和最佳实践
– 潜在的 Bug 和边界情况
– 性能影响
– 安全考虑
提供建设性反馈,不要直接修改代码。
3.2.3 智能体配置选项
| description | 智能体描述(必填) | "审查代码最佳实践" |
| mode | 模式:primary、subagent 或 all | "subagent" |
| model | 使用的模型 | "anthropic/claude-sonnet-4-5" |
| temperature | 随机性(0.0-1.0) | 0.1 |
| prompt | 系统提示词文件路径 | "{file:./prompts/review.txt}" |
| tools | 可用工具 | {"write": false} |
| permission | 权限设置 | {"edit": "ask"} |
| steps | 最大迭代次数 | 10 |
| color | UI 颜色 | "#ff6b6b" |
| hidden | 在 @ 菜单中隐藏 | true |
| top_p | 响应多样性 | 0.9 |
| hidden | 在 @ 菜单中隐藏 | true |
3.2.4 智能体类型关系图
说明:
- 主要智能体:通过 Tab 键切换
- 子智能体:通过 @ 提及调用
- Build:拥有所有工具权限,用于实际开发工作
- Plan:只读模式,用于分析、规划、审查
配置示例(JSON):
{
"agent": {
"build": {
"mode": "primary",
"model": "anthropic/claude-sonnet-4-20250514",
"prompt": "{file:./prompts/build.txt}",
"tools": {
"write": true,
"edit": true,
"bash": true
}
},
"plan": {
"mode": "primary",
"model": "anthropic/claude-haiku-4-20250514",
"tools": {
"write": false,
"edit": false,
"bash": false
}
},
"code-reviewer": {
"description": "审查代码最佳实践和潜在问题",
"mode": "subagent",
"model": "anthropic/claude-sonnet-4-20250514",
"prompt": "你是一个代码审查员。关注安全性、性能和可维护性。",
"tools": {
"write": false,
"edit": false
}
}
}
}
3.3 工具(Tools)
工具是 OpenCode 用来与你的代码库交互的功能。
3.3.1 内置工具
| bash | 执行 shell 命令 | permission.bash |
| edit | 修改现有文件 | permission.edit |
| write | 创建/覆盖文件 | permission.edit |
| read | 读取文件内容 | permission.read |
| grep | 使用正则搜索文件内容 | permission.grep |
| glob | 按模式查找文件 | permission.glob |
| list | 列出目录内容 | permission.list |
| patch | 应用补丁文件 | permission.edit |
| webfetch | 获取网页内容 | permission.webfetch |
| skill | 加载技能文件 | permission.skill |
| todowrite | 管理待办列表 | permission.todowrite |
| question | 向用户提问 | permission.question |
| lsp | LSP 服务器交互(实验性) | permission.lsp |
3.3.2 权限设置
{
"permission": {
"edit": "ask", // ask = 执行前询问
"bash": "allow", // allow = 直接允许
"webfetch": "deny" // deny = 禁止使用
}
}
针对特定命令的权限:
{
"permission": {
"bash": {
"*": "ask", // 默认询问
"git status": "allow", // git status 直接允许
"git *": "ask" // 其他 git 命令询问
}
}
}
3.3.3 忽略模式
工具如 grep、glob 和 list 内部使用 ripgrep。默认情况下,ripgrep 遵守 .gitignore 模式。
包含被忽略的文件:
创建 .ignore 文件在项目根目录:
!node_modules/
!dist/
!build/
这会允许 ripgrep 搜索 node_modules/、dist/ 和 build/ 目录,即使它们在 .gitignore 中。
3.3.4 工具系统架构图
#mermaid-svg-WWAXwwEiitXucTe9{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-WWAXwwEiitXucTe9 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WWAXwwEiitXucTe9 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WWAXwwEiitXucTe9 .error-icon{fill:#552222;}#mermaid-svg-WWAXwwEiitXucTe9 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WWAXwwEiitXucTe9 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WWAXwwEiitXucTe9 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WWAXwwEiitXucTe9 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WWAXwwEiitXucTe9 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WWAXwwEiitXucTe9 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WWAXwwEiitXucTe9 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WWAXwwEiitXucTe9 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WWAXwwEiitXucTe9 .marker.cross{stroke:#333333;}#mermaid-svg-WWAXwwEiitXucTe9 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WWAXwwEiitXucTe9 p{margin:0;}#mermaid-svg-WWAXwwEiitXucTe9 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-WWAXwwEiitXucTe9 .cluster-label text{fill:#333;}#mermaid-svg-WWAXwwEiitXucTe9 .cluster-label span{color:#333;}#mermaid-svg-WWAXwwEiitXucTe9 .cluster-label span p{background-color:transparent;}#mermaid-svg-WWAXwwEiitXucTe9 .label text,#mermaid-svg-WWAXwwEiitXucTe9 span{fill:#333;color:#333;}#mermaid-svg-WWAXwwEiitXucTe9 .node rect,#mermaid-svg-WWAXwwEiitXucTe9 .node circle,#mermaid-svg-WWAXwwEiitXucTe9 .node ellipse,#mermaid-svg-WWAXwwEiitXucTe9 .node polygon,#mermaid-svg-WWAXwwEiitXucTe9 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-WWAXwwEiitXucTe9 .rough-node .label text,#mermaid-svg-WWAXwwEiitXucTe9 .node .label text,#mermaid-svg-WWAXwwEiitXucTe9 .image-shape .label,#mermaid-svg-WWAXwwEiitXucTe9 .icon-shape .label{text-anchor:middle;}#mermaid-svg-WWAXwwEiitXucTe9 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-WWAXwwEiitXucTe9 .rough-node .label,#mermaid-svg-WWAXwwEiitXucTe9 .node .label,#mermaid-svg-WWAXwwEiitXucTe9 .image-shape .label,#mermaid-svg-WWAXwwEiitXucTe9 .icon-shape .label{text-align:center;}#mermaid-svg-WWAXwwEiitXucTe9 .node.clickable{cursor:pointer;}#mermaid-svg-WWAXwwEiitXucTe9 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-WWAXwwEiitXucTe9 .arrowheadPath{fill:#333333;}#mermaid-svg-WWAXwwEiitXucTe9 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-WWAXwwEiitXucTe9 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-WWAXwwEiitXucTe9 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WWAXwwEiitXucTe9 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-WWAXwwEiitXucTe9 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WWAXwwEiitXucTe9 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-WWAXwwEiitXucTe9 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-WWAXwwEiitXucTe9 .cluster text{fill:#333;}#mermaid-svg-WWAXwwEiitXucTe9 .cluster span{color:#333;}#mermaid-svg-WWAXwwEiitXucTe9 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-WWAXwwEiitXucTe9 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-WWAXwwEiitXucTe9 rect.text{fill:none;stroke-width:0;}#mermaid-svg-WWAXwwEiitXucTe9 .icon-shape,#mermaid-svg-WWAXwwEiitXucTe9 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-WWAXwwEiitXucTe9 .icon-shape p,#mermaid-svg-WWAXwwEiitXucTe9 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-WWAXwwEiitXucTe9 .icon-shape rect,#mermaid-svg-WWAXwwEiitXucTe9 .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-WWAXwwEiitXucTe9 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-WWAXwwEiitXucTe9 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-WWAXwwEiitXucTe9 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
权限控制
allow允许
ask询问
deny拒绝
扩展工具
MCP服务器外部集成
自定义工具用户开发
LSP工具代码智能
内置工具
bash执行命令
edit编辑文件
write写入文件
read读取文件
grep搜索内容
glob匹配文件
list列出目录
LLM
3.4 命令系统
3.4.1 内置命令
| /connect | – | 添加提供商 |
| /compact / /summarize | ctrl+x c | 压缩当前会话 |
| /details | ctrl+x d | 切换工具执行详情 |
| /editor | ctrl+x e | 打开外部编辑器 |
| /exit / /quit / /q | ctrl+x q | 退出 |
| /export | ctrl+x x | 导出会话到 Markdown |
| /help | ctrl+x h | 显示帮助 |
| /init | ctrl+x i | 创建/更新 AGENTS.md |
| /models | ctrl+x m | 列出可用模型 |
| /new / /clear | ctrl+x n | 开始新会话 |
| /redo | ctrl+x r | 重做 |
| /sessions / /resume / /continue | ctrl+x l | 列出并切换会话 |
| /share | ctrl+x s | 分享当前会话 |
| /themes | ctrl+x t | 列出可用主题 |
| /thinking | – | 切换思考块显示 |
| /undo | ctrl+x u | 撤销 |
| /unshare | – | 取消分享 |
3.4.2 自定义命令
创建命令文件:
在 .opencode/commands/ 目录下创建 Markdown 文件,例如 test.md:
—
description: 运行测试并生成覆盖率报告
agent: build
model: anthropic/claude-3-5-sonnet-20241022
—
运行完整的测试套件并生成覆盖率报告,显示失败的测试。
重点关注失败的测试并提出修复建议。
使用命令:
/test
带参数的命令:
—
description: 创建新组件
—
创建一个名为 $ARGUMENTS 的新 React 组件,使用 TypeScript。
包含正确的类型定义和基本结构。
使用:
/component Button
$ARGUMENTS 会被替换为 Button。
位置参数:
- $1 – 第一个参数
- $2 – 第二个参数
- $3 – 第三个参数
- 依此类推…
注入 Shell 输出:
使用 !command 注入 bash 命令输出:
—
description: 分析测试覆盖率
—
当前测试结果:
!`npm test`
基于这些结果,建议如何提高覆盖率。
引用文件:
使用 @filename 包含文件:
—
description: 审查组件
—
审查 @src/components/Button.tsx 中的组件。
检查性能问题并提出改进建议。
3.5 工作流示例
3.5.1 添加新功能(推荐工作流程)
制定计划(Plan Mode)
- 按 Tab 键切换到"计划模式"
- 描述功能需求:
当用户删除笔记时,我们希望在数据库中将其标记为已删除。
然后创建一个页面显示所有最近删除的笔记。
用户可以在这个页面恢复笔记或永久删除。
- OpenCode 会给出实施计划
迭代计划
- 对计划提供反馈或添加细节
- 可以拖拽图片作为参考
执行构建(Build Mode)
- 再次按 Tab 键切换回"构建模式"
- 让 OpenCode 执行:
听起来不错!开始实施吧。
3.5.5 Plan-Build 工作流程图
渲染错误: Mermaid 渲染失败: Parse error on line 2: …scribe[1. 描述需求
"我要添加…"] D ———————–^ Expecting 'SQE', 'DOUBLECIRCLEEND', 'PE', '-)', 'STADIUMEND', 'SUBROUTINEEND', 'PIPE', 'CYLINDEREND', 'DIAMOND_STOP', 'TAGEND', 'TRAPEND', 'INVTRAPEND', 'UNICODE_TEXT', 'TEXT', 'TAGSTART', got 'STR'
3.5.2 代码审查
使用 Plan 智能体进行代码审查:
请审查 @src/components 目录下的所有组件代码,
关注安全性、性能和可维护性问题。
3.5.3 修复 Bug
项目中有用户报告了登录问题。
请帮我找到相关的认证代码并诊断问题。
3.5.4 重构代码
请重构 @src/utils/helpers.ts 文件,
使其更易于测试和维护。
第四部分:高级配置
4.1 规则与 AGENTS.md
4.1.1 什么是 AGENTS.md?
AGENTS.md 文件包含给 OpenCode 的自定义指令,类似于 Cursor 的规则。它帮助 OpenCode 理解你的项目结构和编码规范。
4.1.2 创建 AGENTS.md
运行 /init 命令会自动扫描项目并生成 AGENTS.md。
手动创建示例:
# SST v3 Monorepo 项目
这是一个使用 TypeScript 的 SST v3 monorepo。项目使用 bun workspaces 进行包管理。
## 项目结构
– `packages/` – 包含所有工作区包(functions、core、web 等)
– `infra/` – 基础设施定义,按服务分割(storage.ts、api.ts、web.ts)
– `sst.config.ts` – 主 SST 配置,使用动态导入
## 代码规范
– 使用 TypeScript,启用严格模式
– 共享代码放在 `packages/core/`,配置正确的导出
– 函数放在 `packages/functions/`
– 基础设施应该分割成逻辑文件放在 `infra/`
## Monorepo 约定
– 使用工作区名称导入共享模块:`@my-app/core/example`
4.1.3 AGENTS.md 位置
OpenCode 支持从多个位置读取规则:
优先级:
- 从当前目录向上遍历查找 AGENTS.md / CLAUDE.md
- 然后查找全局文件 ~/.config/opencode/AGENTS.md
- 最后查找 ~/.claude/CLAUDE.md(除非禁用)
4.1.4 引用外部文件
方法 1:使用 opencode.json
{
"$schema": "https://opencode.ai/config.json",
"instructions": ["CONTRIBUTING.md", "docs/guidelines.md", ".cursor/rules/*.md"]
}
方法 2:在 AGENTS.md 中指示
# 外部文件加载
关键:当遇到文件引用(如 @rules/general.md)时,
使用 Read 工具按需加载。与当前任务相关的才加载。
## 开发指南
TypeScript 代码风格:@docs/typescript-guidelines.md
React 组件架构:@docs/react-patterns.md
API 设计:@docs/api-standards.md
4.1.5 禁用 Claude Code 兼容性
export OPENCODE_DISABLE_CLAUDE_CODE=1 # 禁用所有 .claude 支持
export OPENCODE_DISABLE_CLAUDE_CODE_PROMPT=1 # 仅禁用 ~/.claude/CLAUDE.md
export OPENCODE_DISABLE_CLAUDE_CODE_SKILLS=1 # 仅禁用 .claude/skills
4.2 主题系统
4.2.1 终端要求
主题需要支持真彩色(24-bit color)的终端。检查:
echo $COLORTERM
应该输出 truecolor 或 24bit。
4.2.2 内置主题
| system | 自动适应终端背景色 |
| tokyonight | 基于 TokyoNight 主题 |
| everforest | 基于 Everforest 主题 |
| ayu | 基于 Ayu 暗色主题 |
| catppuccin | 基于 Catppuccin 主题 |
| catppuccin-macchiato | Catppuccin Macchiato 变体 |
| gruvbox | 基于 Gruvbox 主题 |
| kanagawa | 基于 Kanagawa 主题 |
| nord | 基于 Nord 主题 |
| matrix | 黑客风格绿色主题 |
| one-dark | 基于 Atom One Dark |
4.2.3 使用主题
/theme
或在配置中设置:
{
"theme": "tokyonight"
}
4.2.4 创建自定义主题
创建 JSON 文件在 .opencode/themes/ 或 ~/.config/opencode/themes/:
{
"$schema": "https://opencode.ai/theme.json",
"defs": {
"nord0": "#2E3440",
"nord1": "#3B4252",
"nord4": "#D8DEE9",
"nord8": "#88C0D0",
"nord11": "#BF616A",
"nord14": "#A3BE8C"
},
"theme": {
"primary": {
"dark": "nord8",
"light": "nord10"
},
"text": {
"dark": "nord4",
"light": "nord0"
},
"background": {
"dark": "nord0",
"light": "nord6"
},
"error": {
"dark": "nord11",
"light": "nord11"
},
"success": {
"dark": "nord14",
"light": "nord14"
}
}
}
颜色定义格式:
- Hex 颜色:"#ffffff"
- ANSI 颜色:3(0-255)
- 颜色引用:"primary" 或自定义定义
- 暗/亮变体:{"dark": "#000", "light": "#fff"}
- 无颜色:"none" – 使用终端默认颜色
4.3 按键绑定
4.3.1 Leader 键
默认使用 ctrl+x 作为 Leader 键,避免与终端快捷键冲突。
4.3.2 配置快捷键
{
"$schema": "https://opencode.ai/config.json",
"keybinds": {
"leader": "ctrl+x",
"app_exit": "ctrl+c,ctrl+d,<leader>q",
"editor_open": "<leader>e",
"theme_list": "<leader>t",
"session_new": "<leader>n",
"session_list": "<leader>l",
"session_share": "<leader>s",
"session_compact": "<leader>c",
"messages_undo": "<leader>u",
"messages_redo": "<leader>r",
"model_list": "<leader>m",
"agent_list": "<leader>a",
"command_list": "ctrl+p",
"agent_cycle": "tab",
"agent_cycle_reverse": "shift+tab",
"variant_cycle": "ctrl+t",
"input_submit": "return",
"input_newline": "shift+return,ctrl+return,alt+return,ctrl+j"
}
}
语法:
- <leader> – 引用 leader 键
- , – 分隔多个按键组合
- + – 表示同时按下
- none – 禁用该快捷键
4.3.3 禁用快捷键
{
"keybinds": {
"session_compact": "none"
}
}
4.3.4 桌面应用快捷键
桌面应用提示框支持常见的 Readline/Emacs 风格快捷键:
| ctrl+a | 移动到行首 |
| ctrl+e | 移动到行尾 |
| ctrl+b | 光标后退一个字符 |
| ctrl+f | 光标前进一个字符 |
| alt+b | 光标后退一个单词 |
| alt+f | 光标前进一个单词 |
| ctrl+d | 删除光标下字符 |
| ctrl+k | 删除到行尾 |
| ctrl+u | 删除到行首 |
| ctrl+w | 删除前一个单词 |
| alt+d | 删除下一个单词 |
| ctrl+t | 交换字符 |
| ctrl+g | 取消弹窗/中止运行 |
4.3.5 Windows Terminal 的 Shift+Enter
Windows Terminal 默认不发送 Shift+Enter。需要配置:
编辑 %LOCALAPPDATA%\\Packages\\Microsoft.WindowsTerminal_8wekyb3d8bbwe\\LocalState\\settings.json:
{
"actions": [
{
"command": {
"action": "sendInput",
"input": "\\u001b[13;2u"
},
"id": "User.sendInput.ShiftEnterCustom"
}
],
"keybindings": [
{
"keys": "shift+enter",
"id": "User.sendInput.ShiftEnterCustom"
}
]
}
4.4 格式化器
4.4.1 内置格式化器
| gofmt | .go | gofmt 命令可用 |
| mix | .ex, .exs, .eex, .heex | mix 命令可用 |
| prettier | .js, .jsx, .ts, .tsx, .html, .css, .md | package.json 中有 prettier 依赖 |
| biome | 同上 | biome.json(c) 配置文件 |
| zig | .zig, .zon | zig 命令可用 |
| clang-format | .c, .cpp, .h, .hpp | .clang-format 配置文件 |
| ktlint | .kt, .kts | ktlint 命令可用 |
| ruff | .py, .pyi | ruff 命令可用 |
| rustfmt | .rs | rustfmt 命令可用 |
| cargofmt | .rs | cargo fmt 命令可用 |
| uv | .py, .pyi | uv 命令可用 |
| rubocop | .rb, .rake | rubocop 命令可用 |
| standardrb | .rb | standardrb 命令可用 |
| htmlbeautifier | .erb | htmlbeautifier 命令可用 |
| air | .R | air 命令可用 |
| dart | .dart | dart 命令可用 |
| ocamlformat | .ml, .mli | .ocamlformat 配置文件 |
| terraform | .tf, .tfvars | terraform 命令可用 |
| gleam | .gleam | gleam 命令可用 |
| nixfmt | .nix | nixfmt 命令可用 |
| shfmt | .sh, .bash | shfmt 命令可用 |
| pint | .php | composer.json 中有 laravel/pint |
| ormolu | .hs | ormolu 命令可用 |
4.4.2 工作原理
当 OpenCode 写入或编辑文件时:
4.4.3 配置格式化器
{
"$schema": "https://opencode.ai/config.json",
"formatter": {
"prettier": {
"disabled": true
},
"custom-prettier": {
"command": ["npx", "prettier", "–write", "$FILE"],
"environment": {
"NODE_ENV": "development"
},
"extensions": [".js", ".ts", ".jsx", ".tsx"]
}
}
}
$FILE 占位符会被替换为正在格式化的文件路径。
4.4.4 禁用格式化器
禁用所有格式化器:
{
"formatter": false
}
禁用特定格式化器:
{
"formatter": {
"prettier": {
"disabled": true
}
}
}
4.5 权限系统
4.5.1 权限动作
每个权限规则解析为以下之一:
- "allow" – 无需批准直接运行
- "ask" – 提示请求批准
- "deny" – 阻止动作
4.5.2 全局权限配置
{
"$schema": "https://opencode.ai/config.json",
"permission": {
"*": "ask",
"bash": "allow",
"edit": "deny"
}
}
设置所有权限:
{
"permission": "allow"
}
4.5.3 细粒度规则(对象语法)
{
"permission": {
"bash": {
"*": "ask",
"git *": "allow",
"npm *": "allow",
"rm *": "deny",
"grep *": "allow"
},
"edit": {
"*": "deny",
"packages/web/src/content/docs/*.mdx": "allow"
}
}
}
规则评估: 按模式匹配,最后匹配的规则获胜。常见模式是先把 "*" 规则放第一,更具体的规则放后面。
4.5.4 通配符匹配
- * 匹配零个或多个任意字符
- ? 匹配恰好一个字符
- 其他字符按字面匹配
4.5.5 家目录扩展
可以使用 ~ 或 $HOME 引用家目录:
- ~/projects/* -> /Users/username/projects/*
- $HOME/projects/* -> /Users/username/projects/*
4.5.6 外部目录权限
使用 external_directory 允许工具访问项目工作目录之外的路径:
{
"permission": {
"external_directory": {
"~/projects/personal/**": "allow"
},
"edit": {
"~/projects/personal/**": "deny"
}
}
}
4.5.7 可用权限
- read – 读取文件(匹配文件路径)
- edit – 所有文件修改(覆盖 edit、write、patch、multiedit)
- glob – 文件 globbing(匹配 glob 模式)
- grep – 内容搜索(匹配正则模式)
- list – 列出目录文件(匹配目录路径)
- bash – 运行 shell 命令(匹配解析后的命令)
- task – 启动子智能体(匹配子智能体类型)
- skill – 加载技能(匹配技能名称)
- lsp – 运行 LSP 查询(当前非细粒度)
- todoread / todowrite – 读取/更新待办列表
- webfetch – 获取 URL(匹配 URL)
- websearch / codesearch – 网页/代码搜索
- external_directory – 工具访问项目外路径时触发
- doom_loop – 相同工具调用重复 3 次时触发
4.5.8 默认权限
- 大多数权限默认为 "allow"
- doom_loop 和 external_directory 默认为 "ask"
- read 默认为 "allow",但 .env 文件默认被拒绝:
{
"permission": {
"read": {
"*": "allow",
"*.env": "deny",
"*.env.*": "deny",
"*.env.example": "allow"
}
}
}
4.5.9 “Ask” 的工作方式
当 OpenCode 请求批准时,UI 提供三个选项:
- once – 仅批准这次请求
- always – 批准未来匹配建议模式的请求(当前会话剩余时间)
- reject – 拒绝请求
always 会批准的模式由工具提供(例如,bash 批准通常会将安全命令前缀如 git status* 加入白名单)。
4.5.11 权限决策流程图
#mermaid-svg-hjC9P7uHs8HZzvIZ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-hjC9P7uHs8HZzvIZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-hjC9P7uHs8HZzvIZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-hjC9P7uHs8HZzvIZ .error-icon{fill:#552222;}#mermaid-svg-hjC9P7uHs8HZzvIZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hjC9P7uHs8HZzvIZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-hjC9P7uHs8HZzvIZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hjC9P7uHs8HZzvIZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hjC9P7uHs8HZzvIZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-hjC9P7uHs8HZzvIZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hjC9P7uHs8HZzvIZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hjC9P7uHs8HZzvIZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hjC9P7uHs8HZzvIZ .marker.cross{stroke:#333333;}#mermaid-svg-hjC9P7uHs8HZzvIZ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hjC9P7uHs8HZzvIZ p{margin:0;}#mermaid-svg-hjC9P7uHs8HZzvIZ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-hjC9P7uHs8HZzvIZ .cluster-label text{fill:#333;}#mermaid-svg-hjC9P7uHs8HZzvIZ .cluster-label span{color:#333;}#mermaid-svg-hjC9P7uHs8HZzvIZ .cluster-label span p{background-color:transparent;}#mermaid-svg-hjC9P7uHs8HZzvIZ .label text,#mermaid-svg-hjC9P7uHs8HZzvIZ span{fill:#333;color:#333;}#mermaid-svg-hjC9P7uHs8HZzvIZ .node rect,#mermaid-svg-hjC9P7uHs8HZzvIZ .node circle,#mermaid-svg-hjC9P7uHs8HZzvIZ .node ellipse,#mermaid-svg-hjC9P7uHs8HZzvIZ .node polygon,#mermaid-svg-hjC9P7uHs8HZzvIZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hjC9P7uHs8HZzvIZ .rough-node .label text,#mermaid-svg-hjC9P7uHs8HZzvIZ .node .label text,#mermaid-svg-hjC9P7uHs8HZzvIZ .image-shape .label,#mermaid-svg-hjC9P7uHs8HZzvIZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-hjC9P7uHs8HZzvIZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-hjC9P7uHs8HZzvIZ .rough-node .label,#mermaid-svg-hjC9P7uHs8HZzvIZ .node .label,#mermaid-svg-hjC9P7uHs8HZzvIZ .image-shape .label,#mermaid-svg-hjC9P7uHs8HZzvIZ .icon-shape .label{text-align:center;}#mermaid-svg-hjC9P7uHs8HZzvIZ .node.clickable{cursor:pointer;}#mermaid-svg-hjC9P7uHs8HZzvIZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-hjC9P7uHs8HZzvIZ .arrowheadPath{fill:#333333;}#mermaid-svg-hjC9P7uHs8HZzvIZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hjC9P7uHs8HZzvIZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hjC9P7uHs8HZzvIZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hjC9P7uHs8HZzvIZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-hjC9P7uHs8HZzvIZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hjC9P7uHs8HZzvIZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-hjC9P7uHs8HZzvIZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hjC9P7uHs8HZzvIZ .cluster text{fill:#333;}#mermaid-svg-hjC9P7uHs8HZzvIZ .cluster span{color:#333;}#mermaid-svg-hjC9P7uHs8HZzvIZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hjC9P7uHs8HZzvIZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-hjC9P7uHs8HZzvIZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-hjC9P7uHs8HZzvIZ .icon-shape,#mermaid-svg-hjC9P7uHs8HZzvIZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hjC9P7uHs8HZzvIZ .icon-shape p,#mermaid-svg-hjC9P7uHs8HZzvIZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-hjC9P7uHs8HZzvIZ .icon-shape rect,#mermaid-svg-hjC9P7uHs8HZzvIZ .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hjC9P7uHs8HZzvIZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-hjC9P7uHs8HZzvIZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-hjC9P7uHs8HZzvIZ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
deny
allow/ask
deny
allow
ask
once
always
reject
工具调用
检查全局权限permission.*
拒绝执行
检查智能体权限agent.permission
拒绝执行
执行工具
显示权限提示等待用户确认
用户决策
执行一次
加入白名单以后自动允许
拒绝执行
执行成功
流程说明:
4.5.10 智能体权限覆盖
可以在智能体配置中覆盖全局权限:
{
"permission": {
"bash": {
"*": "ask",
"git *": "allow"
}
},
"agent": {
"build": {
"permission": {
"bash": {
"*": "ask",
"git *": "allow",
"git commit *": "ask"
}
}
}
}
}
也可以在 Markdown 智能体中设置:
—
description: 代码审查
mode: subagent
permission:
edit: deny
bash: ask
—
4.6 MCP 服务器
MCP(Model Context Protocol)允许你添加外部工具和服务到 OpenCode。
4.6.1 启用 MCP 服务器
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"name-of-mcp-server": {
"enabled": true
}
}
}
注意: MCP 服务器会增加上下文,谨慎选择要启用的服务器。
4.6.2 本地 MCP 服务器
{
"mcp": {
"my-local-mcp-server": {
"type": "local",
"command": ["npx", "-y", "my-mcp-command"],
"enabled": true,
"environment": {
"MY_ENV_VAR": "my_env_var_value"
},
"timeout": 5000
}
}
}
示例 – 测试服务器:
{
"mcp": {
"mcp_everything": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-everything"]
}
}
}
4.6.3 远程 MCP 服务器
{
"mcp": {
"my-remote-mcp": {
"type": "remote",
"url": "https://my-mcp-server.com",
"enabled": true,
"headers": {
"Authorization": "Bearer MY_API_KEY"
},
"timeout": 5000
}
}
}
4.6.4 OAuth 认证
OpenCode 自动处理远程 MCP 服务器的 OAuth 认证。
自动 OAuth:
{
"mcp": {
"my-oauth-server": {
"type": "remote",
"url": "https://mcp.example.com/mcp"
}
}
}
预注册客户端:
{
"mcp": {
"my-oauth-server": {
"type": "remote",
"url": "https://mcp.example.com/mcp",
"oauth": {
"clientId": "{env:MY_MCP_CLIENT_ID}",
"clientSecret": "{env:MY_MCP_CLIENT_SECRET}",
"scope": "tools:read tools:execute"
}
}
}
}
手动认证:
opencode mcp auth my-oauth-server
opencode mcp list
opencode mcp logout my-oauth-server
禁用 OAuth:
{
"mcp": {
"my-api-key-server": {
"type": "remote",
"url": "https://mcp.example.com/mcp",
"oauth": false,
"headers": {
"Authorization": "Bearer {env:MY_API_KEY}"
}
}
}
}
4.6.5 管理 MCP 服务器
全局禁用:
{
"mcp": { … },
"tools": {
"my-mcp*": false
}
}
按智能体启用:
{
"mcp": { … },
"tools": {
"my-mcp*": false
},
"agent": {
"my-agent": {
"tools": {
"my-mcp*": true
}
}
}
}
4.6.7 MCP 架构图
渲染错误: Mermaid 渲染失败: Parse error on line 21: … –> B B –> 本地 MCP B –> 远程 MCP ———————-^ Expecting 'SEMI', 'NEWLINE', 'EOF', 'AMP', 'START_LINK', 'LINK', 'LINK_ID', got 'NODE_STRING'
4.6.6 示例 MCP 服务器
Sentry:
{
"mcp": {
"sentry": {
"type": "remote",
"url": "https://mcp.sentry.dev/mcp",
"oauth": {}
}
}
}
然后运行 opencode mcp auth sentry 认证。
Context7(文档搜索):
{
"mcp": {
"context7": {
"type": "remote",
"url": "https://mcp.context7.com/mcp",
"headers": {
"CONTEXT7_API_KEY": "{env:CONTEXT7_API_KEY}"
}
}
}
}
Grep by Vercel(GitHub 代码搜索):
{
"mcp": {
"gh_grep": {
"type": "remote",
"url": "https://mcp.grep.app"
}
}
}
4.7 LSP 服务器
OpenCode 集成了语言服务器协议(LSP)来帮助 LLM 与你的代码库交互。
4.7.1 内置 LSP 服务器
| astro | .astro | 自动安装 |
| bash | .sh, .bash, .zsh | 自动安装 bash-language-server |
| clangd | .c, .cpp, .h, .hpp | 自动安装 |
| csharp | .cs | .NET SDK 已安装 |
| clojure-lsp | .clj, .cljs | clojure-lsp 命令可用 |
| dart | .dart | dart 命令可用 |
| deno | .ts, .tsx, .js | deno 命令可用 |
| elixir-ls | .ex, .exs | elixir 命令可用 |
| eslint | .ts, .tsx, .js | eslint 项目依赖 |
| fsharp | .fs, .fsi | .NET SDK 已安装 |
| gleam | .gleam | gleam 命令可用 |
| gopls | .go | go 命令可用 |
| hls | .hs, .lhs | haskell-language-server-wrapper |
| jdtls | .java | Java SDK 21+ |
| kotlin-ls | .kt, .kts | 自动安装 |
| lua-ls | .lua | 自动安装 |
| nixd | .nix | nixd 命令可用 |
| ocaml-lsp | .ml, .mli | ocamllsp 命令可用 |
| oxlint | .ts, .tsx, .js | oxlint 项目依赖 |
| php intelephense | .php | 自动安装 |
| prisma | .prisma | prisma 命令可用 |
| pyright | .py, .pyi | pyright 依赖已安装 |
| ruby-lsp | .rb, .rake | ruby 和 gem 命令可用 |
| rust | .rs | rust-analyzer 命令可用 |
| sourcekit-lsp | .swift | swift 已安装 |
| svelte | .svelte | 自动安装 |
| terraform | .tf, .tfvars | 自动安装 |
| tinymist | .typ, .typc | 自动安装 |
| typescript | .ts, .tsx, .js | typescript 项目依赖 |
| vue | .vue | 自动安装 |
| yaml-ls | .yaml, .yml | 自动安装 |
| zls | .zig, .zon | zig 命令可用 |
4.7.2 工作原理
当 OpenCode 打开文件时:
4.7.3 配置 LSP 服务器
{
"$schema": "https://opencode.ai/config.json",
"lsp": {
"typescript": {
"disabled": false,
"command": ["typescript-language-server", "–stdio"],
"extensions": [".ts", ".tsx", ".js", ".jsx"],
"env": {
"NODE_ENV": "development"
},
"initialization": {
"preferences": {
"importModuleSpecifierPreference": "relative"
}
}
}
}
}
4.7.4 环境变量
{
"lsp": {
"rust": {
"env": {
"RUST_LOG": "debug"
}
}
}
}
4.7.5 初始化选项
{
"lsp": {
"typescript": {
"initialization": {
"preferences": {
"importModuleSpecifierPreference": "relative"
}
}
}
}
}
4.7.6 禁用 LSP 服务器
禁用所有:
{
"lsp": false
}
禁用特定服务器:
{
"lsp": {
"typescript": {
"disabled": true
}
}
}
4.7.7 自定义 LSP 服务器
{
"lsp": {
"custom-lsp": {
"command": ["custom-lsp-server", "–stdio"],
"extensions": [".custom"]
}
}
}
4.7.8 PHP Intelephense 许可证
PHP Intelephense 提供付费功能。将许可证密钥放在:
- macOS/Linux: $HOME/intelephense/licence.txt
- Windows: %USERPROFILE%/intelephense/licence.txt
4.8 技能系统(Agent Skills)
技能允许你定义可重用的行为。
4.8.1 放置文件
创建技能文件夹,内部放置 SKILL.md:
- .opencode/skills/<name>/SKILL.md – 项目配置
- ~/.config/opencode/skills/<name>/SKILL.md – 全局配置
- .claude/skills/<name>/SKILL.md – Claude 兼容
- ~/.claude/skills/<name>/SKILL.md – Claude 全局兼容
4.8.2 发现机制
对于项目本地路径,OpenCode 从当前工作目录向上遍历到 git 工作树,加载 .opencode/skills/*/SKILL.md 和 .claude/skills/*/SKILL.md。
全局定义从 ~/.config/opencode/skills/*/SKILL.md 和 ~/.claude/skills/*/SKILL.md 加载。
4.8.3 编写 Frontmatter
每个 SKILL.md 必须以 YAML frontmatter 开头:
- name(必填)
- description(必填)
- license(可选)
- compatibility(可选)
- metadata(可选,字符串到字符串的映射)
4.8.4 名称验证
name 必须:
- 1-64 个字符
- 小写字母数字,单连字符分隔
- 不以 – 开头或结尾
- 不包含连续的 —
- 与包含 SKILL.md 的目录名匹配
正则表达式:^[a-z0-9]+(-[a-z0-9]+)*$
4.8.5 长度规则
description 必须 1-1024 个字符。
4.8.6 示例
.opencode/skills/git-release/SKILL.md:
—
name: git-release
description: 创建一致的发布和变更日志
license: MIT
compatibility: opencode
metadata:
audience: maintainers
workflow: github
—
## 我做什么
– 从合并的 PR 起草发布说明
– 提议版本升级
– 提供可复制的 `gh release create` 命令
## 何时使用我
准备打标签发布时使用。
如果不清楚目标版本方案,询问澄清问题。
4.8.7 工具描述
OpenCode 在 skill 工具描述中列出可用技能:
<available_skills>
<skill>
<name>git-release</name>
<description>创建一致的发布和变更日志</description>
</skill>
</available_skills>
智能体通过调用工具加载技能:
skill({ name: "git-release" })
4.8.8 配置权限
{
"permission": {
"skill": {
"*": "allow",
"pr-review": "allow",
"internal-*": "deny",
"experimental-*": "ask"
}
}
}
4.8.9 按智能体覆盖
自定义智能体 frontmatter:
—
permission:
skill:
"documents-*": "allow"
—
内置智能体(在 opencode.json 中):
{
"agent": {
"plan": {
"permission": {
"skill": {
"internal-*": "allow"
}
}
}
}
}
4.8.10 禁用技能工具
自定义智能体:
—
tools:
skill: false
—
内置智能体:
{
"agent": {
"plan": {
"tools": {
"skill": false
}
}
}
}
4.9 插件系统
4.9.1 使用插件
从本地文件:
- .opencode/plugins/ – 项目级插件
- ~/.config/opencode/plugins/ – 全局插件
从 npm:
{
"plugin": ["opencode-helicone-session", "opencode-wakatime", "@my-org/custom-plugin"]
}
加载顺序:
安装方式:
- npm 插件使用 Bun 自动安装在 ~/.cache/opencode/node_modules/
- 本地插件直接从插件目录加载
4.9.2 创建插件
插件是导出插件函数的 JavaScript/TypeScript 模块。
依赖: 在配置目录添加 package.json:
{
"dependencies": {
"shescape": "^2.1.0"
}
}
基本结构:
export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
console.log("Plugin initialized!")
return {
// Hook 实现放在这里
}
}
上下文对象:
- project: 当前项目信息
- directory: 当前工作目录
- worktree: git 工作树路径
- client: OpenCode SDK 客户端
- $: Bun 的 shell API
TypeScript 支持:
import type { Plugin } from "@opencode-ai/plugin"
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
return {
// 类型安全的 hook 实现
}
}
4.9.3 事件列表
命令事件:
- command.executed
文件事件:
- file.edited
- file.watcher.updated
安装事件:
- installation.updated
LSP 事件:
- lsp.client.diagnostics
- lsp.updated
消息事件:
- message.part.removed
- message.part.updated
- message.removed
- message.updated
权限事件:
- permission.asked
- permission.replied
服务器事件:
- server.connected
会话事件:
- session.created
- session.compacted
- session.deleted
- session.diff
- session.error
- session.idle
- session.status
- session.updated
待办事件:
- todo.updated
工具事件:
- tool.execute.after
- tool.execute.before
TUI 事件:
- tui.prompt.append
- tui.command.execute
- tui.toast.show
4.9.4 示例插件
发送通知:
export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => {
return {
event: async ({ event }) => {
if (event.type === "session.idle") {
await $`osascript -e 'display notification "Session completed!" with title "opencode"'`
}
}
}
}
.env 保护:
export const EnvProtection = async ({ project, client, $, directory, worktree }) => {
return {
"tool.execute.before": async (input, output) => {
if (input.tool === "read" && output.args.filePath.includes(".env")) {
throw new Error("Do not read .env files")
}
}
}
}
自定义工具:
import { type Plugin, tool } from "@opencode-ai/plugin"
export const CustomToolsPlugin: Plugin = async (ctx) => {
return {
tool: {
mytool: tool({
description: "This is a custom tool",
args: {
foo: tool.schema.string()
},
async execute(args, context) {
const { directory, worktree } = context
return `Hello ${args.foo} from ${directory} (worktree: ${worktree})`
}
})
}
}
}
日志:
export const MyPlugin = async ({ client }) => {
await client.app.log({
service: "my-plugin",
level: "info",
message: "Plugin initialized",
extra: { foo: "bar" }
})
}
压缩 Hook:
import type { Plugin } from "@opencode-ai/plugin"
export const CompactionPlugin: Plugin = async (ctx) => {
return {
"experimental.session.compacting": async (input, output) => {
output.context.push(`## Custom Context
Include any state that should persist across compaction:
– Current task status
– Important decisions made
– Files being actively worked on`)
}
}
}
4.10 自定义工具
4.10.1 创建工具
工具定义为 TypeScript 或 JavaScript 文件,可调用任何语言的脚本。
位置:
- .opencode/tools/ – 项目本地工具
- ~/.config/opencode/tools/ – 全局工具
4.10.2 结构
使用 tool() 辅助函数:
import { tool } from "@opencode-ai/plugin"
export default tool({
description: "Query the project database",
args: {
query: tool.schema.string().describe("SQL query to execute")
},
async execute(args) {
// 数据库逻辑
return `Executed query: ${args.query}`
}
})
文件名成为工具名。 上述创建 database 工具。
4.10.3 多个工具
单个文件可导出多个工具:
import { tool } from "@opencode-ai/plugin"
export const add = tool({
description: "Add two numbers",
args: {
a: tool.schema.number().describe("First number"),
b: tool.schema.number().describe("Second number")
},
async execute(args) {
return args.a + args.b
}
})
export const multiply = tool({
description: "Multiply two numbers",
args: {
a: tool.schema.number().describe("First number"),
b: tool.schema.number().describe("Second number")
},
async execute(args) {
return args.a * args.b
}
})
这创建两个工具:math_add 和 math_multiply。
4.10.4 参数定义
使用 tool.schema(即 Zod)定义参数类型:
args: {
query: tool.schema.string().describe("SQL query to execute")
}
也可以直接导入 Zod:
import { z } from "zod"
export default {
description: "Tool description",
args: {
param: z.string().describe("Parameter description")
},
async execute(args, context) {
return "result"
}
}
4.10.5 上下文
工具接收当前会话的上下文:
import { tool } from "@opencode-ai/plugin"
export default tool({
description: "Get project information",
args: {},
async execute(args, context) {
const { agent, sessionID, messageID, directory, worktree } = context
return `Agent: ${agent}, Session: ${sessionID}, Message: ${messageID}`
}
})
上下文属性:
- agent: 当前智能体名称
- sessionID: 会话 ID
- messageID: 消息 ID
- directory: 会话工作目录
- worktree: git 工作树根目录
4.10.6 Python 工具示例
先用 Python 编写脚本:
.opencode/tools/add.py:
import sys
a = int(sys.argv[1])
b = int(sys.argv[2])
print(a + b)
然后创建调用它的工具定义:
.opencode/tools/python-add.ts:
import { tool } from "@opencode-ai/plugin"
import path from "path"
export default tool({
description: "Add two numbers using Python",
args: {
a: tool.schema.number().describe("First number"),
b: tool.schema.number().describe("Second number")
},
async execute(args, context) {
const script = path.join(context.worktree, ".opencode/tools/add.py")
const result = await Bun.$`python3 ${script} ${args.a} ${args.b}`.text()
return result.trim()
}
})
第五部分:开发者文档
5.1 服务器(Server)
5.1.1 概述
opencode serve 命令运行一个无头 HTTP 服务器,暴露 OpenAPI 端点供 OpenCode 客户端使用。
5.1.2 用法
opencode serve [–port <number>] [–hostname <string>] [–cors <origin>]
选项:
| –port | 监听端口 | 4096 |
| –hostname | 监听主机名 | 127.0.0.1 |
| –mdns | 启用 mDNS 发现 | false |
| –cors | 允许的额外浏览器来源 | [] |
多 CORS 来源:
opencode serve –cors http://localhost:5173 –cors https://app.example.com
5.1.3 认证
设置 OPENCODE_SERVER_PASSWORD 启用 HTTP 基本认证:
OPENCODE_SERVER_PASSWORD=your-password opencode serve
用户名默认为 opencode,可使用 OPENCODE_SERVER_USERNAME 覆盖。
5.1.4 工作原理
运行 opencode 时,它会启动 TUI 和服务器。TUI 作为客户端与服务器通信。服务器暴露 OpenAPI 3.1 规范端点,也用于生成 SDK。
连接到现有服务器:
TUI 默认随机分配端口和主机名。可以传入 –hostname 和 –port 标志:
opencode –hostname 0.0.0.0 –port 4096
然后使用 opencode attach http://localhost:4096 连接。
5.1.5 OpenAPI 规范
服务器在 http://<hostname>:<port>/doc 发布 OpenAPI 3.1 规范。
5.1.6 API 列表
全局 API:
- GET /global/health – 获取服务器健康和版本
- GET /global/event – 获取全局事件(SSE 流)
项目 API:
- GET /project – 列出所有项目
- GET /project/current – 获取当前项目
路径和版本控制:
- GET /path – 获取当前路径
- GET /vcs – 获取当前项目的版本控制信息
实例:
- POST /instance/dispose – 处置当前实例
配置:
- GET /config – 获取配置信息
- PATCH /config – 更新配置
- GET /config/providers – 列出提供商和默认模型
提供商:
- GET /provider – 列出所有提供商
- GET /provider/auth – 获取提供商认证方法
- POST /provider/{id}/oauth/authorize – OAuth 授权
- POST /provider/{id}/oauth/callback – OAuth 回调
会话:
- GET /session – 列出所有会话
- POST /session – 创建新会话
- GET /session/status – 获取所有会话状态
- GET /session/:id – 获取会话详情
- DELETE /session/:id – 删除会话
- PATCH /session/:id – 更新会话属性
- GET /session/:id/children – 获取子会话
- GET /session/:id/todo – 获取待办列表
- POST /session/:id/init – 分析应用并创建 AGENTS.md
- POST /session/:id/fork – Fork 现有会话
- POST /session/:id/abort – 中止运行中的会话
- POST /session/:id/share – 分享会话
- DELETE /session/:id/share – 取消分享
- GET /session/:id/diff – 获取会话差异
- POST /session/:id/summarize – 总结会话
- POST /session/:id/revert – 恢复消息
- POST /session/:id/unrevert – 取消恢复
消息:
- GET /session/:id/message – 列出会话中的消息
- POST /session/:id/message – 发送消息并等待响应
- GET /session/:id/message/:messageID – 获取消息详情
- POST /session/:id/prompt_async – 异步发送消息
- POST /session/:id/command – 执行斜杠命令
- POST /session/:id/shell – 运行 shell 命令
命令:
- GET /command – 列出所有命令
文件:
- GET /find?pattern=<pat> – 在文件中搜索文本
- GET /find/file?query=<q> – 按名称查找文件和目录
- GET /find/symbol?query=<q> – 查找工作区符号
- GET /file?path=<path> – 列出文件和目录
- GET /file/content?path=<p> – 读取文件
- GET /file/status – 获取跟踪文件状态
工具(实验性):
- GET /experimental/tool/ids – 列出所有工具 ID
- GET /experimental/tool?provider=<p>&model=<m> – 列出模型的工具
LSP、格式化器和 MCP:
- GET /lsp – 获取 LSP 服务器状态
- GET /formatter – 获取格式化器状态
- GET /mcp – 获取 MCP 服务器状态
- POST /mcp – 动态添加 MCP 服务器
智能体:
- GET /agent – 列出所有可用智能体
日志:
- POST /log – 写入日志条目
TUI:
- POST /tui/append-prompt – 追加文本到提示
- POST /tui/open-help – 打开帮助对话框
- POST /tui/open-sessions – 打开会话选择器
- POST /tui/open-themes – 打开主题选择器
- POST /tui/open-models – 打开模型选择器
- POST /tui/submit-prompt – 提交当前提示
- POST /tui/clear-prompt – 清除提示
- POST /tui/execute-command – 执行命令
- POST /tui/show-toast – 显示 toast
- GET /tui/control/next – 等待下一个控制请求
- POST /tui/control/response – 响应控制请求
认证:
- PUT /auth/:id – 设置认证凭证
事件:
- GET /event – 服务器发送的事件流
文档:
- GET /doc – OpenAPI 3.1 规范
5.1.7 Server 架构图
渲染错误: Mermaid 渲染失败: Parse error on line 22: … |HTTP/WS| OpenCode Server OpenCode ———————–^ Expecting 'SEMI', 'NEWLINE', 'EOF', 'AMP', 'START_LINK', 'LINK', 'LINK_ID', got 'NODE_STRING'
5.2 SDK
5.2.1 安装
npm install @opencode-ai/sdk
5.2.2 创建客户端
完整实例(服务器+客户端):
import { createOpencode } from "@opencode-ai/sdk"
const { client } = await createOpencode()
选项:
| hostname | string | 服务器主机名 | 127.0.0.1 |
| port | number | 服务器端口 | 4096 |
| signal | AbortSignal | 取消信号 | undefined |
| timeout | number | 服务器启动超时 | 5000 |
| config | Config | 配置对象 | {} |
仅客户端(连接到现有服务器):
import { createOpencodeClient } from "@opencode-ai/sdk"
const client = createOpencodeClient({
baseUrl: "http://localhost:4096"
})
仅客户端选项:
| baseUrl | string | 服务器 URL | http://localhost:4096 |
| fetch | function | 自定义 fetch 实现 | globalThis.fetch |
| parseAs | string | 响应解析方法 | auto |
| responseStyle | string | 返回风格:data 或 fields | fields |
| throwOnError | boolean | 抛出错误而非返回 | false |
5.2.3 配置
import { createOpencode } from "@opencode-ai/sdk"
const opencode = await createOpencode({
hostname: "127.0.0.1",
port: 4096,
config: {
model: "anthropic/claude-3-5-sonnet-20241022"
}
})
console.log(`Server running at ${opencode.server.url}`)
opencode.server.close()
5.2.4 类型
SDK 包含所有 API 类型的 TypeScript 定义:
import type { Session, Message, Part } from "@opencode-ai/sdk"
5.2.5 错误处理
try {
await client.session.get({ path: { id: "invalid-id" } })
} catch (error) {
console.error("Failed to get session:", (error as Error).message)
}
5.2.6 API 方法
全局:
- client.global.health() – 检查服务器健康和版本
应用:
- client.app.log() – 写入日志条目
- client.app.agents() – 列出所有可用智能体
项目:
- client.project.list() – 列出所有项目
- client.project.current() – 获取当前项目
路径:
- client.path.get() – 获取当前路径
配置:
- client.config.get() – 获取配置
- client.config.providers() – 列出提供商和默认模型
会话:
- client.session.list() – 列出会话
- client.session.get() – 获取会话
- client.session.children() – 列出子会话
- client.session.create() – 创建会话
- client.session.delete() – 删除会话
- client.session.update() – 更新会话
- client.session.init() – 分析应用并创建 AGENTS.md
- client.session.abort() – 中止会话
- client.session.share() – 分享会话
- client.session.unshare() – 取消分享
- client.session.summarize() – 总结会话
- client.session.messages() – 列出消息
- client.session.message() – 获取消息详情
- client.session.prompt() – 发送提示消息
- client.session.command() – 发送命令
- client.session.shell() – 运行 shell 命令
- client.session.revert() – 恢复消息
- client.session.unrevert() – 取消恢复
文件:
- client.find.text() – 在文件中搜索文本
- client.find.files() – 按名称查找文件
- client.find.symbols() – 查找工作区符号
- client.file.read() – 读取文件
- client.file.status() – 获取文件状态
TUI:
- client.tui.appendPrompt() – 追加文本到提示
- client.tui.openHelp() – 打开帮助
- client.tui.openSessions() – 打开会话选择器
- client.tui.openThemes() – 打开主题选择器
- client.tui.openModels() – 打开模型选择器
- client.tui.submitPrompt() – 提交提示
- client.tui.clearPrompt() – 清除提示
- client.tui.executeCommand() – 执行命令
- client.tui.showToast() – 显示 toast
认证:
- client.auth.set() – 设置认证凭证
事件:
- client.event.subscribe() – 订阅服务器发送的事件
5.2.7 示例
创建和管理会话:
const session = await client.session.create({
body: { title: "My session" }
})
const sessions = await client.session.list()
const result = await client.session.prompt({
path: { id: session.id },
body: {
model: { providerID: "anthropic", modelID: "claude-3-5-sonnet-20241022" },
parts: [{ type: "text", text: "Hello!" }]
}
})
// 仅注入上下文,不触发 AI 响应
await client.session.prompt({
path: { id: session.id },
body: {
noReply: true,
parts: [{ type: "text", text: "You are a helpful assistant." }]
}
})
搜索和读取文件:
const textResults = await client.find.text({
query: { pattern: "function.*opencode" }
})
const files = await client.find.files({
query: { query: "*.ts", type: "file" }
})
const directories = await client.find.files({
query: { query: "packages", type: "directory", limit: 20 }
})
const content = await client.file.read({
query: { path: "src/index.ts" }
})
控制 TUI:
await client.tui.appendPrompt({
body: { text: "Add this to prompt" }
})
await client.tui.showToast({
body: { message: "Task completed", variant: "success" }
})
设置认证:
await client.auth.set({
path: { id: "anthropic" },
body: { type: "api", key: "your-api-key" }
})
监听事件:
const events = await client.event.subscribe()
for await (const event of events.stream) {
console.log("Event:", event.type, event.properties)
}
5.3 Web 界面
5.3.1 启动 Web 界面
opencode web
这会启动本地服务器并自动在浏览器中打开 OpenCode。
注意: 如果未设置 OPENCODE_SERVER_PASSWORD,服务器将不安全。本地使用没问题,但网络访问应设置密码。
5.3.2 配置
端口:
opencode web –port 4096
主机名:
opencode web –hostname 0.0.0.0
显示:
Local access: http://localhost:4096
Network access: http://192.168.1.100:4096
mDNS 发现:
opencode web –mdns
自动设置主机名为 0.0.0.0 并广播为 opencode.local。
CORS:
opencode web –cors https://example.com
认证:
OPENCODE_SERVER_PASSWORD=secret opencode web
5.3.3 连接终端到 Web 服务器
# 启动 web 服务器
opencode web –port 4096
# 在另一个终端,连接 TUI
opencode attach http://localhost:4096
5.3.4 配置文件
{
"server": {
"port": 4096,
"hostname": "0.0.0.0",
"mdns": true,
"cors": ["https://example.com"]
}
}
5.4 IDE 集成
5.4.1 VS Code / Cursor / Windsurf / VSCodium
快速启动:
- Cmd+Esc(Mac)或 Ctrl+Esc(Windows/Linux):在分屏终端视图中打开 OpenCode
- Cmd+Shift+Esc 或 Ctrl+Shift+Esc:开始新的 OpenCode 终端会话
文件引用快捷键:
- Cmd+Option+K(Mac)或 Alt+Ctrl+K(Linux/Windows):插入文件引用,如 @File#L37-42
5.4.2 安装
手动安装: 在扩展市场搜索 OpenCode 并点击 Install。
5.4.3 故障排除
如果自动安装失败:
- 确保在集成终端中运行 opencode
- 确认安装了 IDE 的 CLI:
- VS Code: code 命令
- Cursor: cursor 命令
- Windsurf: windsurf 命令
- VSCodium: codium 命令
- 运行 Cmd+Shift+P(Mac)或 Ctrl+Shift+P(Windows/Linux),搜索 “Shell Command: Install ‘code’ command in PATH”
5.5 ACP 支持
OpenCode 支持 ACP(Agent Client Protocol),允许在兼容编辑器中直接使用。
5.5.1 Zed 配置
添加到 ~/.config/zed/settings.json:
{
"agent_servers": {
"OpenCode": {
"command": "opencode",
"args": ["acp"]
}
}
}
键盘快捷键在 keymap.json:
[{
"bindings": {
"cmd-alt-o": [
"agent::NewExternalAgentThread",
{
"agent": {
"custom": {
"name": "OpenCode",
"command": {
"command": "opencode",
"args": ["acp"]
}
}
}
}
]
}
}]
5.5.2 JetBrains IDEs
添加到 acp.json:
{
"agent_servers": {
"OpenCode": {
"command": "/absolute/path/bin/opencode",
"args": ["acp"]
}
}
}
5.5.3 Avante.nvim
{
acp_providers = {
["opencode"] = {
command = "opencode",
args = { "acp" },
env = {
OPENCODE_API_KEY = os.getenv("OPENCODE_API_KEY")
}
}
}
}
5.5.4 CodeCompanion.nvim
require("codecompanion").setup({
interactions = {
chat = {
adapter = {
name = "opencode",
model = "claude-sonnet-4",
},
},
},
})
5.6 GitHub 集成
5.6.1 功能
- 分类问题:让 OpenCode 查看问题并解释
- 修复和实现:让 OpenCode 修复问题或实现功能,在新分支工作并提交 PR
- 安全:OpenCode 在 GitHub runner 内运行
5.6.2 安装
opencode github install
这会引导你完成:
手动设置:
name: opencode
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
jobs:
opencode:
if: |
contains(github.event.comment.body, '/oc') ||
contains(github.event.comment.body, '/opencode')
runs-on: ubuntu–latest
permissions:
id-token: write
steps:
– name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 1
persist-credentials: false
– name: Run OpenCode
uses: anomalyco/opencode/github@latest
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
with:
model: anthropic/claude–sonnet–4–20250514
5.6.3 配置选项
- model(必填):使用的模型(格式:provider/model)
- agent:使用的智能体(必须是主要智能体)
- share:是否分享 OpenCode 会话(公共仓库默认 true)
- prompt:可选自定义提示词覆盖默认行为
- token:可选 GitHub 访问令牌(可用 GITHUB_TOKEN 或 PAT)
5.6.4 支持的事件
| issue_comment | 在问题或 PR 上评论 | 提及 /opencode 或 /oc |
| pull_request_review_comment | 在代码行上评论 | 提及 /opencode 或 /oc |
| issues | 问题打开或编辑 | 使用 prompt 自动触发 |
| pull_request | PR 打开或更新 | 自动触发审查 |
| schedule | 基于 cron 的计划 | 需要 prompt 输入 |
| workflow_dispatch | 手动触发 | 需要 prompt 输入 |
5.6.5 自定义提示词
– uses: anomalyco/opencode/github@latest
with:
model: anthropic/claude–sonnet–4–5
prompt: |
Review this pull request:
– Check for code quality issues
– Look for potential bugs
– Suggest improvements
5.6.6 示例
- 解释问题:/opencode explain this issue
- 修复问题:/opencode fix this
- 审查 PR:Delete the attachment from S3 when the note is removed /oc
- 审查特定代码行:在 PR “Files” 标签页的代码行上留言:/oc add error handling here
5.7 GitLab 集成
5.7.1 GitLab CI
使用社区创建的 CI/CD 组件:https://gitlab.com/nagyv/gitlab-opencode
功能:
- 每个作业使用自定义配置
- 最小设置:CI 组件在后台设置 OpenCode
- 灵活:支持多个输入自定义行为
设置:
将 OpenCode 认证 JSON 存储为文件类型 CI 环境变量 OPENCODE_AUTH_JSON(Settings > CI/CD > Variables,设置为 Masked 和 hidden)
添加到 .gitlab-ci.yml:
include:
– component: $CI_SERVER_FQDN/nagyv/gitlab–opencode/opencode@2
inputs:
config_dir: ${CI_PROJECT_DIR}/opencode–config
auth_json: $OPENCODE_AUTH_JSON
command: optional–custom–command
message: "Your prompt here"
5.7.2 GitLab Duo
在评论中提及 @opencode,OpenCode 会在 GitLab CI 管道中执行任务。
功能:
- 分类问题
- 修复和实现功能
- 安全:在 GitLab runner 上运行
设置: 需要配置 GitLab 环境、设置 CI/CD、获取 AI 模型提供商 API key、创建服务账户、配置 CI/CD 变量、创建流配置文件。
示例:
- @opencode explain this issue
- @opencode fix this
- @opencode review this merge request
5.8 生态系统
5.8.1 社区插件
| opencode-daytona | 在隔离的 Daytona sandboxes 中自动运行 OpenCode 会话 |
| opencode-helicone-session | 自动注入 Helicone 会话头用于请求分组 |
| opencode-type-inject | 自动将 TypeScript/Svelte 类型注入文件读取 |
| opencode-openai-codex-auth | 使用 ChatGPT Plus/Pro 订阅替代 API 计费 |
| opencode-gemini-auth | 使用现有 Gemini 计划替代 API 计费 |
| opencode-antigravity-auth | 使用 Antigravity 的免费模型 |
| opencode-devcontainers | 多分支 devcontainer 隔离,浅克隆 |
| opencode-google-antigravity-auth | Google Antigravity OAuth 插件带搜索支持 |
| opencode-dynamic-context-pruning | 通过剪枝过时工具输出优化 Token 使用 |
| opencode-websearch-cited | 为支持的提供商添加原生网页搜索 |
| opencode-pty | 允许 AI 代理在 PTY 中运行后台进程 |
| opencode-shell-strategy | 非交互式 shell 命令说明 |
| opencode-wakatime | 用 Wakatime 跟踪 OpenCode 使用 |
| opencode-md-table-formatter | 清理 LLM 产生的 markdown 表格 |
| opencode-morph-fast-apply | 用 Morph Fast Apply API 实现 10 倍更快的代码编辑 |
| oh-my-opencode | 后台代理,预建 LSP/AST/MCP 工具 |
| opencode-notificator | 桌面通知和声音提醒 |
| opencode-notifier | 权限/完成/错误事件的桌面通知 |
| opencode-zellij-namer | AI 驱动的自动 Zellij 会话命名 |
| opencode-skillful | 允许代理按需懒加载提示 |
| opencode-supermemory | 使用 Supermemory 实现跨会话持久记忆 |
| @plannotator/opencode | 带视觉注释的交互式计划审查 |
| @openspoon/subtask2 | 将 opencode /commands 扩展为编排系统 |
| opencode-scheduler | 使用 launchd 或 systemd 安排定期作业 |
| micode | 结构化的头脑风暴 → 计划 → 实现工作流 |
| octto | AI 头脑风暴的交互式浏览器 UI |
| opencode-background-agents | Claude Code 风格的后台代理 |
| opencode-notify | OpenCode 的原生 OS 通知 |
| opencode-workspace | 捆绑的多代理编排工具 |
| opencode-worktree | OpenCode 的零摩擦 git worktrees |
5.8.2 社区项目
| kimaki | 控制 OpenCode 会话的 Discord 机器人 |
| opencode.nvim | 编辑器感知提示的 Neovim 插件 |
| portal | 移动优先的 OpenCode Web UI |
| opencode plugin template | 构建 OpenCode 插件的模板 |
| ai-sdk-provider-opencode-sdk | OpenCode 的 Vercel AI SDK 提供商 |
| OpenChamber | Web/桌面应用和 VS Code 扩展 |
| OpenCode-Obsidian | OpenCode 的 Obsidian 插件 |
| OpenWork | Claude Cowork 的开源替代 |
| ocx | OpenCode 扩展管理器 |
| CodeNomad | 桌面、Web、移动和远程客户端应用 |
5.8.3 社区智能体
| Agentic | 模块化 AI 代理和命令 |
| opencode-agents | 配置、提示、代理和插件 |
5.9 网络配置
5.9.1 代理
OpenCode 尊重标准代理环境变量:
# HTTPS 代理(推荐)
export HTTPS_PROXY=https://proxy.example.com:8080
# HTTP 代理(如果没有 HTTPS)
export HTTP_PROXY=http://proxy.example.com:8080
# 绕过代理用于本地服务器(必需)
export NO_PROXY=localhost,127.0.0.1
注意: TUI 与本地 HTTP 服务器通信。必须绕过代理以防止路由循环。
基本认证:
export HTTPS_PROXY=http://username:password@proxy.example.com:8080
5.9.2 自定义证书
如果企业使用自定义 CA:
export NODE_EXTRA_CA_CERTS=/path/to/ca-cert.pem
5.10 企业版
5.10.1 数据安全
OpenCode 不存储你的代码或上下文数据。 所有处理在本地或通过与 AI 提供商的直接 API 调用完成。
分享会话: 如果用户启用 /share,数据会发送到 opencode.ai 的 CDN。禁用:
{
"share": "disabled"
}
代码所有权: 你拥有 OpenCode 产生的所有代码,没有许可限制或所有权声明。
5.10.2 定价
按座位模型。如果你有自己的 LLM 网关,我们不收取 Token 使用费。
5.10.3 部署
中央配置: 单个中央配置适用于整个组织,可与 SSO 提供商和内部 AI 网关集成。
SSO 集成: 通过中央配置,OpenCode 可与组织的 SSO 提供商集成进行认证。
内部 AI 网关: 配置 OpenCode 仅使用你的内部 AI 网关,禁用所有其他 AI 提供商。
自托管: 分享页面可在你的基础设施上自托管。
5.10.4 私有 NPM 仓库
OpenCode 通过 Bun 的原生 .npmrc 文件支持支持私有 npm 仓库:
npm login –registry=https://your-company.jfrog.io/api/npm/npm-virtual/
或配置 .npmrc:
registry=https://your-company.jfrog.io/api/npm/npm-virtual/
//your-company.jfrog.io/api/npm/npm-virtual/:_authToken=${NPM_AUTH_TOKEN}
第六部分:故障排除与常见问题
6.1 日志
日志文件位置:
- macOS/Linux: ~/.local/share/opencode/log/
- Windows: WIN+R -> %USERPROFILE%\\.local\\share\\opencode\\log
日志文件以时间戳命名(如 2025-01-09T123456.log),保留最近的 10 个。
设置日志级别:
opencode –log-level DEBUG
6.2 存储
OpenCode 存储数据位置:
- macOS/Linux: ~/.local/share/opencode/
- Windows: WIN+R -> %USERPROFILE%\\.local\\share\\opencode
包含:
- auth.json – 认证数据(API keys、OAuth tokens)
- log/ – 应用日志
- project/ – 项目特定数据(会话和消息数据)
- Git 仓库内项目:./<project-slug>/storage/
- 非 Git 仓库:./global/storage/
6.3 桌面应用故障排除
6.3.1 快速检查
- 完全退出并重新启动应用
- 如果显示错误屏幕,点击 Restart 并复制错误详情
- macOS:OpenCode 菜单 -> Reload Webview(UI 空白/冻结时有用)
6.3.2 禁用插件
检查全局配置中的 plugin 键:
- macOS/Linux: ~/.config/opencode/opencode.jsonc
- Windows: WIN+R -> %USERPROFILE%\\.config\\opencode\\opencode.jsonc
临时禁用:
{
"plugin": []
}
检查插件目录并重命名:
- 全局: ~/.config/opencode/plugins/ 或 %USERPROFILE%\\.config\\opencode\\plugins
- 项目: <your-project>/.opencode/plugins/
6.3.3 清除缓存
- macOS: Cmd+Shift+G -> ~/.cache/opencode
- Linux: rm -rf ~/.cache/opencode
- Windows: WIN+R -> %USERPROFILE%\\.cache\\opencode
6.3.4 修复服务器连接问题
清除桌面默认服务器 URL: 从主屏幕点击服务器名称(带状态点)打开服务器选择器。在 Default server 部分点击 Clear。
移除配置中的 server.port / server.hostname: 如果 opencode.json(c) 包含 server 部分,临时移除并重启桌面应用。
检查环境变量: 如果设置了 OPENCODE_PORT,桌面应用会尝试使用该端口。取消设置或选择空闲端口:
unset OPENCODE_PORT
6.3.5 Linux: Wayland / X11 问题
- Wayland 上应用空白/崩溃?尝试用 OC_ALLOW_WAYLAND=1 启动
- 如果更糟,移除它并尝试在 X11 会话下启动
6.3.6 Windows: WebView2 运行时
Windows 上 OpenCode Desktop 需要 Microsoft Edge WebView2 Runtime。如果应用打开空白窗口或无法启动,安装/更新 WebView2。
6.3.7 Windows: 一般性能问题
如果在 Windows 上遇到性能慢、文件访问问题或终端问题,尝试使用 WSL(Windows Subsystem for Linux)。
6.3.8 通知不显示
OpenCode Desktop 仅在以下条件显示系统通知:
- 操作系统设置中启用了 OpenCode 通知
- 应用窗口未聚焦
6.3.9 重置桌面应用存储(最后手段)
如果应用无法启动且无法从 UI 清除设置:
- opencode.settings.dat(桌面默认服务器 URL)
- opencode.global.dat 和 opencode.workspace.*.dat(UI 状态)
快速找到目录:
- macOS: Cmd+Shift+G -> ~/Library/Application Support
- Linux: 搜索 ~/.local/share
- Windows: WIN+R -> %APPDATA%
6.3.10 故障排除决策树
#mermaid-svg-sAvdOHrl6IbZ4MtP{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-sAvdOHrl6IbZ4MtP .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-sAvdOHrl6IbZ4MtP .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-sAvdOHrl6IbZ4MtP .error-icon{fill:#552222;}#mermaid-svg-sAvdOHrl6IbZ4MtP .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-sAvdOHrl6IbZ4MtP .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-sAvdOHrl6IbZ4MtP .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-sAvdOHrl6IbZ4MtP .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-sAvdOHrl6IbZ4MtP .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-sAvdOHrl6IbZ4MtP .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-sAvdOHrl6IbZ4MtP .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-sAvdOHrl6IbZ4MtP .marker{fill:#333333;stroke:#333333;}#mermaid-svg-sAvdOHrl6IbZ4MtP .marker.cross{stroke:#333333;}#mermaid-svg-sAvdOHrl6IbZ4MtP svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-sAvdOHrl6IbZ4MtP p{margin:0;}#mermaid-svg-sAvdOHrl6IbZ4MtP .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-sAvdOHrl6IbZ4MtP .cluster-label text{fill:#333;}#mermaid-svg-sAvdOHrl6IbZ4MtP .cluster-label span{color:#333;}#mermaid-svg-sAvdOHrl6IbZ4MtP .cluster-label span p{background-color:transparent;}#mermaid-svg-sAvdOHrl6IbZ4MtP .label text,#mermaid-svg-sAvdOHrl6IbZ4MtP span{fill:#333;color:#333;}#mermaid-svg-sAvdOHrl6IbZ4MtP .node rect,#mermaid-svg-sAvdOHrl6IbZ4MtP .node circle,#mermaid-svg-sAvdOHrl6IbZ4MtP .node ellipse,#mermaid-svg-sAvdOHrl6IbZ4MtP .node polygon,#mermaid-svg-sAvdOHrl6IbZ4MtP .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-sAvdOHrl6IbZ4MtP .rough-node .label text,#mermaid-svg-sAvdOHrl6IbZ4MtP .node .label text,#mermaid-svg-sAvdOHrl6IbZ4MtP .image-shape .label,#mermaid-svg-sAvdOHrl6IbZ4MtP .icon-shape .label{text-anchor:middle;}#mermaid-svg-sAvdOHrl6IbZ4MtP .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-sAvdOHrl6IbZ4MtP .rough-node .label,#mermaid-svg-sAvdOHrl6IbZ4MtP .node .label,#mermaid-svg-sAvdOHrl6IbZ4MtP .image-shape .label,#mermaid-svg-sAvdOHrl6IbZ4MtP .icon-shape .label{text-align:center;}#mermaid-svg-sAvdOHrl6IbZ4MtP .node.clickable{cursor:pointer;}#mermaid-svg-sAvdOHrl6IbZ4MtP .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-sAvdOHrl6IbZ4MtP .arrowheadPath{fill:#333333;}#mermaid-svg-sAvdOHrl6IbZ4MtP .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-sAvdOHrl6IbZ4MtP .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-sAvdOHrl6IbZ4MtP .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sAvdOHrl6IbZ4MtP .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-sAvdOHrl6IbZ4MtP .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sAvdOHrl6IbZ4MtP .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-sAvdOHrl6IbZ4MtP .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-sAvdOHrl6IbZ4MtP .cluster text{fill:#333;}#mermaid-svg-sAvdOHrl6IbZ4MtP .cluster span{color:#333;}#mermaid-svg-sAvdOHrl6IbZ4MtP div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-sAvdOHrl6IbZ4MtP .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-sAvdOHrl6IbZ4MtP rect.text{fill:none;stroke-width:0;}#mermaid-svg-sAvdOHrl6IbZ4MtP .icon-shape,#mermaid-svg-sAvdOHrl6IbZ4MtP .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-sAvdOHrl6IbZ4MtP .icon-shape p,#mermaid-svg-sAvdOHrl6IbZ4MtP .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-sAvdOHrl6IbZ4MtP .icon-shape rect,#mermaid-svg-sAvdOHrl6IbZ4MtP .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-sAvdOHrl6IbZ4MtP .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-sAvdOHrl6IbZ4MtP .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-sAvdOHrl6IbZ4MtP :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}
是
否
认证问题
插件问题
是
否
是
否
遇到问题
1. 检查日志~/.local/share/opencode/log/
有错误信息?
2. 根据错误类型处理
2. 检查配置和权限
错误类型
重新认证
禁用插件
是否解决?
重启解决完成
重装解决完成
仍有问题?
寻求帮助
完成
GitHub Issues
Discord 社区
故障排除步骤:
- 认证问题 → 重新运行 /connect 认证
- 插件问题 → 临时禁用插件测试
- 检查配置和权限设置
- 尝试重启应用
- 尝试重装 OpenCode
6.4 获取帮助
GitHub 报告问题
- https://github.com/anomalyco/opencode/issues
- 创建新问题前搜索现有问题
加入 Discord
- https://opencode.ai/discord
6.5 常见问题
6.5.1 OpenCode 无法启动
6.5.2 认证问题
6.5.3 模型不可用
如果遇到 ProviderModelNotFoundError,可能是错误引用模型。模型格式:<providerId>/<modelId>
示例:
- openai/gpt-4.1
- openrouter/google/gemini-2.5-flash
- opencode/kimi-k2
运行 opencode models 查看可用模型。
6.5.4 ProviderInitError
可能配置无效或损坏。
解决:
Windows: WIN+R -> %USERPROFILE%\\.local\\share\\opencode
6.5.5 AI_APICallError 和提供商包问题
API 调用错误可能由于过时的提供商包。OpenCode 动态安装提供商包并本地缓存。
解决:
Windows: WIN+R -> %USERPROFILE%\\.cache\\opencode
6.5.6 Linux 复制/粘贴不工作
Linux 用户需要安装以下剪贴板工具之一:
X11 系统:
apt install -y xclip
# 或
apt install -y xsel
Wayland 系统:
apt install -y wl-clipboard
无头环境:
apt install -y xvfb
Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
export DISPLAY=:99.0
OpenCode 会检测 Wayland 并优先使用 wl-clipboard,否则尝试 xclip 和 xsel。
6.6 Windows WSL 指南
6.6.1 为什么使用 WSL?
WSL 提供更好的文件系统性能、完整的终端支持,以及与 OpenCode 依赖的开发工具的兼容性。
6.6.2 设置
安装 WSL https://learn.microsoft.com/en-us/windows/wsl/install
在 WSL 中安装 OpenCode
curl -fsSL https://opencode.ai/install | bash
从 WSL 使用 OpenCode
cd /mnt/c/Users/YourName/project
opencode
6.6.3 桌面应用 + WSL 服务器
如果更喜欢 OpenCode 桌面应用但想在 WSL 中运行服务器:
# 在 WSL 中启动服务器,允许外部连接
opencode serve –hostname 0.0.0.0 –port 4096
然后桌面应用连接到 http://localhost:4096
注意: 如果 localhost 不起作用,使用 WSL IP 地址(在 WSL 中运行 hostname -I)
安全: 使用 –hostname 0.0.0.0 时设置密码:
OPENCODE_SERVER_PASSWORD=your-password opencode serve –hostname 0.0.0.0
6.6.4 Web 客户端 + WSL
最佳 Windows Web 体验:
# 在 WSL 终端中运行
opencode web –hostname 0.0.0.0
然后从 Windows 浏览器访问 http://localhost:<port>
6.6.5 访问 Windows 文件
WSL 可通过 /mnt/ 目录访问所有 Windows 文件:
- C: 盘 -> /mnt/c/
- D: 盘 -> /mnt/d/
- 依此类推…
示例:
cd /mnt/c/Users/YourName/Documents/project
opencode
6.6.6 技巧
- 在 Windows 盘上运行项目时保持 OpenCode 在 WSL 中运行 – 文件访问无缝
- 使用 VS Code 的 WSL 扩展与 OpenCode 一起实现集成开发工作流
- OpenCode 配置和会话存储在 WSL 环境中的 ~/.local/share/opencode/
6.7 Zen 服务详解
6.7.1 背景
市场上有很多模型,但只有少数适合作为编程代理。此外,大多数提供商配置差异很大,导致性能和质量差异。
OpenCode Zen 是 OpenCode 团队测试和验证的模型列表。
6.7.2 工作原理
按请求收费,可向账户添加积分。
6.7.3 可用模型和定价
模型端点: https://opencode.ai/zen/v1/
| Big Pickle | 免费 | 免费 | 免费 |
| MiniMax M2.1 Free | 免费 | 免费 | 免费 |
| MiniMax M2.1 | $0.30 | $1.20 | $0.10 |
| GLM 4.7 Free | 免费 | 免费 | 免费 |
| GLM 4.7 | $0.60 | $2.20 | $0.10 |
| Kimi K2.5 Free | 免费 | 免费 | 免费 |
| Kimi K2.5 | $0.60 | $3.00 | $0.08 |
| Claude Sonnet 4.5 (≤200K) | $3.00 | $15.00 | $0.30 |
| Claude Sonnet 4.5 (>200K) | $6.00 | $22.50 | $0.60 |
| GPT 5.2 | $1.75 | $14.00 | $0.175 |
| GPT 5.1 Codex | $1.07 | $8.50 | $0.107 |
价格每 1M tokens
自动充值: 余额低于 $5 时自动充值 $20(可配置或禁用)
月度限额: 可为整个工作区和每个团队成员设置月度使用限额。
6.7.4 隐私
所有模型托管在美国。提供商遵循零保留政策,不将数据用于模型训练,例外:
- Big Pickle、GLM 4.7 Free、Kimi K2.5 Free、MiniMax M2.1 Free:免费期间收集的数据可能用于改进模型
- OpenAI APIs:请求保留 30 天(根据 OpenAI 数据政策)
- Anthropic APIs:请求保留 30 天(根据 Anthropic 数据政策)
6.7.5 团队功能
角色:
- Admin:管理模型、成员、API keys、账单
- Member:仅管理自己的 API keys
Admin 可为每个成员设置月度支出限额。
模型访问: Admin 可为工作区启用或禁用特定模型。对禁用模型的请求将返回错误。
使用自己的 Key: 可以使用自己的 OpenAI 或 Anthropic API keys,同时仍访问 Zen 中的其他模型。使用自己的 keys 时,tokens 直接由提供商计费,而非 Zen。
6.8 分享功能详解
6.8.1 工作原理
分享会话时,OpenCode:
6.8.2 分享模式
手动(默认):
{
"share": "manual"
}
使用 /share 命令手动分享。
自动分享:
{
"share": "auto"
}
每个新会话自动分享。
禁用:
{
"share": "disabled"
}
完全禁用分享。
6.8.3 取消分享
/unshare
6.8.4 隐私建议
- 仅分享不包含敏感信息的对话
- 分享前审查对话内容
- 协作完成后取消分享
- 避免分享包含专有代码或机密数据的对话
- 敏感项目完全禁用分享
6.9 迁移到 1.0
6.9.1 升级
opencode upgrade 1.0.0
降级回 0.x:
opencode upgrade 0.15.31
6.9.2 UX 变化
- 会话历史更压缩,仅显示 edit 和 bash 工具的完整详情
- 添加命令栏(按 ctrl+p)
- 添加会话侧边栏(可切换)
- 移除了一些不确定是否有人使用的功能
6.9.3 破坏性变化
重命名的快捷键:
- messages_revert → messages_undo
- switch_agent → agent_cycle
- switch_agent_reverse → agent_cycle_reverse
- switch_mode → agent_cycle
- switch_mode_reverse → agent_cycle_reverse
移除的快捷键:
- messages_layout_toggle
- messages_next
- messages_previous
- file_diff_toggle
- file_search
- file_close
- file_list
- app_help
- project_init
- tool_details
- thinking_blocks
附录:环境变量参考
| OPENCODE_AUTO_SHARE | boolean | 自动分享会话 |
| OPENCODE_CONFIG | string | 自定义配置文件路径 |
| OPENCODE_CONFIG_DIR | string | 自定义配置目录 |
| OPENCODE_CONFIG_CONTENT | string | 内联 JSON 配置内容 |
| OPENCODE_DISABLE_AUTOUPDATE | boolean | 禁用自动更新检查 |
| OPENCODE_DISABLE_PRUNE | boolean | 禁用旧数据清理 |
| OPENCODE_DISABLE_TERMINAL_TITLE | boolean | 禁用自动终端标题更新 |
| OPENCODE_PERMISSION | string | 内联 JSON 权限配置 |
| OPENCODE_DISABLE_DEFAULT_PLUGINS | boolean | 禁用默认插件 |
| OPENCODE_DISABLE_LSP_DOWNLOAD | boolean | 禁用自动 LSP 服务器下载 |
| OPENCODE_ENABLE_EXPERIMENTAL_MODELS | boolean | 启用实验性模型 |
| OPENCODE_DISABLE_AUTOCOMPACT | boolean | 禁用自动上下文压缩 |
| OPENCODE_DISABLE_CLAUDE_CODE | boolean | 禁用所有 .claude 支持 |
| OPENCODE_DISABLE_CLAUDE_CODE_PROMPT | boolean | 仅禁用 ~/.claude/CLAUDE.md |
| OPENCODE_DISABLE_CLAUDE_CODE_SKILLS | boolean | 仅禁用 .claude/skills |
| OPENCODE_CLIENT | string | 客户端标识符(默认 cli) |
| OPENCODE_ENABLE_EXA | boolean | 启用 Exa 网页搜索工具 |
| OPENCODE_SERVER_PASSWORD | string | 启用 serve/web 基本认证 |
| OPENCODE_SERVER_USERNAME | string | 覆盖基本认证用户名 |
| OPENCODE_GIT_BASH_PATH | string | Windows Git Bash 可执行文件路径 |
实验性变量:
- OPENCODE_EXPERIMENTAL – 启用所有实验性功能
- OPENCODE_EXPERIMENTAL_LSP_TOOL – 启用实验性 LSP 工具
- OPENCODE_EXPERIMENTAL_FILEWATCHER – 启用整个目录的文件监视器
- OPENCODE_EXPERIMENTAL_OXFMT – 启用 oxfmt 格式化器
- OPENCODE_EXPERIMENTAL_PLAN_MODE – 启用计划模式
文档版本:基于 OpenCode 官方文档(2026年2月4日)
本文档基于 OpenCode 开源项目官方文档翻译,仅供学习参考使用。
网硕互联帮助中心




评论前必须登录!
注册