Files

183 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Nebula UI 终局路线图
定案时间:2026-08-13。本文件是唯一的长期计划权威;阶段推进、闸门结果、
裁定变更都回写到这里。
## 当前迁移快照(2026-08-14)
当前 **完整迁移加权完成度约 65%**。这个数字按可验收能力计分,不按代码行数;
其中供应商设置、共享命令面板、文件树抽屉和窗口视效仍位于未提交工作区,不能
等同于已进入可发布基线。默认 UI 切换前的发布准备度低于功能完成度。
| 能力面 | 权重 | 已得 | 当前边界 |
|---|---:|---:|---|
| 架构与产品接入 | 15 | 15 | GPUI 已迁入 `nebula_app`,`nebula --gpui` 可独立运行 |
| 终端核心与会话 | 25 | 21 | ConPTY、网格、输入/选择/鼠标、IME 代码路径、多 tab 与 AI 会话已接入;分屏和最终人工验收未闭环 |
| 工作区与产品表面 | 20 | 12 | 侧栏、tab 拖拽、命令面板、文件树、设置 tab、标题栏/视效已有实现;分屏、SSH HOSTS、Git 抽屉与部分命令动作未接入 |
| 设置与业务工作流 | 20 | 11 | 纯键值设置和 Provider 编辑器已有实现;SSH、备份、按键编辑器、字体选择器仍缺 |
| 三闸门与默认切换 | 15 | 6 | G1/G3 有首轮结果;产品形态复测、G2 用户验收、默认入口切换均未完成 |
| 稳定期与收尾 | 5 | 0 | 默认切换、稳定期、脚手架移除和 P4 拆分尚未开始 |
| **合计** | **100** | **65** | **功能实现约 65%,尚不具备默认替换条件** |
### 当前已越过的里程碑
- GPUI 终端、ConPTY、CJK/Powerline 网格、多 tab、输入/选择/鼠标语义已进入
产品代码;配置与旧壳共享同一事实源。
- 设置已成为内容区单例 tab;全部纯键值项可编辑,主题、配色、字号、背景、
壁纸、透明度和系统深浅跟随已有 GPUI 路径。
- Provider 编辑器已复用共享业务 API;API Key 通过 Windows 原生凭据对话框
写入,不进入可复制的 GPUI 文本框。
- 命令面板复用旧壳动作目录,文件树复用旧壳 `SidePanel` 模型;GPUI 只负责
展示和事件适配。当前目录的复制与系统文件管理器打开动作已接线,并按活动
tab 是否具有本地目录复用旧壳的可用性规则。
### 高难度剩余项(先独立设计和验收,不与零碎修改混做)
1. **分屏面板接线**:接入 `nebula-split` 会改变 tab/pane 所有权、关闭与 Drop
语义、PTY Resize、焦点路由、拖拽落点和 AI hook 的 pane 定位。必须先定
生命周期合同,再改 `workspace.rs` 与终端会话层。
2. **SSH 完整迁移**:共享 HostStore、SSH HOSTS 侧栏、设置 CRUD、置顶/隐藏/
恢复、原生凭据输入、连接状态与错误恢复必须同一套语义;还要验证真实服务
器、远端 hook、Resize 和避免外部 conhost 窗口。
3. **加密备份与远端同步**:本地导出/恢复和 Folder/WebDAV/S3/SFTP 四条路径
涉及凭据、进度/取消、失败回滚、原子恢复与协议错误,且 SFTP 依赖 SSH
主机模型稳定。
4. **三闸门与默认入口切换**:需在 `nebula --gpui` 产品形态重跑等网格性能、
完成真实 IME/DPI/多屏人工验收、视觉对账和稳定期;通过后才能翻转默认入口
并移除 `NEBULA_GPUI_SHELL` spike。
### 低风险剩余项(在高难度文件空闲时穿插)
- 同步路线图和验收清单;补齐已实现能力的针对性测试与离线构建检查。
- 字体选择器、命令面板中不改变 pane 生命周期的简单动作、设置页过期说明。
- 小型视觉/可访问性收尾;凡需修改 `workspace.rs` 或 `settings_pane.rs` 的任务,
在分屏、SSH、备份工作进行时暂停,避免文件竞态。
## 终局形态(不可协商的三条)
1. **唯一产品、唯一代码库**:`nebula.exe`(`nebula_app`)。GPUI 最终作为
`nebula_app` 体内的 UI 层接入——不是第二个产品 exe。`nebula_gpui` crate
永远只是**实验场**:快速验证组件、交互与渲染方案;验证通过的模块**并入
`nebula_app`**,产品代码不在实验场安家。
2. **网格渲染永远自有**:`nebula_terminal` 引擎 + 渲染合同
(`render.rs` / `render/boxdraw.rs`)+ 终端 Element。终端内容只存在
"单元格网格"一种形态,排版引擎(任何字体系统)无权移动网格字形。
powerline、fastfetch、TUI 边框、CJK 对齐是**验收闸门**,不是愿望。
3. **回滚 = 代码保留 + git 历史**:旧 winit/OpenGL UI 保留在树上、保持可
构建,直到闸门全过 + 稳定期结束;删除旧 UI 是迁移的最后一步。不设
运行时开关、不留长期 feature flag 双路径。
## 三道闸门(任一否决即停在原地)
| 闸门 | 内容 | 验收方式 |
|---|---|---|
| G1 性能 | 大流量吞吐与滚动流畅度不低于旧渲染器既定比例(首测后定阈值) | `scripts/perf_baseline.ps1` 可重复测量,新旧同负载对比 |
| G2 IME | 中文输入全链路:预编辑、候选窗跟随光标、提交、退格 | 人工清单(用户亲手验收) |
| G3 视觉保真 | powerline 提示符、fastfetch(logo/色块/宽字符)、boxdraw 边框、CJK 对齐、光标形态 | 新旧并排截图对账 |
## 阶段
### P0 地基(已完成)
- workspace 合并(120859b):crossfont 0.9 解除 links 冲突,单 lockfile。
- 渲染合同(73c584a、d049894):viewport 合流 + 纯数据快照,引擎零框架类型。
- boxdraw 几何(5c6745d):框线/块/Powerline 收归合同,字体无权染指。
- 终端 Element + 多 tab 工作区(5815b95、05ab821):真 ConPTY 在 GPUI 内跑通。
- lib+bin 双形态与进程内拉起验证(f315edc):双 UI 运行时同进程共存已证实。
- 注:2026-08-13 全库改写剔除联合作者尾注,本节哈希已同步为新值。
### P1 闸门建设(当前)
- **1a 性能基线**:`scripts/perf_baseline.ps1`(负载生成 + ConPTY 免焦点
注入 `perf_inject.ps1` + 终端内自计时)。
**首测 2026-08-13(50MB 混合负载:ANSI 256/真彩 + CJK + boxdraw +
Powerline),release 构建,各 3 轮取中位**:
| 壳 | 中位耗时 | 吞吐 | 内存 | 窗口 |
|---|---|---|---|---|
| winit-old | 21.1s | 2.4 MB/s | 118 MB | 1267x740 |
| gpui-lab | 21.8s | 2.3 MB/s | 85 MB | 1095x729 |
判读:吞吐差 3.6%(GPUI 窗口略小,按面积校正视为持平),内存省 28%。
**G1 阈值定为:等网格下吞吐不低于旧壳的 90%——当前通过**。后续在等
网格条件下复测一次收严。
附带判明(判别实验 2026-08-13,两壳分别以 `openconsole=off`/缺侧载对
复测):无侧载 OpenConsole/conpty.dll 时走 in-box ConPTY(conhost),
两壳同样慢 3~8 倍且抖动巨大(0.5~1.3 MB/s、单轮 38~94s、尾部可达
分钟级,观感近似停摆)。这是 in-box host 自身行为,**不是引擎死锁**,
引擎侧无从修复。运维硬规则:任何 nebula 系 exe 旁必须部署侧载对。
- **1b IME 清单**:产品形态人工清单已更新到
`nebula_gpui/IME_CHECKLIST.md`;等待用户在 `nebula.exe --gpui` 亲手验收,
实验场与双运行时 spike 的结果不计入 G2。
- **1c 视觉对账集**:`scripts/visual_parity.ps1`——固定样张(boxdraw 全家
桶、块/浓度/象限、Powerline 分隔符、CJK 对齐标尺、256 色/真彩)注入
两壳并截图(`.tmp_parity_<tag>.png`)。
**首轮对账 2026-08-13:结构级持平**——框线闭合无缝、CJK 标尺逐列对
齐、Powerline 三角在 GPUI 侧(boxdraw 几何)边缘更干净;`mixed/half/
trans` 几行两壳同样偏怪(旧壳像素栅格化的既有观感,非回归)。
待办:config 共享后做同主题对比;fastfetch 未安装(装上即可入集);
放大级笔画粗细对账。
### P2 终端体验齐平(裁定修订 2026-08-13:直接在产品内做)
用户裁定:实验场不再堆产品功能——`nebula_gpui` 只是验证场,验证过即进
`nebula_app`;P2 剩余项全部在 `nebula_app/src/gpui_shell/` 内继续。
- 选择/复制/鼠标语义 **✔(2026-08-13,1244f1a)**:鼠标模式上报(SGR/
normal/UTF-8 扩展,`mouse_protocol.rs` 纯函数逐字对照旧壳 + 字节级单测;
vim/htop 接管指针,Shift 旁路)、右键复制/粘贴(旧壳 Windows 惯例)、
copy_on_select 抬手复制、Shift+点击扩展选区、Shift+PageUp/PageDown/
Home/End 回滚翻页(仅主屏)。
- 分屏规则共享化 **✔(2026-08-13,9e21bc9)**:新共享 crate
`nebula-split`(零依赖)——布局树、几何切割(floor+逐侧单元格钳制)、
分隔条拖拽(关闭边距/预览钉边/整格量化提交)、方向聚焦(垂直漂移 4x
惩罚),数学逐字对照旧壳 `split.rs`,12 个单测锁定。**GPUI 面板接线
待办(在产品内做)**。
- config 共享化 **✔ 第一刀完成(2026-08-13,9e29331)**:新共享 crate
`nebula-settings`(零依赖)承接 `nebula_settings.txt` 路径/键值语义与
主题终端色表;按旧壳同序叠加(toml → 主题),字体/光标/copy_on_select
均读运行时设置。同主题对账样张已验。剩余:toml 侧 font offset、
cursor 反色语义、follow_system_theme、热重载。
- 剩余:滚动条(如旧壳有)、会话/SSH 逻辑共享化评估。
### P3 接入 `nebula_app`(GPUI 成为产品 UI 层)
- **✔ 第一刀(2026-08-13,791fdc8):GPUI UI 层物理迁入产品**。
`git mv` 保历史:终端栈(view/element/session/keymap/mouse_protocol/
colors)、config 桥、workspace、theme/prelude 全部住进
`nebula_app/src/gpui_shell/`;`gpui-shell` feature 自足(直接依赖
gpui/gpui-component/-assets + nebula-settings + futures,fork 经根
patch 表重定向),不再依赖 `nebula-gpui` crate。
**`nebula --gpui` = GPUI 主窗形态**:主线程直接进 GPUI 消息循环,
winit 完全不启动;已实跑验证(Nebula 主窗 + tabs + ConPTY 终端 +
CJK + powerline,样张 `.tmp_parity_gpui-in-nebula.png`)。
`nebula_gpui` 瘦身为组件 gallery(终端预览移除;theme/prelude 留
注记副本),产品代码零残留。
- 剩余:GPUI 主窗成为默认 UI(三闸门在 `--gpui` 形态复测通过后切换);
分屏面板接线(消费 `nebula-split`);产品面直接用组件库实现:设置
**原生内嵌侧栏 pane**、启动器/命令面板、SSH 管理、标题栏/Acrylic
对齐;`NEBULA_GPUI_SHELL` spike 移除。
- 三闸门在接入形态下复测(实验场数字不能替代产品形态数字)。
### P4 重构与收尾(GPUI 接入完成后)
- 旧 winit/OpenGL UI **不删除**(用户裁定 2026-08-13):保留在树上、保持
可构建,作为永久回滚锚点,只移出默认执行路径。
- crossfont **退场但不删除**:新 UI 路径不再使用它,代码与依赖随旧渲染
器保留。
- `gpui-shell` 双运行时脚手架在 P3 主窗接管完成后移除(脚手架不属于
"旧代码"范畴)。
- **大文件拆分分层**(必做,接入完成后统一做一次):
- `display/mod.rs`(10342 行)→ 按面拆:终端视图、布局、消息条、弹层等。
- `display/settings.rs`(7264 行)→ 设置分组模块化。
- `event.rs`(3178 行)/ `window_context.rs`(3100 行)→ 输入/窗口分层。
- 拆分原则:先划模块边界再搬代码,行为零变化,每步独立 commit 可回退。
## 纪律(引用 `nebula_gpui/ARCHITECTURE.md`)
- 功能只写一次,进共享 crate;两壳都只写薄视图。
- 直接采用:GPUI 赢下某个面后就是该面的唯一实现。
- 引擎与渲染合同禁止出现 UI 框架类型(Cargo 依赖方向物理执行)。
- fork 只允许组件级小行为补丁,平台窗口层不碰。