# DSH Box [English](README.md) · **简体中文** **DeepSeek Harness 桌面运行时管理器** —— 在本机运行、隔离、扩展多个 DeepSeek Harness 环境,不需要开浏览器标签页。 DSH Box 是一个用 [Tauri 2](https://tauri.app) 写的轻量桌面外壳,负责安装、启动和管理相互独立的 DSH **容器**(Container)——每个容器有自己的 DSH 版本、profile、插件、技能、工作区和日志——并把它们渲染在内嵌的 WebView 里。 ![容器列表:每个容器有自己的 DSH 版本、profile 和宿主进程,带启动、打开、重建等操作](docs/images/containers.png) --- ## 功能亮点 - **容器相互隔离** —— 每个容器自己的 DSH 版本、profile、工作区和宿主进程。 - **内嵌 WebView** —— DSH 界面在原生窗口里打开,不用端口转发、不用复制 URL。 - **几秒就绪** —— 拉取的 Harness 版本自带已构建的客户端产物,`dshbox run` 只是复制加 store 链接(~10 秒)。 - **插件依赖图** —— 加载了什么、按什么顺序、为什么:深度分层、宿主与浏览器半身分开绘制、可以把某一层折叠掉。 - **资源:提取、注入、编辑** —— 会话、provider 密钥、插件状态,都是具名副本;一个 kind 可以跨文件,任意 YAML 片段按 key 路径编辑。 - **面向 agent** —— `dshbox apply -f` 用一份文档配置资源,所有动词支持 `--json`,容器文件可按 key 路径树读取。 - **零依赖安装** —— 自带 Node、npm、pnpm 与 Git(Windows),运行在干净环境里。 - **内置版本管理** —— 安装任意 Harness tag,按容器固定版本。 - **boxfile** —— `FROM` + `ADD` 描述一个模板;构建一次,多次运行。 - **可移植模板** —— 所有负载都物化进模板,容器不依赖任何可变的东西。 - **整合包** —— 把插件和技能编成包,快速导出(保留 URL)或完整导出(单一归档)。 - **看得见的任务** —— 排队、带耗时的日志、可取消、有历史。 - **daemon 慢也不冻窗口** —— 命令不在主线程执行,每个 RPC 都有超时。 - **RPC + 事件流** —— 一个 `POST /rpc` 加一条 SSE 流,界面、CLI 和 agent 共用。 - **对网络友好** —— GitHub 镜像、npm 仓库镜像、自动代理探测。 - **托盘与后台服务** —— 窗口关掉 `dshboxd` 仍继续工作。 - **轻量** —— Tauri,不是 Electron。 - **双语界面** —— English 与简体中文。 ![插件列表:每个已安装插件一行,带类型、存储方式、缓存状态、自动收录标记,以及它来自哪些模板和容器](docs/images/resources-plugins.png) --- ## 安装 从本仓库的 **Releases** 页面下载对应平台的安装包: | 平台 | 产物 | 说明 | |---|---|---| | Windows (x64) | `dshbox__x64_.msi` | 含捆绑运行时与 sidecar 的 MSI | | Linux (x64) | `dshbox--amd64.deb` | Debian/Ubuntu 包 | | macOS (arm64) | `dshbox--arm64.dmg` | Apple Silicon | > 最新版本见 [Releases 页面](https://github.com/Nexus-Aethra/DSHBox/releases),产物命名遵循 `--`。每个 tag 都会由 [release workflow](.github/workflows/release.yml) 构建三个平台。 Windows 上没有运行时前置要求——捆绑的 Node/npm/pnpm/Git 就在安装包里。Linux 需要系统 Git(`apt install git` 或发行版等价命令),其配置按运行时目录隔离,因此 DSH Box 的构建不会读宿主 `~/.gitconfig`。 --- ## 快速开始 1. **启动 DSH Box**,按提示选一个可写的*运行时目录*(所有 DSH 数据都在这里)。 2. 打开 **资源** → **Harness**,安装你需要的 DSH tag。 3. 打开 **资源** → **模板**,拉取官方 DSH 模板,或用 boxfile 构建一个可复用模板。 4. 打开 **DSH 容器** → 从该模板创建容器(填名字与 profile)。 5. 按 **启动**,DSH Box 会启动这份准备好的拷贝,并在内嵌 WebView 里打开 DSH 界面。创建容器只是复制 + 链接 store;客户端产物在拉取 Harness 版本时就已经构建好了。 6. 用 **资源** 导入插件/技能、组装整合包,或写 boxfile 得到可复用的插件模板。 ### 托盘 关闭窗口时应用会最小化到系统托盘。用托盘菜单可以打开窗口,或启动/停止/重启 `dshboxd` 后台服务。 --- ## 架构 DSH Box 拆成 Tauri **桌面外壳**、一个不依赖框架的 Rust workspace、一个后台 **daemon**(`dshboxd`)和一个小型 React 前端。这样拆是为了让所有业务逻辑(插件获取、容器生命周期、模板解析、后台任务)脱离 UI 就能测试,也让 CLI 或外部 agent 能驱动和界面完全相同的流程。 ![DSH Box 架构:React 界面经 IPC 与 Tauri 外壳通信,外壳与 CLI 都通过 loopback RPC 驱动 dshboxd,daemon 用捆绑运行时为每个容器监管一个 DSH 宿主](docs/images/architecture.svg) ### 分层组件 | 层 | 内容 | 为什么这样分 | |---|---|---| | 前端(React 18 + Vite,`src/`) | 页面、组件、`useTaskQueue`/`useContainers`/`useResources`/`useSettings` 等 hook。**没有业务逻辑**——页面只发 RPC 并对 daemon 的 SSE 事件做出反应。 | 让 Box 界面保持轻薄,并让任何客户端(界面/CLI/agent)共用同一条代码路径。 | | 桌面外壳(Tauri 2,`src-tauri/src/`) | 浏览器窗口、托盘、Tauri IPC 适配层。通过 loopback HTTP 与 daemon 通信。所有实际工作都交给 `dshboxd`。 | 状态变更只有一个源头,界面与 CLI 不会各自漂移。 | | Daemon(`src-tauri/crates/dshboxd`) | 常驻后台服务。拥有任务队列、文档存储、模板索引、容器注册表和 SSE 事件总线。单一 HTTP 入口(`POST /rpc`)加 `GET /events?token=…`。 | 安装、重建、卸载等后台工作不会随窗口关闭而中断。 | | Crate workspace(`src-tauri/crates/`) | 不依赖框架的 Rust crate:`box-foundation`、`box-runtime`、`box-scheduler`、`box-state`、`box-toolchains`、`box-dsh-versions`、`box-containers`、`box-extensions`、`box-image`、`box-template-core`、`box-data-scheduler`、`box-logger`、`box-dsh-context`、`box-server-core`、`box-api`、`box-client`。 | 纯函数 + 单元测试;只有顶层 `dshbox` 与 `dshboxd` 链接 Tauri/HTTP。 | 依赖方向是单向的:`foundation / runtime / scheduler / state` → 功能 crate → Tauri/桌面适配层。功能 crate 不依赖 Tauri,也不依赖彼此的易变状态。 ### Daemon —— 双模 RPC + SSE 事件流 界面 / CLI 的每个动作都落到 `POST /rpc`,JSON 体为 `{"method": "...", "params": {...}, "token": "..."}`。daemon 的 dispatch 表决定每个 handler 是**同步**返回 JSON(列模板、读设置……)还是**异步**排入 worker(安装、构建、启动容器、重建、卸载……)。异步 handler 立即返回 `TaskRecord`;客户端订阅 `GET /events?token=…` 收 `task_stage` / `task_log` / `task_finished` / `resource_added|updated|removed` 事件。daemon 对每个请求单独开一个线程,因此一个长任务不会挡住存活探测。 这意味着同一套 HTTP 面服务所有消费者——桌面应用的 Tauri IPC、CLI(`dshbox rpc …`)、以及用 `curl -d '…' http://127.0.0.1:/rpc` 的外部 agent。没有「客户端兜底」也没有本地状态分叉:daemon 的资源表和任务队列是唯一的事实来源。 任务日志是界面观察长任务的唯一窗口:daemon 写它,桌面把日志行流进面板,用户要等几分钟的步骤会说明它在做什么、花了多久。 ![任务面板:一次容器启动展开日志,每步一行并带耗时](docs/images/tasks.png) ### boxfile 与模板构建流水线 **boxfile**(`.dsh`)是描述你想实例化的容器的声明式脚本。`dshbox build` 把它解析成 **封存模板(sealed template)**:不含 `node_modules` 的 Harness 源码实体,加上 profile、本地插件产物、技能、以及 `ADD` 指令所需的数据。`dshbox run