dsh-ui-container:DeepSeek Harness 的 UI 容器與遠程投影插件

前言

DSH 的理念是「一切皆插件」,瀏覽器插件之間經常需要協作:一個插件負責界面表面,另一個插件讀取文檔狀態,或者 Worker、iframe bridge、host IPC adapter 需要複用同一份前端能力。

這類協作如果直接複製組件、同步 DOM,或者把 Cordis service 對象跨端傳遞,邊界會很難控制。下面介紹的 dsh-ui-container 面向這個問題:它提供一個可複用的 UI 表面容器,並用一個較小的遠程協議連接另一個前端,遠程契約傳輸文檔快照和變更通知,不傳輸 React 元素、DOM 節點或 Cordis service 對象。

這是什麼

dsh-ui-container 是由 CH4ACKO3 維護的 DeepSeek Harness 瀏覽器插件,包名爲 @ch4acko3/dsh-ui-container,許可證爲 MIT。

它的定位是 remote-capable recursive UI surface container,核心職責是:

  • 擁有 named UI surfaces
  • 管理 document providers
  • 提供 recursive React hosts
  • 提供連接另一個前端所需的小遠程協議

這個插件的關鍵邊界是:接收端仍然在自己的前端裏渲染投影;遠程契約不搬運 React 元素、DOM 節點或 Cordis service 對象。

核心能力

下面介紹它已經明確的能力。

能力協商

協議版本 1 會在強制握手階段協商以下能力:

  • documents:解析基於 URI 的文檔投影。
  • subscriptions:訂閱某個 URI,並在其投影可能變化時發送較小的失效通知。
  • surface_commands:把 open、reveal、close 命令路由到已掛載的 surface session。

其中,surface_commands 默認禁用,需要服務端顯式開啓。

傳輸通道

它支持兩類通道:

  • 跨進程 MessagePort 通道
  • WebSocket 網絡通道

線上契約

線上契約使用 JSON-RPC 2.0,方法名帶主版本號。

連接只允許一次握手。握手之後,後續方法必須屬於已經協商的能力。

所有遠程文檔內容和元數據要求 JSON 兼容。

安裝與啓用

先安裝到 DSH profile:

dsh plugin --profile web add github:CH4ACKO3/dsh-ui-container

如果安裝來源會觸發 Git 依賴的 prepare 構建,使用 pnpm 10 或更新版本時,需要先批准首次安裝報告中的精確包鍵,寫入該 profile 的 pnpm-workspace.yaml,再重複執行安裝命令。

典型用法

在其他瀏覽器插件中注入服務

其他瀏覽器插件可以從 @ch4acko3/dsh-ui-container/client 導入公共 API,並注入 uiContainer Cordis service。之後即可通過 ctx.uiContainer 訪問容器能力。

用 MessagePort 連接另一個前端

適用於 Worker、iframe bridge 或 host IPC adapter。先創建 host 和 client 通道,再暴露服務端,最後連接客戶端。

const hostChannel = createMessagePortUiRemoteChannel(hostPort)
const clientChannel = createMessagePortUiRemoteChannel(clientPort)

const stopServing = exposeUiContainerRemote(ctx.uiContainer, hostChannel, {
  server: {
    name: 'patchouli-host',
    version: '0.1.0',
    instance_id: crypto.randomUUID(),
  },
})

const remote = await UiContainerRemoteClient.connect(clientChannel, {
  client: {
    name: 'patchouli-window',
    version: '0.1.0',
    instance_id: crypto.randomUUID(),
  },
  protocol_versions: [UI_REMOTE_PROTOCOL_VERSION],
  capabilities: ['documents', 'subscriptions'],
})

const unregister = ctx.uiContainer.documents.registerProvider(
  remote.createDocumentProvider('memory'),
)

這裏,exposeUiContainerRemote 把容器暴露到 host 通道,UiContainerRemoteClient.connect 在 client 通道完成握手。經過上面的步驟,客戶端側可以註冊一個來自遠端的 document provider。

在生命週期結束時,應按擁有這些 ports 的生命週期處理 unregister、remote 和 stopServing。

用 WebSocket 暴露容器

遠程傳輸層不定義認證。如果通過 WebSocket 暴露容器,擁有該端點的應用必須在調用 exposeUiContainerRemote 之前,自行處理認證、授權、TLS 和 origin policy。

假設 socket 是已通過應用層安全策略檢查的 WebSocket 連接,可以先創建通道,再暴露容器:

const channel = createWebSocketUiRemoteChannel(socket)

exposeUiContainerRemote(ctx.uiContainer, channel, {
  server: {
    name: 'patchouli-host',
    version: '0.1.0',
    instance_id: crypto.randomUUID(),
  },
  capabilities: ['documents', 'subscriptions'],
})

適用場景與注意

適合這類場景:

  • 需要把 DSH 瀏覽器插件中的 UI 表面、文檔投影或 document provider 暴露給另一個前端。
  • 需要在 Worker、iframe bridge、host IPC adapter 或 WebSocket 端點之間共享容器能力,而不想跨邊界發送 DOM 或組件樹。
  • 希望接收端基於 JSON 兼容的文檔投影,在本地完成渲染。

注意以下邊界:

  • 插件運行在 DSH 宿主環境中。安裝前請檢查源碼和 MIT 許可證,並確認它對當前 profile 的權限邊界。
  • 遠程協議本身不提供認證。使用 WebSocket 時,服務端必須自己執行認證、授權、TLS 和 origin policy。
  • surface_commands 默認禁用。服務端只有在明確允許某個主體控制對應前端會話時,才應啓用該能力。
  • 每條連接只允許一次握手;握手後只能調用已協商能力內的方法。
  • 如果通過 Git 依賴安裝,使用 pnpm 10 或更新版本時,需要批准首次安裝報告中的精確包鍵,再重複安裝命令。

結尾

dsh-ui-container 的價值,是把 DSH 插件之間的前端協作從「搬 DOM / 組件樹」收斂爲「協商文檔投影和變更通知」。它沒有擴大前端對象本身的傳輸邊界,而是用較窄的遠程契約完成跨進程、跨端點的容器複用。

倉庫地址:https://github.com/CH4ACKO3/dsh-ui-container

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜