Back to home

nihaozyj7

dsh-desktop

Go + Wails desktop shell for DeepSeek Harness: native window, engine supervision, self-update, and preview source builds

Stars
0
Language
Go
Created
Aug 14, 2026
Updated
Aug 14, 2026

Introduction

DSH Desktop — DeepSeek Harness Desktop Shell

A Go + Wails desktop shell for DeepSeek Harness: native window, supervised Node engine, self-update, and preview source builds. The agent runtime stays 100% inside the harness — this project only wraps it.

platform

Screenshots

Settings panel

Features

  • Custom frameless title bar — logo, shell + harness version chips, settings / minimize / maximize / close controls, draggable, double-click to maximize.
  • Settings panel — update check, update feed, repository URL, port + LAN WebUI toggle, open data/log folders, restart engine, about, quit.
  • Live theme unification — on startup the shell extracts the web UI's palette from its CSS, persists it, and binds the desktop chrome to the page's own CSS variables (var(--dsw-alias-*, …)), so the title bar follows the web theme (light/dark) automatically.
  • Release-based self-update — signed manifests (sha256 + ed25519), atomic versioned payloads, automatic rollback.
  • Preview builds — no release available? Pull the repository source, compile locally, and switch to a preview-<commit> engine. Great for testing the latest code.
  • Full backend permissions — the engine runs with DSH_PERMISSION_MODE=danger-full-access (sandbox unrestricted, no approval prompts); the shell adds no restriction of its own.
  • No console window — the engine runs hidden (CREATE_NO_WINDOW); a loading page with a spinner covers startup.

Architecture

┌───────────────────────────────────────────────────────────────┐
│ dsh-desktop.exe  (Wails shell, Go)                             │
│  ├─ Frameless window (WebView2)                                │
│  ├─ AssetServer: reverse proxy → engine                        │
│  │    Host/Origin/Referer normalized to loopback, so the /api  │
│  │    browser-trust fence accepts the desktop webview; HTML     │
│  │    responses are decorated with the desktop chrome           │
│  ├─ engine: child-process supervisor (readiness/restart/swap)  │
│  └─ updater: release channel + preview source builds            │
└───────────────────────────┬───────────────────────────────────┘
                            │ http://127.0.0.1:<OS-assigned>
┌───────────────────────────▼───────────────────────────────────┐
│ Engine payload (in %LOCALAPPDATA%\DSHByDesktop\versions\<v>)    │
│   node.exe + closure/   — the packaged dsh web engine          │
│   (build via DSHByDesktop/engine/build-engine.mjs inside a     │
│    deepseek-harness checkout)                                  │
└───────────────────────────────────────────────────────────────┘

Key design points:

  • Shell and engine are separated. Updates swap only versions/<v>/engine; the running dsh-desktop.exe is never replaced, so Windows file locking is a non-issue. User data lives in DSH_HOME (default ~/.dsh) and is never touched by updates.
  • Readiness signal. The engine prints dsh web: http://127.0.0.1:<port> once the Loader tree settles; the shell parses the port, arms the proxy, and reloads the window. --port 0 means no port conflicts.
  • The webview is a trusted loopback client. The proxy rewrites Host/Origin/Referer to the engine's loopback authority, so the harness's /api trust fence treats the desktop UI exactly like a page opened from 127.0.0.1.
  • LAN exposure is a shell listener, not an engine bind. The engine stays loopback-only; an optional 0.0.0.0:<port> listener in the shell proxies external requests through the same trust-normalizing proxy.

Repository layout

DSHByDesktop/
  main.go                  entry (--headless / --build-preview / --version)
  shell/                   Go sources (engine supervisor, proxy, updater, theme, UI embed)
  shell/ui/                injected chrome (style.css, markup.html, app.js)
  engine/build-engine.mjs  engine packaging (pnpm deploy + closure carrier)
  scripts/                 icon generation, dist assembly, update signing, local feed server
  build/                   Wails resources (icons)
  frontend/                no-op placeholder for the Wails toolchain

Prerequisites

  • Windows 10/11 x64 with WebView2 (bundled with Windows 11; Evergreen runtime otherwise).
  • To build the engine you need a checkout of deepseek-harness with this project placed at its DSHByDesktop/ directory, plus:
    • Node.js ≥ 22.19, pnpm
    • Go (1.22+), gcc (Wails requirement), Wails CLI v2

Building (inside a deepseek-harness checkout)

pnpm install
pnpm run build                      # harness lib + web dist

# engine: deploy the closure + node.exe carrier (~300 MB, AV-safe)
node DSHByDesktop/engine/build-engine.mjs --skip-build
# optional single-file SEA (trips heuristic AV; only for whitelisted/signed setups)
# node DSHByDesktop/engine/build-engine.mjs --skip-build --sea

# shell
cd DSHByDesktop && wails build && cd ..

# assemble dist + update zip
node DSHByDesktop/scripts/assemble-dist.mjs --zip

Artifacts land in DSHByDesktop/dist/: dsh-desktop.exe, engine/…, dsh-desktop-windows-amd64.zip, update-windows-amd64.json.

Running

DSHByDesktop/dist/dsh-desktop.exe            # desktop window
DSHByDesktop/dist/dsh-desktop.exe --headless # engine only, prints the URL (CI/debug)
DSHByDesktop/dist/dsh-desktop.exe --build-preview # source preview build, then exit

First run copies the bundled engine into %LOCALAPPDATA%\DSHByDesktop\versions\<version>\engine; afterwards the engine always runs from the versioned directory.

Self-update

The update feed defaults to the repository's release asset update-windows-amd64.json (next to dsh-desktop-windows-amd64.zip). The shell checks at startup and every 4 hours, and on demand from the settings panel:

{
  "version": "0.2.0",
  "url": "https://…/dsh-desktop-windows-amd64.zip",
  "sha256": "<zip sha256>",
  "signature": "<ed25519 over the sha256 hex>",
  "releaseNotes": "…"
}

Download → sha256 verify → ed25519 verify (public key embedded in shell/updater.go) → extract to versions/<v> → swap the current pointer → restart the engine; a failed boot within 120s rolls back automatically.

Signing keys. Manifests are signed with an ed25519 keypair. Generate your own and embed the public key in shell/updater.go:

node DSHByDesktop/scripts/gen-signing-key.mjs        # writes scripts/update-signing-key.json
node DSHByDesktop/scripts/sign-update.mjs <version> DSHByDesktop/dist/dsh-desktop-windows-amd64.zip "notes"

Preview builds (from source)

In the settings panel → 预览版(从仓库构建) enter a repository URL and start. The shell:

  1. git fetch the latest source (default https://github.com/deepseek-ai/deepseek-harness; any fork works)
  2. pnpm install + pnpm run build
  3. Packages the engine with build-engine.mjs
  4. Installs it as preview-<commit>, switches, and restarts (with rollback)

Requires git, Node ≥ 22 and pnpm on the machine. Progress is shown live in the panel.

Permissions model

The shell imposes no permission restrictions:

  • Frontend: the proxy normalizes Host/Origin/Referer to loopback, making the desktop webview a trusted loopback client of the /api fence.
  • Backend: the engine runs with DSH_PERMISSION_MODE=danger-full-access — harness preset: sandbox unrestricted + approval never.

Configuration

%LOCALAPPDATA%\DSHByDesktop\settings.json:

{
  "updateFeed": "https://github.com/…/releases/latest/download/update-windows-amd64.json",
  "repoURL": "https://github.com/deepseek-ai/deepseek-harness",
  "autoCheck": true,
  "webPort": 0,
  "exposeWeb": false
}

webPort (0 = auto, used when exposeWeb is on) and exposeWeb are also editable in the settings panel. DSH_DESKTOP_UPDATE_FEED and DSH_DESKTOP_ENGINE are optional environment overrides.

Known limitations

  • Windows/amd64 only so far; macOS/Linux need platform runners and their WebViews.
  • The engine exe is unsigned — code-sign the distribution to avoid SmartScreen warnings.
  • No system tray; closing the window quits the app.
  • LAN exposure is intentionally opt-in and exposes full agent permissions — enable only on trusted networks.

License

MIT