# 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。**