A lightweight, native macOS client for @deepseek-ai/dsh
Keeps the full DeepSeek Harness Web Client and adds the desktop capabilities an app actually needs.
DSH already ships a complete Web Client — there was no need to wrap it in another layer of navigation and sidebars. DSH Desktop launches the local dsh web with Swift, AppKit, and WKWebView, renders the raw interface directly, and fills in desktop capabilities such as window dragging, macOS window buttons, and a network proxy through a built-in Client plugin.
It is not Electron, and it does not reimplement the DSH UI. The app launches the bundled runtime directly on startup — it reaches the page in about half a second in practice.
- Full, unmodified DSH Web Client, sessions, workspaces, and settings UI
- Bundles
@deepseek-ai/dshand@zenmux/dsh-plugins - Native macOS rounded-corner window, shadow, full screen, and standard menu bar
- Client plugin draws the macOS traffic-light buttons with hover effects
- When the sidebar collapses, the red close button stays aligned with the icon rail
- Drag the empty top area to move the window; double-click to zoom
- Built-in network proxy in Settings, supporting HTTP, HTTPS, SOCKS5, and a direct-connection list
- Configurable DeepSeek Base URL and API Key, with the key stored in macOS Keychain
- Proxy config applies to model requests, plugins, and DSH updates alike
- Checks for new DSH versions in the background after launch; you can also check and update manually
- Codex-style DeepSeek whale app icon
Open Settings → Network Proxy to set the proxy address, a list of direct-connection hosts, or restore direct connections with one click.
After saving, the app restarts DSH and sets HTTP_PROXY, HTTPS_PROXY, ALL_PROXY, NO_PROXY, and the Node environment proxy switches for the child process. Local loopback addresses always stay direct-connected.
Open Settings → LLM Gateway to override DEEPSEEK_BASE_URL and configure DEEPSEEK_API_KEY. Leave the Base URL blank to use DeepSeek's official endpoint; DSH appends /chat/completions automatically.
The API Key is stored in macOS Keychain and is never written to app preferences or logs. Saving or clearing gateway settings restarts the local DSH process so the new environment takes effect.
Requirements:
- macOS 13 or newer
- Apple Silicon or Intel Mac (download the matching Release asset)
- Node.js installed with nvm, fnm, Homebrew, or another standard installation
Download the archive from Releases, extract it, and move DSH Desktop.app into your Applications folder.
You need the Xcode Command Line Tools, Node.js, and npm:
git clone https://github.com/ilimei/dsh-desktop.git
cd dsh-desktop
./build.shThe first build installs the DSH and ZenMux dependencies. The output is at dist/DSH Desktop.app.
To cross-build the Intel version on an Apple Silicon Mac with Rosetta installed:
./build-x86_64.shThe Intel output is at dist-x86_64/DSH Desktop.app. Its npm runtime is installed separately so native Node modules match x86_64.
The default build uses ad-hoc signing and is fine only for local development. For public distribution, use a fixed Apple Developer Developer ID Application certificate:
DSH_CODESIGN_IDENTITY="Developer ID Application: Your Name (TEAMID)" ./build.shWhen building with a Developer ID, the script enables the Hardened Runtime and timestamping. Before releasing, you should also complete Apple notarization with notarytool and run stapler staple.
DSHClient.swift Native AppKit / WKWebView client and updater
plugin/ Bundled DSH Web Client extension
assets/ App icon, screenshots, and the icon generator
runtime-install/ DSH and ZenMux dependency manifest
build.sh arm64 macOS build script
build-x86_64.sh Intel x86_64 macOS cross-build script
flowchart LR
App["AppKit native window"] --> WebView["WKWebView"]
App --> Process["local dsh web"]
Process --> WebClient["DeepSeek Harness Web Client"]
Plugin["bundled Client plugin"] --> WebClient
Plugin <-->|"native message bridge"| App
ZenMux["@zenmux/dsh-plugins"] --> Process
