Introduction

The philosophy of DSH is “everything is a plugin.” Over time, a profile often accumulates many community plugins. To temporarily disable one—for instance, a desktop pet or sidebar with a frontend interface—usually requires editing the configuration and restarting dsh, which entails a significant back-and-forth cost.

dsh-plugin-manager brings this capability into the WebUI: simply toggle the switch in “Settings → Plugins → Plugin Manager”. Switching takes effect immediately without restarting dsh. Below, we introduce its features, installation, and daily usage.

What is it

dsh-plugin-manager is a DSH plugin manager maintained by Retr67, currently at version 0.1.0 and licensed under the MIT License. It provides a WebUI panel to visually view the list of currently loaded plugins and their switch status, as well as perform a hot switch on user plugins.

The toggle mechanism uses the entry.update({ disabled }) method of the Cordis loader, following the same path as the official dsh-market theme toggle. It is only responsible for enabling and disabling plugins, not for installing or upgrading them.

Core Features

  • User plugins can be toggled: This includes community plugins installed via profile/package.json, as well as entries manually added to cordis.patch.yml (such as MCP bridges).
  • System components are read-only: The built-in host/web infrastructure of DSH is displayed only and does not offer a toggle to prevent accidentally disabling it, which would cause Harness to fail to start. The manager itself (plugin-manager) cannot be disabled.
  • No restart required: By default, the page refreshes automatically after a toggle, causing plugins with frontend interfaces (desktop pets, sidebars, etc.) to take effect immediately and fully. You can also switch to a manual refresh mode, saving the preference in browser localStorage.
  • Persistence across restarts: The IDs of disabled plugins are recorded in <profile>/.plugin-manager/state.json. On the next startup, they are automatically replayed as disabled until you re-enable them.
  • “Restore All” button: A one-click action to clear all plugins that are currently disabled.
  • Group plugin handling: When a group plugin cannot be directly disabled, the manager automatically toggles its child entries instead.

State persistence, startup replay, and self-healing guard (listening to the internal/plugin event) were ported from dsh-market.

Installation and Enablement

Environment Requirements: DeepSeek Harness (dsh) and Node.js (including npx) must be installed. The engines requirement is node >= 22, and it is compatible with Windows, macOS, and Linux.

Execute the following command in any terminal; it installs to the web profile by default:

npx -y @deepseek-ai/dsh plugin --profile web add https://github.com/Retr67/dsh-plugin-manager.git

This command installs dependencies and automatically adds the plugin to dsh.profile.bundles upon detecting that the package declares dsh.bundle, ensuring it loads automatically on the next startup.

If dsh is globally available, you can use it directly:

dsh plugin --profile web add https://github.com/Retr67/dsh-plugin-manager.git

To install to a different profile, simply replace web with the profile name:

npx -y @deepseek-ai/dsh plugin --profile myprofile add https://github.com/Retr67/dsh-plugin-manager.git

Note: This step only adds the plugin to dsh.profile.bundles and does not take effect immediately. After installation, you need to restart dsh web to load the plugin and refresh the browser page. The repository also includes install.ps1 / install.sh one-click scripts, which internally execute the standard npx command described above.

Uninstall command:

npx -y @deepseek-ai/dsh plugin --profile web remove dsh-plugin-manager

Usage

After completing the steps above, the plugin is loaded. The daily operations are as follows:

  1. Open “Settings (⚙️ / Settings) → Plugins → Plugin Manager”.

  2. The panel displays two categories:

  • User plugins (toggable): Each plugin is on a separate line with a toggle switch on the right; click to enable/disable.
  • System components (read-only): Only displayed, no toggle provided.
  1. Choose the refresh mode as needed:
  • Default auto refresh: The page refreshes automatically after a toggle, causing plugins with frontend interfaces (desktop pets, sidebars, etc.) to take effect immediately and fully.
  • Manual refresh: No automatic refresh after a toggle; click “Refresh” in the panel or manually refresh the page to take effect. This preference is saved in browser localStorage.

When you need to return to the “all enabled” state, click the “Restore All” button to clear all disabled plugins with a single click.

HTTP API

In addition to the panel, the plugin exposes three same-origin HTTP interfaces for scripting operations:

Method Path Description
GET /plugin-manager/list Returns the plugin list and toggle status
POST /plugin-manager/toggle { id, enabled } Hot switch a specific plugin
POST /plugin-manager/reset Restore all plugins that were kept disabled

The POST interfaces perform an Origin === Host same-origin check; the GET list is read-only and is only exposed on the web server bound to the loopback address.

Security and Implementation Boundaries

The host side only uses Node.js built-in modules (fs, os, path); there are no network calls, subprocesses, or eval. The client side uses React to render plugin names (with automatic escaping), and all requests are same-origin fetch.

Regarding implementation boundaries, it does not perform hot add/remove operations on dsh.profile.bundles in package.json—that requires a restart to take effect. Instead, it operates on the running loader entry, a method verified by dsh-market theme switching.

Applicable Scenarios and Notes

Suitable scenarios:

  • You have installed many plugins and want to temporarily disable one that is malfunctioning or no longer needed, without repeatedly restarting dsh.
  • You are debugging plugins with frontend interfaces and need to frequently toggle them to compare effects.
  • You want a specific plugin to remain disabled after a restart without manually editing configuration files.

Notes:

  • The toggle only affects the running loader entry and does not modify dsh.profile.bundles; adding or removing bundles still requires a restart.
  • Like all DSH plugins, this plugin runs with the permissions of the current dsh process. It is recommended to review the source code and license before installation. The source code for this plugin is open on GitHub under the MIT License.

Conclusion

dsh-plugin-manager solves a small but specific problem: turning “disabling a plugin requires a restart” into a simple toggle in the WebUI, while maintaining the state across restarts. If your profile accumulates more and more plugins, it is worth a try.

  • Community Plugin Directory Page: https://www.skillhub.cn/plugins/Retr67/dsh-plugin-manager
  • Source Code and README: https://github.com/Retr67/dsh-plugin-manager