YV3507/dsh-webui-launcher
项目介绍Project Overview
这是跨平台 DSH Web UI 启动插件,提供启动、停止、状态检查、打开浏览器,以及 /webui 命令、设置卡片和桌面快捷方式。适合在 harness 内管理本地 Web UI,无需桌面脚本。默认仅监听回环地址;无桌面环境会跳过快捷方式。
A cross-platform DSH plugin for launching the DeepSeek Harness Web UI. It starts, stops, checks, and opens the UI, adds /webui commands, a Settings card, and an optional desktop shortcut. Use it to manage the local Web UI from inside the harness without desktop scripts. It binds to loopback by default; headless hosts skip shortcut creation.
请帮我了解并安装插件:【dsh-webui-launcher】【https://github.com/YV3507/dsh-webui-launcher】
把上面这条消息直接发给当前会话里的 DSH,让它帮你了解并安装。安装命令不一定准确,发给 DSH 更稳。Send this message to DSH in your current session. CLI install commands may not be accurate across systems — DSH will figure it out for you.
或使用命令行安装(适合开发者)Or use CLI install (for developers)
命令行安装CLI Install
dsh plugin --profile web add github:YV3507/dsh-webui-launcher
把 YV3507/dsh-webui-launcher 加入你的 DSH 配置(web profile)即可启用。
READMEREADME
dsh-webui-launcher — cross-platform Web UI launcher for DeepSeek Harness
English | 中文
Start, stop, check and open the DeepSeek Harness Web UI from inside the harness — cross-platform (Windows / macOS / Linux), no desktop scripts needed.
Install
dsh plugin --profile web add github:YV3507/dsh-webui-launcher
or from a checkout:
cd dsh-webui-launcher
npm install && npm run build
dsh plugin --profile web add .
What it adds
- Model tools —
webui_start,webui_stop,webui_status,webui_open: start the Web UI (spawningdsh --profile webin the background), wait until it answers HTTP 200, report or stop it, open the default browser. - Slash command —
/webui start|stop|status|open. - Settings card — a "Web UI Launcher" card on the Settings page of the web GUI (browser half,
exports["./client"]), driving the same/webui/*JSON endpoints. - Desktop shortcut — on the first plugin start, a launcher shortcut is created on the desktop (
.lnkon Windows,.desktopon Linux,.commandon macOS) that starts the Web UI and opens the browser once ready. Headless hosts (no Desktop, no DISPLAY) skip creation silently; disable withdesktopShortcut: false. - dsh default icon — the shortcut uses the official dsh icon by default (the web-app favicon rasterized and bundled in
assets/;.icoon Windows,.pngon Linux), copied into the persistent state directory so a reinstall never orphans it. - Custom shortcut icon — upload any image (PNG/JPEG/BMP/GIF/TIFF) from the Settings card; it is converted automatically (multi-size
.icoon Windows,.pngon Linux) and the existing shortcut's icon is updated immediately. An explicitshortcutIconPathoverrides the default.
Configuration
| Option | Default | Meaning |
|---|---|---|
port |
3080 |
Web UI port. |
host |
127.0.0.1 |
Loopback host dsh web binds. |
cliBin |
"" |
Explicit dsh CLI script; empty reuses the running CLI. |
startupTimeoutMs |
120000 |
How long start waits for the surface to answer HTTP 200. |
openBrowserOnStart |
true |
Open the default browser once the Web UI is ready. |
desktopShortcut |
true |
Create the desktop launcher shortcut on the first plugin start. |
shortcutName |
"DeepSeek Harness Web UI" |
Display name of the desktop shortcut. |
shortcutIconPath |
"" |
Explicit icon image; empty uses the bundled dsh icon. |
Behavior and robustness
- Adopt-or-start — a server already listening on the port is adopted: never restarted, never stopped.
webui_stopkills the tree this plugin spawned, and also an adopted server whose PID the launcher (or an earlier instance) recorded — only when that PID is the one currently listening, and only for the process hosting this plugin, with the samenode.exeidentity guard before killing. A foreign server without a PID record is never touched. - Explicit state machine —
idle → starting → running → stopping, single-flight serialized: concurrentstart/stopcalls never interleave. - Orphan cleanup — when the plugin unloads or hot-reloads, any server it spawned is stopped (
ctx.effectdispose). - PID identity guard — before killing, the process is re-checked (alive, still our child, still
node.exevia tasklist on Windows) so a recycled PID is never touched. - Abort/timeout hygiene — an aborted or timed-out start kills the child it spawned and surfaces the output tail in the error.
- CLI location fallback — the running CLI (
process.argv[1]) → the@deepseek-ai/dshpackage → explicitcliBin; resolution failure throws an actionable error.
Development
npm run build # esbuild → lib/index.js (host) + lib/client.js (browser)
npm test # node --test, zero-dependency (mocks the two external packages)
The state-machine failure paths (child death, timeout, abort, sibling adoption, concurrency, dispose) are unit-tested against the built bundle with scripted fake dependencies — no real processes or timers.
Security
Loopback-only by default, no elevation, no external network. The plugin kills only the process tree it spawned — or a PID-recorded launcher server it hosts — after verifying the PID still belongs to that process.
License
MIT
nexu-io/open-design
freestylefly/awesome-gpt-image-2
anywhere-labs/dsh-desktop
walkinglabs/learn-harness-engineering
awesome-dsh-plugin/awesome-dsh-plugin
MemTensor/MemOS