DSH Plugins Marketplace

DSH Plugins

Plugins

/

Development & Infrastructure

/

dsh-upgrade-guard

w

dsh-upgrade-guard

Manifest valid★ 2

DSH 升级守卫:升级前兼容盘点 / 升级后契约扫描 / 启动冒烟(DeepSeek Harness 插件)

UI (client)hasBundlePatch

dsh-upgrade-guard · upgrade safety net for DeepSeek Harness

升级前盘点插件兼容性 → 升级后扫描已知破坏性契约 → 切换端口前先启动冒烟,不通过就别切。 中文文档:README.zh.md

Stop "upgrading DeepSeek Harness" from turning into "one upgrade, one broken plugin".

DeepSeek Harness (dsh) ships fast, and every release can change a contract that plugins depend on. The same class of failure keeps recurring:

UpgradeRoot causeSymptom
0.1.1 → 0.1.2client-modules module table got strictpage shows Failed to load plugins
0.1.2 → 0.1.5service access contract got strict (missing inject throws)31 plugins pending in a chain
0.1.6 → 0.1.7service settingsScope removed/renamed26 plugins pending
0.1.7-alpha.1ui-primitives icon renamed (IconXxx14 → IconXxxRegular, no alias)Minified React error #130
0.1.7session message v4 source contracta run fails after finishing: format v4 message requires a producer-owned source kind

This plugin turns the diagnosis of each such incident into a reusable check.

Three actions

ActionWhenWhat it does
Contract scan (offline, seconds)anytime / after upgradingscans installed plugins against a catalogue of known-breaking contracts: removed service names, old session-message source shape, references to ui-primitives exports that do not exist
Preflight (online, 10–40 s)before upgradingfor each plugin: declared compatibility range, newest version on npm, whether it supports the target → "can we upgrade + what must move with it + what to disable"
Boot smoke (30–90 s)before switching portsboots a throwaway host on a test port, reads its boot summary (SKIPPED / DEGRADED / PENDING / real culprit), probes each client bundle for reachability, kills the test host afterwards

Compatibility (why it works on both web and desktop)

Designed to keep working across 0.1.x and 0.2.x, and on both the web profile and the official desktop app:

  • Zero @deepseek-ai/* imports. The host half imports only Node builtins plus the webServer service. The largest historical failure class is "host changed a package/service contract while the plugin still imported the old thing", so this plugin imports none.
  • No hardcoded machine paths. The profile is found by walking up from the plugin's own location; the host binary/install root is derived from process.argv[1]; ui-primitives is searched through several candidates. The same files run unchanged in profiles/web and profiles/desktop.
  • peerDependencies declared as *, all optional. dsh 0.1.7+ ships a peer-compatibility gate that silently skips bundles declaring a narrow range (e.g. browser-skill-dsh-plugin@0.3.1 requires @deepseek-ai/dsh-tools: ^0.1.5-rc.3 and gets skipped on 0.2.0-rc.2). A * + optional declaration is the declaration shape that survives that gate.
  • Client half follows the 0.1.2+ client contract. exports.inject = ['slots'] is declared, and slots are reached via ctx.slots with a ctx.get('slots') fallback, so both the older proxy and the newer restricted proxy work. It only requires react (a platform seed word), so the tightened module table cannot hit it.
  • Electron aware. On the desktop app process.execPath is the app binary; smoke spawns with ELECTRON_RUN_AS_NODE=1 so no second app window appears. Inside a packaged app.asar runtime smoke reports UNSUPPORTED (with alternatives) instead of failing mysteriously.
  • Honest about the export table. When the ui-primitives copy found on disk differs from the running host version, the UI says so, because "export does not exist" conclusions are only as good as that copy.

Install

# ① from GitHub (installed into the profile)
cd $env:USERPROFILE\.dsh\profiles\web
pnpm add github:wqx11235/dsh-upgrade-guard
# then add "dsh-upgrade-guard" to dsh.profile.bundles in that profile's package.json

# ② manual placement (no network)
#   copy this repo to %USERPROFILE%\.dsh\profiles\web\node_modules\dsh-upgrade-guard
#   and add "dsh-upgrade-guard" to dsh.profile.bundles

# ③ desktop app: same, but use %USERPROFILE%\.dsh\profiles\desktop

Restart the host, hard-refresh the page, then open 设置 → 通用 → 升级守卫.

Usage

In the UI

Settings → General → Upgrade guard — three buttons plus a footer that tells you which host/runtime/primitives the result came from:

  • Contract scan → ⚠ critical N / warn N (scanned M plugins) + findings
  • Preflight → 📋 target x.y.z: N plugins, K have updates + the list
  • Boot smoke → ✅ PASS / ❌ FAIL + key output lines (ROOT? / PENDING / SKIPPED / DEGRADED / BADBUNDLE)

Command line (same engine)

node lib/guard.mjs scan      --json --report scan.md [--profile <dir>] [--primitives <dir>]
node lib/guard.mjs preflight --json --report preflight.md --target 0.1.8-rc.1 [--no-network]
node lib/guard.mjs smoke     --bin <.../dsh/lib/bin.js> --cwd <dir> --port 3099 --timeout 120 [--keep]

Environment fallbacks: DSH_HOME (default ~/.dsh), DSH_PROFILE, DSH_PRIMITIVES, DSH_SMOKE_BIN, DSH_SMOKE_PORT, DSH_SMOKE_CWD, DSH_SMOKE_TIMEOUT, DSH_SMOKE_KEEP=1.

Console output is deliberately English/ASCII (Windows cmd at code page 936 garbles UTF-8 Chinese); the Chinese report goes to the --report file (default $DSH_HOME/upgrade-guard/).

Where the judgement comes from

KNOWN_RULES in lib/guard.mjs is the catalogue of known-breaking contracts:

  1. removed-service — services the host removed or renamed (settingsScope, conversationEvents, …). Hard references are critical; optional inject([...]) uses are warn (the plugin degrades gracefully), and matches inside comments are skipped to avoid false positives.
  2. session-source-v4 — the old session-message source: { kind: 'plugin', plugin: 'x' } shape (rejected since 0.1.7).
  3. missing-host-export — client code referencing a member absent from the host's ui-primitives export table (e.g. the IconXxx14/16 rename). It only throws React #130 at render time, so this is a static early warning.
  4. pinned-exact — a plugin pinned to an exact version in the profile ("x": "1.2.3"), so it can never follow the host (real case: a plugin pinned and stuck 19 versions behind).

Every new incident adds one rule — that is the only way this plugin grows, and the reason it gets sharper over time.

Limits (read these)

  • Smoke only covers boot time: plugin tree loading, service dependencies, client bundle reachability. Render-time errors (e.g. the primitives rename causing React #130) will not show up; the contract scan is what covers those.
  • Contract scan only covers the known catalogue. A brand-new kind of breakage it has never seen stays invisible.
  • Preflight needs npm registry access. Plugins installed from git/url sources cannot be checked for a newer version and are flagged for manual review.
  • A plugin skipped by the host's peer gate is not a crash — the host is protecting you. Smoke lists it as SKIPPED; reinstalling requires an explicit dsh plugin allow-version exemption.
  • Smoke is unavailable in a packaged desktop runtime (the entry lives inside app.asar).

Host route

POST /api/dsh-upgrade-guard

{ "action": "status" }                      // → { ok, paths: {...}, host: { version, runtime, primitivesSource, ... } }
{ "action": "scan" }                        // → { ok, result: { criticalCount, warnCount, scanned, topFindings, reportPath } }
{ "action": "preflight", "target": "latest"} // → { ok, result: { target, rows, stale, reportPath } }
{ "action": "smoke", "port": 3099 }         // → { ok, result: { verdict, summary, tail, reportPath } }

Layout

package.json          dsh.bundle.patch + dsh.client declarations
dsh.plugin.json       plugin manifest (name / entry / client)
cordis.patch.yml      the `insert` line that mounts the plugin
lib/index.js          host half: profile+host probing, webServer route, spawns the engine
lib/client.js         client half: the Settings → General row
lib/guard.mjs         the engine: scan / preflight / smoke (also usable as a plain CLI)

License

MIT © 2026 wqx11235

Versions

Latest versionPublishedSize
0.2.0——

Comments

Loading…

From the same category

awesome-dsh-plugin

by awesome-dsh-plugin

A curated list of plugins for DeepSeek Harness (dsh) · DeepSeek Harness 插件精选列表

Development & Infrastructure

★ 19.2k

CC0-1.0

Python

Oct 17, 2026

Index only — not installable

by 0xsline

DeepSeek Harness (DSH) ecosystem: curated plugins, tools, and infrastructure from dsh-external/hub and the public dsh-plugin topic.

Development & Infrastructure

★ 1.2k

CC0-1.0

Python

Oct 16, 2026

Index only — not installable

by pax-beehive

Open-source CLI, schemas, resolver, and DSH agent tools for DSH Plugin Hub

Development & Infrastructure

★ 391

MIT

TypeScript

Oct 6, 2026

Index only — not installable

by xiajiajun516

DeepSeek Harness (DSH) backup & restore plugin — export, import, migrate and sync your complete DSH configuration, plugins, MCP servers, skills and workspace. One-click migration to another machine.

Development & InfrastructureManifest valid

★ 201

MIT

TypeScript

Oct 17, 2026

dsh plugin --profile web add dsh-config-manager

by yjh051108

推荐组件(非必须):DeepSeek Harness 运行时注入器;已随 dsh-routing-suite 单仓库化保留,本仓库继续维护/发布。

Development & InfrastructureManifest valid

★ 167

TypeScript

Oct 16, 2026

dsh plugin --profile web add @dsh-external/dsh-super-injector

by jigjoy-ai

A CLI that turns a goal into a pull request - and a sandbox for testing concurrent AI coding agents on the Mozaik runtime.

Development & Infrastructure

★ 124

MIT

TypeScript

Oct 13, 2026

Index only — not installable