dsh-plugin-toggle
Enable/disable DeepSeek Harness (dsh) plugins from Settings > Plugins, grouped into collapsible categories
- Stars
- 0
- Language
- JavaScript
- Created
- Aug 25, 2026
- Updated
- Aug 25, 2026
Introduction
dsh-plugin-toggle
Enable or disable DeepSeek Harness (dsh) plugins
directly from Settings > Plugins → Toggle, grouped into collapsible categories — no more
hand-editing cordis.patch.yml and hunting for the right row.
Unofficial, community plugin. Not affiliated with or endorsed by DeepSeek. Shared per deepseek-harness's CONTRIBUTING.md, which explicitly encourages independent plugins over upstream PRs (not accepted at this stage).
dshitself is developer preview — expect the internals this plugin relies on to shift.
What it does
- Adds a Toggle tab next to the built-in Plugin list and Plugin configuration tabs.
- Every plugin the tree currently composes gets a switch reflecting its effective state (after every bundle layer and patch override), grouped into ~11 collapsible categories (Core & Runtime, LLM & Credentials, Agent Loop, Tools, Sandbox & Permissions, Session & Storage, Client UI, …) instead of one long flat list.
- Flipping a switch:
- Persists an explicit
disabled: true|falserow for that plugin into a managed region appended at the end of the profile'scordis.patch.yml— your own rows and comments above it are never touched, and an empty region is removed entirely. - Applies the change to the live Loader tree immediately (
ctx.loader.update), because the web profile ships with patch-file hot-reload disabled — no restart needed for a toggle.
- Persists an explicit
- Categories start collapsed; state is remembered per browser (
localStorage). Searching auto-expands only the categories with a match.
Install
dsh has no plugin registry yet — install like any local/out-of-tree plugin:
git clone https://github.com/yogeek/dsh-plugin-toggle.git ~/.dsh/plugins/dsh-plugin-toggle
# make it resolvable from the profile (same trick the harness itself uses for its
# own installation-owned packages — see ~/.dsh/profiles/node_modules for reference)
ln -sfn ~/.dsh/profiles/node_modules ~/.dsh/plugins/node_modules
Add it as a linked dependency of the profile you want it in (usually web):
cd ~/.dsh/profiles/web
npm pkg set dependencies.dsh-plugin-toggle="link:$HOME/.dsh/plugins/dsh-plugin-toggle"
ln -sfn ../../../plugins/dsh-plugin-toggle node_modules/dsh-plugin-toggle
Register it in that profile's cordis.patch.yml:
- insert:
- id: plugin-toggle
name: 'dsh-plugin-toggle'
Restart dsh web once (needed to load the new plugin — the web profile does not hot-reload
cordis.patch.yml). After that, toggles apply live without further restarts.
How it works
- Host half (
lib/index.js): apluginToggleRemote service (TypertRemoteService), auto-discovered by dsh's Typert gateway through its SRC markers — no code generation, no rebuild of the harness.list()returns every entry the profile patch directly composes (nested agent-preset copies and dynamically-created entries with no stable id are excluded — see Known limitations);set({ entryId, enabled })writes the managed patch row and applies it live, rolling the row back if the live tree rejects the change. - Browser half (
lib/client.js): a hand-writtendsh.clientbundle (the harness's lazy-CJS module format) contributing asettings.plugins.tabslot entry, calling the Remote over the existing/apiconnection RPC channel — no generated remote artifacts or zod schemas required.
Known limitations
- Two entries share the same raw id but live at different tree depths are excluded, not merged.
A plugin an agent preset mounts inline (e.g.
include:agent-presets:tool-bash) is a different Loader entry from the top-levelinclude:tool-bash, sharing only the module name. Toggling one never silently affects the other — the Toggle tab only lists and can only write entries directly composed bycordis.patch.yml's top level; the rest are omitted rather than shown broken. - A toggled entry stays pinned by its managed row even if the underlying bundle composition
changes later. Delete the row from the managed region in
cordis.patch.ymlto fall back to the composed default. - Category rules are a client-side heuristic on the entry id (see
CATEGORY_RULESinlib/client.js), not an authoritative taxonomy from the harness. Tested against a real ~139-entry web profile composition; adjust the rules for your own composition if something lands oddly. - Protected entries (
include,plugin-toggleitself) cannot be toggled from the UI.
Compatibility
Built and tested against @deepseek-ai/dsh 0.1.1-rc.1 (developer preview). The Remote
discovery mechanism, the loader's patch semantics, and the settings.plugins.tab slot contract
are all internal APIs with no stability guarantee yet — a future dsh release may require changes
here. Issues and PRs against this repo are welcome.
License
MIT — see LICENSE.