Introduction

The philosophy of DSH is “everything is a plugin”. Browser plugins often need to collaborate: one plugin handles the UI surface, another reads document state, or Workers, iframe bridges, and host IPC adapters need to reuse the same frontend capabilities.

If this kind of collaboration directly copies components, synchronizes DOM, or passes Cordis service objects across boundaries, the boundaries become difficult to control. The dsh-ui-container introduced below addresses this problem: it provides a reusable UI surface container and uses a lean remote protocol to connect to another frontend. The remote contract transmits document snapshots and change notifications without transmitting React elements, DOM nodes, or Cordis service objects.

What is it

dsh-ui-container is a DeepSeek Harness browser plugin maintained by CH4ACKO3, with the package name @ch4acko3/dsh-ui-container and licensed under the MIT License.

It is designed as a remote-capable recursive UI surface container, with core responsibilities:

  • Having named UI surfaces
  • Managing document providers
  • Providing recursive React hosts
  • Providing the lean remote protocol needed to connect to another frontend

The key boundary of this plugin is: the receiver still renders the projection in its own frontend; the remote contract does not transport React elements, DOM nodes, or Cordis service objects.

Core Capabilities

The following outlines its defined capabilities.

Capability Negotiation

Protocol version 1 negotiates the following capabilities during the mandatory handshake phase:

  • documents: Parses URI-based document projections.
  • subscriptions: Subscribes to a URI and sends a smaller invalidation notification when its projection might change.
  • surface_commands: Routes open, reveal, and close commands to mounted surface sessions.

Among these, surface_commands is disabled by default and requires explicit enabling by the server.

Transport Channels

It supports two types of channels:

  • Cross-process MessagePort channels
  • WebSocket network channels

Remote Contract

The remote contract uses JSON-RPC 2.0, with method names carrying the major version number.

Connections only allow one handshake. After the handshake, subsequent methods must belong to the already negotiated capabilities.

All remote document content and metadata must be JSON-compatible.

Installation and Activation

First, install it to the DSH profile:

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

If the installation source triggers the prepare build for Git dependencies, and you are using pnpm 10 or later versions, you need to first approve the exact package key in the first installation report, write it to the profile’s pnpm-workspace.yaml, and then repeat the installation command.

Typical Usage

Injecting services in other browser plugins

Other browser plugins can import the public API from @ch4acko3/dsh-ui-container/client and inject the uiContainer Cordis service. Afterward, you can access container capabilities via ctx.uiContainer.

Connecting to another frontend using MessagePort

Suitable for Workers, iframe bridges, or host IPC adapters. First, create host and client channels, then expose the server, and finally connect the 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'),
)

Here, exposeUiContainerRemote exposes the container to the host channel, and UiContainerRemoteClient.connect completes the handshake on the client channel. After the steps above, the client side can register a document provider coming from the remote side.

At the end of the lifecycle, unregister, remote, and stopServing should be handled according to the lifecycle of the ports that own them.

Exposing the container using WebSocket

The remote transport layer does not define authentication. If exposing the container via WebSocket, the application owning that endpoint must handle authentication, authorization, TLS, and origin policy itself before calling exposeUiContainerRemote.

Assuming socket is a WebSocket connection that has passed the application-layer security policy check, you can first create the channel and then expose the container:

const channel = createWebSocketUiRemoteChannel(socket)

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

Use Cases and Considerations

Suitable for scenarios like:

  • Need to expose UI surfaces, document projections, or document providers from a DSH browser plugin to another frontend.
  • Need to share container capabilities between Workers, iframe bridges, host IPC adapters, or WebSocket endpoints without sending DOM or component trees across boundaries.
  • Want the receiver to complete rendering locally based on JSON-compatible document projections.

Note the following boundaries:

  • The plugin runs in the DSH host environment. Before installing, please check the source code and the MIT license, and confirm its permission boundaries for the current profile.
  • The remote protocol itself does not provide authentication. When using WebSocket, the server must execute authentication, authorization, TLS, and origin policy itself.
  • surface_commands is disabled by default. The server should only enable this capability if it explicitly allows a certain principal to control the corresponding frontend session.
  • Only one handshake is allowed per connection; after the handshake, only methods within the negotiated capabilities can be called.
  • If installed via Git dependency, using pnpm 10 or later versions requires approving the exact package key in the first installation report before repeating the installation command.

Conclusion

The value of dsh-ui-container is to converge DSH plugin frontend collaboration from “moving DOM / component trees” to “negotiating document projections and change notifications”. It does not expand the transmission boundary of the frontend objects themselves, but rather achieves cross-process, cross-endpoint container reuse using a narrower remote contract.

Repository Address: https://github.com/CH4ACKO3/dsh-ui-container