前言¶
如果你的 dsh 需要把活派給一個常駐的 OpenCode 服務,又不想在終端、網頁和 dsh 之間來回手工搬運上下文,dsh-opencode-client 就是爲這種情況寫的。插件直接連到遠程的 opencode serve 實例,把它的 project、session、message 暴露成 dsh 裏的工具,再把 OpenCode 註冊成 dsh 的原生 subagent 後端。
已有的做法一般是在 dsh 裏開一個外部命令 subagent,或者自己寫腳本調 OpenCode 的 HTTP API。前者上下文只能跑一次,後者要自己維護鑑權、輪詢、權限回調。這個插件把這層補齊了:多服務器配置、SSE 事件、權限審批卡、會話續跑和 workspace 操作都內置。
這是什麼¶
yhuan416/dsh-opencode-client 是 DeepSeek Harness(DSH)插件,由 yhuan416 維護。它充當 OpenCode 的 client:連接一臺或多臺遠程 opencode serve,把遠端的 projects / sessions / messages 帶到 dsh 裏,支持把任務委派進去,並提供把 OpenCode 作爲原生 dsh subagent 後端的能力。
OpenCode 自身架構裏,opencode serve 暴露一個 OpenAPI HTTP 服務,TUI、Web UI、SDK 都是它的 client。這個插件是其中一個 client,宿主是 dsh。插件自身的定位寫得也很清楚:主要角色是註冊 OpenCode 爲原生 subagent 後端(opencode_subagent_<server>),並把遠端會話、workspace 暴露爲工具;內嵌 OpenCode Web UI 是可選便利,不是替代。
倉庫信息:MIT License,stargazers_count 爲 0(截至 2026-11-08,來自 GitHub API),未發佈到 npm,需要從 git 或本地路徑安裝。README 明確已驗證 dsh 0.2.1-rc.2 與 OpenCode 1.18.10 / 1.18.31 / 1.18.33。
核心能力¶
服務器配置與發現¶
通過 servers 數組配置多臺實例,每臺可以是 id / label? / url / password? / directory?。發現能力由 GET /api/opencode-client/list 提供,返回服務器健康狀態、projects 以及按 directory 分組的 sessions。會話列表走工具 opencode_sessions 或 GET /api/opencode-client/sessions,消息走 opencode_messages 或 GET /api/opencode-client/messages。
會話讀取與逐輪續跑¶
opencode_session_info 拿 title / summary / todos / diff;opencode_share 生成或取消分享鏈接。opencode_prompt 向一個已存在的遠端會話發一條消息,默認 fire-and-forget,加 wait=true 可阻塞;再用 opencode_messages 或 opencode_progress 讀結果,然後發下一條。這是讓遠端 worker 會話跨 dsh turn 存活的關鍵。
委派與原生子代理¶
opencode_subagent 新建會話,或用 session= 繼續;可選 agent、model 和 prompt-enforced schema。實現上用的是 prompt_async 加消息輪詢,失敗時回退到阻塞式 prompt。提交時支持 files JSON 數組(text/base64 → data URL file parts)。
原生子代理通過在 profile 里加一行 tool-subagent 註冊,provider 名是 opencode-<serverId>,生成 opencode_subagent_<server> 工具,接入 dsh 的 ctx.subagents provider seam。它和 opencode_subagent 共用同一個 session-run 生命週期(lib/session-run.js),包括會話創建、交互追蹤、async prompt + SSE idle 等待、abort 處理。README 說原生子代理會話標題爲 dsh subagent: <label>,便於在插件頁面識別。
實時進度與中止¶
opencode_progress 讀當前 tool/step、耗時和輸出尾部,數據來自 SSE tool event,委派在 SSE idle 事件上判定完成。每臺服務器還有獨立的 SSE 訂閱(/global/event,帶重連),用於快速處理 permission / question、刷新 live state,以及 GET /api/opencode-client/events 和 /status。
opencode_abort 停掉運行中的遠端會話,等待中的委派會返回 abort error 而不是懸掛。注意 README 明確:同 turn 內 tool call 是串行的,所以必須從另一個 dsh session 或 agent 調用它,才能中止本 turn 裏阻塞的 opencode_subagent。
工作區與權限¶
workspace 操作工具有 opencode_shell、opencode_git_status、opencode_git_diff、opencode_read_file、opencode_find。opencode_init 會寫 AGENTS.md,需要 confirm=true;opencode_fork、opencode_children、opencode_summarize(mutating)用於會話管理。opencode_command 在會話裏執行遠端命令,例如 init。另外還有目錄類工具:opencode_models(providers/models,credentials 已剝離)、opencode_commands、opencode_skills、opencode_tools、opencode_references、opencode_agents(區分 primary/subagent、native/custom),以及診斷用的 opencode_search(v2 session search)和 opencode_mcp(MCP server 狀態)。
權限方面,permission: ask(默認)把遠端權限請求變成 dsh 的 approval card,allow / reject 是確定性回答。question: reject(默認)拒絕交互式提問,也可設爲 "ignore" 它們。README 在 Notes 裏說明:交互式問題只有在 run 由 opencode_subagent 啓動(agent 在 scope 內)時纔會轉發到 dsh 的 user-question UI,否則會被拒絕。
內嵌 OpenCode UI¶
插件支持註冊一個右側欄 tab(kind: opencode),內容是 server picker 加上真實 OpenCode Web UI 的 iframe,顯示在當前會話頁面裏。可以從服務器列表的「側邊欄打開」按鈕打開,也可以走右側欄 add-tab 引導;「全屏」overlay 和「新標籤」仍作爲兜底。README 強調沒有重新實現,內嵌頁面保留 streaming、tool cards、diffs 和 permissions。插件頁面本身還有單獨的 “OpenCode Client” 區塊,展示 servers / workspaces / sessions、session ids、active tool、messages,並可創建會話。
安裝與啓用¶
從本地路徑安裝並加入 web profile:
dsh plugin --profile web add /path/to/dsh-opencode-client
或者手動寫入 profile 的 dependencies,並把它選爲 bundle:
{
"dependencies": { "dsh-opencode-client": "file:/path/to/dsh-opencode-client" },
"dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "@deepseek-ai/dsh-web-app", "dsh-opencode-client"] } }
}
安裝前需要先看源碼和 LICENSE(倉庫標註 MIT)。注意它目前沒有 npm 包,README 說從 git 或本地路徑安裝。
配置¶
配置寫在插件條目的 config 下,多臺服務器並列:
- id: opencode-client
name: dsh-opencode-client
config:
servers:
- id: n100
label: n100 opencode
url: http://192.168.4.50:4096
# password: xxx # OPENCODE_SERVER_PASSWORD (basic auth, user "opencode")
# directory: /home/yhuan/workspace # default remote dir when the caller does not give one
# agent: plan # default OpenCode agent for delegation
# model: deepseek/deepseek-chat # default model "provider/model"
- id: m65
label: 4.65 opencode
url: http://192.168.4.65:4096
permission: ask # ask (default, dsh approval card) | allow | reject
question: reject # reject (default) interactive questions or "ignore" them
pathMap: # only when local and remote path layouts differ
- { from: /home/yhuan, to: /home/yhuan }
要把它當成原生 dsh subagent,加一行 tool:
- insert:
- id: tool-opencode-n100
name: "@deepseek-ai/dsh-tool-subagent"
config:
provider: opencode-n100 # "opencode-" + server id
maxDepth: provider-managed
toolName: opencode_subagent_n100
典型用法¶
先用發現接口確認服務器可達、projects 和 sessions 能列出:
curl http://192.168.4.50:4096/api/opencode-client/list
在 dsh 裏把一個任務派給遠端新會話:
opencode_subagent 還有一堆 CSV 需要清洗,在 /home/yhuan/workspace 下新建會話處理,agent 用 plan,模型用 deepseek/deepseek-chat
需要跨 dsh turn 保留同一個遠端會話時,用 opencode_prompt 逐條發消息,回覆後 opencode_messages 取結果,再發下一條。想盯着執行過程就用 opencode_progress 看當前 tool 和輸出尾部;發現狀態不對,從另一個 dsh session 調 opencode_abort 停掉。
遠端要臨時跑點東西,用 workspace 工具而不是另開 shell:opencode_shell、opencode_git_diff、opencode_read_file 都可以直接作用到遠端目錄。pathMap 只在本地和遠端路徑佈局不一致時才需要配。
適用場景與注意¶
適合這幾類人:已經在用 opencode serve 做常駐代碼服務、想把 dsh 和它打通的人;想統一委派入口,而不是手寫 HTTP 調用腳本的人;想讓 OpenCode 作爲 dsh subagent 後端之一參與多後端編排的人。
注意事項摘自 README:
- 遠端 OpenCode 服務必須能被 dsh 宿主訪問。
opencode serve默認綁127.0.0.1,需要綁0.0.0.0或放在 SSH 隧道後面。 - 會話續跑走 OpenCode HTTP API;原生外部 subagent 仍然是執行一次,行爲與 Codex / Claude Code backend 一致。
- 結構化輸出是通過 prompt 約束,不是
format=約束。opencode 1.18.x 存在上游 bug:prompt 帶format: {type:"json_schema"}後,服務會持久化一個retryCount字段,導致GET /session/{id}/message返回 400,會話被污染。插件因此在 prompt 末尾追加一段約束輸出的說明來繞開。 - 插件以當前 dsh 進程的權限運行。裝之前檢查源碼,確認
servers裏配置的 url、password 和你暴露的 directory 範圍符合預期;opencode_init、opencode_summarize、opencode_shell都屬於會改遠端狀態或執行命令的工具。 permission默認是ask,會把遠端權限請求轉成 dsh 審批卡;如果你希望全自動跑,改成allow之前先想清楚後果。
文檔在倉庫裏:ARCHITECTURE.md(模塊圖、數據流、設計決策)、COMPATIBILITY.md(dsh / OpenCode 兼容性與版本策略)、docs/subagent-seam.md(subagent provider contract)、docs/chat-ui-proposal.md(頁面內遠程會話聊天提案),另有中文版 README.zh.md、TODO.md、CHANGELOG.md。
結尾¶
這個插件解決的是一個具體的接頭問題:讓 dsh 能用工具和原生 subagent 兩種方式驅動一個已經在線運行的 OpenCode 服務,同時保留遠端的實時進度、權限審批與會話續跑能力。它並非 OpenCode 的全功能克隆,遠端 UI 而已;真正的計算和上下文仍在 opencode serve 那一側。
目錄頁:https://www.skillhub.cn/plugins/yhuan416/dsh-opencode-client
源碼:https://github.com/yhuan416/dsh-opencode-client