dsh-plugin-restart-desktop

DSH PLUGIN会话与消息

仓库 railgun20001/dsh-plugin-restart-desktop · npm dsh-plugin-restart-desktop

会话与消息 L5 · 运行验证通过 安全审查:低风险 可信度:金 可安装插件
安装这个插件

DSH 桌面版一键重启插件,重启后保留窗口位置、大小、最大化状态与所在显示器,并可自动续接被打断的会话。

一句话选型结论

按资料字段整理

dsh-plugin-restart-desktop 是会话与消息类的 DSH 可安装插件,验证等级 L5 · 运行验证通过,安全审查为低风险,列出 4 项功能,有可直接复制的安装命令。验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么;涉及密钥或系统权限的,建议先在隔离环境试装。

分类会话与消息 收录类型可安装插件 验证等级L5 · 运行验证通过 安全审查低风险
验证等级 L5 L5 · 运行验证通过
GitHub 星标 0 复刻 0 · 未关闭 issue 0
最近更新 2026-11-05 创建于 2026-11-05
README 24.8 KB 正文体量,越大说明说明书写得越细

安装

可安装插件
在 DSH 里执行,装完用 dsh plugin list 确认已挂上;标了 L4 / L5 的命令已在沙盒里真实跑通
dsh plugin --profile web add github:railgun20001/dsh-plugin-restart-desktop
  1. 1
    确认版本与运行环境

    兼容的 DSH 版本为 0.2.2-rc.1,Node.js 要求 >=20;版本不匹配时安装会报错。

  2. 2
    执行安装命令

    在 DSH 里执行上面的命令;多包仓库要注意区分具体子包名,别装错包。

  3. 3
    确认已挂载

    用 dsh plugin list 查看列表里是否出现这个插件,出现即挂载成功。

  4. 4
    试跑并检查权限

    加载后跑一个最小用例,确认它能正常工作;同时看它申请了哪些文件、命令或网络权限。

兼容 DSH 版本0.2.2-rc.1版本不匹配时安装会报错
Node.js 要求>=20来自仓库 package.json 的 engines 字段
前置依赖无需要同时安装的同级依赖
npm 包名dsh-plugin-restart-desktop可用 npm view 查看包信息

能做什么

4 项功能
字段来自项目仓库与公开索引,中文说明由本站标注

dsh-plugin-restart-desktop:为 DeepSeek Harness 桌面版补上一键重启

  • 侧栏图标一键重启
  • 保留窗口几何与显示器
  • 自动续接被打断会话
  • 斜杠命令 /restart-desktop

适用场景

存储

上游标签

cordis-plugindeepseek-harnessdshdsh-pluginelectronrestartwindows

验证等级与安全审查

L5 · 运行验证通过
自动化流程结论,不是人工审核
验证等级L5 · 运行验证通过在 dsh 沙盒中完成安装与运行冒烟——装得上、跑得起来
安全审查低风险静态分析结论,未标注不代表已通过审查
仓库健康度活跃按仓库活跃度与最近更新时间给出
可信度金综合仓库活跃度与验证结果

上面的结论来自上游最近一次自动化验证(2026-11-11): 同一套检查会在插件发新版后重跑,页面显示的是最新一次的逐项结果。

逐项检查结果

L1 · 已找到 ✓ 通过
  • L1.0_DEFAULTED_FROM_L3 由 L3 推定 默认通过——L3 安装规范已通过(全库 L3 扫描策略)
L2 · 结构化 ✓ 通过
  • L2.0_DEFAULTED_FROM_L3 由 L3 推定 默认通过——L3 安装规范已通过(全库 L3 扫描策略)
L3 · 安装规范 ✓ 通过
  • L3.1_INSTALL_COMMAND_PARSED 安装命令已解析 方式:安装规范解析
  • L3.2_DSH_VERSION_DECLARED DSH 版本已声明 方式:DSH 版本声明
L4 · 安装已测 ✓ 通过
  • L4.1_INSTALL_EXECUTED_CONFINED 受限沙盒内执行安装 方式:沙盒安装执行
  • L4.2_INSTALL_SUCCESS 沙盒安装成功 方式:沙盒安装执行
  • L4.3_ARTIFACT_CONFIRMED 安装产物已确认 方式:沙盒安装执行
L5 · 运行已测 ✓ 通过
  • L5.1_INSTALL_PASSED_SANDBOXED 沙盒安装通过 方式:沙盒安装执行
  • L5.2_WEB_BOOT_READY Web 启动就绪 方式:Web 启动
  • L5.3_HTTP_SERVED HTTP 服务响应 方式:HTTP 请求
  • L5.4_PLUGIN_INVENTORY_ACTIVE 插件清单中已激活 方式:插件清单查询

风险详情

  • 结论说明 静态扫描 低;动态审计无结论(以下以静态为准)→ 总评级 低。
  • 风险计数 严重 0 / 高 0

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 验证等级 L5:安装和运行都在沙盒里跑通过,装完能直接用的概率高。
  • 静态安全审查为低风险,没有发现明显可疑行为。
  • 有可直接复制的安装命令,不用自己翻文档找入口。
  • 标注了兼容的 DSH 版本(0.2.2-rc.1),按版本装不容易报错。
  • 列出了 4 项功能,能直接看出它解决什么问题。

先想清楚的地方

  • 验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么。

更适合

  • 需要在会话与消息场景里给 DSH 补能力的人。
  • 想装完就能用、不想自己排依赖的人。
  • 能接受在本地装依赖、愿意自己确认权限的人。

不太适合

  • 只使用 DSH 官方内置能力、不接受第三方插件的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
插件验证等级安全审查星标兼容版本安装命令
dsh-plugin-restart-desktop当前 L5 · 运行验证通过 低风险 0 0.2.2-rc.1 有
dsh-desktop L3 · 安装规范通过 低风险 3.0 万 未标注 无
openpets L4 · 沙盒安装通过 低风险 1,274 未标注 有
deeptide L4 · 沙盒安装通过 低风险 1,104 0.1.1-rc.2 有
jingyun-dsh L3 · 安装规范通过 低风险 1,004 未标注 有
study-mate 未做沙盒验证 未标注 856 未标注 无

仓库档案

会话与消息
字段来自项目仓库与公开索引,中文说明由本站标注
作者 / 维护方railgun20001仓库 dsh-plugin-restart-desktop · 默认分支 master
分类会话与消息desktop
收录类型可安装插件声明了 dsh.bundle、可用 dsh plugin add 安装的条目
开发语言JavaScript仓库主语言
许可证MIT商用或二次分发前请确认条款原文
星标 / 复刻 / issue0 / 0 / 0收录时的数值,非实时
创建 / 更新2026-11-05 · 2026-11-05最后推送 2026-11-05
本站收录2026-11-05首次进入本站目录的时间

README 全文

24.8 KB
作者原文,中文版优先;只做安全转义,不改内容

dsh-plugin-restart-desktop



DSH 桌面版(DeepSeek Harness Electron 壳)的一键重启插件:保留窗口位置、大小、最大化状态与所在显示器,可选在重启后自动续上被打断的会话(不只是你当前打开的那个)。

只有一个入口:侧栏底部账号行右侧的图标按钮(刷新图标)。单击即重启 —— 没有二次确认,有任务在跑时也不要求再点一次(那一路实况只写进悬停提示)。插件不提供任何设置页配置。

入口 位置
账号行右侧图标 侧栏底部那一行账号(头像 + 昵称)的右边

账号行认不出来时(官方改了 DOM)会自动回落到官方给第三方插件的动作座位 sidebar.footer.action(侧栏底部同一行区域的图标按钮),功能不会凭空消失。

另外还注册了斜杠命令 /restart-desktop(一样单击即重启;这条路上的宿主侧警告仍需 /restart-desktop --force 越过)。


为什么需要这个插件

这不是「官方本来就有、只是藏得深」的功能,而是官方没有留任何通道。两条硬事实(都来自解包 app.asar 读主进程源码):

  1. 主进程没有暴露重启。 完整 IPC 只有 shutdown / quit-inspection / update-tasks(主进程 → host)与 ready / fatal / shutdown-complete / platform-session(host → 主进程);渲染进程侧的 dshDesktop API 只有 browser / deviceInfo / keyboard / shortcuts / updates。内置的「重启应用与 Host」菜单项只在 development 分支里加入菜单,打包版永远看不到;Windows 上托盘菜单只有「打开应用」和「退出」。
  2. 窗口几何从不落盘。 createWindow() 硬编码 width: 1280, height: 820,主进程里没有 getBounds 保存、没有 window-state 存储,%APPDATA%\@deepseek-ai\dsh-desktop\ 下也没有任何窗口状态文件。正常退出再开一定回到 1280×820。

还有一条容易踩的坑:窗口的关闭按钮不会退出应用(主进程 preventDefault + hide,只是收进托盘),所以「关掉再打开」这条最直觉的路并不成立。

所以插件只能自己动手:从宿主进程里派一个分离的 helper,由它结束 Electron 主进程、等端口释放、拉起新实例,再逐像素还原窗口。


它是怎么做的

DeepSeek Harness.exe            ← Electron 主进程:窗口、托盘、更新、spawn host
└── DeepSeek Harness.exe      ← host 子进程(ELECTRON_RUN_AS_NODE=1),监听 127.0.0.1:19387
└── 本插件的宿主半
└── (分离)helper:node lib/helper.mjs handoff.json
  1. 宿主半校验目标是不是桌面宿主、把「现在停掉会打断什么」讲清楚、写一份交接描述,然后把 helper 拉起来。
  2. helper 等 1.5 秒(让 HTTP 响应先送达页面)→ 趁主进程还活着捕获窗口几何 → 结束 Electron 主进程 → 等主进程消失、等端口释放 → 拉起新实例 → 等新窗口出现 → 还原几何。

关键取舍:只杀主进程,不带 /T

主进程一死,host 子进程到它的 IPC 通道断开,host 里的 process.once('disconnect') 会走 application.shutdown.shutdown(0) —— 这和官方正常退出走的是同一个 stop(),会话日志因此正常落盘。带 /T 会把 host 一起强杀,那才是真的可能丢数据。

只有一种情况会碰到 host:端口在主进程消失后仍然不放(说明 host 卡住了)。那一步是最后手段,且会把「它的会话日志可能不完整」如实写进日志。

窗口几何

lib/geometry.ps1 用 GetWindowPlacement 取 rcNormalPosition(用户真正选定的那个矩形 —— 窗口最大化时当前矩形是最大化后的,只有它记录着要还原的尺寸)、showCmd(常规 / 最小化 / 最大化),以及 MonitorFromWindow / GetMonitorInfo(窗口在哪块显示器上,例如 \\.\DISPLAY2),重启后用 SetWindowPos + ShowWindow 放回去,并读回实际值写进日志。

最大化的窗口必须先把位置放回去,再最大化。 Windows 是在「窗口此刻所在的那块屏」上最大化的,而重新拉起的应用总是把窗口创建在主屏(笔记本屏)上 —— 所以对一个最大化的窗口直接 ShowWindow(SW_MAXIMIZE),等于把住在副屏的窗口拽回笔记本屏。现在的顺序是:退出最大化 → SetWindowPos 到捕获到的正常矩形(它标记着用户当时在用哪块屏)→ 最大化。最小化同理:先放回那块屏再最小化,否则从任务栏还原时会弹到主屏。

还原后还会读回窗口所在的显示器并与捕获值比对,wanted / actual / onTarget 一并写进日志与结果文件。若目标屏仍在、窗口却落在别处(正常矩形跨两块屏时会发生),脚本会把它居中到目标屏再最大化一次,并在结果里标 corrected: true;目标屏已经拔掉时不做任何猜测,只如实报 onTarget: false。

> 这个脚本必须保持 ASCII-only:Windows PowerShell 5.1 对无 BOM 的 -File 脚本按 ANSI 解码,一句中文注释的字节被解码坏之后可能连行尾换行一起吞掉,下一行代码就整行变成注释(实测踩过:还原时静默拿不到目标显示器,wanted 变成 null)。npm test 里有一条断言把这条约束钉住。


调研结论:重启后能不能自动恢复对话

能,但形态不是「续跑那一轮」。结论分三层:

问题 结论
被打断的那一轮能续跑吗? 不能。 主进程被结束、host 优雅关停,正在生成的那一轮就没了。官方自己的退出确认框也写「当前正在运行的任务将会中断」。
会话会丢吗? 不会。 会话按工作区落盘(session.v4.jsonl.zstd),客户端还把「当前会话」持久化在 dsh-app://app 的 localStorage(dsh.sessions.current),重启后自动回到同一个会话,历史完整。
那「自动恢复对话」是什么? 把被打断的会话恢复成活 Agent,注入一条只陈述事实的恢复消息(什么时候重启过、这个会话当时是什么状态),怎么接着做由模型自己按会话记录判断。

实现走的是官方通道(源码级核对过):

  • ctx.agents.resume({ resumeSessionId, setup }) —— 把持久化会话恢复成活 Agent。setup 会把会话原本的 agent preset 重新挂上,否则恢复出来的 Agent 会丢掉它那一整套工具(bash / read / goal …);preset 解析不到时降级为「不带 preset 工具恢复」并记日志,而不是整个失败。
  • agent.followup(message) —— 往收件箱排一条消息并唤醒驱动。官方 dsh-headless 与 @deepseek-ai/dsh-goal-round-driver 都走这两步。
  • 消息的 source.kind 刻意不是 'user':Chat 把 source.kind === 'user' 的用户消息渲染成用户气泡,其余 kind 渲染成「注入的上下文行」。用自定义 kind,这条自动消息在对话里长得像系统注入 —— 它确实是。
  • 消息正文是纯报告(英文),只有两句:The desktop app restarted at … (scheduled by dsh-plugin-restart-desktop). + At that moment this session was running a turn.(或有几条消息在队列 / 几个后台任务在跑;没有明细就写 The state of this session at that moment was not recorded.)。用英文是因为宿主自己注入的元信息本来就是英文(被打断工具调用上的 ToolOutcomeUnknownError),同一层上下文保持同一种语言。不写 "continue" / "do not retry blindly" 这类指令 —— 重试判据宿主已经写在会话记录里,插件再讲一遍既重复,又可能把说错的话永久写进历史,让模型为了「对齐」它去改动本来没坏的东西。旧版标记没有 details 时只陈述「重启过」,不拿名单去推断这个会话当时在干什么。

副作用面被刻意收敛到最小(自动发消息会真的花钱、真的跑模型):

  • 名单由宿主自己在排程那一刻取实况:只接「agent 正在生成 / 跑工具」或「收件箱里有排队消息」的会话 —— 也就是那一轮对话确实被打断了的会话。刻意不是「你当前打开的那个会话」:在一个会话里挂着长任务、切到另一个会话点重启时,被打断的是后台那个;早先的实现把标记落在空闲的当前会话上,于是 not-interrupted,真正被打断的任务一条恢复消息都拿不到(上报现场就是这个形状);
  • 后台任务在跑不算「被打断」,只作为明细记进标记。任务活着不等于对话没结束:实测有一个会话挂着跑了 34 小时的 pnpm dev,而它的最后一轮对话在前一天就正常 turn/end 了;按任务唤醒它只会凭空多跑一轮。应用重启会杀掉后台任务,这件事写在「已知边界」里,不用恢复消息去通知模型;
  • 新版标记里的 sessionId 只是状态页展示用的「客户端当前会话」,不参与恢复名单。旧实现把它无条件补进名单,于是用户在哪个会话里点重启、哪个会话就会被续一轮 —— 哪怕它早已结束(真实事故:最后一轮比重启早 3 分钟就完成了);
  • agents / jobs 服务读不到、形状不认识、抛错时名单为空 —— 宁可一条都不恢复,也绝不凭猜测唤醒会话;
  • 空闲会话与历史会话永不被唤醒;
  • 标记带 5 分钟 TTL:宿主要是在几分钟之后才起来(比如用户手动重开),就不再自动发消息;
  • 标记在宿主启动时被取走即删,所以一次重启最多恢复一次,恢复失败也不会在下次启动时重放;
  • 一次重启可能接上多个会话,每个各发一条恢复消息;其中一个恢复失败不连累其余,失败原因逐个记进日志。

安装

从 npm 装(推荐):

plugin_manager(action: "install_bundle", target: "dsh-plugin-restart-desktop")

或者直接写进 profile —— bundles 与 dependencies 两处都要有:

// ~/.dsh/profiles/desktop/package.json
"dsh": { "profile": { "bundles": [ /* … */ "dsh-plugin-restart-desktop" ] } },
"dependencies": { "dsh-plugin-restart-desktop": "^1.0.0" }

开发本仓库时用 link: 指向本地目录,改完代码立即生效:

plugin_manager(action: "install_bundle", target: "link:C:\work\my\dsh\plugins\dsh-plugin-restart-desktop")

安装后 DSH 的 HMR 会当场把两半挂上,不需要重启(实测:安装后宿主路由立即应答,客户端半的图标按钮立即出现在账号行右侧)。如果入口没出现,刷新一次页面即可。

正常情况下 HMR 会当场把两半挂上,不必重启。只有在没开 HMR 的组合里,宿主半才要等 DSH 下次启动;客户端半每次刷新页面重新取。两半版本不一致时,控制台 __DSH_RESTART_DESKTOP__.status().version 是宿主版本、__DSH_RESTART_DESKTOP__.version 是客户端版本。

> 只支持 Windows 桌面版(能力探测不通过会明确拒绝,见「已知边界」)。宿主版本要求见 package.json 的 engines.dsh,作者本机实测于 0.2.1-rc.5。


使用

点侧栏底部账号行右侧的刷新图标:一次点击就排程重启 —— 窗口的位置、大小、最大化状态与所在显示器保留,被打断的会话按宿主实况自动续接;页面随后断开,应用重启并回到原来的样子。

单击即重启意味着不拦你:宿主守卫(有任务在跑 / 插件正在安装)不再要求第二次点击,只在按钮的悬停提示里说明「会打断它们」。斜杠命令那条路仍然保留一次警告(/restart-desktop --force 才是「我看过了」)。

配置

插件没有设置页,界面开关一个都不提供。两个宿主侧行为开关仍有默认值(都是开),需要时改插件 config 或宿主侧设置文件:

// ~/.dsh/profiles/desktop/package.json 里本插件那一行的 config
{ "geometry": true, "resume": true }   // 还原窗口几何 / 自动续接被打断的会话

宿主侧设置文件 ~/.dsh/restart-desktop/settings.json 优先于 config;也可以 POST /dsh-plugin-restart-desktop/api/settings?geometry=0&resume=0 改。

排障

浏览器控制台里有 globalThis.__DSH_RESTART_DESKTOP__:

__DSH_RESTART_DESKTOP__.status()      // 宿主状态快照
__DSH_RESTART_DESKTOP__.button()      // 账号行按钮的注入状态(found / injected / lastReason)
__DSH_RESTART_DESKTOP__.sweep()       // 立刻重扫一次账号行
__DSH_RESTART_DESKTOP__.action()      // 按钮此刻的动作状态

button().lastReason 的取值:injected(这一轮插进去了)、already-present(已经在位)、no-account-row(没找到账号行)、insert-failed、no-document(不是浏览器环境)。

宿主侧的交接记录在 ~/.dsh/restart-desktop/:handoff-*.json、restart-*.log、restart-*.result.json、restart-*.geometry.json(保留最近 20 组)。几何结果文件里除了矩形,还有 wanted / actual / onTarget / corrected(显示器名与矩形),重启后窗口到底落在哪块屏一眼可见。


已知边界(写清楚,免得当成 bug)

  • 正在跑的那一轮一定会断,不会自动续跑;自动恢复注入的是一份事实报告,不是「重放那一轮」,也不替模型决定该怎么接着做。
  • 正在被工具写入的文件可能停在半路。插件不做回滚。
  • 后台任务 / 子 agent / teammate 全部被杀;定时任务在应用关闭期间不会触发。被杀的后台任务不会换来一条恢复消息(对话本身没被打断),需要的话重启后自己再拉起。
  • 账号行右侧那个按钮靠观察 DOM。官方没给第三方留「账号行里的按钮」座位(sidebar.settings 是 single 座位,整块由 @deepseek-ai/dsh-client-ui-settings-account 渲染),所以只能等它渲染出来、按官方写死的 data-signed-out + aria-haspopup="menu" 认出那个展开按钮,再顺它往上两层定位到账号行、把按钮插在账号行右边。判据里没有一个哈希类名(官方 CSS 模块类名每个构建都变)。认不出来时不猜:回落到官方 sidebar.footer.action 座位,日志与 button().lastReason 会写明原因。
  • 侧栏收起时不显示这个按钮:Windows 上官方本来就把整个底栏(账号行那一片)隐藏了。收起状态下用斜杠命令 /restart-desktop。
  • 只支持 Windows 桌面版,而且是能力探测后的拒绝,不是文档约定:
  • 非桌面宿主(dsh web / headless):desktop: false,重启返回 409;
  • 非 Windows 的桌面版(macOS / Linux):desktop: true 但 capabilities.restart: false,重启在写交接描述之前就返回 409,原因写明「当前平台(darwin)还没有实现进程控制驱动」;
  • helper 里还有第二道同样的检查:万一交接描述被别的方式塞进来,它会在等待 1.5 秒之前掉头,不会空等 15 秒再空拉三次。
    能力快照由 lib/platform.mjs 统一给出,GET /dsh-plugin-restart-desktop/api/status 的 platform 与 capabilities 字段就是它的原样输出(restart / launchArgs / geometry / alert / reason)。客户端按钮读同一份快照:不支持时直接禁用,悬停提示里就是 reason 那句话。
  • 窗口几何依赖 rcNormalPosition 与显示器本身:还原记的是「哪块屏 + 哪个矩形」,比对靠显示器设备名(\\.\DISPLAY2)。重启期间被拔掉或换掉的屏不会凭空回来 —— 此时窗口落在系统给的那块屏上,日志与结果文件里 onTarget: false 会直说(脚本不会往一个不存在的坐标上挪窗口)。各屏 DPI 不同时工作区坐标与屏幕坐标可能不一致,还原结果可能偏移(日志里有 wanted / actual)。

验证情况

已经跑过的(全部通过):

层 内容
单元(npm test,本次 85 项) 账号行触发按钮的识别判据(严格 / 宽松 / 反例)、重启状态机(单击即执行、busy·done 期间的点击被忽略、失败可重试、非桌面版 / 非 Windows 平台禁用)、平台能力快照(Windows / macOS / Linux / 未知平台,注入式、可在任何机器上跑)、helper 在不支持平台上的即时拒绝、提示文案与颜色语气、当前会话 id 的解析、宿主守卫判据、「哪些会话真的在跑」的快照判据、可信请求判定、交接目录清理、设置读写、恢复标记(新旧两种形态、TTL、跳过)与多会话恢复流程的每一条分支、lib/geometry.ps1 的 ASCII-only 约束
客户端 bundle 冒烟 在 Node 里用假 window / document / React 真正执行 lib/client.js:factory 注册、apply 跑完、账号行已在时只挂提示浮层、账号行认不出来时观察期过后回落到官方座位、刷新后「已重启」提示被消费、诊断入口可用、slots 缺失时优雅退出
账号行图标按钮 用假 DOM 按官方真实结构(footerActions 下面的账号动作区 → AccountMenu.root → Menu 的 span → button[data-signed-out][aria-haspopup="menu"])整条跑一遍注入桥:落点就在账号行右侧、幂等、update() 把忙碌/提示/禁用写进节点、被官方重渲染踢出去后下一轮插回来、认不出账号行时页面上不多出任何节点、stop 之后不再动 DOM。结构取自解包 app.asar 里的 AccountMenu / Menu / ui-sidebar 源码
宿主挂载与路由 假 ctx 真 apply 一遍,按真实 HTTP 形状调路由:状态契约、403 / 404 / 409 / 500、设置写入、守卫先拦、force=1 才交接(并核对写下的待恢复名单来自宿主实况,而不是请求里那个会话)
端到端 临时编译一个 WinForms 靶子程序当「应用」,跑完 lib/helper.mjs 全链路:捕获几何(700×500 @ 300,200)→ 结束靶子主进程(确认日志里是 /T 之外的方式)→ 拉起新实例(靶子第二次启动刻意用默认几何 320×220 @ 20,20)→ 独立复核新窗口实际几何逐像素等于重启前
多显示器(本机三块屏) 靶子第一次在副屏 \\.\DISPLAY2 上最大化 → 重新拉起的实例按默认几何落在主屏 \\.\DISPLAY1 → helper 全链路还原 → 独立复核窗口回到副屏、最大化矩形与重启前逐像素一致、结果里 onTarget: true;另一条用例手工构造「正常矩形与记录的显示器互相矛盾」的状态,验证纠偏分支(corrected: true / onTarget: true)
复现上报缺陷(对照实验) 同一段靶子、同一个「副屏上最大化 → 重启」场景,分别用 git HEAD 的旧脚本与本次修复后的脚本跑一遍:旧版落到主屏 \\.\DISPLAY1(正是上报的「在左上屏,重启回到笔记本屏」),新版落回 \\.\DISPLAY2。另:17:14 那次真实重启的会话日志显示,被打断的是后台 session-3f255a53(turn/end reason: interrupted),而插件当时瞄准的是空闲的 session-c5744114(last-resume.json 写着 not-interrupted)—— 与修好的判据逐条对上
helper 启动方式 用真正的 DeepSeek Harness.exe + ELECTRON_RUN_AS_NODE=1 + detached 跑一次最小脚本,证明这条启动路径确实能跑起来
安装后的活体验证 插件安装到 desktop profile 后,DSH 的 HMR 当场把两半都挂上了(无需重启):• 宿主半路由 GET /dsh-plugin-restart-desktop/api/status 实测返回 {"host":"dsh-plugin-restart-desktop","version":"0.1.0","desktop":true,...},守卫正确读到真实服务(有任务在跑(4 项正在生成或运行工具、1 个后台任务在跑),12 个在挂会话);• 客户端半的注入落点在解包出来的官方源码里逐层核对过(上一行那条离线用例就是照它写的)。这一版(账号行图标按钮)还没有在真实窗口里目视确认过:客户端半要刷新一次页面才会换上新 bundle,而刷新会打断正在进行的会话。第一次刷新后请看账号行右侧是否出现刷新图标,控制台 __DSH_RESTART_DESKTOP__.button() 会给出 found / injected / lastReason。

没有跑过的(诚实说明):修复后的版本还没有真正重启过一次正在运行的 DSH —— 一跑就会杀掉当前会话。上面的对照实验与多显示器用例用的都是临时编译的靶子程序,生产路径的每一段都被单独验证过,但「在本机完整重启一次 DSH(新版)」以及「真的 resume 一个 Agent 并发出一条恢复消息」这两步,仍然留给你第一次点按钮时完成(~/.dsh/restart-desktop/ 下的 restart-*.log 与 last-resume.json 会把结果如实记下来)。

复现:

cd C:\work\my\dsh\plugins\dsh-plugin-restart-desktop
npm run check        # bundle 一致性 + npm test(本次 85 项)
npm run test:e2e     # 端到端(需要 Windows 桌面会话;多显示器那两条需要在多屏机器上跑,约 20 秒)

发布时的现状:插件仍以 link: 方式常驻作者本机 desktop profile,账号行按钮这条路已经在真实窗口里用过(包括 2026-11-05 15:42 那次由按钮排程的真实重启 —— 会话被打断后按新判据恢复)。


文件结构

index.js                 宿主半:路由、任务守卫、交接、启动后自动续接会话
lib/platform.mjs         平台能力(「本机能不能重启 / 有没有几何驱动」的唯一事实来源)
lib/helper.mjs           分离 helper:重启的实际执行者
lib/geometry.ps1         Win32 窗口几何捕获 / 还原(刻意只用 ASCII)
lib/resume.mjs           重启后自动续上被打断会话(纯逻辑 + 服务缝)
src/client-core.js       客户端纯逻辑:账号行识别判据、重启状态机、提示文案
src/account-button.js    账号行右侧图标按钮的 DOM 注入
src/client-main.js       客户端接线:图标按钮 + 官方座位回落 + 提示浮层
lib/client.js            客户端 bundle(由 build/bundle.mjs 生成,不要手改)
build/bundle.mjs         客户端 bundle 构建(三源文件内联,无外部依赖)
test/fake-dom.mjs        假 DOM(客户端 DOM 注入的离线测试用)
test/                    单元 + 冒烟 + 端到端测试

发布(维护者)

推 v* tag 即触发 .github/workflows/release.yml:校验 tag 与 package.json 版本一致 → npm run check → 发布 → 建 GitHub Release。

认证走 npm 可信发布(Trusted Publishing / OIDC),仓库里不存任何 npm token。 一次性前置(在 npmjs.com 上做):包的 Settings → Trusted publishing → GitHub Actions,填 railgun20001、dsh-plugin-restart-desktop、工作流文件名 release.yml,允许 npm publish。该配置要求创建后 2 天内完成首次成功发布,所以顺序是「先把包发出来 → 再配可信发布」;npm 要求 CLI ≥ 11.5.1、Node ≥ 22.14。

流程是幂等的:registry 上已存在的版本不会重发,只补一个 GitHub Release —— 所以 v1.0.0 这个 tag 可以照推,首次发布是本地 npm publish 干的,CI 只负责把它挂成 Release。

本地手动发(首次发布只能这么干:可信发布不支持为「还不存在的包」预配置):

# 本机 npm 默认 registry 是镜像源,登录要显式指官方源;
# package.json 的 publishConfig.registry 已钉住发布目标,publish 不必再带 --registry。
npm login --registry=https://registry.npmjs.org/
npm run check
npm publish

发布内容由 files 白名单决定:index.js + lib/(含构建好的 lib/client.js)+ cordis.patch.yml + README + LICENSE。src/、build/、test/ 不进包 —— 所以发版前必须先 npm run build 并提交,prepublishOnly 里的 --check 会拦住忘提交的情形。

卸载

plugin_manager(action: "remove_bundle", target: "dsh-plugin-restart-desktop")

宿主侧状态在 ~/.dsh/restart-desktop/,可以直接删;浏览器里只剩一个 dsh-plugin-restart-desktop/pending-v1 标记(重启完成后的一次性提示),一样可以直接删。

许可

MIT

常见问题

9 问
答案由本站依据条目字段整理,不引用上游原文
dsh-plugin-restart-desktop 怎么安装?

在 DSH 里执行 `dsh plugin --profile web add github:railgun20001/dsh-plugin-restart-desktop` 即可。对应的 npm 包名是 `dsh-plugin-restart-desktop`。

dsh-plugin-restart-desktop 的验证等级是什么意思?

L5 · 运行验证通过。在 dsh 沙盒中完成安装与运行冒烟——装得上、跑得起来

dsh-plugin-restart-desktop 安全吗?

低风险。静态扫描 低;动态审计无结论(以下以静态为准)→ 总评级 低。

dsh-plugin-restart-desktop 装之前要先确认什么?

先看它会读写哪些文件、执行哪些命令、连接哪些网络地址;验证等级只说明装得上、跑得起来,不等于安全。涉及密钥或系统权限的,建议先在隔离环境试装。

dsh-plugin-restart-desktop 支持哪些 DSH 版本?

上游记录的兼容版本包括 0.2.2-rc.1。

dsh-plugin-restart-desktop 需要什么运行环境?

Node.js >=20。环境不满足时安装会失败,建议先确认本机版本。

dsh-plugin-restart-desktop 用的是什么许可证?

上游标注为 MIT。商用或二次分发前请到仓库确认许可证原文。

dsh-plugin-restart-desktop 有哪些功能?

侧栏图标一键重启、保留窗口几何与显示器、自动续接被打断会话、斜杠命令 /restart-desktop。

这条记录的数据可靠吗?

本站按仓库名去重后合并整理,字段以作者仓库与 npm 元数据为准;安装命令、仓库地址与 README 保持原文,带 L4 / L5 标记的安装命令已在隔离沙盒里真实跑通。

同名或近似条目

1 条
不同作者的仓库分开列,请确认你要装的是哪一个
会话与消息
按星标排序,可作替代方案

dsh-desktop

dsh-desktop

为 DeepSeek Harness (DSH) 插件生态打造的现代化桌面端解决方案。万物皆「插件」,桌面本身也是「插件」。

L3 · 安装规范通过 3.0 万 星

openpets

openpets

L4 · 沙盒安装通过 1,274 星

deeptide

deeptide

L4 · 沙盒安装通过 1,104 星

jingyun-dsh

jingyun-dsh

井云 DSH 客户端插件,为 DeepSeek Harness 注入会员登录、订阅支付、算力管控与应用市场,让智能体和技能快速变成可交易商品

L3 · 安装规范通过 1,004 星

study-mate

study-mate

StudyMate 是 DSH 的「学习模式」预设与技能包,为数学、计算机科目定制学习路线、讲解课件与练习评估,跨科目共享记忆。

未标注验证等级 856 星

railgun20001 的其它插件

6 个

插件的元信息来自作者仓库;分类、验证等级与安全结论的中文说明为中文整理,最近核验 2026-11-11。