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.

Safety Restart — DSH Plugin for DeepSeek Harness
DeepSeek Harness Plugin Hub
ProfilesPluginsCategoriesNewsDocsSign inManage Profiles
ProfilesPluginsCategoriesNewsDocsSign in
← Plugins
S

dsh-safety-restart

Safety Restart

DSH safe, seamless restart: the agent can restart the host itself and continue working, but must pass four checks first (a restart-loop circuit breaker, refusal if another session is running, refusal if the profile bundle cannot be parsed, and refusal if no reliable launch method is available). The

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

npx -y @deepseek-ai/dsh plugin --profile web add github:Dayi-Z/dsh-safety-restart#a72db0808fb0745caa0fb53efa3c3ad65d4c6e9f
READMECompatibilityVersions

Description

DSH safe, seamless restart: the agent can restart the host itself and continue working, but must pass four checks first (a restart-loop circuit breaker, refusal if another session is running, refusal if the profile bundle cannot be parsed, and refusal if no reliable launch method is available). The original session resumes automatically after the restart. Desktop uses Electron app.relaunch(); web/CLI uses a detached helper.

Compatibility and provenance

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

DSH compatibility
*
Runtime surfaces
web
Release source
github
Registry updated
9/12/2026

Versions

0.1.0stable
9/12/2026

Related plugins

Loading related plugins…

Latest
0.1.0
DSH
*
HMR
Process restart
Tree shaking
Safe tree shaking not declared
Unpacked size
Unavailable
Files
Unavailable
Surface
web
License
MIT
Source
github
GitHub
★ 0
Weekly downloads
0
Last push
9/12/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 agents-orchestration.

Headless@deepseek-ai/dsh-headlessThe dsh one-shot bundle: a direct core Agent/Session runner over dsh-base with no Host, HTTP, or browser layerExperimental Agent Team Web Profile@deepseek-ai/dsh-experimental-agent-team-web-profileExperimental Web profile layer for Agent Teams Remote and UI pluginsSubagent Codex@deepseek-ai/dsh-subagent-codexOne-shot Codex subagent provider over the official app-server protocolSubagent Claude Code@deepseek-ai/dsh-subagent-claude-codeOne-shot Claude Code subagent provider over the official Agent SDK

README

dsh-safety-restart

English TL;DR — A safe, seamless restart plugin for DeepSeek Harness. The agent can restart the host itself (host-half code changes only take effect after a full process restart) and gets woken up afterwards to continue. Before restarting it must pass four gates: restart-loop breaker, other sessions mid-turn, unresolvable profile bundles, and (on desktop) an unavailable app.relaunch(). Any gate that fails means refuse with a reason, never force it through. Desktop uses Electron app.relaunch(); web/CLI uses a detached helper.


DSH 的安全无感重启插件。

它解决什么

改完宿主半(index.js / lib/*.js)必须整进程重启才生效。这不是洁癖,是实测:

回收渲染器进程只会重载外壳。插件确实会重新 apply、日志也照打,但服务请求的那张路由表仍然是更早那次 apply 的 —— 新加的路由一律 404,而返回的是插件自己那句 not found,看起来像"路由写错了",其实是"根本没走到新 handler"。

而在此之前 agent 没有重启的手段:只能让用户去点。这个插件把它变成一次工具调用。

四道闸("安全"具体是什么)

每一条都对应一次真实踩坑,不是设想出来的风险。

闸拒绝条件为什么
重启循环熔断窗口内已重启 ≥ loopMax(默认 3 次 / 10 分钟)一个起不来的配置会让每次启动都失败,而 agent 看到失败只会想再重启 —— 那是重启风暴,代价是机器一直在 boot
有别的会话在跑一轮除调用方外还有会话处于 turn/start 之后未 turn/end(除非 force: true)盲着重启会把别人正在做的事从中间切断,而且切断后那一轮的工具调用结果未知
profile 的 bundle 表解析不了某个 bundle 在 node_modules 里不存在、或入口文件不存在重启进一个坏掉的 profile,得到的是起不来的 app —— 连报错界面都没有
拿不到可靠拉起手段桌面端 electron.app.relaunch 不可达绝不退化成"杀进程":那会把 app 关掉而不拉起来,把可恢复的状态变成不可恢复的

任一不过就是拒绝重启并说明原因,返回里带 gate 与 why。拒绝不是失败 —— 那道闸就是为了不让你把环境弄成不好收拾的样子。

无感在哪

  1. 重启前写续作标记(会话 id),重启后把"你已经重启过、请继续"投回原来那个会话。 顺序是刻意的:先写标记,再拉起。反过来会在进程先退出时丢掉标记。
  2. 续作提示里明确要求:重启前结果未知的工具调用不要盲目重试,先核查实际影响。
  3. 标记消费掉就删;标记文件损坏时返回空数组而不是抛 —— 重启后的启动不能因为读标记而挂。

两条重启路径

环境机制为什么不能只用一种
桌面端(Electron 内嵌宿主)app.relaunch() + 延迟 app.quit()桌面端宿主的 webServer 是 IPC 载体(app://),不开端口 —— 任何"起 helper 等健康检查通过"的做法在这里都不成立
web / CLI写一个 detached helper(detached:true + stdio:'ignore' + unref()),老进程随后 process.exit(0)helper 必须在父进程死掉之后继续活着;它等旧 pid 退出 → 用同一份 execPath / execArgv / argv 拉起新实例 → 等它活过 10 秒 → 把结果写进审计

装

// profiles/<name>/package.json
{
  "dependencies": { "dsh-safety-restart": "link:/path/to/dsh-safety-restart" },
  "dsh": { "profile": { "bundles": [ "...", "dsh-safety-restart" ] } }
}

装完必须重启一次 app —— 插件自己也要先被加载才谈得上重启。

用

Agent 侧(工具):

safety_restart({ reason: "改了宿主半的 index.js,让新路由生效" })
safety_restart({ reason: "...", force: true })   // 即使有别的会话在跑一轮也重启

人侧:设置 → 插件 → 「dsh-safety-restart」卡片(运行环境、熔断计数、最近一次审计、立即重启)。

HTTP(web 端;只接受本机请求,反代/远程访问会被 403):

GET  /safety-restart/status
POST /safety-restart/restart   { "reason": "ui" }

审计与状态文件

都在 $DSH_HOME(默认 ~/.dsh):

文件内容
safety-restart-audit.jsonl只追加。一次重启算一次的判定是 kind:"restart" && phase:"scheduled";其余(helper / exit / quit / refused / resume)都是诊断信息
safety-restart-resume.json续作标记(待叫醒的会话 id),消费后删除
safety-restart-helper.mjsweb 端生成的 helper(每次重写)
safety-restart.json可选配置:loopWindowMs / loopMax / delayMs / busyStaleMs

配置

{
  "loopWindowMs": 600000,
  "loopMax": 3,
  "delayMs": 1500,
  "busyStaleMs": 1800000
}

delayMs 是"发起重启"到"真的退出"之间的等待,留出时间把这次工具结果回传给模型。设成 0 会让结果大概率丢掉。

已知限制(如实写,不粉饰)

  • busy 只覆盖本进程启动之后的轮次。 它是按 session/event 维护的,更早就在跑的会话不在里面。所以第二道闸是"尽力而为",不是权威快照。超过 busyStaleMs 的记录会被当作过期清掉(防止一条漏掉的 turn/end 把闸门永久焊死)。
  • bundle 体检是轻量的:它只证明"包在、入口文件在",不证明它能被 import 成功,更不证明客户端半在 slot 契约上是对的。要那一层用 dsh-guardian 的 bundle scan。
  • web 端退出是 process.exit(0)(非优雅)。 会话日志是只追加的 jsonl,写到哪算哪;工具结果在 delayMs 之前已回传;尾巴真被截了也有续作提示兜。不退就永远重启不成,那才是真的坏。
  • 客户端半按 rc 契约写:settings.plugin.item 在 rc.12 是 list(要 id),更晚的契约是 keyed(要 key)。所以两个都传 —— 多传一个用不到的字段不会报错,少传必需的那个才会。整个 apply 包在 try/catch 里:契约再漂,结果也只是"没有这张卡片",不会牵连界面。

这里的坑都是踩过的

开发过程中端到端测出来、并已修掉的两个:

  1. web 路径最初根本没完成:helper 起来了、等了 30 秒、然后报 old pid still alive — giving up。因为没有任何人让老进程退出 —— helper 等的是"老进程死掉",而它就那样继续服务着。修法是 helper 起来后老进程自己 process.exit(0)。
  2. 熔断计数翻倍:一次重启会在审计里留下多条(begin/scheduled/helper/quit),全数进来会让"一次重启动"算成两次 —— 实测第三次就直接熔断了,而配置写的是 3。修法是只数一条。

自检

node scripts/run-all.mjs

37 条断言,都是"闸门的判定边界":熔断窗口与计数口径、checked:false 的诚实降级、标记损坏不抛、生成的 helper 是合法 ESM、会话 id 的三种取值回退、调用方自身的排除。

License

MIT