🐳 DeepSeek Harness Developer Preview
All-in-one native desktop client · bundles Node.js runtime + deepseek-harness
What is this
DeepSeek Harness Developer Preview is a native desktop client (all-in-one architecture) for DeepSeek Harness:
- 📦 No Node.js install needed — ships its own Node.js LTS runtime (v24.19.0)
- 🚀 Ready to run — bundles the latest
@deepseek-ai/dsh; startsdsh webon launch - 🖥️ Native feel — Tauri 2 native window, system tray, native menus
- 🔔 Session notifications — native notification when a session turn completes; click to return to the window
- 🔄 Auto-update — distributed via GitHub Releases; silent startup check plus a manual menu item
⚠️ This is a community-maintained third-party desktop client, not affiliated with DeepSeek. For development and research use only. Currently in beta (Developer Preview) and supports macOS (Apple Silicon) only.
Features
| Capability | Details |
|---|---|
| Bundled runtime | Node.js LTS v24.19.0 + full @deepseek-ai/dsh production closure (~66 MiB compressed archive with size pruning; see below) |
| Local-first | Sessions and settings live on your machine (default ~/.dsh); the service binds 127.0.0.1 |
| Single instance | Launching again focuses the existing window instead of starting a second server |
| Tray resident | Closing the window hides to the tray; the background service keeps running |
| Auto-update | Silent check 3s after startup; "Check for Updates…" menu item; signed update manifests |
| Session notifications | Polls the session store; notifies on turn/end with reason completed/error |
| Plugin manager | Manage dsh-plugin topic plugins from GitHub: list/search/install/remove; pre-install manifest verification (dsh.bundle/dsh.client), install confirmation, and an audit log at ~/.dsh/desktop-audit.log |
| External links | GUI links open in the system browser; the window only ever visits the local service |
| Error fallback | A dedicated error page when the bundled service fails to start; logs under the system log dir |
Download & install
Grab the DMG from the Releases page (Apple Silicon builds).
macOS builds are unsigned/un-notarized: on first launch allow the app in System Settings → Privacy & Security, or right-click → Open.
Development
pnpm install # install dependencies
pnpm run runtime # assemble the bundled runtime (downloads Node v24.19.0 + prod-installs @deepseek-ai/dsh)
DSH_DESKTOP_PRUNE=1 pnpm run runtime # same, but prune dead weight first (node strip, .map/.d.ts, node-pty cross-platform prebuilds, OTel esm/esnext builds, READMEs/tests): ~97 MiB -> ~66 MiB
pnpm run smoke # boot the assembled runtime exactly like the shell and GET the root
pnpm run tauri:dev # development mode
pnpm run tauri:build # release build (.dmg)
pnpm run check:upstream # check for a newer @deepseek-ai/dsh on npm
pnpm run verify:update # verify the updater-latest manifest + update URL after a release
Layout
├── scripts/ # runtime assembly & tooling
│ ├── download-node.mjs # download + verify the bundled Node binary
│ ├── assemble-runtime.mjs # prod-install @deepseek-ai/dsh → resources/runtime
│ ├── smoke.mjs # boot + probe the assembled runtime
│ ├── check-upstream.mjs # npm upstream check (used by the scheduled workflow)
│ ├── verify-update.mjs # post-release check: updater-latest manifest + update URL
│ ├── gen-icons.sh # app / tray icons
│ └── gen-signer-key.sh # updater signing keypair
├── resources/ # build artifacts (git-ignored): runtime/ + runtime.tar.gz
├── src-tauri/ # Tauri 2 shell (Rust)
│ └── src/
│ ├── lib.rs # entry, menus, window lifecycle
│ ├── server.rs # spawn/supervise dsh web, wait for readiness, navigate
│ ├── tray.rs # system tray
│ ├── updater.rs # auto-update (silent startup + manual menu)
│ └── notify.rs # session-completion notifications (store polling)
├── public/error.html # startup-failure fallback page
├── index.html # splash page
└── .github/workflows/ # CI / upstream check / release
How it works
scripts/assemble-runtime.mjsprod-installs@deepseek-ai/dshwith npm in a temp dir (real directories, no symlinks), then bundles it with the downloaded Node binary asresources/runtime.tar.gz. Release builds setDSH_DESKTOP_PRUNE=1to prune dead weight first (strip the node binary + re-sign, drop.map/.d.ts, node-pty cross-platform prebuilds, READMEs/tests): the archive goes from ~97 MiB to ~66 MiB (gzip -9).- Release builds ship the archive as a Tauri resource.
- On first launch the app extracts the archive into a cache dir keyed by a content hash (stale versions are cleaned up automatically).
- Rust spawns
dsh --profile web --port 0with the bundled Node (OS-assigned port), reads the readiness linedsh web: http://127.0.0.1:<port>from stdout, polls the root, then navigates the window. - Navigation is confined to the local service origin; external links leave via the system browser.
- A background thread polls
~/.dsh/sessions/**/session.jsonl.zstdevery 2s and posts a notification on a freshturn/end(reasoncompleted/error).
Update signing
Auto-update needs a minisign keypair:
pnpm run signer-key
- The private key lives at
~/.tauri/dsh.key— never commit it; - Paste the public key into
src-tauri/tauri.conf.json→plugins.updater.pubkey; - CI signs update packages with the
TAURI_SIGNING_PRIVATE_KEY/TAURI_SIGNING_PRIVATE_KEY_PASSWORDsecrets.
Release flow
- Bump the version in
package.jsonandsrc-tauri/Cargo.toml(must carry a-betasuffix) and updateCHANGELOG.md/CHANGELOG-zh.md; commit and push. - Trigger the
releaseworkflow manually (optionally overriding the version). - The workflow builds on macOS (Apple Silicon,
macos-latest), signs, and publishes a pre-releasevX.Y.Z-beta.Nwith thelatest.jsonupdate manifest attached. - Clients pick the manifest up at startup and via "Check for Updates…".
- After the release, verify the update pointer end-to-end:
pnpm run verify:update(fetchesupdater-latest/latest.json, validates thedarwin-aarch64entry, and probes the update package URL for HTTP 200/302).
Upstream sync
.github/workflows/check-upstream.yml checks npm daily for a newer @deepseek-ai/dsh:
- New version → opens/updates a dependency-bump PR; merge after CI passes;
- Or run manually:
gh workflow run check-upstream.yml.
Roadmap
- macOS: development / CI / deployment / auto-update full loop
- Notification click navigates to the finished session
- Windows / Linux support
- dsh plugin management (MVP: list/search/install/remove from the GitHub
dsh-plugintopic, with pre-install manifest verification + audit log) - Smaller bundle (prune the runtime closure)
Credits
- deepseek-ai/deepseek-harness — the engine and the served web app
- Tauri — the native shell framework
No comments yet. Be the first to write one.