dsh
OpenPetsHQ/openpets将 DeepSeek Harness 的生命周期状态、错误与审批请求,桥接到本地运行的 OpenPets 桌面伙伴。
为运行在 WSL 的 DSH 提供 Windows 桌面快捷方式和系统托盘启动器:完全隐藏启动,托盘菜单支持打开/重启/退出,插件配置页可管理快捷方式。
中文 | English
A DeepSeek Harness plugin for WSL deployments: it puts a Windows desktop shortcut and a system-tray launcher in front of the DSH web server running inside WSL.
--no-open; only the tray opens it).watchdog.log (see Watchdog below).wscript.exe + VBS and
the entire chain is launched with window style 0.WSL_DISTRO_NAME set, /mnt/c
accessible).wscript.exe, powershell.exe, and wsl.exe.Once published to npm:
dsh plugin --profile web add dsh-wsl-tray
Or add it manually to a DSH web profile:
cd ~/.dsh/profiles/web
pnpm add dsh-wsl-tray
and add "dsh-wsl-tray" to package.json:
"dsh": {
"profile": {
"bundles": [
"@deepseek-ai/dsh-base",
"@deepseek-ai/dsh-web-app",
"dsh-wsl-tray"
]
}
}
Restart dsh web and open Settings → WSL Desktop & Tray (中文界面为
设置 → WSL 桌面与托盘).
The launcher never starts a checkout from src. A tsx/src host loads plugin
packages from lib (the default runtime resolution mode), so the same packages
end up twice in one process; symbols do not cross instances, and tool calls fail
with undefined state. start.sh therefore only ever launches a checkout's BUILD
OUTPUT:
cd ~/deepseek-harness
pnpm run build # required once, and again after every source change
Then set the checkout path in Settings → WSL Desktop & Tray (either the
repository root or its apps/cli directory works). With a path configured:
start.sh runs node <checkout>/apps/cli/lib/bin.js web --no-open before
anything else — never src, and never whichever dsh happens to be on
PATH.~/.dsh/dsh-wsl-tray/start.log and exits instead of silently running a
different install.DSH_WSL_TRAY_AUTO_BUILD=1 in WSL to let the launcher run
pnpm run build itself when the output is missing (a full build is slow, so
this stays opt-in).WARN ... newer than the build output line, so a forgotten rebuild does not
look like a change that did nothing.Known limitation: the freshness check only scans <checkout>/apps/cli/src; a
change under packages/ is not detected, so keep pnpm run build in the loop.
The plugin writes five generated files:
| File | Location |
|---|---|
dsh.ico | %USERPROFILE%\.dsh\dsh-wsl-tray\dsh.ico |
dsh-tray.ps1 | %USERPROFILE%\.dsh\dsh-wsl-tray\dsh-tray.ps1 |
dsh-tray.vbs | %USERPROFILE%\.dsh\dsh-wsl-tray\dsh-tray.vbs |
start.sh | ~/.dsh/dsh-wsl-tray/start.sh |
stop.sh | ~/.dsh/dsh-wsl-tray/stop.sh |
and creates:
%USERPROFILE%\Desktop\DeepSeek Harness.lnk
While the tray runs, the watchdog maintains two runtime files (both are shown on the settings page):
| File | Location |
|---|---|
watchdog.log | %USERPROFILE%\.dsh\dsh-wsl-tray\watchdog.log (rotated at 512 KB) |
watchdog-status.json | %USERPROFILE%\.dsh\dsh-wsl-tray\watchdog-status.json (latest tick) |
The shortcut points at wscript.exe, which runs dsh-tray.vbs; the VBS starts
the tray PowerShell hidden, and the tray starts start.sh inside WSL through
WScript.Shell.Run(..., 0, false).
The watchdog lives inside the tray helper (the one process that is deliberately independent of DSH), and answers the three questions a restart daemon has to:
Invoke-WebRequest probe of the DSH
web URL every probeIntervalSec (default 10 s, probe timeout 3 s). Each
probe records its status code or error text, so a refused connection
(nothing listening), a timeout (hung server) and a bad status stay
distinguishable in the log. DSH is only considered DOWN after
downThreshold (3) consecutive failed probes.wsl.exe) and the watchdog waits up to restartWaitSec (180 s) for the URL
to answer again: an answer = success, which resets the failure counter; an
unanswered window = one failed restart. After maxRestartFailures (3)
consecutive failures the watchdog pauses instead of looping forever. It
resumes from the tray menu (恢复守护进程), or automatically as soon as DSH
answers again.watchdog.log with a timestamp, level and the
probe detail; the current state machine snapshot goes to
watchdog-status.json every tick. The settings page exposes both through
/dsh-wsl-tray/watchdog and /dsh-wsl-tray/watchdog-log.Phases: starting (initial boot grace) → probing (steady state) →
restarting (waiting after a restart) → backoff (cooldown) or paused
(give-up / manual pause). The tuning values above are baked into
dsh-tray.ps1; change them in src/artifacts.ts
(DEFAULT_WATCHDOG_CONFIG) and regenerate.
If npm publishing is not an option, install the prebuilt tarball that is included in this repository:
cd ~/.dsh/profiles/web
pnpm add /path/to/dsh-wsl-tray-github/dist/dsh-wsl-tray-0.1.7.tgz
Then add "dsh-wsl-tray" to the profile bundle list as above.
wscript.exe → VBS → hidden PowerShell tray.start.sh runs DSH in the foreground of the hidden
wsl.exe session, so WSL does not recycle the process after the one-shot
launcher exits.Start-Process $webUrl once DSH answers.dsh-tray.ps1 -Regenerate.npm install
npm run typecheck
npm test
npm run build
npm pack --dry-run
stop.sh: a PID file
tracks the instance start.sh launched, then a pattern fallback covers
bin.js web launches from source checkouts, npm global installs and npx).
Add the shortcut to the Windows Startup folder if you want the watchdog to
follow Windows boot.wsl --shutdown) if the pattern fallback does not reach it.