# deepseek-harness-studio

> dsh 浏览器表层组合包：在 dsh-base 之上叠加 Web 宿主与浏览器插件，注册前端 dist、URL 输出、默认浏览器打开与 DSH_WEB_URL 变量。

## Metadata

- Author: [@fufankeji](https://github.com/fufankeji)
- Repo: <https://github.com/fufankeji/deepseek-harness-studio.git>
- GitHub: [fufankeji/deepseek-harness-studio](https://github.com/fufankeji/deepseek-harness-studio)
- Stars: 403
- Language: TypeScript
- License: [MIT](https://spdx.org/licenses/MIT.html)
- Homepage: <https://www.beyondata.com/>
- Topics: `ai-agent`, `deepseek`, `deepseek-harness`, `deepseek-harness-studio`, `desktop-app`, `developer-tools`, `dsh`, `dsh-plugin`, `electron`, `macos`, `plugin-manager`, `windows`
- Forks: 43
- Open Issues: 2
- Last push: 2026-08-20T10:56:44.000Z
- Added: 2026-08-20T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:fufankeji/deepseek-harness-studio/packages/bundle/web-app
```

## Wiki

## 一句话定位
dsh 的浏览器表层组合包。在 dsh-base 之上叠加 Web 宿主与浏览器插件，让 `dsh --profile web` 起一个本地 GUI 服务，并按需用默认浏览器打开。

## 核心能力
- 启动一个本地 Web 服务，自动部署前端 dist 并挂载 `/api` 转发
- 注入浏览器插件名单（主题、布局、会话、附件、命令、插件中心、模型选择等 30+ 客户端插件）
- 在监听端口就绪后打印 `dsh web: http://127.0.0.1:<port>` (`dài 9825`)，并按配置打开默认浏览器
- 在 bash 环境中注册 `DSH_WEB_URL` 运行时变量，每次调用时取当前 URL
- 给模型系统提示词注入 `harness:source` 和 `app:web-surface` 段落，让模型知道它在 GUI 中
- 解析 `--host` / `--port` / `--no-open` / `--trusted-host` 等命令行参数，再以 `webStartup` 服务形式提供给宿主行

## 技术实现
- **语言**: TypeScript (ESM)
- **关键依赖**: `@deepseek-ai/dsh-web-frontend` (前端 dist 入口), `commander` (命令行解析), `open` (跨平台默认浏览器启动), `@deepseek-ai/cordis` & `@deepseek-ai/cordis-plugin-loader` (插件宿主)
- **架构模式**: Cordis function plugin + `cordis.patch.yml` 组合包，通过 `dsh.bundle.patch` manifest 字段叠加在 dsh-base 之上；宿主行注入 `webStartup` 服务，web-runtime 采样 bind 依赖值后释放 `webRuntime` 给客户端信任栅栏
- **入口文件**: `src/index.ts` (web-runtime glue plugin) + `src/startup.ts` (CLI provider) + `cordis.patch.yml` (插件名单)

## 适用场景
给最终使用者安装「浏览器里跑的 dsh」体验：本地装一个仓库后，谁想用 GUI 而不是 CLI/TTY 就可以装这个 bundle；或者开发者需要带 URL 的 dsh 进程来给宿主、Claude Code/Codex 这类工具代理时使用。也适合作为 dsh-frontend 的资源供应商，上游打包/分发平台以此 bundle 为嵌入点。

## 前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH | 0.1.0-rc.8 | 作为 `dsh.bundle.patch` 叠加在 dsh-base 之上，需使用同主版本的 dsh CLI |
| Node | >=22.19.0 | 仓库根 `engines` 声明 `^22.19.0 \|\| >=24.0.0` |
| 平台 | macOS / Linux / Windows | 跨平台；Windows 端 launcher 需等待 PowerShell 退出 |
| 原生模块 | 无 | 不依赖 node-gyp 或 platform-specific binary |

安装前还需要：仓库根先执行 `pnpm run build`，构建 `@deepseek-ai/dsh-web-frontend` 的 dist（bundle 启动时通过 `require.resolve` 校验，未构建会立刻报 usage error）。

## 安装方式
```bash
dsh plugin --profile web add github:fufankeji/deepseek-harness-studio/packages/bundle/web-app
```

## 配置项
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| `openBrowser` | 布尔 | 启动后是否用默认浏览器打开本地 URL（SSH 启动时被强制关闭） | `true` |
| `printUrl` | 布尔 | 是否在启动时输出 `dsh web: http://127.0.0.1:<port>` 行 | `true` |
| `surfaceContext` | 布尔 | 是否注册 `app:web-surface` 提示词段落和 `DSH_WEB_URL` 运行时变量（关闭后模型看不到自己是 GUI 上下文） | `true` |
| `trustedHosts` | 字符串数组 | 浏览器 `/api` 信任栅栏接受的额外 origin（host 或 host:port），通过 `--trusted-host` 重复传入 | `[]` |
| `--host` (CLI) | 字符串 | 监听 host；`0.0.0.0` 被主动拒绝；默认 `127.0.0.1` | `127.0.0.1` |
| `--port` (CLI) | 数字 | 监听端口；传入 `0` 由 OS 分配空闲端口 | `3080` |
| `--no-open` (CLI) | 开关 | 本次调用关闭自动打开浏览器 | — |
| `--trusted-host` (CLI) | 字符串 | 重复传入的额外信任主机 | — |

## 常见问题

**Q: 启动后会自动打开浏览器吗？能不能关掉？**

A: 默认会自动用系统默认浏览器打开本地 URL；通过 `--no-open` 关闭，或将 `web-runtime` 配置里 `openBrowser` 设为 false；通过 SSH 启动时也会自动跳过浏览器交接。

**Q: 为什么 `--host 0.0.0.0` 被拒绝？**

A: bundle 当前有意不支持绑定所有网卡（会在激活前报 usage error 并退出），因为这会把远程代码执行能力暴露到网络。请使用 127.0.0.1 或 LAN 信任主机模式。

**Q: 报「frontend dist not built」该怎么办？**

A: 这表示仓库未构建前端 dist。此 bundle 把 dist 路径当作工作区内部知识，要求在仓库根先执行 `pnpm run build`。

**Q: 提供的 `DSH_WEB_URL` 变量是干什么用的？**

A: bundle 会注册一个 bash 可见的运行时变量 `DSH_WEB_URL`，每次调用时由当前监听的本地 URL 解析，模型与脚本可用它定位当前 GUI。

**Q: Web 和 dsh-base 共享的工具/工具栏为什么有些被禁用了？**

A: Web 把 agent 平面（tool-bash、tool-pwsh、tool-fs、tool-skill、tool-subagent 等）移到会话级别的 agent 预设中，宿主平面只保留 registry 与服务，因此联网后的 agent 由各自 preset 决定如何装配。

**Q: HMR 好像没在工作？**

A: 当前 `hmr` 行在 `cordis.patch.yml` 中被置为禁用，并标注 TODO：等 Web 端重载生命周期测试完成后重新启用。

## 上手难度
入门 — 一个 `dsh plugin add` 加一个 `dsh --profile web` 即可启动；自定义行为只暴露 4 个 config + 4 个 CLI flag，cordis.patch.yml 默认覆盖已够用。

## 已知问题与限制
- 前端 dist 必须先构建；对 dist 的 `require.resolve` 在激活时给出明确报错与构建提示，没有从源码直接服务的回退路径
- `lanAddresses` 是启动期快照：启动后网卡变化不会重新公告；打印的 LAN URL 始终匹配配置的信任栅栏
- 只观测浏览器交接启动：观测在 platform opener 接受 spawn 后结束（Windows 除外，会等待 PowerShell launcher 退出）；浏览器退出后不会上报
- SSH 转发下浏览器 URL 由 SSH 客户端持有：打印的 URL 指向远端 loopback，自动交接被跳过；本地转发地址需在 SSH 客户端或编辑器侧手动打开
- 浏览器命令覆盖只能来自启动环境：`.env` 中的 `BROWSER` 不会生效；只有继承自父进程的环境变量能抵达 opener 路径
- HMR 当前在 Web 端被禁用（`cordis.patch.yml` 中 `hmr` 行为 `disabled: true`，注释 TODO "Re-enable shared HMR for Web after its reload lifecycle is tested"）：客户端插件无刷新热重载需要 `pnpm run dev:web` watcher 重建 bundle

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [deepseek-harness-studio](https://deepseek-plugin.org/plugins/fufankeji/deepseek-harness-studio/packages/bundle/web-app)
Wiki generated by AI (model: `MiniMax-M3`)
