Bundle
deepseek-harness-desktop
macOS (Apple Silicon) desktop shell for the DeepSeek Harness Web GUI — double-click to run, no terminal needed.
- Source
- Evan1u
- stars
- 1 stars
- Updated
- Updated 5 days ago
Readme
<div align="center">
# 🐋 DeepSeek Harness — Desktop
**A native macOS desktop shell for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) — double-click, no terminal.**
[](https://github.com/Evan1u/deepseek-harness-desktop/releases)
[](#)
[](LICENSE)
[](https://github.com/Evan1u/deepseek-harness-desktop)
*[English](README.md) · [中文](README.zh.md)*
</div>
---
## ✨ 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.
<div align="center">
| 🖥️ 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 |
</div>
## 🐋 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**:
<table>
<tr><th>Style</th><th>Idle</th><th>Working</th></tr>
<tr><td><b>🐟 Fish Swing</b> <i>(default)</i></td><td>Still whale</td><td>Swinging whale — faster with more work</td></tr>
<tr><td><b>🔮 Thinking Orb</b></td><td>Search globe</td><td>Listening orb — a rippling dot sphere</td></tr>
</table>
Both styles adapt to light/dark menu bars automatically, and your choice is remembered across launches.
<div align="center">
<table>
<tr>
<td align="center"><img src="assets/demo.gif" width="220" alt="Fish Swing"><br><sub>🐟 Fish Swing</sub></td>
<td align="center"><img src="assets/demo-orb.gif" width="220" alt="Thinking Orb"><br><sub>🔮 Thinking Orb</sub></td>
</tr>
</table>
</div>
### 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
<kbd>double-click</kbd> 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
<details>
<summary><b>🔧 How it works</b></summary>
```
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:<port>"
├─ 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`).
</details>
<details>
<summary><b>📦 Develop / package</b></summary>
```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.
</details>
<details>
<summary><b>🔏 Code signing & notarization (remove Gatekeeper)</b></summary>
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
```
</details>
<details>
<summary><b>🔄 Auto-update (GitHub Releases)</b></summary>
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.
</details>
## ⚙️ 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. |
<details>
<summary><b>🗺️ Roadmap</b></summary>
- [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`
</details>
<div align="center">
*Made with ❤️ for the DeepSeek Harness community.*
</div>
Install
dsh plugin --profile web add github:Evan1u/deepseek-harness-desktop
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install deepseek-harness-desktop from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.