插件目录 / UI & Skins / dsh-system-control
dsh-system-control
已验证 · 实测可装 FrankZhangIronly
功能简介
DSH网页插件:侧边栏系统菜单,重启/关机,重启退出码42,关机0,仅回环RPC
可用 — 实测通过,早期项目
DSH网页插件:侧边栏系统菜单,重启/关机,重启退出码42,关机0,仅回环RPC 实测能干净安装、正常启动。早期项目,但功能可用。
「已验证」表示我们的自动化 CI 在干净 profile 里实际执行了 dsh plugin add 并启动成功——仅此而已。功能描述与版本兼容性均为作者声明。这不是安全审计,也不代表对第三方代码的背书。
README
dsh-system-control
A DeepSeek Harness (DSH) web plugin that adds a System menu to the sidebar footer with Restart and Shutdown controls. Restart cycles the launcher (
dsh webexits with code42and is relaunched); Shutdown exits cleanly (0). Both are routed over a loopback RPC channel so non-local callers are rejected automatically.
The plugin is shipped as a two-sided DSH plugin: a host (Node) half that owns the /system RPC channel and calls the existing appExit exit hook, and a browser half that renders the sidebar button + the centered modal dialog.
🌏 中文版本 / Chinese version is also available.
Features
- Sidebar trigger in the sidebar footer mirroring the official settings button shape (wide-bar / collapsed-circle variants).
- Centered modal with two side-by-side actions: Restart service and Shutdown service. Shutdown asks for a second confirmation (auto-reverts after 4 s).
- Loopback-only RPC so anyone hitting the host port from another network is blocked with
403by DSH's existing authority check. - Ack-before-exit: the response is flushed before
appExit()is invoked (80 ms timer), so the browser receives a clean acknowledgement. - Zero changes to DSH core — installed as an ordinary plugin, survives
@deepseek-ai/dshupdates.
Installation
dsh plugin --profile web add dsh-system-control
Restart dsh web. The new 系统 / System button appears at the bottom of the sidebar.
To install from a local checkout:
dsh plugin --profile web add /path/to/dsh-system-control
Exit-code protocol
| Action | Exit code | Launcher behavior |
|---|---|---|
| Shutdown | 0 |
The launcher loop exits and the window closes. |
| Restart | 42 |
The launcher loop relaunches dsh web. |
| Status | n/a | Probe: returns { exitAvailable, exitType }. |
The companion launcher DSH Web.ps1 already implements this contract:
- exit
0→ close window, - exit
42→ relaunch, - any other code → log and exit.
If you launch DSH through a different mechanism (systemd unit, plain dsh web, etc.) make sure it understands these codes. Anything else will be treated as a hard crash.
How it works
┌────────────────────┐ connection.rpc.call('/system', 'restart', {}) ┌──────────────────────────┐
│ Sidebar button │ ───────────────────────────────────────────────▶ │ HostConnectionService │
│ + modal (browser) │ │ → loopback authority │
└────────────────────┘ │ → /system handler │
│ → ctx.get('appExit')(42)│
└──────────────────────────┘
- The bundle patch inserts a single host row
system-controlthat injectsconnectionand (transitively, viaconnectionstartup)appExit(which the cmdline launcher registers before any plugin mounts). - The host half registers an RPC handler on channel
/systemwithauthority: 'loopback'. Anything not bound to loopback is automatically rejected. - The browser half registers a slot entry under
sidebar.footer.actionwith order20and renders the trigger + modal component. appExit(code)is invoked throughctx.get('timer').timeout(..., 80)so the200 OKresponse can flush first.
RPC contract (host half)
Channel: /system · authority: loopback (non-local callers get 403).
| Endpoint | Returns |
|---|---|
status |
{ ok: true, value: { exitAvailable: <is function>, exitType: <typeof> } } |
restart |
{ ok: true, value: { accepted: true, code: 42 } } then appExit(42) after ~80 ms. |
shutdown |
{ ok: true, value: { accepted: true, code: 0 } } then appExit(0) after ~80 ms. |
| anything else | { ok: false, error: { code: 'internal', message: 'unknown endpoint …' } } |
The status endpoint is purely a sanity probe used by the modal to display "退出通道:可用 / 不可用" in the dialog header.
Repository layout
system-control/
├── cordis.patch.yml # bundle patch: insert the system-control row
├── lib/
│ ├── index.js # host half (Node): /system RPC + appExit bridge
│ └── client.js # browser half: sidebar trigger + modal
├── package.json
└── README.md
The cordis.patch.yml adds a single row to the host composition tree that injects connection. appExit is provided by the cmdline launcher before the tree mounts, so it is consumed implicitly rather than declared in inject: [...].
Compatibility
@deepseek-ai/dsh≥ current web profile (consumesconnection,slots,timer).- Node ≥ 18 (matches DSH host runtime).
- Browser: Chromium-based (uses standard React +
KeyboardEvent/documentAPIs).
License
MIT
安装
装一次目录插件,之后本站所有插件都能让 DeepSeek Harness 自动找、自动装:
dsh plugin add dshbase-catalog 然后对 agent 说「帮我装 dsh-system-control」,它会在目录里找到并自动安装。文档:dshbase-catalog · 已验证场景包。
该插件是 GitHub 源码(未发 npm)——直接从仓库装:
Web profile:
dsh plugin --profile web add github:FrankZhangIronly/dsh-system-control Headless(CLI)profile:
dsh plugin --profile headless add github:FrankZhangIronly/dsh-system-control 实测报告
验证通过:从 GitHub 源码完成 L1 安装 + L2 加载 + L3 运行(dsh 0.1.0-rc.6)。
使用场景
改变 dsh 的外观或交互方式——一套主题、皮肤或新面板,重塑工作区。
适合谁
在 web UI 里一待几小时、想让它按自己的习惯好看又好用的人。
二次开发建议
皮肤、面板和主题 token 是扩展点——写新皮肤、加面板,或与上游配色同步 token。