From 9ce782e6bb3c61d5f7e27e09aecb3f303a481962 Mon Sep 17 00:00:00 2001 From: weidu12123 Date: Sat, 17 Oct 2026 18:29:59 +0800 Subject: [PATCH] docs: add the build guide for the GPUI client Pins the order (docs, then dependencies, then one board at a time with the front end rebuilt before moving on), lists every old front-end capability with its GPUI replacement, the dependencies still missing, the assets that must be ported verbatim (OS icons, brand logo), and the four things GPUI cannot reproduce. --- docs/gpui-build.md | 169 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 docs/gpui-build.md diff --git a/docs/gpui-build.md b/docs/gpui-build.md new file mode 100644 index 0000000..c0dd367 --- /dev/null +++ b/docs/gpui-build.md @@ -0,0 +1,169 @@ +# GPUI 客户端制作文档 + +> 2026-10-17 制订。**这是施工顺序的权威**:文档 → 依赖补齐 → 逐板块(先功能、后前端)。 +> 旧前端的视觉与交互以 `docs/ui-spec.md` 与 Playwright 实测真值为准;本文管的是 +> 「旧前端的每个能力,在 GPUI 里用什么来顶」。 + +--- + +## 一、流程(不可越级) + +1. **本文档定稿**——能力清单、依赖清单、板块顺序一次列全,之后按它执行。 +2. **依赖补齐**——一次性把所有"替代旧前端能力"的东西装进来并逐个冒烟验证;缺什么在这里发现,而不是做到一半再发现。 +3. **逐板块施工**:每个板块 = ①功能链路(后端已有则跳过)→ ②前端还原 → ③验收 → ④下一块。**一个板块验收通过才允许碰下一个板块。** + +**每块前端的施工纪律** + +- 动手前:用 Playwright 打开旧前端(守护进程 18800 一直在跑),点开该板块的每个状态,读 computed style(尺寸/间距/字号/颜色/圆角/阴影/行高),并截图存档到 `artifacts/ui-reference/`。 +- 实现时:所有数值来自实测,不来自记忆或目测;旧前端的 SVG 一律原样移植,不用字符或近似图形代替。 +- 完成后:逐元素核对(尺寸、颜色、间距、图标、悬停态),写无头 UI 测试,最后交用户目视。 +- **禁止语**:"差不多""近似""占位"——除第二节 2.4 列明的不可还原项。 + +--- + +## 二、能力与资源清单("依赖" = 旧前端每个能力的 GPUI 对应物) + +### 2.1 视觉资源(必须原样移植,不允许字符近似) + +| 资源 | 旧实现 | GPUI 方案 | 状态 | +|---|---|---|---| +| **OS 图标**(Ubuntu 圆环+三点、Debian 螺旋、Alpine 山、Windows 四格、其余两字母) | `OsBadge.vue` 内联 SVG,品牌色(Ubuntu #e95420 / Debian #e11d48) | 4 个 SVG 原子化到 `gpui-client/assets/icons/os/*.svg`,`svg()` 单色遮罩 + 品牌色;两字母回退保留 | **未做(现在是字符近似,必须替换)** | +| **品牌 Logo**(黑底圆角方块 + 白色双向 L 形滑块 + 中心圆点,三档尺寸 28/36/48) | `BrandLogo.vue` 内联 SVG + shadow + ring | 同源 SVG 到 `assets/logo.svg`,尺寸 sm/md/lg 三档 | **未做(现在是字符近似)** | +| UI 图标(房子/漏斗/刷新/太阳/月亮/齿轮/加号/×/星/置顶箭头/铅笔/拖拽手柄/分屏/文件夹/图表/外链) | 内联 Lucide SVG(stroke 2 / 1.8) | gpui-kit 图标集(Lucide 同源),逐图标核对名称、描边、尺寸 | 已用 Lucide,**待逐图标核对** | +| 字体 | `Inter → PingFang SC → Microsoft YaHei → sans-serif`(本机无 Inter,实测回退浏览器默认 sans) | 主题显式 `Segoe UI`;如仍不像,打包 Inter 字体文件用 `add_fonts` | 已定 Segoe UI(折中,记录差异) | + +### 2.2 UI 能力 → gpui-kit 组件 + +| 旧前端能力 | 旧实现 | GPUI 组件(gpui-kit 0.7.3) | +|---|---|---| +| 输入框 / 搜索框 | `` | `Input` / `InputState`(已用) | +| 下拉选择(跳板机、认证方式) | `` | `Switch` / `Checkbox` | +| 滑块 | 无 | `Slider` | +| 标签页(设置页分类) | 自绘胶囊 | 自绘(已做)或 `Tab` | +| 树(文件浏览器后续可能用) | 自绘 | `Tree` | +| 表格(MCP 调用记录) | `` | `DataTable` | +| 虚拟列表(大目录) | 自绘 | `VirtualList` | +| 图表(探针:圆环/柱状/曲线) | 手写 SVG | `chart` / `plot`;CPU 圆环用 `plot` 或自绘 Element | +| 代码编辑器(CodeMirror 6) | CodeMirror | `Input` 的 editor 模式 + `tree-sitter`(需开 feature + 语言包) | +| 剪贴板复制 | `navigator.clipboard` | gpui `ClipboardItem`(`cx.write_to_clipboard`) | +| 命令面板 / 搜索(Ctrl+K 聚焦搜索) | keydown | gpui `keymap` + `Action`,或手动 `on_key_down` | +| 滚动条 | 自定义 6px 圆角 | gpui-kit `Scrollable` 样式(对齐 6px、圆角、半透明) | +| 日期选择(调用记录筛选) | `input[type=date]` | **组件库无 DatePicker**——用文本框 `YYYY-MM-DD` 输入(记录差异) | + +### 2.3 交互能力 + +| 能力 | 旧前端 | GPUI | 状态 | +|---|---|---|---| +| 单击 / 双击卡片 | `@click` / `@dblclick` | `on_click`(`click_count`) | 已做 | +| 悬停反馈 | CSS `hover:` | `.hover()` | 已做(无过渡,见 2.4) | +| 拖拽排序 | HTML5 drag | `on_drag` / `drag_over` / `on_drop` | 已做 | +| 文件拖放上传(拖进文件面板) | `@drop` | gpui `FileDropEvent`(窗口级) | 未做(板块三) | +| 快捷键 | Esc、Ctrl+K | `on_key_down` / keymap | 未接 | +| 右键菜单(**旧网页版没有**) | — | 卡片可加 `ContextMenuExt` 作为增强;**托盘右键菜单**(旧桌面壳 tray-icon 提供:主机列表、秒开终端、显示主窗口、退出)在 M5 用 `gpui-tray` 重建 | 托盘 M5;卡片右键属增强,待用户确认 | +| 复制(API Key / 路径 / 链接) | `navigator.clipboard` | gpui 剪贴板 | 未接 | +| 打开外部链接(GitHub release) | `` | `open` crate(系统浏览器) | **依赖未补** | +| 文件保存 / 选择对话框(下载、上传本机路径) | 浏览器下载 | `rfd` 原生对话框 | **依赖未补** | +| SSE 事件流(`/api/events`,agent 唤起终端) | `EventSource` | `reqwest` stream 特性手写 | **依赖未补** | +| 系统通知(提醒) | 无 | `notify-rust` | M5 | +| 独立终端窗口(旧版由 tao 桌面壳打开) | `POST /api/window/open-terminal` | GPUI `open_window` 自建(M6 替代旧壳时) | M5/M6 | +| 主题偏好持久化 | `localStorage` | 后端设置 API(`/api/settings`) | 待接 | + +### 2.4 明确不可还原(不追求,只做记录) + +| 项 | 原因 | 替代 | +|---|---|---| +| 背景模糊 `backdrop-blur` | GPUI 无背景模糊能力 | 半透明白 + 边框 + 阴影 | +| 径向渐变页面底 | GPUI 只有线性渐变 | 中间色近似;或自绘背景 Element(后续) | +| CSS 过渡动画 | 需逐个用 `with_animation` 手写 | 逐块补 hover 过渡 | +| 浏览器字体回退栈 | GPUI 按名取系统字体 | 主题定 `Segoe UI`;必要时打包 Inter | +| 浏览器窗口形态 | 旧版在浏览器里运行 | GPUI 原生窗口(产品形态变化,不是还原目标) | + +--- + +## 三、依赖补齐(一次性,做完验收才进板块) + +### 3.1 Cargo 依赖 + +| 依赖 | 用途 | 操作 | +|---|---|---| +| `gpui-kit` features:`tree-sitter` + `tree-sitter-bash/json/yaml/toml/python/javascript/css/html/markdown` | 代码编辑器高亮(板块三) | 加到 `gpui-client/Cargo.toml` | +| `rfd` | 原生文件选择/保存对话框(板块三/四:上传、下载) | 新增 | +| `open` | 系统浏览器打开链接(关于页) | 新增 | +| `reqwest` 增 `stream` 特性 | SSE `/api/events` | 改已有 | +| `gpui-tray`(M5) | 托盘图标与右键菜单 | 板块六前加 | +| `notify-rust`(M5) | 系统通知 | 板块六前加 | + +### 3.2 资源文件 + +- `gpui-client/assets/icons/os/ubuntu.svg`、`debian.svg`、`alpine.svg`、`windows.svg`——从 `OsBadge.vue` 原样复制 path。 +- `gpui-client/assets/logo.svg`——从 `BrandLogo.vue` 原样复制。 +- 资源加载:gpui 的 `AssetSource`(gpui-kit `application().with_assets`),自定义图标用 `Icon::default().path(...)`(与 shell-rs 的 `OS_ICONS` 同法)。 + +### 3.3 依赖验收(逐个冒烟) + +每项依赖补齐后写一个最小验证(编译通过 + 实际跑一次):SVG 能渲染且颜色正确、Dialog 能弹出与关闭、ContextMenu 能右键弹出、Clipboard 能写入、rfd 能打开对话框、open 能拉起浏览器、SSE 能收到事件。 + +--- + +## 四、逐板块施工(先功能,后前端) + +> 后端五大板块与 MCP 都已存在(v0.1.0 已发布),所以"功能"阶段主要是确认 API 契约;前端阶段按板块做透。 + +### 板块一:VPS 仓库(当前) + +功能:`/api/hosts` CRUD、check / check-all、inspect、meta(收藏/置顶/标签/角色)、reorder、prewarm —— 全部已有。 +前端块与顺序: +1. 卡片列表(含拖拽排序、状态四态)——**已做,待最终核对(含 OS 真图标替换)** +2. 顶栏首页部分(品牌、仓库按钮、搜索、筛选下拉、检测在线)——**已做,待核对** +3. 新建/编辑主机弹窗(表单:名称/地址/端口/用户名/认证方式/密码/私钥/口令/跳板/角色/标签/置顶/归档/快捷链接)——**未做** +4. 删除确认弹窗——**未做** +5. Toast——**已有简版,待按真值细化** +6. 详情抽屉的仓库部分(铭牌、角色、标签、快捷链接、底部操作栏)——**已有骨架,待核对与补快捷链接** +7. 快捷键(Ctrl+K 聚焦搜索、Esc 关闭浮层/弹窗)——**未做** + +### 板块二:终端 + +功能:`/api/terminals`、WS 终端(0x00/0x01/0x02)、resize、paste —— 已有;终端渲染已建。 +前端块: +1. 终端舞台顶栏(cwd 胶囊、运行中/退出码徽章、分屏、白黑底、文件/详情、独立窗口、收起) +2. 分屏画布与焦点环、多 pane 关闭按钮 hover 显隐 +3. 断线/退出/加载/失败四条状态条与重连 +4. 中文 IME 输入(InputHandler 完整实现) +5. Ctrl+C/Ctrl+V 语义(有选区复制、bracketed paste) +6. 独立窗口模式(standalone) + +### 板块三:文件浏览器 + +功能:`/api/files/*`、/api/transfers —— 已有。 +前端块:面包屑、文件列表(DataTable/VirtualList)、上传/下载(rfd + 原生对话框 + FileDropEvent)、压缩/解压/重命名/删除、在线编辑器(CodeMirror → Input editor + tree-sitter)、与终端 cwd 联动。 + +### 板块四:文件上传下载 + +前端块:传输队列面板(速率、进度、剩余时间、暂停/继续/取消)、拖拽上传、跨 VPS 直传入口。 + +### 板块五:探针 + +前端块:CPU 圆环(plot/自绘)、内存双色条、磁盘多分区、网络吞吐柱状谱与历史、实时刷新节流(2.8s 已接)。 + +### 板块六:MCP 与设置 + +前端块:设置页五分类(常规与自启 / 访问安全 / MCP Server / 调用记录 / 关于与更新)、命令黑名单编辑器、调用记录表格(DataTable + 日期筛选)、关于与更新(检查更新、外链 open)、托盘与自启(M5)。 + +--- + +## 五、每块施工清单 + +**开始前**:旧版该块截图存档 → Playwright 读真值 → 对照本文第二节确认用到的能力已补齐。 +**实现中**:数值来自真值;SVG 原样移植;不做近似。 +**完成后**:逐元素核对表(尺寸/颜色/间距/图标/hover/选中态)→ 无头 UI 测试 → 用户目视验收 → 通过才标 ✅。 + +## 六、当前进度 + +- ✅ 方案与规格:`docs/gpui-client.md`、`docs/ui-spec.md` +- ✅ 依赖补齐之外的基础设施:workspace 拆分(api/theme/util/top_bar/host_card/terminal_stage/detail_drawer/settings_page) +- ⬜ 本文档的第三节(依赖补齐)**尚未执行**——下一步就是它 +- 板块一:卡片列表与顶栏已有实现,OS 图标/品牌 Logo 仍是字符近似,待替换为原样 SVG;弹窗、删除确认、快捷键未做