Bundle
@ch4acko3/dsh-ui-container
Remote-capable recursive UI surface container for DeepSeek Harness
- Source
- CH4ACKO3
- stars
- 2 stars
- License
- MIT
- Updated
- Updated yesterday
Readme
# dsh-ui-container
Reusable visual and service container for DeepSeek Harness browser plugins. It
owns named UI surfaces, document providers, recursive React hosts, and the small
remote protocol needed to connect another frontend without transmitting a DOM
or component tree.
Install the plugin into a DeepSeek Harness profile:
```sh
dsh plugin --profile web add github:CH4ACKO3/dsh-ui-container
```
This command is profile-scoped and can be run from any directory.
Git dependencies run this package's `prepare` build. With pnpm 10 or newer,
approve the exact package key reported by the first install in the profile's
`pnpm-workspace.yaml`, then repeat the command. Registry releases and packed
artifacts do not require that approval.
Other browser plugins import its public API from
`@ch4acko3/dsh-ui-container/client` and inject the `uiContainer` Cordis service.
## Remote transport
`@ch4acko3/dsh-ui-container` can project a container across a process or
network boundary. The remote contract transfers document snapshots and change
notifications; it never transfers React elements, DOM nodes or a Cordis service
object.
## Capabilities
Protocol version 1 negotiates these capabilities during the mandatory
handshake:
- `documents` resolves URI-based document projections.
- `subscriptions` subscribes to a URI and sends a small invalidation when its
projection may have changed.
- `surface_commands` routes open, reveal and close commands to a mounted surface
session. A server must opt in to this capability; it is disabled by default.
Document resolution includes an optional `known_revision`. When it matches the
current server revision, the response is `not_modified` and contains no document
payload. A change notification contains only the subscription id and URI. The
client then resolves the document again, so network usage follows actual data
changes rather than the size or nesting of the rendered component tree.
All remote document content and metadata must be JSON-compatible. Renderers stay
inside the receiving frontend and render the projection locally.
## Cross-process connection
Use `MessagePort` for a Worker, iframe bridge or host IPC adapter:
```ts
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'),
)
```
Dispose `unregister`, `remote`, and `stopServing` with the lifecycle that owns
the ports.
## Network connection
The network owner accepts and authenticates the WebSocket first, then exposes
the container over that socket:
```ts
webSocketServer.on('connection', (socket, request) => {
const principal = authenticate(request)
if (!principal) return socket.close(1008, 'Unauthorized')
const channel = createWebSocketUiRemoteChannel(socket)
exposeUiContainerRemote(ctx.uiContainer, channel, {
server: {
name: 'patchouli-host',
version: '0.1.0',
instance_id: processInstanceId,
},
capabilities: ['documents', 'subscriptions'],
})
})
```
A browser client can connect directly:
```ts
const remote = await connectUiContainerWebSocket('wss://host.example/ui', {
client: {
name: 'patchouli-web',
version: '0.1.0',
instance_id: crypto.randomUUID(),
},
protocol_versions: [UI_REMOTE_PROTOCOL_VERSION],
capabilities: ['documents', 'subscriptions'],
})
```
The transport intentionally does not define authentication. The application
that owns the WebSocket endpoint must enforce authentication, authorization,
TLS and origin policy before calling `exposeUiContainerRemote`. A server should
enable `surface_commands` only for principals allowed to control the addressed
frontend session.
## Wire contract
Messages are JSON-RPC 2.0. Method names carry their major version:
```text
ui.container.handshake@1
ui.container.document.resolve@1
ui.container.document.subscribe@1
ui.container.document.unsubscribe@1
ui.container.document.changed@1 # server notification
ui.container.surface.open@1
ui.container.surface.reveal@1
ui.container.surface.close@1
```
The TypeScript definitions in `src/client/remote-protocol.ts` are the normative
wire schema. A connection permits exactly one handshake, and every later method
must belong to a negotiated capability.
Install
dsh plugin --profile web add github:CH4ACKO3/dsh-ui-container
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install ch4acko3-dsh-ui-container from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.