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

托盘客户端 Mos0526/DSHarness-Tray

DeepSeek Harnessv0.1.1
Mos052646 天前有提交已提供中文文档扫描:含敏感能力

在系统托盘里启动、更新并管理 DSH 插件

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

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

自动兼容检查未通过:仓库 package.json 标记 private,未发布到 npm,需从源码安装。以下命令仍可尝试,但可能失败。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Mos0526/DSHarness-Tray
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · desktop
装得上吗
本站已在 dsh 0.2.1-rc.5 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 46 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查需源码安装

仓库 package.json 标记 private,未发布到 npm,需从源码安装

展开查看检查明细 ↓

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

✓npm 包dsh-tray @ 0.1.1
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

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

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/12 15:09:19

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

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

可执行外部命令读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 115 处,展示前 82 条)
  • 读取本地文件
    main.js:97
    return existsSync(TRAY_PNG) ? TRAY_PNG : ICON_PNG;
  • 读取本地文件
    main.js:101
    const png = existsSync(join(__dirname, "icon-256.png")) ? join(__dirname, "icon-256.png") : ICON_PNG;
  • 读取本地文件
    main.js:166
    if (existsSync(full)) return full;
  • 读取本地文件
    main.js:181
    return JSON.parse(readFileSync(statePath(), "utf8"));
  • 写入本地文件
    main.js:188
    mkdirSync(app.getPath("userData"), { recursive: true });
  • 写入本地文件
    main.js:189
    writeFileSync(statePath(), JSON.stringify(state, null, 2));
  • 执行外部命令来自配置/变量
    main.js:222
    const output = execFileSync(reg, ["query", key, "/v", LEGACY_LOGIN_ITEM_NAME], {
  • 执行外部命令来自配置/变量
    main.js:228
    execFileSync(reg, ["delete", key, "/v", LEGACY_LOGIN_ITEM_NAME, "/f"], {
  • 读取本地文件
    main.js:275
    ].find((path) => existsSync(path));
  • 执行外部命令来自配置/变量
    main.js:303
    const out = execFileSync(node, ["-p", "process.versions.node"], {
  • 读取本地文件
    main.js:316
    return Boolean(node && existsSync(node) && npmCliFor(node) && readNodeMajor(node) >= MIN_NODE_MAJOR);
  • 写入本地文件
    main.js:369
    mkdirSync(home, { recursive: true });
  • 写入本地文件
    main.js:372
    if (existsSync(source)) copyFileSync(source, join(home, name));
  • 删除本地文件递归
    main.js:423
    rmSync(target, { recursive: true, force: true });
  • 写入本地文件
    main.js:424
    renameSync(nested, target);
  • 删除本地文件递归
    main.js:448
    rmSync(join(destRoot, "node"), { recursive: true, force: true });
  • 写入本地文件
    main.js:451
    mkdirSync(destRoot, { recursive: true });
  • 执行外部命令来自配置/变量
    main.js:505
    return spawn(command, args, {
  • 发起网络请求
    main.js:1147
    const response = await fetch(url, {
  • 发起网络请求
    main.js:1159
    const response = await fetch(url, {
  • 删除本地文件递归
    main.js:1270
    rmSync(dest, { recursive: true, force: true });
  • 删除本地文件递归
    main.js:1271
    rmSync(staging, { recursive: true, force: true });
  • 删除本地文件
    main.js:1272
    rmSync(`${dest}.upgrade-state.json`, { force: true });
  • 删除本地文件递归
    main.js:1279
    rmSync(dir, { recursive: true, force: true });
  • 发起网络请求
    main.js:1729
    const response = await fetch(settled.readyUrl, {
  • 删除本地文件递归
    src/plugin-center/operations.js:128
    rmSync(stagingProfile, { recursive: true, force: true });
  • 读取本地文件
    src/plugin-center/operations.js:129
    if (!existsSync(activeProfile)) return false;
  • 写入本地文件
    src/plugin-center/operations.js:130
    mkdirSync(dirname(stagingProfile), { recursive: true });
  • 删除本地文件
    src/plugin-center/operations.js:138
    rmSync(require("node:path").join(stagingProfile, "node_modules"), {
  • 写入剪贴板
    src/plugin-center/ipc.js:122
    clipboard.writeText(value);
  • 写入本地文件
    src/homes/io.js:7
    mkdirSync(dir, { recursive: true });
  • 读取本地文件
    src/homes/io.js:13
    return JSON.parse(readFileSync(file, "utf8"));
  • 写入本地文件
    src/homes/io.js:25
    writeFileSync(tmp, `${JSON.stringify(value, null, 2)}\n`, "utf8");
  • 写入本地文件
    src/homes/io.js:27
    renameSync(tmp, file);
  • 写入本地文件
    src/homes/io.js:29
    copyFileSync(tmp, file);
  • 删除本地文件
    src/homes/io.js:30
    rmSync(tmp, { force: true });
  • 读取本地文件
    src/homes/io.js:36
    return existsSync(file);
  • 删除本地文件递归
    src/homes/io.js:40
    rmSync(target, { recursive: true, force: true });
  • 读取本地文件
    make-ico.js:31
    buf: fs.readFileSync(path.join(dir, `icon-${size}.png`)),
  • 写入本地文件
    make-ico.js:34
    fs.writeFileSync(path.join(dir, "icon.ico"), ico);
  • 发起网络请求
    src/catalog/fetch.js:20
    return fetch(url, init);
  • 写入本地文件
    src/catalog/fetch.js:43
    mkdirSync(dirname(filePath), { recursive: true });
  • 读取本地文件
    src/catalog/fetch.js:48
    return JSON.parse(readFileSync(filePath, "utf8"));
  • 写入本地文件
    src/catalog/fetch.js:56
    writeFileSync(filePath, JSON.stringify(value, null, 2));
  • 读取本地文件
    src/catalog/index.js:37
    return JSON.parse(readFileSync(filePath, "utf8"));
  • 写入本地文件
    src/catalog/index.js:44
    mkdirSync(dirname(filePath), { recursive: true });
  • 写入本地文件
    src/catalog/index.js:45
    writeFileSync(filePath, JSON.stringify(value, null, 2));
  • 发起网络请求
    src/catalog/translate.js:28
    return fetch(url, init);
  • 删除本地文件递归
    src/dsh-upgrade/promote-staging.js:14
    rmSync(dir, { recursive: true, force: true });
  • 写入本地文件
    src/dsh-upgrade/promote-staging.js:34
    mkdirSync(staging, { recursive: true });
  • 读取本地文件
    src/dsh-upgrade/promote-staging.js:43
    if (!existsSync(staging)) {
  • 读取本地文件
    src/dsh-upgrade/transactional-upgrade.js:48
    const parsed = JSON.parse(readFileSync(file, "utf8"));
  • 写入本地文件
    src/dsh-upgrade/transactional-upgrade.js:61
    mkdirSync(dirname(dest), { recursive: true });
  • 写入本地文件
    src/dsh-upgrade/transactional-upgrade.js:68
    writeFileSync(statePath(dest), JSON.stringify(next, null, 2));
  • 删除本地文件递归
    src/dsh-upgrade/transactional-upgrade.js:92
    rmSync(dir, { recursive: true, force: true });
  • 读取本地文件
    src/dsh-upgrade/transactional-upgrade.js:100
    if (existsSync(backup)) {
  • 读取本地文件
    src/dsh-upgrade/transactional-upgrade.js:101
    if (!existsSync(dest)) {
  • 写入本地文件
    src/dsh-upgrade/transactional-upgrade.js:102
    renameSync(backup, dest);
  • 写入本地文件
    src/dsh-upgrade/transactional-upgrade.js:108
    mkdirSync(dirname(dest), { recursive: true });
  • 读取本地文件
    src/dsh-upgrade/transactional-upgrade.js:109
    const destExisted = existsSync(dest);
  • 写入本地文件
    src/dsh-upgrade/transactional-upgrade.js:111
    renameSync(dest, backup);
  • 写入本地文件
    src/dsh-upgrade/transactional-upgrade.js:115
    renameSync(staging, dest);
  • 读取本地文件
    src/dsh-upgrade/transactional-upgrade.js:117
    if (destExisted && existsSync(backup) && !existsSync(dest)) {
  • 读取本地文件
    src/dsh-upgrade/transactional-upgrade.js:139
    if (!existsSync(staging)) {
  • 读取本地文件
    src/homes/layout.js:79
    if (!existsSync(patchPath)) writeFileSync(patchPath, "[]\n", "utf8");
  • 写入本地文件
    src/homes/layout.js:79
    if (!existsSync(patchPath)) writeFileSync(patchPath, "[]\n", "utf8");
  • 读取本地文件
    src/homes/layout.js:81
    if (!existsSync(workspace)) writeFileSync(workspace, "packages:\n - '.'\n", "utf8");
  • 写入本地文件
    src/homes/layout.js:81
    if (!existsSync(workspace)) writeFileSync(workspace, "packages:\n - '.'\n", "utf8");
  • 读取本地文件
    src/homes/layout.js:150
    for (const entry of readdirSync(store, { withFileTypes: true })) {
  • 写入本地文件
    src/install/pipeline.js:32
    writeFileSync(file, typeof content === "string" ? content : `${JSON.stringify(content, null, 2)}\n`);
  • 读取本地文件
    src/install/pipeline.js:139
    if (existsSync(dest)) removePath(dest);
  • 读取本地文件
    src/install/pipeline.js:140
    if (existsSync(src)) cpSync(src, dest, { recursive: true });
  • 读取本地文件
    src/install/pipeline.js:145
    if (!existsSync(src)) return null;
  • 读取本地文件
    src/install/pipeline.js:404
    if (!existsSync(store)) continue;
  • 读取本地文件
    src/install/pipeline.js:469
    if (existsSync(store)) {
  • 读取本地文件
    src/install/pipeline.js:507
    if (!existsSync(homes.pluginStorePath(staging, pluginId))) {
  • 读取本地文件
    src/install/receipt.js:76
    if (existsSync(file)) return normalizeReceipt(readJson(file));
  • 写入本地文件
    src/install/wal.js:28
    writeFileSync(undo.path, undo.snapshot);
  • 读取本地文件
    src/install/wal.js:32
    if (undo.from && existsSync(undo.from)) {
  • 读取本地文件
    src/install/wal.js:117
    for (const name of readdirSync(dir)) {
  • 读取本地文件
    src/runtime/dsh-paths.js:85
    if (existsSync(candidate)) return candidate;
  • 执行外部命令来自配置/变量
    src/runtime/dsh-supervisor.js:70
    return spawn(command, args, options);
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 GitHub 仓库

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

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 托盘启动管理插件
  • 更新至最新版
  • 一键安装升级插件

DSH的桌面客户端,可更新DSH最新版,一键安装升级插件

README

由 DeepSeek 最新模型翻译生成
DS harness(dsh-tray) test license Windows 托盘应用。它不实现 DeepSeek Harness 本体,而是: 1. 找到或安装本机 @deepseek-ai/dsh 2. 用独立 DSH_HOME 启动 dsh web 3. 把 Web GUI 嵌进 Electron 窗口 4. 从托盘打开插件中心,按供应链门禁安装 / 卸载社区插件 产品名:DS harness。安装包快捷方式同名,可执行文件为 DSH.exe。 仓库: 本仓库是 Electron 壳源码,不发布到 npm。DSH 本体来自官方包;本项目与 DeepSeek 官方无隶属关系。
展开完整文档(README 剩余 1 节)
DS harness(dsh-tray)

test
license

Windows 托盘应用。它不实现 DeepSeek Harness 本体,而是:

1. 找到或安装本机 @deepseek-ai/dsh
2. 用独立 DSH_HOME 启动 dsh web
3. 把 Web GUI 嵌进 Electron 窗口
4. 从托盘打开插件中心,按供应链门禁安装 / 卸载社区插件

产品名:DS harness。安装包快捷方式同名,可执行文件为 DSH.exe。

仓库:

本仓库是 Electron 壳源码,不发布到 npm。DSH 本体来自官方包;本项目与 DeepSeek 官方无隶属关系。

目录

- 界面
- 功能
- 环境
- 快速开始
- 测试
- 打包
- 日常使用
- 数据目录
- 插件安装在做什么
- 项目结构
- 脚本
- 文档
- 故障排查
- 安全边界
- 许可证

界面

主窗口(嵌入的 DSH Web GUI):

主窗口

托盘菜单:

关于与更新:

关于与更新

插件中心:

插件中心

功能

- 系统托盘常驻;单击打开窗口,单实例运行
- 托盘「设置」:开机自启动、允许锁屏运行
- 自动准备 Node.js(系统 Node ≥ 20,或安装包内的便携 Node)
- 启动时查找或自动安装 pnpm(dsh plugin 依赖它),并把垫片目录插到 PATH
- 首次启动自动 npm install -g @deepseek-ai/dsh;缺依赖的预发布会跳过
- 每天检查一次 DSH 更新(托盘「关于与更新」可手动检查)
- DSH 子进程崩溃时托盘不退出,自动切到无社区插件的安全模式
- 退出或切换模式时在 Windows 上 taskkill /T 杀掉 DSH 进程树,避免文件锁挡住更新
- 插件中心:社区目录、中文说明、星标 / 下载量、收藏、安装 / 升级 / 卸载、隔离失败项
- 单体仓库(如 integrations/deepseek-harness/)也能解析出真正的插件包名
- 插件安装走精确版本 + integrity + 仓库身份校验;先在 staging home 验证,再写入正式环境
- 当前 DSH 是预发布时,安装 pin 跟随对应 npm dist-tag(如 next / rc)
- 自定义托盘弹出菜单(与插件中心同色板);主题对话框跟随系统浅色 / 深色
- DSH 0.1.6 起就绪 URL 带 ?token=,主窗口加载完整地址;换端口时清掉回环 dsh-auth- cookie
- 给 Node 加大 HTTP 请求头上限,避免官方插件 combo URL 触发 431 / Failed to load plugins
- 启动失败或 DSH 输出里的 token、密钥、用户主目录会先脱敏再显示;中文 Windows 下按 GBK 解码子进程日志

环境

| 项 | 要求 |
| 系统 | Windows 10 及以上(打包解压便携 Node 需要系统 tar.exe) |
| Node | 开发需要 Node.js 20+;安装包可自带便携 Node 24 |
| pnpm | 不必预装。启动时按 PATH / Node 目录 / npm 全局 / 私有 prefix / %LOCALAPPDATA%\pnpm 查找,找不到就 npm install -g pnpm |
| 网络 | 安装 DSH、pnpm、刷新插件目录、拉取 npm / GitHub 信号时需要 |

快速开始

git clone https://github.com/Mos0526/DSHarness-Tray.git
cd DSHarness-Tray
npm install
npm start

没有 git 时,也可在资源管理器中双击 scripts\dev-demo.cmd 或 launch.vbs。二者都会在项目根目录启动 electron .。

开发时日志打在启动该命令的终端。托盘「退出」或关掉该终端即可结束进程。

测试

单元测试与集成测试走 Node 内置测试运行器,不启动真实 Electron 窗口:

npm test

可选联网目录测试(会打 GitHub / 社区 README):

set DSH_CATALOG_LIVE=1
npm test

CI 在 GitHub Actions 的 Windows runner 上跑同一套 npm test。

打包

npm run dist

会先执行 scripts/prepare-node.js,把便携 Node 放进 runtime/node/(该目录已被 gitignore),再由 electron-builder 打 NSIS 安装包。产出在 release/:

- DS-harness-Setup-.exe — 一键安装,带桌面与开始菜单快捷方式

仅准备便携 Node、不打包:

npm run prepare-node

重新生成 icon.ico(从 icon-16/32/48/256.png):

node make-ico.js
日常使用

托盘菜单(右键图标;单击仍打开主窗口):

| 项 | 作用 |
| 打开窗口 | 显示已嵌好的 DSH Web GUI |
| 打开 .dsh 目录 | 打开当前 active DSH_HOME |
| 插件商店 | 打开插件中心。有待升级 / 隔离 / 验证失败时显示红点 |
| 设置 | 开机自启动、允许锁屏运行(开关,位于关于与更新之上) |
| 关于与更新 | 当前 DSH 版本与发行说明;点「检查更新」后再「更新版本」 |
| 退出 | 先停 DSH 子进程再退出壳 |

开机自启动会带 --autostart,窗口留在托盘、不弹出。允许锁屏运行会阻止系统挂起应用,并关闭 Chromium 后台节流。

插件中心只从托盘进入。列表支持搜索、筛选(已安装 / 可升级 / 收藏 / 隔离等)和分类快捷(高星、UI、视觉、记忆、Bot、工具)。选中条目后可看说明、社区热度、维护状态与供应链信息,再安装、升级、卸载或收藏。收藏只存在本机 plugin-favorites.json,不上传。

数据目录

壳自己的数据在 Electron userData(通常是 %APPDATA%\DS harness):

%APPDATA%\DS harness\
dsh\
homes\
safe\ # 无社区插件;升级后或崩溃恢复时启动 active\ # 壳内部备用;当前托盘会把 active 指到用户 ~/.dsh staging\ # 安装前隔离验证,用完删除 quarantine\ # 失败代次 / 隔离记录 ledger\ # WAL、receipt、lifecycle tmp\ # DSH 本体升级暂存(库代码;当前托盘走 npm -g) catalog-cache\ # 目录与 GitHub / npm 信号缓存 runtime\ # 从安装包解出的便携 Node(仅当系统 Node 不可用) shell-state.json # lastCheckAt、safeBootRequired、shellSettings plugin-favorites.json # 插件收藏与本地历史(无账号)

当前托盘接线:

- DSH 二进制通过 npm install -g @deepseek-ai/dsh 安装。有系统 Node 时写入 %APPDATA%\npm;只有便携 Node 时写入壳的私有 npm prefix。
- pnpm 装在同一 prefix(或沿用已有的 PATH / %LOCALAPPDATA%\pnpm),再把该目录插到子进程 PATH。dsh plugin 在 Windows 上走 shell: true,必须能直接叫到 pnpm.cmd。
- 正式 active home 是用户目录下的 ~/.dsh(%USERPROFILE%\.dsh),与终端里直接跑 dsh 共用同一份配置和 profile。
- 凭证与设置(.credentials.yaml、settings.yaml、pet.json)在切到安全模式时会同步到 homes/safe。
- 社区插件仍先在 homes/staging 验证,通过后再写入 ~/.dsh/profiles/web。

src/runtime 里还有一套「壳独占 {userData}/dsh/current」路径约定,供事务升级库使用。托盘启动路径目前不走那套目录,见 docs/ARCHITECTURE.md。

插件安装在做什么

一次「安装」不是直接 npm i 进正式环境,顺序是:

1. 用所选 GitHub 仓库的 package.json 确认 npm 包名
2. 向 npm registry 取 精确版本 + integrity + manifest
3. assertInstallGate:禁止浮动 git spec、市场类插件、生命周期脚本;核对仓库身份;相对上次 receipt 检测供应链变更
4. 检查与当前 DSH 的 host / renderer 兼容范围
5. 确认 pnpm 可用后,把 active profile 拷到 staging(不含 node_modules),在隔离 home 里 dsh plugin add --save-exact --ignore-scripts
6. 启动隔离 DSH,做 host / renderer 探活
7. 通过后才写入正式 profile,记 WAL 与 receipt;失败则回滚或切安全模式

目录来源(发现用,不是安全评分):

- awesome-deepseek-harness
- awesome-dsh-plugin

热度(星标、下载)从不参与托盘红点。红点只来自:可升级、已隔离、验证失败。

项目结构

main.js Electron 主进程:托盘、窗口、DSH 生命周期、插件安装编排 dialog.html 「关于 / 更新 / 确认」主题对话框 preload-dialog.js src/ adapters/ DSH CLI argv / stdout / 退出码,不绑死某一预览版 runtime/ 路径、监督器、进程树、输出解码、pnpm 解析、回环鉴权 cookie、版本候选、诊断脱敏 dsh-upgrade/ 单目录事务升级库(测试覆盖;当前托盘未接线) homes/ DSH_HOME 四种隔离、ledger 路径、profile 清单 install/ 门禁、WAL、receipt、兼容性、安装管线 identity/ 稳定插件 ID、仓库 / npm 身份、单体仓库 package.json catalog/ 社区目录抓取、中文说明、详情 signals/ GitHub / npm 热度与维护信号

plugin-center/ 插件中心窗口、IPC、视图模型、UI tray-plugin/ 托盘「插件商店」文案与红点 tray-menu/ 右键托盘的自定义弹出菜单 shell-settings/ 托盘「设置」:开机自启、锁屏运行 scripts/ 测试、便携 Node、开发演示、冒烟安装 test/ 单元测试、集成测试、夹具 docs/ 架构与有效代码清单

每个 src/ 包都有 README。完整文件清单见 docs/MODULES.md,设计说明见 docs/ARCHITECTURE.md。

脚本

| 命令 | 作用 |
| npm start | electron . |
| npm test | node scripts/run-tests.js |
| npm run prepare-node | 下载并整理便携 Node 到 runtime/node/ |
| npm run dist | 准备 Node 后打 Windows NSIS 安装包 |
| scripts\dev-demo.cmd | 缺依赖则本地 npm install,再 npm start |
| node scripts/smoke-plugin-install.js [spec] | 对全局 DSH 做一次隔离安装冒烟(需已安装 dsh) |
| node make-ico.js | 从 PNG 生成 icon.ico |

文档

| 文档 | 内容 |
| README.en.md | English README |
| docs/ARCHITECTURE.md | 进程模型、启动、Home、安装管线、目录、故障恢复 |
| docs/MODULES.md | 有效源码与测试对照表 |
| src/adapters/README.md | DSH 协议适配 |
| src/runtime/README.md | 路径、监督器、进程树、输出解码、pnpm、HTTP 头上限、诊断脱敏 |
| src/dsh-upgrade/README.md | 事务升级库 |
| src/homes/README.md | Home 与 ledger |
| src/install/README.md | 安装门禁与 WAL |
| src/catalog/README.md | 社区目录 |
| src/plugin-center/README.md | 插件中心 |
| src/identity/README.md | 稳定身份 |
| src/signals/README.md | GitHub / npm 信号 |
| src/tray-plugin/README.md | 托盘插件入口 |
| src/tray-menu/README.md | 自定义托盘菜单 |
| src/shell-settings/README.md | 开机自启与锁屏运行 |

故障排查

| 现象 | 处理 |
| npm start 提示找不到 Electron | 在仓库根目录执行 npm install |
| 启动页停在「正在准备 Node / 安装 DSH」 | 检查网络;预发布缺依赖时会自动跳过并试下一个版本 |
| 窗口能开、页面是错误页 | 看启动终端日志;托盘仍在,可「退出」后重开 |
| 窗口 401 / 提示重新打开 dsh web 打印的 URL | DSH 0.1.6 起必须加载带 ?token= 的就绪地址;请更新到本壳 1.1.17 及以上 |
| GUI 提示 Failed to load plugins / 431 | 官方 combo URL 头太大。1.1.17 已给 Node 加上 --max-http-header-size;请更新壳后托盘退出再开 |
| 插件安装失败、正式环境未变 | 预期行为:staging 验证失败不会写入 ~/.dsh |
| 插件安装提示找不到 pnpm | 壳会在启动和安装前自动 npm install -g pnpm。仍失败则手动执行该命令,或从已有 pnpm 的终端再开托盘 |
| DSH 崩溃后功能变少 | 已切到安全模式(无社区插件);修好后可在插件中心重新安装 |
| 启动后提示「已进入安全模式」 | 正常模式里的社区插件和当前 DSH 不兼容,已自动停用社区插件;对话框里的路径和 token 已经脱敏 |
| 锁屏后任务停住 | 托盘 → 设置 → 打开「允许锁屏运行」 |
| 更新 DSH 后仍像旧版本 / 文件被占用 | 先托盘退出再更新;壳会 taskkill /T 杀进程树。若仍占用,结束残留 node.exe 后再试 |
| 第二次双击安装包 / npm start 没有新窗口 | 单实例锁:会唤起已有窗口 |
| npm run dist 解压 Node 失败 | 确认系统有 tar.exe(Windows 10+ 自带) |

安全边界

壳能保证:安装前校验 npm integrity 与仓库身份;社区插件 --ignore-scripts;先隔离运行再进入 ~/.dsh;渲染进程不能乱开链接或复制任意剪贴板。

壳不能保证:插件一旦进入 active,就拥有该 home 下 Host 的能力;Windows 上默认 danger-full-access,与官方 GUI 权限模型一致,不是沙箱。细节见 docs/ARCHITECTURE.md 第 9 节。

许可证

MIT。见 LICENSE。
DeepSeek Harness(@deepseek-ai/dsh)及其社区插件各有自己的许可证,不在本仓库范围内。

相关链接

- DeepSeek Harness
- CLI 用户指南
- 社区目录:awesome-deepseek-harness、awesome-dsh-plugin
- 问题反馈:GitHub Issues
预览分享卡片长什么样 ↓Mos0526/DSHarness-Tray
分享 · DeepSeek Harness Hub
Mos0526/DSHarness-Tray

在系统托盘里启动、更新并管理 DSH 插件

回到顶部