dsh-restart-handoff:改完需重启时自动重启并把对话接回原会话

前言

在 DSH 桌面版里开发或调试插件时,宿主经常在改动生效前返回 application: "restart-required"。常见做法是手动退出 App、再打开,然后凭记忆把「刚才改到哪、下一步做什么」重新说一遍。普通重启只恢复进程,不会保留上下文里的「为什么重启」和「重启后第一步」。

下面介绍社区插件 dsh-restart-handoff(维护者 Saolence,分类:客户端)。它在需要重启时替你完成退出与重开,并把模型写好的交接话作为同一会话的下一条消息投递回来。

这是什么

dsh-restart-handoff 面向 DSH 桌面版(Electron) 与 macOS:重启 helper 使用 osascript 退出 App、open -n 重开。纯 web / CLI 宿主调用相关能力时会得到 status: "unsupported"。

插件在 GitHub 开源(Saolence/dsh-restart-handoff),许可证 MIT;社区目录页见 skillhub.cn。DeepSeek Harness 生态强调「一切皆插件」;SkillHub 等目录为独立社区站点,与 DeepSeek / 幻方无官方从属关系。

核心功能

三种触发方式

触发源 谁发起 什么时候
自动 宿主监听 plugin_manager 工具结果 结果里出现 restart-required
工具 主会话调用 restart_handoff 主动写入交接话并排程重启
手动 设置 →「重启交接」→ 现在重启 立即重启(不续跑,不写 pending)

自动路径与工具路径同时排队时,后到的请求会让位(日志 hand-off request dropped);已有排程时返回 already-scheduled / already-deferred。

重启前后行为

  1. 交接话:重启前把「接下来怎么做」存盘;重启约 2.5 秒后,插件通过 resolveAgent(sessionId) 与 prompt({ mode: "queue", content: [交接话] }) 投回原会话。正文由模型撰写,插件只搬运;缺省、超时(2 分钟)或拿不到会话 id 时,兜底为一句:🔄 DSH 已重启完成,继续未完成的工作。
  2. 不打断当前轮:默认等本轮回答结束、结果落盘后再重启;可配合「等所有任务都做完再重启」等待其它会话 idle。
  3. 防连环重启:冷却时间、尝试次数上限、pending.json 10 分钟有效期等,避免无限重启循环。

权限与并发

只有主会话可发起工具重启或接受自动重启;子代理、子会话、teammate 调用 restart_handoff 返回 status: "not-root"。重启会打断所有正在跑的任务,因此插件用 api-session/status 与 agent/status 维护「正在跑的会话」名单;名单非空时不进入倒计时,面板可显示等待 N 个会话结束。

客户端设置

设置 →「重启交接」:常用开关包括「需要重开时自动帮我重启」「等所有任务都做完再重启」「重启后自动接着做」(均默认开)。侧栏账号行上方有仅图标的 ↻ 按钮,手动重启需确认与 3 秒倒计时,且不续跑。

配置与状态文件位于 ~/.dsh/restart-handoff/(如 settings.json、pending.json、gate.json、history.jsonl);完整文本日志为 ~/.dsh/restart-handoff.log。

安装与启用

前提:DSH 桌面版。安装前建议自行查阅仓库源码与 MIT 许可证;插件以当前 DSH 进程权限运行。

从 Release 的 tarball 安装(README 示例版本 0.1.0):

plugin_manager: { action: "install_bundle", target: "/绝对路径/saolence-dsh-restart-handoff-0.1.0.tgz" }

从 npm 安装(发布后):

plugin_manager: { action: "install_bundle", target: "@saolence/dsh-restart-handoff" }

从本地仓库目录安装:

plugin_manager: { action: "install_bundle", target: "/绝对路径/dsh-restart-handoff" }

package.json 声明了 dsh.bundle.patch,bundle 自带的 cordis.patch.yml 会自动插入 restart-handoff。停用或启用:

plugin_manager: { action: "set_plugin", target: "include:restart-handoff", enabled: false }

注意:改包本体不会热重载;若 profile 为符号链接,改完 index.js / client.js 需 toggle 一次或重启宿主才生效。

典型用法

工具 restart_handoff

主会话在已知改动需重启时,可主动调用(next_step 已移除,请用 continuation):

{
  "reason": "换了侧边栏插件",
  "continuation": "## 为什么重启\n…\n## 刚才做到哪\n…\n## 下一步\n…",
  "delay_ms": 1500
}

工具立即返回、不阻塞本轮。常见返回:deferred(挂起,回合结束再重启)、scheduled、already-deferred / already-scheduled、not-root、cooldown / disabled / unsupported。排队成功时返回含 mustStopNow: true 与 waitFor: "turn-end",模型应只回复「已排定重启」并停手,避免同一回合继续调工具(否则记 late-tool 警告)。完成证据是重启后到达的那段交接话,不会从工具同步返回「重启完成」。

自动路径

当主会话的 plugin_manager 结果含 restart-required 时,宿主会用 steer 请模型写交接话并调用 restart_handoff;2 分钟无回音则按提示照常重启。

适用场景与注意

适合:在 macOS 上使用 DSH 桌面版、频繁改插件或宿主模块、希望重启后同一会话自动收到「下一步」说明的开发者。

边界(来自 README):

  • restart_handoff 工具只出现在新创建的会话;装插件前已打开的会话拿不到该工具,需新开会话或使用面板 / 自动触发。
  • 仅 macOS、仅桌面宿主;重启后 GUI 端口可能变化,以 App 打印地址为准。
  • 重启无法续跑 shell 等进程内状态,交接话描述的是「从哪继续」,不是恢复当时内存里的句柄。
  • 手动「现在重启」不写 pending.json,不会自动投递交接话。
  • 安装与使用前请阅读 GitHub 仓库 与 Release,勿在未审源码的情况下盲目安装第三方插件。

结尾

dsh-restart-handoff 把「检测到 restart-required → 安全退出 → 重开 → 同会话续写上下文」串成一条可配置的路径,减少手工重启与重复解释。目录页:https://www.skillhub.cn/plugins/Saolence/dsh-restart-handoff;源码与文档:https://github.com/Saolence/dsh-restart-handoff。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜