dsh-local-terminal

August 15, 2026 · View on GitHub

为 DeepSeek Harness Web UI 提供 VS Code 风格的本机 zsh 终端。

A VS Code-style local zsh terminal plugin for the DeepSeek Harness web UI.

功能

  • 终端嵌入对话区底部,不遮挡聊天内容和输入框。
  • 点击 Terminal 展开或收起面板,关闭按钮也可收起;`Ctrl+`` 快速开关。
  • 面板顶边可拖动调整高度,双击恢复默认高度。
  • 终端与终端列表之间的竖直分割线可拖动调整宽度,双击恢复默认宽度。
  • 支持多个相互独立的 zsh 会话。
  • 终端列表支持切换、关闭,以及右键重命名或关闭。
  • 终端列表标签页支持上下拖动排序(白色指示条预览插入位置)。
  • 面板收起后保留 PTY、输出、滚动位置和进程状态。
  • 面板开关、尺寸、会话列表(命名/顺序)与激活标签持久化到 localStorage,刷新页面自动恢复。
  • WebSocket 断线自动重连(指数退避);服务端 PTY 断线保留 60 秒并重放断线期间的输出。
  • Cmd+V / Ctrl+Shift+V 粘贴;Ctrl+Shift+FFind 按钮在终端内搜索。
  • Cmd+A 全选、Cmd+K 清屏(均提供 Ctrl+Shift+ 别名,不劫持 shell 的 Ctrl+A/Ctrl+K)。
  • 终端区域右键菜单:Copy / Copy as HTML / Paste / Select All / Clear / Restart,视口内自动避让。
  • 标签右键 Split Terminal 竖向分屏,同一组最多 6 个窗格,全部共享组名(如 zsh 1);侧边栏每组显示为一行并带数量角标。
  • 双窗格分割线可拖动(双击复位);3 个及以上窗格等宽排列。点击窗格切换焦点(蓝色描边提示)。
  • Join Terminals 把组内窗格拆回独立标签;关闭组会关闭组内全部终端。
  • 分屏组、窗格顺序与分割比例随会话状态一起持久化。
  • 右键终端列表空白处或空舞台:New Terminal 新建会话、Move Tabs Left/Right 切换标签栏位置、Hide Tabs 隐藏标签栏;布局偏好持久化。
  • 面板标题行提供 VS Code 风格的终端选择器(zsh 1 ▾,与 Find/Clear/Restart 并列):点击弹出下拉,列出全部终端组(✓ 当前组)并可直接切换,底部提供 Show Tabs 恢复标签栏。
  • 面板高度变化时通知对话视图重新布局,避免虚拟列表裁切滞后。
  • 使用 xterm.js、Unicode 11 宽度规则和 Nerd Font 回退字体。

环境要求

  • macOS。
  • DeepSeek Harness,且已配置 web profile。
  • Node.js 22.19 或更高版本。
  • 系统存在 /bin/zsh

插件会启动真实的本机 shell。终端中运行的命令拥有启动 dsh web 的用户权限,请只在可信设备和可信 DSH 插件环境中使用。

安装

从 GitHub 安装到 DSH 的 web profile:

dsh plugin --profile web add github:Daisuki0721/dsh-local-terminal

安装后启动或重启 Web UI:

dsh web

浏览器打开 DSH 页面后,Terminal 按钮会显示在 Agent preset 右侧。

从本地源码安装

git clone https://github.com/Daisuki0721/dsh-local-terminal.git
cd dsh-local-terminal
pnpm install
pnpm build
dsh plugin --profile web add "$PWD"

使用

  1. 点击对话区顶部的 Terminal 打开底部面板。
  2. 点击工具栏的 + 创建新的 zsh 会话。
  3. 点击右侧终端名称切换会话。
  4. 右键终端名称进行重命名或关闭。
  5. 拖动面板上边界调整高度;双击上边界恢复默认高度。
  6. 拖动终端列表左侧的竖直分割线调整列表宽度;双击恢复默认宽度。
  7. 再次点击 Terminal 或点击面板右上角的关闭按钮收起面板。

快捷键:Ctrl+`` 开关面板;Cmd+V/Ctrl+Shift+V 粘贴;Ctrl+Shift+F 打开搜索(Enter 下一个、Shift+Enter 上一个、Esc` 退出);刷新页面后会话列表、命名、顺序与面板尺寸自动恢复,运行中的 shell 会在 60 秒内重连并保留输出。

Clear 只清除当前终端的可见缓冲区;Restart 只重启当前 zsh 会话。

安全设计

后端 WebSocket PTY 路由采用以下限制:

  • 只接受 127.0.0.1localhost 和 IPv6 loopback 请求。
  • 校验浏览器请求的 Host、Origin 和同源关系。
  • 拒绝浏览器标记为 cross-site 的请求。
  • 对 WebSocket 输出设置背压上限。
  • 每个 WebSocket 连接对应一个独立 PTY,连接销毁时终止其 shell。

不要把 DSH Web 服务代理到不受信任的公网地址。loopback 校验是本插件安全边界的一部分。

更新

dsh plugin --profile web remove @dsh-external/dsh-local-terminal
dsh plugin --profile web add github:Daisuki0721/dsh-local-terminal

卸载

dsh plugin --profile web remove @dsh-external/dsh-local-terminal

开发

pnpm install
pnpm typecheck
pnpm test
pnpm build

项目结构:

src/index.ts             Host 插件入口
src/routes.ts            loopback WebSocket upgrade 路由
src/pty-session.ts       node-pty 会话管理
src/client/              Web UI、终端列表和布局逻辑
cordis.patch.yml         DSH loader 插件声明

构建产物位于 lib/。插件仅依赖公开发布的 @deepseek-ai/* SDK,不需要 DeepSeek Harness 源码 checkout。

常见问题

安装后没有出现 Terminal 按钮

确认插件存在于 web profile,然后完整重启 dsh web。单纯刷新浏览器不能加载新的 Host 插件。

License

BSD 3-Clause