dsh-shared-bash:DeepSeek Harness 的会话级持久 PTY Bash 终端

前言

在 DeepSeek Harness(DSH)中,每个 Agent 的调用往往从空白环境开始:没有保留的 Shell、没有当前目录、也没有正在运行的后台进程。这让需要保持状态的自动化任务(比如在特定目录下构建、调试、长时间运行服务)必须反复“重置”上下文,增加开销且容易出错。

dsh-shared-bash 为 DSH 提供了“会话级持久 PTY Bash 终端”:每个 DSH 会话对应一个长期存在的 Shell,该 Shell 通过会话 ID 索引。Agent 可以随时“挂载”到这个 Shell,继续使用其工作目录、环境变量、函数与后台任务,而不必重新初始化。

是什么

  • 定位:为 DeepSeek Harness 提供按会话 ID 索引的持久 PTY Bash 终端,支持异步命令任务。
  • 维护者:snowy-yang。
  • 核心能力:
  • 每个会话一个 PTY,Shell 状态(目录、变量、函数、后台进程)跨调用保持。
  • 命令通过 bash_exec 异步提交,立即返回任务句柄,可稍后用 bash_wait 获取结果或 bash_read 实时读取输出。
  • 提供跨会话访问:通过指定 session_id,Agent 可以与其它会话的 Shell 交互。
  • 提供设置页与 HTTP API(/api/shared-bash)用于管理与调试。

安装与启用

安装前请确认 DeepSeek Harness 版本满足 ^0.2.1-rc.2,且已配置支持 PTY 的子进程提供者(桌面组合默认挂载 @deepseek-ai/dsh-subprocess-local + dsh-experimental-terminal-bundle;Windows 默认 Shell 为 MSYS2 bash)。

安装命令如下:

dsh plugin --profile desktop add git+https://github.com/snowy-yang/dsh-shared-bash.git

执行前请先退出 DSH 应用:pnpm 在 Host 持有文件时会重写 node_modules 并因权限错误失败。

工具与用法

安装后,可通过以下工具与终端交互(均可选 session_id,省略时指当前 Agent 的会话):

  • bash_attach:挂载到指定会话的终端(无则创建),可选 cwd 与 recreate 标志。
  • bash_exec:在终端中执行一条命令,立即返回 {job_id, session_id, status};可选 wait_ms 以快速返回已完成的结果。
  • bash_wait:等待指定任务,返回退出码、输出与 timed_out 标志。
  • bash_read:读取终端已保留的输出(不发送输入)。
  • bash_interrupt:向前台进程组发送 SIGINT(即真实 Ctrl-C),Shell 仍存活。
  • bash_close:关闭指定终端或全部终端。
  • bash_list:列出所有终端,显示会话 ID、状态、工作目录与是否正在执行命令。

示例:跨会话读取 Shell 输出并执行命令

bash_list              → 3f2a… · busy · C:\proj\widgets
bash_read   {session_id: "3f2a…"}
bash_exec   {session_id: "3f2a…", command: "git status --short"}
bash_wait   {job_id: "bash-9c1e…"}

终端模型

  • 每个会话一个 PTY,注册为全局,Shell 不在背后被共享。
  • Shell 启动为 bash -l -i(交互登录 Shell),使 MSYS2 的 PATH 与用户配置生效;指定 cwd 会先在 Shell 中 cd,POSIX 路径会被翻译到 MSYS2 安装目录。
  • Shell 保持当前目录、导出变量、Shell 变量、函数、别名以及后台进程。
  • 命令写入脚本文件并从 /dev/null source,确保 heredoc、循环、管道与引号行为与脚本一致,尝试读取 stdin 的命令会收到 EOF 而非占用终端输入。
  • 利用 Shell 在命令后打印的 sentinel 检测命令完成,token 仅存在于环境,防止终端回显伪造。
  • 每个终端保留 4000 行输出(环形缓冲),并剥离 ANSI 转义序列。

异步命令

bash_exec 不会阻塞等待命令完成,而是立即返回任务句柄。后续可按需继续:

bash_exec  {command: "npm run build"}        → job bash-9c1e…, status running
bash_wait  {job_id: "bash-9c1e…"}            → blocks until done, returns exit_code + output
bash_read  {}                                → what the terminal has printed so far
bash_interrupt {}                            → SIGINT, job settles as interrupted

同一终端同一时刻只能运行一个命令;再次在繁忙终端上提交 bash_exec 会被拒绝,返回 SESSION_BUSY。bash_wait 可指定短 timeout_ms,超时返回 timed_out: true 并让命令继续运行,便于轮询。

设置页与 API

DSH 设置中的“Bash terminals”页面列出每个终端,显示保留输出,支持发送命令、中断任务、附加新会话 ID 与关闭终端。

页面由插件的 JSON API 提供:GET /api/shared-bash、GET /api/shared-bash/output?session_id=…、GET /api/shared-bash/wait?job_id=…、POST /api/shared-bash/attach|/exec|/interrupt|/close。

由于 Harness Web 服务器没有额外的请求策略,该路由会自行防护:优先使用组合的 connection 服务;否则仅允许来自 Host 的请求,并要求匹配 Origin/Referer(仅允许 dsh-app://app 时的转发)。

配置项

cordis.patch.yml 中的默认配置均为可选:

Key 默认值 含义
bashPath C:\msys64\usr\bin\bash.exe Shell 可执行文件路径
msystem MSYS Shell 的 MSYSTEM 值
login true 使用 bash -l -i 而非 --noprofile --norc -i
cwd Host 进程当前目录 终端无初始目录时的启动目录
maxLines 4000 每个终端保留的输出行数
maxSessions 16 每个配置文件允许的并发终端数
cols / rows 120 / 30 报告的 PTY 尺寸

限制与注意事项

  • 每个终端同一时刻仅支持一条命令;并行工作需要创建多个会话。
  • 设置页是配置与监控界面,不是完整模拟器:仅显示剥离后的文本输出,不提供实时屏幕。
  • 终端为进程本地资源,随 Host 进程结束;Shell 以 Host 的权限运行,不是沙箱环境。使用前请检查源码与许可证。

小结

dsh-shared-bash 通过会话 ID 索引持久 PTY Bash,让 DSH Agent 可以在保持上下文的同时,以异步任务方式执行 Shell 命令,并支持跨会话共享与 Web 管理。适合需要在特定目录、环境与后台进程中持续工作的自动化工作流场景。

  • 目录页:https://www.skillhub.cn/plugins/snowy-yang/dsh-shared-bash
  • GitHub:https://github.com/snowy-yang/dsh-shared-bash
羽毛球分组比赛记分
小程序二维码

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

Xiaoye