前言¶
在 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/nullsource,确保 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