dsh-web-terminal:给 DSH web GUI 加一个多标签本地终端

前言

用 DeepSeek Harness(DSH)做智能体开发,大部分时间泡在 web GUI 里,但一到要执行 shell 命令——起服务、看日志、临时进 vim 改配置——就得切出去另开一个终端窗口,回来还要自己对一遍目录和会话状态。

dsh-web-terminal 解决的就是这个问题:它在 web GUI 侧边栏加一个 Terminal 入口,打开一个多标签终端面板,每个标签都是宿主进程上的真实 PTY shell。DSH 的理念是一切皆插件,这个插件不改 dsh 源码,装进 web profile 即可。下面按功能、安装、配置、验证的顺序介绍。

这是什么

dsh-web-terminal 是 iamsee123 维护的 DeepSeek Harness web GUI 本地终端插件,当前版本 0.1.1,MIT 许可证(README 的 License 章节与 package.json 均标明)。一句话定位:侧边栏多标签 xterm.js 面板,每个标签通过 node-pty 在宿主进程运行真实 PTY shell,并经 WebSocket 路由流式传输。

依赖栈很直接:node-pty ^1.1.0 负责 PTY,@xterm/xterm ^6.0.0 负责前端渲染,@xterm/addon-fit ^0.11.0 负责尺寸适配,ws ^8.18.0 负责传输,react ^18.2.0 作为 peer dependency。

核心功能

按 README 的说明,能力集中在六点:

1、真实伪终端 shell:交互程序(vim、top、htop)、Ctrl-C、resize 均可用;
2、多标签终端面板,提供新建 / 关闭 / 断开 / 重连 / 清屏控制;
3、面板打开、窗口 resize、容器变化时自动适配(auto-fit);
4、shell 与工作目录可配置(settings panel 或 patch yaml);
5、所有路由带 loopback-only 信任栅栏(同源 + 127.0.0.1/localhost 校验);
6、热插拔:不改 dsh 源码,通过 web profile bundle list 挂载,与 dsh-ssh 相同的 dual-face 插件模式。

双半边架构

插件分 host、client 两半:

半边 入口 职责
host(node) lib/index.js(源码 src/index.ts node-pty shell 会话、/api/dsh-terminal/info 路由、/api/dsh-terminal/terminal WebSocket 升级、system-prompt 公告、settings 命名空间(shell/cwd)
client(浏览器) lib/client.js(源码 src/client/index.ts 侧边栏 Terminal 入口(DOM 注入、自愈)、多标签终端面板(React + xterm.js)

线协议

两端通信走 src/protocol.ts 定义的线协议:

client → host: {type:"input",data}、{type:"resize",cols,rows}
host → client: {type:"ready",shell}、{type:"output",data}、{type:"exit",code,error?}

client 发送键盘输入和尺寸变化,host 返回就绪、终端输出和退出事件。

安装与启用

先确认 Node 版本:package.json 的 engines 要求 ^22.19.0 || >=24.0.0。官方提供两种安装方式。

Option A:bundle list(推荐)

先做构建脚本放行,再添加依赖并挂载到 bundle list。在 ~/.dsh/profiles/web 下操作:

# 1) 一次性:在 ~/.dsh/profiles/web/pnpm-workspace.yaml 允许构建脚本
#    allowBuilds:
#      esbuild: true
#      node-pty: true

# 2) 添加依赖(路径换成你的 checkout 位置)
cd ~/.dsh/profiles/web
pnpm add dsh-web-terminal@link:/path/to/dsh-web-terminal

# 3) 在 package.json 的 dsh.profile.bundles 里追加 "dsh-web-terminal"
#    (bundle 自带的 cordis.patch.yml 会插入 id=terminal 的插件行)

# 4) 重启 dsh web

第一步不能省:node-pty 和 esbuild 的构建脚本需要先在 pnpm-workspace.yaml 里放行,否则装不上。

Option B:手动 patch 行

如果包已安装到 profile,也可以在 ~/.dsh/profiles/web/cordis.patch.yml 手动添加 patch 行:

- insert:
    - id: terminal
      name: 'dsh-web-terminal'

配置

shell 与工作目录都可在 settings panel 或 patch yaml 里配置:

- id: terminal
  config:
    enabled: true
    announceToAgent: true
    shell: /bin/zsh      # 默认取 $SHELL
    cwd: /path/to/work   # 默认为宿主进程 cwd(即 workspace root)

四项分别控制开关、是否向 system-prompt 公告、要启动的 shell、以及工作目录。不配置时 shell 取 $SHELL,工作目录落在宿主进程 cwd(workspace root)。

验证

重启 dsh web 后,先用 curl 确认 host 路由已就位:

curl http://127.0.0.1:3080/api/dsh-terminal/info
# {"shell":"/bin/zsh","platform":"darwin",...}

能返回 shell 和平台信息,说明 host 半边挂载成功。然后刷新浏览器 GUI:侧边栏出现 Terminal 入口,新建标签,输入命令即可。

开发与已知问题

想从源码构建或参与开发,官方给出的命令如下:

pnpm install                   # pnpm-workspace.yaml 必须放行 esbuild / node-pty 构建脚本
pnpm run typecheck             # tsc --noEmit
pnpm run build                 # esbuild 产出 lib/index.js(host)+ lib/client.js(ModuleLoader 包装)
pnpm test                      # client bundle 语法 + jsdom ModuleLoader 模拟
node scripts/smoke.mjs         # host WebSocket 链路冒烟测试
node scripts/browser-diag.mjs  # Playwright:打开真实 GUI,点 Terminal,敲一条命令

构建脚本会把 node_modules/@xterm/xterm/css/xterm.css 内嵌进 src/client/xterm-css.ts(生成文件),因为 ModuleLoader 环境没有 CSS loader。

README 列了三个已知坑:

1、@xterm/* 必须打包进 bundle。client 侧只有平台种子模块(react 全家)和 shell 自带模块(@deepseek-ai/*)可以保持 external,xterm 若保持 external 会报 require("@xterm/xterm") missed the module table

2、面板高度链。[data-dsh-terminal-view] 是绝对定位容器,其直接子元素 .dshTermView 必须设 height: 100%,否则内层 .dshTermPanel { height: 100% } 会解析到 auto 高度的父级,整条 flex 链塌陷,终端被压成 2px 条。

3、spawn-helper 可执行位。预编译的 prebuilds/<platform>/spawn-helper 可能丢失可执行位,报 posix_spawnp failed;执行 pnpm run fix:spawn-helper 修复(postinstall 会在 pnpm install 时自动执行)。另外注意:node-pty 的 spawn 在 dsh 文件沙箱内会被阻止,冒烟测试需针对真实 dsh 进程运行。

适用场景与注意

适合的场景:你已经在用 DSH web GUI,希望在同一个界面里完成命令执行——调试智能体时看日志、跑脚本、临时进 vim 或 top,不必来回切窗口。

权限方面务必明确:这个终端以当前 dsh 进程(即宿主用户)的权限执行命令,等同于直接 shell 访问。所有路由虽有 loopback-only 信任栅栏(同源 + 127.0.0.1/localhost 校验),也应只在本地环境使用。安装任何第三方插件前,建议先检查源码与许可证;本插件许可证为 MIT。

结尾

回顾一下:dsh-web-terminal 把真实 PTY shell 塞进 DSH web GUI,不改源码、热插拔,交互程序、Ctrl-C、resize 都能用。如果你日常泡在 dsh web GUI 里,可以装一份试试。

  • 目录页:https://www.skillhub.cn/plugins/iamsee123/dsh-web-terminal (社区维护的目录站点,与 DeepSeek / 幻方无官方从属关系)
  • GitHub:https://github.com/iamsee123/dsh-web-terminal
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

Xiaoye