Sutera-Diffusus / dsh-sandbox-tester

Listed

DSH sandbox tester: process-isolated testing ground for DeepSeek Harness

mainToolSandbox View source

Installation

npx -y @deepseek-ai/dsh plugin --profile web add github:Sutera-Diffusus/dsh-sandbox-tester

This installation command is an unverified starting point generated from the GitHub repository address.

README

Maintainer-authored documentation snapshot.

View on GitHub ↗
Commit 8fd746dSynced Aug 18, 2026

dsh-sandbox-tester

DSH 沙盒测试器——为 DeepSeek Harness 打造的进程级隔离测试场。

开发者正在面对什么

在 DSH 上开发插件、打补丁、做测试时,你面对的是这样一个现实:所有插件都运行在同一个宿主进程里。改坏一行代码,死循环会卡死整个主进程,未捕获异常会崩掉整个应用;测试脚本一个手滑,误杀进程、误删数据,连聊天记录都可能一起陪葬。然后就是那个熟悉的循环:页面打不开 → 重启 Launcher → 切换间隙报连接失败和 400 → 再重启……改坏一次代码,一晚上就没了。

于是,有了沙盒测试器

把每一次开发/测试改动,先关进一个完全隔离的沙盒实例(独立进程 + 独立数据 + 独立端口)里跑:沙盒里随便崩、随便死循环、随便误操作,最坏的结果也只是沙盒进程自己倒下,本体 3080 全程无恙。改动想回到本体,还必须通过机器强制的合回门禁(目标白名单 + 逐文件语法校验 + bundle 校验 + 备份/回滚清单),带着坏状态偷渡?门都没有。

沙盒里随便作,本体永不翻车。

License Version DSH


目录


特性

🧪 进程级隔离沙盒

  • sandbox_create 从本体程序目录复制出独立沙盒(默认裁剪,fullCopy: true 全量);
  • 沙盒 = 独立程序副本 + 全新 DSH_HOME + 自动分配独立端口(3182 起,冲突自动 +1);
  • 沙盒由 node bin.js web --port <p> 直接拉起,崩溃只死沙盒进程;
  • 实证:沙盒内注入坏补丁/强杀沙盒进程,本体 3080 全程 HTTP 200。

🛠️ 9 个原生工具

工具用途
sandbox_list列出全部沙盒(状态/端口/年龄/最近报告)
sandbox_create创建沙盒(裁剪或全量复制、指定端口)
sandbox_inject把待测插件/补丁打进沙盒(自动备份 + 回滚清单,路径越界即拒绝)
sandbox_run预检本体 → 拉起沙盒 → 轮询健康 → 可选一键 QA
sandbox_health端口 + HTTP + 关键 bundle 检查,产出报告
sandbox_stop停止沙盒(进程树校验:永不会误伤 3080)
sandbox_destroy销毁沙盒(需 confirm: true,目录与注册表全清)
sandbox_merge门禁式合回(见下文)
sandbox_prune清理孤儿/超龄沙盒(默认 48h 标记,dryRun 预览)

🚧 合回门禁(机器强制,不可绕过)

目标白名单(11 个补丁面文件 + 显式新增)→ 逐文件 node --check → bundle 校验 → 备份计划 + 回滚清单 → 默认 dryRun 只校验出报告;真实写入需 DSH_SANDBOX_MERGE_ALLOW=1 且失败即自动回滚。

🌐 一键 QA(真实浏览器)

sandbox_run qa: true 接跑 CDP 9223 驱动的 headless Edge:首页 200、/plugins/dsh-sandbox/client.js 200、设置页真实渲染「测试沙盒」区段、控制台无未捕获异常,产出结构化报告。

⚙️ 设置页管理

DSH 设置 → 测试沙盒:沙盒卡片(状态徽标/报告徽标/端口/年龄/操作按钮)、新建表单、48h 超龄提示、一键清理、合回门禁摘要卡。


架构

设计原则:编排/执行平面分离

dsh-sandbox 遵循编排平面与执行平面分离(orchestration–execution separation)原则:编排平面驻留于本体进程(信任域 T0),只承担调度、校验与生命周期管理;一切不可信的插件与补丁都在执行平面——独立沙盒进程(不可信域 T1)——中运行。两个平面之间唯一的交互通道是受操作系统强制约束的进程边界,不存在任何共享内存或共享数据目录。

分层架构

┌─────────────────────────────── 编排平面(本体进程 · 信任域 T0)───────────────────────────────┐
│  L4 客户端层   client/client.js — 设置页「测试沙盒」区段(卡片管理 / 报告徽标 / 门禁摘要)       │
│                                                                                             │
│  L3 工具层     9 个原生工具:list · create · inject · run · health · stop · destroy ·         │
│                merge · prune                                                                  │
│                · 统一参数 schema 校验;merge 为门禁式事务(见隔离不变量 I5)                      │
│                                                                                             │
│  L2 服务层     registry — 沙盒注册表(原子写:tmp + rename)                                    │
│                ports    — 端口池(探测分配,冲突自动递增,3182 起)                               │
│                proctree — 进程树管理(终止前反查 3080 归属,含本体即拒绝)                       │
│                                                                                             │
│  L1 配置层     settings 命名空间 sandbox(SANDBOX_ROOT / PORT_START / AGE_HOURS)              │
├─────────────────────────────────────────────────────────────────────────────────────────────┤
│      ▲ 受控接口:spawn(强制注入独立 env)· taskkill(进程树校验)· HTTP 轮询 · report.json 回传  │
│      │        信任边界 = 操作系统进程隔离(无共享内存,无共享数据目录)                          │
├─────────────────────────────────────────────────────────────────────────────────────────────┤
│  执行平面(沙盒进程 · 不可信域 T1)                                                            │
│  独立程序副本 ─ 独立 DSH_HOME ─ 独立端口(3182+)─ 待测插件 / 补丁                              │
│  故障域 F 完全独立:死循环 / 未捕获异常 / 资源耗尽 / 误操作均被限制在 F 内                      │
└─────────────────────────────────────────────────────────────────────────────────────────────┘

隔离不变量(架构正确性判据)

#不变量强制机制
I1进程隔离沙盒由 spawn 独立拉起;沙盒崩溃/被强杀,本体进程不受任何影响
I2数据隔离启动时强制注入独立 DSH_HOME;沙盒对本体数据目录零引用
I3端口隔离端口池自动分配(3182 起),与本体 3080、固定副本 3181 永不冲突
I4终止安全sandbox_stop 在 taskkill 前反查 3080 监听 PID,目标进程树包含本体即拒绝执行
I5写入门禁merge 执行目标白名单 + 逐文件语法判定 + bundle 校验;默认 dryRun 只出报告,真实写入需显式开关且失败自动回滚

生命周期状态机

creating ──▶ stopped ⇄ running ──▶ destroyed
                │                     ▲
                └──(48h 未运行或进程已死)──▶ prune 回收

完整的门禁决策树、一键 QA 交互时序与事故对照见 FLOW.md


安装要求

项目要求
操作系统Windows 10 / 11
Node.js18+(执行安装脚本需要)
DeepSeek Harness0.1.0-rc.6 或同系列版本
磁盘每个沙盒默认裁剪复制约 270 MB(node_modules)

安装脚本会修改 DSH 安装目录中两处文件(profile manifest、apiproxy 白名单,均先备份),建议安装前关闭 DSH 页面。

安装教程

第 1 步:获取插件

方式 A:下载 Release(推荐):打开 Releases,下载最新版 zip 并解压。

方式 B:克隆仓库

git clone https://github.com/Sutera-Diffusus/dsh-sandbox-tester.git
cd dsh-sandbox-tester

第 2 步:确认 DSH 安装目录

DSH 安装目录通常包含 DeepSeekHarness-Launcher.exenode_modules。可通过启动器配置确认:

Get-Content "D:\Deepseek harness\DeepSeekHarness-Launcher.cfg"

其中 workDir 字段指向安装目录,下文以 <DSH_INSTALL_DIR> 代替(本文示例路径 D:\Deepseek harness 为作者环境,请按实际替换)。脚本会从目标目录的 DeepSeekHarness-Launcher.cfg 自动解析其 DSH_HOME

第 3 步:执行安装脚本

node install.mjs --target "<DSH_INSTALL_DIR>"

幂等四步接线(重复执行安全):

  1. bundle 行合入 profile manifest(dsh-sandbox + file: 依赖);
  2. node_modules junction(profile 链接 + 内置包扁平回退);
  3. apiproxy 设置白名单加 sandbox(先备份 .dsh-sandbox-bak);
  4. 客户端插件挂载校验(/plugins/dsh-sandbox/client.js 可达)。

第 4 步:重启 DSH 并验证

  1. 重启 DSH(服务与页面);
  2. 打开设置页 → 应出现「测试沙盒」区段;
  3. 新建会话,让 Agent 调用 sandbox_list → 9 个工具已注册。

卸载

node install.mjs --target "<DSH_INSTALL_DIR>" --uninstall

使用说明

在会话中使用工具

直接对 Agent 说,例如:

  • 「用测试沙盒验证这个补丁:先 sandbox_create,再 sandbox_inject 打进去,sandbox_run 起来,健康检查过了再 sandbox_merge
  • sandbox_list 看看现在有哪些沙盒,把超龄的清掉」

设置面板

路径:DSH 设置 → 测试沙盒

分组内容
沙盒卡片名称 / 状态(运行中·已停止·已销毁)/ 最近报告(通过·失败 + 摘录)/ 端口 / 年龄 / 启动·停止·健康检查·销毁
新建沙盒名称 + 可选端口 + 完整复制开关
维护48h 超龄标记、一键清理孤儿沙盒、合回门禁摘要

合回门禁

sandbox_merge(name, targets, dryRun=true)
 ├─ ① 目标白名单(11 补丁面 + 显式新增,越界即拒)
 ├─ ② 逐文件 node --check
 ├─ ③ bundle 校验
 ├─ ④ 备份计划 + 回滚清单(不执行)
 └─ ⑤ dryRun=true → 只出报告;dryRun=false 需 DSH_SANDBOX_MERGE_ALLOW=1,失败即回滚

合回成功后自动同步 D:\DeepseekHarness_Backup(DSH 启动守卫 bin-guard 的回滚源)。

数据与隐私

  • 沙盒注册表写入 D:\ai-temp\dsh-sandbox-registry.json,沙盒实体在 D:\DeepseekHarness_Sandboxes\(可在设置中改);
  • 不读取、不上传任何用户凭据或会话数据;
  • 除复制本体程序目录(只读)外,插件不对本体做任何写入;
  • 无遥测、无外部网络请求(一键 QA 仅连本机 127.0.0.1)。

项目结构

dsh-sandbox/
├─ lib/
│  ├─ index.js            # 宿主插件主入口(服务组装 + 9 工具注册 + settings 命名空间)
│  ├─ registry.js         # 沙盒注册表(原子写)与共享常量
│  ├─ ports.js            # 端口池(探测 + 自动分配)
│  ├─ proctree.js         # 进程树管理(3080 保护 + 拉起/停止/存活判定)
│  ├─ tools-lifecycle.js  # list/create/inject/stop/destroy/prune
│  ├─ tools-runhealth.js  # run/health
│  └─ merge-gate.js       # 合回门禁
├─ client/
│  └─ client.js           # 设置页「测试沙盒」区段
├─ test/
│  ├─ smoke.mjs           # 单元冒烟(24 项)
│  ├─ e2e.mjs             # 端到端对抗(创建→启动→杀进程→坏补丁→销毁,13 项)
│  └─ qa-cdp.mjs          # 一键 QA(CDP 9223 真实浏览器,4 项)
├─ skills/dsh-sandbox/    # Agent 技能(SKILL.md)
├─ cordis.patch.yml       # bundle 接入(loader entry: test-sandbox)
├─ install.mjs            # 安装/卸载(幂等)
├─ DESIGN.md              # 设计规格(含评审结论)
├─ FLOW.md                # 工作流程图(Mermaid)
├─ LICENSE / README.md / CHANGELOG.md / SECURITY.md / CONTRIBUTING.md

开发与测试

# 单元冒烟(24 项,不启动任何进程)
node test/smoke.mjs

# 端到端对抗(真实复制 270MB 创建沙盒;需本体 3080 在运行以做无损对照)
node test/e2e.mjs

# 一键 QA(需 headless Edge CDP 9223 + 目标实例)
node test/qa-cdp.mjs <port>

开发建议:在独立 DSH 测试副本上开发验证,避免污染主安装;本仓库开发期间遵循的隔离政策见 CONTRIBUTING。

故障排查

现象处理
副本/本体启动报 duplicate loader entry id: sandbox你的组合里混入了旧版 cordis.patch.yml;确认使用 test-sandbox entry(本仓库已修复)
设置页没有「测试沙盒」区段安装后需重启 DSH;确认 apiproxy 白名单含 sandbox(install.mjs 会打印)
沙盒启动失败看沙盒 stderr;首启需完成引导,QA 脚本已自动处理(预置 workspace)
销毁沙盒报错confirm 必须为 true;运行中的沙盒先 sandbox_stop

License

MIT

Project files and signals

Shown items are public repository signals detected in the directory snapshot.

TestsDetected
Security policyDetected
Contributing guideDetected

Repository information

Language
JavaScript
License
MIT
Latest release
v0.1.0
Last updated
Aug 16, 2026, 5:20 PM

Install deliberately

Review source code, permissions, lifecycle hooks, dependencies and network access. Test untrusted plugins in an isolated environment.