2768651338/dsh-plugin-manager

2768651338/dsh-plugin-manager

设置 → 插件里的插件管理页:已装插件中文名与白话描述、一键启停、界面内改备注,支持搜索与筛选。

插件市场与管理deepseek-harness

dsh-plugin-manager

Every plugin finally speaks for itself — Chinese names, plain-language descriptions, one-click enable/disable, and in-UI notes editing for DeepSeek Harness.

Settings → Plugins → Plugin Manager · 165 plugins cataloged, one click to toggle, notes edited in place.

Overview · Compatibility · Install / Uninstall · Quick Start · Configuration · Permissions & Data · Features · Troubleshooting · Development

中文 · Español · 日本語 · Deutsch · Русский · Português · 한국어

2026-10-20 · v0.9.0 — Adapted to DSH 0.2.1-rc.2. The browser
manifest declares package dependencies, and the independent dsh-plugin-manager
row / dshPluginManager namespace preserves the official manager's install and
uninstall services. DSH 0.2.1 enforces owner access to these Remote endpoints.
🆕 2026-10-01 · v0.7.0 — Adapted to DSH 0.2.0 (0.2.0-rc.2) with a
dual-form codec artifact that registers on both the 0.1.x and the 0.2.0
typert chains (0.2.0 switched from zod instances to create() factories) —
the full e2e suite passes against both 0.2.0-rc.2 and 0.1.5-rc.3.
Catalog gained the 0.2.0 rows (dsh-hmr, the DeepSeek LLM split, the official
plugin manager rows); peer ranges widened to cover 0.2.0-rc.0+. Hot-reload
still works on 0.2.0 (the dsh-hmr service watches the global patch file).
🆕 2026-10-01 · v0.6.0 — Adapted to DSH 0.1.5 (0.1.5-rc.3): the host
and client halves build and pass the full e2e suite against the 0.1.5-rc.3
package set, and the test suite now runs hermetically (no local DSH install
needed). Also fixes a locale-namespace collision with @linxin666/dsh-web-ui-all.
🆕 2026-08-14 · v0.3.0 — In-UI notes editing is live: click Edit notes on any card to rename a plugin or rewrite its description in place. No more hand-editing catalog.json.
🏷️ v0.4.0 — Package renamed to the owner-controlled scope @2768651338/dsh-plugin-manager (previous @dsh-external/* scope was not authorized).
🔧 v0.2.x — Fixed endpoint 404 under tsx source launch (strict ./typert registration) and the cordis inject access (ctx.get channel).

Overview

Problem. The built-in "Plugin list" in DeepSeek Harness shows only English module names with no descriptions — once you install many plugins, nobody can tell what each row does. Enable/disable previously required hand-editing cordis.patch.yml, which is easy to break.

Who it's for. Every DeepSeek Harness user, especially people who install many plugins and want to know what each one does, toggle them safely, and annotate the ones the catalog doesn't cover.

Pain · Before · With this plugin Plugin list is meaningless · English module names only, no clue what each row does · Chinese name + one-line description + category for every plugin Toggling is manual · Hand-edit cordis.patch.yml (easy to break) · One-click switch, surgical line-level edits, hot-reloaded in ~1s Unknown plugins stay mysterious · Fallback text only · Add your own notes directly in the UI Nothing is safe from fat fingers · Any row can be disabled · System rows locked, !!js-controlled rows labeled

Compatibility

Item · Value DSH version · 0.2.1-rc.2, with regression coverage for 0.2.0-rc.2 and 0.1.5-rc.3 Verification · 2026-10-20, Windows / Node 24: isolated SDK builds and tests, strict Host RPC and actual browser SlotRegistry lifecycle. This does not replace a Desktop acceptance check. Install mechanism · dsh plugin --profile web add (bundle patch + dual-face row) Depends on · typert-loader / api-gateway / client-modules rows shipped in dsh-base + dsh-web-app

The official launcher boots via tsx from source; this plugin's strict ./typert registration is specifically designed to work under both plain-node and tsx source launch (covered by tests/claims.e2e.mjs). If you run a different DSH version, re-run the test suite before reporting issues.
Official manager coexistence: this plugin uses row id dsh-plugin-manager and service / Remote namespace dshPluginManager. The official plugin-manager row and pluginManager namespace remain available to the official sidebar, CLI and agent tools. After upgrading from 0.8.0, restart DSH and press Ctrl+F5 to load both updated halves. Custom configurations that inserted this plugin under plugin-manager must change that row id to dsh-plugin-manager.

Install / Uninstall

# Install (recommended, same bundle mechanism as dsh-navbar)
dsh plugin --profile web add github:2768651338/dsh-plugin-manager#main

# Alternative: install from a zip (download from the Release page), unzip to a path without spaces, then:
dsh plugin --profile web add file:/<unzipped-dir>/dsh-plugin-manager

# Alternative: build locally (clone this repository)
pnpm build   # tsc + tsdown → lib/index.js (host half) and lib/client.js (browser half)
dsh plugin --profile web add file:./dsh-plugin-manager
After installing, restart DeepSeek Harness and press Ctrl+F5 once. Open *Settings → Plugins → Plugin Manager*. The lib/ artifacts are committed, so GitHub installs need no local build.

Action · Command Upgrade · dsh plugin --profile web update (or re-run the add command), then restart DSH Disable (temporarily) · Click 停用/Disable on the plugin's own card in Plugin Manager — the row stays installed Remove · dsh plugin --profile web remove @txc2768651338/dsh-plugin-manager, then remove its rows from cordis.patch.yml if any

Quick Start

Minimal reproducible walkthrough (2 minutes):

# 1. Install
dsh plugin --profile web add github:2768651338/dsh-plugin-manager#main
# 2. Restart DeepSeek Harness, press Ctrl+F5 in the web page
  1. Open Settings → Plugins → Plugin Manager — you see the full catalog with Chinese names and descriptions.
  2. Toggle one plugin: search for trajectory, click 停用 (Disable) on the *轨迹视图* card → the row turns 已停用 within ~1 second (host-side effect; browser-side plugins fully unload after a page refresh).
  3. Annotate one plugin: click 编辑备注 (Edit notes) on the *联网搜索* card, rename it and add a note, click 保存 (Save) → the card updates immediately; 恢复默认 (Restore default) reverts it.

Configuration

Item · Details Toggle file · ~/.dsh/cordis.patch.yml (global layer, hot-reloaded by DSH) Notes override file · ~/.dsh/plugin-manager/catalog.json (auto-created on first save) Community catalog sources · Optional ~/.dsh/plugin-manager/catalog-sources.json; HTTPS or local JSON only, manually maintained in this release Environment variables · None of its own; follows DSH's DSH_HOME resolution for the files above Defaults · User override → later community sources override earlier ones → built-in catalog → English short name → fallback text Sensitive items · None — no keys, tokens, or credentials are read or stored

Permissions & Data

Scope · What it touches Files (read) · cordis.patch.yml, plugin-manager/catalog.json, optional plugin-manager/catalog-sources.json plus local source JSON files it names, the in-process loader plugin list, and the profile package.json (backup) Files (write) · ~/.dsh/cordis.patch.yml (toggle rows), ~/.dsh/plugin-manager/catalog.json (notes), and the profile package.json (restore) — inside the DSH home only Network · The browser half talks only to your local DSH /api RPC endpoint. If you configure an HTTPS catalog source, the host half fetches that JSON once per launch Credentials · Never read User data · Never read (no access to sessions, messages, or prompts)

Access control. This plugin uses DSH's Host access policy. On DSH 0.2.1+, the Gateway permits only owner Peers to call this plugin's Remote endpoints, including list, and rejects non-owner or disposed Peers before calling the service. Older hosts retain their own trust boundary. The tab footer displays local configuration paths returned by list.

Features

Feature · Description 📚 Bilingual catalog · 190+ built-in entries (name / description / category) in Chinese and English — the English UI shows English names/descriptions, falling back to the module short name + an English note instead of Chinese. Unlisted modules fall back automatically; every entry is customizable 🌐 Community sources · Optional local/HTTPS JSON catalog sources; invalid sources produce a warning and are skipped, while the built-in catalog and notes keep working 🔘 One-click toggle · Writes ~/.dsh/cordis.patch.yml (global layer); DSH's HMR watcher re-applies within ~1 second; enabling writes an explicit disabled: false that overrides lower layers ✏️ In-UI notes · "Edit notes" on each card edits the Chinese name/description (~/.dsh/plugin-manager/catalog.json), with one-click restore-to-default 🛡️ Safety guards · Bootstrap/transport/settings-shell rows locked as "System"; !!js-expression rows labeled "Expression-controlled"; a warning banner appears if the official plugin manager is still loaded alongside (takeover did not happen); a broken override file is reported with a one-click rename-aside rescue 🔍 Search & filter · Search by name/description/module (matching both languages), filter by category, enabled-count summary ↩️ Toggle undo · Disabling shows a 9-second in-card Undo button instead of a no-confirm instant change 💾 Backup & restore · Export notes + plugin list (profile dependencies/bundles) + the enable/disable patch to one JSON file; import previews every change first (notes to add/overwrite, dependencies, bundles, toggle rows) and only writes after you confirm — merges, never removes your existing entries. Non-registry dependency sources (git:/file:/URLs/shorthand) require per-item confirmation; unchecked entries are skipped

How It Works

Half · File · Role Host · lib/index.js · Registers the dshPluginManager cordis service (Typert remote): list / setEnabled / setOverride / removeOverride / exportBackup / previewBackup / importBackup / quarantineOverrides. Toggles use surgical patch-file editing — comments and !!js expressions preserved. Every file-writing method shares one serialized write queue (no cross-operation lost updates), and import runs as a read-only preview followed by a confirmed merge. Host · lib/typert.host.js · Exports ./typert; the typert-loader registers it as strict invocation definitions. Crucial fix: under tsx source launch the gateway and an external plugin can hold two copies of typert-protocol — decorator markers are invisible across copies (symptom: every call 404s). Strict registration goes through the shared registry, sidestepping module-instance identity. Browser · lib/client.js · Mounts the dshPluginManager remote namespace via the inject-free ctx.get() channel (avoids a self-mount deadlock) and registers the Plugin Manager tab in the settings.plugins.tab slot.

Runtime dependencies: @deepseek-ai/cordis and @deepseek-ai/dsh-typert-protocol resolve through DSH's profiles/node_modules fallback links — no extra pnpm downloads.

Custom Notes

Click Edit notes on any card. Saving with both fields empty removes that plugin's customization. Power users may still edit ~/.dsh/plugin-manager/catalog.json directly:

{
  "@dsh-external/dsh-navbar": { "name": "对话导航条", "desc": "对话区右缘的消息节点导航" }
}

Precedence: override file > built-in catalog > English short name.

Community Catalog Sources

Optional sources live in ~/.dsh/plugin-manager/catalog-sources.json. A source is display metadata only: it does not install code, enable plugins, or make anything executable. Later sources win field by field; user notes still win over every source.

{
  "version": 1,
  "sources": [
    { "id": "perrylink", "url": "https://raw.githubusercontent.com/PerryLink/dsh-catalog/main/data/packages.json" },
    { "id": "local", "path": "my-catalog.json" }
  ]
}

Normalized sources use the v1 format below; partial language fields are valid:

{
  "format": "dsh-plugin-manager-catalog-source",
  "version": 1,
  "entries": [
    {
      "key": "dsh-auto-review",
      "aliases": ["dsh-auto-review-legacy"],
      "name": { "zh": "自动审查", "en": "Auto review" },
      "description": { "zh": "一件事", "en": "One thing" },
      "category": "agent"
    }
  ]
}

category must be one of the built-in functional categories (core, llm, session, agent, tool, skill, ui, web, sandbox, storage, other); invalid values fall back to other. The existing PerryLink top-level array is accepted as a legacy format: displayName is the English name, locale: "zh" maps summary to the Chinese description, summaryZh supplies Chinese text for English summaries, and the first legacy category is mapped to the nearest built-in functional category.

Broken or too-large source files are skipped with a warning banner; local paths are resolved relative to catalog-sources.json. HTTPS is the only allowed remote protocol in v1, sources are cached once per DSH launch, and editing the source list requires restarting DSH.

Troubleshooting

Symptom · Fix The tab doesn't appear · Restart DeepSeek Harness, then Ctrl+F5 the page (client bundles load at boot) "暂时无法读取插件" with an error block · Read the gray error detail under the message: dshPluginManager.list failed: ... / transport failure ... and match it below Error mentions 404 or invocation-unavailable · Your installed version is older than 0.2.0 (missing ./typert strict registration) — update and restart cannot get property "remote.dshPluginManager" without inject · Version older than 0.2.2 — update and refresh A toggle doesn't seem to work · Check ~/.dsh/cordis.patch.yml keeps row-block structure (a - dash at column 0); rows labeled "表达式控制" are !!js-controlled — edit the config file directly pnpm warns peer range @deepseek-ai/*@* does not match resolved 0.2.0-rc.2 · Harmless — DSH ships these as prereleases and semver * doesn't match them. v0.7.0+ declares >=0.1.0-rc.0 \ · \ · >=0.1.5-rc.0 \ · \ · >=0.2.0-rc.0; for other plugins add peerDependencyRules.allowAny: ['@deepseek-ai/*'] to pnpm-workspace.yaml Where are the logs? · DSH host startup log (launcher console) for host errors; browser DevTools (F12) console for client errors Rollback · Remove the plugin's rows from cordis.patch.yml, use 恢复默认 for notes, or uninstall with the remove command above

Project Structure

src/
  index.ts              host half: PluginManagerGateway (list / setEnabled / setOverride / removeOverride)
  patch-file.ts         surgical patch-file editor (pure functions)
  catalog.ts            built-in catalog + system-protection set
  catalog-source.ts     community source schema, legacy adapter, and loading helpers
  types.ts              shared plain data types
  typert-host.ts        strict endpoint registration artifact (./typert)
  client/
    index.ts            browser half: mount remote namespace + register the tab
    remote.ts           client remote artifact (strict zod codecs)
    PluginManagerTab.tsx tab UI (list / toggles / notes editing)
    locales.ts          zh/en dictionaries
cordis.patch.yml        bundle patch (inserts the plugin-manager row)
lib/                    built artifacts (committed; GitHub installs skip building)
tests/                  smoke / end-to-end tests

Development

pnpm build                      # tsc + tsdown
pnpm lint                       # eslint (flat config, lenient rules)
pnpm typecheck                  # tsc --noEmit
pnpm test                       # patch-file / patch-yaml / fs-safe / client-util / origin / catalog-source / backup smokes + claims/gateway/host e2e
node tests/patch-file.smoke.mjs # patch editor smoke tests
node tests/client-util.smoke.mjs# browser-half pure-function smoke tests
node tests/host-gateway.e2e.mjs # host gateway end-to-end (incl. override-file contents)
node tests/claims.e2e.mjs       # endpoint claims under plain-node and tsx source launch

CI runs lint + typecheck + build + test on Node 22/24 against DSH 0.2.1-rc.2, and on Node 24 against 0.2.0-rc.2 and 0.1.5-rc.3. The client registration suite executes the built closure factory against each SDK's actual SlotRegistry, including late slot declaration, reload and disposal.

Artifact shape note: the two hand-written typert artifacts (src/client/remote.ts,
src/typert-host.ts) keep their generator-aligned descriptor shapes but share one
schema source (src/schemas.ts) — edit schemas there, not in the artifacts. If a
future host ever requires byte-exact comparison against generator output, split
the schemas back out.
The DSH host packages the tests boot against (dsh-app-boot, dsh-typert-*,
dsh-api-gateway, …) are pinned devDependencies at the DSH 0.2.1-rc.2
versions, and every entry path is resolved via import.meta.resolve — no
local DSH installation is needed to build, test, or typecheck. The dual-form
codec artifacts are regression-verified in isolated checkouts with
node scripts/use-dsh-version.mjs 0.2.0-rc.2 (or 0.1.5-rc.3), followed by
pnpm install --no-frozen-lockfile, pnpm build and pnpm test.

Contributing. Fork → change → pnpm build → run the tests above → open a PR against main. Small fixes (docs, catalog entries, translations) are welcome without prior discussion. Report issues with the DSH version and the exact error detail shown in the tab.