# pilot-harness

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

## Metadata

- Author: [@op7418](https://github.com/op7418)
- Repo: <https://github.com/op7418/pilot-harness.git>
- GitHub: [op7418/pilot-harness](https://github.com/op7418/pilot-harness)
- Stars: 240
- Language: TypeScript
- License: [MIT](https://spdx.org/licenses/MIT.html)
- Topics: `ai-agent`, `codepilot`, `deepseek`, `deepseek-harness`, `desktop-app`, `dsh`, `dsh-plugin`, `electron`, `linux`, `macos`, `typescript`, `windows`
- Forks: 13
- Open Issues: 16
- Last push: 2026-08-20T12:42:53.000Z
- Added: 2026-08-20T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:op7418/pilot-harness/packages/bundle/web-app
```

## Wiki

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

## 核心能力
- 在 dsh-base 之上叠加 Web 宿主行（webserver、API 网关、workspace、投影缓存、存储）与浏览器插件组合（主题、布局、会话、命令、插件中心、模型选择等）
- 解析 `--host` / `--port` / `--trusted-host` / `--help` 等命令行参数，并以 `webStartup` 服务提供给宿主行
- 在端口就绪、Loader 配置树结算后打印 `dsh web: http://127.0.0.1:<port>`，避免兄弟行失败时公告一个已失效的应用
- 在 bash 环境中注册 `DSH_WEB_URL` 运行时变量，每次调用时由当前监听 URL 解析
- 给模型系统提示词注入 `harness:source` 和 `app:web-surface` 段落，让模型知道它在 GUI 中以及不接受浏览器替代品
- 监听阶段从当前网卡采样 IPv4 地址，作为 LAN 信任栅栏的来源

## 技术实现
- **语言**: TypeScript (ESM)
- **关键依赖**: `@deepseek-ai/dsh-web-frontend` (前端 dist 入口)、`commander` (命令行解析)、`@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.7+ | 与 monorepo 同版本，本 bundle 与 dsh-base / dsh-headless 同级 |
| Node | ^22.19.0 \|\| >=24.0.0 | 来自 monorepo 根 `package.json` 的 `engines.node` 字段 |
| 平台 | 跨平台 | 未声明 `os`/`cpu` 限制；启动行为不依赖特定 OS |
| 原生模块 | 无 | 仅使用 Node 内置 `node:os` / `node:module` / `node:url`，未引入 `node-gyp` 依赖 |

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

## 配置项

**bundle 自身配置（写在 cordis.patch.yml 的 web-runtime 行）**

| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| `printUrl` | boolean | 是否在端口就绪后向终端打印 `dsh web: http://127.0.0.1:<port>` 一行 | `true` |
| `surfaceContext` | boolean | 是否给模型注入「Web 表层」提示词段落和 bash 变量 `DSH_WEB_URL` | `true` |
| `trustedHosts` | string[] | `--trusted-host` 命令行参数传入的额外权威主机，会拼入浏览器信任栅栏 | `[]` |

**命令行参数（通过 `dsh --profile web` 传入）**

| 参数 | 用途 |
|---|---|
| `--host <host>` | 监听 host；绑定 `0.0.0.0` 会被拒绝并报 usage error |
| `--port <port>` | 监听端口；传 `0` 表示由 OS 选一个空闲端口 |
| `--trusted-host <authority...>` | 浏览器信任栅栏额外允许的权威主机，可重复 |
| `-h, --help` | 打印本应用帮助文本；打印过程中不启动服务 |

## 常见问题

**Q: 这个 bundle 是什么，有什么用？**

A: 它是 dsh 的「Web 表层」组合包，在 dsh-base 之上叠加一层浏览器界面所需的全部宿主与浏览器插件，安装后通过 `dsh --profile web` 启动一个本地 GUI 服务。

**Q: 和 dsh-headless、dsh-desktop 是什么关系？**

A: 这三个是 dsh-base 上的同级表层组合包。web-app 是浏览器表层，headless 是无界面表层，desktop 是桌面应用；它们互不嵌套，按 `--profile` 选其一加载。

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

A: 这个 bundle 本身不负责拉起系统浏览器，只在端口就绪后打印一行 `dsh web: http://127.0.0.1:<port>`。是否由其它层（如 desktop 或外部 supervisor）打开浏览器不在此 bundle 范围内。

**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`，然后再启动 `dsh --profile web`。

**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 端重载生命周期测试完成后重新启用；客户端插件热重载需配合 `pnpm run dev:web` watcher 才会触发。

## 上手难度
入门 — 安装一次、跑一行 `pnpm run build` 与 `dsh --profile web` 即可在浏览器看到界面；除 `--host` / `--port` / `--trusted-host` 外没有必填配置。

## 已知问题与限制
- **前端 dist 必须已构建**：对 dist 的 `require.resolve` 在激活时报错并给出构建提示，没有从源码直接服务的回退路径（README.md:25）
- **`lanAddresses` 是启动期快照**：启动后网卡变化不会重新公告；打印的 LAN URL 始终与配置的信任栅栏一致（README.md:26）
- **`--host 0.0.0.0` 被有意拒绝**：CLI 把「绑定所有网卡」视为安全风险，会在解析阶段退出而不发布 `webStartup` 服务（src/startup.ts:69-71）
- **`hmr` 行被禁用**：cordis.patch.yml 中以 TODO 标注，等 Web 端重载生命周期测试完成后再启用（cordis.patch.yml:21-23）
- **`DSH_TOOLS_MODE` 是临时绕过**：整个 dsh 进程的 tools 模式（native|code|both）通过环境变量切换，等 Web UI 能按 session 选择后移除（cordis.patch.yml:36-41）

---

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