How a Floating Pet Plugin Exposes the UI Extension Model Inside DeepSeek Harness
Most AI coding tools lock down their interfaces; DeepSeek Harness exposes a slot-based UI plugin system that lets developers reshape the editor they stare at all day. The dual-entry pattern keeps front-end dependencies out of the Node process, a practical separation that other plugin architectures often miss.
DeepSeek Harness supports two plugin types: server-side tools that give models new capabilities, and client-side UI plugins that modify the interface itself. A new open-source salted-fish pet plugin demonstrates the latter, injecting React components into `shell.overlay` slots to add a floating companion and a wallpaper picker. The plugin uses a dual-entry structure—an empty Node-side `apply` function satisfies the Cordis loader, while the real component logic loads only in the browser—so installing a UI plugin adds zero weight to the server process. Cross-slot state between the pet and wallpaper modules is handled through a module-level shared store with listener subscriptions, since the two components live in separate React trees. Wallpaper selection persists via localStorage and broadcasts changes through CustomEvents on the window object. The build pipeline auto-scales and base64-encodes images, so adding a wallpaper means dropping a file into a directory. The plugin registers into the user's persistent profile through a single npx command that patches the bundle manifest, surviving terminal restarts.
Slot-based UI extension models invert the typical plugin approach: instead of plugins reaching into the host, the host exposes designated injection points with explicit contracts, which constrains what plugins can break but also limits what they can reach.
The dual-entry pattern solves a real dependency problem—an empty Node-side entry means UI plugins don't pollute the server runtime with React and DOM libraries, a separation that many Electron-based tools fail to enforce.
Using `backdrop-filter` on a parent element silently changes the containing block for all `position: fixed` children, a CSS behavior documented on MDN but still surprising in practice because it breaks portal-rendered panels that assume the viewport as their container.
CSS Modules' hashed class names create a deliberate encapsulation boundary that UI plugins must pierce with fragile attribute selectors; this tension between host encapsulation and plugin extensibility has no clean resolution in current web standards.
The plugin's known limitations—no persistence, no config panel, DOM-dependent button positioning—are honest trade-offs for a display-only plugin, but they also highlight how much infrastructure a "real" UI plugin needs before it feels like a first-class feature.