opencode-acp-control
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOpenCode ACP Skill
OpenCode ACP 技能
Control OpenCode directly via the Agent Client Protocol (ACP).
通过Agent Client Protocol(ACP)直接控制OpenCode。
Metadata
元数据
- For ACP Protocol Docs (for Agents/LLMs): https://agentclientprotocol.com/llms.txt
- GitHub Repo: https://github.com/bjesuiter/opencode-acp-skill
- If you have issues with this skill, please open an issue ticket here: https://github.com/bjesuiter/opencode-acp-skill/issues
- ACP协议文档(面向Agents/LLMs):https://agentclientprotocol.com/llms.txt
- GitHub仓库:https://github.com/bjesuiter/opencode-acp-skill
- 如果使用本技能遇到问题,请在此提交工单:https://github.com/bjesuiter/opencode-acp-skill/issues
Quick Reference
快速参考
| Action | How |
|---|---|
| Start OpenCode | |
| Send message | |
| Read response | |
| Stop OpenCode | |
| List sessions | |
| Resume session | List sessions → ask user → |
| Check version | |
| 操作 | 方法 |
|---|---|
| 启动OpenCode | |
| 发送消息 | |
| 读取响应 | |
| 停止OpenCode | |
| 列出会话 | |
| 恢复会话 | 列出会话 → 询问用户 → |
| 检查版本 | |
Starting OpenCode
启动OpenCode
bash(
command: "opencode acp --cwd /path/to/your/project",
background: true,
workdir: "/path/to/your/project"
)Save the returned - you'll need it for all subsequent commands.
sessionIdbash(
command: "opencode acp --cwd /path/to/your/project",
background: true,
workdir: "/path/to/your/project"
)保存返回的 - 后续所有命令都需要用到它。
sessionIdProtocol Basics
协议基础
- All messages are JSON-RPC 2.0 format
- Messages are newline-delimited (end each with )
\n - Maintain a message ID counter starting at 0
- 所有消息均为JSON-RPC 2.0格式
- 消息采用换行分隔(每条消息以结尾)
\n - 维护一个从0开始的消息ID计数器
Step-by-Step Workflow
分步工作流
Step 1: Initialize Connection
步骤1:初始化连接
Send immediately after starting OpenCode:
json
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{"fs":{"readTextFile":true,"writeTextFile":true},"terminal":true},"clientInfo":{"name":"clawdbot","title":"Clawdbot","version":"1.0.0"}}}Poll for response. Expect .
result.protocolVersion: 1启动OpenCode后立即发送:
json
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{"fs":{"readTextFile":true,"writeTextFile":true},"terminal":true},"clientInfo":{"name":"clawdbot","title":"Clawdbot","version":"1.0.0"}}}轮询等待响应。预期返回。
result.protocolVersion: 1Step 2: Create Session
步骤2:创建会话
json
{"jsonrpc":"2.0","id":1,"method":"session/new","params":{"cwd":"/path/to/project","mcpServers":[]}}Poll for response. Save (e.g., ).
result.sessionId"sess_abc123"json
{"jsonrpc":"2.0","id":1,"method":"session/new","params":{"cwd":"/path/to/project","mcpServers":[]}}轮询等待响应。保存(例如:)。
result.sessionId"sess_abc123"Step 3: Send Prompts
步骤3:发送提示词
json
{"jsonrpc":"2.0","id":2,"method":"session/prompt","params":{"sessionId":"sess_abc123","prompt":[{"type":"text","text":"Your question here"}]}}Poll every 2 seconds. You'll receive:
- notifications (streaming content)
session/update - Final response with
result.stopReason
json
{"jsonrpc":"2.0","id":2,"method":"session/prompt","params":{"sessionId":"sess_abc123","prompt":[{"type":"text","text":"Your question here"}]}}每2秒轮询一次。你将收到:
- 通知(流式返回内容)
session/update - 包含的最终响应
result.stopReason
Step 4: Read Responses
步骤4:读取响应
Each poll may return multiple lines. Parse each line as JSON:
- Notifications: - collect these for the response
method: "session/update" - Response: Has matching your request - stop polling when
idappearsstopReason
每次轮询可能返回多行内容。将每行解析为JSON:
- 通知:- 收集这些内容作为响应
method: "session/update" - 响应:包含与请求匹配的- 当出现
id时停止轮询stopReason
Step 5: Cancel (if needed)
步骤5:取消(如需)
json
{"jsonrpc":"2.0","method":"session/cancel","params":{"sessionId":"sess_abc123"}}No response expected - this is a notification.
json
{"jsonrpc":"2.0","method":"session/cancel","params":{"sessionId":"sess_abc123"}}无需等待响应 - 这是一个通知。
State to Track
需要跟踪的状态
Per OpenCode instance, track:
- - from bash tool (clawdbot's process ID)
processSessionId - - from session/new response (OpenCode's session ID)
opencodeSessionId - - increment for each request you send
messageId
针对每个OpenCode实例,跟踪:
- - 来自bash工具(clawdbot的进程ID)
processSessionId - - 来自session/new的响应(OpenCode的会话ID)
opencodeSessionId - - 每次发送请求时递增
messageId
Polling Strategy
轮询策略
- Poll every 2 seconds
- Continue until you receive a response with
stopReason - Max wait: 5 minutes (150 polls)
- If no response, consider the operation timed out
- 每2秒轮询一次
- 持续轮询直到收到包含的响应
stopReason - 最长等待时间:5分钟(150次轮询)
- 如果5分钟无响应,判定操作超时
Common Stop Reasons
常见停止原因
| stopReason | Meaning |
|---|---|
| Agent finished responding |
| You cancelled the prompt |
| Token limit reached |
| stopReason | 含义 |
|---|---|
| Agent已完成响应 |
| 你已取消提示词 |
| 达到令牌限制 |
Error Handling
错误处理
| Issue | Solution |
|---|---|
| Empty poll response | Keep polling - agent is thinking |
| Parse error | Skip malformed line, continue |
| Process exited | Restart OpenCode |
| No response after 5min | Kill process, start fresh |
| 问题 | 解决方案 |
|---|---|
| 轮询响应为空 | 继续轮询 - Agent正在思考 |
| 解析错误 | 跳过格式错误的行,继续轮询 |
| 进程已退出 | 重启OpenCode |
| 5分钟无响应 | 终止进程,重新启动 |
Example: Complete Interaction
示例:完整交互流程
1. bash(command: "opencode acp --cwd /home/user/myproject", background: true, workdir: "/home/user/myproject")
-> processSessionId: "bg_42"
2. process.write(sessionId: "bg_42", data: '{"jsonrpc":"2.0","id":0,"method":"initialize",...}\n')
process.poll(sessionId: "bg_42") -> initialize response
3. process.write(sessionId: "bg_42", data: '{"jsonrpc":"2.0","id":1,"method":"session/new","params":{"cwd":"/home/user/myproject","mcpServers":[]}}\n')
process.poll(sessionId: "bg_42") -> opencodeSessionId: "sess_xyz789"
4. process.write(sessionId: "bg_42", data: '{"jsonrpc":"2.0","id":2,"method":"session/prompt","params":{"sessionId":"sess_xyz789","prompt":[{"type":"text","text":"List all TypeScript files"}]}}\n')
5. process.poll(sessionId: "bg_42") every 2 sec until stopReason
-> Collect all session/update content
-> Final response: stopReason: "end_turn"
6. When done: process.kill(sessionId: "bg_42")1. bash(command: "opencode acp --cwd /home/user/myproject", background: true, workdir: "/home/user/myproject")
-> processSessionId: "bg_42"
2. process.write(sessionId: "bg_42", data: '{"jsonrpc":"2.0","id":0,"method":"initialize",...}\n')
process.poll(sessionId: "bg_42") -> 初始化响应
3. process.write(sessionId: "bg_42", data: '{"jsonrpc":"2.0","id":1,"method":"session/new","params":{"cwd":"/home/user/myproject","mcpServers":[]}}\n')
process.poll(sessionId: "bg_42") -> opencodeSessionId: "sess_xyz789"
4. process.write(sessionId: "bg_42", data: '{"jsonrpc":"2.0","id":2,"method":"session/prompt","params":{"sessionId":"sess_xyz789","prompt":[{"type":"text","text":"List all TypeScript files"}]}}\n')
5. 每2秒执行process.poll(sessionId: "bg_42")直到出现stopReason
-> 收集所有session/update内容
-> 最终响应: stopReason: "end_turn"
6. 完成后: process.kill(sessionId: "bg_42")Resume Session
恢复会话
Resume a previous OpenCode session by letting the user choose from available sessions.
通过让用户从可用会话中选择,恢复之前的OpenCode会话。
Step 1: List Available Sessions
步骤1:列出可用会话
bash(command: "opencode session list", workdir: "/path/to/project")Example output:
ID Updated Messages
ses_451cd8ae0ffegNQsh59nuM3VVy 2026-01-11 15:30 12
ses_451a89e63ffea2TQIpnDGtJBkS 2026-01-10 09:15 5
ses_4518e90d0ffeJIpOFI3t3Jd23Q 2026-01-09 14:22 8bash(command: "opencode session list", workdir: "/path/to/project")示例输出:
ID Updated Messages
ses_451cd8ae0ffegNQsh59nuM3VVy 2026-01-11 15:30 12
ses_451a89e63ffea2TQIpnDGtJBkS 2026-01-10 09:15 5
ses_4518e90d0ffeJIpOFI3t3Jd23Q 2026-01-09 14:22 8Step 2: Ask User to Choose
步骤2:询问用户选择
Present the list to the user and ask which session to resume:
"Which session would you like to resume?
1. ses_451cd8ae... (12 messages, updated 2026-01-11)
2. ses_451a89e6... (5 messages, updated 2026-01-10)
3. ses_4518e90d... (8 messages, updated 2026-01-09)
Enter session number or ID:"将列表展示给用户并询问要恢复哪个会话:
"你想要恢复哪个会话?
1. ses_451cd8ae... (12条消息,更新于2026-01-11)
2. ses_451a89e6... (5条消息,更新于2026-01-10)
3. ses_4518e90d... (8条消息,更新于2026-01-09)
请输入会话编号或ID:"Step 3: Load Selected Session
步骤3:加载选定的会话
Once user responds (e.g., "1", "the first one", or "ses_451cd8ae..."):
-
Start OpenCode ACP:
bash(command: "opencode acp --cwd /path/to/project", background: true, workdir: "/path/to/project") -
Initialize:json
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{...}} -
Load the session:json
{"jsonrpc":"2.0","id":1,"method":"session/load","params":{"sessionId":"ses_451cd8ae0ffegNQsh59nuM3VVy","cwd":"/path/to/project","mcpServers":[]}}
Note: requires and parameters.
session/loadcwdmcpServersOn load, OpenCode streams the full conversation history back to you.
用户回复后(例如:"1"、"第一个"或"ses_451cd8ae..."):
-
启动OpenCode ACP:
bash(command: "opencode acp --cwd /path/to/project", background: true, workdir: "/path/to/project") -
初始化:json
{"jsonrpc":"2.0","id":0,"method":"initialize","params":{...}} -
加载会话:json
{"jsonrpc":"2.0","id":1,"method":"session/load","params":{"sessionId":"ses_451cd8ae0ffegNQsh59nuM3VVy","cwd":"/path/to/project","mcpServers":[]}}
注意:需要和参数。
session/loadcwdmcpServers加载后,OpenCode会将完整的对话历史流式返回给你。
Resume Workflow Summary
恢复工作流总结
function resumeSession(workdir):
# List available sessions
output = bash("opencode session list", workdir: workdir)
sessions = parseSessionList(output)
if sessions.empty:
notify("No previous sessions found. Starting fresh.")
return createNewSession(workdir)
# Ask user to choose
choice = askUser("Which session to resume?", sessions)
selectedId = matchUserChoice(choice, sessions)
# Start OpenCode and load session
process = bash("opencode acp --cwd " + workdir, background: true, workdir: workdir)
initialize(process)
session_load(process, selectedId, workdir, mcpServers: [])
notify("Session resumed. Conversation history loaded.")
return processfunction resumeSession(workdir):
# 列出可用会话
output = bash("opencode session list", workdir: workdir)
sessions = parseSessionList(output)
if sessions.empty:
notify("未找到之前的会话。将启动新会话。")
return createNewSession(workdir)
# 询问用户选择
choice = askUser("要恢复哪个会话?", sessions)
selectedId = matchUserChoice(choice, sessions)
# 启动OpenCode并加载会话
process = bash("opencode acp --cwd " + workdir, background: true, workdir: workdir)
initialize(process)
session_load(process, selectedId, workdir, mcpServers: [])
notify("会话已恢复。对话历史已加载。")
return processImportant Notes
重要说明
- History replay: On load, all previous messages stream back
- Memory preserved: Agent remembers the full conversation
- Process independent: Sessions survive OpenCode restarts
- 历史重放:加载时,所有之前的消息会流式返回
- 记忆保留:Agent会记住完整的对话
- 进程独立:会话可在OpenCode重启后保留
Updating OpenCode
更新OpenCode
OpenCode auto-updates when restarted. Use this workflow to check and trigger updates.
OpenCode在重启时会自动更新。使用以下工作流检查并触发更新。
Step 1: Check Current Version
步骤1:检查当前版本
bash(command: "opencode --version")Returns something like:
opencode version 1.1.13Extract the version number (e.g., ).
1.1.13bash(command: "opencode --version")返回示例:
opencode version 1.1.13提取版本号(例如:)。
1.1.13Step 2: Check Latest Version
步骤2:检查最新版本
webfetch(url: "https://github.com/anomalyco/opencode/releases/latest", format: "text")The redirect URL contains the latest version tag:
- Redirects to:
https://github.com/anomalyco/opencode/releases/tag/v1.2.0 - Extract version from the URL path (e.g., )
1.2.0
webfetch(url: "https://github.com/anomalyco/opencode/releases/latest", format: "text")重定向URL包含最新版本标签:
- 重定向至:
https://github.com/anomalyco/opencode/releases/tag/v1.2.0 - 从URL路径中提取版本(例如:)
1.2.0
Step 3: Compare and Update
步骤3:对比并更新
If latest version > current version:
-
Stop all running OpenCode processes:
process.list() # Find all "opencode acp" processes process.kill(sessionId) # For each running instance -
Restart instances (OpenCode auto-downloads new binary on start):
bash(command: "opencode acp --cwd /path/to/project", background: true, workdir: "/path/to/project") -
Re-initialize each instance (initialize + session/load for existing sessions)
如果最新版本 > 当前版本:
-
停止所有运行中的OpenCode进程:
process.list() # 查找所有"opencode acp"进程 process.kill(sessionId) # 终止每个运行中的实例 -
重启实例(OpenCode会在启动时自动下载新版本):
bash(command: "opencode acp --cwd /path/to/project", background: true, workdir: "/path/to/project") -
重新初始化每个实例(初始化 + session/load恢复现有会话)
Step 4: Verify Update
步骤4:验证更新
bash(command: "opencode --version")If version still doesn't match latest:
- Inform user: "OpenCode auto-update may have failed. Current: X.X.X, Latest: Y.Y.Y"
- Suggest manual update:
curl -fsSL https://opencode.dev/install | bash
bash(command: "opencode --version")如果版本仍未匹配最新版本:
- 通知用户:"OpenCode自动更新可能失败。当前版本:X.X.X,最新版本:Y.Y.Y"
- 建议手动更新:
curl -fsSL https://opencode.dev/install | bash
Update Workflow Summary
更新工作流总结
function updateOpenCode():
current = bash("opencode --version") # e.g., "1.1.13"
latestPage = webfetch("https://github.com/anomalyco/opencode/releases/latest")
latest = extractVersionFromRedirectUrl(latestPage) # e.g., "1.2.0"
if semverCompare(latest, current) > 0:
# Stop all instances
for process in process.list():
if process.command.includes("opencode"):
process.kill(process.sessionId)
# Wait briefly for processes to terminate
sleep(2 seconds)
# Restart triggers auto-update
bash("opencode acp", background: true)
# Verify
newVersion = bash("opencode --version")
if newVersion != latest:
notify("Auto-update may have failed. Manual update recommended.")
else:
notify("OpenCode is up to date: " + current)function updateOpenCode():
current = bash("opencode --version") # 例如:"1.1.13"
latestPage = webfetch("https://github.com/anomalyco/opencode/releases/latest")
latest = extractVersionFromRedirectUrl(latestPage) # 例如:"1.2.0"
if semverCompare(latest, current) > 0:
# 停止所有实例
for process in process.list():
if process.command.includes("opencode"):
process.kill(process.sessionId)
# 等待进程终止
sleep(2 seconds)
# 重启触发自动更新
bash("opencode acp", background: true)
# 验证
newVersion = bash("opencode --version")
if newVersion != latest:
notify("自动更新可能失败。建议手动更新。")
else:
notify("OpenCode已是最新版本:" + current)Important Notes
重要说明
- Sessions persist: survives restarts — use
opencodeSessionIdto recoversession/load - Auto-update: OpenCode downloads new binary automatically on restart
- No data loss: Conversation history is preserved server-side
- 会话持久化:在重启后仍然有效 — 使用
opencodeSessionId恢复session/load - 自动更新:OpenCode会在重启时自动下载新版本
- 无数据丢失:对话历史在服务器端保留