🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

桌面客户端 Antony-Jia/deepseek-harness-desktop

DeepSeek Harnessv0.2.0
Antony-Jia67 天前有提交已提供中文文档扫描:含敏感能力

在 Windows 上启动并管理 DSH 运行时与插件

28.9/100
综合分
1
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/9/18 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查未通过:缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Antony-Jia/deepseek-harness-desktop
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么[目录]—
dsh 原生插件 · dev
暂无时间戳·判据 →
装得上吗[实装验证]✓
本站已真实安装成功
非静态推断
L4 · 真实安装等级说明 →
数据截至 2026/09/25·判据 →
安全吗[自动扫描]—
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
数据截至 2026/11/05·判据 →
还在维护吗[仓库]—
更新放缓:最近一次提交在 67 天前
暂无时间戳·判据 →
图例:✓ 通过! 需注意— 未判定 / 无数据· 「未判定」= 本站尚无数据,不代表插件有问题
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →

可信度证据

安装兼容性检查需源码安装

缺少 main/exports/bin 入口声明;仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-desktop @ 0.2.0
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✗入口文件缺少入口声明

源码安装时若 pnpm 拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑。

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/9/23 21:28:22

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件写入剪贴板(不计风险)读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 99 处,展示前 91 条)
  • 发起网络请求
    dsh-plugin-template/lib/client.js:77
    fetch('/dsh-plugin-template/echo?text=' + encodeURIComponent('你好,DSH'))
  • 读取本地文件
    market/akshare-market-analysis/lib/index.js:242
    if (!existsSync(this.runtimePath)) throw new Error(`AKShare sidecar 未随插件包提供:${this.runtimePath}`)
  • 读取本地文件
    market/akshare-market-analysis/lib/index.js:352
    return readFileSync(SKILL_PATH, 'utf8').replace(/^--- * ? [ ]*? ? --- * ? ?/, '')
  • 发起网络请求
    market/akshare-market-analysis/lib/index.js:417
    const result = await manager.request(endpointFor(name), normalized, exec?.signal)
  • 发起网络请求
    market/amap-map-assistant/lib/client.js:125
    fetch(BASE_PATH + '/settings', { cache: 'no-store' })
  • 发起网络请求
    market/amap-map-assistant/lib/client.js:143
    return fetch(BASE_PATH + '/settings', {
  • 发起网络请求
    market/amap-map-assistant/lib/client.js:169
    var request = fetch(BASE_PATH + '/state?sessionId=' + encodeURIComponent(sessionId), { cache: 'no-store' })
  • 发起网络请求
    market/amap-map-assistant/lib/client.js:375
    fetch(BASE_PATH + '/bootstrap', { cache: 'no-store' })
  • 读取密钥环境变量
    market/amap-map-assistant/lib/index.js:114
    const webServiceKey = String(process.env.DSH_DESKTOP_MCP_AMAP_MAPS_API_KEY || process.env.AMAP_MAPS_API_KEY || '').trim()
  • 读取密钥环境变量
    market/amap-map-assistant/lib/index.js:116
    jsApiKey: String(process.env.DSH_DESKTOP_MCP_AMAP_JS_API_KEY || process.env.AMAP_JS_API_KEY || '').trim(),
  • 读取本地文件
    market/amap-map-assistant/lib/index.js:197
    content: readFileSync(SKILL_PATH, 'utf8').replace(/^--- * ? [ ]*? ? --- * ? ?/, ''),
  • 写入本地文件
    market/amap-map-assistant/lib/session-storage.js:44
    await mkdir(this.sessionsDir, { recursive: true })
  • 读取本地文件
    market/amap-map-assistant/lib/session-storage.js:52
    raw = await readFile(path, 'utf8')
  • 写入本地文件
    market/amap-map-assistant/lib/session-storage.js:64
    try { await rename(path, quarantine) } catch { }
  • 写入本地文件
    market/amap-map-assistant/lib/session-storage.js:77
    await writeFile(temp, payload, { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    market/amap-map-assistant/lib/session-storage.js:79
    await rename(temp, path)
  • 删除本地文件
    market/amap-map-assistant/lib/session-storage.js:84
    await rm(path, { force: true })
  • 写入本地文件
    market/amap-map-assistant/lib/session-storage.js:85
    await rename(temp, path)
  • 删除本地文件
    market/amap-map-assistant/lib/session-storage.js:87
    await rm(temp, { force: true }).catch(() => {})
  • 读取本地文件
    market/amap-map-assistant/lib/settings-storage.js:59
    if (!existsSync(this.path)) return { present: false, jsApiKey: '', securityJsCode: '' }
  • 读取本地文件
    market/amap-map-assistant/lib/settings-storage.js:61
    return { present: true, ...normalize(JSON.parse(readFileSync(this.path, 'utf8'))) }
  • 写入本地文件
    market/amap-map-assistant/lib/settings-storage.js:76
    await mkdir(dirname(this.path), { recursive: true })
  • 写入本地文件
    market/amap-map-assistant/lib/settings-storage.js:78
    await writeFile(temporary, `${JSON.stringify(next, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    market/amap-map-assistant/lib/settings-storage.js:80
    await rename(temporary, this.path)
  • 删除本地文件
    market/amap-map-assistant/lib/settings-storage.js:83
    await rm(this.path, { force: true })
  • 写入本地文件
    market/amap-map-assistant/lib/settings-storage.js:84
    await rename(temporary, this.path)
  • 删除本地文件
    market/amap-map-assistant/lib/settings-storage.js:86
    await rm(temporary, { force: true }).catch(() => {})
  • 发起网络请求
    market/conversation-knowledge-map/lib/client.js:134
    var response = await fetch(BASE + path, init)
  • 写入剪贴板
    market/conversation-knowledge-map/lib/client.js:650
    try { navigator.clipboard && navigator.clipboard.writeText(pending.question) } catch (_) {}
  • 读取本地文件
    market/conversation-knowledge-map/lib/index.js:311
    content: readFileSync(SKILL_PATH, 'utf8').replace(/^--- * ? [ ]*? ? --- * ? ?/, ''),
  • 读取本地文件
    market/conversation-knowledge-map/lib/workspace-storage.js:36
    return JSON.parse(await readFile(filePath, 'utf8'))
  • 写入本地文件
    market/conversation-knowledge-map/lib/workspace-storage.js:44
    await writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`, 'utf8')
  • 写入本地文件
    market/conversation-knowledge-map/lib/workspace-storage.js:58
    await mkdir(stagingDir, { recursive: true })
  • 写入本地文件
    market/conversation-knowledge-map/lib/workspace-storage.js:65
    await rename(item.final, backup)
  • 写入本地文件
    market/conversation-knowledge-map/lib/workspace-storage.js:71
    await rename(item.temp, item.final)
  • 删除本地文件
    market/conversation-knowledge-map/lib/workspace-storage.js:74
    for (const backup of backups) if (backup.hadOld) await rm(backup.backup, { force: true })
  • 删除本地文件递归
    market/conversation-knowledge-map/lib/workspace-storage.js:75
    await rm(stagingDir, { recursive: true, force: true })
  • 删除本地文件
    market/conversation-knowledge-map/lib/workspace-storage.js:77
    for (const filePath of installed) await rm(filePath, { force: true }).catch(() => {})
  • 写入本地文件
    market/conversation-knowledge-map/lib/workspace-storage.js:79
    if (backup.hadOld) await rename(backup.backup, backup.final).catch(() => {})
  • 删除本地文件递归
    market/conversation-knowledge-map/lib/workspace-storage.js:81
    await rm(stagingDir, { recursive: true, force: true }).catch(() => {})
  • 读取本地文件
    market/deepseek-vision-bridge/lib/index.js:33
    content: readFileSync(SKILL_PATH, 'utf8')
  • 发起网络请求
    market/dsh-open-workspace/lib/client.js:517
    return fetch(path, options).then(function (res) {
  • 发起网络请求
    market/dsh-open-workspace/lib/client.js:675
    fetch('/open-workspace/list?path=' + encodeURIComponent(path))
  • 发起网络请求
    market/dsh-open-workspace/lib/client.js:741
    fetch('/open-workspace/read?path=' + encodeURIComponent(entry.path))
  • 发起网络请求
    market/graph-job-orchestrator/lib/client.js:54
    return fetch(BASE + path, config).then(function (response) {
  • 读取本地文件
    market/graph-job-orchestrator/lib/executors.js:174
    const canonicalCwd = existsSync(cwd) ? realpathSync(cwd) : cwd
  • 读取本地文件
    market/graph-job-orchestrator/lib/executors.js:185
    const canonicalAbsolute = existsSync(absolute) ? realpathSync(absolute) : absolute
  • 读取本地文件
    market/graph-job-orchestrator/lib/executors.js:189
    if (options.requireExisting && !existsSync(absolute)) throw new OutputContractError(`artifactRefs[${index}] 文件不存在:${path}`)
  • 读取本地文件
    market/graph-job-orchestrator/lib/index.js:328
    content: readFileSync(SKILL_PATH, 'utf8'),
  • 写入本地文件
    market/graph-job-orchestrator/lib/storage.js:24
    mkdirSync(dirname(target), { recursive: true })
  • 写入本地文件
    market/graph-job-orchestrator/lib/storage.js:26
    writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\n`, { encoding: 'utf8', flag: 'wx' })
  • 写入本地文件
    market/graph-job-orchestrator/lib/storage.js:28
    renameSync(temporary, target)
  • 删除本地文件
    market/graph-job-orchestrator/lib/storage.js:34
    try { unlinkSync(target) } catch (removeError) { if (removeError?.code !== 'ENOENT') throw removeError }
  • 写入本地文件
    market/graph-job-orchestrator/lib/storage.js:35
    renameSync(temporary, target)
  • 删除本地文件
    market/graph-job-orchestrator/lib/storage.js:37
    try { unlinkSync(temporary) } catch { }
  • 读取本地文件
    market/graph-job-orchestrator/lib/storage.js:44
    return JSON.parse(readFileSync(filePath, 'utf8'))
  • 读取本地文件
    market/graph-job-orchestrator/lib/storage.js:51
    if (existsSync(filePath)) {
  • 写入本地文件
    market/graph-job-orchestrator/lib/storage.js:65
    mkdirSync(dirname(target), { recursive: true })
  • 写入本地文件
    market/graph-job-orchestrator/lib/storage.js:66
    appendFileSync(target, `${JSON.stringify(value)}\n`, { encoding: 'utf8' })
  • 读取本地文件
    market/graph-job-orchestrator/lib/storage.js:71
    if (!existsSync(filePath)) return []
  • 读取本地文件
    market/graph-job-orchestrator/lib/storage.js:73
    const lines = readFileSync(filePath, 'utf8').split(/ ? /)
  • 读取本地文件
    market/graph-job-orchestrator/lib/storage.js:89
    return readdirSync(directory, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name)
  • 读取本地文件
    market/graph-job-orchestrator/lib/storage.js:228
    return readdirSync(directory, { withFileTypes: true })
  • 发起网络请求
    market/multi-agent-roundtable/lib/client.js:187
    var response = await fetch(BASE + path, init)
  • 读取本地文件
    market/multi-agent-roundtable/lib/config-storage.js:18
    if (!existsSync(path)) return fallback
  • 读取本地文件
    market/multi-agent-roundtable/lib/config-storage.js:19
    const document = JSON.parse(readFileSync(path, 'utf8'))
  • 写入本地文件
    market/multi-agent-roundtable/lib/config-storage.js:36
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    market/multi-agent-roundtable/lib/config-storage.js:38
    await writeFile(temporary, `${JSON.stringify(document, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    market/multi-agent-roundtable/lib/config-storage.js:39
    await rename(temporary, path)
  • 读取本地文件
    market/multi-agent-roundtable/lib/conversation-storage.js:114
    if (!existsSync(path)) return normalizeConversationIndex(null, legacyDiscussions)
  • 读取本地文件
    market/multi-agent-roundtable/lib/conversation-storage.js:115
    const document = JSON.parse(readFileSync(path, 'utf8'))
  • 写入本地文件
    market/multi-agent-roundtable/lib/conversation-storage.js:122
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    market/multi-agent-roundtable/lib/conversation-storage.js:124
    await writeFile(temporary, `${JSON.stringify(document, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    market/multi-agent-roundtable/lib/conversation-storage.js:125
    await rename(temporary, path)
  • 读取本地文件
    market/multi-agent-roundtable/lib/index.js:106
    return readFileSync(SKILL_PATH, 'utf8').replace(/^--- * ? [ ]*? ? --- * ? ?/, '')
  • 读取本地文件
    market/multi-agent-roundtable/lib/role-schema.js:37
    const document = JSON.parse(readFileSync(path, 'utf8'))
  • 发起网络请求
    plugins/dsh-desktop-bridge/lib/client.js:129
    return fetch(url, {
  • 读取密钥环境变量
    plugins/dsh-desktop-bridge/lib/index.js:8
    const TOKEN = process.env.DSH_DESKTOP_TOKEN
  • 读取本地文件
    plugins/dsh-desktop-bridge/lib/index.js:236
    try { entries = readdirSync(skillsPath, { withFileTypes: true }) } catch { continue }
  • 读取本地文件
    plugins/dsh-desktop-bridge/lib/index.js:269
    try { entries = readdirSync(root, { withFileTypes: true }) } catch { return [] }
  • 读取本地文件
    plugins/dsh-desktop-bridge/lib/index.js:278
    const target = statSync(entryPath)
  • 读取本地文件
    plugins/dsh-desktop-bridge/lib/index.js:296
    try { source = readFileSync(path, 'utf8') } catch { return undefined }
  • 读取本地文件
    plugins/dsh-desktop-bridge/lib/index.js:338
    try { source = readFileSync(path, 'utf8') } catch { return undefined }
  • 读取本地文件
    plugins/dsh-desktop-bridge/lib/index.js:383
    try { return JSON.parse(readFileSync(path, 'utf8')) } catch { return undefined }
  • 写入本地文件
    plugins/dsh-desktop-bridge/lib/index.js:518
    mkdirSync(dirname(path), { recursive: true })
  • 写入本地文件
    plugins/dsh-desktop-bridge/lib/index.js:520
    writeFileSync(temporary, JSON.stringify({
  • 写入本地文件
    plugins/dsh-desktop-bridge/lib/index.js:526
    renameSync(temporary, path)
  • 删除本地文件
    plugins/dsh-desktop-bridge/lib/index.js:528
    rmSync(path, { force: true })
  • 写入本地文件
    plugins/dsh-desktop-bridge/lib/index.js:529
    try { renameSync(temporary, path) } catch (renameError) {
  • 删除本地文件
    plugins/dsh-desktop-bridge/lib/index.js:530
    rmSync(temporary, { force: true })
  • 发起网络请求
    plugins/dsh-desktop-bridge/lib/index.js:541
    const response = await fetch(CONTROL + path, {
扫描于 2026/11/5(1 天前) · 范围 全包扫描 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

社区实装还没有人打卡 · 装过的第一个就是你
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 启动管理运行时进程
  • 提供桌面外壳体验

DSH Desktop 是 Windows/Tauri 的轻量外壳,包着 @deepseek-ai/dsh 的 npm 运行时,只管运行时进程和桌面体验,不复制也不重编上游 DSH 代码。

README

由 DeepSeek 最新模型翻译生成
DSH Desktop English: README.md DSH Desktop 是一个基于 Windows/Tauri 的桌面客户端,用于管理并运行 @deepseek-ai/dsh npm 运行时,同时提供桌面体验、界面主题和经过协议校验的插件市场;客户端不会内置或重新构建上游 DSH 代码。 DSH Desktop 首页 下载与安装 当前 Windows x64 安装包位于 GitHub v0.1.8 Release: 下载 DSH Desktop Windows 安装包 安装包内置经过 SHA256 校验的 Node.js v24.19.0 x64 运行时,因此目标电脑不需要预先安装 Node.js、npm 或 npx。首次安装桌面托管版 DSH 时,仍需要联网从 npm registry 下载所选的 @deepseek-ai/dsh 版本。 安装后启动 DSH Desktop,在首页启动 DSH 或进入已经运行的 DSH 页面。客户端会通过内置 WebView 打开本地回环 Web UI,不需要手动复制地址到浏览器。 桌面客户端提供的能力 - 通过独立的 Node 进程启动 DSH,并使用明确的工作目录。
展开完整文档(README 剩余 1 节)
DSH Desktop

English: README.md

DSH Desktop 是一个基于 Windows/Tauri 的桌面客户端,用于管理并运行 @deepseek-ai/dsh npm 运行时,同时提供桌面体验、界面主题和经过协议校验的插件市场;客户端不会内置或重新构建上游 DSH 代码。

DSH Desktop 首页

下载与安装

当前 Windows x64 安装包位于 GitHub v0.1.8 Release:

下载 DSH Desktop Windows 安装包

安装包内置经过 SHA256 校验的 Node.js v24.19.0 x64 运行时,因此目标电脑不需要预先安装 Node.js、npm 或 npx。首次安装桌面托管版 DSH 时,仍需要联网从 npm registry 下载所选的 @deepseek-ai/dsh 版本。

安装后启动 DSH Desktop,在首页启动 DSH 或进入已经运行的 DSH 页面。客户端会通过内置 WebView 打开本地回环 Web UI,不需要手动复制地址到浏览器。

桌面客户端提供的能力

- 通过独立的 Node 进程启动 DSH,并使用明确的工作目录。
- Web/控制端口仅监听回环地址,使用随机 Bearer token,并通过配置了 KILL_ON_JOB_CLOSE 的 Windows Job Object 管理子进程。
- 支持系统中的本地 DSH,也支持独立的桌面托管 DSH。托管版本安装在独立目录中,不会覆盖系统 npm。
- 提供面向 Web profile 的插件市场,可搜索、安装和卸载通过清单协议校验的插件与主题包,并按安装、启用和协议兼容状态控制入口。
- 缓存经过校验的市场扫描结果,在顶栏提示待更新插件,并提供主动刷新远程目录的入口。
- 将 @p-dsh-market/conversation-knowledge-map 纳入校验市场,可把用户选择的同工作区对话整理为思维导图或只读知识图谱。
- 在插件市场旁提供 MCP 管理入口,通过 DSH 官方 MCP Client 注册工具;内置默认关闭的 Tavily Search、Firecrawl 与仅限本机的 Chrome DevTools,也支持用户添加 stdio/npm、本地命令或 Streamable HTTP MCP。
- 自定义 MCP 添加对话框跟随亮色、暗色、系统主题和已安装 Theme Pack 外观变化。
- 支持受控的桌面顶栏扩展、工作区文件浏览、终端、股票行情分析和多 Agent 圆桌讨论。
- 市场内置 DeepSeek 视觉桥接插件,为不支持图片输入的模型提供 /vision 命令和受控的 deepseek_vision_analyze 工具,只分析 DSH 会话中已持久化的图片。
- 顶栏插件操作支持响应式溢出菜单,并提供标准的首页和重启入口。
- 顶栏提供统一的 Skills 管理入口,可查看市场插件、用户级 Skills 以及当前工作区的 .dsh/skills 和 .agents/skills。
- 在恢复首页显示启动、安装、更新和失败日志。
- 提供可见的系统托盘图标、原生通知桥接和无边框窗口控制。
- 将窗口位置、尺寸、最大化状态、外观模式、界面皮肤、背景强度和减少效果偏好保存到 %LOCALAPPDATA%/dsh-desktop/state.json。
- 提供受控的 Neon Agent Theme Pack 预览、15 秒确认回退、本地背景资源和默认主题恢复;主题包不能携带任意 CSS、selector、远程资源或桌面命令。

MCP 管理

插件市场旁的 MCP 页面用于管理默认关闭的 Tavily Search、Firecrawl 和 Chrome DevTools 预设,并允许用户添加 stdio npm 包、已有的本地命令或 Streamable HTTP 服务。npm 包会在首次启用并启动 DSH 时由桌面托管的 Node/npm 自动安装;启用后通过官方 @deepseek-ai/dsh-mcp-client 注册为 mcp____* 工具。API Key、环境变量和 HTTP Header 使用 Windows DPAPI 保护且不会回显;页面会显示每个服务的连接状态、工具数量和工具名称。
Chrome DevTools 只通过本机 stdio 启动隔离的本地 Chrome,不提供远程 URL。
可选的 autoConnect 开关允许连接当前本地 Chrome;关闭时仍使用独立隔离浏览器。
页面顶部的启动诊断会分别显示本地 Node/npm、npm Registry 下载能力、精确版本缓存、web profile 注入和实际工具注册状态,便于区分下载失败与 MCP 子进程启动失败。

Skills 管理

顶栏 Skills 入口会汇总已安装市场插件、~/.dsh/skills、~/.agents/skills 以及当前工作区 .dsh/skills、.agents/skills 中的 Skills。桌面端通过 DSH 官方 Skills provider 管理可控 Skills 的启用状态,同时保留不可管理的上游 Skills 只读展示。

DeepSeek 视觉桥接

市场内置 @p-dsh-market/deepseek-vision-bridge,用于让不支持图片输入的模型分析会话图片。安装插件并重启 DSH 后,附加图片并执行 /vision 你的问题;插件会通过受控的 deepseek_vision_analyze 工具调用官方 deepseek-official/deepseek-v4-flash-vision-exp 模型。未显式指定图片时,默认分析最近一条含图片消息中的全部图片;显式选择时最多支持 8 张。插件只读取 DSH 已持久化的会话附件,不读取任意本地路径或远程 URL;原生视觉模型会直接看图并隐藏桥接工具。/vision 会把原始问题和图片作为正常用户消息写入聊天流,桥接指令只进入系统提示词,因此界面会显示用户气泡和图片画廊。

对话知识视图

市场内置 @p-dsh-market/conversation-knowledge-map。用户可以从同一工作区明确选择多个历史对话,生成有阶段段落的思维导图、带来源回溯的只读知识图谱,或同时生成两者。生成前必须经过应用内确认,支持 Provider/Model 与提取范围选择,并将图数据和来源元数据保存到 .g-dsh-market-knowledge/,不会复制完整聊天正文。
知识视图还提供进度时间线、失败诊断、分批生成、缩放、节点间距和一跳局部筛选。

界面预览

插件市场

为 DSH Web profile 搜索、查看、安装和卸载经过协议校验的插件与主题包。

DSH 插件市场

工作区文件与终端

在 DSH 对话旁浏览工作区文件并预览 Markdown、HTML 与代码,同时可在下方直接使用集成的 PowerShell 终端。

工作区文件浏览器与终端

股票行情分析插件

AKShare 插件可在对话消息和右侧面板中展示行情快照、历史 K 线与技术分析结果。

AKShare 股票行情分析插件

多 Agent 圆桌讨论

多个独立 Agent 可按自定义角色并行讨论、交叉评审,通过 Markdown 实时输出消息,并由主持人生成最终总结。

多 Agent 圆桌讨论

运行时与数据位置

- %LOCALAPPDATA%/dsh-desktop/state.json 保存固定版本、最后可用版本、可用更新、运行来源、桌面偏好设置和窗口边界。
- 托管 DSH 版本保存在 %LOCALAPPDATA%/dsh-desktop/runtimes/。
- 应用日志保存在 %LOCALAPPDATA%/dsh-desktop/logs。
- 当安装包包含内置 Node 资源时,客户端首次启动会将它复制到 %LOCALAPPDATA%/dsh-desktop/node。

本地开发

仓库使用 Node/npm 执行检查,并使用 Tauri CLI 启动开发客户端:

npm install
npm run check
npm test
npm run tauri dev

开发模式默认使用系统 PATH 中的 Node;如果 runtime-assets/node/ 中存在 portable Node,则优先使用该目录。Node 二进制由 Git 忽略,仓库只跟踪 runtime-assets/node/README.md。

构建安装包

如需复现当前 release,先下载官方 Node.js 24 x64 portable ZIP,完成校验后将内容直接解压到 runtime-assets/node/:

- 文件:node-v24.19.0-win-x64.zip
- SHA256:57f71ab3652e797d84acddc79c81cc9ff1c6ddb2a1974cdb83f00fee9bff4c73
- 官方发布目录:

该目录必须包含 node.exe 和 node_modules/npm/bin/npm-cli.js。然后执行:

npm run check
npm test
npm run build

Windows NSIS 安装包生成在:

src-tauri/target/release/bundle/nsis/DSH Desktop_0.1.8_x64-setup.exe

.gitignore 会忽略 src-tauri/target/、dist/bundle/、portable Node 二进制和安装包文件;这些内容只作为 release 构建输入或输出,不应提交到源码仓库。

当前 Tauri 配置会嵌入 WebView2 bootstrapper,代码签名由最终分发环境负责。

运行时 Smoke Test

独立运行时探针位于 scripts/e1-runtime-smoke.ps1。它会将 rc.6 安装到临时目录、检查回环页面,并且只删除该临时目录。
预览分享卡片长什么样 ↓Antony-Jia/deepseek-harness-desktop
分享 · DeepSeek Harness Hub
Antony-Jia/deepseek-harness-desktop

在 Windows 上启动并管理 DSH 运行时与插件

这个插件是你维护的吗?
作者本人可认领并核对本条目;认领通过后,详情页会显示「作者已认领」标记。
认领条目 →
回到顶部