Escape Pod (dsh-escape-pod): Keeping Commands Alive Outside the DSH Process Tree

前言

DeepSeek Harness(DSH)里,模型常用的 pwsh 等工具把命令跑在 Host 进程树里。Host 一旦退出——重启、更新插件、崩溃——子进程会被一并清掉;前台调用在重启时还可能被平台补一条 TOOL_OUTCOME_UNKNOWN,长任务只能从头再来。

下面介绍独立插件 逃生舱(仓库 DX12xyz/dsh-escape-pod,包名 @local/dsh-escape-pod)。它用 detached 的 pod 进程接管命令寿命,DSH 只做客户端;重启或热重载只断连接,不杀正在跑的命令。权限仍跟随会话文件策略,不是把沙箱一起搬走。

这是什么

逃生舱由社区维护者 DX12xyz 发布,分类为工作流,许可证 MIT。当前 README 标明版本 1.1.1,仅支持 Windows,提供七个以 pod_* 为前缀的工具,并自带设置页。

一句话定位:命令在 DSH 之外的 pod 里继续跑,输出与账本落在 %LOCALAPPDATA%\dsh-escape-pod-core\,Host 重启后可以连回同一个 pod 续读、继续等结果。

核心功能

命令寿命与 DSH 解耦

pod 由 Host 以 detached: true 方式 spawn 并 unref(),不经过 ctx.subprocess / ctx.jobs / ctx.terminal,因此不在 DSH 的 kill-on-close Job 里。DSH 重启或崩溃只关闭连接,不停命令。

七个工具

工具 作用
pod_run 后台启动命令,立即返回 jobId;不设命令超时,跨重启继续跑
pod_exec 前台同路径 spawn,阻塞到结算;可通过 resumableToolCalls 跨重启回填,避免 TOOL_OUTCOME_UNKNOWN
pod_output 从上次偏移续读输出,内部自动 ack
pod_kill 终止 runner,账本记为 killed
pod_freeze 冻结或解冻整棵命令树;DSH 消失约 10 秒后可进入冻结,超时预算在冻结期间暂停
pod_status 诊断 pod 身份、protocol、本会话 job、会话文件策略、命令行等;支持 action:"relaunch" 换代码
pod_shell 列出本机 PowerShell / bash / cmd 候选并为当前会话选择;不连接 pod

插件不提供 shell,只探测本机可用候选(含其他插件或系统安装的路径)。

权限仍留在 DSH 会话里

每次调用重新解析会话文件策略:

  • read-only / workspace-write:Host 用 ctx.sandbox.confine() 现签受限 runner 前缀,命令在 Low 完整性 + WRITE_RESTRICTED 与 kill-on-close Job 里跑。
  • danger-full-access:无前缀,pod 以 Medium 完整性直接 spawn。

窄会话可对单条命令申请更宽模式:传 sandbox_permissions 与 justification,走真实 DSH 审批;只有用户选「仅本次允许」才执行。

冻结与生命周期

DSH 长时间不在时,可按设置冻结运行中的命令;回来立即解冻。长时间无人回来则按 freezeMinutes 再生,次数耗尽 pod 自毁。无客户端、无运行中 job、无冻结 episode 时,pod 也会自行退出,不再空等。

安装与启用

要求:Windows、可用的 dsh 命令。装好插件后重启 DSH(Host 半身需重启;Client 刷新页面即可)。

方式一:插件页(推荐)

  1. 打开 DSH 插件页 →「安装插件」;
  2. 安装源填 https://github.com/DX12xyz/dsh-escape-pod,或 github:DX12xyz/dsh-escape-pod;
  3. 按提示重启 DSH。

方式二:命令行从 git 源安装

Web profile 示例(桌面版将 web 换成 desktop):

dsh plugin --profile web add github:DX12xyz/dsh-escape-pod

方式三:本地目录(开发或离线)

dsh plugin --profile web add "link:<仓库根目录绝对路径>"

方式四:离线 tgz

在仓库根目录执行 npm pack 后安装产出的 tgz:

cd <仓库根目录>
npm pack
dsh plugin --profile web add "file:<仓库根目录>/local-dsh-escape-pod-1.1.1.tgz"

验证是否装好

重启 DSH 后调用一次 pod_status,确认 podVersion=1.1.1、protocol=3,以及 podPid、pipe、会话文件策略、命令行映射等字段符合 README 中的「装好判据」。

注意:Host 与 pod 必须同版本;旧 pod(protocol < 3)会导致 pod_run / pod_exec 报 EPROTOCOL。卸载前应在插件页「逃生舱」卡片长按 5 秒关闭正在运行的 pod;卸载命令为:

dsh plugin --profile web remove @local/dsh-escape-pod

典型用法

先做后台长任务,DSH 重启后继续读输出:

pod_run({ command: "1..600 | ForEach-Object { Start-Sleep -Seconds 1; $_ }",
          description: "long ticker" })
→ { jobId: "podc-...", runnerPid: 1234, ... }

pod_output({ jobId: "podc-..." })
pod_status({})
pod_kill({ jobId: "podc-..." })

前台跑一条命令并拿完整结果(含跨重启):

pod_exec({ command: "npm test" })

只读会话里需要写盘构建时,可申请一次性提权(须用户批准):

pod_run({ command: "npm run build",
          description: "build(当前会话是只读)",
          sandbox_permissions: "workspace-write",
          justification: "构建要写 dist/ 与 node_modules/.cache,当前会话是只读" })

适用场景与注意

适合谁:在 Windows 上用 DSH 跑长时间构建、测试、批处理,且希望 Host 重启、插件热重载或崩溃时不中断命令、又能续读输出的开发者。

务必知晓:

  • 插件与 pod 以当前用户权限运行;danger-full-access 会话下命令能力等同于用户本机权限。安装前应阅读仓库源码与 MIT 许可证,自行评估风险。
  • 账本在工作区外的 %LOCALAPPDATA%\dsh-escape-pod-core\,卸载插件不会自动删除;确认不需要时再手动清理。
  • 社区目录 SkillHub 插件页 与 GitHub 仓库相互独立索引,并非 DeepSeek 或幻方官方应用商店;生态遵循 DSH「一切皆插件」的思路,选型以仓库 README 与 TECHDOC 为准。

结尾

逃生舱解决的是「DSH 一动长任务就死」的问题:寿命搬到 detached pod,权限仍绑在会话策略与 DSH 审批上。需要细节时见仓库 README 与 TECHDOC.md。

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

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

Xiaoye