Bundle
dsh-process-panel
Process panel for DeepSeek Harness: start, stop and watch long-running background processes from the sidebar, with live logs.
- Source
- ALIWUER
- License
- MIT
- Updated
- Updated 3 hours ago
Readme
# dsh-process-panel
[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(dsh)的侧栏**进程面板**插件:
在 Web GUI 里管理长时后台进程 —— 启动、停止、重启、看实时日志,AI 侧通过 `sv_*` 工具操作。
> A sidebar process panel for DeepSeek Harness: manage long-running background
> processes (start / stop / restart / live logs) from the Web GUI, with matching
> `sv_*` tools for the agent. Installs as a standard DSH bundle.
```
┌ 侧栏 ───────────────┐
│ 记忆系统 │
│ 工作区 │
│ …会话列表… │
│ 进程任务 ● 2 │ ← 侧栏底部,紧挨「设置」的官方座位
│ 设置 │
└─────────────────────┘
```
## 功能
- **侧栏入口「进程任务」**:位于侧栏底部、紧挨「设置」(官方 `sidebar.footer.action` 座位),
徽标显示运行中的任务数;点开是全屏面板,左侧任务列表、右侧实时日志。
- **任务状态一目了然**:运行中 / 孤儿进程 / 已失效 / 已停止 / 已退出 / 启动失败。
- **面板按钮**:`重启`、`停止`、`终止`(针对孤儿进程)、`清除`,列表顶部还有 `清理已结束`。
- **日志体验**:默认选中第一个运行中的任务并**自动跟随底部**;手动上滚即暂停跟随,滚回底部恢复。
- **AI 工具**:`sv_start` / `sv_stop` / `sv_restart` / `sv_logs` / `sv_list` / `sv_clear`,
所以你(或你的 agent)只要说「启动后端」「看下 backend 日志」就够了。
- **任务归属宿主进程**:所有会话与 GUI 面板共享同一份任务列表。
### 任务状态语义
| 状态 | 含义 | 面板能做什么 |
|---|---|---|
| `running` | 本 dsh 进程的子进程,正常可控 | 重启 / 停止 |
| `orphan` | dsh 被强杀(kill -9 / 崩溃)时活下来的进程。**面板读不到它的输出**(管道随旧进程消失),只保留 pid | 只能「终止」(按 pid 发 SIGTERM→SIGKILL) |
| `lost` | dsh 重启过,进程已不在;命令行与日志仍保留 | 重启(一键拉回来)/ 清除 |
| `stopped` / `exited` / `failed` | 已结束 | 重启 / 清除 |
dsh **正常退出**(SIGTERM/SIGINT,含 `systemctl restart`)会连任务一起结束;
只有 kill -9 / 崩溃才可能留下「孤儿进程」,此时面板会如实显示并提供「终止」。
## 环境要求与兼容性
| 依赖 | 版本 |
|---|---|
| **DeepSeek Harness** | **0.1.1-rc.2**(本插件在该版本上开发并验证) |
| `@deepseek-ai/dsh-tools` | **0.1.1-rc.2**(已锁死在 `dependencies`,随插件一起安装) |
| Node.js | `^22.19.0 \|\| >=24.0.0` |
| pnpm | 11(`corepack enable pnpm`) |
> 版本锁定说明:插件在运行时 `import "@deepseek-ai/dsh-tools"`,该包与 dsh 主版本同步发布。
> 本项目把它写成**精确版本依赖**(不是 peer),以确保任何安装方式下都能解析到与宿主匹配的实现;
> 升级 dsh 后如果行为异常,请把这里的版本与本表对齐。
## 安装
> 本插件以 **bundle** 形式分发:仓库自带 `cordis.patch.yml` 并在 `package.json` 声明
> `dsh.bundle.patch`,因此 `dsh plugin add` 会自动把插件层登记进 profile,无需手工改配置文件。
### 方式一:拉源码后一条命令(推荐,无需任何授权)
```bash
git clone https://github.com/ALIWUER/dsh-process-panel.git
cd dsh-process-panel
./install.sh # 装进 web profile;也可 ./install.sh <profile>
```
`install.sh` 做三件事:安装依赖并构建 → 注册 bundle → 打印验证命令。等价于手动执行:
```bash
pnpm install && pnpm run build
dsh plugin --profile web add "$PWD"
```
### 方式二:直接从 GitHub 安装
```bash
dsh plugin --profile web add github:ALIWUER/dsh-process-panel#v0.5.0
```
pnpm ≥10 默认拒绝执行 git 依赖的构建脚本,首次会失败并给出提示 —— 把 pnpm 打印的包键写进该
profile 的 `pnpm-workspace.yaml` 后重试:
```yaml
allowBuilds:
dsh-process-panel: true
```
> ⚠️ **安全提示**:这一步等于允许该仓库的代码在你的机器上执行构建。
> 请**锁定 tag 或 commit**(如 `#v0.5.0`),不要直接装 `main` 这种浮动引用。
### 验证与生效
```bash
dsh --profile web --dump-config | grep -A2 process-panel # 应看到 id: process-panel
# 然后重启 dsh web(bundle 层在启动时装配)
```
打开 GUI,侧栏底部(设置旁边)即可看到「进程任务」。**若之前开着页面,请刷新一次。**
### 卸载
```bash
dsh plugin --profile web remove dsh-process-panel
```
## 配置
| 配置项 | 默认值 | 说明 |
|---|---|---|
| `stateDir` | `$DSH_HOME/process-panel` | 任务快照(状态 + 最近日志)的存放目录 |
在 profile 的 `cordis.patch.yml` 里覆盖(patch 按行替换,需要重述该行所有键):
```yaml
- insert:
- id: process-panel
name: 'dsh-process-panel'
config:
stateDir: '/path/to/my/process-panel'
```
## 使用
### GUI
点侧栏底部「进程任务」→ 面板。左侧点任务看日志,行内按钮做操作,顶部「清理已结束」批量清掉已结束记录
(仍在运行的孤儿进程会保留)。
### 自然语言(AI 侧)
| 你说 | 会调用 |
|---|---|
| 「启动后端」「把 backend 跑起来」 | `sv_start` |
| 「重启 backend」「改完代码重新部署」 | `sv_restart` |
| 「停掉 backend」 | `sv_stop` |
| 「看下 backend 日志」 | `sv_logs` |
| 「现在有哪些任务在跑」 | `sv_list` |
| 「清理一下已结束的任务」 | `sv_clear` |
`sv_start` 的 `command` 是**一个字符串**(直接 spawn,不做 shell 解析;需要管道/重定向请写成 `bash -c '...'`)。
## 开发
```bash
pnpm install
pnpm run typecheck # tsc --noEmit
pnpm run build # rolldown(host ESM + client CJS)+ 生成类型
pnpm run dev # rolldown --watch
```
- 改 **host** 半边 → 重启 dsh(`systemctl restart dsh-web`)。
- 改 **client** 半边 → 刷新页面即可(`/plugins/<包名>/client.js` 不缓存)。
- 本地联调:`dsh plugin --profile <你自己的 profile> add "$PWD"` 装的是**指向本目录的链接**,
构建后重启即生效。
## 实现要点
插件的每一处副作用都归属 dsh 的 Cordis 容器,停止/更新/卸载时自动回收:
| 半边 | 贡献 | 所有权 |
|---|---|---|
| client | `sidebar.footer.action` 入口(`{ wide }` 由座位下发,收起时自动变圆图标) | `ctx.slots.inject` + `ctx.slots.register` |
| client | `shell.overlay` 全屏面板(该层本身 click-through,面板自行开启 pointer-events) | 同上 |
| client | 轮询 | 注入的 `timer` 服务(`ctx.interval`),无全局定时器 |
| client | 样式 | 注入一张 `style[data-plugin-css]`(0.1.1-rc.2 无 `styles` 服务,与官方面板同法) |
| host | `sv_list` / `sv_start` / `sv_stop` / `sv_restart` / `sv_logs` / `sv_clear` | `ctx.effect(() => ctx.tools.register(...))` |
| host | `GET|POST /sv-api/process-panel/*` | `ctx.inject(['webServer'])` + `ctx.effect(() => ws.register(...))` |
| host | 停机钩子(把子进程一起带走)、SIGKILL 升级定时器 | `ctx.effect(...)` + `ctx.timeout(...)` |
**重启是「先停干净再起」**:SIGTERM → 等进程真正退出(最多 5s,超时再 SIGKILL)→ 才重新拉起,
所以像 dev server 这类占端口的任务不会因为端口没释放而 `EADDRINUSE` 起不来。
## 已知限制
- 入口与面板分别挂在 `sidebar.footer.action` / `shell.overlay` 两个座位名上;dsh 大版本若改名,
入口会消失,跟进修这里即可(不会再依赖任何产品 DOM 类名)。
- 已脱离 dsh 的 `orphan` 进程:面板只能显示 pid 并终止它,**无法读取它的输出**(管道已随旧进程消失)。
- 面板 HTTP 接口挂在 `/sv-api/process-panel/{state,action}`(仅本机 GUI 使用)。
- 命令以 `spawn` 直接执行、不经 shell(`&&`、管道、重定向请自行包 `bash -c '...'`)。
## License
[MIT](./LICENSE)
Install
dsh plugin --profile web add github:ALIWUER/dsh-process-panel
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-process-panel from the hub
- This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.