dsh-desktop-packager
把 DeepSeek Harness 封装成一个可分发的
macOS 桌面应用(.app + .dmg)的 DSH 插件,并在 dsh web 的 Settings 里新增一个
「桌面打包」菜单,通过 4 个配置模块定制化生成 dmg。
能力
- 注册工具
dsh_package_desktop:把一个已构建的 deepseek-harness checkout 封装成.app+.dmg,并按「桌面打包」配置定制化生成。 - Settings 菜单「桌面打包」(浏览器半侧,
settings.section),含 4 个 Tab:- 设计方案 — 显示当前 logo、应用名、VI 方案(主题色 / 背景色),可更换 logo 或整体 VI。
- 插件设置 — 从已安装插件中勾选「打包进桌面 app」的插件。
- 模型设置 — 从已支持的模型中勾选「打包进桌面 app」的模型。
- 权限设置 — 配置桌面 app 的用户(账号 + 密码)与权限(查看/修改 settings 各页)。
- 打包定制化落地:
appName→ ElectronproductName;logo→ 应用图标(.icns/.png/.svg);themeColor/backgroundColor→ 注入 DSH web 主题变量 (--dsw-alias-brand-primary/--dsw-alias-bg-base)与窗口背景色;selectedPlugins/selectedModels→ 写入 app 的DSH_HOME/desktop-config.json, 供 app 内的运行时插件做插件/模型过滤;users→ 打包进Contents/Resources/desktop.json,由 Electron 主进程实现 登录门(账号 + 密码,加盐 scrypt 校验)并注入当前用户权限。
架构
一个 dual-face bundle(Host 原生 TS + 手写浏览器 client bundle):
| 半侧 | 入口 | 形态 | 说明 |
|---|---|---|---|
| Host(入口) | src/index.ts |
原生 TS(dsh plugin add 直接加载) |
提供 desktopConfig 服务 + 注册 dsh_package_desktop 工具 + 注册 HTTP 路由 |
| Host(服务) | src/desktop-config.ts |
原生 TS | 持久化 + 插件/模型枚举 + 用户管理(scrypt 加盐哈希)+ HTTP 路由 |
| Client(浏览器) | client.js |
手写 bundle(window.__ModuleLoader__.load) |
settings.section「桌面打包」4 Tab,fetch 同源调 HTTP 路由 |
| 打包驱动 | packaging/build-macos.mjs |
独立 .mjs |
定制化生成 .app/.dmg |
| 桌面壳 | packaging/electron/* |
独立 .js |
登录门 + 主题注入 + 拉起 dsh web |
配置状态存于单个 JSON 文件(默认 ~/.dsh/desktop-packager/config.json),由 Host 服务、
打包工具与 build-macos.mjs 共享。
浏览器 ↔ Host 桥接(同源 HTTP)
浏览器半侧不依赖 Typert/Remote,直接用同源 fetch 访问 Host 半侧在 webServer 上
注册的 JSON 路由:
| 路由 | 方法 | 作用 |
|---|---|---|
/api/desktop-config |
GET |
返回 { view }(脱敏后的 design/plugins/models/users) |
/api/desktop-config |
POST |
{ action, payload } → 应用改动并返回 { view } |
/api/desktop-config/catalog |
GET |
返回 { plugins, models }(枚举) |
/api/desktop-config/logo |
GET |
返回 { ok, dataUrl? }(logo 预览) |
安装
dsh plugin --profile web add /path/to/dsh-desktop-packager
或在 dsh web 会话里让助手调用 dsh_master_install(需 DSH-master)。
本包已在当前机器以符号链接方式装进
~/.dsh/profiles/web/node_modules/dsh-desktop-packager, 指向源码目录;改动源码后重启dsh web即生效。
使用
1. 在 Settings 里配置
打开 dsh web → 左下角 Settings → 「桌面打包」,分别配置:
- 设计方案:填 logo 绝对路径(
.png/.svg/.icns)、应用名、主题色、背景色,点「保存」。 - 插件设置:勾选要打进桌面 app 的插件(留空 = 全部)。
- 模型设置:勾选要打进桌面 app 的模型(留空 = 全部)。
- 权限设置:新增/删除用户(账号 + 密码),并为每个用户勾选权限
(查看/修改
settings、settings-design、settings-plugins、settings-models、settings-permissions)。
2. 打包
对助手说「帮我用 dsh_package_desktop 打包我的 deepseek-harness」,助手会调用该工具。 核心参数:
| 参数 | 默认 | 说明 |
|---|---|---|
dshCheckoutDir |
配置 dshCheckoutDir |
已构建(pnpm run build 完成)的 harness 源码目录 |
out |
~/Desktop/DeepSeek-Harness-dist |
产物输出目录 |
appName |
设计方案里的 appName |
应用显示名(工具参数优先级高于设计方案) |
bundleId |
com.deepseek.harness |
bundle identifier |
version |
0.1.1 |
版本号 |
arch |
arm64 |
arm64 / x64 |
identity |
空(ad-hoc) | Developer ID 签名身份 |
nodeBin / nodeVersion |
空 | 复用本地 Node / 指定下载版本 |
skipDmg / keepStaging |
false | 只出 .app / 保留中间目录 |
打包时工具把 configPath 传给 build-macos.mjs,后者读取同一份 JSON 并应用
logo / 主题色 / 插件 / 模型 / 用户权限定制。
配置项(cordis.yml)
- id: dsh-desktop-packager
name: dsh-desktop-packager
config:
dshCheckoutDir: /absolute/path/to/deepseek-harness
out: ~/Desktop/DeepSeek-Harness-dist
appName: DeepSeek Harness
bundleId: com.deepseek.harness
version: 0.1.1
arch: arm64 # arm64 | x64
identity: "" # Developer ID Application: …
nodeBin: "" # 复用本地 node 二进制
nodeVersion: ""
nodeDistBase: https://nodejs.org/dist
electronMirror: "" # 国内镜像加速
electronBuilderBinariesMirror: ""
skipDmg: false
keepStaging: false
configPath: ~/.dsh/desktop-packager/config.json # 定制化状态文件
定制化状态文件(configPath)
{
"design": {
"appName": "DeepSeek Harness",
"logoPath": "/absolute/path/to/logo.svg",
"themeColor": "#4D6BFE",
"backgroundColor": "#0f1115"
},
"selectedPlugins": ["@deepseek-ai/dsh-web-app"],
"selectedModels": [{ "provider": "deepseek", "model": "deepseek-chat" }],
"users": [
{ "username": "admin", "passwordHash": "$scrypt$<salt>$<hash>", "permissions": ["settings:view", "settings:edit"] }
]
}
密码只保存加盐 scrypt 哈希,绝不落明文。
权限模型
权限键为 <section>:<action>:settings(面板整体)、settings-design、
settings-plugins、settings-models、settings-permissions,每个都有 :view 与 :edit。
打包后桌面 app 的登录门校验账号密码后,把该用户权限通过
DSH_DESKTOP_USER / DSH_DESKTOP_PERMISSIONS 环境变量与
DSH_HOME/desktop-config.json 注入运行时,由 app 内的运行时插件据此对设置页做
可见性 / 可编辑控制。
前置条件(打包机)
- macOS(默认 arm64 / Apple Silicon)。
- Node.js ≥ 22.19(跑打包脚本用)。
- 网络(下载 Node 运行时 / Electron / electron-builder),或提供
nodeBin复用本地 Node。 - 一个已构建的 deepseek-harness checkout:
apps/cli/lib/bin.js与apps/web/dist必须存在。
目录结构
dsh-desktop-packager/
├── src/
│ ├── index.ts # Host 入口:desktopConfig 服务 + 打包工具 + HTTP 路由
│ ├── config.ts # 部署配置 schema(含 configPath)
│ ├── desktop-config.ts # 定制化状态模型 + 服务(持久化/枚举/用户/哈希/HTTP)
│ └── packager.ts # 子进程 runner(跑 build-macos.mjs)
├── client.js # 浏览器半侧 bundle(settings.section「桌面打包」4 Tab)
├── packaging/
│ ├── build-macos.mjs # 打包驱动(应用 logo/名称/主题/配置)
│ └── electron/
│ ├── main.js # 登录门 + 主题注入 + 拉起 dsh web
│ ├── preload.js # 登录窗 contextBridge
│ └── entitlements.mac.plist
├── package.json # dual-face manifest(dsh.bundle + dsh.client)
├── cordis.patch.yml
└── tsconfig.json
签名与公证(分发建议)
默认 ad-hoc 签名:本机可正常打开,发给别人时 Gatekeeper 会提示「无法验证开发者」。
彻底免除拦截需 Developer ID 签名 + 公证,详见 packaging/README.md。
No comments yet. Be the first to write one.