Skills Plugins MCP Prompt Model 导航 博客 资讯 我的中心
开发与运行时 #dsh-plugin#dsh-plugin-market#dsh-plugins

dsh-status-plugin

dsh 状态插件:以 JSON 暴露运行时健康(进程、监听、API key、内存、插件清单)并推送 SSE 告警,Web UI 以头部徽章+展开面板展示。

woshi-tom @woshi-tom ⬇ 2 ★ 1 master

安装

dsh plugin --profile web add github:woshi-tom/dsh-status-plugin
下载安装清单

需要可复现安装时,可在仓库后追加 #commit 固定提交。

dsh 状态插件:以 JSON 暴露运行时健康(进程、监听、API key、内存、插件清单)并推送 SSE 告警,Web UI 以头部徽章+展开面板展示。

该插件未提供要点说明,请参考仓库 README。

dsh-plugindsh-plugin-marketdsh-plugins
  1. 安装并启动 DeepSeek Harness:npx @deepseek-ai/dsh web
  2. 在终端执行上面的安装命令(CLI 会解析插件并核验来源)
  3. 用 dsh plugins list 确认已安装,必要时重启 Harness 生效

插件以当前 dsh 进程的权限运行,安装时可能执行代码。请先通读仓库源码与许可证,确认无破坏性命令与越权访问;本站只做索引,不对第三方插件安全性作担保。

代码仓库github.com/woshi-tom/dsh-status-plugin
许可证MIT
主要语言master
下载量2
GitHub 星标1
最近推送2026-08-14
收录日期2026-09-19
分类开发与运行时

事实信息来自公开插件目录快照(2026-10-01),介绍文案由本站再加工。

以下为插件仓库 README 全文(原始内容,由公开目录抓取整理)。

# dsh-status-plugin

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

A status plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (dsh). Two planes in one package:

- **Host plane** — HTTP endpoints exposing the running harness's runtime health as JSON: process, listener, API-key presence, memory, uptime, and the live plugin inventory.
- **Client plane** — a header badge in the web UI (top-right of a conversation session) that shows uptime, opens a detail panel, and raises toasts when the host reports overload or memory-pressure alerts.

- **Package**: `dsh-status-plugin`
- **Runtime**: host (ESM) + browser bundle (a CJS factory wrapped for the dsh client-modules `__ModuleLoader__` contract), built with `tsc` + esbuild to `lib/`.
- **Language**: TypeScript.

## Install

```sh
dsh plugin --profile web add dsh-status-plugin
```

The CLI reconciles `dsh.profile.bundles` automatically: because the manifest declares `dsh.bundle.patch`, the package joins the profile's bundle layer stack. Stop the running process and restart the profile to load it:

```sh
dsh web   # or: dsh --profile
```

Verify the plugin joined the composed tree without booting:

```sh
dsh --profile web --dump-config
```

The client manifest (`package.json` → `dsh.client`) declares the browser entry; the profile's client-modules scanner picks it up and injects `dsh-status-plugin/client.js` into the web app automatically — no bundle or overlay configuration needed.

## Usage

[图片: abcddf52074cd98f465253a6619de744]

The plugin registers two exact routes on the profile's web server:

```
GET /api/status          # JSON snapshot on demand
GET /api/status/events   # Server-Sent Events stream
```

### `GET /api/status`

Example response:

```json
{
  "ok": true,
  "timestamp": "2026-08-14T03:50:00.000Z",
  "host": {
    "hostname": "host",
    "platform": "linux",
    "arch": "x64",
    "nodeVersion": "v22.23.2",
    "pid": 23185,
    "cwd": "/root/.dsh",
    "uptimeSeconds": 3600,
    "loadAvg": [0.1, 0.1, 0.1],
    "cpuPercent": 12.4,
    "memory": { "rss": 123456, "heapTotal": 654321, "heapUsed": 432100, "external": 12345 },
    "systemMemory": { "total": 17179869184, "free": 4294967296, "used": 12884901888 },
    "lanAddresses": ["192.168.5.227"]
  },
  "webServer": {
    "host": "0.0.0.0",
    "port": 3080,
    "url": "http://localhost:3080"
  },
  "apiKey": {
    "configured": true,
    "source": "env"
  },
  "plugins": {
    "entries": [
      { "entryId": "llm", "moduleName": "@deepseek-ai/dsh-llm", "enabled": true, "fiberPhase": "active" }
    ]
  }
}
```

### Fields

| Field | Source |
|---|---|
| `host.*` | `process` + `node:os` (pid, uptime, process memory, LAN IPv4 addresses); `cpuPercent` is CPU utilization sampled from `os.cpus()` deltas and works on every platform; `loadAvg` is the Unix load average — always `[0, 0, 0]` on Windows; `systemMemory.*` is machine-wide memory (`os.totalmem()` − `os.freemem()`) |
| `webServer.*` | `ctx.webServer` (bind host and actual listening port) |
| `apiKey` | `DEEPSEEK_API_KEY` in `process.env`, else the working directory `.env`, `~/.env`, or `$DSH_HOME/.env` (checked in loadLayeredEnv priority order) — **presence only, never the value**; an empty assignment (`` DEEPSEEK_API_KEY="" ``) does not count as configured |
| `plugins.entries` | `ctx.pluginInventory.list()` (live Cordis Loader entry state) |

The API key check reports only whether a key is configured and where it was found; the value itself never leaves the process.

### `GET /api/status/events` (SSE)

The host pushes to open browser streams — the server decides when the page needs new state, so idle pages make zero requests:

- **`snapshot`** — a full status snapshot, emitted immediately on connect and then every `heartbeatMs` (default 30 s). Each snapshot card dissects to `cpuPercent`, `loadAvg`, `systemMemory`, and process-memory fields inside `host.*` for alert-driven UIs.
- **`alert`** — emitted when an indicator enters or leaves its alert band. Entering requires `value > threshold`; an active alert only clears when the value drops below `threshold × (1 − hysteresis)`, so a value hovering near the threshold does not flap. Events are emitted on every transition and **re-synchronized on connect** so a page that opens mid-alert still learns about it:

```
event: snapshot
data: {"ok":true,"timestamp":"...","host":{...},"plugins":{...}}

event: alert
data: {"active":true,"reason":"cpu","value":0.87,"threshold":0.8}
```

Default thresholds (configurable via the plugin config in the profile's cordis.yml):

| Config | Default | Meaning |
|---|---|---|
| `cpuWarning` | `0.8` | CPU utilization above which a CPU overload alert fires |
| `memoryWarning` | `0.85` | system memory pressure above which a memory alert fires |
| `hysteresis` | `0.1` | recovery margin: an alert clears only below `threshold × (1 − hysteresis)` |
| `heartbeatMs` | `30000` | snapshot push interval |
| `checkIntervalMs` | `5000` | alert monitor sampling interval |
| `authToken` | `''` | shared secret required on both routes; empty disables auth. See [Authentication](#authentication) |
| `maxSubscribers` | `32` | SSE subscriber cap; new connections over the cap fail with an error response |
| `maxBufferedBytes` | `65536` | per-subscriber write-buffer high-water mark; a slow consumer over it is dropped |

### Authentication

When `authToken` is set, both routes require it. The token can travel in either channel:

- `GET /api/status` — `Authorization: Bearer ` header, or `?token=`.
- `GET /api/status/events` — `?token=` query parameter; a native `EventSource` cannot set custom headers.

A rejected request answers `401` with `{ "ok": false, "error": "unauthorized" }`. Comparison is constant-time (`crypto.timingSafeEqual`), so a wrong token does not leak its length. Because the query parameter can appear in logs and history, prefer header auth for `GET /api/status` and keep the SSE stream on a loopback-only webserver.

The built-in browser badge has no channel to receive the host's token (the client manifest cannot read the host config), so enabling `authToken` disables the badge's status views; a custom UI can authenticate by sending the header/query token above. Instances that need the bundled UI should leave `authToken` empty (the default) and rely on the webserver's loopback binding.

The browser side subscribes with a native `EventSource` (auto-reconnects on drop) and renders:

- a compact badge in the conversation header (status dot + uptime, click to open);
- a detail panel with process/resource/service/plugin sections and the last update time;
- a toast on every alert transition (auto-dismisses after 6 s) plus a pulsing badge while an alert is active;
- a gray badge dot when the stream is disconnected or no snapshot arrived for 90 s — a monitoring widget must say *unknown*, not *healthy*, when it loses contact.

### Failure behavior

- A collection error inside the handler returns `500` with `{ "ok": false, "error": "" }` — structured, no stack leak, never a hung socket.
- `pluginInventory` is optional: when the service is absent, `plugins.entries` is `[]` rather than an error.
- Response handlers and both periodic timers (heartbeat and alert sampler) are exception-isolated: a throwing collection is logged, never propagated as an uncaught exception that could crash the harness the plugin monitors.
- Responses carry `cache-control: no-store` (runtime data must not be cached); the SSE stream uses `text/event-stream` with `x-accel-buffering: no`.
- SSE streams are bounded: at most `maxSubscribers` concurrent streams; a subscriber whose write buffer exceeds `maxBufferedBytes` (or whose socket write stalls) is dropped so a slow consumer cannot pin the process. Plugin teardown ends every open stream.

## Requirements

- dsh profile with the web bundle (`@deepseek-ai/dsh-web-app`) — provides `ctx.webServer` and `ctx.pluginInventory`.
- Node `^22.19 || >=24`.
- The browser entry renders in the conversation session header (`conversation.session.header.utilities` slot); it is not shown on the empty/home screen.
- The load-average row in the panel is a Unix concept: on Windows it is always `0.00`. CPU utilization and memory metrics work on every platform.

## Development

```sh
pnpm install
pnpm run build          # host tsc + client typecheck + esbuild bundle
pnpm test               # vitest unit tests
npm pack --dry-run      # verify tarball contents (prepack runs the build)
```

## Publish

This package is a dsh *bundle*: the npm tarball ships `cordis.patch.yml` and the manifest's `dsh.bundle.patch` points at it, so installing the package into any dsh profile automatically mounts the plugin layer. Tag the repository `dsh-plugin` for discoverability in the [dsh plugin topic](https://github.com/topics/dsh-plugin).

## License

MIT

数据来源:公开的 DeepSeek Harness 插件目录与各插件 GitHub 仓库。本站为独立第三方目录,与 DeepSeek、幻方(High-Flyer)及插件作者均无隶属或背书关系。

每日精选 Skill 推荐,免费送到你邮箱

输入邮箱,每天接收一个精选 AI Agent 技能推荐。完全免费,持续更新。

提交后我们会发送一封确认邮件,点击邮件里的链接才会开始收信。

完全免费,取消任意时间。我们不会发送垃圾邮件。