# ๐Ÿ‹ DeepSeek Harness โ€” Desktop **A native macOS desktop shell for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) โ€” double-click, no terminal.** [![version](https://img.shields.io/badge/version-0.1.4-4c7dff?style=flat-square)](https://github.com/Evan1u/deepseek-harness-desktop/releases) [![platform](https://img.shields.io/badge/macOS-arm64-888888?style=flat-square)](#) [![license](https://img.shields.io/badge/license-MIT-4caf50?style=flat-square)](LICENSE) [![stars](https://img.shields.io/github/stars/Evan1u/deepseek-harness-desktop?style=social)](https://github.com/Evan1u/deepseek-harness-desktop) *[English](README.md) ยท [ไธญๆ–‡](README.zh.md)*
--- ## โœจ What this is DeepSeek Harness is powerful, but starting it means opening a terminal and typing `dsh web`. This app wraps it in a **thin Electron shell** โ€” double-click, and it boots `dsh --profile web --no-open --port 0`, waits for the local URL, and renders the **exact same Web GUI** in a native window. Every web feature, zero divergence, zero terminal.
| ๐Ÿ–ฅ๏ธ No terminal | ๐Ÿ‹ Live tray | ๐ŸŽฏ Busyness-aware | ๐ŸŒ— Light/dark | ๐Ÿ”„ Auto-update | |:---:|:---:|:---:|:---:|:---:| | Double-click to run | Two switchable icon styles | The icon reacts to real workload | Adaptive icons | GitHub Releases |
## ๐Ÿ‹ The tray icon โ€” alive and switchable The menu-bar icon is **not a static glyph**. It reflects what DeepSeek Harness is doing: - **Idle** โ†’ a calm, still icon. - **Working** โ†’ an animated icon whose **speed** follows how busy the backend is (running sessions + running jobs). Right-click the icon to switch between **two styles**:
StyleIdleWorking
๐ŸŸ Fish Swing (default)Still whaleSwinging whale โ€” faster with more work
๐Ÿ”ฎ Thinking OrbSearch globeListening orb โ€” a rippling dot sphere
Both styles adapt to light/dark menu bars automatically, and your choice is remembered across launches.
Fish Swing
๐ŸŸ Fish Swing
Thinking Orb
๐Ÿ”ฎ Thinking Orb
### Busyness โ†’ animation | Busyness | State | Frequency | | --- | --- | --- | | 0 | Still | โ€” | | 1 | Light | Slow (~1.8 s/cycle) | | 2 | Medium | Medium (~1.2 s/cycle) | | 3 | Heavy | Fast (~0.8 s/cycle) | > Busyness = running sessions + running jobs, read live from the harness's own event streams. ### Swing amplitude Right-click the menu-bar icon โ†’ **Swing Amplitude** โ†’ pick a preset: | Preset | Subtle | Default | Strong | Stronger | Strongest | | --- | --- | --- | --- | --- | --- | | Rotation | 6ยฐ | 9ยฐ | 12ยฐ | 15ยฐ | 18ยฐ | ## ๐Ÿš€ Getting Started double-click the `.app` โ€” or drop it into **Applications**. If macOS warns on first launch (unsigned build), *right-click โ†’ Open*. - **Left-click** the tray icon โ†’ show the window - **Right-click** โ†’ Open / Quit / Icon Style / Swing Amplitude - **Red close button** โ†’ hides to the tray; the app keeps running in the background
๐Ÿ”ง How it works ``` DeepSeek Harness.app โ””โ”€ Electron main process โ”œโ”€ resolve dsh (DSH_BIN override โ†’ /opt/homebrew/bin/dsh โ†’ โ€ฆ โ†’ PATH) โ”œโ”€ spawn: dsh --profile web --no-open --port 0 โ”œโ”€ parse stdout: "dsh web: http://127.0.0.1:" โ”œโ”€ BrowserWindow.loadURL(that URL) โ””โ”€ lifecycle: SIGTERM on quit ยท retry dialog on backend crash ``` The backend binds `127.0.0.1` on an OS-assigned port, so the `/api` loopback trust fence passes with no extra configuration and there is no fixed-port conflict. > โš ๏ธ **Do not** open the same session in a separate terminal `dsh web` at the same time โ€” the session store is single-writer, so two live backends writing one session log can corrupt it (history then fails with `corrupt session log: seq gap in committed region`).
๐Ÿ“ฆ Develop / package ```sh npm install # installs electron + electron-builder npm start # run from source npm run pack # build the .app (release/mac-arm64/DeepSeek Harness.app) npm run dist # also build .dmg and .zip ``` Output lands in `release/`. If a **Developer ID Application** certificate is in your Keychain, electron-builder signs automatically; otherwise the app is left **unsigned** for local use.
๐Ÿ” Code signing & notarization (remove Gatekeeper) Signing + notarization require an Apple Developer Program membership and a Developer ID certificate. The toolchain and build config are already wired up โ€” you only supply the credentials. **One-time setup** 1. Join the [Apple Developer Program](https://developer.apple.com/programs/) (paid). 2. Create a **Developer ID Application** certificate: Xcode โ†’ Settings โ†’ Accounts โ†’ Manage Certificates โ†’ `+` โ†’ Developer ID Application. Verify with `security find-identity -v -p codesigning`. 3. Create an **App Store Connect API key** (Developer role): [App Store Connect](https://appstoreconnect.apple.com/) โ†’ Users and Access โ†’ Integrations โ†’ App Store Connect API โ†’ Team Keys โ†’ generate โ†’ download the `.p8` โ†’ note the **Key ID** and **Issuer ID**. **Build + notarize** ```sh npm run pack # signs automatically once the cert is in Keychain APPLE_API_KEY_PATH=~/.appstoreconnect/AuthKey_XXXXXX.p8 \ APPLE_API_KEY_ID=XXXXXXXXXX \ APPLE_API_ISSUER_ID=00000000-0000-0000-0000-000000000000 \ ./scripts/notarize.sh ```
๐Ÿ”„ Auto-update (GitHub Releases) The app checks for updates on launch (then hourly) and offers **Restart now** when a newer version is out. Publish a new release with a GitHub token: ```sh GH_TOKEN=github_pat_xxx ./scripts/publish.sh ``` > Note: reliable macOS auto-update is best with a signed app; for an unsigned personal build it is best-effort.
## โš™๏ธ Configuration | Variable | Purpose | | --- | --- | | `DSH_BIN` | Absolute path to the `dsh` executable (defaults to `/opt/homebrew/bin/dsh`). | | `DSH_HOME` | Inherited from the environment; shares `~/.dsh` profiles, credentials, and sessions with the CLI. |
๐Ÿ—บ๏ธ Roadmap - [x] v0.1 โ€” Electron shell wrapping `dsh web` (full web parity) - [x] Appearance-adaptive Dock icon (light/dark) - [x] Busyness-aware animated tray + close-to-tray - [x] Two switchable tray icon styles (Fish Swing / Thinking Orb) - [x] Auto-update (GitHub Releases) - [ ] Code signing + notarization โ€” config ready, pending Apple Developer credentials - [ ] Native IPC transport โ€” load `dist` over `file://` and bridge `/api` over `ipcRenderer`
*Made with โค๏ธ for the DeepSeek Harness community.*