DeepSeek Harness Bluebook
Developer Guide

Dynamic Plugins

The runtime dynamic plugin model: Host and Client halves, immutable package versions, the define/run/stop/undefine lifecycle and approval flow

A dynamic plugin temporarily extends the running harness process: it mounts new capability without editing repository source or restarting. It suits temporary interfaces, one-off tools, or quick validation. It exists only in the current process — definitions are not written to on-disk config and do not survive a restart.

Host and Client halves

A dynamic plugin has two halves, each running on a different platform:

Runs in the DSH Node.js process. Suited to files, networking, commands, Agent/Session access, Host events, services, model tools, and JSON methods callable by the Client.

The halves communicate through package-private JSON methods, in the Client → Host direction; only lossless JSON crosses that boundary. Host versus Client is an implementation choice: use Client when visible page behavior is needed, Host otherwise.

Immutable package versions

A dynamic plugin is identified by a stable id and can be modified over time; each change appends a new immutable Package instead of overwriting an old one.

  • pluginId: identifies one plugin that can be modified over time.
  • packageId: one immutable Host/Client source version under that plugin.
  • currentPackageId: the most recent fully successful version.
  • nextPackageId: the target awaiting approval, being attempted, awaiting Client activation, or most recently failed.

Because old versions are never overwritten, you can update or roll back between versions.

Lifecycle

  • define: records source without running it. Defining only validates parameters and syntax.
  • run: activates one exact version. Use run for the first activation, restarting the current version, or rollback; use update to switch versions.
  • update: stops the old version, then starts the target. A failed update does not automatically restart the old version.
  • stop: stops the current run and cancels unfinished approval/activation requests, while retaining definitions, versions, and grants.
  • undefine: permanently stops and deletes the plugin and all its versions.

Approval flow

Activating an unauthorized Client package creates an approval request; it proceeds only after authorization. A single check authorizes the current version only; double check authorizes future versions of the same plugin. A grant remains in effect after a technical failure; do not request approval again after the user rejects it.

Asynchronous results

A run result of "starting" only means the request entered the asynchronous flow — not success. Success, rejection, or technical failure is reported through runtime state; after a failure, read the diagnostics and fix the same plugin rather than silently creating another.

Every side effect is reversible

A plugin's services, events, tools, handlers, timers, Slots, styles, and theme overrides must all belong to the current fiber's lifecycle. Use ctx.effect(), ctx.on(), or official APIs that return a disposer, so stop, update, and undefine unwind every side effect.

Next steps

On this page