packages/dsh-task-board
zhu1090093659/dsh-web侧边栏多列任务看板:卡片交给真实 DSH 智能体会话执行,支持 cron 定时(Host 侧到点执行,关浏览器也生效)。
在侧栏底部添加两个按钮:一个只重新加载界面与客户端插件,另一个连同 Host 重启整个桌面应用;插件安装期间拒绝重启。重启仅支持 Windows,其他平台返回 409;刷新全平台可用。
English | 中文
Two buttons in the sidebar foot of the DeepSeek Harness desktop app: reload the interface, or restart the entire application (app + Host).
The production desktop shell ships no *Reload Page* menu item and no built-in accelerator for it, and it exposes no way to relaunch itself — app.relaunch() lives in the Electron main process and is wired only to crash recovery. This plugin adds both, as ordinary sidebar actions.
[⟲ 刷新界面] [↻ 重启应用]Button · What it does Reload UI · location.reload(). Reloads the page and every client plugin; the Host keeps running and turns in flight are not interrupted. Restart app · Asks the Host to end every process of the application binary and start it again from the same path. Second click to confirm; the label turns red when Agent turns are running.
0.2.1-rc.2 or newer (declared in engines.dsh; tested on 0.2.1-rc.3), Node >=20.index.js imports only Node built-ins; client.js imports react, provided by the shell.From npm:
pnpm add @moonsand/dsh-desktop-restartFrom a local checkout, while developing:
# "dependencies": { "@moonsand/dsh-desktop-restart": "link:D:/path/to/dsh-desktop-restart" }
pnpm installEither way, the package must also be registered as a bundle — that entry is what actually loads it:
"dsh": { "profile": { "bundles": [ ..., "@moonsand/dsh-desktop-restart" ] } }A package that is installed but absent from `dsh.profile.bundles` silently does nothing: it produces no error and no button. Add the bundle entry, then restart the app.
The package ships its own cordis.patch.yml, which inserts the Host-side service, so no edit to the profile patch layer is needed.
market/index.json in this repository is a format 1 plugin market index, validated by DSH's own @deepseek-ai/dsh-plugin-market-index. To see this plugin in the desktop app's Plugins → Discover tab:
https://raw.githubusercontent.com/MoonSand/dsh-desktop-restart/main/market/index.json (GitHub Pages works too).http: / https: only, without credentials or a fragment.description as an { "en": …, "zh": … } object and must contain `en`; a Chinese-only value is rejected by the validator. Installing uses the exact npm version.Every version entry carries engines.dsh matching package.json; the Discover tab derives compatibility and the default version from it, and disables Install when no version is compatible. When publishing a new version, append a versions entry with version, the real publish time as Unix seconds in publishTimestamp, and source.type: "npm".
Three platform facts shape the design, all measured on a real machine:
powershell.exe starts but never runs its -EncodedCommand script — silently, with no error. The helper is spawned as a plain child instead.So the order is inverted:
Client click
-> POST /desktop-restart/restart
-> Host writes watchdog.ps1 + launch.vbs, spawns a helper (powershell -EncodedCommand, not detached)
-> helper creates a one-shot scheduled task: wscript.exe launch.vbs (GUI subsystem, no console)
-> launch.vbs starts watchdog.ps1 hidden (window style 0)
-> helper polls a marker file (<= 5 s) to prove the watchdog is alive
-> without that proof it aborts and kills nothing
-> helper exits — it lives inside the job and must not touch the kill
-> watchdog (outside the job): sleep 1.2 s -> kill every process of the executable
-> wait for all to disappear -> sleep 0.6 s -> Start-Process the same path
-> verify it came back (up to 3 attempts, 6 s apart) -> append to the logRoute · Purpose GET /desktop-restart/status · { desktop, restarting, activeAgents, logPath } POST /desktop-restart/restart · Needs header x-dsh-desktop-restart: 1 (or the desktop proxy shape: loopback peer, no Host/Origin header) POST /desktop-restart/diagnose · Arms a watchdog in probe mode and reports { armed, method }. Kills nothing — use it to check the chain without restarting.
File · Role index.js · Host half: routes, helper/watchdog generation, arming, kill/relaunch mode client.js · Client half: the two sidebar actions, styles, zh/en dictionaries, confirm state machine cordis.patch.yml · Inserts the Host service into the profile package.json · Declares both halves (dsh.bundle.patch + dsh.client) locale/*.json · Plugin page name and description icon.svg · Sidebar icon
Because the package declares a Host half, Host changes need an app restart; client-half changes only need a page reload.
TerminateProcess). The turn in flight is interrupted. Session history and anything already written to disk are unaffected.409 installing). Three signals are checked: the plugin manager's own plugin-manager/install-state reports (installing / cancelling / applying) — authoritative, but it never reports completion, so a phase expires after ten minutes; a manifest written within the last 10 seconds, which catches the moment an install *finishes*, since the lockfile is written last; and, as a fallback, a live node process whose command line mentions pnpm. The 10-second window is kept short on purpose: a finished install should not block a restart for longer than it takes to notice. All three are best-effort and fail open.dsh web Host the route answers 409 not-desktop and the button falls back to reloading the page.(direct powershell).tasklist.exe is *not* used for process detection: on a measured machine it answers Access denied (exit 1) in this context, which would make every poll report the app as gone and start several copies. Detection filters by image name first (Get-Process -Name) and then checks .Path.npm test # smoke: builders, install guard, both sidebar actions, PS 5.1 parse
node --check index.js
node --check client.jsThe three script builders are exported as pure functions, so they can be generated and handed to the Windows PowerShell parser without arming anything:
import { watchdogSource, watchdogLauncherSource, restartHelperScript } from '@moonsand/dsh-desktop-restart'Safe way to exercise the whole chain without touching a live app: generate a watchdog with a non-existent executable path, run it with powershell -File, and watch the log walk matched pids: -> application gone=True -> relaunch issued -> watchdog end.
Everything the helper and the watchdog do is appended to %TEMP%\dsh-desktop-restart.log. This is the first place to look when a restart misbehaves. The GET /status route reports the exact path.
MIT. See LICENSE.