opencode-acp-control

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

OpenCode ACP Skill

OpenCode ACP 技能

Control OpenCode directly via the Agent Client Protocol (ACP).
通过Agent Client Protocol(ACP)直接控制OpenCode。

Metadata

元数据

Quick Reference

快速参考

ActionHow
Start OpenCode
bash(command: "opencode acp --cwd /path/to/project", background: true)
Send message
process.write(sessionId, data: "<json-rpc>\n")
Read response
process.poll(sessionId)
- repeat every 2 seconds
Stop OpenCode
process.kill(sessionId)
List sessions
bash(command: "opencode session list", workdir: "...")
Resume sessionList sessions → ask user →
session/load
Check version
bash(command: "opencode --version")
操作方法
启动OpenCode
bash(command: "opencode acp --cwd /path/to/project", background: true)
发送消息
process.write(sessionId, data: "<json-rpc>\n")
读取响应
process.poll(sessionId)
- 每2秒重复一次
停止OpenCode
process.kill(sessionId)
列出会话
bash(command: "opencode session list", workdir: "...")
恢复会话列出会话 → 询问用户 →
session/load
检查版本
bash(command: "opencode --version")

Starting OpenCode

启动OpenCode

bash(
  command: "opencode acp --cwd /path/to/your/project",
  background: true,
  workdir: "/path/to/your/project"
)
Save the returned
sessionId
- you'll need it for all subsequent commands.
bash(
  command: "opencode acp --cwd /path/to/your/project",
  background: true,
  workdir: "/path/to/your/project"
)
保存返回的
sessionId
- 后续所有命令都需要用到它。

Protocol 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: 1

Step 2: Create Session

步骤2:创建会话

json
{"jsonrpc":"2.0","id":1,"method":"session/new","params":{"cwd":"/path/to/project","mcpServers":[]}}
Poll for response. Save
result.sessionId
(e.g.,
"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:
  • session/update
    notifications (streaming content)
  • 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:
    method: "session/update"
    - collect these for the response
  • Response: Has
    id
    matching your request - stop polling when
    stopReason
    appears
每次轮询可能返回多行内容。将每行解析为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:
  • processSessionId
    - from bash tool (clawdbot's process ID)
  • opencodeSessionId
    - from session/new response (OpenCode's session ID)
  • messageId
    - increment for each request you send
针对每个OpenCode实例,跟踪:
  • processSessionId
    - 来自bash工具(clawdbot的进程ID)
  • opencodeSessionId
    - 来自session/new的响应(OpenCode的会话ID)
  • 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

常见停止原因

stopReasonMeaning
end_turn
Agent finished responding
cancelled
You cancelled the prompt
max_tokens
Token limit reached
stopReason含义
end_turn
Agent已完成响应
cancelled
你已取消提示词
max_tokens
达到令牌限制

Error Handling

错误处理

IssueSolution
Empty poll responseKeep polling - agent is thinking
Parse errorSkip malformed line, continue
Process exitedRestart OpenCode
No response after 5minKill 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     8
bash(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     8

Step 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..."):
  1. Start OpenCode ACP:
    bash(command: "opencode acp --cwd /path/to/project", background: true, workdir: "/path/to/project")
  2. Initialize:
    json
    {"jsonrpc":"2.0","id":0,"method":"initialize","params":{...}}
  3. Load the session:
    json
    {"jsonrpc":"2.0","id":1,"method":"session/load","params":{"sessionId":"ses_451cd8ae0ffegNQsh59nuM3VVy","cwd":"/path/to/project","mcpServers":[]}}
Note:
session/load
requires
cwd
and
mcpServers
parameters.
On load, OpenCode streams the full conversation history back to you.
用户回复后(例如:"1"、"第一个"或"ses_451cd8ae..."):
  1. 启动OpenCode ACP:
    bash(command: "opencode acp --cwd /path/to/project", background: true, workdir: "/path/to/project")
  2. 初始化:
    json
    {"jsonrpc":"2.0","id":0,"method":"initialize","params":{...}}
  3. 加载会话:
    json
    {"jsonrpc":"2.0","id":1,"method":"session/load","params":{"sessionId":"ses_451cd8ae0ffegNQsh59nuM3VVy","cwd":"/path/to/project","mcpServers":[]}}
注意
session/load
需要
cwd
mcpServers
参数。
加载后,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 process
function 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 process

Important 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.13
Extract the version number (e.g.,
1.1.13
).
bash(command: "opencode --version")
返回示例:
opencode version 1.1.13
提取版本号(例如:
1.1.13
)。

Step 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:
  1. Stop all running OpenCode processes:
    process.list()  # Find all "opencode acp" processes
    process.kill(sessionId) # For each running instance
  2. Restart instances (OpenCode auto-downloads new binary on start):
    bash(command: "opencode acp --cwd /path/to/project", background: true, workdir: "/path/to/project")
  3. Re-initialize each instance (initialize + session/load for existing sessions)
如果最新版本 > 当前版本:
  1. 停止所有运行中的OpenCode进程:
    process.list()  # 查找所有"opencode acp"进程
    process.kill(sessionId) # 终止每个运行中的实例
  2. 重启实例(OpenCode会在启动时自动下载新版本):
    bash(command: "opencode acp --cwd /path/to/project", background: true, workdir: "/path/to/project")
  3. 重新初始化每个实例(初始化 + 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:
    opencodeSessionId
    survives restarts — use
    session/load
    to recover
  • Auto-update: OpenCode downloads new binary automatically on restart
  • No data loss: Conversation history is preserved server-side
  • 会话持久化
    opencodeSessionId
    在重启后仍然有效 — 使用
    session/load
    恢复
  • 自动更新:OpenCode会在重启时自动下载新版本
  • 无数据丢失:对话历史在服务器端保留