DeepSeek Harness Plugin Hub

发布与管理完整 Harness Profiles,发现适合你的插件。

探索

插件目录环境预设文档中心动态

社区

发布插件联系我们报告问题

相关链接

Plugin Hub GitHubDeepSeek Harness 官方项目系统状态隐私说明
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

独立、非官方社区项目,与 DeepSeek 官方无隶属、授权或背书关系。

Update Checker — DeepSeek Harness 插件(DSH Plugin)
DeepSeek Harness Plugin Hub
ProfilesPlugins分类动态文档登录管理 Profiles
ProfilesPlugins分类动态文档登录
← Plugins

dsh-update-checker

Update Checker

自动检查 DeepSeek Harness 和第三方插件更新,在 Web GUI 中发送通知,支持一键更新、备份/回滚和重启监控。

插件会安装到这里;不确定时保持 web。

npx -y @deepseek-ai/dsh plugin --profile web add dsh-update-checker@1.5.0
README兼容性版本

兼容性与来源证明

Update Checker 以 dsh-update-checker 发布,当前版本为 1.5.0。Plugin Hub 会校验它的 manifest,并保存精确安装来源,便于复现安装结果。

DSH 兼容范围
*
运行环境
web
发布来源
npm
Registry 更新时间
2026/9/20

版本

1.5.0stable
2026/9/17
1.4.23stable
2026/9/16
1.4.22stable
2026/9/9
查看其余 35 个版本收起版本
1.4.21stable
2026/9/4
1.4.20stable
2026/9/3
1.4.19stable
2026/9/1
1.4.18stable
2026/9/1
1.4.16stable
2026/8/25
1.4.15stable
2026/8/22
1.4.14stable
2026/8/21
1.4.13stable
2026/8/21
1.4.12stable
2026/8/21
1.4.11stable
2026/8/21
1.4.10stable
2026/8/21
1.4.9stable
2026/8/20
1.4.8stable
2026/8/19
1.4.7stable
2026/8/19
1.4.6stable
2026/8/19
1.4.5stable
2026/8/19
1.4.4stable
2026/8/19
1.4.3stable
2026/8/18
1.4.1stable
2026/8/18

相关插件

正在加载相关插件…

最新版
1.5.0
DSH
*
HMR
重启进程
Tree shaking
未声明可安全裁剪
解包体积
440.3 kB
文件数
44
Surface
web
许可证
MIT
发布源
npm
GitHub
★ 17
周下载
1,417
安全扫描
✓ v1.5.0 扫描通过
最近提交
2026/9/17
查看源码 ↗项目主页 ↗
README Badge

点击下方 Badge 复制 Markdown,粘贴到 README 即可。

这是你的 Plugin?认领权益 · 优先安全扫描

验证 package.json 声明的 GitHub 仓库,即可管理这个公开页面。认领后,Hub 会优先安排当前版本的安全扫描,并在通过后公开展示结果。

认领这个 Plugin →
报告问题
1.4.0
stable
2026/8/17
1.3.2stable
2026/8/15
1.3.1stable
2026/8/15
1.3.0stable
2026/8/15
1.2.3stable
2026/8/15
1.2.2stable
2026/8/15
1.2.1stable
2026/8/15
1.2.0stable
2026/8/15
1.1.2stable
2026/8/15
1.1.1stable
2026/8/15
1.1.0stable
2026/8/15
1.0.4stable
2026/8/15
1.0.3stable
2026/8/15
1.0.2stable
2026/8/15
1.0.1stable
2026/8/15
1.0.0stable
2026/8/15

相关插件

继续浏览 developer-tools 分类下经过校验的插件。

Web App@deepseek-ai/dsh-web-appdsh 浏览器界面捆绑包:位于 dsh-base 之上的 Web 补丁层,加上运行时粘合插件(提供前端 dist、Web 界面提示符、bash 运行时变量和 URL 行)Sdk Minimal@deepseek-ai/dsh-sdk-minimal独立的最小 SDK 配置包:JSON-RPC、一个 DeepSeek 适配器、持久化 Shell 和 JSONL 会话Sdk App@deepseek-ai/dsh-sdk-appdsh SDK 配置包:基于 dsh-base 提供 stdio JSON-RPC 服务和进程生命周期管理Subagent Codex@deepseek-ai/dsh-subagent-codex基于官方 app-server 协议的一次性 Codex 子代理提供程序

README

dsh-update-checker

English | 中文

A permanent Cordis plugin for the DeepSeek Harness Web GUI that auto-checks for new DeepSeek Harness releases and installed third-party plugin updates (the former standalone dsh-plugin-checker was merged in v1.1.0), asks the user, and one-click updates with success/failure feedback.

Features

  • Full update lifecycle — check, backup, update, rollback, and restart, all in one plugin.
  • Main program check — compares the installed @deepseek-ai/dsh against the npm latest (full packument, stable-first, semver-aware). A pre-release target is installed only when it belongs to the channel the deployment already follows — a cross-channel promotion (rc → alpha) is refused with E_PRERELEASE unless you enable the allowPrerelease setting, so the checker never promotes the harness into an unintended pre-release channel.
  • Third-party plugin check — scans installed non-official plugins (layout-agnostic, incl. pnpm-hoisted node_modules), cross-compares each against npm + GitHub (target = higher version); local tools with no publish source go to ignored. When a plugin name has multiple copies, the one in the composition-owning profile's node_modules wins (the rest are listed as copies), and each plugin can be excluded from prompts (excludedPlugins, re-enableable in the settings page).
  • Working GitHub channel — dedicated HTTPS client for GitHub domains (tolerates self-signed local proxies; the npm registry still uses strict TLS), with redirects, size caps and timeouts; codeload tarballs are validated before install.
  • In-GUI banner — locale-aware (zh/en follows the DSH UI language), states update / up-to-date / failure, with a suppression flag and a change brief (vX→vY + risk level + release notes when available).
  • One-click update with safety — main program: dry-run guard (abort if the plan contains remove) → snapshot backup (version manifests + a main-snapshot copy of the @deepseek-ai tree for offline rollback) → layout-adaptive install (in-place or -g) → post-install check installed==latest; plugins: temp-dir install + copy, dependency version reconciliation, auto --allow-scripts for native deps on npm ≥ 12. Updates (and rollbacks) persist to the profile package.json + lockfile (pnpm install --lockfile-only / npm install --package-lock-only), so a later install never silently reverts the plugin — no more "same plugin keeps asking for the same update" loops.
  • Real rollback — main program via POST /rollback, plugins via POST /plugin-rollback; GET /backups.json lists both.
  • Restart with watchdog — launcher derived from the current process argv, kill by PID + port, recovery confirmed by port listening, an HTTP 200 probe (GET /restart-status.json) and a new instance id read back from this plugin's own routes, so "something answers on the port" is no longer mistaken for "the updated build came up".
  • Write-route security — all write routes require { "confirm": true } and a loopback source (127.0.0.1/::1), so LAN clients can't trigger update/restart/rollback.
  • Zero-config portability — profile dir / composition file / deploy root are derived from the plugin's own install location, while state, backups and logs honour DSH_HOME (then ~/.dsh); works on any machine without editing code.

Host & Client

  • Host (lib/index.js) — HTTP routes: status.json (check), suppress, update (with dry preview), rollback, backups.json, restart, restart-status.json, plugins.json, plugin-update, plugin-rollback, plugin-exclude.
  • Client (lib/client.js) — renders two banners in the root shell.overlay slot: a core banner (main-program update state) and a plugin banner (updatable plugins with single / update-all buttons). Both check on page load, then every 6 hours; the settings page ("检查更新") adds rollback buttons.

Install & mount

The package is a profile bundle (its manifest declares dsh.bundle.patch).

# 1) put the package into $DSH_HOME/profiles/node_modules/ so the profile can resolve it.
#    ⚠️ Never run `npm install` directly inside $DSH_HOME/profiles — it has no
#    package.json and npm would prune the whole node_modules (data loss).
#    Safe option A — install in a temp dir, then copy only this package:
npm i dsh-update-checker --prefix <temp-dir> --no-save
cp -r <temp-dir>/node_modules/dsh-update-checker $DSH_HOME/profiles/node_modules/
#    Safe option B — copy the package directory manually (git clone or tarball).

# 2) add the row to $DSH_HOME/profiles/web/cordis.patch.yml
# $DSH_HOME/profiles/web/cordis.patch.yml
- insert:
    - id: dsh-update-checker
      name: 'dsh-update-checker'

Then let patch HMR apply it (or restart dsh web) and reload the page.

Step-by-step guide with troubleshooting (中文): docs/INSTALL.md.

Configuration & portability

All paths are auto-detected at runtime — nothing is hardcoded:

  • Plugin / profile dir — derived from the plugin's own install location (import.meta.url).
  • $DSH_HOME — the parent of the profiles root (state, backups, restart log live there).
  • Composition file — defaults to $DSH_HOME/profiles/web/cordis.patch.yml.
  • Deployment root — junction realpath first, then DSH_DEPLOY_ROOT, then process.cwd(), then the npm global prefix (parent of npm root -g's output; v1.4.9+ covers npm -g installs).
    • systemd / npm -g escape hatch: if auto-detection ever misses your setup, set DSH_DEPLOY_ROOT to the directory that contains node_modules/@deepseek-ai/dsh (e.g. <npm prefix>/lib on Linux).
  • Node / npm executables — resolveNodeExe() finds the real Node: DSH_UC_NODE_EXE override → npm_node_execpath → process.execPath when it is Node → common install dirs → PATH. This is what makes DSH Desktop (Electron, where process.execPath is electron.exe) able to run npm for plugin updates. If your Desktop build bundles Node elsewhere, set DSH_UC_NODE_EXE to it. If your Node is managed by mise / asdf / nvm and your PATH only exposes the version-manager shim (e.g. ~/.local/share/mise/shims/node), the shim directory has no npm beside it; v1.4.22+ resolves the real binary by running node -p process.execPath through the shim. If that still fails (or you want to skip the lookup), set DSH_UC_NODE_EXE to the real binary, e.g. mise which node / asdf which node.
  • Restart launcher — self-adapting: probes common launcher names under the deployment root; the web port is read from the running webServer.port.
  • Tuning env vars — DSH_UC_UPDATE_PORT sets the port the update worker stops/starts/probes (default 3080), and DSH_UC_RESTART_WINDOW_MS sets how long the worker keeps observing a slow first start before giving up (default 150000; the progress record streams the whole time).

Platform & install-layout support

  • Detection (checks) — layout-agnostic, works on any machine.
  • One-click update & restart — tuned for the layout they were developed on:
    • Windows only — the restart flow spawns PowerShell.
    • Main-program update adapts: in-place npm install when the deploy root has a package.json, npm install -g otherwise; both run the dry-run guard and re-read the installed version afterwards.
    • Plugin updates — temp-dir install + copy, npm 11/12+ compatible.
  • Other platforms/layouts: banners and version checks still work. On Linux/macOS the main-framework update route now refuses immediately with 501 E_PLATFORM_UNSUPPORTED (install/restart there still need code adaptation) instead of hanging at 8% and leaving a stuck banner; plugin updates and rollback work. Full POSIX support is the natural next step.

Notes

  • Host code changes require a service restart (the loader caches imported modules); client changes are picked up by HMR and apply on the next page refresh.
  • Update/rollback/restart/suppress/settings routes are guarded by { "confirm": true } and a loopback-source check (127.0.0.1/::1).
  • Before npm install, a backup (deployment package.json + package-lock.json + both @deepseek-ai version manifests + backup-meta.json + a main-snapshot copy of the @deepseek-ai framework tree) is written to $DSH_HOME/dsh-update-checker-backups/<timestamp>/; both main-program and plugin rollback routes are provided, and main-program rollback restores from the main-snapshot when present instead of re-installing from the registry.

Changelog

  • v1.5.0 — syncProfilesToDeploy links instead of copying (fixes the crash that followed a main-program update):

    • Root cause: the function's name and its junctionSkipped log field promised linking, but the write path never created a link — it called cp(src, dst, { recursive: true, force: true }). Entries already present and resolving to the same real path were skipped (228 of 236 on a real host), while packages not yet present in the profile — the 8 new ones a 0.1.6-alpha.1 update brings — were copied as real directories into $DSH_HOME/profiles/node_modules/@deepseek-ai/.
    • Why that is fatal: dsh's healProfilesModuleFallback/ensureSymlink only takes over symbolic links or dsh-managed module proxies. A real directory makes it throw dsh: <path> exists and is not a symlink or dsh-managed module proxy; remove it so dsh can manage the installation fallback during composeProfile — before the web server binds — so the next launch dies outright, while the update itself reported success (main-profile-sync total:236 junctionSkipped:228 failed:[]).
    • Fix: the write path is now mkdir + symlink(src, dst, process.platform === "win32" ? "junction" : "dir"), so the profile keeps pointing at the single deployed copy — exactly what healProfilesModuleFallback expects.
    • Self-healing: a destination that exists but is not the deploy copy is reclaimed safely — a symbolic link (including a dangling one) is rebuilt, and a real directory is replaced only after its package.json name matches the deploy package. Anything else is left untouched and reported as a failure (refusing to replace) instead of being overwritten, which also closes a second, previously unreported hazard: fs.cp(..., { force: true }) does not reject a same-named directory from another source — it overwrites that package's files and leaves the rest behind, silently gutting it.
    • Regression test: scripts/integration-sync-profiles.test.mjs extracts syncProfilesToDeploy from the real worker source (so the test cannot drift from the implementation) and covers six scenarios — a new package becomes a link, a leftover real copy is reclaimed, a same-named foreign directory is never deleted, a dangling link is rebuilt, non-dsh packages are ignored, and an unreadable deploy tree exits safely. The suite fails 4/6 against the 1.4.23 worker and passes 6/6 against this one.

Development

  • lib/index.js — Host half: plain ESM, Node built-ins only, no build step; pure helpers exported as named ESM exports for unit testing.
  • lib/client.js — Client half: plain JS (window.__ModuleLoader__), requires only react, no build step.
  • Tests: npm test (Node ≥ 20 built-in test runner, no third-party deps).
  • scripts/restart-service.ps1 — manual restart helper (run with -ExecutionPolicy Bypass).

License

MIT

  • The post-install health check now proves a new dsh process is serving: it used to accept any answer on the port — GET / → 200 swept assets, while 401/403/407 were declared success outright — so a build that died in composeProfile (no server at all) was still reported as a successful update. The host now hands its own instanceId to the worker, which reads the id back from this plugin's own routes (update-progress.json, then status.json; both answer without a browser session): a different id means the updated build really came up, the same id means the instance from before the restart is still the one answering and the update is reported as failed. When the probe cannot decide — this plugin not composed, a route not answering yet, or an older host that passed no id — the previous behaviour is kept rather than failing a healthy update.
  • The prerelease gate is channel-aware, instead of asking whether a stable version exists: the old test was isPrerelease(target) && !allowPrerelease && hasStable, and hasStable meant "npm holds some non-prerelease version". Every published @deepseek-ai/dsh is an rc/alpha, so hasStable was always false and the gate never fired: an allowPrerelease: false deployment was promoted rc → alpha anyway. The gate now compares release channels (alpha/beta/rc/stable) — a same-channel upgrade stays allowed, a cross-channel promotion is refused with E_PRERELEASE and a message naming the allowPrerelease setting, and missing data fails open.
  • State, backups and logs follow DSH_HOME: the home was derived only from where this package happens to sit, so an install outside a …/profiles/node_modules tree wrote its state next to the program files. A layout that really is a Harness home still wins (which keeps DSH_UC_PROFILE_NODE_MODULES overrides and the test suite's isolation working); anything else falls back to DSH_HOME, then ~/.dsh.
  • Recovery for machines already hit by this bug: move (do not delete) the real directories under $DSH_HOME/profiles/node_modules/@deepseek-ai/; the next dsh launch rebuilds them as junctions automatically.
  • v1.4.23 — Live main-program progress, stale-update recovery, safe plugin replacement (issues #17 #18 #20 #21 #25, PRs #23 #24):

    • Real progress during the dependency-tree check (#18 + the "6% → 64%" report): the download phase used to sit at 4–6% for the whole npm install --dry-run (minutes) and then jump straight to 64%. Every phase now runs a monotonic creep ticker that rewrites the progress record once per second (phaseCreepPercent, exported and unit-tested), and real npm/tarball counts only push the floor forward. The milestones were rescaled (download 10→55, stop 58, install 62→78, verify 84→87, sync-decl 88, restart 92→95, health 96, restart-pending 97–98, done 100) so no phase teleports. The 30-second service start and the restart watch also stream progress while they block.
    • Restart is observed instead of reported as failure (#18): after install + integrity + declaration sync succeed, a failed restart no longer ends the update. The worker enters restart-pending, keeps streaming progress, re-probes the port and re-spawns the launcher for up to DSH_UC_RESTART_WINDOW_MS (default 150000 ms), and only then fails with E_RESTART — with installed, restartPending: true and text stating the install itself succeeded. A later port appearing becomes a normal success.
    • Progress counters fixed (#18): the install phase no longer divides npm's http-line counter by a hardcoded 587; the total now comes from the real lockfile (countLockPackages, null when unknown) and done is clamped to it, so done > total cannot be displayed. The banner also states that closing the page does not interrupt the update.
    • An auth-gated frontend is no longer mistaken for a broken service (#18, real-world): the health check required GET / to return 200, so on a host whose / answers 401/403 (a password/token-gated UI) every successful install ended as E_RESTART: update installed <version> but restart/health failed: GET / -> 401, while the crash-recovery started the service right after — the user was told the update failed when it had actually succeeded. Health classification is now a pure exported helper (classifyHealthStatus): 200 → full dist/asset verification; 401/403/407 → the service is up but the frontend is auth-gated, so the update succeeds and the asset sweep is skipped (recorded as main-update-health-auth-gated); timeouts, 5xx and other 4xx still fail. The E_RESTART text now quotes both the launcher error and the health problems.
    • Stale progress/state reconciliation (#25): writeProgress no longer let the cached record overwrite the at timestamp — it froze at the first write, which is exactly why a killed update could look "fresh" or a live one look stale. Progress records now carry the owning workerPid/hostPid; isStaleProgress treats a record as stale when its owner process is gone (or, without pids, after 10 minutes without an update), and at startup / on read the host rewrites it to running:false, phase:error, code:E_INTERRUPTED and releases the update lock. A stale lock no longer blocks a new update for 10 minutes: locks older than the 2-minute spawn grace are dropped when no live worker owns them.
    • A crashed worker can no longer leave running:true (#25): uncaughtException/unhandledRejection and a fatal main() rejection write an error progress record and release the lock; previously the process simply died. startService/taskkill spawns got error handlers (a POSIX ENOENT or a batch-file EINVAL used to become an unhandled error event that killed the worker mid-update), and a failed launch fails fast instead of waiting 30 seconds.
    • Plugin replacement is now stage-then-swap (#21): backupAndReplace copies the new content into .dsh-uc-staging-* next to the target, renames the old directory to .dsh-uc-trash-*, renames the staged tree into place, and only then best-effort deletes the trash. Deleting a directory that contains a native module currently mapped by the running host used to raise EPERM after the delete-then-copy had already removed everything, leaving the package gutted (a locked .node file and nothing else, package.json included) and breaking the host. Any failure before the swap now leaves the installed package untouched, and a locked trash directory is simply swept on the next update. The two "stop reminding" buttons also stopped writing each other's flag.
    • Transient request failures no longer reload the page (#20): the client's 1.5-second status probe treated any single failed fetch (LLM streaming, tool work, a proxy hiccup) as "the service restarted" and called location.reload() unconditionally, refreshing the page mid-conversation. Reloading is now driven by a server instanceId: the page reloads only when the reported instance actually changes, at most once per instance (sessionStorage guard), so transient failures are ignored entirely.
    • Locale-service race fixed (#22/#23): the client half waits for the locale service (ctx.inject(["slots", "locale"])) before registering dictionaries and slot bindings, instead of reading ctx.get("locale") at apply time and silently binding fallbackT() (the Chinese dictionary) on an English UI.
    • POSIX core updates fail fast (#24): the main-framework /update route returns 501 E_PLATFORM_UNSUPPORTED immediately on Linux/macOS — before lock creation, backup or the Windows-only PowerShell spawn — instead of hanging at 8% with a stuck banner. Full POSIX support remains open (upstream PR #19).
  • v1.4.22 — Node version-manager shim resolution (issue #17):

    • resolveNodeExe() resolves a version-manager shim (mise/asdf/nvm) to the real Node binary by running node -p process.execPath through it, and getNpmCli() no longer falls back to a path that cannot exist — it throws ENPMCLI naming DSH_UC_NODE_EXE instead of producing MODULE_NOT_FOUND at npm time.