✨ 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:
| Style | Idle | Working |
|---|
| 🐟 Fish Swing (default) | Still whale | Swinging whale — faster with more work |
| 🔮 Thinking Orb | Search globe | Listening orb — a rippling dot sphere |
Both styles adapt to light/dark menu bars automatically, and your choice is remembered across launches.
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:<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).
📦 Develop / package
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
- Join the Apple Developer Program (paid).
- Create a Developer ID Application certificate: Xcode → Settings → Accounts → Manage Certificates →
+ → Developer ID Application. Verify with security find-identity -v -p codesigning.
- Create an App Store Connect API key (Developer role): App Store Connect → Users and Access → Integrations → App Store Connect API → Team Keys → generate → download the
.p8 → note the Key ID and Issuer ID.
Build + notarize
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:
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
Made with ❤️ for the DeepSeek Harness community.