DeepSeek Harness Plugin Hub

Publish and manage complete Harness Profiles. Discover Plugins for your next setup.

Explore

PluginsPresetsDocsNews

Community

Publish a pluginContactReport an issue

Resources

Plugin Hub on GitHubDeepSeek HarnessSystem statusPrivacy notice
© 2026 DeepSeek Harness Plugin HubPowered byPaxTech

Independent and unofficial. Not affiliated with, authorized by, or endorsed by DeepSeek.

DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins

dsh-restart-guard

Restart Guard

Watchdog plugin for DeepSeek Harness web: survives the host process, detects failed restarts and upgrades, repairs what can be repaired, and reports to IM, webhooks or logs.

The plugin will be installed here. Keep web if you are unsure.

npx -y @deepseek-ai/dsh plugin --profile web add dsh-restart-guard@0.1.6
READMECompatibilityVersions

Compatibility and provenance

Restart Guard is published as dsh-restart-guard and currently resolves to version 0.1.6. The Hub verifies its manifest and preserves the exact installation source for reproducible installs.

DSH compatibility
*
Runtime surfaces
web
Release source
npm
Registry updated
11/1/2026

Versions

0.1.6stable
11/1/2026
0.1.4stable
10/31/2026
0.1.1stable
10/31/2026

Related plugins

Loading related plugins…

Latest
0.1.6
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
394.2 kB
Files
38
Surface
web
License
MIT
Source
npm
GitHub
★ 1
Weekly downloads
0
Last push
11/1/2026
View source ↗
README badge

Click the badge to copy Markdown for your README.

Do you maintain this Plugin?Claim benefit · Priority security scan

Verify the GitHub repository declared in package.json to manage this listing. After you claim it, Hub will prioritize a security scan of the current version and publish the result when it passes.

Claim this Plugin →
Report an issue

Related plugins

More verified plugins in integrations-communication.

Remote Web Ui@linxin666/dsh-remote-web-uiScan-to-pair remote access for the dsh web GUI that shares one official interface: a QR beside the settings button pairs phones and PCs into the same Web GUI (a portrait-touch adaptation layer for phones, full desktop on PCs) through one-time tokens and rRemote Bridge@linxin666/dsh-remote-bridgeDSH remote bridge: the host half serves protocol v1 over one exact /ios/v1 WebSocket route — session roster, history baseline, prompting, live turn increments with tool activity, interrupt, and in-process agent approval — to a device paired by a one-shot Ds Botds-botDS Bot: a team of long-lived Bots for DeepSeek Harness, with Main Bots, Bot-to-Bot messages and group chatsPocketdsh-pocketPut DeepSeek Harness in your pocket: one package, one settings page, and scan a QR code on your phone to access DSH on your computer in sync (LAN + public network, real-time screen mirroring).

README

dsh-restart-guard · 重启守护

English · 简体中文

为 DeepSeek Harness 的 Web 服务加一个能在宿主进程死掉后继续存活的守护进程:发现重启没起来,按一组小规则判断原因,能修的自己修,修不了就把过程和结论发到你指定的渠道(IM、Webhook、命令或本地日志)。

它解决的问题很具体:容器/脚本里 dsh web 是后台启动、启动器随后 exec 成代理,没有任何 supervisor 会在插件加载失败、patch 写坏、端口被占时把服务拉起来。页面 502 到有人发现为止,中间没有任何信息。

DSH 宿主 (dsh web)                     独立 watcher
┌───────────────────────┐   spawn    ┌──────────────────────────────┐
│ 插件:体检 / 路由 /   │ ─────────► │ 每 2s 探测 127.0.0.1:<port>/  │
│ 设置页                │            │ 字节偏移确认就绪 → 诊断 → 修复 │
│                       │ ◄───────── │        → 通知                 │
└───────────────────────┘  state.json└──────────────────────────────┘
        │ 崩溃 / 被杀                         │
        ▼                                     ▼
   端口消失  ─────────────────────────►  重启 / 回滚 patch / 停下并告警

能力

  • 活得比宿主久:watcher 由插件以 detached 方式拉起,和 DSH 没有父子关系;kill -9 DSH 不会带走它。
  • 知道什么叫“起来了”:401 且正文是 DSH 的鉴权文案,或 200 且含 __DSH_BOOT__ 才算 DSH;普通的 200 HTML 是陌生监听者,既不算健康,也绝不会被当成 DSH 杀掉。
  • 只认新进程的新日志:就绪判定读取本次 spawn 之后追加的字节,必须出现带 token 的 dsh web: 访问行,再 settle 复验。整文件 grep 会命中旧行、拿到旧 token,这里刻意不做。
  • 有边界的修复阶梯:用抓到的 argv/env/cwd 重启;把 cordis.patch.yml 回滚到能通过 --dump-config 的最新备份;或者停下并把证据交给人。每个事件最多启动 2 次;10 分钟 3 次崩溃进入 30 分钟暂停,避免重启风暴。
  • 升级/维护期免误判:显式维护窗口、包树 inode/版本变化、<pkgRoot>.prev-* 等兄弟目录、包管理器进程、$DSH_HOME/upgrade 最新目录、慢启动六路信号任一命中即进入维护态:不启动、不回滚、不杀进程。
  • 尊重主动停止:宿主 exit(0) 被当作“操作者有意停的”,不拉起。
  • 通知到你所在的地方:本地日志恒开;Webhook(飞书、企业微信、钉钉、Slack、Telegram、Discord、ntfy、healthchecks、通用 JSON);任意命令(argv 直传、消息走 stdin);dsh-im 插件(宿主不在线时先落盘,回来后补发)。设置页点“扫描 dsh-im”可直接从已装插件里列出 bot 与 target,不用手抄 ID。
  • 装完就告诉你环境缺什么:设置页顶部有体检卡(启动日志、patch 备份、Webhook/IM、监督者、维护态),每个缺口都给出可操作提示;另有一键“模拟崩溃”演练(守护自己造成的停机不会被当成“卡死”,会直接重启)。
  • 可选 AI 辅助判定:规则确实没有安全动作时才征询模型,模型只能选“重试 / 回滚 patch / 等待 / 人工”,不会执行任何命令(详见下文)。

安装

# 1. 本地目录或 npm 包
cd /path/to/dsh-restart-guard
pnpm install --ignore-scripts

# 2. 链接进 profile(会备份 package.json 并跑 pnpm install)
npx dsh-restart-guard install --profile web
#    或:dsh plugin --profile web add dsh-restart-guard
#    然后手动把 "dsh-restart-guard" 加进 profiles/web/package.json 的 dsh.profile.bundles

# 3. 重启 DSH,让插件加载(watcher 随宿主启动)

重启后打开 设置 → 重启守护:顶部体检报告会列出还缺什么(Webhook 地址、IM 的 botId/targetId、启动日志路径……),在页面里补完,点 测试通知。

命令行核对:

dsh-restart-guard status      # watcher / 阶段 / 最近健康状态
dsh-restart-guard doctor      # 与设置页同一套体检
dsh-restart-guard logs -f     # 跟随守护日志

环境要求

项要求
Node≥ 22
DSH≥ 0.2.1(用到 host 插件 API 与 webServer.tapIndex)
系统Linux 完整支持(依赖 /proc);macOS 可用探测与监督逻辑,进程/端口映射回退到 lsof
运行时依赖无

升级 DSH 时

照常升级即可。升级脚本通常会杀掉旧进程、换树、再拉起;watcher 能从换树/兄弟目录/升级目录/包管理器进程/restarter 进程识别出“这是维护”,只观察、不抢端口、不中途回滚文件。维护窗口是锚定的:同一信号沿用原截止时间,不会因为进程还在而每 2 秒往后顺延;每个窗口只通知一次(信号变化才再发),显式窗口(maintenance start --minutes N)严格按 N 分钟结束、不额外加 graceMs。

修复判定

探测失败 → 宽限 → 诊断 → 计划:

诊断(先匹配者优先)日志示例动作
yaml-configYAMLException、bad indentation回滚到最新可用备份,再启动
patch-incompatiblecannot get property "webRuntime" without inject首次回滚,之后仅重启
wildcard-hosthost "0.0.0.0" is an unspecified (wildcard) address停下,需改配置
port-in-useEADDRINUSE端口被占:停下(开启 killStaleDshHolder 时只清理旧 DSH)
module-missingCannot find module停下,依赖缺失
permission-disk-memoryEACCES、ENOSPC、ENOMEM停下,环境问题
crashSegmentation fault、Killed重启
startup-failed / plugin-failedentries did not activate、failed to apply loader entry重启
stalled进程在、端口静默超过 stalledExitMs杀掉僵死进程再启动
timeout超时未就绪重启
unknown其它重启

每个事件都会写 incidents/*.json、ALERT.md、一行日志,并按配置发通知。不自动修复的情形:非 DSH 进程占着端口、维护窗口内、包树不完整、通配地址绑定、缺模块、权限/磁盘问题、以及开启尊重主动停止时的 exit(0)。

AI 修复(可选,默认关闭)

开启后守护多一档修复手段,分两种模式:

  • act(默认)· 完全权限:一旦判定服务起不来,先让 AI 直接处理——提示词里附带当前环境(端口、宿主 pid/运行时长、node 与 DSH 版本、profile 路径、cordis.patch.yml 及最近备份、启动日志路径与大小、端口监听者、诊断与证据、/proc 抓到的启动命令),再附上脱敏后的日志尾部;AI 可以读文件、改配置、补依赖、回滚 patch、重启服务,随后守护复验端口。先试 dsh 本体(dsh --profile <p> headless "<prompt>",继承 DSH 自己的模型凭据与工具权限),再试插件直连(HTTP / 桥接);两者都不行才回退到原来的规则阶梯(重启 → 回滚 → 人工)。
  • advise · 只判定:不给动作权限,只回一个 JSON 判定(retry/rollback-patch/wait/manual),映射到已有白名单动作;模型输出永远不会被当作命令执行。

安全边界:维护窗口、包树不完整、有真正的监督者(systemd/pm2)时 AI 也不会动手;发送的日志已脱敏,环境变量只发键名,密钥与访问令牌不外发;不开启就没有任何外发。硬停与“非 DSH 进程占端口”同样不会被覆盖。

在 设置 → 重启守护 → AI 修复 里开启,选择模式与尝试顺序(dsh-agent-first / direct-first / dsh-agent-only / direct-only),再配服务商与密钥来源。密钥默认直接借用 DSH 自己的:读 $DSH_HOME/.credentials.yaml 的 refs: 块(DEEPSEEK_API_KEY、XIAOMI_API_KEY、OPENAI_API_KEY、ANTHROPIC_API_KEY),所以即使 dsh web 本身起不来,AI 修复仍然可用;也可改成只读环境变量(ai.credentialSource: "env")、只读 DSH 凭据库("dsh")或指定凭据名(ai.keyRef)。密钥只读、不写配置、不落日志。

ai.dshAgent 控制“dsh 本体”通道(command 默认 dsh、args 默认 ["headless"]、timeoutMs 默认 300000)。不想让守护直接连 API 时开桥接(ai.bridge):提示词写程序 stdin、判定从 stdout 读。点 测试 AI 验证链路,命令行等价命令 dsh-restart-guard ai-test。

配置

全局文件:$DSH_HOME/restart-guard/config.json(0600)。设置页可改,watcher 自动重载。

{
  "enabled": true,
  "locale": "auto",
  "watchdog": {
    "probeIntervalMs": 2000,
    "probeTimeoutMs": 3000,
    "startupGraceMs": 30000,
    "bootTimeoutMs": 120000,
    "settleMs": 5000,
    "stalledExitMs": 20000,
    "maxRestartAttempts": 2,
    "rollbackProfilePatch": true,
    "killStaleDshHolder": false,
    "respectIntentionalStop": true,
    "crashLoop": { "windowMs": 600000, "maxIncidents": 3, "pauseMs": 1800000 }
  },
  "maintenance": { "autoDetect": true, "graceMs": 900000, "lookbackMs": 1800000 },
  "logs": { "bootLogPath": "", "mirrorToHostLog": true },
  "ai": {
    "enabled": false, "preset": "deepseek", "endpoint": "", "model": "",
    "keyEnv": "DEEPSEEK_API_KEY", "keyRef": "", "credentialSource": "auto",
    "bridge": { "enabled": false, "program": "", "args": [] }
  },
  "notify": {
    "webhook": { "enabled": false, "preset": "generic", "url": "" },
    "command": { "enabled": false, "program": "", "args": [] },
    "im": { "enabled": false, "botId": "", "targetId": "", "format": "markdown" }
  },
  "supervision": { "mode": "auto" },
  "security": { "allowRemoteMutations": false, "dangerousActions": false }
}

bootLogPath 通常不需要:宿主健康时守护会从 /proc/<pid>/fd/1 抓真实 stdout。若启动器把 stdout 接成管道,再手动指定。

logs.mirrorToHostLog(默认 true):守护把自己的日志行以 [dsh-restart-guard] 前缀追加进宿主的 stdout(即 bootLogPath 或抓到的 stdout 文件),所以容器部署时 docker logs <container> 里能直接看到“谁在修、修到哪一步”,不必再进容器翻 $DSH_HOME/restart-guard/。它只写这一行前缀,不会伪造 DSH 自己的访问行,就绪判定不受影响。

supervision.mode 决定“谁负责重启”:auto(默认)识别 systemd、pm2、supervisord 和容器;none 表示没有别的程序会重启 DSH,让守护照常动手(适合 CI,或 PID 1 是 systemd 但平台并不会重启服务的容器);supervised 表示只报告、不动手,用于检测不到真正归属者的场景。

  • 状态目录 $DSH_HOME/restart-guard/ 必须能跨重启保留。
  • 已有 systemd/pm2 等 supervisor 时,守护只报告,不与 supervisor 抢端口。
  • 容器启动器自己会重启 DSH 时,守护在仲裁阶段看到端口恢复就等待,不会起第二个服务。

通知渠道

渠道配置说明
日志恒开.../instances/<profile>-<port>/restart-guard.log,5 MB 轮转、保留 2 份
Webhooknotify.webhook 或 DSH_RESTART_GUARD_WEBHOOK_URL预设:feishu、wecom、dingtalk、slack、telegram、discord、ntfy、healthchecks、generic
命令notify.commandargv 直传(不经过 shell),消息写 stdin
IMnotify.im 或环境变量需要 dsh-im 插件;发不出去先落 outbox,宿主回来后补发

消息按事件节流(60 秒),默认附 40 行日志尾部,token/cookie 已脱敏;除非显式开启,不含启动 token 与访问地址。

CLI

dsh-restart-guard status [--json]      watcher/阶段/健康摘要
dsh-restart-guard doctor               环境体检 + 提示
dsh-restart-guard logs [-f] [-n N]     守护日志
dsh-restart-guard incidents            最近事件
dsh-restart-guard outbox               待补发的 IM 消息
dsh-restart-guard restart|start|rollback|simulate-crash
dsh-restart-guard pause --minutes 30   暂停自动修复
dsh-restart-guard resume
dsh-restart-guard maintenance start|end [--minutes 60] [--reason upgrade]
dsh-restart-guard notify-test          发测试消息
dsh-restart-guard ai-test              征询一次 AI 判定(不执行动作)
dsh-restart-guard reload               重载配置
dsh-restart-guard install|uninstall [--profile web] [--dry-run]
dsh-restart-guard purge                清空全部守护状态

CLI 通过控制文件与 watcher 通信(不需要页面 token);动作需要存活 watcher,否则退出码 3。

安全与隐私

  • 无遥测。没配渠道就是零外连;AI 默认关闭。
  • 设置页 API 使用注入到页面壳里的每页 token;变更只接受 POST、动作白名单、请求体 ≤64 KB;远程变更默认拒绝(security.allowRemoteMutations)。
  • 日志与通知在落盘/外发前脱敏(Webhook URL、IM id、token、cookie、Authorization、常见密钥字段);环境变量只存键名,不存值。
  • 数据在 $DSH_HOME/restart-guard/:目录 0700、配置与计划 0600;写入不跟随符号链接。

细节见 SECURITY.md、PRIVACY.md。

排障

现象检查
没有 watcherdsh-restart-guard status;宿主启动后 10 秒内会拉起,插件日志里有 watcher-spawn
端口起来了但守护没反应体检里的 boot-log:没抓到 stdout 时仍能靠 HTTP 判定,但无法确认新 token
不重启状态是 maintenance/supervised:升级期和 systemd 下这是预期行为
反复重启state 文件里有诊断;修好后 resume
IM 没动静先从 设置 → IM Bot 复制 botId/targetId,用“测试通知”验证

QQ 机器人只暴露 Bot ID:targetId 可以留空,守护会在该 bot 只有一个投递目标时自动使用它;还没有目标时,先和机器人私聊一次(或拉进群),再到 dsh-im 里“新建目标”,然后回到设置页重新扫描。

更多见 docs/TROUBLESHOOTING.md。

开发

pnpm install --ignore-scripts
pnpm run typecheck      # tsc --noEmit,无构建步骤
pnpm test               # node:test,含针对假 dsh 的 e2e
pnpm run build:client   # 由 src/client.jsx 重新生成 lib/client.js
node scripts/build-client.mjs --check   # CI:bundle 已提交且是最新

架构与不变量见 docs/ARCHITECTURE.md。

许可证

MIT,见 LICENSE。