DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

Saolence /

Saolence/dsh-restart-handoff

Verified

改完东西必须重启?它替你重启,再把对话接回原来的会话 —— Restart the DSH desktop host when a change requires it, then hand the conversation back to the same session.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@3ca8d43a

dsh-restart-handoff

dsh-restart-handoff

改完东西必须重启?它替你重启,再把对话接回原来的会话。

简体中文 · English

MIT 许可证 仅 macOS 仅 DSH 桌面版 最新版本 Star 数

普通的「重启」只是关掉再打开:你正在做的事全没了,得从头解释一遍自己在哪一步。 这个插件补上缺的那一半——为什么重启、重启后第一步做什么,跟着进程一起活下来。

A plain restart throws the work away. This plugin keeps the "why" and the "what next" alive across the relaunch.

重启倒计时面板

它解决什么

Agent 改完插件代码,宿主会回一句 application: "restart-required"——改动只有重启才生效。于是你手动关掉 App、重新打开、想起来刚才做到哪、再打一遍需求。

这个插件把这三步接了起来:

  • 不用你记得——重启前先把「下一步做什么」写成交接话存到磁盘,重启后它作为会话的第一条消息出现;
  • 不打断回答——重启排到这一轮说完之后才执行,不会把句子截断在半路;
  • 不连环重启——冷却时间、尝试次数上限、一次性续跑,撞车时也只重启一次。

三种开始方式

触发源 谁发起 什么时候
自动 宿主监听 plugin_manager 的工具结果 结果里出现 restart-required,即改动必须重启才生效
工具 agent 主动调 restart_and_continue agent 知道自己刚改了什么,顺手把交接话写掉
手动 设置 →「重启并交接」→ 立即重启 你现在就想重启(这一种不续跑)

两条自动路径撞车时,后到的会让位(日志里是 hand-off request dropped),已排程或已在等待时返回 already-scheduled / already-deferred。

重启后会收到什么

不是模板,是模型自己写的一段话——插件只负责搬运,原样投递:

🔄 DSH 已自动重启完成,接着做未完成的部分

发生了什么:触发原因是 plugin-manager: host-module,上一轮是等回答说完、结果落盘之后才退出的(不是崩溃),上下文完整。

接下来怎么做:① 从这句话中断的地方继续:把 client.js 的新开关接上;② 先确认上一步有没有只做了一半。

模板只在三种情况下兜底:没给交接话、交接超时(2 分钟)、拿不到会话 id。

安装

前提:DSH 桌面版(Electron)。宿主这一半要重启 App,纯 web / CLI 宿主会拿到 status: "unsupported"。

从 Release 的 tarball 装(不需要 npm 账号):

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 指向它的是符号链接,HMR 收不到通知;改完 index.js / client.js 要 toggle 一次(或重启一次)才生效。

设置面板

设置 →「重启并交接」:

  • 检测到需要重启时自动重启——盯着 plugin_manager 的结果找 restart-required;
  • 允许 agent 主动重启——开放 restart_and_continue 工具;
  • 等本轮回答结束后再重启——默认开;关掉就是立刻重启,会打断正在作答的这一轮;
  • 重启后自动继续——重启后把交接话投回去;不勾选就只是重启,等你开口;
  • 立即重启——现在重启,不续跑;
  • 倒计时可取消,下面是最近几次事件的时间线。
空闲状态:守护中,四个开关,最近事件 等待模型写交接说明

设置存在 ~/.dsh/restart-handoff/settings.json,事件在 history.jsonl,完整日志在 ~/.dsh/restart-handoff.log。

一次重启的完整路径

改动需要重启
      │
      ├── 自动:宿主看到 restart-required → 用 steer 问模型
      │        「写交接话,然后调 restart_and_continue」
      │        └── 2 分钟没回音:用内置文案照常重启
      └── 工具:agent 调 restart_and_continue({ continuation })
      │
      ▼
挂起请求            pending.json ← { sessionId, continuation, reason, requestedAt, attempts }
      ▼
等这一轮说完
      ▼
1.5 秒倒计时(可取消)→ detached 的 sh helper
      │   退出 App · 清理 Electron 的 Singleton 锁 · open -n · 确认新主进程真的活着
      ▼
新宿主启动,插件加载,2.5 秒后:
      resolveAgent(sessionId) → prompt({ mode: "queue", content: [交接话] }) → 删掉 pending.json
      ▼
同一个会话收到的下一条消息,就是那段交接话

工具:restart_and_continue

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

工具立刻返回,不等重启,也不阻塞这一轮:

返回 含义
deferred 已挂起,这一轮说完再重启
scheduled 倒计时已经在跑
already-deferred / already-scheduled 已经有一次在排队了
cooldown / disabled / unsupported 冷却中 / 功能被关 / 不是桌面宿主

「重启完成」永远不会从这个工具返回——完成证据就是那段交接话本身,它作为下一条消息到达。

next_step 仍然接受,但已弃用,请用 continuation。

写入的文件

~/.dsh/restart-handoff/
├── pending.json     # 跨重启保留;交接话投递成功后删除
├── settings.json    # 第一次改设置时创建;没有文件 = 默认值
└── history.jsonl    # 面板时间线用的追加式事件日志
~/.dsh/restart-handoff.log   # 完整文本日志,含 helper 脚本自己的输出

已知边界

  • 只有桌面版。其它宿主拿到 status: "unsupported"。
  • 只有 macOS:重启 helper 是 /bin/sh 脚本,用 osascript 退出 App、open -n 重开。
  • 重启仍然会打断正在跑的那一步:shell 命令没法接着跑,只能重跑。交接话说的是「从哪继续」,不是「当时手里有什么」。
  • GUI 端口会变:重启后请用 App 打印出来的地址,别用书签。
  • 「立即重启」按钮不续跑,因为不写 pending。
  • 冷却时间存在内存里,重启后归零;但 pending.json 带着尝试次数和 10 分钟有效期,成不了无限重启循环。

开发

node --check index.js && node --check client.js
node test/smoke.mjs          # 状态读写往返 + helper 脚本断言,不需要装进 Harness

不装进 App 也能看面板长什么样(自带一个极简 React 替身 + 静态页):

cd test/preview && cp ../../client.js . && python3 -m http.server 8781
# 打开 http://127.0.0.1:8781/preview.html?s=idle

s 可选 idle / countdown / waiting / handoff / empty。

目录

.
├── index.js             # 宿主:排程、工具、post-execute 监听、HTTP 路由
├── client.js            # 设置面板(__ModuleLoader__ + settings.section)
├── lib/relaunch.js      # sh helper:退出 → 清锁 → open -n → 确认活着
├── lib/state.js         # pending / settings / history / log
├── cordis.patch.yml     # 一条 insert
├── locale/{en,zh}.json  # 插件列表里的名字与简介
├── icon.svg
├── docs/                # 面板截图
└── test/                # 冒烟测试 + 面板预览台

许可

MIT


English · 简体中文

—/ 5

No ratings yet

Verified DSH bundle

Commit 3ca8d43ae047

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout