
DSH Desktop
☆ 1Desktop shell for DeepSeek Harness Web GUI — auto-installs dsh, native macOS tray, packaged for macOS & Windows.
Get this plugin
Review the source, then continue to the publisher.
dsh plugin add dsh-desktop@latestAbout this plugin
Source snapshot 8/13/2026dsh-desktop
English | 中文
A desktop shell (Electron) for the DeepSeek Harness Web GUI (dsh web, served at 127.0.0.1:3080 by default).
Zero-config: clone it, run npm install && npm start — if dsh isn't installed, the app installs it for you.
Features
- 🚀 Zero-config startup — auto-locates or auto-installs
dsh(@deepseek-ai/dsh); no prerequisites beyond Node.js - 🖥️ Native desktop experience — standalone window + macOS menu-bar tray (hide-to-tray on close; show/hide/quit from the tray)
- 🔄 Smart server management — reuses an existing
dsh webinstance; spawns a resident server when none is running; keeps it alive after the app quits - 🐋 Official DeepSeek icon — app and tray icons use the official whale mark
- 📦 One-command packaging — electron-builder produces
.app/ dmg / zip for macOS and an NSIS installer + zip for Windows
How it works
npm start first runs scripts/ensure-dsh.js:
- Locate
dsh(resolveDshBin, in order):DSH_BINenv var →dshonPATH→~/.npm/_npx/*/node_modules/.bin/dsh→ common install locations → project-localvendor/dsh - No
dsh? Auto-install (ensureDshBin): runsnpm install --prefix vendor/dsh @deepseek-ai/dshinto the project — no global install, no dependence on the user'sPATH(first run takes ~1–2 min) - Probe
127.0.0.1:3080— an existing instance (started by CLI or this app) is reused; otherwise a resident server is spawned (detached, logs tologs/) and the app waits until the port is ready before opening the window.
The Electron process is a pure client: it loads the page and owns the tray. Quitting the app does not kill dsh web — the server stays resident so the next npm start opens instantly. Stop it with pkill -f "dsh web".
Running electron . directly (npm run start:raw, skipping the preflight) still triggers the same locate/install/spawn fallback from the main process.
Getting started
cd dsh-desktop
npm install # installs Electron (downloads binary)
npm start # locate/install dsh → ensure server → open the app
Pin a specific dsh binary:
DSH_BIN=/path/to/dsh npm start. Install output goes to your terminal duringvendor/dshsetup; runtime logs live inlogs/dsh-web.{stdout,stderr}.log.
Known environment quirks (seen on some machines)
~/.npmcache owned by root breaksnpm installwithEPERM. Workaround:npm install --cache /path/to/writable/npm-cache- Electron's binary download writes to
~/Library/Caches/electronby default; if that's not writable, point it elsewhere withelectron_config_cache(note: this is the variableinstall.jsreads — notELECTRON_CACHE):electron_config_cache=/path/to/.electron-cache node node_modules/electron/install.js
None of these matter for a normal npm start.
Packaging
npm run dist # macOS: dmg + zip
npm run dist:win # Windows: NSIS installer + zip (cross-compile from macOS)
npm run dist:all # both
Notes:
- For everyday use just
npm start. - Released builds do not bundle
vendor/dsh(it's large); the target machine auto-installs it on firstnpm start. For a fully offline, self-contained build, shipvendor/dshviaextraResourcesand pointDSH_BINatprocess.resourcesPathin the main process.
Project layout
dsh-desktop/
├── package.json # deps, start/dist scripts, build config
├── scripts/
│ ├── ensure-dsh.js # preflight: locate/install dsh → probe 3080 → spawn resident server
│ └── dsh-server-lib.js # shared logic: dsh locate/install, port probe, readiness wait, spawn
├── electron/
│ ├── main.js # main process: fallback locate/install/spawn, window, tray
│ └── preload.js # minimal preload bridge (read-only version info)
├── vendor/dsh/ # auto-installed dsh (created on first start; safe to delete)
├── logs/ # dsh web logs & pid (runtime)
├── build/ # app icons (icon.icns, icon.ico, icon.png)
└── release/ # packaging output (electron-builder)
License
MIT © 2026 tiankunrui