Bundle
dsh-rescue-tui
Minimal emergency-maintenance terminal front-end for DeepSeek Harness: session picker + resume, inherited permission presets, live model/effort routing. · DSH 救援 TUI:WebUI 挂掉时的极简终端维护入口(会话续聊 / 权限继承 / 模型路由切换)。
- Source
- marshfolx
- License
- MIT
- Updated
- Updated 2 days ago
Readme
# dsh-rescue-tui
> WebUI 挂掉时的极简终端维护入口:一个纯插件挂载的 DSH profile bundle。
> 会话续聊 · 权限三层继承 · 终端审批 · 模型路由切换。零核心改动,装上即用。
[](https://www.npmjs.com/package/dsh-rescue-tui)
[](LICENSE)
## 适用场景
- **WebUI 挂了**:web server 起不来、端口被占、浏览器端异常——会话日志在磁盘上完好,TUI 直接续聊
- **SSH / 远程维护**:没有图形界面,一个终端就是全部
- **低配环境 / 应急救援**:零第三方 UI 依赖(原生 readline + ANSI),残破环境也能跑
## 功能特性
| | |
|---|---|
| 🔄 **会话续聊** | 启动列出历史会话(当前工作区优先),数字键 resume;无标题会话自动节选首条用户 prompt 作标题;崩溃残缺回合由持久化层自动合成关闭 |
| 🛡️ **权限三层继承** | 原样挂载 `sandbox-policy` + `approval` + `permission-presets`:默认 `workspace-write`(写入限工作区)+ `ask` 审批;越界操作终端弹 `y/N` |
| 🔀 **模型路由切换** | `/model` 动态列出 llm-pi-ai 目录全部分组;同一会话日志原位重开换路由(历史保留);`save` 可写入默认设置 |
| 🧠 **推理强度** | `/effort low\|high\|max\|off` 独立调整,不必换模型 |
| 🌐 **网络工具** | `web_search` 开箱即用;自研 ~100 行匿名 HTTP fetch provider 补齐 `web_fetch`(HTML→markdown、私网拦截、截断控制) |
| ✂️ **工具面裁剪** | 保留 pwsh/bash、fs 编辑、todo、jobs、搜索抓取;禁用 subagent/workflow/ralph/goal/plan-mode/skills——救援场景一个人一个 agent 就够 |
## 安装
前置:Node ≥ 22、官方 [`@deepseek-ai/dsh`](https://www.npmjs.com/package/@deepseek-ai/dsh) CLI、pnpm ≥ 10。
### 方式 A · 一键安装脚本(Node,跨平台)
```powershell
git clone https://github.com/marshfolx/dsh-rescue-tui.git
node dsh-rescue-tui/scripts/install-profile.mjs # 默认创建 rescue profile,从 npm 安装
# 或直接从 GitHub 安装:
node dsh-rescue-tui/scripts/install-profile.mjs --package "github:marshfolx/dsh-rescue-tui"
# 开发模式:源码直连
node dsh-rescue-tui/scripts/install-profile.mjs --link /abs/path/to/this-repo
```
### 方式 B · 手动安装(任何 profile 通用)
```powershell
$dir = "$env:USERPROFILE\.dsh\profiles\rescue"
New-Item -ItemType Directory -Force $dir | Out-Null
# 1. cordis.yml 与 cordis.patch.yml 写入空模板 '[]'(launcher 每次 boot 会重写 cordis.yml)
Set-Content "$dir\cordis.yml" "[]"; Set-Content "$dir\cordis.patch.yml" "[]"
# 2. pnpm-workspace.yaml:packages: [- .] + nodeLinker: hoisted
# 3. package.json —— bundles 必须包含本插件:
# { "name": "dsh-profile-rescue", "private": true,
# "dependencies": { "dsh-rescue-tui": "^0.2.0" },
# "dsh": { "profile": { "bundles": ["@deepseek-ai/dsh-base", "dsh-rescue-tui"] } } }
# 4. 安装并启动
pnpm install --dir $dir
dsh --profile rescue
```
### 方式 C · 开发模式(源码直连)
```powershell
# profile 的 dependencies 用 link: 协议指向本仓库根(package.json 所在处),
# 改代码即时生效,无需重装(插件自身依赖安装在仓库根 node_modules)
```
## 使用
```text
$ dsh --profile rescue
dsh rescue TUI — WebUI 挂掉时的极简维护入口
── 会话列表 ──
1 2026-08-24 20:27 · dsh-fix-ui · 156d8a5f-bf81 修复登录超时的问题
2 2026-08-23 12:53 · eval · 5b198c22-a3f4 (untitled)
数字=继续该会话 · n=新建 · q=退出
选择> 1
```
### 指令一览
| 分组 | 指令 |
|---|---|
| 会话 | `/sessions` 回列表 · `/new` 新会话 · `/exit` 退出 |
| 权限 | `/perm` 查看当前与可选 · `/perm read-only\|workspace-write\|danger-full-access` 切换 |
| 路由 | `/model` 列出全部 provider/model · `/model opencode/mimo-v2.5-free [effort] [save]` 切换 |
| 强度 | `/effort` 查看 · `/effort low\|high\|max\|off` |
| 审批 | `y` / `n` 回应当前审批 · `/y` `/n` 预答下一次审批 |
| 其它 | `/help` 帮助 |
回合进行中:直接输入 = 排队追问;Ctrl+C = 打断当前回合;空闲双击 Ctrl+C = 退出。
管道/脚本调用时 EOF 会 fail-closed:未决审批按拒绝处理。
## 权限模型
与 WebUI 完全同源的机制,零改动继承:
| 预设 | 文件沙箱 | 审批 |
|---|---|---|
| `read-only` | 只读 | ask |
| `workspace-write`(默认) | 限工作区 + 会话私有临时目录 | ask |
| `danger-full-access` | 不限 | never |
会话创建时钉扎权限预设,resume 保留原有效权限;切换前端不产生权限漂移。
## 工作方式
```text
dsh --profile rescue
→ @deepseek-ai/dsh-base (模型适配器 / 工具 / 持久化 / 沙箱 / 审批 全部来自 base)
→ dsh-rescue-tui cordis patch (裁剪协作工具行 + 插入三行)
├─ rescue-runner 终端 REPL:会话选择、resume、事件流渲染、审批应答
├─ rescue-web-fetch 匿名 HTTP fetch provider(启用 web_fetch)
└─ tool-web config fetch: true
→ ctx.agents.create()/resume() 同一套 ~/.dsh/sessions 日志,WebUI 与 TUI 天然互通
```
## 验证矩阵
| 场景 | 结果 |
|---|---|
| 组合校验 + boot→菜单→退出 | ✓ |
| resume 含崩溃残尾的真实历史会话 + 续聊 | ✓ |
| 越界写入被沙箱拒绝 → 升级审批 y 放行 → 文件落盘 | ✓ |
| `/perm` 查看 / 切换 / 回读 | ✓ |
| 单回合并行 pwsh + web_search | ✓ |
| `/model` 切 opencode/mimo-v2.5-free(日志实证 `"provider":"opencode"` ×6) | ✓ |
| `/effort` max → low 切换与回读 | ✓ |
## 已知边界
- WebUI 后端进程仍在运行时,不要两边同时续同一个 session(追加式日志双写冲突)
- fetch provider 无 JS 渲染能力,SPA 页面拿不到动态内容——此类需求用 pwsh 跑 curl 兜底
- 上游偶发 `PI_AI_ERROR: network_error` 会提前结束回合,重发即可(不做静默自动重试)
- peer 依赖对齐 `@deepseek-ai/*@^0.1.1-rc.2`,harness 大版本升级需回归
- Windows 下 bash 行由 base 平台门控自动禁用(pwsh 栈接管),POSIX 反之
## 开发
```powershell
pnpm install # 仓库根执行
pnpm check # node --check 全部模块
$env:RESCUE_TRACE='1'; dsh --profile rescue # stderr 过渡探针
```
插件契约照搬官方 headless runner:`export { name, inject, apply }`,服务经 `ctx.get()` 获取,
事件经 `ctx.on('session/event' | 'approval/request')` 订阅——无构建步骤,纯 ESM JS。
## License
[MIT](LICENSE) © marshfolx
Install
dsh plugin --profile web add github:marshfolx/dsh-rescue-tui#31b91fee786075bb8fd032702b34570446397b63
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-rescue-tui from the hub