DSH Plugins Marketplace

DSH Plugins

Plugins

/

dsh-systemd-restart

5

dsh-systemd-restart

Discovered

DeepSeek Harness plugin: a restart row in Settings -> General that ends the host gracefully and lets the systemd unit's Restart=always bring it back. No detached helper, so KillMode=control-group cann

dsh-systemd-restart

DeepSeek Harness(dsh)插件:在设置 → 通用里加一行「重启 dsh web」按钮。

它和常见的重启用插件最大的区别是重启机制:不派分离进程(detached helper,独立子进程), 而是让宿主自己优雅退出,交给 systemd 的 Restart=always 把它拉起来。

为什么需要它

一个进程无法替换自己,所以「重启」天然是两件事:结束旧的、启动新的。常见做法是派一个 detached helper 去做第二件事 —— 但 helper 和宿主在同一个 cgroup 里。systemd 默认的 KillMode=control-group 会在服务停止时清掉该 cgroup 内的所有进程,helper 跟着陪葬, 于是「重启」变成「把服务杀了、没人拉起来」。dsh-simple-restart 与 dshmarket 因此 选择在检测到 systemd 监管时直接拒绝(本机实测:按钮返回 403)。

本插件走 systemd 本来就期望的那条路:

[按钮] → 围栏校验 → 先回 202 → 写 boot 标记 → 宿主给自己发 SIGTERM
       → dsh 核心优雅收尾(dispose 插件树 / 会话落盘 / 关 HTTP / exit 0)
       → systemd 按 Restart=always 用原 ExecStart 拉起
       → 新进程读 boot 标记,算出停机时长写回那一行

零权限(不调 systemctl 就不需要 polkit / DBus 授权)、零端口竞态(没有第二个进程抢 3080)。

安装

要求:dsh 0.2.x 的 web profile;宿主由 systemd 用户级 unit 托管,且该 unit 的 Restart=always。 不满足时按钮不会假装能用 —— 它会在那一行写清拒绝的理由。

git clone https://github.com/534056668/dsh-systemd-restart.git
cd dsh-systemd-restart
bash install.sh

install.sh 先给 profile 的 package.json / pnpm-lock.yaml 打带时间戳的备份,再执行 dsh plugin --profile web add "$(pwd)",最后打印装配状态。不想用脚本,等价的一步是:

cd ~/.dsh/profiles/web && dsh plugin --profile web add /path/to/dsh-systemd-restart

装完刷新一次页面:宿主半会随 patchReload: live 立即生效,客户端那一行在页面加载时组装。

使用

设置 → 通用 / General → 重启 dsh web:

  • 第一次点击武装按钮(确认重启?,5 秒后自动取消),第二次点击执行;
  • 提示行先说清这台机器会怎么重启(例如「unit dsh-web.service 的 Restart=always:进程退出即被拉起,不需要任何权限」),以及上次重启的停机时长;
  • 页面断开后在后台轮询 boot id,新进程一开始服务就自动刷新;120 秒还没起来就停下并给出日志位置。

配置

行级 config(在 profile 的 cordis.patch.yml 里用 - id: systemd-restart + config: 覆盖; 注意它是整体替换,不是逐键合并):

键类型默认含义
modeauto / kill / systemctl / offauto重启方式。auto 读 unit 的 Restart= 决定
delayMsnumber1500回执发出后等多久再退出,给浏览器留出收到 202 的时间
unitstring''显式指定 systemd unit;留空则从 /proc/self/cgroup 探测
stateFilestring''状态文件路径;留空则用 $DSH_HOME/storages/dsh-systemd-restart/state.json
maxRestartsnumber3窗口内允许的重启次数,超出直接拒绝
windowMsnumber600000上面那个窗口(毫秒)

auto 的判定:unit 的 Restart=always → kill;否则若本机有 systemd-run 且是用户级 unit → systemctl(在独立 cgroup 的瞬时单元里跑 systemctl --user restart,所以不会被连坐); 两者都不成立 → off,并在按钮那一行写清原因,而不是假装能用。

HTTP 接口

路由方法作用
/dsh-systemd-restart/api/statusGET只读:boot id、pid、探测到的 unit 与 Restart=、将要采用的方式及理由、上次重启记录、循环守卫计数
/dsh-systemd-restart/api/restartPOST重启。先过围栏再动任何东西

围栏(重启路由):非 POST → 405;socket 对端不是 loopback → 403;带任何转发头 (forwarded / x-forwarded-for / x-real-ip)→ 403;缺 Origin 或 Origin 的 host ≠ Host → 403;mode 判定为 off → 403;已有重启排程 → 409;超出循环守卫 → 429。 通过后返回 202 并附上 boot.id(客户端据此判断「新进程起来了没有」)。

限制

  • 只支持 systemd。手敲 dsh web 起的进程没有任何东西会在它退出后拉起它 → 拒绝重启 (这正是本插件存在的理由:不做「杀了回不来」的事)。
  • 系统级 unit(/etc/systemd/system/...)不行:重启它需要 root/polkit,脚本会拒绝。
  • 重启会掐断正在跑的回合(本插件的取舍:点了就重启,不等待会话空闲)。
  • 端口与 unit 的探测是 Linux 特有的;其他平台一律判为 off。

自检

npm test          # 46 项离线断言:决策逻辑、两个路由的围栏与拒绝、循环守卫、boot 记账、客户端 bundle 与两个半边的路径一致性

测试从不真的重启任何东西:唯一会触发退出的那条路径(合法 POST + 非 off 模式)被刻意排除。

装到真实环境后按 dsh 插件 SOP 的「闸⑤」验收:

OFF=$(wc -c < ~/.dsh/web-stdout.log)     # 该文件是追加式的,先记偏移
systemctl --user restart dsh-web
sleep 20
tail -c +$((OFF+1)) ~/.dsh/web-stdout.log | grep -nE "did not activate|failed to import"
curl -s http://127.0.0.1:3080/dsh-systemd-restart/api/status   # 需带登录凭据,未登录会 401

许可与出处

MIT。

  • 设置行的排版(16px 内边距 + 发丝分隔线 + 36px 胶囊按钮)与同源 loopback 围栏的写法, 参考了 dsh-simple-restart(MIT)——它把「按钮该长什么样、围栏该怎么写」试对了, 只是重启机制(detached helper)在 KillMode=control-group 的 unit 上走不通;
  • 「让进程退出、由服务管理器拉起」这条机制在生态里被反复验证过: @goodandready/dsh-smart-restart(默认 restartMode: kill)、dsh-restart-handoff、 @gehennawu/dsh-service。

Comments

Loading…

Similar plugins

dsh-autorestart

by Eason-22

DeepSeek Harness plugin: restart without losing work, with an idle-aware graceful restart and automatic session resume after the host comes back. Built-in restart supports the Windows desktop app only

Sessions & MessagesManifest valid

★ 0

MIT

JavaScript

Oct 28, 2026

dsh plugin --profile web add dsh-autorestart

by chenkui-luo

A Restart button for DeepSeek Harness Settings: replaces the dsh web process serving the page, then reconnects the page by itself.

Development & InfrastructureTerminal & ClientsManifest valid

★ 1

MIT

JavaScript

Oct 12, 2026

dsh plugin --profile web add dsh-plugin-restart

by 893413974-bit

One-click restart of the DSH service from Settings → General. A dsh-plugin for DeepSeek Harness; the restart row stays pinned at the bottom of the general settings page. 在设置 → 通用设置中一键重启 DSH 服务。DeepSe

UI & ExperienceManifest valid

★ 22

↓ 503/wk

MIT

JavaScript

Aug 18, 2026

dsh plugin --profile web add dsh-setting-restart

by 13520rygvv

DSH desktop plugin: a one-click restart button in Settings, plus a customizable shortcut.

Tools & CapabilitiesUI & ExperienceManifest valid

★ 1

JavaScript

Oct 27, 2026

dsh plugin --profile web add @local/dsh-restart-button

by PPsz-qqq

DeepSeek Harness plugin: one-click restart button in the top-right of the session header (Windows desktop + dsh web). 一键重启 DeepSeek Harness 客户端。

UI & ExperienceDevelopment & InfrastructureManifest valid

★ 5

↓ 50/wk

MIT

JavaScript

Oct 3, 2026

dsh plugin --profile web add dsh-restart-button

by pandashere

Self-control guard plugin for DeepSeek Harness host exit and restart workflows.

Manifest valid

★ 4

MIT

TypeScript

Aug 13, 2026

dsh plugin --profile web add self-control-guard