Preface

The philosophy of DeepSeek Harness (DSH) is “everything is a plugin”. However, following the official pipeline, bundles written into dsh.profile.bundles are loaded when the process starts and remain resident. To temporarily disable a third-party plugin, one must modify the profile manifest and then restart. At the same time, DSH has a key architectural requirement: optional third-party plugins can only be placed in dependencies and must not be written to dsh.profile.bundles—that is to say, the official static layer does not provide a location for enabling/disabling these plugins at runtime.

dsh-bundle-manager fills this gap: it mounts/unmounts bundles within the process via the Loader API, takes effect immediately without restart, does not modify the profile manifest, and provides named presets and self-healing failure fallback. The following sections introduce each point in detail.

What is this?

dsh-bundle-manager is maintained by KaramachiA217, under the MIT license. Its positioning is as a runtime mount manager for DeepSeek Harness optional third-party plugin packages. After installation, it itself enters the official static layer as a framework bundle and provides a “Plugin Mount Management” section on the settings page; the managed third-party plugins are only placed in dependencies and are mounted by it at runtime.

Two architectural constraints are clarified first:

  1. Optional third-party plugins can only be placed in dependencies and must not be written to dsh.profile.bundles;
  2. This plugin is the only framework bundle that mounts these plugins at runtime.

Core Features

Draft Toggles and One-time Application

In the local draft on the settings page, toggle plugin switches and click Save & Refresh to apply the entire table at once: the host side diffs out the mounts that need to be created/removed and persists them, followed by a hard refresh to align the client side. apply runs on a serial queue with a 30-second limit per run.

Named Presets

You can save the current draft combination as a named preset: uncommitted switches will be merged into the snapshot, and saving a preset with a new name will automatically activate it. Afterwards, you can switch presets from the dropdown box; deletion supports multi-select with irreversible confirmation, and refuses to delete the default preset or the currently active preset.

Self-healing Failure Fallback

Bad plugins won’t drag down other plugins: the plugin that errors falls into the Failed group (containing kind, attempt count, error message), while the rest continue to work. There is a built-in 20-second mount watchdog; on startup, mounts run in parallel by group, with the number of groups controlled by DSH_PM_BOOT_GROUPS, ranging from 1 to 8.

Security Mechanisms

The framework whitelist protects core bundles (marked as framework-protected); registry writes are atomic and keep a .bak most recent available copy; automatic old path migration is supported.

Coexistence with Official Static Layer (v0.5)

v0.5 introduces reversible switching between the official static layer (dsh.profile.bundles) and the bm runtime layer:

  • import-to-bm: Import plugins from the static layer into bm, handing them over to runtime management;
  • export-to-bundles / export-all-to-bundles: Export managed plugins from bm back to the official static layer; the latter can be used as a safety net to batch export all before removing bm.

Plugins covered by the static layer are displayed as superseded-by-static in bm. Import/Export edits the profile manifest, which are the three explicit exceptions to the “Never Rewrite Manifest” rule, and all use Level A redundancy: atomic write + .bm.bak backup + JSON.parse rollback, one-click batch rollback, dependency group hints, and framework hard protection.

Note: Track switching (Import/Export) requires a restart; mounting/unmounting within the bm runtime layer itself requires zero restart.

Partial Uninstall (v0.5)

Uninstall consists of two steps: first, bm unregisters the registry row (only clears bm’s own files, does not touch the manifest), and then guides the execution of the official dsh plugin remove pkg... (supports batch). Clearing the registry row first is to keep it reversible: if the official removal fails, the package degrades to a dormant dependency (installed, idle) and can be re-enabled on the settings page (rewrite registry row) to restore management. There is also a reactive GC that cleans up registry rows for packages removed externally bypassing bm and records a visible failed entry.

Fence API

The aforementioned capabilities are exposed via the Fence API /bundle-manager/api (browser-trust fence), comprising ten interfaces: list, apply, preset/save, preset/switch, preset/delete, import-to-bm, export-to-bundles, export-all-to-bundles, import/rollback, uninstall.

Installation and Enablement

Install using the official CLI, which adds dependencies in one step, and reconcile will append the package to dsh.profile.bundles:

dsh plugin --profile <profile-name> add dsh-bundle-manager

After installation, the profile layout generated by the CLI looks like:

{
  "dependencies": { "dsh-bundle-manager": "^0.5.3" },
  "dsh": { "profile": { "bundles": ["dsh-base", "dsh-web-app", "dsh-settings-ui", "dsh-bundle-manager"] } }
}

To upgrade, run again with @latest:

dsh plugin --profile <profile-name> add dsh-bundle-manager@latest

Runtime environment requires Node >= 20; peerDependencies includes dsh-settings-ui >=0.3.0, @deepseek-ai/cordis >=4.0.0-rc.0, @deepseek-ai/dsh-host-webserver >=0.1.0-rc.0, @deepseek-ai/dsh-client-runtime >=0.1.0-rc.0, and @deepseek-ai/dsh-client-ui-slots >=0.1.0-rc.0.

Local Development and Testing

For local development, first build a tarball with npm pack, then install the local package with the official CLI (or file: dependency); every change requires repackaging:

npm pack
dsh plugin --profile <profile-name> add ./dsh-bundle-manager-<ver>.tgz

Known difference: On rc.6, link: mounting fails due to ESM resolution; please use file: tarball instead.

There is one command each for testing and CI:

npm test     # Offline regression, 210 assertions, mock ctx drives fence API
npm run ci   # 5-step gate: syntax + test + key scan + cleanup + whitelist build

Compatibility

  • dsh 0.1.0-rc.5: Verified on the official desktop shell (framework bundle only).
  • rc.6 (Verified 2026-08-17): Same upstream commit 47f9438 as rc.5, zero code adaptation passed for runtime mount/unmount, framework whitelist, failure isolation, presets, registry persistence, and client side alignment.
  • rc.7 (Verified 2026-08-19): The only kit face settings.section used by bm is unchanged on rc.7; kit locks to npm release dsh-settings-ui@0.2.22, not depending on kit 0.3.0’s pluginCard/settingsScope.

See MANUAL.md in the repository for the full Chinese manual.

Use Cases and Notes

Suitable users:

  • DSH users who need to frequently start/stop third-party plugins and don’t want to modify the manifest and restart every time;
  • Users who want to save different plugin combinations as presets and switch with one click based on tasks;
  • Users who want to try static layer plugins on the bm runtime layer first, and then decide whether to harden them (or export them back).

Notes before use:

  1. Track switching (import-to-bm / export-to-bundles / export-all-to-bundles) requires a restart and is the only three exceptions to the “Never Rewrite Manifest” rule; mounting/unmounting within the bm runtime layer requires zero restart.
  2. apply is a serial queue with a 30-second limit; preset deletion is an irreversible operation, and default and the currently active preset are protected.
  3. Family single-track explanation: Other first-party family plugins (mcp / search / proxy / skill / balance, etc.) remain dependencies-only single-track, mounted by bm at runtime, and do not participate in import/export; the dual-track is an optional enhancement for external users.
  4. Plugins run with the current dsh process permissions; check source code and license before installation.

Summary

dsh-bundle-manager turns the start/stop of third-party plugins from “modify manifest + restart” into a single click on the settings page; failure isolation and dual-track coexistence make trial-and-error costs controllable. If you have many plugins in your DSH profile, it is worth a try.

  • Community directory page (independent site, no official affiliation with DeepSeek or Hypothesis): https://www.skillhub.cn/plugins/KaramachiA217/dsh-bundle-manager
  • GitHub repository: https://github.com/KaramachiA217/dsh-bundle-manager