# 🐋 DeepSeek Harness — 桌面版 **一个 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 的原生 macOS 桌面外壳 —— 双击即用,无需终端。** [![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)*
--- ## ✨ 这是什么 DeepSeek Harness 很强,但启动它得打开终端敲 `dsh web`。这个 App 用一个**轻量 Electron 外壳**把它包了起来——双击后,它会启动 `dsh --profile web --no-open --port 0`,等待本地 URL,然后在原生窗口里渲染**完全相同的 Web GUI**。所有 web 功能,零差异、零终端。
| 🖥️ 无需终端 | 🐋 灵动托盘 | 🎯 忙闲感知 | 🌗 深/浅自适应 | 🔄 自动更新 | |:---:|:---:|:---:|:---:|:---:| | 双击即用 | 两套图标可切换 | 图标反映真实负载 | 图标随系统切换 | GitHub Releases |
## 🐋 托盘图标 —— 活的、可切换 菜单栏图标**不是一个静态图案**,它会反映 DeepSeek Harness 正在做什么: - **空闲** → 安静的静止图标; - **工作** → 动态图标,**速度**跟随后端忙碌程度(运行中的会话数 + 任务数)。 右键图标可在**两套风格**间切换:
风格静止工作
🐟 Fish Swing (默认)静止鲸鱼摆动鲸鱼——工作越多摆得越快
🔮 Thinking Orb搜索球聆听球——点阵波纹球
两套风格都会自动适配深/浅色菜单栏,选择会在下次启动时记住。
Fish Swing
🐟 Fish Swing
Thinking Orb
🔮 Thinking Orb
### 忙碌度 → 动画 | 忙碌度 | 状态 | 频率 | | --- | --- | --- | | 0 | 静止 | — | | 1 | 轻 | 慢(约 1.8 秒/循环) | | 2 | 中 | 中(约 1.2 秒/循环) | | 3 | 重 | 快(约 0.8 秒/循环) | > 忙碌度 = 运行中的会话数 + 运行中的任务数,实时读取自 harness 自身的事件流。 ### 摆动幅度 右键菜单栏图标 → **Swing Amplitude** → 选一档: | 档位 | Subtle | Default | Strong | Stronger | Strongest | | --- | --- | --- | --- | --- | --- | | 旋转 | 6° | 9° | 12° | 15° | 18° | ## 🚀 使用指南 双击 `.app`——或拖进「应用程序」。首次启动若被 Gatekeeper 拦截(未签名),*右键 → 打开*。 - **左键**托盘图标 → 唤出窗口 - **右键** → Open / Quit / Icon Style / Swing Amplitude - **红色关闭按钮** → 藏到托盘,App 在后台继续运行
🔧 工作原理 ``` DeepSeek Harness.app └─ Electron 主进程 ├─ 定位 dsh(DSH_BIN 覆盖 → /opt/homebrew/bin/dsh → … → PATH) ├─ 启动:dsh --profile web --no-open --port 0 ├─ 解析 stdout:"dsh web: http://127.0.0.1:" ├─ BrowserWindow.loadURL(那个 URL) └─ 生命周期:退出时 SIGTERM · 后端崩溃弹重试对话框 ``` 后端绑定 `127.0.0.1` 的系统分配端口,`/api` 的 loopback 信任栅栏无需额外配置即可通过,也不存在固定端口冲突。 > ⚠️ **不要**同时用另一个终端 `dsh web` 打开同一个会话——会话存储是单写者,两个活着的后端写同一份日志会损坏它(历史会报 `corrupt session log: seq gap in committed region`)。
📦 开发 / 打包 ```sh npm install # 安装 electron + electron-builder npm start # 从源码运行 npm run pack # 构建 .app(release/mac-arm64/DeepSeek Harness.app) npm run dist # 同时构建 .dmg 和 .zip ``` 产物输出到 `release/`。若钥匙串里有 **Developer ID Application** 证书,electron-builder 会自动签名;否则保持未签名,供本地使用。
🔏 签名与公证(消除 Gatekeeper) 签名 + 公证需要 Apple Developer Program 会员与 Developer ID 证书。工具链与构建配置都已就绪——你只需提供凭证。 **一次性设置** 1. 加入 [Apple Developer Program](https://developer.apple.com/programs/)(付费)。 2. 创建 **Developer ID Application** 证书:Xcode → Settings → Accounts → Manage Certificates → `+` → Developer ID Application。用 `security find-identity -v -p codesigning` 验证。 3. 创建 **App Store Connect API key**(Developer 角色):[App Store Connect](https://appstoreconnect.apple.com/) → Users and Access → Integrations → App Store Connect API → Team Keys → 生成 → 下载 `.p8` → 记下 **Key ID** 与 **Issuer ID**。 **构建 + 公证** ```sh npm run pack # 证书装好后会自动签名 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 ```
🔄 自动更新(GitHub Releases) App 启动时(之后每小时)自动检查更新,发现新版本会提示 **Restart now**。用 GitHub token 发布新版本: ```sh GH_TOKEN=github_pat_xxx ./scripts/publish.sh ``` > 注:macOS 自动更新在签名后的 App 上最可靠;未签名的个人构建是尽力而为。
## ⚙️ 配置 | 变量 | 用途 | | --- | --- | | `DSH_BIN` | `dsh` 可执行文件的绝对路径(默认 `/opt/homebrew/bin/dsh`)。 | | `DSH_HOME` | 从环境继承;与 CLI 共用 `~/.dsh` 的 profiles、凭据与会话。 |
🗺️ 路线图 - [x] v0.1 —— Electron 外壳包裹 `dsh web`(完整 web 功能对等) - [x] 跟随系统明暗切换的 Dock 图标 - [x] 忙闲感知的动态托盘 + 关窗后台常驻 - [x] 两套可切换的托盘图标风格(Fish Swing / Thinking Orb) - [x] 自动更新(GitHub Releases) - [ ] 签名 + 公证——配置就绪,待 Apple Developer 凭证 - [ ] 原生 IPC 传输——通过 `file://` 加载 `dist`,借 `window.__DSH_TRANSPORT__` 把 `/api` 走 `ipcRenderer`
*为 DeepSeek Harness 社区用心打造。*