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

电源控制 harmless0819-dev/dsh-power-controls

DeepSeek Harness
harmless0819-dev40 天前有提交已提供中文文档扫描:含敏感能力

在设置页一键重启或关闭后端服务

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

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

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add harmless0819-dev/dsh-power-controls
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

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

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

可执行外部命令发起外部网络请求
查看扫描证据(共 7 处,展示前 7 条)
  • 执行外部命令固定命令
    lib/index.js:130
    child = spawn('powershell.exe', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', inner], {
  • 发起网络请求
    lib/client.js:26
    fetch(REPORT, {
  • 发起网络请求
    lib/client.js:35
    return fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}' })
  • 发起网络请求
    lib/client.js:112
    fetch(PING, { cache: 'no-store' })
  • 发起网络请求
    lib/client.js:209
    fetch('/dsh-power/alive', {
  • 发起网络请求
    lib/client.js:255
    fetch('/dsh-power/leaving', {
  • 执行外部命令来自配置/变量
    test-harness.mjs:149
    const child = spawnSync(process.execPath, [fileURLToPath(import.meta.url), '--exit-case', WORK], {
扫描于 2026/10/31(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 一键重启后端服务
  • 一键关闭后端服务
  • 等待页面停止上报

设置 > 通用里加了关闭 / 重启 DSH 按钮,还有可关闭的自动关闭,会等到所有浏览器页面都停止上报再执行。

README

由 DeepSeek 最新模型翻译生成
dsh-power-controls 设置 → 普通设置(General)里的两枚电源按钮。 | 按钮 | 做什么 | | 重启 DSH | 电源循环后端:杀掉当前 dsh web → 等 3080 释放 → 重新拉起 → 验证监听。页面断线几秒后自动刷新回来 | | 关闭 DSH | 只关后端。浏览器标签页会停在断线状态,需要双击桌面的 DSH Web 图标重新打开 | 为什么重启要绕一圈计划任务 第一版的重启是「spawn 一个 detached helper,然后自己 exit」。这是错的:dsh 退出时会回收自己的进程树, helper 跟着一起死,于是后端再也起不来(用户看到的「关闭/重启后不会重新起来」就是这个)。
展开完整文档(README 剩余 1 节)
dsh-power-controls

设置 → 普通设置(General)里的两枚电源按钮。

| 按钮 | 做什么 |
| 重启 DSH | 电源循环后端:杀掉当前 dsh web → 等 3080 释放 → 重新拉起 → 验证监听。页面断线几秒后自动刷新回来 |
| 关闭 DSH | 只关后端。浏览器标签页会停在断线状态,需要双击桌面的 DSH Web 图标重新打开 |

为什么重启要绕一圈计划任务

第一版的重启是「spawn 一个 detached helper,然后自己 exit」。这是错的:dsh 退出时会回收自己的进程树, helper 跟着一起死,于是后端再也起不来(用户看到的「关闭/重启后不会重新起来」就是这个)。

Windows 上没有可靠办法让子进程比父进程活得久(job object 说了算),所以重启改成把活交给任务计划程序:

点「重启 DSH」 └─ 后端: Register-ScheduledTask DSHPowerRestart + Start-ScheduledTask ← 确认成功后才 exit └─ 计划任务(独立进程树): respawn-dsh-web.ps1 ├─ 按端口找到旧的 dsh web 并停掉 ├─ 等 3080 释放(最多 60 秒) ├─ start-dsh-web.ps1 -NoOpen 拉起新实例 └─ 验证端口,最多重试 3 次

关键点:注册计划任务成功后才允许自己退出。注册失败就返回 500 并继续活着,否则用户会面对一个「点了按钮、后端没了、也没有人来拉」的死局。

文件

| 路径 | 作用 |
| lib/index.js | 后端:/dsh-power/close、/dsh-power/restart、/dsh-power/ping、/dsh-power/report、/dsh-power/health,以及 tapIndex 注入 |
| lib/client.js | 前端:往 [data-slot="settings.general.item"] 所在的 section 追加按钮行(每次请求都从磁盘读,改完只要 F5) |
| test-harness.mjs | 离线自检:mock 掉 ctx.webServer,直接驱动路由验证自动收尾规则(node test-harness.mjs) |
| respawn-dsh-web.ps1 | 计划任务跑的电源循环脚本(ASCII-only,PS 5.1 按 ANSI 读无 BOM 的 .ps1) |
| logs/dsh-power-restart.log | 电源循环日志 |
| logs/dsh-power-restart.{out,err}.log | 新实例的 stdout/stderr |

自检(看不到浏览器时的验收通道)

curl http://127.0.0.1:3080/dsh-power/health

返回 lastReport / reportCount / clicks:客户端注入成功会上报 injected,点了按钮会上报 click,重连成功会上报 reconnect。看见 injected 就说明按钮已经画到设置页上了。

安装

从 GitHub(推荐)
dsh plugin --profile web add github:harmless0819-dev/dsh-power-controls

或从本地克隆
dsh plugin --profile web add link:

装/卸这个插件会让 pnpm 重解析依赖树,而 正在运行的 dsh web 锁着 lightningcss 原生模块,所以必须先停后端再装(我踩过:不停后端会 拒绝访问 (os error 5))。

顺带:浏览器标签页图标(web icon)

同一个插件还负责把标签页 favicon 换成鲸鱼娘(图片由用户提供,128px 落在 assets/web-icon.png)。

为什么不走皮肤:皮肤中心的 canServeSkinHooks() 只放行内置皮肤和字节校验过的官方市场皮肤,用户目录里的皮肤即使 manifest 合法,它的 hooks.mjs 也会被拒绝执行(原文:hooks only run for built-in or byte-verified official-market skins)。所以 favicon 只能从受信代码路径注入。

两条腿走路,互为兜底:

| 层 | 做什么 |
| 服务端 tapIndex | 摘掉原有的 (stock 是 favicon.svg),在 里声明 /dsh-power/web-icon.png |
| 客户端 applyFavicon() | SPA 重渲染可能把 stock 图标放回来,所以每次 tick 重新确认我们的 link 是唯一候选 |

资源路由 /dsh-power/web-icon.png 每次请求从磁盘读,换图不用重启。

自动收尾:关掉浏览器之后(默认开启)

关标签页不会停掉 dsh web —— 它是服务器,会话/正在跑的回合都靠它活着。但那会白占 ~0.5GB 内存。
所以页面会主动打招呼,并且每次都报上自己的可见性(document.hidden):

| 时机 | 请求 | 作用 |
| 页面打开期间,每 3 秒 | POST /dsh-power/alive { cid, hidden } | 登记这个页面还活着、以及它是不是被切到后台了 |
| 可见性变化(切走 / 切回) | 同上,立即补一次 | 不用等下一个 3 秒 tick |
| 关闭 / 刷新 / 跳转 | navigator.sendBeacon('/dsh-power/leaving', { cid, hidden }) | 明确道别(beacon 能在页面消失后送出,普通 fetch 会被丢) |

「客户端消失」有两种,含义完全不同:

| 现象 | 判定 | 处理 |
| 收到 pagehide 道别 | leaving | 立刻从客户端表移除 |
| 12 秒(CLIENT_STALE_MS)没心跳,最后上报是可见 | stale-visible | 移除(人走开了 / 断网 / 浏览器被杀) |
| 12 秒没心跳,最后上报是隐藏 | 静默但保留 | 不算离开:后台标签被浏览器节流是常态,页面很可能还开着 |

只有客户端表彻底空了才开始计时(默认 15 秒,autoCloseMs 可调,设 0 = 关掉这个功能):

1. 宽限期内页面回来了(刷新、手快重开)→ 直接取消,什么都不做
2. 宽限到了但还有回合在跑(宿主 ctx.get('agents') 里 status === 'running')→ 继续等,直到回合跑完
3. 没人看 + 没有回合在跑 → 退出进程把内存还回去,并把原因写下来

退出时日志里会写明原因,例如:

auto-close firing: reason=explicit-pagehide: last client p4x… (visible) said goodbye, no client for 16s …
auto-close firing: reason=silent-visible: last client p4x… (visible) went quiet, no client for 16s …

同一份记录还会落到 D:\deepseek\logs\dsh-power-last-exit.json,由下一次启动的 /dsh-power/health 里的 lastExit 报出来—— 「上一次到底为什么退出」不用再靠猜。

怎么区分「用户没在看」和「用户把页面关了」

| 日志里看到 | 结论 |
| page left (cid, visible/hidden) | 明确的关闭 / 刷新 / 跳转 |
| client cid went stale while visible | 可见页面静默失联(断网、浏览器被杀) |
| client cid went quiet while hidden … kept alive | 后台标签被节流 —— 页面还在,只是没在被看 |
| 同一个 cid 隔一会儿又出现 | 同一个页面实例一直活着(cid 每次页面加载重新铸,且不写入任何存储) |
| 出现新 cid,而旧 cid 之前没有 page left | 旧页面是没打招呼就没了(强杀 / 崩溃 / 信标丢包) |

自检通道:/dsh-power/health 的 clients[].hidden / clients[].quiet、visibleClients、 autoClose.pendingReason / autoClose.lastRemoval、lastExit、logFile、runningTurns;日志写在 D:\deepseek\logs\dsh-power-auto-close.log。

离线自检

node test-harness.mjs

Mocks ctx.webServer + ctx.get('agents'),直接驱动插件自己的路由,覆盖上面全部规则(可见性计数、 hidden 静默保留、visible 静默丢弃、道别移除、退出原因与 last-exit.json 的跨进程回报)。
退出路径跑在子进程里,所以它的 process.exit 不会杀掉测试本身。

测试用 tickMs / staleMs / logFile 三个配置缩短等待并把日志写进临时目录(为了可测性而存在,生产环境不要设)。
预览分享卡片长什么样 ↓harmless0819-dev/dsh-power-controls
分享 · DeepSeek Harness Hub
harmless0819-dev/dsh-power-controls

在设置页一键重启或关闭后端服务

回到顶部