deepseek-harness
deepseek-ai
DeepSeek Harness: Everything is a Plugin.
PROJECT TOPICS
PROJECT README
无需 Node.js,不碰 YAML,一站式使用和管理 DeepSeek Harness。
DeepSeek Harness 官方 Web UI 桌面客户端 —— 支持 DeepSeek 账号登录,并内置插件、MCP 与 Skills 管理台。
注:本项目是社区维护的开源项目,非 DeepSeek 官方产品。
欢迎加入 QQ 交流群,获取使用帮助、交流插件与功能想法。
| QQ 交流群 |
|---|
![]() |
| 群名:dsh-desktop-hub · 群号:1106611027 |
不是套壳。官方 Web UI 原样保留在 Harness Tab 里,同时把三个命令行场景搬进同一个窗口:
dsh plugin / 手写 YAML。.bak-<ts>、官方 HMR 热生效,改错了随时可恢复。插件、MCP 与 Skills 共用一个目录体验:搜索、查看来源、来源等级与权限,确认后分别安装到当前 profile 或用户级 skills。插件默认来自 DSH Plugin Market 发布的 Awesome DSH Plugin 清单,MCP 合并官方 Registry 与 DSH MCP Market,Skills 合并 ClawHub 与 SkillsMP。npm 只在插件安装预检时读取 manifest,不作为主市场搜索源;网络不可用时回退到本地缓存和随包精选目录。
市场数据来源声明:各来源的运行时地址、用途、缓存策略、许可证边界和安全限制见
MARKET_SOURCES.md。上游目录的收录不等于 DSH 安全背书。
账号登录、退出与授权状态统一由 Harness 设置管理。Desktop Hub 提供插件、MCP 与 Skills 管理,不再提供独立的账号管理入口。也可以在 Harness 设置中配置 API Key。
Claude Code / Cursor 导出的 MCP JSON,粘贴进去 → 自动转换成 DSH 插件行 YAML(${VAR} 自动转 !!js process.env.VAR,sse / 非法 serverName 会警告)→ 确认后写入 profile patch,官方 HMR 热生效。市场条目若声明环境变量,会在安装卡片中先填写密钥,DSH 将值写入当前 MCP 配置,用户不需要再手动设置系统环境变量。

扫描用户级 / 随包全部 skills(rank 规则,同名低 rank 生效、高 rank 标「被遮蔽」);支持导入 .skill / .zip / GitHub 仓库链接,或直接新建用户级 skill,模型可见 / 用户可见一键切换。
按组合包 / 依赖分类展示 web profile 的插件清单;安装、移除、更新真实执行 dsh plugin;聚合仓库(缺 dsh.bundle)拒绝误装,避免把仓库根目录装成插件。
当前为预览版(macOS arm64,已签名并公证;Windows x64 未签名)。
| 状态 | 项目 |
|---|---|
| ✅ | 基础版:Harness 主界面 + 桌面管理面板 + MCP / Skills / Plugin 管理 + 内置运行时 |
| ✅ | 扩展中心 MVP:Plugin 市场、MCP 市场、Skills 市场(随包精选目录) |
| ✅ | DeepSeek 账号:使用 Harness 内置的账号设置 |
| 🚧 | Profile 切换(当前固定 web) |
| Planned | Model Manager(API Key / 模型管理面板) |
| Planned | Doctor(环境自检与一键修复) |
| ✅ | Windows 安装包(NSIS,x64,与 macOS 并行发布) |
| ✅ | 后台托盘:关闭窗口后继续运行 Harness,可从托盘显示或退出 |
| Planned | Linux 安装包 |
| ✅ | 应用更新(GitHub Releases 检查、下载与重启安装) |
| ✅ | 首次访问引导:Spotlight 分步教程,侧栏「使用引导」可重看 |
| ✅ | macOS 签名与公证(Developer ID,v0.3.5 起;应用内更新同步启用) |
应用内置“反馈”Tab。匿名/署名反馈会提交到可访问的反馈服务,再由 bot 整理为 GitHub Issue,普通用户不需要访问 GitHub。诊断环境信息默认不附加,用户可以单独复制诊断信息或完整反馈;网络不可用时可复制内容发送到 QQ 群。
1106611027,二维码见应用内反馈 Tab本项目是活项目:CI 每个 tag 自动出包,Roadmap 上的能力持续在长。Star 一下跟踪进展。
想参与开发?请先阅读 贡献指南。
渲染进程(sandbox) preload 主进程 核心逻辑 捆绑运行时
┌──────────────────┐ ┌──────────────────┐ ┌────────────────────┐ ┌──────────────────┐ ┌─────────────────────────┐
│ 六 Tab 壳 │ │ window.dshDesktop│ │ IPC handlers │ │ src/core/ │ │ resources/ │
│ index.html │──▶│ contextBridge │──▶│ harness:url │──▶│ harness.ts │──▶│ node/(Node v24.10.0) │
│ renderer.ts │ │ preload.cjs │ │ plugins:list/ │ │ plugins.ts │ │ dsh-runtime/ │
│ (harness iframe) │◀──│ (CJS, sandbox) │◀──│ install/remove/ │ │ mcp.ts │ │ @deepseek-ai/dsh │
│ │ │ │ │ update │ │ skills.ts │ │ (0.1.7-rc.2) │
│ │ │ │ │ mcp:list/convert/ │ └──────────────────┘ │ │ │
│ │ │ │ │ apply/update/ │ │ spawn(detached) ▼ │
│ │ │ │ │ delete │ └──── dsh web --port 0 ─────┘ │
│ │ │ │ │ skills:list/create/ │ │ │
│ │ │ │ │ toggle │ │ │
│ │◀──│ harness:frame- │ │ harness:frame-loaded │ http://127.0.0.1:PORT │
└──────────────────┘ └──────────────────┘ └────────────────────┘ └─────────────────────────────────┘
flowchart LR
UI["渲染进程(sandbox)<br/>六 Tab 壳 index.html + renderer.ts"]
PRE["preload.cjs<br/>contextBridge → window.dshDesktop"]
MAIN["主进程 main.ts<br/>IPC handlers + harness 生命周期"]
CORE["src/core 纯逻辑<br/>harness / plugins / mcp / skills"]
RT["捆绑运行时 resources/<br/>Node v24.10.0 + @deepseek-ai/dsh@0.1.7-rc.2"]
WEB["dsh web → http://127.0.0.1:PORT"]
UI -->|IPC invoke| PRE --> MAIN
MAIN --> CORE
CORE -->|spawn detached 进程组| RT
RT --> WEB
WEB -->|iframe src| UI
生命周期:
启动 → registerIpc() → resolveDshExec()(打包内 runtime 优先,回退 PATH)
→ spawn dsh web --port 0(独立进程组)→ 解析 127.0.0.1:PORT → 轮询 HTTP 200(就绪超时 120s)
→ BrowserWindow(1280×800,sandbox + contextIsolation + preload.cjs)
→ 加载六 Tab 壳(file://dist/renderer/index.html)
→ renderer 经 IPC 取 harness URL → iframe 挂载官方 Web UI
→ 创建系统托盘;普通关闭按钮隐藏窗口,托盘菜单可重新显示或退出
退出 → 托盘「退出」/应用菜单 → will-quit → harness.stop():SIGTERM 进程组 → 2s 兜底 SIGKILL → app.quit
--smoke(不启 harness,DOM + 真实数据断言);--harness-smoke(真实 harness + iframe 加载断言)。dsh-desktop-hub/
├── src/
│ ├── main/main.ts # Electron 主进程:窗口 + 托盘 + IPC + harness 进程生命周期
│ ├── preload/preload.ts # contextBridge 白名单 API(sandbox,编译为 preload.cjs)
│ ├── renderer/ # 六 Tab 壳:index.html + renderer.ts(纯脚本,无模块)
│ └── core/ # 纯逻辑(可单测):harness.ts / plugins.ts / plugin-ops.ts / pnpm.ts / mcp.ts / skills.ts / feedback.ts / diagnostics.ts
├── tests/ # node --test 单测(从 dist/ 导入,需先 build)
├── scripts/
│ ├── build-preload.mjs # preload 以 CJS 编译并重命名为 .cjs
│ ├── copy-renderer.mjs # 拷贝 index.html → dist/renderer
│ ├── bundle-runtime.mjs # 下载 Node + npm 安装 dsh 到 resources/
│ ├── generate-icon.mjs # 生成品牌图标 build/icon.png(1024×1024,深蓝鲸鱼 + hub 节点)
│ ├── capture-demo.mjs # README 演示截图/GIF 捕获(合成演示 profile,不碰真实数据)
│ ├── verify.mjs # 一键门禁:契约 + 构建 + typecheck×2 + 单测
│ └── verify-m1.mjs # M1 实机验证:dsh web 启动 → HTTP 200 → 优雅停止
├── resources/ # 捆绑运行时(node_modules 忽略):nd/(Node 本体+shim)+ rt/(dsh runtime,锁文件入库)
├── assets/demo/ # README 截图与 GIF(脚本生成,可重跑)
├── build/icon.png # 应用图标(electron-builder 引用,macOS 自动转 icns)
├── release/ # electron-builder 产物(gitignore):DMG arm64 + NSIS EXE x64
├── dist/ # tsc 产物(gitignore)
├── tsconfig.json # 主进程 + core + preload(NodeNext,outDir dist)
├── tsconfig.preload.json # preload:CommonJS → dist/preload/preload.cjs
├── tsconfig.renderer.json # renderer:纯脚本 → dist/renderer
├── electron-builder.yml # appId com.dshdesktophub.app;mac DMG+zip(arm64);asar: false
└── package.json
| 命令 | 说明 |
|---|---|
npm install |
安装依赖(electron / typescript / electron-builder / electron-updater / yaml) |
npm run build |
三套 tsc(main+core → preload CJS → renderer)+ 拷贝 index.html,产物 dist/ |
npm run typecheck |
顺序检查 tsconfig.json 与 tsconfig.renderer.json(main + core + preload + renderer) |
npm test |
node --test 单测(自动发现 tests/,Windows 兼容;需先 build,测试从 dist 导入) |
npm start |
产品模式:启动 harness + 六 Tab 壳(需 dsh 可用且 ~/.dsh 存在 web profile);默认反馈地址为 https://feedback.flashingchen.xyz/v1/feedback,可用 DSH_FEEDBACK_ENDPOINT 覆盖 |
npm run smoke |
骨架冒烟(不启 harness):六 Tab DOM + 真实插件/MCP/skills 数据断言,截屏 artifacts/m0-smoke.png |
npm run smoke:harness |
真实 harness 冒烟:iframe 挂载 + 状态「已连接」,截屏 artifacts/m1-harness.png |
npm run verify:m1 |
M1 实机验证:真实启动 dsh web → HTTP 200 → 优雅停止 → 端口关闭无孤儿 |
npm run verify |
一键门禁:骨架契约 + 构建产物 + typecheck×2 + 单测全绿(npm test 已改为先 build) |
npm run build # 1. 构建 dist/
node scripts/bundle-runtime.mjs # 2. 捆绑运行时(首次/更新):下载 Node v24.10.0 +
# 安装 @deepseek-ai/dsh@0.1.7-rc.2 到 resources/
npx electron-builder --mac dmg zip --arm64 # 3. macOS:DMG 首装 + zip(签名版本的更新载荷)
npx electron-builder --win nsis --x64 # 4. Windows:release/DSH-Desktop-Hub-<version>-x64.exe
bundle-runtime.mjs:下载官方 Node v24.10.0(win/darwin/linux × x64/arm64)到 resources/nd,用捆绑 npm 以 --ignore-scripts 安装锁定版本 @deepseek-ai/dsh@0.1.7-rc.2 到 resources/rt;该版本提供官方账号授权 RPC;RUNTIME_TARGET=win32 可在 macOS 上交叉捆绑 Windows 运行时(含 .cmd shim 生成)。nd/*.zip 与 nd/*.tar.gz 只作为下载校验/复用缓存,不进入安装包。electron-builder.yml:files 含 dist/**/* + 解压后的 resources/**/*,并排除 Node 官方压缩缓存;asar: false(产物直放 resources/app,压低 Windows 安装路径深度);mac 目标 DMG + zip(arm64,签名后 zip 作为自动更新载荷)+ Windows 目标 NSIS(x64,assisted per-user,可选择安装目录);macOS 签名与公证由 Release CI 的 secrets 驱动。/usr/bin:/bin(无系统 node/dsh)的环境下可用捆绑运行时启动。旧版桌面端捆绑的 DSH 0.1.0-rc.6 只支持平铺凭据文件;较新的 DSH 会写入包含 version: 1、refs 和可选 records 的格式。共用同一个 DSH_HOME 时,旧运行时会将数字版本字段误当成凭据,报 the value for "version" ... must be a string 并退出。
捆绑运行时现锁定为 0.1.7-rc.2,直接支持版本化凭据格式,也由官方凭据提供器迁移合法的旧版平铺格式,并提供官方 DeepSeek 账号授权流程。无需手动给 version 加引号或删除凭据。请勿将凭据文件上传到 Issue。
实机回归:构建后,将 DSH_TEST_RESOURCES 设置为包含 rt/、nd/ 的运行时目录,使用捆绑 Node 执行 scripts/smoke-credentials.mjs。脚本在临时 DSH_HOME 中分别验证新版凭据原样保留、旧版凭据迁移、HTTP 200 与退出后端口关闭,不读取真实用户凭据。
推送 v* tag 后,GitHub Actions 自动完成发布(无需手动构建/上传):
verify → 捆绑运行时 → electron-builder.dmg / .dmg.blockmap / .zip / .zip.blockmap / .exe / .exe.blockmap / latest.yml / latest-mac.yml(双平台的 .zip / .exe 均为 electron-updater 更新载荷)git tag v0.3.0
git push origin v0.3.0
resources/采用「蓝图入库」:nd/node.exe、rt/package-lock.json提交进仓库;rt/node_modules(数百 MB)被忽略,由bundle-runtime.mjs在打包时从锁文件重建(npm ci)。
| 层级 | 内容 |
|---|---|
契约测试 tests/skeleton.test.mjs |
骨架文件齐全;package.json 脚本与 devDependencies;六 Tab 契约;contextIsolation + sandbox + nodeIntegration:false;tsconfig strict |
Harness tests/harness.test.mjs(5 例,不依赖真实 dsh) |
findDsh 可解析;dshHome 默认/覆盖;真实 web profile 发现(首个 bundle = dsh-base);忽略非 profile 目录;parseHarnessUrl |
Plugin tests/plugins.test.mjs(17 例) |
bundles ∪ dependencies 分类;排序稳定;buildPluginCommand 命令形态;normalizeInstallSpec GitHub 链接归一化;聚合仓库识别/拦截;pnpm ignored builds 与 Git prepare 授权、显式拒绝保护;runPluginOp 退出码 + 取消;deactivatePluginIfActive 幂等清理(remove 后残留激活行) |
Plugin 生命周期 tests/plugin-ops.test.mjs(2 例) |
启动立即返回 token;完成推送失败时仍可查询终态 |
权限策略 tests/permissions.test.mjs(7 例) |
Harness iframe 剪贴板权限精确放行;主帧、其他来源与未知权限继续拒绝 |
MCP tests/mcp.test.mjs(18 例) |
混合 stdio+http 解析;sse / 非法 serverName 警告;格式拒绝;YAML 与官方示例同构;${VAR} → !!js process.env.VAR;patch 提取 / 替换 / 编辑 / 删除保留注释;空 patch 新建 / 备份事务;!!js 行在 merge/update/delete 后保真(AST 行级操作 + $js 哨兵) |
Skills tests/skills.test.mjs(15 例) |
rank 合并 + shadowed;custom/bundled 根扫描;frontmatter 往返一致;kebab-case 校验落盘;可见性切换(含扁平 skill 文件名回退);zip/.skill 导入(含资源文件、包裹目录剥离、拒绝无 SKILL.md、目录穿越拒绝);GitHub URL 解析;ClawHub 固定版本导入 |
npm run smoke |
六 Tab 就绪;反馈面板/二维码存在;Plugin/Skills 面板加载完成;MCP 转换端到端(preview 含 dsh-mcp-client / streamable-http);不依赖特定 profile 数据 |
npm run smoke:plugin |
临时 DSH_HOME 中执行真实 dsh plugin remove,确认退出码与 package.json 依赖删除;不触碰用户 profile |
npm run smoke:harness |
harness 就绪;iframe 挂载 http://127.0.0.1:PORT;状态条「已连接」(#harness-status);重启后 iframe 重挂载到新端口 |
npm run verify:m1 |
真实 dsh web 启动并 HTTP 200(页面 ≥100B);优雅停止后端口关闭、无孤儿进程 |
ACTIVE_PROFILE 常量 = 'web',暂无 UI 切换(Roadmap 中)。dsh.bundle,npm 锁定精确版本,GitHub 尽量锁定 commit;ClawHub Skills 锁定版本后只写入 SKILL.md。https://github.com/yjh051108/dsh-routing-suite 不是单一 DSH bundle,根目录缺 package.json/dsh.bundle;Plugin Tab 会拒绝直接安装。应按仓库说明分别装配 injector、router-standard preset 与可选 mode-boost。pnpm-workspace.yaml.allowBuilds 并重试一次。该授权仍属于在本机执行第三方代码。!!js backtick 模板兼容:patch 中以反引号模板写 Bearer ${...}(官方 README 示例写法)超出 yaml 解析器语法,MCP 面板会拒绝解析并提示;请改用单引号字符串 !!js 'Bearer ${...}'(语义为字面字符串)或行级 process.env.X。${VAR} 自动转 !!js process.env.VAR;默认合并写入,可选全量替换),暂无 .mcp.json 文件选择器。resources/ 捆绑运行时约 586MB(gitignore),首包体积较大。https://feedback.flashingchen.xyz/v1/feedback,也可通过 DSH_FEEDBACK_ENDPOINT 覆盖;服务不可达时复制反馈仍可用。服务端启用 Cloudflare Rate Limiting(每个 edge client IP 每 60 秒 10 次,限流策略具有边缘位置级最终一致性)。私有 github-issue-server/ 不随公开仓库发布。~/.dsh/profiles/web/cordis.patch.yml(写入前自动 .bak-<ts> 备份);插件安装/移除真实执行 dsh plugin。MIT
CLASSIFICATION EVIDENCE
系统优先读取 GitHub Topics,再与站内分类词典和词根规则比对。当前命中: desktop-app。