# dsh-web-ui

> Adds desktop one-click launch icons for dsh Web GUI across Windows/macOS/Linux, and a floating shutdown button in the top-right corner. Both features are integrated into the settings panel and system prompts.

## Metadata

- Author: [@zhu1090093659](https://github.com/zhu1090093659)
- Repo: <https://github.com/zhu1090093659/dsh-web-ui.git>
- GitHub: [zhu1090093659/dsh-web-ui](https://github.com/zhu1090093659/dsh-web-ui)
- Stars: 5,126
- Language: TypeScript
- License: [Apache-2.0](https://spdx.org/licenses/Apache-2.0.html)
- Homepage: <https://gallery.dsh-market.com>
- Topics: `deepseek-harness`, `dsh`, `dsh-plugin`, `web-ui`
- Forks: 311
- Open Issues: 49
- Last push: 2026-08-20T14:37:38.000Z
- Added: 2026-08-20T00:00:00.000Z

## Install

```bash
dsh plugin --profile web add github:zhu1090093659/dsh-web-ui/packages/dsh-desktop-launcher
```

## Wiki

## 一句话定位
为 dsh Web GUI 增加桌面一键启动图标和右上角浮动关机按钮：图标双击自动启动 dsh web 并打开浏览器，浮动按钮则在确认后让 dsh web 进程优雅退出；两者都通过设置面板的「Web UI 插件」卡片独立控制。

## 核心能力
- 在桌面创建一键启动图标：Windows 下生成 `.lnk` 快捷方式，macOS 下生成 `.command` 文件，Linux 下生成 `.desktop` 文件；启动脚本统一写到 `~/.dsh/desktop-launcher/`
- 双击图标自动启动 dsh web：先探测 GUI 端口（默认 `http://127.0.0.1:3080`），已在响应就直接打开浏览器；否则后台启动 dsh web（Windows 隐藏窗口），最多轮询 30 秒等就绪，再打开浏览器
- Windows 启动器显示鲸鱼图标（白底）与深色风格的「启动中」小窗，实时报告进度；找不到 `dsh` 命令或超时则红字提示，不会静默失败
- 浮动关机按钮：固定在浏览器右下角，独立于侧边栏布局，点击默认先弹确认框；确认后调用 `/api/dsh-desktop-launcher/shutdown` 让 dsh web 进程优雅退出
- 在「设置 → 插件配置 → Web UI 插件」卡片内提供 `enabled / announceToAgent / dshCommand / url / profile / iconPath / confirmShutdown` 七个字段，且会向 Agent 系统提示词宣告本插件能力

## 技术实现
- **语言**: TypeScript（host 半区 `src/index.ts` + `src/routes.ts` + `src/shutdown-routes.ts`）+ TypeScript + React 18 + CSS Modules（browser 半区 `src/client/`）
- **关键依赖**: `schemastery` ^3.18.0（配置 schema 校验）、`react` ^18.2.0 / `react-dom` ^18.2.0（peer 依赖由宿主注入）、`@deepseek-ai/cordis` ^4.0.1（host 半区插件编排）、`@deepseek-ai/dsh-host-webserver` ^0.1.0-rc.8（注册 loopback 路由）、`@deepseek-ai/dsh-client-*` ^0.1.0-rc.8（client-runtime / client-connection / client-ui-conversation / client-ui-settings / client-ui-sidebar 等浏览器半区依赖）
- **架构模式**: 双半区 cordis bundle。`src/index.ts` 是 host 半区（注册 `/api/dsh-desktop-launcher/create` 与 `/api/dsh-desktop-launcher/shutdown` 两个 loopback 路由 + systemPrompt 章节宣告），`src/client/index.ts` 是 browser 半区（注册 `desktop-launcher` 词条到 `web-ui.plugin.item` 槽 + 右下角浮动按钮挂载 + locale 注册）。bundle 声明在 `packages/dsh-desktop-launcher/cordis.patch.yml:11-13`（插入 id `desktop-launcher`），浏览器端通过 `dsh.client.inject` 注入 5 个官方 `@deepseek-ai/dsh-client-*` 模块 + `platform: web`
- **入口文件**: `packages/dsh-desktop-launcher/src/index.ts`（host apply）、`packages/dsh-desktop-launcher/src/client/index.ts`（browser apply）

## 适用场景
- 频繁重启 dsh web 的开发者：当前每次都要先开「隐藏控制台」再切换浏览器，希望在桌面、任务栏或 Dock 上点一下就到位，省去手动开进程 + 切浏览器。
- 想用与 DSH 风格一致的「鲸鱼图标」启动入口替代浏览器收藏夹，或者 macOS Dock / Windows 任务栏里塞一个图标，每次启动体验都比浏览器标签更顺。
- 不想让团队成员每次都梳理「先启动 dsh web、再打开 127.0.0.1:3080」的临时同事：在他们机器上装好插件并点一次「创建桌面图标」即可，无需口述步骤。

## 前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| Node.js | `^22.19.0` 或 `>=24.0.0` | package.json `engines.node` |
| DSH 宿主 | `0.1.0-rc.8+` 推荐 | package.json 未在 `dsh.engines` 声明；devDependencies 统一锁到 `@deepseek-ai/dsh-* ^0.1.0-rc.8` |
| 平台 | Windows / macOS / Linux | 三端均支持；不支持这三者以外的平台（`toLauncherPlatform` 直接抛 `unsupported platform`） |
| 原生模块 | 无 | 运行时只依赖 Node 内置 `fs` / `child_process` / `http` 与 React；不引入 native 绑定 |
| React | `^18.2.0` | peerDependency，由宿主运行时注入 |
| dsh 命令 | 需在 PATH 或绝对路径 | 启动器检测不到 `dshCommand` 时弹提示而非失败（`probeDsh`） |
| 桌面目录 | 存在（Windows 自动识别 OneDrive 重定向） | 重定向到 OneDrive 之外的桌面需手动放置图标 |

## 安装方式
```bash
dsh plugin --profile web add github:zhu1090093659/dsh-web-ui/packages/dsh-desktop-launcher
```

## 配置项
设置卡片提供 7 个字段（保存即写入 host 端 schema 校验，`profile` / `iconPath` 留空表示「不传该参数」）：

| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| enabled | 开关 | 插件总开关；关闭后不注册 create / shutdown 路由、不挂浮动按钮，桌面图标不会被自动清理 | true |
| announceToAgent | 开关 | 是否在系统提示词中向 Agent 宣告本插件（关闭后 Agent 看不到"桌面图标"与"开关机"能力） | true |
| dshCommand | 字符串 | 启动 dsh 的命令，双击图标时需在 PATH（不在 PATH 时填绝对路径） | `dsh` |
| url | 字符串 | 启动器等待就绪并最终打开的 GUI 地址 | `http://127.0.0.1:3080` |
| profile | 字符串 | 传给 `dsh web --profile <profile>` 的 profile 名；留空不传该参数 | "" |
| iconPath | 字符串 | 桌面图标文件 `.ico` / `.png` 路径；留空使用内置的鲸鱼图标 | "" |
| confirmShutdown | 开关 | 浮动关机按钮是否弹确认框；关闭后点按钮直接请求宿主退出 | true |

修改 `dshCommand` / `url` / `profile` / `iconPath` 后必须重跑「创建桌面图标」按钮，启动脚本才会用新值重新生成。

## 常见问题

**Q: 装好之后桌面上没有图标怎么办？**

A: 插件不会自动创建图标。打开「设置 → 插件配置 → Web UI 插件」里的 dsh-desktop-launcher 卡片，点「创建桌面图标」按钮，host 才会把启动脚本写到 `~/.dsh/desktop-launcher/`、把图标放到桌面。安装只是把能力挂到 dsh 上，桌面图标需要手动点一次生成。流程见 `packages/dsh-desktop-launcher/README.zh.md:11-12`。

**Q: 双击图标启动后多久才算"完成"？**

A: 启动器先探测 GUI 端口（默认 `http://127.0.0.1:3080`），已经在响应就直接打开浏览器；否则后台启动 dsh web（Windows 隐藏进程窗口），最多轮询 30 秒等就绪，再打开浏览器。30 秒是写死的固定值，初次启动特别慢可能超时（启动器会弹提示）。逻辑在 `packages/dsh-desktop-launcher/src/core/launcher.ts:23-27`、`packages/dsh-desktop-launcher/README.zh.md:13-15`。

**Q: 浮动开关按钮按下后会发生什么？**

A: 按钮点击后默认先弹确认框（可由 `confirmShutdown` 设置关闭），确认后浏览器 POST 到 `/api/dsh-desktop-launcher/shutdown`，host 先回 200 响应、约 80ms 后再调用 `ctx.appExit`（缺失时回退 `process.exit(0)`）让 dsh web 进程优雅退出。响应在前、退栈在后，浏览器能拿到确认回执。实现见 `packages/dsh-desktop-launcher/src/shutdown-routes.ts:14`（`EXIT_DELAY_MS=80`）、`packages/dsh-desktop-launcher/src/index.ts:98-105`。

**Q: 局域网里别人能调到这两个接口吗？**

A: 不能。`create` 和 `shutdown` 两个路由都走 loopback 围栏：socket 必须命中 IPv4 127/8 / `::1` / IPv4-mapped `::ffff:127/8`，并校验同源 Host 头与 `sec-fetch-site` / `Origin`，非本机请求直接 403。围栏在 `packages/dsh-desktop-launcher/src/shutdown-routes.ts:11-16`、`packages/dsh-desktop-launcher/src/routes.ts:202-204`。

**Q: 我把 dsh 装到了非 PATH 路径，怎么启动？**

A: 在设置卡片里把 `dshCommand` 改成绝对路径（例如 `/usr/local/bin/dsh` 或 `C:\Users\you\scoop\apps\dsh\current\dsh.exe`），再点「创建桌面图标」重新生成启动脚本。launcher 不会自动改图标目标，修改 `dshCommand` / `url` / `profile` 后必须重新创建才能生效。说明在 `packages/dsh-desktop-launcher/README.zh.md:16-17`、`packages/dsh-desktop-launcher/src/core/launcher.ts:35-47`。

**Q: Linux 桌面图标显示但点了不启动怎么办？**

A: GNOME 拒绝未标记为 trusted 的 `.desktop` 文件。插件会尝试用 `gio` 把 `metadata::trusted` 标成 true；没有 `gio` 的桌面环境图标仍会出现，但需要手动"允许启动"一次。逻辑与限制在 `packages/dsh-desktop-launcher/src/routes.ts:183-188`、`packages/dsh-desktop-launcher/README.zh.md:57-58`。

**Q: 浮动按钮关掉能省点资源吗？关闭后还能用桌面图标吗？**

A: 关闭 `enabled` 总开关会让浮动按钮消失、`create` / `shutdown` 路由不再注册，但已经生成在桌面上的图标与 `~/.dsh/desktop-launcher/` 下的脚本不会被删除，依然可以双击。开关在 `packages/dsh-desktop-launcher/src/index.ts:124-148`。

**Q: 关机按钮会丢失当前会话吗？**

A: 会。关机走 `ctx.appExit` 终止 dsh web 进程，未保存的会话、正在跑的 Agent 任务、以及 Web 终端里的 SSH 会一并中断。这与官方 DSH 退出语义一致，不是独立 bug。提示词在 `packages/dsh-desktop-launcher/src/index.ts:81`。

## 上手难度
入门 — 一行命令安装、重启 `dsh web`、点一次「创建桌面图标」即可生效；浮动按钮开箱即用。但若 `dsh` 不在 PATH 或使用了非主流桌面环境，需要理解 `dshCommand` / `gio` 手动放行的处理。

## 已知问题与限制
- 启动器假设双击时 `dsh` 在 PATH 中；非 PATH 安装需把 `dshCommand` 设为绝对路径（`packages/dsh-desktop-launcher/README.zh.md:62-63`）
- 30 秒就绪轮询是固定值；首次启动特别慢可能超时（启动器会弹提示；不是设置项）（`packages/dsh-desktop-launcher/README.zh.md:64-65`）
- 创建图标需要桌面目录存在；Windows 自动识别 OneDrive 重定向桌面，其它重定向可能需要手动放置图标（`packages/dsh-desktop-launcher/src/routes.ts:108-115`、`packages/dsh-desktop-launcher/README.zh.md:66`）
- Linux 下尽力用 `gio` 把 `.desktop` 标记为 trusted；没有 `gio` 的桌面环境图标仍会出现，但可能需要手动「允许启动」（`packages/dsh-desktop-launcher/src/routes.ts:183-188`、`packages/dsh-desktop-launcher/README.zh.md:57-58`）
- 关机响应延迟 80ms 是写死的 `EXIT_DELAY_MS`（`packages/dsh-desktop-launcher/src/shutdown-routes.ts:14`），不能通过设置调整
- 关闭 `enabled` 不会再清理已创建的桌面图标与 `~/.dsh/desktop-launcher/` 脚本（`packages/dsh-desktop-launcher/src/index.ts:124-148`）
- 修改 `dshCommand` / `url` / `profile` / `iconPath` 后必须重跑「创建桌面图标」按钮，已存在的桌面图标不会自动重新生成（`packages/dsh-desktop-launcher/README.zh.md:16-17`）
- 仅支持 `win32` / `darwin` / `linux` 三个平台；`process.platform` 返回其它值时 `toLauncherPlatform` 直接抛 `unsupported platform`（`packages/dsh-desktop-launcher/src/routes.ts:99-102`）
- 关机按钮不可见于 DSH 进程外的标签页——按钮通过浮动挂载注入到当前 Web GUI；隐身窗口（无 Web 渲染）时无意义

---

This document is auto-generated by [deepseek-plugin.org](https://deepseek-plugin.org). HTML page: [dsh-web-ui](https://deepseek-plugin.org/plugins/zhu1090093659/dsh-web-ui/packages/dsh-desktop-launcher)
Wiki generated by AI (model: `MiniMax-M3`)
