@chenkai114/dsh-daemon

devtested: passnpmMIT

Registers the DeepSeek Harness web server (dsh web) as an auto-start, self-healing background service — LaunchAgent / systemd / cron plus a 30s health-check watchdog — with seven dsh_daemon_* tools (install/uninstall/reinstall/status/start/stop/update).

下载量 / Downloads
3,633
依赖体积 / node_modules
2.23 MB
测试时间 / Tested
2026-11-06
DSH 版本 / Version
0.2.2-rc.1

Install

dsh plugin --profile web add @chenkai114/dsh-daemon

Sandbox test results

StageResult
1 install✓
2 list✓
3 mount✓
4 boot—

Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).

README

版本对照(dsh-daemon ↔ dsh)

dsh-daemon · 支撑的 dsh · 说明

0.1.29 · 0.1.x 与 0.2.x · 自动更新加 dsh 兼容门禁:每版在 package.json 声明 dsh.requires.dsh,更新前比对客户端已装 dsh 版本,不满足/未声明/读不到就跳过自动升级(dsh-daemon update --apply 可人工强制);更新检查改为 2 次尝试 + 15s 预算,错误细分为 timeout / DNS / HTTP / 连接失败,status 显示上次成功检查时间

0.1.28 · 0.1.x 与 0.2.x · 修「健康检查误杀 + 重启风暴」:/health 单次预算 5s → 20s、失败阈值 3 → 5(~50s 真超时才重启);tick 串行(tickBusy)+ launch() 单飞,杜绝同一秒拉起两个 dsh web(EADDRINUSE);收养未托管但正在服务的 dsh web(纠正 pid 文件)而不是再拉一个;停进程前校验「这个 PID 真的是 dsh web」(PID 复用不误杀);status 报出 pid 文件与实际监听者不一致;非 JS 入口(dsh.ps1/.cmd shim)拒绝启动并明确报错

0.1.27 · 0.1.x 与 0.2.x · 健康检查间隔默认 30s → 10s(自愈更快);新增 dsh-daemon logs 与 dsh_daemon_logs:dsh web 启动失败时像 systemctl 一样打印明细入口(web + watchdog 日志尾部、/health、PID、启动时长)

0.1.26 · 0.1.x 与 0.2.x · 启动宽限期:dsh web 启动慢(大插件集、冷缓存)时不再被 watchdog 按 90 秒判死反复重启,宽限期内不计健康失败(DSH_DAEMON_STARTUP_GRACE,默认 5 分钟);停旧进程改为先 SIGTERM 再 SIGKILL 并等端口真正释放(修 EADDRINUSE 连锁失败);status / start 如实报「仍在启动」

0.1.25 · 0.1.x 与 0.2.x · 适配 0.2.x 的 shell 服务改名:run(spec) → execute(spec) + 句柄 result()(0.2.1 上 reinstall 曾报 shell.run is not a function),并兼容两种结果形状

0.1.24 · 0.1.x(0.2.x 部分路径不可用) · OIDC 发布流水线;未适配 0.2.x shell API

0.1.23 · ≥ 0.1.2-alpha.1(token 认证起) · 注册漂移自愈、status 如实上报注册状态、拒绝易失 DSH_HOME

0.1.21–0.1.22 · 同上 · 单实例守卫校验 cmdline、dsh web 显式传 cwd

0.1.20 · 同上 · DSH_DAEMON_TRUSTED_HOST:反代场景下给 dsh web 追 --trusted-host

0.1.19 · 同上 · 自动开浏览器补齐 token 认证的入场 cookie

≤ 0.1.18 · ≥ 0.1.0-rc.8(--no-open 起) · 更早的 dsh 没有 --no-open,watchdog 启动时会跳过该参数

两个门限常量取自代码(lib/index.js):DSH_NO_OPEN_MIN = 0.1.0-rc.8、DSH_TOKEN_AUTH_MIN = 0.1.2-alpha.1。

dsh 侧与 daemon 交互的接口只有三处:web 启动参数、/health 探活、以及注入的 shell/fs 服务 —— 后者是 0.2.x 唯一改过的地方。


dsh-daemon

[中文](README.md) | [English](README.en.md)

将 DeepSeek Harness 网络服务(dsh web)注册为自启动、自愈的后台服务。

安装后,dsh web 将:

  • 登录时自动启动(LaunchAgent RunAtLoad / systemd WantedBy=default.target / cron @reboot)
  • 睡眠唤醒后自动重启
  • 自愈:watchdog 每 10 秒(可配置)健康检查一次 http://127.0.0.1:<port>/health,连续 3 次失败后重启服务
  • 慢启动安全:刚拉起的 dsh web 处在启动宽限期(DSH_DAEMON_STARTUP_GRACE,默认 5 分钟)内时,健康检查失败不计入重启阈值,进程也不会被杀
  • 不依赖当前会话:watchdog 是独立生成的脚本,而非内存中的插件

安装/卸载永远不会触碰当前正在运行的会话。

账号对应关系(npm scope / GitHub 账号)见 [CONTEXT.md](CONTEXT.md)。

使用方式

方式 A —— 用 dsh plugin 安装(v0.1.9+,推荐)

1. 用官方插件管理器将包安装到 web profile(在 profile 目录内运行 pnpm,使 loader 能解析到它;仅全局安装不够——见下):

   dsh plugin --profile web add @chenkai114/dsh-daemon

(需要 PATH 上有 pnpm——用 corepack enable 一次性启用。)

> 为什么不能只 npm install -g?loader 以 Node ESM 解析导入 name: 行,解析锚点是 profile 目录(~/.dsh/profiles/web/);全局 node_modules 不在该解析链上(NODE_PATH 对 ESM 无效)。profile 自己的 node_modules——由 pnpm 管理——才是包可达的原因。

2. 重启 dsh web。包声明了 dsh.bundle manifest,dsh plugin add 会把它自动加入 dsh.profile.bundles,启动时作为 bundle 层挂载——不需要(也不应该)再手动往 ~/.dsh/profiles/web/cordis.patch.yml 里 insert 同一行,否则会触发 duplicate loader entry id: dsh-daemon 启动失败。

七个 dsh_daemon_* 工具即可供每个 agent 使用——直接让 agent 运行 dsh_daemon_install。

以后升级:dsh plugin --profile web update @chenkai114/dsh-daemon(并重启)。

⚠️ 从 v0.1.8 及更早版本升级:如果你之前按旧文档在 ~/.dsh/profiles/web/cordis.patch.yml 里手动加过 - insert: dsh-daemon 行,升级后必须删掉那一行(保留文件里其他内容),否则 bundle 层 + 手动层会插入同一个 id: dsh-daemon 两次,dsh web 启动时报 duplicate loader entry id。删除后重启即可。
权限说明:daemon 管理用户级系统服务(LaunchAgent plist、$DSH_HOME 下的状态文件),因此插件对其文件与命令操作请求 danger-full-access。若部署拒绝提权,工具会以沙箱拒绝失败。

方式 B —— 动态 Cordis 插件(无需安装)

将 lib/index.js 的内容粘贴到 cordis_define 的 code.host 字段并运行。这正是插件在真实会话中开发与验证的方式:沙箱提供 harness 全局,文件以 return plugin; 结尾。

端口

默认端口为当前监听的 webServer 端口(通常 3080),其次 DSH_WEB_PORT,再其次工具显式 port 参数。更换端口后运行 dsh_daemon_reinstall。


架构

守护进程是一个watchdog 监督者,由三部分组成。

1. 平台注册

一个按用户注册的服务,负责在登录时启动 watchdog 并保持其存活:

平台 · 机制

macOS · LaunchAgent ~/Library/LaunchAgents/com.deepseek-ai.dsh-watchdog.plist —— ProgramArguments=[node, watchdog.js]、RunAtLoad、KeepAlive{SuccessfulExit:false}、ThrottleInterval=10,环境变量携带 DSH_WEB_PORT 与 DSH_HOME。通过 launchctl load -w 加载。

Linux · systemd 用户单元 ~/.config/systemd/user/dsh-watchdog.service —— Type=simple、Restart=always、RestartSec=10、StartLimitIntervalSec=0;通过 systemctl --user enable --now 启用。systemd 不可用时回退为 cron @reboot 条目。

Windows · VBS 启动器 + 计划任务 —— 任务 DshWatchdog(XML 在 $DSH_HOME/daemon/dsh-watchdog-task.xml,UTF-16LE)在登录时运行 wscript.exe //B dsh-watchdog.vbs;VBS 设置 DSH_WEB_PORT/DSH_HOME 并以隐藏窗口启动 node watchdog.js。RestartOnFailure PT1M/999,MultipleInstancesPolicy=IgnoreNew。通过 schtasks /Create 注册。

Windows 支持按 macOS/Linux 的同等行为实现(插件的 shell 层在 win32 下切换到 PowerShell,即 DSH 的 shell 执行器),但尚未在真实 Windows 机器上验证。

2. watchdog 循环

生成的独立脚本 $DSH_HOME/daemon/watchdog.js(零依赖,任意 Node ≥ 18 可运行,无需会话):

  • 将自身 PID 写入 .dsh-watchdog.pid;SIGINT / SIGTERM / SIGHUP 清理后退出;单实例锁拒绝重复的 watchdog
  • 启动时若 http://127.0.0.1:<port>/health 不健康,则拉起 web 服务(node <dsh> web --port <port>,分离运行,输出到 logs/dsh-web.log)
  • 之后每 10 秒(可通过 DSH_DAEMON_HEALTH_INTERVAL 配置):
  • 存在 .daemon-stopped(用户暂停监控)或 .daemon-restart.lock 较新(< 120 秒,重启进行中)时跳过;
  • tick 间隔超过 90 秒(睡眠唤醒)时重启服务;
  • 服务仍在启动宽限期内(.dsh-web.started 距今 < DSH_DAEMON_STARTUP_GRACE,默认 5 分钟)且进程存活时,只记录「仍在启动」,不计失败、不重启——大插件集/冷缓存的 dsh web 可能几十秒到几分钟才对外提供 /health,旧的「90 秒判死」会让它永远起不来;
  • 进程已消失(崩溃、激活期 EADDRINUSE、OOM)时立刻重启,不等满 3 次失败;
  • 连续 3 次健康检查失败后重启服务(进程存活但超过宽限期仍未健康);
  • 停旧进程先发 SIGTERM,等待最多 8 秒(dsh web 会优雅退出并释放监听端口),仍不退再 SIGKILL;随后等端口真正空闲(最多 5 秒)才拉起新进程,避免新进程在插件激活期报 EADDRINUSE 而秒退;
  • .daemon-installed 标记消失(已卸载)时退出;
  • 日志写入 logs/watchdog.log(5 MB × 3 轮转)。

3. daemon 感知的 start / stop

  • dsh_daemon_stop 写入 .daemon-stopped(watchdog 不再重启服务),并停止正在运行的托管服务。
  • dsh_daemon_start 清除该标记、确保 watchdog 运行,并在服务不健康时拉起它。

工具

插件仅包含 Host 侧,注册 8 个可供模型调用的工具:

工具 · 功能

dsh_daemon_install · 生成 watchdog.js 与状态文件,写入 L

…(truncated)

Rendered from the README published on npm. Formatted only, not edited.

Versions

Published on npm::30,最后更新 2026-10-29

Links

GitHub · Homepage · npm

Same category