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