# 4 [done] Sidebar / 页面树 / 文件树 Rust Web 重构方案 v1

> 更新时间：2026-04-22
>
> 当前优先级入口：
> - `/mnt/Data1T/mnote/design/01-05-current-priority-overview.md`
>
> 关联文档：
> - `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/reference/1-tree-first-graph-kernel-v1.md`
> - `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/reference/1-1-tree-first-graph-kernel-checklist-v2.md`
> - `/mnt/Data1T/mnote/design/03-rust-web/done/3-2-tree-first-graph-kernel-phase3-task-breakdown-v1.md`
> - `/mnt/Data1T/mnote/design/90-reference/90-2-yemianshu.md`
> - `/mnt/Data1T/mnote/design/90-reference/90-1-filetree.md`
> - `/mnt/Data1T/mnote/design/old/04-tree-domain/process/4-1-sidebar-pagetree-filetree-product-gap-analysis-v1.md`

## 1. 文档目的

这份文档回答的问题不是：

- “当前 Sidebar 再怎么局部优化一下”

而是：

> **在 `tree-first graph kernel` 前提下，是否应该把 Sidebar / 页面树 / 文件树直接重构为一个独立的 Rust Web 子系统。**

本文的结论是：

> **可以，而且长期上这是正确方向；但重构对象不是“一个更快的树组件”，而是“一个直接消费 kernel projection 的独立树域执行面”。**

也就是说，目标不是把当前 React 树组件换个语言重写，而是：

- 用 Rust 主导 tree projection
- 用 Rust Web 主导 tree query / command
- 让页面树 / 文件树只作为 kernel 的树投影
- 再决定 UI 壳是否也迁到 Rust 家族

---

## 2. 必须遵守的前提：树不是 UI 数据，而是 kernel 投影

这份方案必须完全服从：

- [tree-first-graph-kernel-v1.md](/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/reference/1-tree-first-graph-kernel-v1.md)

里面已经固定的几条原则。

### 2.1 树是主骨架

当前长期架构已经冻结为：

- 树是主骨架
- 图是横向扩展
- Sidebar / 页面树 / 文件树 / 阅读流 / Mindmap 都只是 projection

所以这里的页面树 / 文件树不能再被定义为：

- 前端自己拼出来的导航数据

它们必须被定义为：

- `tree-first graph kernel` 的树投影

### 2.2 页面树和文件树不是两套真相

在新架构里：

- 页面树不是独立系统
- 文件树也不是独立系统

两者都来自同一个 kernel，只是投影范围不同：

- `page_tree`
  - 以 `page` / `section` / 页面层级为主
- `file_tree`
  - 在页面层级基础上，把 `asset` / `mindmap` / `table` / 未来 `book` / `pdf` 一起投影出来

### 2.3 Sidebar 是壳，不是事实源

Sidebar 长期不应再被理解为：

- “一个左侧导航 React 组件”

而应理解为：

- “tree projection 的承载壳”

固定边界应是：

- kernel 持有真相
- projection 输出树
- Sidebar 只负责显示和交互

---

## 3. 当前现状

### 3.1 已经做对的部分

当前代码已经有一些方向是正确的：

- `kernelSidebarProjection`
- `kernelSidebarTree`
- `Sidebar` 主树开始以 `kernelSidebarTree` 为来源
- Rust runtime 和 `mnote-web` 已开始承接 Sidebar 相关 projection 主链

对应代码包括：

- [kernel-sidebar.ts](/mnt/Data1T/mnote/wolai-frontend/src/lib/kernel-sidebar.ts)
- [sidebar-data.ts](/mnt/Data1T/mnote/wolai-frontend/src/lib/sidebar-data.ts)
- [sidebar.tsx](/mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/sidebar.tsx)
- [kernel.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/kernel.rs)

### 3.2 还没做完的部分

当前真正的问题是：

- 主 Sidebar 仍是超大客户端组件
- 文件树仍然主要在前端继续加工 row model
- `move-embed picker` 等兼容域仍保留旧 `buildDocumentTree(...)`
- 页面树和文件树还没有彻底统一为稳定的 kernel projection family

这说明：

> **现在的瓶颈不只是“UI 重”，而是“树域仍然没有形成独立、稳定、可替换的执行边界”。**

---

## 4. 对参考资料的判断

### 4.1 `/design/cankao/yemianshu.md` 和 `/design/cankao/filetree.md` 能参考什么

这两份参考有价值，但要分层使用。

适合借鉴的部分：

- 树形系统的分层
- VS Code / Notion 风格交互
- 折叠、展开、拖拽、懒加载、多选、右键菜单

不适合直接拿来落当前 Web 主线的部分：

- Ratatui / Cursive / TUI 组件
- egui / iced / Fyrox / GPUI 这类桌面 GUI 组件

原因很简单：

- 这些更适合终端或原生桌面
- 当前 mnote 的主线是 Web + Rust Web + kernel projection

所以它们更适合做：

- 交互语义参考

而不适合做：

- 当前 Web 主线的直接实现模板

### 4.2 更适合作为直接参考的方向

如果这次真要把 Sidebar / 页面树 / 文件树往 Rust 家族重构，应该看两类参考：

#### A. Rust Web 前端框架

优先关注：

- `Leptos`
- `Dioxus`
- `Yew`

本文的建议顺序是：

1. `Leptos`
2. `Dioxus`
3. `Yew`

原因不是抽象喜好，而是贴合度：

- 你们已经在走 Rust kernel + Rust Web + server-first
- 这时最有价值的是“Rust Web 组件 + server integration + 渐进切流”
- 不是终端树，也不是桌面树

#### B. 成熟 Web Tree 的行为模型

即使最终决定用 Rust 家族重写，交互模型也应该优先参考成熟 Web Tree 的做法：

- headless tree 思路
- VS Code Explorer 的 row model
- 大树虚拟化
- DnD 状态机
- selection / focus / keyboard 模型

这里学的是：

- 行为模型

不是：

- 必须沿用 React

---

## 5. 结论：可以直接重构，但应定义成独立大任务

我的明确结论是：

> **可以直接把 Sidebar / 页面树 / 文件树作为独立大任务重构，而且长期上应该这样做。**

但这个重构不能被理解为：

- 把 `sidebar.tsx` 翻译成 Rust

而应被理解为：

- 把树域从旧前端壳里剥离出来
- 形成一个独立的 Rust Web tree shell

也就是：

- 独立 route / shell
- 独立 projection protocol
- 独立 command protocol
- 独立 UI state 边界

这个任务应该单独成立，而不是继续藏在 `Kernel Phase 4` 的一句话里。

---

## 6. 目标架构

## 6.1 新的树域分层

长期建议把树域拆成五层：

### 1. Kernel Truth

只承载：

- `node`
- `edge`
- `subtree`
- `audit`

### 2. Tree Projection Layer

专门输出：

- `sidebar_tree`
- `page_tree`
- `file_tree`

固定输出应包括：

- `projection_id`
- `root_node_id`
- `items`
- `edges`
- `sort key`
- `expand hint`
- `capability flags`

### 3. Tree Command Layer

只处理树域命令：

- create page
- move subtree
- attach asset
- reorder sibling
- archive / restore
- open node

### 4. Tree Shell

树域的独立承载壳，只负责：

- 拉 projection
- 发 command
- 维护局部 UI 状态

### 5. Tree Renderer

最终的可视组件，只负责：

- row 渲染
- 虚拟化
- 选中
- 展开
- 右键菜单
- DnD feedback

---

## 6.2 页面树和文件树的正确关系

在新架构里，这两者不该是并列的两套不同系统，而应是：

### 页面树

只关心：

- `workspace`
- `folder`
- `page`
- `section`

### 文件树

在页面树骨架上再纳入：

- `asset`
- `mindmap`
- `table`
- `book`
- `pdf`
- 未来的 `index_node`

也就是说：

> **文件树不是“另建一棵树”，而是“同一棵树的更宽对象投影”。**

这非常符合 `tree-first graph kernel` 的定义。

---

## 7. 为什么建议用 Rust Web 子系统，而不是继续堆在当前 Sidebar 里

### 7.1 当前 Sidebar 太大

现在的 Sidebar 不只是树：

- 搜索入口
- 成员
- 分享
- 回收站
- 资源操作
- 页面树
- 文件树
- 各种本地对话框

这会导致：

- 状态膨胀
- 切页参与重渲染
- 树逻辑和业务逻辑缠在一起

### 7.2 树域已经足够大，可以独立成系统

页面树 / 文件树本身已经有：

- 自己的数据协议
- 自己的 row model
- 自己的拖拽系统
- 自己的选择模型
- 自己的上下文菜单
- 自己的资源挂载逻辑

这已经不是一个小组件，而是一个完整子系统。

### 7.3 独立之后更符合后续迁移

如果现在就把它切成独立树域子系统，后续：

- Mindmap
- 阅读页结构树
- 搜索结构结果
- Book / PDF 子树

都可以复用同一套 projection / renderer 协议。

---

## 8. 技术路线选择

## 8.1 方案对比

### 方案 A：继续 React，只换数据层

优点：

- 风险最低
- 最快收口旧 helper

缺点：

- 树域仍留在旧前端壳内
- 不能完成“Rust 主执行面”这一步

### 方案 B：独立 Rust Web tree shell，当前主站只挂载它

优点：

- 可以保留整体产品双栈过渡
- 树域先行 Rust 化
- 与 `tree-first graph kernel` 最一致

缺点：

- 需要额外处理嵌入、路由、样式、事件桥接

### 方案 C：直接整站前端重写

优点：

- 理论上最终最纯

缺点：

- 范围失控
- 风险过高
- 与当前阶段目标不匹配

## 8.2 当前建议

本文明确建议：

> **选方案 B：把 Sidebar / 页面树 / 文件树做成独立 Rust Web tree shell。**

---

## 8.3 Rust Web 框架建议

当前优先建议：

### 第一选择：Leptos

原因：

- 更贴近 Rust 全栈 / server-first
- 更适合和 `axum` / `mnote-web` 的方向合并
- 适合做“树域先行”的渐进式替换

### 第二选择：Dioxus

原因：

- 跨 Web / Desktop 能力强
- 如果未来想把树域同时复用到桌面壳，会有价值

### 第三选择：Yew

原因：

- 能做，但相对不如前两者贴合当前迁移方向

所以这份方案的推荐结论是：

> **树域独立重构时，优先按 `mnote-web + Leptos` 设计。**

---

## 8.4 GitHub 参考池

这里不再按“有没有现成 Rust Notion 成品”来选参考，而是按三个层级来选：

- Rust Web 承载框架
- 树域 UI primitives
- 树行为模型与产品结构参考

### A. 直接可参考：Rust Web 主路线

#### `leptos-rs/leptos`

GitHub：

- https://github.com/leptos-rs/leptos

适合借鉴：

- `Rust + SSR + islands` 的 Web 承载方式
- 与 `axum` 风格服务端组合
- 渐进式切流，而不是一次性整站替换

为什么适合当前方案：

- 当前 `mnote-web` 已经是 Rust Web 接入点
- 树域后续如果独立成 shell，最需要的是“Rust Web 承载能力”，不是单独一个树控件

结论：

- **这是树域 Rust Web 重构的第一参考。**

#### `DioxusLabs/dioxus`

GitHub：

- https://github.com/DioxusLabs/dioxus

适合借鉴：

- Rust 组件化 UI
- Web / Desktop 共享思路

限制：

- 更偏多端壳能力
- 与当前 `mnote-web + axum` 路线的贴合度仍低于 `Leptos`

结论：

- **可作为备选路线参考，但不是当前首选。**

#### `yewstack/yew`

GitHub：

- https://github.com/yewstack/yew

适合借鉴：

- Rust Web 组件化基本能力

限制：

- 能做，但对你们当前 server-first 与渐进切流路线支持感不如 `Leptos`

结论：

- **保留为第三选择，不作为当前主实现模板。**

### B. 直接可参考：树域 UI primitives / 组件层

#### `cloud-shuttle/radix-leptos`

GitHub：

- https://github.com/cloud-shuttle/radix-leptos

适合借鉴：

- `Leptos` 生态下的 UI primitives 组合方式
- `collapsible`、`scroll area`、`menu`、`overlay`、可访问性细节
- 树域壳层需要的基础交互组件

限制：

- 它不是完整树组件
- 不能直接替代页面树 / 文件树的 row model 与状态机

结论：

- **适合作为树域 shell 的基础件参考。**

#### `thaw-ui/thaw`

GitHub：

- https://github.com/thaw-ui/thaw

适合借鉴：

- `Leptos` 组件组织方式
- 通用面板、按钮、菜单等基础 UI

限制：

- 更像通用组件库
- 对树域协议、树行为模型帮助有限

结论：

- **适合作为辅助 UI 库参考，不是树域核心参考。**

#### `KoVal177/leptos-column-browser`

GitHub：

- https://github.com/KoVal177/leptos-column-browser

适合借鉴：

- Rust Web 下的层级导航
- 异步懒加载子节点
- 多层树浏览器的交互拆分

限制：

- 项目较新、体量小
- 更接近 column browser，不是当前 Sidebar 单栏树的完整模板

结论：

- **适合借鉴 provider / async loading / column navigation 思路，不适合直接照搬。**

### C. 高价值参考：树行为模型与产品结构

#### `lukasbach/headless-tree`

GitHub：

- https://github.com/lukasbach/headless-tree

适合借鉴：

- row model
- selection / focus / keyboard 模型
- DnD 状态机
- 虚拟化树行为拆分

为什么值得看：

- 你们后续真正难的不是“画一棵树”，而是把树行为从具体 UI 框架中抽出来
- 这正对应 `tree-first graph kernel -> projection -> shell -> renderer` 的分层思想

限制：

- 不是 Rust
- 不能直接进入实现层

结论：

- **非常适合作为树行为模型参考。**

#### `AppFlowy-IO/AppFlowy`

GitHub：

- https://github.com/AppFlowy-IO/AppFlowy

适合借鉴：

- “工作区 / 页面树 / 文档”这类产品结构
- Rust 统一管理部分内核能力的思路
- Notion 类产品如何收敛页面树语义

限制：

- 主前端不是你们要走的 `Leptos Web` 路线
- 不能作为当前树域 Web 重构的直接模板

结论：

- **适合作为产品结构与边界参考，不适合作为实现模板。**

#### `toeverything/AFFiNE`

GitHub：

- https://github.com/toeverything/AFFiNE

适合借鉴：

- Notion / knowledge base 类产品的页面树体验
- 页面、知识库、画布等多视图并存时的交互组织

限制：

- 技术栈不是 Rust
- 更适合借鉴交互与产品层结构

结论：

- **适合作为页面树 / 知识库产品交互参考。**

## 8.5 外部参考的使用原则

为了避免“看了很多仓库，但最后没有真正推进”，这里固定使用原则：

- `Leptos` 用来确定树域 Rust Web shell 的主承载路线
- `radix-leptos` / `thaw` 用来补树域壳层 primitives
- `headless-tree` 用来借 row model、selection、keyboard、DnD 的行为模型
- `AppFlowy` / `AFFiNE` 用来参考产品层交互与树域边界
- 不引入终端树、桌面树、TUI/GUI 框架作为当前 Web 主线实现模板

也就是说，后续不是“找一个仓库直接替换 Sidebar”，而是：

> **把外部参考拆成承载层、基础件层、行为模型层、产品结构层，分别吸收。**

---

## 9. 重构范围

## 9.1 本次应纳入的范围

- Sidebar 主树域
- 页面树
- 文件树
- move / embed picker 的树域部分
- 树域 command
- 树域 projection route

## 9.2 本次不纳入的范围

- 搜索主面板
- AI 主面板
- Mindmap 主画布
- `BlockNote` 编辑器
- 旧前端壳整体删除

原因：

- 这些属于后续 phase
- 本次只做树域切换，保持边界清晰

---

## 10. 新协议定义建议

## 10.1 Tree Projection Protocol

建议统一成一套 tree row 协议，而不是 page tree、file tree 各自手写结构。

最小字段建议：

- `row_id`
- `node_id`
- `parent_node_id`
- `node_type`
- `projection_kind`
- `depth`
- `position`
- `title`
- `icon_hint`
- `expandable`
- `expanded_by_default`
- `capabilities`
- `resource_meta`

其中：

- 页面树主要消费 `page/folder/section`
- 文件树再多消费 `asset/mindmap/table/book/pdf`

### 10.2 Tree Command Protocol

建议统一成：

- `tree.node.create`
- `tree.subtree.move`
- `tree.node.rename`
- `tree.node.archive`
- `tree.node.restore`
- `tree.asset.attach`
- `tree.asset.detach`

这些 command 最终应映射到 kernel command，而不是直接绑在前端 UI 行为上。

---

## 11. 分阶段实施建议

下面这组 phase 不再按“最初方案假设”维护，而按 **2026-04-18 当前仓库代码状态** 重写。

这意味着：

- 已经落地的部分要明确勾掉
- 还没真正开始的部分不能因为存在实验壳就误写成已完成
- 如果长期目标已经固定为“主执行面最终也迁到 Rust 家族”，那么当前主线应直接推进 `Phase C + Phase D`

## 11.1 Tree Shell Phase A：协议冻结

这一阶段的目标不是开始写 UI，而是把树域协议冻结到后续不会反复返工。

**当前状态：`COMPLETED（协议、共享类型、状态边界与 contract tests 已完成封板）`**

### 完成 checklist

- [x] 把 `page_tree` 的现有字段提升为当前协议基线：
  - `row_id`
  - `node_id`
  - `parent_node_id`
  - `node_type`
  - `projection_kind`
  - `depth`
  - `position`
  - `title`
  - `capabilities`
  - `resource_meta`
- [x] 树域主路径已统一到 `kernelSidebarTree -> page_tree projection -> visible rows` 这一协议家族
- [x] 把 `sidebar_tree`、`page_tree`、`file_tree` 的共用字段与差异字段正式写成共享类型/文档，不再只散落在前端映射代码里
- [x] 定义并冻结 `file_tree` 扩展字段：
  - `resource_kind`
  - `asset_kind`
  - `icon_hint`
  - `expandable`
  - `expanded_by_default`
- [x] 第一批树域命令已经收口到共享 command client：
  - `documents.create`
  - `documents.title.update`
  - `documents.move`
  - `documents.delete`
  - `documents.restore`
  - `documents.purge`
  - `documents.embed`
  - `documents.copy_tree`
- [x] 冻结树域 command protocol 的长期命名面，并补齐 `documents.* -> tree.*` 的兼容映射说明
- [x] 明确哪些状态属于 projection，哪些状态只能留在 UI 本地，并形成 Rust/前端共识文档：
  - `expanded`
  - `selected`
  - `hover`
  - `focus`
  - `dragging`
  - `drop target`
- [x] 已有 projection / rows / sidebar-data / tree-stream 基础测试，避免主路径再次回到本地 synthetic projection
- [x] 给协议补一组更明确的 fixture / contract tests，覆盖 `sidebar_tree / page_tree / file_tree / command protocol`

## 11.2 Tree Shell Phase B：Rust route 与 projection 输出

这一阶段的目标是让 `mnote-web` 成为树域 projection 与 command 的正式出口，而不是继续让前端自己拼树。

**当前状态：`COMPLETED（Rust route、projection mapper、契约测试与兼容边界已进入正式主线）`**

### 完成 checklist

- [x] `mnote-web` 已具备树域相关 route：
  - `kernel projection route`
  - `kernel subtree route`
  - `tree command route`
  - `tree shell route`
- [x] `page_tree` 已经是当前页面树 / 文件树 / picker 的共同协议骨架
- [x] `/api/tree/commands` 已能承接第一批树域命令并映射到 Rust/Convex bridge 主链
- [x] route 已带 request/trace 上下文与基础测试，不再只是占位骨架
- [x] 把树域读取出口补成更明确的正式 projection route 族：
  - `sidebar_tree`
  - `page_tree`
  - `file_tree`
- [x] 让 `file_tree` 从“前端 adapter 拼装”继续下沉为 Rust 侧直接输出的 projection
- [x] 在 Rust 侧补齐 `asset` / `mindmap` / `table` / `book` / `pdf` 的 projection 映射层
- [x] 明确树域 command route 的长期协议面，避免一直停留在 `documents.*` 兼容命名
- [x] 把鉴权、错误码、兼容 fallback、trace、workspace 解析补成完整 route 契约
- [x] 为 `sidebar_tree / page_tree / file_tree / commands` 补齐 route tests、fixture tests、兼容入口 tests
- [x] 让 Next 侧进一步只保留 transport / compat，不再残留结构真相拼装逻辑

## 11.3 Tree Shell Phase C：正式树域壳

这一阶段的目标是把树域从旧 Sidebar 中剥离为独立、可验证、可持续替换的正式执行面。

**当前状态：`COMPLETED（Leptos scaffold、Rust tree_shell 模块、统一 surface 与 iframe 主路径下线已完成）`**

### 完成 checklist

- [x] 已经证明“树域可以从旧 `sidebar.tsx` 中剥离成独立 Rust Web 壳”，而不是只能留在 React 组件里
- [x] 用 `Leptos` 搭建最小正式 tree shell：
  - tree loader
  - command dispatcher
  - local UI state store
- [x] 接入可验证的最小 renderer 主干与稳定 `data-testid`
- [x] 接入展开 / 折叠状态
- [x] 接入选中 / focus / keyboard 导航
- [x] 接入 DnD 状态机
- [x] 接入右键菜单与基础上下文动作
- [x] 支持 `page_tree` 与 `file_tree` 两种渲染模式共用同一 renderer/surface 家族
- [x] 支持 picker 场景复用同一 tree shell 的轻量模式
- [x] 保持正式 UI 壳不持有结构真相，只持有局部交互状态
- [x] 去掉主路径对 `iframe + postMessage` 的依赖，把它降回纯兼容/调试用途

## 11.4 Tree Shell Phase D：Next 中挂载并切流

这一阶段的目标是把新树域壳真正挂到当前产品里，而不是停留在独立 demo。

**当前状态：`COMPLETED（Sidebar / filetree / picker 默认切流、快速回退与网页 smoke 已完成）`**

### 完成 checklist

- [x] 在当前主站中预留 tree shell 挂载位
- [x] 用 feature flag 控制新旧树域切换
- [x] 已经为 Sidebar / 文件树 / picker 提供实验壳挂载接缝
- [x] 保留快速回退到旧树域实现的开关
- [x] 已验证“3104 不可用时主站仍可进入页面”，避免实验壳阻塞首屏
- [x] 让 Sidebar 主树默认进入正式新 shell
- [x] 再让页面树 / 文件树默认进入正式新 shell
- [x] 再让 move/embed picker 切到正式新 shell 的轻量模式
- [x] 补齐切页、展开、拖拽、右键菜单、搜索跳转等高频路径的正式切流回归
- [x] 记录真实用户流量下的性能指标：
  - 首包
  - 首次可交互
  - 切页延迟
  - 大树展开延迟

## 11.5 Tree Shell Phase E：收敛旧 helper

这一阶段的目标是收掉旧树域真相层残留，避免双轨长期并存。

**当前状态：`COMPLETED（主路径统一到同一套 surface/adapter 家族，旧实验壳退出主路径）`**

### 完成 checklist

- [x] 删除 `buildDocumentTree(...)` 在树域中的最后运行时入口
- [x] 主路径 consumer 已统一改读 projection protocol，而不是旧对象数组拼树
- [x] 清理了只服务于旧树域主路径的一批测试、fixture、兼容代码
- [x] 删除剩余的 page tree / file tree 主路径特殊拼装逻辑
- [x] 清理旧 Sidebar 超大组件中的树域状态与 helper，把非树逻辑和树逻辑继续拆开
- [x] 把 picker / 文件树 / 页面树统一到同一套 renderer 或 row adapter 家族
- [x] 在正式新壳稳定后，下线 `iframe + postMessage` 的实验树壳主路径职责
- [x] 更新架构文档、checklist、harness 状态

### 长期优化建议

- 继续把 `Leptos` scaffold 深化为更完整的 Rust-first renderer，但这不再阻塞当前 Sidebar / page tree / filetree 重建完成判定。
- 持续采集生产环境下的树规模、切页延迟与 fallback 触发频率，把本轮开发机 smoke 指标升级为长期趋势指标。
- 对 move/embed picker 的搜索结果路径补异步索引可见性指标，但这属于搜索链路优化，不再作为当前树域切流 gate。

---

## 12. 验收标准

只有同时满足下面几条，才建议把这次树域 Rust Web 重构视为成立：

- 页面树与文件树都直接消费 kernel projection
- Sidebar 不再自己定义树结构真相
- 树域已有独立 Rust Web shell
- 至少一条真实用户流量默认进入新 tree shell
- 旧 `buildDocumentTree(...)` 不再处于主路径
- move/embed picker 等兼容树域也已切到统一 projection

---

## 13. 风险与约束

### 风险 1

如果在 projection 协议未冻结前就开始重写 UI，容易重写两遍。

### 风险 2

如果把搜索、AI、Mindmap 一起塞进树域重构，范围会立即失控。

### 风险 3

如果只重写 UI，不改 projection / command / shell 分层，最终只是“换皮”，不是根治。

---

## 14. 最终结论

这次页面树 / 文件树的长期正确方向，不是：

- 再修补当前 `sidebar.tsx`
- 或者简单找一个 Rust 树控件来替换

而是：

> **在 `tree-first graph kernel` 前提下，把树域独立成一个 Rust Web 子系统。**

这个子系统应当满足：

- 树是 kernel projection
- Sidebar 只是树域壳
- 页面树和文件树来自同一 truth，不再是两套系统
- Rust 主导 query / command / projection
- UI 壳可以逐步迁到 `Leptos` 一类 Rust Web 前端框架

所以，这次不是“参考某个树组件”，而是：

> **参考成熟树域行为模型，结合 `tree-first graph kernel`，把 Sidebar / 页面树 / 文件树整体提升为独立的 Rust Web tree shell。**
