dsh-interactive-terminal
Verifieddsh-interactive-terminal · v0.2.0 · MIT · Web UI
Interactive terminal plugin for DeepSeek Harness
Install
dsh plugin add dsh-interactive-terminal Confirm the layer applied with dsh --profile default --dump-config — see the install guide.
Source
Published to npm without a public repository. Inspect the package contents before installing.
Creators
Readme
dsh-interactive-terminal
English | 中文
在 DeepSeek Harness Web 中提供模型与用户共享的持久 Bash 终端。每个存活的 Agent 独占一个 PTY,通过 xterm.js 显示在对话输入框上方。模型可以调用终端工具,用户也可以在同一交互进程中继续输入,无需另开 shell。

模型启动交互程序后,用户完成四轮 UTF-8 输入时的已连接 Controller 视图。
快速开始
要求:macOS 或 Linux、Bash、Node.js ^22.19 || >=24,且 PATH 中有 pnpm。插件 0.1.0 已针对 DSH 0.1.0-rc.8 和 pnpm 10.18.3 验证。
npm install -g @deepseek-ai/[email protected] [email protected]
dsh plugin --profile web add [email protected]
dsh --profile web
打开 DSH 输出的 Web 地址,按需配置模型,选择工作区和对话,再点击 Open terminal(打开终端)。在空闲提示符下输入 echo hello,即可验证浏览器输入。以后启动只需:
dsh --profile web
安装
使用已安装的 DSH CLI 加载 npm 包
dsh plugin --profile web add [email protected]
dsh --profile web
插件命令会把包安装到 Web profile,并自动启用包内的 cordis.patch.yml,无需额外添加 --patch。仅执行 npm install -g 全局安装插件不会在 DSH 中启用它。
安装和启动必须使用同一个 DSH_HOME,默认值是 ~/.dsh。添加或更新插件后,需要重启已运行的 DSH。若 pnpm 报告没有可用版本,请确认 profile 使用 npm 公共 registry:
cd "${DSH_HOME:-$HOME/.dsh}/profiles/web"
pnpm config set registry https://registry.npmjs.org/ --location=project
从 DSH 源码加载 npm 包
使用插件支持的 DSH 标签,再运行仓库中的源码 CLI:
git clone --branch dsh-v0.1.0-rc.8 --depth 1 https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
pnpm dsh plugin --profile web add [email protected]
pnpm dsh --profile web
第一个 pnpm dsh 等价于已安装的 dsh 命令,但直接运行源码。Profile 仍保存在同一个 DSH_HOME 下,因此后续从源码启动只需执行最后一条命令。
从插件源码安装
git clone https://github.com/mingzhicode/dsh-interactive-terminal.git
cd dsh-interactive-terminal
pnpm install
pnpm run build
dsh plugin --profile web add "$PWD"
dsh --profile web
Profile 会加载本地 checkout 中已构建的 lib/ 和 dist/ 文件。修改插件源码后,需要重新构建并重启 DSH。如果同时使用 DSH 源码,请在 DSH 仓库中运行 pnpm dsh,并把本插件的绝对目录传给 plugin add。
安装已下载的 npm 压缩包
dsh plugin --profile web add ./dsh-interactive-terminal-0.1.0.tgz
dsh --profile web
压缩包包含服务端和浏览器构建产物,安装时不执行构建或 postinstall;安装依赖仍可能需要访问 registry。可用 npm pack [email protected] 单独下载已发布的压缩包。
交互过程
- 点击 Open terminal(打开终端)。首次展开面板或首次调用 Agent 工具时,才为该 Agent 创建 shell。
- 确认状态栏以 Controller 开头。Shell 空闲时可以直接输入;首个按键申请人工输入权,后续按键等待授权。
- 让模型调用
shared_terminal_send启动程序。模型操作占用队列时,普通键盘输入会被忽略,不会在稍后变成 shell 命令。 - 程序要求输入时,点击 Take over input(接手输入),等待授权后再输入。接手保留原进程、不发送信号,并解除模型操作的时限。
- 在同一个 PTY 中继续输入文字、Enter、emoji 或其他 UTF-8 内容。Enter 只提交输入,不释放输入权;验证过的 shell 提示符或进程退出才结束本轮交互。所有人工交互完成后,无论是从空闲提示符直接输入还是通过接手输入,插件都会直接通知 Agent,使其读取终端并继续执行。
- 使用 Interrupt input(中断输入) 向重新检查后的前台进程组发送
SIGINT。它会中断程序,并保持输入权直到提示符恢复;它不是输入接手。
设置菜单提供 Reconnect(重新连接)、本地 Clear view(清除显示)、字号调整和需要确认的 Reset Terminal(重置终端)。折叠面板、清屏或重连不会结束 shell;调整面板大小也不会改变固定的 PTY 行列数。服务端销毁终端时,面板会关闭并清理本地渲染器和未发送输入;短暂断线仍会自动重连。
每个 Agent 只允许一个浏览器视图控制终端,其他视图和所有移动端视图均为只读。Take over input 是把模型当前占用的队列操作转交给浏览器 Controller,并不会从另一个浏览器视图夺取 Controller。若状态栏显示 Read only,请关闭控制端视图,等待 disconnectGraceMs,再点击 Reconnect。
配置
在 ~/.dsh/profiles/web/cordis.patch.yml 中添加覆盖项;使用自定义目录时,路径为 $DSH_HOME/profiles/web/cordis.patch.yml:
- id: dsh-interactive-terminal
config:
shellPath: /bin/bash
shellArgs: [--noprofile, --norc, -i]
rows: 40
cols: 160
Patch 会替换该条目的完整 config;请写入所有需要保留的自定义值。省略字段使用下表默认值。
插件加载时解析配置。修改 patch 后需要重启 DSH,新值才会生效。Reset Terminal 会销毁当前 shell,并使用内存中已经加载的配置创建新代次;它不会重新读取 YAML 文件。
| 字段 | 默认值 | 生效方式 |
|---|---|---|
shellPath |
/bin/bash |
Bash 可执行文件,不支持其他 shell;创建终端代次时使用。 |
shellArgs |
--noprofile --norc -i |
交互式 shell 参数,不允许空参数;生成 shell 时使用。 |
rows |
40 |
每个新终端代次固定的 PTY 行数。 |
cols |
160 |
每个新终端代次固定的 PTY 列数。 |
scrollbackLines |
10000 |
保留的历史行数,不含视口;用于服务端快照和浏览器渲染器。 |
scrollbackMaxBytes |
4194304 |
序列化 ANSI 历史的 UTF-8 字节上限,不含视口。 |
maxToolOutputBytes |
262144 |
完整工具结果 JSON 的字节上限;至少 1024,且不超过 scrollbackMaxBytes。 |
maxInputBytes |
65536 |
单次模型发送或一次人工输入授权的字节上限。 |
maxQueuedOperations |
128 |
每个 Agent 接受的修改操作数上限,包含当前操作。 |
maxSessions |
32 |
存活 Agent 终端数上限。 |
pollIntervalMs |
50 |
两次前台进程检查之间的等待时间。 |
operationTimeoutMs |
30000 |
模型修改操作进入中断恢复前的时限。 |
interruptTimeoutMs |
5000 |
发送 SIGINT 后等待受控提示符恢复的时限。 |
disconnectGraceMs |
15000 |
Controller 断开后,在恢复并释放人工输入权前保留重连机会的时间。 |
disposeGraceMs |
3000 |
重置或销毁时终止进程树的宽限时间。 |
方案说明
终端持有与生命周期
- 终端属于确切的存活 Agent,而不是浏览器标签页或某次工具调用。首次展开 UI 或调用工具时,才在该 Agent 的工作区和 sandbox 策略下创建终端。
- 折叠面板和通过认证的重连会保留原 shell。重连先恢复有界屏幕快照,再接收实时输出,并校验终端代次和输出序号。
- 每个 Agent 只有一个浏览器 WebSocket 是 Controller。私有重连凭证可以在
disconnectGraceMs内恢复控制权;其他桌面视图和所有移动端视图只读。 - 重置会终止当前进程树并创建新代次。Agent 销毁、插件卸载和 HMR 会撤销浏览器连接并终止所属进程树。Shell 自然退出后保留最终屏幕,直到重置。
FIFO 队列、接手与恢复
- 模型发送、人工输入授权、信号和重置共用每个 Agent 的严格 FIFO 修改队列,按接受顺序执行;
shared_terminal_read不占用输入权并绕过该队列。 - 已授权的模型发送可以原地转交给 Controller。接手保留当前队列位置、清除模型超时、向模型返回
waitReason: human_handoff,并让后续操作继续等待。 - 提示符、检测到的前台
stdin_read或进程退出会完成当前操作。macOS 上的 DSHrc.8不报告stdin_read,因此交互提示需要在operationTimeoutMs到期前显式接手。 - 模型超时或取消时,会向重新检查后的前台进程组发送
SIGINT,恢复提示符前不会释放队列。若在interruptTimeoutMs内未恢复,队列进入 blocked 状态;只有最早接受的 reset 可以替换它。 - 配置会限制队列长度、输入字节、保留输出、工具 JSON 和存活 Agent 终端数。输出快照截断时保留最新的有效 UTF-8 后缀。
Agent 工具
四个工具都作用于当前执行 Agent 的终端。调用者不能另选 Agent、PTY、工作目录、shell、环境或 sandbox。
| 工具 | 行为 |
|---|---|
shared_terminal_send({ text, submit? }) |
排队发送模型输入。submit 默认为 true,会附加 Enter;在提示符、检测到 stdin_read、人工接手、退出或超时/取消恢复时返回。 |
shared_terminal_read({ offset?, count? }) |
不申请输入权,读取视口和相对最新端的历史分页。offset 从最新端跳过行,count 选择此前的行。 |
shared_terminal_signal({ signal }) |
排队向重新检查后的前台进程组发送 SIGINT、SIGTERM、SIGKILL、SIGTSTP 或 SIGHUP;拒绝对顶层 shell 发送 SIGKILL。 |
shared_terminal_reset({}) |
排队终止进程树并创建新 shell 代次,也用于替换自然退出的 shell。 |
结果包含终端代次、输出序号、行列数、视口、光标、进程与队列状态、当前持有者、排队数和截断状态。修改类操作另含排队时长和 waitReason;发送与信号另含捕获的操作输出。读取另含 text、lineBegin(含)、lineEnd(不含)和 totalLines。光标坐标从零开始。
waitReason: human_handoff 表示用户持有仍在运行的交互,不表示命令已经完成。模型必须等待,不应在人工输入授权之后继续提交回答。超时同样不能证明前台进程已经退出。
恢复与限制
queue is blocked until reset:中断恢复超时。等待最早接受的 reset;后续修改操作会被拒绝。terminal queue is full:等待已经接受的操作完成,不要并行重试。terminal capacity reached:先结束 Agent 或等待清理完成,再考虑提高maxSessions。- 浏览器写入被拒绝后,需要显式点击 Reconnect。Controller 断开恢复仍遵守
disconnectGraceMs。 - 固定使用
TERM=dumb、固定行列数和PAGER=cat。不支持全屏或依赖终端查询的 TUI;浏览器会抑制自动生成的查询回复,Host 也没有查询响应器。 - Linux 可以在检测到前台标准输入等待时让出输入权,但 Linux 原生环境和多轮 REPL 尚待验证。
安全
Host 决定终端身份、工作目录和 sandbox 策略。需要隔离时,如果隔离不可用就拒绝启动,不会退回非隔离执行。Shell 不继承 Harness 凭据。
浏览器使用与 Agent 绑定、只存哈希、十秒有效的一次性令牌连接。WebSocket 不接受调用者指定的 Agent、Session 或 PTY 标识。原始终端输出和人工按键不作为会话事件记录;模型工具参数和有界结果仍正常记录。
自定义 subprocess provider 必须和官方 DSH rc.8 provider 一样,在发送信号时重新检查前台进程组,并拒绝对顶层 shell 发送 SIGKILL。
开发与打包
pnpm install
pnpm run build
npm pack --dry-run
npm pack
生成的 .tgz 可以按上方压缩包方式安装。需要隔离验证时,请在安装和启动前把 DSH_HOME 设为新目录。无密钥 Web 测试使用回放模型、真实 Agent loop 和原生 PTY,不等同于实时模型测试。
构建和验证不会发布 npm 包。手工发布前需运行发布检查、核对包内容,并确认 npm 账户、registry、版本和明确的发布授权。不要把凭据写入仓库或日志。
许可证
MIT,见 LICENSE。