桌面控制台 xiaowei2025cqu23phy/dsh-desktop
DeepSeek Harnessv0.2.0DeepSeek Harness 桌面端:内嵌 Web UI、AI 屏保替换系统屏保、全模型切换、手机 PWA…
32.9/100
综合分
4
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
自动兼容检查未通过:仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add xiaowei2025cqu23phy/dsh-desktop该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · platform
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 32 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装仓库 package.json 标记 private,未发布到 npm,需从源码安装
展开查看检查明细 ↓
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✓npm 包dsh-desktop @ 0.2.0
✓Node 引擎要求 >=22.13.0 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。
验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/20 23:01:57
安全扫描自动 · 静态分析源码v2.7.0🔵 扫描:含敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。
可执行外部命令读写/删除本地文件发起外部网络请求
查看扫描证据(共 166 处,展示前 120 条)
- 读取本地文件src/main/appearance.ts:41
if (!existsSync(dir)) return null - 读取本地文件src/main/appearance.ts:43
for (const name of readdirSync(dir)) { - 读取本地文件src/main/appearance.ts:46
if (!statSync(file).isFile()) continue - 读取本地文件src/main/appearance.ts:52
const existing = readFileSync(file) - 写入本地文件src/main/appearance.ts:85
mkdirSync(dir, { recursive: true }) - 读取本地文件src/main/appearance.ts:86
const buf = readFileSync(source) - 写入本地文件src/main/appearance.ts:89
if (duplicate === null) copyFileSync(source, target) - 写入本地文件src/main/appearance.ts:110
mkdirSync(dir, { recursive: true }) - 写入本地文件src/main/appearance.ts:114
if (duplicate === null) writeFileSync(target, buf) - 读取本地文件src/main/appearance.ts:135
if (existsSync(path)) return path - 写入本地文件src/main/appearance.ts:189
mkdirSync(dir, { recursive: true }) - 写入本地文件src/main/appearance.ts:198
copyFileSync(source, target) - 发起网络请求src/main/client.ts:101
const response = await fetch(`${this.baseUrl}/?token=${encodeURIComponent(token)}`, { - 发起网络请求src/main/client.ts:138
const response = await fetch(`${this.baseUrl}/api/respond`, { - 发起网络请求src/main/client.ts:166
const response = await fetch(`${this.baseUrl}/`, { - 发起网络请求src/main/client.ts:308
const response = await fetch(`${this.baseUrl}/api/${wireMethod}`, { - 发起网络请求src/main/client.ts:442
const response = await fetch(url, { - 发起网络请求src/main/client.ts:484
const response = await fetch(url, { signal, headers: { accept: 'text/event-stream' } }) - 读取本地文件src/main/config.ts:508
if (!existsSync(this.path)) return structuredClone(DEFAULTS) - 读取本地文件src/main/config.ts:510
const text = readFileSync(this.path, 'utf8').replace(/^ FEFF/, '') - 写入本地文件src/main/config.ts:553
copyFileSync(this.path, broken) - 读取本地文件src/main/config.ts:558
if (existsSync(backupPath)) { - 读取本地文件src/main/config.ts:560
const raw = JSON.parse(readFileSync(backupPath, 'utf8').replace(/^ FEFF/, '')) as Partial<AppConfig> - 写入本地文件src/main/config.ts:608
writeFileSync(target, JSON.stringify(safe, null, 2), 'utf8') - 读取本地文件src/main/config.ts:618
const parsed: unknown = JSON.parse(readFileSync(source, 'utf8').replace(/^ FEFF/, '')) - 写入本地文件src/main/config.ts:749
mkdirSync(dirname(this.path), { recursive: true }) - 写入本地文件src/main/config.ts:751
writeFileSync(tmp, text, 'utf8') - 读取本地文件src/main/config.ts:752
if (existsSync(this.path)) { - 写入本地文件src/main/config.ts:754
copyFileSync(this.path, `${this.path}.bak`) - 写入本地文件src/main/config.ts:759
renameSync(tmp, this.path) - 删除本地文件src/main/config.ts:763
rmSync(tmp, { force: true }) - 写入本地文件src/main/db.ts:96
copyFileSync(dbPath, backup) - 删除本地文件src/main/db.ts:97
rmSync(dbPath, { force: true }) - 写入本地文件src/main/db.ts:104
renameSync(`${dbPath}${suffix}`, `${backup}${suffix}`) - 读取本地文件src/main/db.ts:111
const candidates = existsSync(dbPath) ? [`${dbPath}.rebuilt-${stamp}`] : [dbPath, `${dbPath}.rebuilt-${stamp}`] - 读取本地文件src/main/gateway.ts:352
if (existsSync(keyPath) && existsSync(certPath) && existsSync(metaPath)) { - 读取本地文件src/main/gateway.ts:353
const key = readFileSync(keyPath, 'utf8') - 读取本地文件src/main/gateway.ts:354
const cert = readFileSync(certPath, 'utf8') - 读取本地文件src/main/gateway.ts:355
const meta = JSON.parse(readFileSync(metaPath, 'utf8')) as { ips?: unknown } - 写入本地文件src/main/gateway.ts:368
mkdirSync(dir, { recursive: true }) - 写入本地文件src/main/gateway.ts:369
writeFileSync(keyPath, key, 'utf8') - 写入本地文件src/main/gateway.ts:370
writeFileSync(certPath, cert, 'utf8') - 写入本地文件src/main/gateway.ts:371
writeFileSync(metaPath, JSON.stringify({ ips: currentIps, generatedAt: Date.now() }), 'utf8') - 读取本地文件src/main/gateway.ts:391
if (!existsSync(certPath)) return { enabled: true, fingerprint: null, hosts: [] } - 读取本地文件src/main/gateway.ts:392
const cert = readFileSync(certPath, 'utf8') - 发起网络请求src/main/gateway.ts:985
const response = await fetch(`${this.harness.baseUrl()}/api/respond`, { - 执行外部命令固定命令src/main/gateway.ts:1246
const summary = execFileSync('git', args, { encoding: 'utf8', timeout: 5000, maxBuffer: 128 * 1024, windowsHide: true }) - 执行外部命令固定命令src/main/gateway.ts:1248
const text = execFileSync('git', ['-C', path, 'diff', '--no-ext-diff', '--', '.'], { encoding: 'utf8', timeout: 5000, maxBuffer: 128 * 1024, windowsHi - 执行外部命令固定命令src/main/gateway.ts:1290
const text = execFileSync('git', args, { encoding: 'utf8', timeout: 5000, maxBuffer: 128 * 1024, windowsHide: true }) - 执行外部命令固定命令src/main/gateway.ts:1292
const diff = execFileSync('git', ['-C', path, 'diff', '--no-ext-diff', '--', '.'], { encoding: 'utf8', timeout: 5000, maxBuffer: 128 * 1024, windowsHi - 写入本地文件src/main/gateway.ts:1580
mkdirSync(realTarget, { recursive: true }) - 写入本地文件src/main/gateway.ts:1710
mkdirSync(userRoot, { recursive: true }) - 发起网络请求src/main/harness.ts:257
const response = await fetch(`http://127.0.0.1:${this.config.port}/`, { signal: controller.signal }) - 读取本地文件src/main/harness.ts:301
if (!existsSync(cwd)) mkdirSync(cwd, { recursive: true }) - 写入本地文件src/main/harness.ts:301
if (!existsSync(cwd)) mkdirSync(cwd, { recursive: true }) - 删除本地文件src/main/harness.ts:312
try { rmSync(logPath, { force: true }) } catch { } - 执行外部命令来自配置/变量src/main/harness.ts:317
? spawn(cmdLine, [], { env, cwd, windowsHide: true, stdio: ['ignore', outFd, outFd], shell: true }) - 执行外部命令来自配置/变量src/main/harness.ts:318
: spawn(command, args, { env, cwd, windowsHide: true, stdio: ['ignore', outFd, outFd] }) - 读取本地文件src/main/harness.ts:456
try { size = statSync(logPath).size } catch { return } - 执行外部命令固定命令src/main/harness.ts:481
execFile('taskkill', ['/pid', String(child.pid), '/T', '/F'], { windowsHide: true }, () => resolve()) - 读取本地文件src/main/harness.ts:491
if (!existsSync(dir)) mkdirSync(dir, { recursive: true }) - 写入本地文件src/main/harness.ts:491
if (!existsSync(dir)) mkdirSync(dir, { recursive: true }) - 执行外部命令固定命令src/main/harness.ts:593
exec('npx --version', { timeout: 4000 }, (error, stdout) => { - 读取本地文件src/main/harness.ts:620
if (explicit !== undefined && explicit.trim() !== '' && existsSync(explicit)) return explicit - 读取本地文件src/main/harness.ts:627
for (const hash of readdirSync(npxRoot)) { - 读取本地文件src/main/harness.ts:637
if (!existsSync(candidate)) continue - 写入本地文件src/main/index.ts:45
mkdirSync(dirname(path), { recursive: true }) - 删除本地文件src/main/index.ts:48
rmSync(`${path}.1`, { force: true }) - 写入本地文件src/main/index.ts:49
renameSync(path, `${path}.1`) - 读取本地文件src/main/index.ts:55
if (statSync(path).size > maxBytes) rotate() - 写入本地文件src/main/index.ts:59
let stream = createWriteStream(path, { flags: 'a' }) - 写入本地文件src/main/index.ts:72
stream = createWriteStream(path, { flags: 'a' }) - 读取本地文件src/main/ipc.ts:247
if (typeof path !== 'string' || path.trim() === '' || !existsSync(path) || !statSync(path).isDirectory()) return '路径无效' - 读取本地文件src/main/ipc.ts:279
if (existsSync(file)) { - 读取本地文件src/main/ipc.ts:281
const text = readFileSync(file, 'utf8').slice(0, 8192) - 读取本地文件src/main/ipc.ts:293
if (existsSync(pkgFile)) { - 读取本地文件src/main/ipc.ts:295
const pkg = JSON.parse(readFileSync(pkgFile, 'utf8')) as { scripts?: Record<string, string>; dependencies?: Record<string, string>; devDependencies?: - 读取本地文件src/main/ipc.ts:412
if (path === null || !existsSync(path)) return { dataUrl: null } - 写入本地文件src/main/ipc.ts:485
mkdirSync(target, { recursive: true }) - 写入本地文件src/main/ipc.ts:490
copyFileSync(from, join(target, name)) - 发起网络请求src/main/qq-bot.ts:718
const response = await net.fetch(url, { signal: AbortSignal.timeout(15000) }) - 发起网络请求src/main/qq-onboard.ts:62
const response = await net.fetch(`https://${PORTAL_HOST}${path}`, { - 写入本地文件src/main/remote-commands.ts:348
mkdirSync(dir, { recursive: true }) - 读取本地文件src/main/remote-commands.ts:1441
const entries = readdirSync(path, { withFileTypes: true }).slice(0, 40) - 读取本地文件src/main/remote-commands.ts:1460
if (!statSync(path).isFile()) return '不是文件,发「目录 <路径>」查看目录' - 读取本地文件src/main/remote-commands.ts:1461
const size = statSync(path).size - 读取本地文件src/main/remote-commands.ts:1463
const text = readFileSync(path, 'utf8') - 写入本地文件src/main/remote-commands.ts:1513
mkdirSync(this.exportDir, { recursive: true }) - 写入本地文件src/main/remote-commands.ts:1515
writeFileSync(path, markdown, 'utf8') - 执行外部命令固定命令src/main/screensaver.ts:260
execFile('reg', ['query', 'HKCU\\Control Panel\\Desktop', '/v', 'SCRNSAVE.EXE'], { windowsHide: true }, - 执行外部命令固定命令src/main/screensaver.ts:322
execFile('reg', [action, ...args], { windowsHide: true }, (error, stdout) => { - 执行外部命令固定命令src/main/screensaver.ts:335
execFile('reg', ['delete', 'HKCU\\Control Panel\\Desktop', '/v', name, '/f'], { windowsHide: true }, () => { - 执行外部命令固定命令src/main/screensaver.ts:347
execFile('reg', ['query', 'HKCU\\Control Panel\\Desktop', '/v', name], { windowsHide: true }, - 读取本地文件src/main/settings-heal.ts:47
if (!existsSync(path)) return { changed: 0, messages: [] } - 读取本地文件src/main/settings-heal.ts:50
doc = load(readFileSync(path, 'utf8')) ?? {} - 写入本地文件src/main/settings-heal.ts:92
copyFileSync(path, `${path}.bak`) - 写入本地文件src/main/settings-heal.ts:97
writeFileSync(path, dump(root, { lineWidth: 120, noRefs: true }), 'utf8') - 发起网络请求src/main/telegram-bot.ts:206
const response = await net.fetch(url, { - 发起网络请求src/main/telegram-bot.ts:246
const response = await net.fetch(url, { signal: AbortSignal.timeout(40000) }) - 请求外部主机api.telegram.orgsrc/main/telegram-bot.ts:349
const metaRes = await net.fetch(`https://api.telegram.org/bot${token}/getFile?file_id=${encodeURIComponent(fileId)}`, { signal: AbortSignal.timeout(15 - 发起网络请求src/main/telegram-bot.ts:349
const metaRes = await net.fetch(`https://api.telegram.org/bot${token}/getFile?file_id=${encodeURIComponent(fileId)}`, { signal: AbortSignal.timeout(15 - 请求外部主机api.telegram.orgsrc/main/telegram-bot.ts:354
const fileRes = await net.fetch(`https://api.telegram.org/file/bot${token}/${filePath}`, { signal: AbortSignal.timeout(30000) }) - 发起网络请求src/main/telegram-bot.ts:354
const fileRes = await net.fetch(`https://api.telegram.org/file/bot${token}/${filePath}`, { signal: AbortSignal.timeout(30000) }) - 发起网络请求src/main/updater.ts:38
const response = await fetch(CHECK_URL, { - 读取本地文件src/main/workspace-registry.ts:32
if (!existsSync(file)) throw new Error('找不到工作区注册表文件(可能从未初始化)') - 读取本地文件src/main/workspace-registry.ts:33
const parsed = JSON.parse(readFileSync(file, 'utf8')) as { global?: { archivedSessionIds?: string[] } } - 写入本地文件src/main/workspace-registry.ts:39
writeFileSync(tmp, JSON.stringify(parsed, null, 2), 'utf8') - 写入本地文件src/main/workspace-registry.ts:40
renameSync(tmp, file) - 发起网络请求src/remote/api.ts:60
return fetch(state.server + '/api/rpc', { - 发起网络请求src/remote/api.ts:80
return fetch(state.server + '/api/respond', { - 发起网络请求src/remote/api.ts:92
return fetch(state.server + '/api/action', { - 发起网络请求src/remote/app.ts:325
fetch(state.server + '/api/events/ticket', { - 发起网络请求src/remote/app.ts:747
fetch(state.server + '/api/diag', { - 发起网络请求src/remote/app.ts:941
fetch(state.server + '/api/info', { signal: AbortSignal.timeout(10000) }).then(function (r) { return r.json() }).catch(function () { return {} }), - 发起网络请求src/remote/app.ts:1642
fetch(state.server + '/api/wallpapers', { - 发起网络请求src/remote/app.ts:2002
fetch(state.server + '/api/action', { - 发起网络请求src/remote/fsbrowser.ts:167
return fetch(state.server + '/api/fs/ticket', { - 发起网络请求src/remote/panels.ts:19
fetch(state.server + '/api/tasks', { - 发起网络请求src/remote/sw.js:40
return fetch(event.request).then((resp) => { - 发起网络请求src/remote/wallpaper.ts:17
fetch((base.replace(/ +$/, '')) + '/api/info').then(function (res) {
扫描于 2026/11/4(0 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库
涉及外部主机:api.telegram.org
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
界面预览
3 张 · 点击查看大图功能亮点
- 内嵌WebUI
- AI屏保替换系统屏保
- 全模型切换
README
由 DeepSeek 最新模型翻译生成DeepSeek Harness Desktop
build
release
license
DeepSeek Harness 的桌面客户端(Electron + TypeScript)。
这是什么
harness 是个很能干的 agent 运行时,但它长在浏览器标签页里:你得记着开、记着看,离开电脑就只能干等。这个项目把它搬进桌面,并补上三件在浏览器里做不到的事:
- 它替你盯着——agent 卡住等审批时会主动来找你,不用守着标签页;空闲时还能顺手把屏幕变成一块屏保(纯壁纸+时钟,可顶替系统屏保);
- 它让手机也能用——扫个码,手机上发任务、看流式进展、一键批准;审批队列三端同一份,任一端答应即可;
- 它让 QQ / Telegram 成为你的遥控器——私聊发一句话就干活,干完主动汇报。
全程本地运行,密钥与会话不出你的机器。
目录
- 下载与安装 · 新手部署三步走
- 功能亮点 · 演示
- 快速开始 · 功能说明
- 开发 · 与 harness 的通信协议 · 已知限制
- 参考与致谢 · 支持与联系
许可证与使用条款
本项目遵循自定义许可协议(见 LICENSE),核心条款:
- 不得商用:任何衍生项目不得用于商业用途(DeepSeek 官方、本项目作者本人、有关项目贡献者及作者书面授权的个人/组织除外)。
展开完整文档(README 剩余 1 节)
DeepSeek Harness Desktop
build
release
license
DeepSeek Harness 的桌面客户端(Electron + TypeScript)。
这是什么
harness 是个很能干的 agent 运行时,但它长在浏览器标签页里:你得记着开、记着看,离开电脑就只能干等。这个项目把它搬进桌面,并补上三件在浏览器里做不到的事:
- 它替你盯着——agent 卡住等审批时会主动来找你,不用守着标签页;空闲时还能顺手把屏幕变成一块屏保(纯壁纸+时钟,可顶替系统屏保);
- 它让手机也能用——扫个码,手机上发任务、看流式进展、一键批准;审批队列三端同一份,任一端答应即可;
- 它让 QQ / Telegram 成为你的遥控器——私聊发一句话就干活,干完主动汇报。
全程本地运行,密钥与会话不出你的机器。
目录
- 下载与安装 · 新手部署三步走
- 功能亮点 · 演示
- 快速开始 · 功能说明
- 开发 · 与 harness 的通信协议 · 已知限制
- 参考与致谢 · 支持与联系
许可证与使用条款
本项目遵循自定义许可协议(见 LICENSE),核心条款:
- 不得商用:任何衍生项目不得用于商业用途(DeepSeek 官方、本项目作者本人、有关项目贡献者及作者书面授权的个人/组织除外)。
- 必须开源:任何衍生项目必须公开源代码,并同样遵守本协议。
- 更宽松授权:作者保留对特定个人或组织授予更宽松协议条款的权利(包括商业使用许可),须经作者明确书面授权;未获书面授权者一律适用本协议默认条款。
- 第三方依赖组件(DeepSeek Harness、@tencent-connect/qqbot-nodejs、Electron 等)遵循各自许可证,详见 THIRD_PARTY_NOTICES.md 与下文「参考与致谢」。
隐私说明
- 发布包(安装包 exe / zip)只包含应用代码与运行库,不包含任何本地配置、壁纸、访问令牌、API 密钥、会话数据或日志。
- 用户的壁纸、令牌与配置保存在系统用户目录(%APPDATA%/DeepSeek Harness Desktop),永远不会进入安装包或提交到仓库。
- 安装程序不会删除用户数据:卸载时保留 %APPDATA% 下的配置与壁纸(deleteAppDataOnUninstall = false)。
- 若从源码自行构建,构建产物同样不涉及上述用户数据。
- 发布包随附 LICENSE 与 THIRD_PARTY_NOTICES.md(第三方组件清单),位于安装目录的 resources/ 下;免安装版在 resources/ 同级。
下载与安装
从 GitHub Releases 下载,三种形态任选:
| 形态 | 文件 | 说明 |
| 安装版(推荐) | DeepSeek-Harness-Desktop-Setup-.exe | NSIS 安装程序,双击安装,自动创建开始菜单与桌面快捷方式,可选安装目录 |
| 便携版 | DeepSeek.Harness.Desktop-.win.zip | 解压即用,免安装,适合 U 盘携带 |
| 源码版 | 克隆仓库npm install && npm start | 自行构建 |
安装版卸载时保留用户配置与壁纸(不会删除 %APPDATA% 数据);如需彻底清理请手动删除 %APPDATA%/DeepSeek Harness Desktop。
系统要求:Windows x64、Node.js ≥ 22.13(建议 24 LTS)。
打包版自带 Electron 运行时,数据库用其内置的 node:sqlite,不需要额外装数据库。系统 Node 只在两种情况下用到:源码构建/跑测试,以及用 npx 托管拉起 harness。
提示:先运行 npx @deepseek-ai/dsh web 并配置好模型密钥,再打开桌面端,体验最佳。
🆕 新手部署三步走(给第一次装的朋友)
安装包不包含智能体运行时与任何配置/密钥(隐私设计),新电脑只需三步:
1. 装 Node.js(LTS)
- 打开 https://nodejs.org/zh-cn/download,下载 Windows Installer(.msi,LTS 版 22 或 24),一路「下一步」;
- 或 PowerShell 执行 winget install OpenJS.NodeJS.LTS;
- 装完重开终端,node -v 能看到版本号即成功;
- 国内网络慢可先执行 npm config set registry https://registry.npmmirror.com;
2. 装本桌面端:下载上方安装版(或便携版解压),双击安装;
3. 配模型密钥:打开桌面端 → 打开内置 Web UI(「设置 → 服务 → 打开 Web UI」)→ 设置 → Models,填入模型 API Key(如 DeepSeek 官方 Key);密钥只存在本机。
不需要手动安装 dsh:桌面端首次启动会用 npx 自动下载智能体运行时;想用 QQ 机器人再加一步:QQ 开放平台注册机器人,把 AppID/Secret 填入「设置 → QQ 机器人」(见 QQ-BOT.md)。
📖 完整安装、配置、手机端与 QQ 机器人使用步骤见 实操指南(汉英双语),接入钉钉/飞书/Home Assistant/iOS 捷径等更多方式见 接入指南。
🤖 QQ 机器人完整指南(部署/平台权限/指令集/FAQ)见 docs/QQ-BOT.md;📱 手机 PWA 特色功能见 docs/PWA.md。
✨ 功能亮点
- 内嵌 Web UI:原生控制条 + 内嵌完整 harness Web UI(会话、工具、插件全功能)。官方 / 本地魔改双实例自由嵌入:内置页面与顶栏 🧪 按钮可在「官方版(npx 发布)」与「本地自建 fork 版」之间切换,各自独立端口/DSH_HOME/凭据;实例来源与能力自动探测——只装官方 dsh 的用户功能完整可用,魔改增强(侧边栏文件浏览、文本/图片预览等)探测到才显示,官方实例上不会出现不可用的入口。
- 屏保(可替换系统屏保):空闲 N 分钟自动全屏显示壁纸与时钟,点击/按键/滚轮/触摸立即退出(鼠标移动不退出,避免轻微抖动就闪退);纯展示,不跑 agent 任务,不消耗 token 与 CPU;可注册为 Windows 系统屏保,注册前自动备份原设置、取消时恢复。
- 手机 PWA 遥控:扫码配对(自动填地址+令牌),手机上发任务、看流式进展、停止任务;审批/提问卡片一键应答——agent 卡住等你批准时不再“失联”。可添加到主屏幕当 App 用。远程访问仅面向可信局域网,默认启用 2 小时自动关闭;禁止使用内网穿透、端口转发或公网反向代理暴露 Harness。令牌即访问权:有效令牌的手机/脚本首次连接即可用;因此拿到令牌就等于拿到这台电脑的控制权,真正的保护是「仅局域网可达 + 令牌保密」。控制权在桌面端:可一键暂停全部连接、对单个设备暂停/拉黑(被拉黑或已暂停的设备令牌正确也拒绝)、锁屏/睡眠自动暂停,并支持只监听当前局域网 IP(默认 0.0.0.0 全网卡,含 VPN/虚拟网卡)。
- PWA 离线外壳(可选 HTTPS):设置里可开启 HTTPS(自签证书,含本机全部局域网 IP)。手机信任一次证书后即可注册 Service Worker——应用壳可缓存、断网也能打开,并支持「添加到主屏幕」。明文 HTTP 下浏览器不允许注册 SW,此时 PWA 以普通标签页形态工作。
- 常驻状态条:顶栏三个实时徽标——运行中的活动数 ▶、今日 Token 用量 💰、已连接的远程设备数 📱,不用发指令或翻设置就能看到当前状态;手机端同样有(运行中/用量两项)。
- 首次启动引导:首次打开显示三步检查单(① harness 是否就绪 ② 模型是否配好 ③ 开始使用),就地显示每步的实时状态并可直接跳到模型配置,不用翻文档猜下一步。
- QQ / Telegram 机器人通道:私聊发指令即干活(群聊只聊天、不响应任何指令);打通主动推送(QQ 交互后 48h 窗口),任务完成、失败、要审批都会主动找你;低风险审批带「允许/拒绝」内联按钮,点一下即批(高风险操作转桌面端确认);访问控制为平台侧关闭「允许被添加为好友」(首次启用强制确认)+ 可选openid 白名单(留空 = 不限制)。
- QQ 机器人体验(0.6.0+):未指定工作区的任务自动并入「默认任务会话」(不再刷屏;重启后仍复用同一会话);指定工作区用 任务 @工作区名 或「进入工作区后直接发」;进展 显示阶段(思考/工具/输出/完成+产物提示);任务过程默认静默、播报 按需开;机器人对话(私聊/群聊)集中放在可见的「机器人对话」工作区;群聊仅聊天、不响应任何指令(含查询)并带安全提醒;归档的会话可随时 恢复 ;完整指令集与部署/权限指引见 QQ-BOT.md。
- 默认对话模式:机器人开启后,普通消息直接进入纯对话(不绑定工作区),无需任何指令前缀。
- 各种模型选择:快捷切换默认模型(DeepSeek 官方、OpenAI、Anthropic 及 37+ 目录 Provider),添加自定义 OpenAI 兼容网关(公司网关、Ollama 本地等),密钥安全写入 credentials 存储。
- 三端独立壁纸 + 拼豆像素滤镜:主窗口 / 手机 / 屏保各配一张,导入自己的图片一键拼豆化(本地处理,不碰版权);内置五套壁纸包(深空 / 拼豆 / 星野 / 几何 / 赛博)一键应用到三端。
- harness 托管:自动探测已运行的 dsh web,没有则自动拉起(默认 npx @deepseek-ai/dsh web),崩溃自动重启。
- AI 活动中心与本地记忆:统一查看远程任务状态、来源和工作区;按工作区保存本地项目记忆(简介/约定/常用命令/笔记),可从 README 与 package.json 一键生成草稿,默认关闭注入,仅在用户明确启用后加入匹配目录的任务上下文。
- 可信审计与通知分级:任务、审批、提问和记忆使用形成可导出、可清空的本地时间线;审批、问题、成功和失败通知可独立开关并支持勿扰时段。
- 串行任务调度队列:任务持久化入队,已有任务运行中时新任务自动排队;失败自动重试(指数退避 30s/60s,最多 2 次),应用重启后中断任务标记失败可手动重试;工作台「任务队列」面板支持取消与立即重试。
- 工作台三页导航:顶栏「工作台 / 工作区 / 会话」——工作台聚合待处理审批、活动中心、工作区健康、任务队列、用量与审计;工作区页按工作区查看健康状态、编辑本地记忆与关联活动;设置抽屉只保留真正配置项。
- SQLite 本地存储:活动、审计与任务队列存入本地 SQLite(userData/local.db,零额外依赖),事务写入与索引查询,旧 JSON 数据首次启动自动迁移。
- 文件预览增强:手机 PWA 预览支持超大文本分片加载与图片直接查看(≤2MB),仍受工作区白名单限制。
- 系统托盘常驻:开机自启、一键启动屏保、快速打开 Web UI、更新提示。
演示
主窗口与壁纸穿透(主窗口壁纸会透出到内嵌对话页):
主窗口演示
手机 PWA 远程控制(扫码连接 → 选择工作区与模型 → 一键运行任务 → 实时流式查看):
手机远程控制演示
屏保(空闲全屏显示壁纸与时钟,壁纸可自定义):
屏保演示
该演示录制于屏保还能展示 agent 实时画面的时候;当前屏保只显示壁纸与时钟。
演示使用内置“鲸鱼海洋”示例壁纸录制,不涉及任何个人壁纸或会话内容。
快速开始
npm install
npm start # 构建并启动桌面端
首次启动会自动探测 http://127.0.0.1:3080:已有 harness 则直接接入;没有则自动执行 npx --yes @deepseek-ai/dsh web --port 3080 拉起(需要 Node.js ≥ 22.13)。
提示:先运行 npx @deepseek-ai/dsh web 并配置好模型密钥,再打开桌面端,体验最佳。
功能说明
模型切换
顶栏的「默认模型」下拉框列出当前已配置的全部 Provider 与模型:
- 选择后通过 session.selectModel 写入,harness 会同时持久化为新会话的默认模型,热生效、无需重启。
- 「设置 → 添加自定义 Provider」可添加 OpenAI 兼容网关(预设:DeepSeek 官方 / OpenAI / Ollama 本地 / 自定义),支持「从网关拉取模型」自动发现模型列表;API Key 通过 credentials.set 安全写入,不会明文落盘到配置。
- 更完整的模型管理(密钥配置、目录 Provider、推理参数)在嵌入式 Web UI 的「设置 → Models」页面。
屏保
「设置 → 外观与扩展 → 屏保」:
| 配置 | 说明 |
| 启用空闲检测 | 空闲达到阈值后自动进入全屏屏保 |
| 空闲几分钟后触发 | 默认 5 分钟 |
屏保是纯屏保:全屏显示壁纸与时钟,不启动任何 agent 任务、不调用模型、不消耗 token。屏保的职责是遮挡屏幕,不是替你在无人看管时跑任务——那类需求请用「定时任务」或机器人通道,它们有独立的开关与配额。
退出方式:点击、按键、滚轮、触摸均可立即退出;鼠标移动不触发退出(避免鼠标抖动导致屏保闪退)。主进程也监听输入事件,即使页面卡住也能退出。
防循环弹出:系统屏保拉起(/s)与空闲检测自动激活都受 5 分钟退出冷却约束——用户点击退出后,5 分钟内不会被系统/空闲检测再次拉起,避免“关了又弹”。用户主动点击顶栏按钮不受此限制。
注册为 Windows 系统屏保:点击「注册为系统屏保」后,Windows 的锁屏/超时机制会用 /s 参数拉起本应用直接进入全屏模式(注册表 HKCU\Control Panel\Desktop\SCRNSAVE.EXE,无需管理员权限;注册前自动备份原设置,取消时恢复。重复点击只更新超时值,不会覆盖已保存的原设置备份)。
Harness 服务
- auto(默认):先探测已运行实例(接入 3080 或自定义端口),没有则托管启动。
- external:仅连接外部地址(如局域网内的另一台机器)。
- managed:始终由桌面端托管启动,启动命令支持模板一键选择:官方最新版(npx @deepseek-ai/dsh 自动下载)、官方指定版本(如 @deepseek-ai/dsh@0.1.1-rc.2)、本机仓库脚本(浏览选择 run-local.cmd),也可手动输入自定义命令(如 pnpm dsh web --port {port})。
外观 · 壁纸
「设置 → 外观」可分别自定义:
- 主窗口壁纸:顶栏与设置抽屉呈现毛玻璃透出效果(不影响内嵌 Web UI 的显示区域)。
- 屏保壁纸:全屏背景图,带可调遮罩(0.1~0.9)保证文字可读。
- 图片会复制到应用数据目录(%APPDATA%/DeepSeek Harness Desktop/wallpapers),原图移动/删除不影响;支持 png/jpg/jpeg/gif/webp/bmp。
手机远程控制(PWA)
「设置 → 远程访问」启用后,桌面端开一个局域网网关(默认端口 3082,可修改,Bearer token 认证):
1. 手机与电脑连同一 WiFi,用手机扫设置面板中的二维码(或浏览器访问 http://:3082)
2. 手机首次连接即直接可用(令牌即访问权),设备会自动登记到桌面端「已连接设备」列表,便于之后暂停或拉黑
3. 连接后页面顶部有常驻状态条(运行中的活动数 ▶、今日 Token 用量 💰),与桌面端同一份数据
安装为 App(PWA):
- 默认走明文 HTTP。手机浏览器把 http://192.168.x.x 视为非安全上下文,不会注册 Service Worker——此时 PWA 仍可正常当浏览器标签页使用(在线收发消息/任务/审批),只是不缓存应用壳;
- 想要完整离线外壳与「添加到主屏幕」:桌面端 设置 → 远程访问 → 启用 HTTPS(自签证书,含本机全部局域网 IP 的 SAN,缓存在 userData)。手机首次访问会提示证书不受信任,手动信任一次即可,之后自动注册 Service Worker。设置面板会显示证书 SHA-256 指纹与覆盖的地址,信任前可据此核对;换网络/网卡导致 IP 变化时证书会自动重新签发,届时按新指纹再信任一次。
- 详见 docs/PWA.md。
安全策略:远程访问默认启用 2 小时后自动关闭(可在设置中调整过期策略),到期需在桌面端重新启用;仅可信局域网可达,禁止内网穿透/公网转发。有效令牌即访问权——拿到令牌的人或程序能像你一样操控这台电脑,所以令牌必须保密,泄露后立即在设置里重新生成。
控制权全在桌面端:一键暂停全部连接(会立即断开已建立的连接,而不是等到下次请求)、单设备暂停/拉黑(拉黑或暂停后令牌正确也拒绝)、锁屏/睡眠自动暂停、可只监听当前局域网 IP。
手机端功能:
- 新对话(工作区优先):与 harness Web 一致——先选择/新建工作区,再创建对话;新会话自动落入所选工作区分组(预设工作区根也可直接作为工作区)
- 会话:列表、历史、实时流式收发、停止任务;消息模式可选「排队」或「插入发送(打断当前等待)」
- 权限预设:新建会话可指定「工作区可写」或「完全访问」(对应 harness 的 /permission 命令,需新版 harness)
- 任务:输入描述 + 选择工作区 + 选择模型,一键运行并实时查看
- 工作区:列表、新建、浏览文件夹;文件预览:文本/Markdown/图片/视频(mp4/webm)/音频/PDF——浏览器不支持内嵌 PDF 时提供「新窗口打开 / 下载」
- 壁纸:内置壁纸一键切换,也可从手机相册上传图片设为壁纸
- 设置:预设工作区根目录(查看/移除/浏览添加)、定时任务、重启 Harness 等
- 断线自动重连:网络短暂断开(飞行模式/弱网)自动指数退避重连,恢复后自动回到原会话
- 安全:Bearer token 认证 + RPC 白名单 + 文件浏览白名单(仅工作区/预设根内,越权 403),仅局域网可达
QQ 机器人远程控制(可选)
「设置 → QQ 机器人」填入在 QQ 开放平台 注册机器人得到的 AppID/AppSecret 即启用(留空自动禁用),并在开放平台关闭机器人的「允许被添加为好友」(首次启用时会强制确认:只有你本人能把机器人加为好友/拉进群)。想再收紧可填「允许的用户 openid」(留空 = 不限制;QQ 的 openid 识别需企业主体,个人主体拿不到自己的 openid,发一条消息即可在设置页状态里看到自己的),也可设置默认工作区/目录(任务命令未指定时自动使用)。在 QQ 私聊机器人发送指令(发送任意无法识别的消息,机器人会自动回复完整指令集与示例):
| 指令 | 说明 | 示例 |
| 状态 / 会话 / 工作区 / 模型 | 查询类 | 状态、工作区 |
| 任务 | 默认工作区执行任务 | 任务 分析这个仓库的架构 |
| 任务 @ | 指定工作区执行 | 任务 @qqbot 修复登录 bug |
| 任务 目录: | 指定目录执行(仅限工作区/预设根目录内) | 任务 目录:D:/work 写一个脚本 |
| 进入 | 纯对话:不绑定工作区/目录,朋友模式 | 进入 |
| 进入 | 在该工作区对话(助手模式) | 进入 qqbot、进入 D:/work |
| (对话模式) | 直接发消息即可,无需前缀;agent 回复自动推送给你,全程无"已发送"噪音;退出 结束 | 帮我看看项目里的 TODO → 💬 回复 → 退出 |
| 进展 | 任务实时进展(状态/工具统计/最新输出) | 进展 session-xxxxxxxx |
| 停止 / 打开 | 停止任务 / 查看会话内容 | 停止 session-xxxxxxxx |
| 允许 / 拒绝 | 审批应答:agent 请求权限时允许/拒绝(多个待审批时带会话 id) | 允许、拒绝 session-xxxxxxxx |
| 选 | 选择题应答:回答 agent 提问(多选 选 1 3,自定义 选 自定义:…,多题批次 #2 选 1) | 选 2 |
| 定时 | 定时任务:定时 10分钟 检查更新(10 分钟/5m/2小时/1天 一次性;定时 每天9:00 写日报 每天) | 定时 10分钟 检查更新 |
| 定时列表 / 取消定时 | 查看/取消已排定时任务 | 取消定时 2 |
| 目录 / 文件 | 浏览工作区目录 / 查看文本文件(白名单内) | 目录 D:/work、文件 D:/work/README.md |
| 导出 | 将会话导出为 Markdown(保存在桌面端exports/ 目录) | 导出 session-xxxxxxxx |
| 用量 | 今日用量统计(会话数/回合数/Token) | 用量 |
| 角色 | 角色扮演:设置对话模式角色(仅纯对话生效,与朋友提示词叠加);角色 无 清除 | 角色 你是温柔的英语老师 |
| (私聊发图片) | 图片理解:对话模式下直接发图片,agent 看图分析 | 发一张截图 →看看这张图有什么问题 |
按钮操作:任务启动后自动附带「⏹ 停止 / 📋 进展 / 📖 打开」按钮;审批推送带「✅ 允许 / ❌ 拒绝」;单选提问带选项按钮——点一下即操作/应答,基本不用打字。
模式提示词:任务 xxx 等指令下,agent 以专业助手身份工作;对话模式下以朋友口吻聊天;两套提示词可在桌面端「设置 → QQ 机器人」自定义(留空 = 不注入)。角色扮演:角色 为对话模式叠加角色(如“你是温柔的英语老师”),角色 无 清除,在桌面端同样可预设默认角色。
图片理解:对话模式下直接给机器人发图片(私聊),agent 自动“看图说话”,无需任何额外配置。
对话可见性:QQ/Telegram 的对话会话在手机 PWA 侧边栏「🤖 机器人对话」分组置顶显示,点开即可看到完整聊天记录并实时流式同步。
典型流程:工作区 查看列表 → 进入 qqbot → 连续对话 → 退出。
基于 @tencent-connect/qqbot-nodejs(WebSocket 长连接),协议参考 QQ 开放平台 API v2 文档(消息收发/消息类型/事件订阅)与 Agent QQBot 接入指南。QQ 官方机器人以被动回复为主,但与机器人交互后 48 小时内支持主动推送;长回复自动分段。agent 需要审批/提问时会主动推送通知(QQ 交互窗口内与 Telegram 均可即时送达;低风险审批带「允许/拒绝」内联按钮,点一下即可应答;高风险操作——写入/删除/执行等——只转桌面端确认,聊天侧「允许」无效),推送失败时待办仍会附加在下次消息的回复末尾提醒。手机端同样支持审批:会话中出现审批/提问卡片,一键允许/拒绝或作答。QQ/Telegram 均可开启默认对话模式:非指令消息直接进入纯对话(不绑定工作区),无需先发「进入」。
开发
npm run build # tsc 编译 main/preload/renderer/remote 到 dist/,再 esbuild 打包 PWA、复制静态资源
npm start # 构建 + electron .
npm test # 离线测试套件(无需 harness):指令解析、RPC 协议、审批流、任务队列、SQLite、网关断开
npm run lint # ESLint(flat config,含类型感知规则)
npm run smoke # 冒烟测试:验证 RPC 客户端与模型目录(需 harness 运行中)
npm run pack # 打包安装版 + 免安装 zip 到 release/
npm run pack:zip # 只出免安装 zip
npm run pack:portable # 只出单文件 portable exe
类型检查分三套(主进程 / 渲染进程 / PWA);另有 tsconfig.scripts.json 对 scripts/.mjs 做 checkJs 扫描。CI 在 push 与 PR 上跑:三套类型检查 + 脚本 checkJs + 构建 + ESLint + npm test。
脚本 checkJs 只以 scripts/ 目录下的报错判定成败:scripts/.mjs 会 require 编译产物 dist/,而 dist/ 是 tsc 的降级输出(类型断言在 emit 时被擦除),对它做 checkJs 得到的报错不代表源码有问题——源码已由上面三套类型检查完整覆盖。CI 因此显式过滤掉 dist/ 的噪声。
调试开关:
- --remote-debugging-port=9222 启动时启用 CDP,可用 node scripts/cdp-eval.mjs '' 检查页面状态。
- --ss-debug 启动时,屏保窗口保持打开(禁用空闲退出),便于调试屏保画面。
- node scripts/mux-test.mjs 端到端管线测试:设置默认模型 → 建会话 → 发提示 → 订阅事件流(会消耗少量模型调用)。
结构
src/main/ 主进程 index.ts 入口(单实例锁、/s 屏保参数、事件桥、启动编排) config.ts 配置读写与老配置迁移(userData/config.json) ipc.ts IPC 处理器注册 harness.ts harness 进程托管(探测/接管/拉起/健康检查/崩溃重启) client.ts HTTP RPC 客户端(POST /api/ + mux 事件流) rpc-protocol.ts RPC 协议适配器(typert 斜杠 / 旧版点协议的能力表与参数壳) gateway.ts 局域网网关(Bearer token、设备暂停/拉黑、RPC 与文件白名单、SSE) tls-cert.ts 自签 X.509 证书生成(纯 node:crypto,供 PWA 离线外壳用) remote-commands.ts 远程指令处理器(QQ/TG/PWA 共用:任务、审批、提问、会话、定时) remote-util.ts 远程指令的纯工具函数(可单测) qq-bot.ts QQ 适配器(门禁、按钮身份、推送、诊断) qq-commands.ts QQ 指令解析(纯函数,可单测) qq-onboard.ts QQ 扫码绑定流程 telegram-bot.ts Telegram 适配器 models.ts 模型目录、默认模型切换、自定义 Provider 向导 screensaver.ts 屏保(空闲检测、全屏窗口、系统屏保注册) appearance.ts 三端壁纸与拼豆滤镜 workspace-registry.ts 工作区注册表与路径白名单 db.ts SQLite 本地存储(活动/审计/任务队列,含旧 JSON 迁移) event-hub.ts mux 事件广播 notifications.ts 通知分级与勿扰时段 updater.ts 版本检查 diagnostics.ts 诊断信息收集 settings-heal.ts harness 配置自愈(改写前自动备份) tray.ts / windows.ts 托盘与窗口管理 src/preload.ts 预加载(IPC 桥,渲染进程不直接接触 Electron) src/renderer/ 渲染进程(经典脚本,无打包器) index.html 主窗口(控制条 + 工作台 + webview) main.ts 主窗口逻辑 screensaver.html 全屏屏保(壁纸 + 时钟) src/remote/ 手机 PWA(网关直接托管) index.html app.ts 单页应用 sw.js 离线外壳(仅 HTTPS 下可注册) manifest.webmanifest + 图标 scripts/ 构建、冒烟、端到端与离线测试脚本
与 harness 的通信协议
桌面端直接实现 deepseek-harness 的 HTTP RPC 协议,并兼容两代 harness:
- 官方 @deepseek-ai/dsh 0.1.2-rc.1+(typert 斜杠协议):探测时自动协商协议与参数壳,支持浏览器 token 鉴权(?token= 换持久 cookie);模型目录走 session/modelCatalog、Provider 目录走 llm/listProviders / llm/listConfigurableProviders,自定义 Provider 写入走 settings/update + settings/mutate + credentials/set。
- 旧版 / 自建 fork(点协议):llm.models、llm.providers、workspace.*、host.describe 等方法自动回退兼容。
- 一元调用:POST /api/,body 为 {type:'client-request', rpcId, method, payload},响应 {type:'server-response', rpcId, result};回环地址免令牌。
- 事件流:GET /api/events.mux(SSE / WebSocket 自动协商),推送 session/event 等帧,手机 PWA 与机器人通道据此实时渲染。
- 会话历史回放(官方版无 session.history):先取 session/list 的 projections.asOfSeq,再调 session/page 拉取记录,过滤出 message 级事件回放给手机 / QQ / 屏保。
- 关键方法:session.list/create/prompt/cancel/rename/selectModel、session.modelCatalog、session.page、llm.listProviders/listConfigurableProviders/discoverModels、settings.update/mutate、credentials.set、workspace.create/rename/delete。
协议细节随 harness 演进可能变化;桌面端对参数壳(typert:_request / request / 平铺)按方法自适应,并在官方版缺失旧方法时提供降级或桥接(如 workspace.list 由会话 cwd 合成)。
⚠️ 本项目已冻结:只做必要的正确性修复,不再跟随 harness 版本演进。
实测适配的版本、超出边界时的降级行为、以及哪些上游变更会导致失效,见 兼容性与冻结说明。
已知限制
- 审批只有「允许一次 / 拒绝」两种选择,这不是界面偷懒:@deepseek-ai/dsh-user-approval 里 ApprovalOutcome 是封闭枚举(allowed-once / rejected / cancelled / unavailable),协议里不存在「一直允许」。想减少审批次数请用 DSH 的权限预设(permission presets)。
- 审批卡片能展示的信息上限是「工具名 + 原因」两项文本:协议里审批请求的客户端可见字段只有 toolName、callId、reason,不含工具参数。原因字段通常包含完整命令,手机端已按 markdown 完整渲染(过长可展开)。
- 手机浏览器普遍禁用 iframe 内嵌 PDF 预览,手机端提供「新窗口打开 / 下载」两种方式查看 PDF。
- 屏保为纯展示(壁纸 + 时钟),不承载交互;需要看 agent 在做什么请回到主窗口的 Web UI 或手机 PWA。
- 系统屏保注册仅支持 Windows(注册表方案,注册前自动备份原设置,取消时恢复);macOS/Linux 可用内置空闲检测模式。
- 事件流传输自动协商:旧版 harness 只接受 WebSocket(HTTP 返回 426),新版额外支持 SSE;两者都兼容。
- 屏保窗口内禁用了系统休眠时的自动唤醒逻辑(跟随系统屏保行为)。
参考与致谢 / Acknowledgements
本项目站在众多优秀开源项目的肩膀上,在设计与实现中参考、依赖并致谢以下项目及其维护者:
| 项目 | 贡献 | 许可 |
| deepseek-ai/deepseek-harness | 核心 Agent 引擎与 HTTP RPC / 事件流协议(dsh-host-apiproxy:一元 RPC、mux 事件流、settings/credentials/llm 域),桌面端、手机 PWA 与机器人通道都建立在它之上 | MIT |
| tencent-connect/qqbot-nodejs | QQ 开放平台机器人 Node SDK:WebSocket 网关、消息收发、主动推送(48h 窗口)与内联键盘审批按钮 | MIT |
| tencent-connect/qqbot-agent-sdk | 扫码登录(onboard:create_bind_task / AES-GCM 凭据解密)与审批内联键盘的协议参考实现 | MIT |
| tencent-connect/dsh-qqbot | 官方 QQ×DSH 插件:指令集、会话映射与事件展示的设计参考 | 各自许可 |
| electron 与 electron-builder | 桌面壳与打包分发 | MIT |
| node-qrcode | 手机扫码配对与 QQ 扫码登录的二维码生成 | MIT |
QQ 机器人通道的协议细节参考了 QQ 开放平台 API v2 文档 与 Agent QQBot 接入指南。
同时感谢 DeepSeek Harness 社区与本项目测试过程中提供反馈的各位使用者。完整第三方组件与许可证清单(含间接依赖)见 THIRD_PARTY_NOTICES.md,发布包内随附一份。
如果你也是这些项目的维护者——谢谢你们的工作,让这个项目成为可能 🙏
支持与联系 / Support
觉得有用?欢迎加入内测交流群反馈问题、提出建议;也可以请作者喝杯咖啡 ☕
| 内测交流群(QQ) | 微信赞赏 |
| QQ 群 | 微信赞赏码 |预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
xiaowei2025cqu23phy/dsh-desktop
DeepSeek Harness 桌面端:内嵌 Web UI、AI 屏保替换系统屏保、全模型切换、手机 PWA…
相关插件 · 平台集成
智能体工程课walkinglabs/learn-harness-engineering
一门项目制课程,教你搭建环境、管理状态、做验证、加控制机制,让 AI 编程智能体稳定干活。
★ 21,155已汉化DSH
71.7
视频翻译配音liuzhao1225/YouDub-webui
开源视频本地化工作台:导入视频,识别、翻译并逐句克隆原声,生成字幕和配音成片。
★ 5,792已汉化Cordis
71.4
失败经验库Ikalus1988/MisakaNet
📚 零依赖、由 git 支撑的微课程库,让 AI 智能体异步分享并检索经过验证的调试经验。| https://misakanet.org
★ 550已汉化DSH
71.2
IM 机器人接入xmanrui/dsh-im
让 DeepSeek Harness 触手可及 Connecting DeepSeek Harness
★ 3,170已汉化DeepSeek 客户端
71
桌面智能体工作区freestylefly/wesight
WeSight 是开源桌面控制台,面向本地 AI 智能体。它帮你安装或复用 Claude…
★ 933已汉化MCP
71
中国平台研究引擎Jesseovo/last30days-skill-cn
给 AI Agent 的中文互联网研究 Skill:检索 8 大平台最近 30…
★ 2,041已汉化DSH
70.7
这是你的仓库?认领条目