# dsh-plugin-hub [![npm](https://img.shields.io/npm/v/@wingsky-1/dsh-plugins-all)](https://www.npmjs.com/package/@wingsky-1/dsh-plugins-all) [![CI](https://github.com/wingsky-1/dsh-plugin-hub/actions/workflows/ci.yml/badge.svg)](https://github.com/wingsky-1/dsh-plugin-hub/actions/workflows/ci.yml) [![License](https://img.shields.io/github/license/wingsky-1/dsh-plugin-hub)](LICENSE) [简体中文](README.md) | **English** A collection of plugins for the **DSH (DeepSeek Harness)** web GUI, distributed via npm: install them all at once as a single bundle, or pick individual plugins as needed. - **Bundle package**: `@wingsky-1/dsh-plugins-all` — install everything in one shot - **Individual plugins**: `@wingsky-1/dsh-*` — install only what you need ## Quick navigation [Before you start](#before-you-start) · [Quick start](#quick-start) · [Plugin list](#plugin-list) · [Configuration and maintenance](#configuration-and-maintenance) · [Verification and troubleshooting](#verification-and-troubleshooting) · [Detailed reference](#detailed-reference) · [Development and architecture](#development-and-architecture) ## Before you start ### Version support (rc only) This plugin set only adapts to **rc (release-candidate) releases of DeepSeek Harness — alpha versions are not supported**. - All plugins are currently pinned to `dsh 0.1.5-rc.1` (the official type-layer catalog and every package's peerDependencies are locked in lockstep) - npm/pnpm will surface a peer mismatch if your dsh version does not match — upgrade the dsh CLI to the corresponding rc release first - Per-release adaptation baselines, breaking changes and upgrade guides live in [Release Notes](docs/release-notes/) - The plugin set follows official rc releases; **alpha versions are unsupported** — do not install on an alpha dsh (or accept the compatibility risk yourself) ### Individual install vs. bundle: pick ONE (since 0.1.5) Each individual package and the bundle share the same patch `id` (`ui-*`). **Install only one way** — installing both `dsh-plugins-all` and any individual package such as `@wingsky-1/dsh-lan-proxy` results in duplicate same-name entries, and `dsh web` fails to start with a *duplicate* error (detectable, not corrupting). To adjust: uninstall the bundle, or uninstall the corresponding individual package, then restart. ### Per-plugin security boundaries - After installing `dsh-lan-proxy`, HTTP/HTTPS ports are opened on `0.0.0.0` — **every device on your LAN can access your dsh**. Uninstall it when not needed. - The launch-token auto-injection of `dsh-lan-proxy` (`injectToken`) is **on by default**: any device on the LAN that can reach the port gets full dsh control without a token (equivalent to trusting the entire LAN — bash passthrough to the host). Enable it only on a trusted intranet; turn it off in the settings card on untrusted segments. - The stdio subprocesses of `dsh-mcp-manager` inherit host privileges; only configure MCP servers you trust. - Plugin management routes are loopback-fenced (non-loopback → 403, wrong method → 405); requests forwarded through `dsh-lan-proxy` are trusted by design, not isolated from LAN clients. - `dsh-notifier` owns its configuration files; settings responses mask channel credentials, but notification text and outbound error details are not redacted and may reach logs, history and push services. - `dsh-provider-usage` keeps API keys on the host, never in the browser. - `dsh-verify-isolated` uses a temporary DSH_HOME, independent profile, port and browser instance; this is a verification boundary, not a global security guarantee. - `dsh-worktree-sidebar` changes only the sidebar root; session cwd, `@` references and `present` remain anchored to cwd. See each plugin README for its threat model and hardening details. ## Quick start Prerequisite: DeepSeek Harness installed and `dsh web` running normally (for running dsh without a global install, see "Without a global dsh install" below). ### Install plugins (add) ```sh # Install everything (recommended) dsh plugin --profile web add @wingsky-1/dsh-plugins-all # Or install individual plugins (as needed) dsh plugin --profile web add @wingsky-1/dsh-notifier dsh plugin --profile web add @wingsky-1/dsh-lan-proxy ``` > After install / uninstall / update, **restart `dsh web` once** (bundle layers are only > composed at startup) for the sidebar / settings page to reflect the change. ### Access and verify Restart `dsh web`, open its startup URL, and check the installed plugin cards under Settings → Plugins. For notifier, send a test notification; for LAN access, follow the [LAN proxy access and health checks](packages/dsh-lan-proxy/README.en.md#quick-start). ## Plugin list | Package | What it does | Docs | Status | |---|---|---|---| | `@wingsky-1/dsh-notifier` | Task-event notifications via browser, host toast, Bark and Webhook. | [README](packages/dsh-notifier/README.en.md) · [Architecture](docs/architecture/dsh-notifier.md) | Published | | `@wingsky-1/dsh-provider-usage` | Multi-provider usage statistics, trends and reports with custom adapters. | [README](packages/dsh-provider-usage/README.en.md) · [Adapter guide](packages/dsh-provider-usage/docs/adapter-guide.md) · [Architecture](docs/architecture/dsh-provider-usage.md) | Published | | `@wingsky-1/dsh-lan-proxy` | LAN HTTP/HTTPS/WebSocket forwarding with TLS, compression and keep-alive. | [README](packages/dsh-lan-proxy/README.en.md) · [Architecture](docs/architecture/dsh-lan-proxy.md) | Published | | `@wingsky-1/dsh-mcp-manager` | Per-workspace MCP configuration and middleware-based tool access. | [README](packages/dsh-mcp-manager/README.en.md) · [Architecture](docs/architecture/dsh-mcp-manager.md) · [Upgrade repair](#mcp-catalog-upgrade-notice-and-repair) | Published | | `@wingsky-1/dsh-verify-isolated` | Isolated browser verification for DSH plugin development. | [README](packages/dsh-verify-isolated/README.en.md) · [Architecture](docs/architecture/dsh-verify-isolated.md) | Published | | `@wingsky-1/dsh-worktree-sidebar` | Bind a worktree to the session sidebar without changing its cwd. | [README](packages/dsh-worktree-sidebar/README.en.md) · [Architecture](docs/architecture/dsh-worktree-sidebar.md) | Unreleased | ## Configuration and maintenance Use the plugin cards under Settings → Plugins; configuration and storage boundaries differ by plugin, so follow its README. ### Uninstall plugins (remove) ```sh dsh plugin --profile web remove @wingsky-1/dsh-notifier ``` ### Update plugins (update) ```sh # Update a single plugin to latest dsh plugin --profile web update @wingsky-1/dsh-notifier # Update the bundle (aggregate + the sub-packages it pulls in) to latest dsh plugin --profile web update @wingsky-1/dsh-plugins-all # Update all plugins under the current profile dsh plugin --profile web update ``` > After install / uninstall / update, **restart `dsh web` once** (bundle layers are only > composed at startup) for the sidebar / settings page to reflect the change. ## Verification and troubleshooting If a plugin is missing after installation, first restart `dsh web`. For duplicate entry errors, check that bundle and individual packages are not installed together. > **Upgraded DSH from a pre-0.1.5 version and a historical session will not open?** > Sessions failing with `cannot safely transform unclassified message source` were hit by the > host migration gate on the capability-catalog messages injected by early `dsh-mcp-manager` > builds (the artifact is intact — it simply cannot be read). **One command recovers them**: > > ```sh > # stop dsh web before applying; logs being written cannot be safely rewritten > node scripts/maintenance/repair-mcp-catalog-sessions.mjs # dry run: list affected sessions > node scripts/maintenance/repair-mcp-catalog-sessions.mjs --apply # apply (backup first), then restart dsh web > ``` > > See [the repair guide](#mcp-catalog-upgrade-notice-and-repair) · > [issue #723](https://github.com/wingsky-1/dsh-plugin-hub/issues/723) ## Upgrade notice and repair: a historical session will not open (mcp-catalog) **Symptom**: after upgrading from a pre-0.1.5 DSH, some historical sessions report in the GUI: ``` 历史加载失败:failed to observe session "session-…": cannot safely transform unclassified message source; source v0 artifact remains unchanged (raw log: …/session.jsonl.zstd)(gateway/internal) ``` and `session.v3.jsonl.zstd` never appears next to the original log — every attempt fails the same way. **Cause (the session is not corrupt)**: `dsh-mcp-manager` 0.2.x and earlier wrote the catalog injection message as `source.kind = "mcp-catalog"`, while DSH 0.1.5's session-format v2-to-v3 migration validates surface `source.kind` against a **closed whitelist**; a self-invented value is refused and the artifact is (by host design) **preserved unchanged**. The v3 read path itself does not validate that field, so only sessions written before the upgrade by a host that ran this plugin with catalog injection are affected; new sessions after the upgrade are fine. **Repair**: current plugin versions use the host-registered generic source shape (no such message is produced any more). Artifacts already on disk are repaired in place by a one-off script that touches only source metadata, never the body or the event sequence: ```sh # stop dsh web first: a log being written is not guaranteed safe to rewrite node scripts/maintenance/repair-mcp-catalog-sessions.mjs # dry run: list affected sessions node scripts/maintenance/repair-mcp-catalog-sessions.mjs --apply # apply: .bak- first, atomic write # restart dsh web and open the session ``` - Reads `` by default (`--home ` / `DSH_HOME` overrides it); `--session ` limits it to one session - Idempotent; self-checked writes (frame structure + per-line JSON + zero leftover legacy kinds); rollback = restore the `.bak-` - **v3 sessions are repaired by default too**: a v3 session can carry both kinds (created before the upgrade, written incrementally after it), and a future v3-to-v4 migration with a similar gate would repeat this outage; the rewrite only swaps source metadata, leaving v3 semantics unchanged. `--legacy-only` limits the run to v0/v1/v2 - Never writes a v3 artifact: DSH still performs the migration itself for v0/v1/v2 - Details and evidence: [dsh-mcp-manager README](packages/dsh-mcp-manager/README.en.md#723-repair) and [issue #723](https://github.com/wingsky-1/dsh-plugin-hub/issues/723) ## Detailed reference ### Capabilities in detail - **Task-event notification center**: six task-event kinds (ask / approval / completion / subagent completion / error / turn end) with dual-channel delivery — browser notifications + host system toasts — plus Bark / Webhook push to your phone; quiet hours with urgent exceptions, per-channel popup/sound switches (4 tones), and a host capability self-check (`/diagnostics`) - **Context-cost-controlled MCP management**: project-level MCP is collapsed into the four atomic tools `ws_mcp_list` / `ws_mcp_detail` / `ws_mcp_search` / `ws_mcp_call` by default, so project-level scale never balloons the context (`middleware: all` folds global servers into the middleware too, hot-switchable from the settings page); per-working-directory project/global config tiers let each repo carry its own MCP servers without cross-project interference - **Extensible usage-stats framework**: supports multi-provider usage stats and custom data-source adapters; covers daily usage derivation, usage trends, peak/valley countdown, and daily/weekly/monthly reports - **Engineering-quality backing**: every plugin ships smoke assertions (route fences / client contracts), plus build contract + pack checks + full gates run in CI ### `@wingsky-1/dsh-notifier` Task-event notification center: 6 event kinds (ask / approval / completion / subagent completion / error / turn end), dual channels (browser Notification + host system toast) plus Bark/Webhook push channels (ntfy, Gotify, self-hosted gateways); quiet hours with urgent exceptions, per-channel popup/sound switches (4 tones), and a host capability self-check (`/diagnostics` with availability and remediation hints) ### `@wingsky-1/dsh-provider-usage` Multi-provider usage stats framework (v2 adapter contract): persistent capsule + detail panel; DeepSeek official (interval-bookkeeping daily usage derivation + peak/valley countdown badge — works even without an official usage endpoint) and OpenCode Go built in; plug in any data source with a single mjs file, hot-swappable from the settings page; daily/weekly/monthly usage reports (generated via the host llm, including directory and time-of-day observations); API keys stay on the host, never reach the browser ### `@wingsky-1/dsh-lan-proxy` Access the dsh web UI over LAN: HTTP/HTTPS/WS forwarding + TLS (self-signed / custom certs); dual compression for HTTP (Brotli/gzip adaptive) and WebSocket (permessage-deflate); WS half-open probing keeps mobile backgrounding from going stale; launch-token auto-injection lets LAN devices connect without fetching the token; DNS-rebinding protection + loopback target allowlist ### `@wingsky-1/dsh-mcp-manager` MCP server manager (stdio / streamable-http): per-working-directory project/global config tiers; all MCP collapsed into 4 atomic tools via the middleware (no model-visible `mcp__` direct-call tools); workspace isolation prevents cross-project interference; configs store `${ENV}` references only — no plaintext secrets on disk; runtime registration API for other plugins to inject MCP servers; optional MCP call statistics and debug mode (metadata-only, off by default) ### `@wingsky-1/dsh-verify-isolated` Isolated-environment browser verification skill for DSH plugin development: temp DSH_HOME + independent profile + independent port + independent browser instance (four-way isolation), one-command launch with automatic cleanup; bundled zero-dependency raw-CDP browser driver (snapshot / click / screenshot / eval, with device-viewport emulation), optional isolation audit, first-run dialogs skipped by default ### `@wingsky-1/dsh-worktree-sidebar` Three agent tools (register / create / remove) bind a git worktree to the current session so its right-sidebar file tree uses that root, while the session cwd stays unchanged (`@` references and `present` still resolve against cwd); child sessions inherit the parent binding; rereads on tab open, official refresh, or window becoming visible, without polling
Installation variants: version pinning and npx ### Pin a version (@version) Omitting `@version` installs the default latest (recommended). Only when the registry has not synced the latest yet, or the latest has issues in your environment, append `@version` to the package name — works for both `add` and `update`: ```sh # Install a specific version (instead of latest) dsh plugin --profile web add @wingsky-1/dsh-notifier@ # Update to a specific version dsh plugin --profile web update @wingsky-1/dsh-notifier@ ``` ### Without a global dsh install If there is no global `dsh` command on the machine, use `npx` to run it on the fly (`dsh plugin` calls `pnpm` under the hood, so `pnpm` and `Node.js` must still be installed locally): ```sh # Install the bundle npx @deepseek-ai/dsh plugin --profile web add @wingsky-1/dsh-plugins-all # Install an individual plugin (with a version pin) npx @deepseek-ai/dsh plugin --profile web add @wingsky-1/dsh-notifier@ # Uninstall / update (same shape — swap add for remove / update) npx @deepseek-ai/dsh plugin --profile web remove @wingsky-1/dsh-notifier npx @deepseek-ai/dsh plugin --profile web update @wingsky-1/dsh-plugins-all ``` > `npx` fetches `@deepseek-ai/dsh` on each run. To pin it, run `pnpm add -g @deepseek-ai/dsh` > (or `npm i -g @deepseek-ai/dsh`) and then use `dsh` directly.
Historical maintenance & migration — discontinued packages and legacy-package migration (expand if you installed the old/retired packages) **Discontinued (do not install; deprecated on npm)**: - `@wingsky-1/dsh-skill-explorer` (skill-center / skill management) is discontinued; both the plugin package and the bundle package have been removed. A better implementation now ships on the web UI side, `@linxin666/dsh-client-ui-skill-explorer` (`dsh-web-ui` repository `packages/dsh-skill-explorer`), which supports symlink detection, safe handling of linked skills, and more. Use the built-in skill center in the web UI instead. - `@wingsky-1/dsh-idle-archive` (idle-conversation archiving prompt) is discontinued because the community offers more mature session lifecycle-management / archiving implementations (e.g. [dsh-session-pruner](https://github.com/mrzhangkris/dsh-session-pruner)). - `@wingsky-1/dsh-subagent-model-inherit` (child agents inherit parent-session model and reasoning effort) is discontinued because official dsh-subagent 0.1.2-alpha.2 natively implements `resolveChildAgentOptions` (child agents inherit the parent session's model / reasoning effort / output-token limit). - `@wingsky-1/dsh-codegraph` (codegraph local code-graph MCP + worktree development discipline) is discontinued: the wrapper tools are tightly coupled to the codegraph CLI version, so the maintenance cost exceeds the benefit. - `@wingsky-1/dsh-mem0` (mem0 long-term memory system) is discontinued: environment-isolation and related defects were never resolved (#644 / #612), so it no longer meets the bar for continued maintenance. - `@wingsky-1/dsh-web-file-preview` (rewrites "open with the default application" into the built-in right-Sidebar preview) is discontinued: official dsh 0.1.6 routes delivered-file mention clicks to the built-in Sidebar preview, leaving only the card menu's explicit "open in default app" entry, which the plugin rewrote against the user's explicit intent (#840). Uninstall these packages if you installed them before: ```sh dsh plugin --profile web remove @wingsky-1/dsh-skill-explorer dsh plugin --profile web remove @wingsky-1/dsh-idle-archive dsh plugin --profile web remove @wingsky-1/dsh-subagent-model-inherit dsh plugin --profile web remove @wingsky-1/dsh-codegraph dsh plugin --profile web remove @wingsky-1/dsh-mem0 dsh plugin --profile web remove @wingsky-1/dsh-web-file-preview ``` > dsh-memory (project long-term memory) is not included yet; it is planned. **Legacy packages (published historically, no longer distributed)**: `@wingsky-1/dsh-gzip` → merged into `@wingsky-1/dsh-lan-proxy` (since 0.1.9) HTTP response compression moved wholesale into lan-proxy (on by default, Brotli/gzip negotiated via Accept-Encoding, SSE streaming exempt, configurable). Uninstall dsh-gzip and install dsh-lan-proxy to get the equivalent: ```sh dsh plugin --profile web remove @wingsky-1/dsh-gzip dsh plugin --profile web add @wingsky-1/dsh-lan-proxy ``` `@wingsky-1/dsh-opencode-usage` → renamed/refactored to `@wingsky-1/dsh-provider-usage` Refactored into a multi-provider adapter framework (built-in OpenCode Go, custom data-source adapters supported). The patch `id` changed from `ui-dsh-opencode-usage` to `ui-dsh-provider-usage` and config keys were adjusted — nothing migrates automatically. Reinstall, then re-check your settings in the settings panel (e.g. `apiKey`, `baseUrl`): ```sh dsh plugin --profile web remove @wingsky-1/dsh-opencode-usage dsh plugin --profile web add @wingsky-1/dsh-provider-usage ``` > Both legacy packages are marked deprecated on npm (installing them prints a migration hint).
### Related projects - [dsh-web-mobile](https://github.com/mexiaosqwq/dsh-web-mobile) (npm: `@dsh-external/dsh-mobile-nav`) — DSH web mobile adaptation: auto-collapses the sidebar on narrow screens, opens TOC as a drawer. A lot of this project's development and debugging was done by using it remotely from a phone / tablet. - [dsh-web-ui](https://github.com/zhu1090093659/dsh-web-ui) — A collection of DSH web UI skins. Learned many good practices from it; it is also the inspiration for DSH plugin development. - [dsh-routing-suite / dsh-router-standard](https://github.com/yjh051108/dsh-routing-suite) — Provides the Router Standard agent preset (task-aware reasoning-mode routing: spec / mixed / react) for selecting presets in a session. ## Development and architecture Requirements: Node ≥ 23.6 (tests run TS directly with native type stripping), pnpm ≥ 11. Build / contract / test / pack commands, directory layout, and host- & client-side coding conventions all live in [DEVELOPMENT.md](docs/DEVELOPMENT.md) (start at §0); contributing workflow in [CONTRIBUTING.md](CONTRIBUTING.md); issue workflow in [ISSUE-WORKFLOW.md](docs/ISSUE-WORKFLOW.md). Plugin capabilities, architecture, and runtime mechanisms (SVG architecture diagrams and Mermaid sequences) are covered in the [architecture documentation](docs/architecture/README.md) (in Chinese). Plugins were reviewed before being moved into this repository (self-contained build, privacy cleanup, security hardening, complete metadata). ## Contributing See [CONTRIBUTING.md](CONTRIBUTING.md): Conventional Commits, feature branch + PR workflow, pre-commit checks (sensitive info / artifact boundaries). ## License [MIT](LICENSE)