🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

无缝重启续跑 StvLi/dsh-phoenix

DeepSeek Harnessv0.2.5
StvLi63 天前有提交已提供中文文档扫描:含敏感能力

优雅重启不打断任务,页面自动重连并续跑目标

32.1/100
综合分
5
GitHub 星标
61
npm 周下载
—/5
用户评分

数据截至 2026/9/3 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add dsh-phoenix
npm 源 · dsh-phoenix 的发布者账号已校验与本仓库一致

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · skill
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 63 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查✓ 自动检查通过
展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✓npm 包dsh-phoenix @ 0.2.5
✓Node 引擎要求 >=22 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/18 00:25:57

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件
查看扫描证据(共 5 处,展示前 5 条)
  • 读取本地文件
    lib/index.js:41
    if (existsSync(p)) return p
  • 读取本地文件
    lib/index.js:249
    return parseState(readFileSync(cfg.stateFile, 'utf8'))
  • 读取本地文件
    lib/index.js:253
    if (!existsSync(cfg.stateFile)) return defaultState()
  • 写入本地文件
    lib/index.js:265
    writeFileSync(tmp, JSON.stringify(s, null, 2))
  • 写入本地文件
    lib/index.js:266
    renameSync(tmp, cfg.stateFile)
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 全包扫描 · 来源 npm 发布包

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-tools@deepseek-ai/dsh-agent-presets
给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 优雅重启不中断
  • 客户端自动重连
  • 跨重启续跑目标

为 DeepSeek Harness(dsh)提供不中断、可恢复的生命周期:优雅重启 + 客户端自动重连 + 跨重启目标续跑。

v0.2.52026-09-01
持久目标续跑:标记过的目标只要还在进行,每次重启后都会重新续跑,续跑状态(goalId/pendingResume)一直保留,直到目标完成、过期或续跑次数用尽。已在多次重启中端到端验证,共 21 项测试。
v0.2.42026-09-01
修复:defer 截止时间原先按时长(900000)与 epoch 比较,结果恒为真,首次轮询就强制重启。现在把 epoch 截止时间传给 deferDecision(soft = hard - span),并新增一个不会提前强制的测试,共 21 个测试。
v0.2.32026-09-01
修复:(1) 优雅重启现在不依赖 DSH_PHOENIX_STATE_FILE 也能工作(生命周期在内存中;持久恢复与续跑仍需该文件)。(2) 恢复流程会等待一个有界窗口,让目标完成注册,再判定其过期。(3) 心跳重载已做缓存失效处理(不再出现旧 token 重载循环)。20 项测试。
数据来自仓库的 GitHub Release,可能与插件实际版本不一致。

README

由 DeepSeek 最新模型翻译生成
🐦 dsh-phoenix 为 DeepSeek Harness(dsh)提供"永不中断、可续跑"的生命周期 dsh-phoenix 是一个持久的 DeepSeek Harness host 插件,它把 "插件更新 → 重启 dsh" 从一次破坏性的中断,变成一条优雅、无缝、可续跑的循环——让正在运行的任务能跑完、浏览器能保持连接、长时目标能跨重启继续进化。 English · 中文版 为什么你需要它 DeepSeek Harness 是"一切都是插件",而 dsh Web 是由 systemd 托管的单个常驻进程。这带来三个痛点: | 痛点 | dsh-phoenix 的做法 | | 更新插件意味着硬重启 dsh,会切断正在运行的任务 | 优雅重启——等地步空闲才重启,让当前任务先跑完再重启。 | | 后端重启后,浏览器页面掉线并卡死("已停止") | 自动重连——注入一段极小心跳脚本,后端一恢复页面就自动刷新。 | | 重启会清空内存中的目标状态,目标无法跨重启继续 | 重新武装目标——重启后重新激活一个被解武装的目标,让长时目标恢复并继续进化。 | ✨ 功能特性 1. 优雅重启——只在安全时重启 - 通过 dsh 插件工具识别插件(重新)激活(cordis_run),不立即重启。
展开完整文档(README 剩余 1 节)
🐦 dsh-phoenix

为 DeepSeek Harness(dsh)提供"永不中断、可续跑"的生命周期

dsh-phoenix 是一个持久的 DeepSeek Harness host 插件,它把 "插件更新 → 重启 dsh" 从一次破坏性的中断,变成一条优雅、无缝、可续跑的循环——让正在运行的任务能跑完、浏览器能保持连接、长时目标能跨重启继续进化。

English · 中文版

为什么你需要它

DeepSeek Harness 是"一切都是插件",而 dsh Web 是由 systemd 托管的单个常驻进程。这带来三个痛点:

| 痛点 | dsh-phoenix 的做法 |
| 更新插件意味着硬重启 dsh,会切断正在运行的任务 | 优雅重启——等地步空闲才重启,让当前任务先跑完再重启。 |
| 后端重启后,浏览器页面掉线并卡死("已停止") | 自动重连——注入一段极小心跳脚本,后端一恢复页面就自动刷新。 |
| 重启会清空内存中的目标状态,目标无法跨重启继续 | 重新武装目标——重启后重新激活一个被解武装的目标,让长时目标恢复并继续进化。 |

✨ 功能特性

1. 优雅重启——只在安全时重启
- 通过 dsh 插件工具识别插件(重新)激活(cordis_run),不立即重启。
- 检查所有活体 agent(含子代理):只要有 running,就延后,每隔几秒复查,等地步空闲才重启(5 分钟兜底,避免永不重启)。
- 通过 systemd-run --user 以独立瞬时 unit 执行重启,即使被重启的进程本身也能等到重启完成。
- 只响应 cordis_run——dsh 自带 HMR 热载的客户端 bundle 源码改动不属于 cordis_run 操作,因此不会触发 dsh-phoenix 重启。

2. 客户端自动重连——页面始终与后端同步
- 注册一个 /__dsh_health 端点,返回本次启动 token。
- 向被服务的 index 注入一段零依赖心跳:每几秒轮询 /__dsh_health;当 token 变化(后端已重启)时,页面自动 reload。
- 不再有"卡死 / 已停止"。后端重启变得无感。

3. 跨重启目标重新武装——任务继续进化
- 目标由会话日志背书、持久,但 dsh 每次重启都会解武装 active 目标,导致自动续跑停止。
- dsh-phoenix 读取一个持久断点(JSON 状态文件);当其 pendingResume: true 时,找到活体 agent 的 active + disarmed 目标并 goals.resume() 重新武装。
- 重新武装后,harness 的目标轮次驱动会继续驱动下一轮迭代。

🧬 完整目标:自进化循环把三者组合起来,就得到一条跨重启的自主进化闭环(可复现步骤见 docs/VERIFY.md):

读断点 → 判断下一步 → 测试 / 修改插件 → 写断点(pendingResume)→ 优雅重启 → dsh 启动 → dsh-phoenix 重新武装目标 → 下一轮 … 直到完成

断点是循环的持久记忆;目标是它的驱动器;重新武装钩子是它的复活点。

🆚 与同类项目的差异

| 项目 | 关注点 | dsh-phoenix 的补充 |
| dsh-doctor | 自愈启动:从插件引发的启动失败中恢复、doctor 运行、卡死回合检测 | 等地步空闲的优雅重启(绝不打断运行中的任务)、客户端自动重连、目标续跑 |
| dsh-daemon | 把 dsh web 注册为自启动、自愈的后台服务 | 在已有进程之上叠加可续跑、自进化的生命周期 |

dsh-doctor 与 dsh-daemon 是在"救活启动";dsh-phoenix 让"生命周期"变得优雅、连接、可续跑。 它们互补——dsh-phoenix 可以舒服地架在 dsh-daemon 管理的进程之上。

互补而非竞争——两个轴,一套防漏的分层

"phoenix" 和 "hot" 常被看作对手——都"围绕插件更新",都为了让变更生效。这种看法误读了系统。一个 dsh 进程有两个相互独立的轴,两家各占其一。

轴 1 · 组合(dsh 由什么构成)
dsh 是一个 Cordis 组合:由 patch 层 diff 出来的插件行树。它在启动时被加载,但不是冻结的——行可以通过 loader 的 diff 机制当场增/删/换。dsh 自带的 HMR(cordis-plugin-hmr)已经能热载这一层,但它刻意忽略 node_modules,所以升级一个已安装的插件包仍需要重启——这正是 hot 家族要补的缺口。

hot 家族拥有这条轴。 当你在 CLI 里 dsh plugin add/remove/update 一个 bundle 时,dsh-hot-installer 监听 profile 清单(dsh.profile.bundles),dsh-hot-reload 监听 pnpm-lock.yaml。它们驱动的是与启动完全相同的挂载路径,只是改为现场执行:解析该包、读它的 dsh.bundle.patch、把行注入运行中的树、重新 import 新模块(缓存失效 + 纤维重建)。失败时回滚到可用旧版并标记"需要重启"。它们从不碰进程本身——从不替你重启 dsh。

轴 2 · 进程生命周期有些东西不是组合里的行,它们活在进程边界:systemd 用户单元与其 cgroup、HTTP/WebSocket 服务、内存中的目标激活、浏览器的实时连接。这些都无法热换。 一旦重置跨过它们,诚实的选择就是重启——而这个重启正是 dsh-phoenix 拥有的那部分。

dsh-phoenix 把它做得优雅(地步空闲——等到没有 agent 在跑)、连接(注入心跳在后端启动 token 变化时刷新浏览器)、可续跑(重新武装被解武装的目标,长时目标得以继续)。它还通过 systemd-run --user 以脱离的瞬时 unit 执行重启,被杀的进程永远不会把重启序列一起拖下水。

边界由这两个轴自然得出二者因变更路径不同而不相交,且各是自己所辖轴上"正确的那把工具":

| 变更路径 | 轴 | 处理方 | dsh-phoenix 是否重启 |
| dsh plugin add/remove/update(CLI,已安装 bundle) | 组合 | hot 家族 → 现场挂载/重载 | 否 |
| 通过 dsh cordis 工具(cordis_run)改动插件树 | 组合(运行时、agent 驱动) | dsh-phoenix | 是,优雅重启 |
| 热换失败(import 坏 / apply 抛错) | 组合 | hot 家族回滚并标记"需要重启" | dsh-phoenix 把这个重启做安全 |

所以不是"谁抢到同一次变更",而是源头预防 + 兜住泄漏:hot 家族在变更入口消除可避免的重启;dsh-phoenix 是下面那层,保证剩下的、真正必要的重启不会打断任务、不会掉浏览器、不会杀掉进行中的目标。这是经典的分层系统分隔,不是竞争。

[!NOTE]
这是对当前行为的描述,不是保证。 今天 dsh-hot-installer / dsh-hot-reload 监听 profile 清单与 lockfile,不响应 cordis_run;dsh-phoenix 监听 tools/result,不监听清单。若任一方将来扩大触发范围,请复核此表——边界是行为性的,不是架构性的。

🧭 耐久生命周期与安全重启语义

"重启 → 恢复 → 续跑"是一条显式、耐久的状态机。状态原子地持久化到 DSH_PHOENIX_STATE_FILE(.tmp + rename),因此能在任何一点崩溃后存活,且坏/缺失的断点永远不会触发误续跑。

状态

IDLE ──重启请求──▶ DEFERRED ──安全点/截止──▶ RESTARTING ──启动/崩溃──▶ RECOVERING ──续跑──▶ RUNNING ▲ │ └────────────────────────────── 新请求(在途时合并) ◀────────────────────────────────────────────┘

| 状态 | 含义 |
| idle | 无待重启 |
| deferred | 已请求重启但有 agent 在跑;等待安全点 |
| restarting | 重启已调度(systemd-run) |
| recovering | 重启/崩溃后启动;对记录的目标做有界、幂等的续跑 |
| running | 已安定;无残留待重启 |

迁移与不变量

- idle/running — 重启请求 → deferred(忙)或 restarting(闲);铸造新 generation。
- deferred — 安全点 → restarting;硬截止 → restarting(强制,有日志)。
- restarting — 启动 / 崩溃 → recovering。
- recovering — 续跑(至多一次) → running。

不变量
- RESTARTING:不得再调度第二个重启(请求合并)。
- RECOVERING:只对记录的 generation 续跑;stale goalId(无匹配活体目标)被失效化,绝不续跑。
- RUNNING:不得残留 pendingResume。

续跑语义——持续续跑

pendingResume 不是松散布尔;断点还记录 generation、goalId、resumeAttempt。一个被标记的目标是续跑载体:dsh-phoenix 会在每次重启后都重新续跑它(每个重启/generation 至多一次),只要它仍处于 active。调用 goals.resume() 之前,插件会原子地先递增 resumeAttempt,因此中途崩溃不会在同一重启里重复续跑同一个目标。续跑被保留(goalId/pendingResume 持续存在),直到目标完成、变 stale、或 resumeAttempt 耗尽(maxResumeAttempts)——这样既终止循环,又让目标能跨多次重启存活。

安全截止,而非"到点就重启"

defer 超时是一个带升级的截止期,不是无条件定时器:

deferred(agent 忙) ├─ 软截止 → 记录 WARNING(agent 仍忙) └─ 硬截止 → 若策略为 'auto' 则强制重启(有日志)若策略为 'wait' 则继续等(不强制)

DSH_PHOENIX_DEFER_POLICY=auto(默认)保留对无限 defer 的保护;wait 取消强制重启(你接受可能很长的 defer)。Phoenix 无法区分"agent 忙"与"agent 处于关键区"——DSH 不暴露此类信号——因此"忙"被当作不可重启,靠截止期兜底。

验收答案

1. 任意一点崩溃? 耐久状态存活;启动时在途状态(deferred/restarting/recovering)进入 recovering 并幂等地安定。
2. 同一目标在同一重启里被重复续跑? 不会——每个重启/generation 至多一次(调用前原子递增 resumeAttempt)。被标记的目标会在后续每次重启时再次续跑(有意的持续续跑)。
3. stale 断点触发续跑? 不会——缺失/损坏断点归为 idle;匹配不到活体目标的 goalId 被失效化,不续跑。
4. 重复更新事件→重复重启? 不会——在途请求合并,重复事件只产生一次重启。
5. 无限重启/续跑循环? 不会——在途合并、续跑次数上限、失败/耗尽后安定到 running。
6. defer 截止而 agent 仍忙? 软→告警;硬→强制(auto)或继续等(wait),均有日志。
7. 忙 vs 关键区? Phoenix 无法区分(DSH 无关键区信号);把"忙"当作不可重启,靠安全截止兜底。
8. 迁移确定且可测? 是——状态机是纯函数(见 tests/,17 项,含崩溃/stale/重复/失败注入)。

📦 环境要求

[!WARNING]
优雅重启功能要求 dsh 以 systemd --user 服务运行(默认单元 dsh-web)。在其它形态下——macOS、无 systemd 的容器、或 pnpm run dev:web——只有重启这一项无法工作。此时要么设置 DSH_PHOENIX_RESTART_CMD 指向能重启你 dsh 进程的命令,要么接受只有客户端自动重连和目标重新武装生效。插件会在启动时检测并打印 graceful restart DISABLED,确保它永不静默失效。

- 一个 dsh 安装,其 Web 以 systemd --user 服务运行(默认单元 dsh-web)。
- Node >= 22。
- 零外部依赖——只用 dsh 自身的运行时服务(timer、webServer、agents、goals、shell)。

🚀 安装

dsh-phoenix 是一个官方 dsh bundle(声明了 dsh.bundle),用标准工具即可安装。

从 npm(推荐)

dsh plugin --profile add dsh-phoenix

从 git / tarball

git(需 prepare 构建 + pnpm >= 10 的 allowBuilds)
dsh plugin --profile add github:StvLi/dsh-phoenix

tarball(先打包;文件名跟随包版本,故动态读取)
TARBALL=$(npm pack 2>/dev/null | tail -1) # 例:dsh-phoenix-0.2.6.tgz
dsh plugin --profile add "$TARBALL"

然后校验该层并启动:

dsh --profile --dump-config # 期待一个 "# == dsh-phoenix" 层
dsh --profile

安装后,插件行会被自动注入(见 cordis.patch.yml):

- insert:
- id: dsh-phoenix
name: dsh-phoenix

⚙️ 配置

所有参数都是带安全默认值的环境变量——无需配置文件。

| 环境变量 | 默认值 | 作用 |
| DSH_PHOENIX_UNIT | dsh-web | 要重启的 systemd 用户单元 |
| DSH_PHOENIX_DELAY | 8 | stop 与 start 之间的秒数 |
| DSH_PHOENIX_ARMING_MS | 5000 | 加载后 N 毫秒内忽略信号(防自触发) |
| DSH_PHOENIX_DEBOUNCE_MS | 3000 | 把突发信号合并为一次重启 |
| DSH_PHOENIX_DEFER_POLL_MS | 3000 | 延后期间的空闲复查间隔 |
| DSH_PHOENIX_DEFER_SOFT_MS | 300000 | 软安全截止——到点记告警,继续等待 |
| DSH_PHOENIX_DEFER_HARD_MS | 900000 | 硬安全截止——到点强制重启(若策略为 auto) |
| DSH_PHOENIX_DEFER_POLICY | auto | auto(硬截止时强制)或 wait(永不强制;可能长久延后) |
| DSH_PHOENIX_HEALTH_MS | 4000 | 浏览器心跳间隔 |
| DSH_PHOENIX_RESTART_CMD | (空) | 非 systemd 部署的自定义重启命令覆盖(见环境要求警告) |
| DSH_PHOENIX_REARM_MS | 8000 | 目标重新武装检查的初始延迟 |
| DSH_PHOENIX_MAX_RESUME_ATTEMPTS | 1 | 每个重启的续跑次数上限(1 = 每次重启续跑一次;>1 重试;达到则结束续跑) |
| DSH_PHOENIX_STATE_FILE | (空) | 启用目标重新武装所需的断点文件路径;为空则禁用 |

🧠 工作原理

- 检测——订阅 tools/result,响应插件(重新)激活(cordis_run)。
- 延后——若有 agent running,暂缓重启并复查直到空闲(或到上限)。
- 重启——systemd-run --user 调度 stop → sleep → start,与 dsh 的 cgroup 解耦。
- 重连——健康端点 + 注入心跳在启动 token 变化时刷新页面。
- 续跑——启动时读断点;若 pendingResume,则通过 goals.resume() 重新武装被解武装的目标。

所有日志都以 [dsh-phoenix] 前缀写入 dsh journal,便于排查。

✅ 如何验证它生效

本 README 中的结论由 docs/VERIFY.md 的可复现清单 + 单测(npm test,17 项)支撑。快速开始:

npm test # 21 项:状态机迁移、持续续跑、stale/损坏断点、合并、defer 升级

在真实插件更新后,观察 journal: journalctl --user -u dsh-web -f | grep dsh-phoenix 你会看到 "deferring (agent busy)",随后在地步空闲时 "executing deferred restart" 重启后会看到 "re-armed goal after resume (rev=N)"

curl http://127.0.0.1:3080/__dsh_health 应返回 {"token":"…"}。

📄 许可证

MIT © Steven P.LI
预览分享卡片长什么样 ↓StvLi/dsh-phoenix
分享 · DeepSeek Harness Hub
StvLi/dsh-phoenix

优雅重启不打断任务,页面自动重连并续跑目标

这是你的仓库?认领条目

回到顶部