dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
One-click restart for the DeepSeek Harness Web UI — restarts the whole dsh web process so freshly installed, updated, or reconfigured plugins and settings take effect immediately. The Edge/PWA window stays open and reconnects on its own.
中文说明见 README.zh.md。
DSH has no official "restart the process" API. The only official way to stop it is the graceful path behind ctx.appExit() (dispose the root fiber tree, close the listening socket, let Node exit normally — never process.exit(), which can trip a libuv assertion on Windows).
Restarting itself is the hard part: when DSH runs under a supervisor (e.g. Start-DSH-GUI.ps1), that supervisor puts the process into a Windows Job Object with JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE. Everything inside that job — including plain spawn({ detached: true }) children — dies with it. So the thing that brings DSH back must live outside the job:
Win32_Process.Create (its parent becomes WmiPrvSE.exe, so it escapes the job),sidebar.footer.action, next to Settings) plus a full page under Settings → Quick Restart.idle → checking → waiting-for-tasks → (confirming-force-restart) → preparing-helper → stopping → starting → waiting-for-ready → succeeded | failed.port-pid; process kills are verified by PID + creation time + port ownership (never "kill every node.exe").newInstance.pid === self) and reports "this instance was started by Quick Restart".The plugin installs as a profile bundle (the dsh.bundle.patch entry adds it to the profile's cordis.patch.yml):
// <DSH_HOME>/profiles/web/package.json
"dependencies": { "dsh-quick-restart": "link:D:/path/to/dsh-quick-restart" }
# <DSH_HOME>/profiles/web/cordis.patch.yml
- insert:
- id: dsh-quick-restart
name: dsh-quick-restart
Then restart DSH once manually (that is the bootstrapping problem this plugin solves afterwards). A page reload is enough for client-half changes — DSH re-hashes plugin bundles and serves the new revision.
| Field | Default | Meaning |
|---|---|---|
enabled | true | Show/enable the entry |
gracefulShutdownTimeoutMs | 30000 | How long to wait for running tasks (1000–3600000) |
startupTimeoutMs | 60000 | How long to wait for the service to come back (5000–1800000) |
reconnectEnabled | true | Read the real result back after reconnecting |
requireConfirmationWhenBusy | true | Ask before restarting while tasks run |
Values are clamped/validated; unlimited waits are rejected on purpose.
npm run typecheck # tsc --noEmit
npm run build # type stripping + copy client bundle & helper into lib/
npm test # 20 unit tests (state machine, locks, recipes, redaction, birth record)
npm run test:launch # helper launch regression (fake new instance, no real DSH)
npm run e2e # full restart against a throwaway instance
src/ is the single source of truth; lib/ is a committed build artifact (DSH loads lib/index.js, and git installs must work without a build step).
ctx.workflowEngine has no list() — workflows are only observable through events.$DSH_HOME/.credentials.yaml, not in the environment.Get-NetTCPConnection semantics).MIT