Files
mnote/design/05-editor-mainline/process/5-7-wolai-page-tree-main-editor-experience-restoration-v1.md
T

52 KiB
Raw Blame History

5-7 [process] Wolai 页面树与主编辑器体验复刻方案 v1

更新时间:2026-04-30

Wolai-aline 执行口径更新(2026-04-30): 本文只保留体验复刻任务拆解和产品目标。所有 Wolai 对标测试、浏览器取证、编辑权限、安全边界、subagent 使用、截图复核和 smoke 补齐,统一以 /home/lix/.codex/skills/wolai-aline/mnt/Data1T/mnote/design/08-wolai-aline-test-flow/process/wolai-aline-test-flow-v1.md 为准。若本文旧段落与该 skill 冲突,以 skill 为准。

关联文档:

  • /mnt/Data1T/mnote/ARCHITECTURE.md
  • /mnt/Data1T/mnote/design/01-05-current-priority-overview.md
  • /mnt/Data1T/mnote/design/01-tree-first-graph-kernel/process/1-tree-first-graph-kernel-v1.md
  • /mnt/Data1T/mnote/design/02-convex-rust-long-term-architecture/process/2-tree-first-graph-convex-rust-long-term-architecture-v1.md
  • /mnt/Data1T/mnote/design/03-rust-web/process/3-rust-web-long-term-architecture-v1.md
  • /mnt/Data1T/mnote/design/03-rust-web/process/3-3-rust-web-tree-realtime-event-stream-v1.md
  • /mnt/Data1T/mnote/design/04-tree-domain/done/4-2-sidebar-pagetree-filetree-product-interaction-contract-v1.md
  • /mnt/Data1T/mnote/design/04-tree-domain/done/4-6-tree-command-protocol-cutover-stage2-v1.md
  • /mnt/Data1T/mnote/design/05-editor-mainline/process/5-2-tiptap-notion-like-template-adoption-v1.md
  • /mnt/Data1T/mnote/design/05-editor-mainline/process/5-4-leptos-tiptap-mainline-correction-v1.md
  • /mnt/Data1T/mnote/design/05-editor-mainline/process/5-5-page-aggregate-single-truth-alignment-v1.md
  • /mnt/Data1T/mnote/design/05-editor-mainline/process/5-6-page-aggregate-alignment-checklist-v1.md
  • /mnt/Data1T/mnote/design/05-editor-mainline/process/5-9-wolai-aline-continuous-checklist-v1.md
  • /mnt/Data1T/mnote/design/05-editor-mainline/done/5-5-1-page-aggregate-contract-v1.md

1. 文档目的

这份方案只处理一件事:

以真实 Wolai 页面为视觉和交互 benchmark,继续还原 mnote 的页面树与主编辑器体验。

本轮目标不是重新定义系统架构,也不是把 Wolai 的全部协作能力完整复制过来,而是把当前 3000 页面在视觉密度、布局节奏、页面树反馈、主编辑器输入体验上继续向 Wolai 靠近。

约束如下:

  • UI 以像素级复刻为目标。
  • 功能以“高频路径可用、复杂能力可降级”为原则。
  • 当前项目保留“文件树 / Explorer”创新,不要求删除。
  • 默认主编辑器继续是页面内 leptos-tiptap island。
  • BlockNote 只作为 fallback / 对照链,不重新变成默认方向。
  • 树、页面结构、标题、正文、页面设置不能在 UI 层再拼第二份真相。

这份文档应放在 05-editor-mainline/process,因为它的核心不是 Rust Web 壳复刻,也不是单独的树命令合同,而是:

围绕 Page Aggregate,把页面树、页头、页面设置、正文编辑器统一成接近 Wolai 的产品体验。


2. 本轮取证基线

2.1 真实 Wolai 参考

本轮参考页面:

  • https://www.wolai.com/wolai/xhqeop8UHpVTMUSVmgz8nq
  • https://www.wolai.com/wolai/qN1Bh9YjLAXs8bxCJoAJ6C
  • https://www.wolai.com/liaibo/ikFSSM1a4GgvmHBYFCNfVd

本轮已保存的截图与快照:

  • /mnt/Data1T/mnote/tmp/wolai-page1.png
  • /mnt/Data1T/mnote/tmp/wolai-page1-snapshot.md
  • /mnt/Data1T/mnote/tmp/wolai-page2.png
  • /mnt/Data1T/mnote/tmp/wolai-page2-snapshot.md
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-target-1392x1213.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-target-snapshot.md
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-public-search-overlay.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-public-search-results-skill.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-public-presentation-mode.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-public-start-edit-overlay.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-public-comment-panel.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-public-good-night-mode.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-help-first-viewport-current.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-help-sidebar-filter-page-reference.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-help-search-overlay.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-help-search-results-page-reference.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-help-search-result-navigated-block-reference.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-help-embedded-page-reference-hover.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/wolai-help-block-reference-page-snapshot.md
  • /mnt/Data1T/mnote/wolai-basic-editing-reference.png
  • /mnt/Data1T/mnote/wolai-basic-editing-reference-snapshot.md
  • /mnt/Data1T/mnote/wolai-hermes-public-hover-block.png
  • /mnt/Data1T/mnote/wolai-hermes-start-edit-login-dialog.png
  • /mnt/Data1T/mnote/wolai-hermes-comment-panel.png
  • /mnt/Data1T/mnote/wolai-hermes-presentation-mode.png
  • /mnt/Data1T/mnote/wolai-hermes-good-night-mode.png

用户在内置浏览器中提供的登录态截图也作为本轮重要视觉证据:该截图展示了真实个人空间的长页面树、当前页 Hermes 选中态、完整顶部图标区、底部垃圾桶 / 模板中心入口、右下角 AI / 帮助浮动入口。

补充说明:历史截图和用户提供的登录态截图只作为现有证据池,不再作为后续任务的唯一验收依据。该 owner 态菜单不是单纯样式:它包含“在右侧边栏打开 / 移动到 / 嵌入到 / 复制访问链接 / 复制页面引用链接 / 复制页面 ID / 拷贝副本 / 重命名 / 删除”等页面树动作,应进入后续交互合同,而不是只当成截图复刻。

2026-04-30 口径更新:后续取证统一从 wolai-aline skill 启动。已知技术路径是 Playwright Node + /opt/google/chrome/chrome + /mnt/Data1T/mnote/tmp/wolai-playwright-profile,但本文不再维护独立自动化方案。当前 Hermes 测试页已授权用于最小编辑验证;owner 首屏、搜索浮层、顶部更多菜单、正文块 hover、.hover-block-menu 块菜单等行为,都必须通过 subagent 浏览器取证、主线程截图复核和差异矩阵重新确认。dokobot doko read --local --reuse-tab 可作为登录态 read evidence,但不能替代键鼠操作验收。

2.2 当前 mnote 参考

当前本地 3000 截图:

  • /mnt/Data1T/mnote/tmp/wolai-compare/local-3000-playwright-1392x1213.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/local-3000-first-viewport.png
  • /mnt/Data1T/mnote/tmp/wolai-compare/local-3000-dom-snapshot.txt

当前本地页面已经具备接近 Wolai 的基本壳:

  • 左侧 workspace / 快捷操作 / 页面树 / 底部入口。
  • 右侧顶部 breadcrumb / 页面操作。
  • 中央文档页标题和正文区。
  • 右下角帮助与 AI 入口。

但与真实 Wolai 仍有显著差距:

  • 左侧树的视觉密度、选中态、图标系统、滚动条和层级缩进仍不够像 Wolai。
  • 文档主内容的起始位置、标题尺寸、正文列宽、页头留白和默认元信息展示不一致。
  • 顶栏按钮体系与 Wolai 的 owner / published 两种状态还没有明确分型。
  • 主编辑器的块级 hover 手柄、slash、浮动工具条和块菜单需要按 Wolai / Notion 风格继续收口。
  • 当前页面树、页头、正文、页面设置仍必须继续服从 Page Aggregate 单一真源主线,不能为了 UI 快速复刻重新制造局部状态。

2.3 2026-04-30 subagent 基线复核

本轮已按 wolai-aline skill 派 subagent 同时操作 Wolai Hermes 与本地 3000。工具链结论:Node.js Playwright + /opt/google/chrome/chrome 可操作两个目标;Wolai 通过 /mnt/Data1T/mnote/tmp/wolai-playwright-profile 进入 owner 登录态,本地 3000 返回可用页面。无源码改动,证据写入:

  • /mnt/Data1T/mnote/tmp/wolai-editor-parity/baseline-20260430/
  • /mnt/Data1T/mnote/tmp/wolai-editor-parity/doc-baseline-mini/

主线程已复核关键截图:

  • Wolai 首屏:/mnt/Data1T/mnote/tmp/wolai-editor-parity/doc-baseline-mini/wolai-initial.png
  • 本地首屏:/mnt/Data1T/mnote/tmp/wolai-editor-parity/doc-baseline-mini/local-initial.png
  • Wolai 搜索:/mnt/Data1T/mnote/tmp/wolai-editor-parity/baseline-20260430/wolai-03-search-modal-controls-filled.png
  • 本地搜索:/mnt/Data1T/mnote/tmp/wolai-editor-parity/baseline-20260430/local-03-search-modal-controls-filled.png
  • Wolai 块 hover/mnt/Data1T/mnote/tmp/wolai-editor-parity/baseline-20260430/wolai-08-block-hover-insert-entry.png
  • 本地块 hover/mnt/Data1T/mnote/tmp/wolai-editor-parity/baseline-20260430/local-14-block-hover-insert-entry.png
  • Wolai 编辑清理后:/mnt/Data1T/mnote/tmp/wolai-editor-parity/baseline-20260430/wolai-14-title-suffix-after.png

当前差异矩阵:

Wolai Hermes 本地 3000 后续处理
首屏入口 owner 登录态直接显示 Hermes 正文页,标题、正文、页面树同屏 task130 后已改为根页直接进入 document shell + editor island;历史上曾停留在聚合 / 预览壳 后续仅继续收口侧栏数据、视觉密度与 owner/published 状态差异
侧栏数据与选中态 真实空间树,当前页在 个人 / 软件开发 / Hermes 路径下,红色选中态明显 anonymous 示例树,当前页为 1111,行密度和图标体系仍偏本地化 Sidebar checklist 必须同时验视觉和真实 active path
搜索入口 左侧放大镜可打开全局搜索;本轮 Ctrl+K 未稳定打开,Ctrl+P 在另一轮可 toggle 顶栏搜索可打开;侧栏搜索曾修为 modal;Ctrl+P 可 toggle 搜索任务不得只测一个入口;需记录每个入口、快捷键和 URL
搜索控件 modal 居中,遮罩、结果行、快捷键提示完整;switch 视觉可见 modal 结构接近,role="switch" 可测;不同输入下结果为空或本地数据结果 switch 默认状态必须同时记录截图和 aria-checked,结果态需拆数据差异与控件差异
搜索结果 输入 Hermes 命中页面和块,结果有红色高亮和路径 本地同词可出现空态或示例数据结果,取决于当前页面数据 建立固定本地 fixture 或 smoke 种子,不能用随机工作区数据验视觉
正文编辑区 首屏正文 contenteditable=true,标题也可编辑 当前已在首屏直接出现主编辑区;剩余差异转为标题区、正文密度与块交互细节 文档画布任务继续聚焦主编辑器体验,而不是首屏入口纠偏
编辑焦点风险 Wolai 标题和正文均可编辑,测试输入曾误落到标题,已清理 本地输入 / 撤销可完成,但页面结构不同 editable-test mode 前必须先断言焦点 block 类型,优先在正文末尾新建唯一测试块
块 hover 正文块左侧出现轻量块控制入口,视觉很克制 本地显示 + 与拖拽/块句柄按钮,但位置、密度、内容列差异明显 E2-E4 必须以截图和 hover 点位复核,不可只看按钮存在

这轮基线说明:当前最大偏差不是单个按钮,而是本地普通文档首屏仍像“聚合入口 / 预览页”,Wolai 则直接进入可读写的页面正文。后续 P0/P1 checklist 必须优先处理这个入口语义,否则搜索、块 hover、编辑器测试都会测到不同页面状态。

2.4 Wolai-aline 取证与验收统一口径

本节旧版“published / owner readonly / sandbox mutation”分层已经收口到 wolai-aline skill。后续执行不再从本文推导测试策略,统一遵循:

  • Codex skill/home/lix/.codex/skills/wolai-aline
  • 流程文档:/mnt/Data1T/mnote/design/08-wolai-aline-test-flow/process/wolai-aline-test-flow-v1.md
  • 失败模式:/home/lix/.codex/skills/wolai-aline/references/failure-patterns.md

现行要点:

  • 每个 Wolai-aline 小任务都必须先取 Wolai 基线,再做本地 RED smoke,再实现,再由 subagent 浏览器复测,最后主线程复核截图和差异矩阵。
  • 浏览器取证必须使用 subagent;subagent 默认只读,但当任务明确需要编辑器行为时,可在当前 Hermes 测试页进入 Hermes editable-test mode 做最小编辑验证。
  • 当前 Hermes 测试页 https://www.wolai.com/liaibo/ikFSSM1a4GgvmHBYFCNfVd 已授权用于最小编辑验证;可以创建带唯一标记的临时测试块、输入少量测试文本、验证 slash / toolbar / block menu / 快捷键等编辑器行为。
  • 编辑验证必须记录编辑前后截图、动作链、输入内容和清理状态。若安全清理有风险,不扩大操作,报告残留测试内容。
  • 即使在 Hermes 测试页,也禁止未经确认地删除、移动、归档、发布、评论、改权限或批量修改既有非测试内容。
  • 其他 Wolai 页面仍默认只读;写入仍需用户提供沙盒页 URL 和明确授权。
  • 对标不能只看文案或 DOM 是否存在;必须主动检查截图中的控件形态、状态、hover/active、快捷键 toggle、关闭路径和 URL 跳转。

硬门槛:

  • 不能把 subagent 文本结论当作最终对齐证据;主线程必须复核截图。
  • 如果截图里有肉眼可见差异,先补 smoke 捕获差异,再改实现。
  • 任何新发现的稳定失败模式,都要沉淀到 wolai-aline skill 的 failure-patterns.md

2.5 基本编辑能力 操作矩阵

https://www.wolai.com/wolai/qN1Bh9YjLAXs8bxCJoAJ6C 是 Wolai 对“主编辑器基础操作”的官方内容页。本页不只是说明文字,它给出了后续 3000 必须能复现的主编辑器操作矩阵:

操作 Wolai 参考页说明 当前对 Hermes 可自动化验证性 3000 后续验收要求
普通文本输入 / 回车 / 光标移动 像普通文本编辑器一样输入、换行、移动光标 可用 Hermes editable-test mode 取基线 在本地编辑态 smoke 中验证输入、换行、保存后刷新保持
块模型 文本、列表项、图片、文件等都是“块” owner 态只读已可观察块 hover 手柄和 block menu 本地每个块需有稳定 block id 与 hover target
拖动块 块左侧 :: 图标可拖动,并显示辅助线 owner 态只读可观察手柄;真实拖动是写入动作,按 Hermes editable-test mode 最小验证 本地必须验证拖拽预览、横向 drop line、分栏 drop line
Esc 选中块 输入态按 esc 选中当前块,上下方向键切换,shift + 上/下 多选,enter 回编辑 可用 Hermes editable-test mode 取基线 本地必须有 block selection state、keyboard smoke
cmd/ctrl + A 输入态第一次选中当前块文字,第二次选中所有块;块选中态直接选中所有块 可用 Hermes editable-test mode 取基线 本地必须区分 text selection 与 block selection
上 / 下插入块 hover 左侧 :: 上方 / 下方点击 +;或 esc 选中块后按 a / b owner 态可观察手柄;真实插入可用 Hermes editable-test mode 做最小验证 Hermes editable-test mode 必须验证 before / after 插入与 Esc, a / Esc, b
块布局显示 cmd/ctrl + shift + U 显示 / 隐藏块布局虚线框 可用 Hermes editable-test mode 取基线 本地需有布局 overlay smoke,至少验证虚线框开关
分栏 拖块到另一个块左 / 右,辅助线由横线变竖线,松开形成分栏 可用 Hermes editable-test mode 取拖拽基线 本地可先做 drop preview,不要求完整分栏持久化一次到位
转换块 通过块菜单 转换为、快捷键、或 slash 命令转换块类型 owner 态已可打开块菜单并看到 转换为;执行转换可用 Hermes editable-test mode 做最小验证 本地必须验证块菜单中的 转换为 入口与至少 paragraph/headings/list 的转换
复制 / 粘贴 文本或块选中后 cmd/ctrl + C/V,匹配样式为 cmd/ctrl + shift + V 可用 Hermes editable-test mode 取基线 本地需验证纯文本粘贴与块复制的最小路径
缩进 / 取消缩进 tab 缩进成为上一块子元素,shift + tab 取消缩进 可用 Hermes editable-test mode 取基线 本地需验证 list / paragraph 缩进语义与 tree projection 不冲突
文本样式工具条 选中文字出现工具条,支持粗体、斜体、下划线、删除线、行内代码、颜色、链接、页面引用、转换块类型 可用 Hermes editable-test mode 取基线 本地需验证 selection toolbar 出现、按钮视觉与 command dispatch
slash 菜单 输入 / 唤起快捷命令菜单;空行左侧 + 也可创建块 可用 Hermes editable-test mode 取基线 本地需验证 / 菜单、搜索过滤、选择条目插入块

本轮已能在目标页 Hermes 自动化验证的 published 操作:

  • 顶栏搜索:打开搜索 modal,输入 技能,出现 共1条匹配结果
  • 开始编辑:点击后出现 登录以编辑 对话框,文案为“登录后,您才可以编辑该页面,是否继续?”,包含 取消继续
  • 评论:点击后打开右侧评论面板,tab 为 未解决(0),空态为 还没有评论
  • 演示模式:点击后进入 presentation view,隐藏侧栏 / 顶栏,画面只保留大字号内容和演示控件。
  • Good Night:右下角主题按钮切换暗色 token。
  • 正文块 hover:owner 态可在块左侧看到手柄,并可点击 .hover-block-menu 打开块菜单;上 / 下插入块等写入路径按 wolai-aline 的 Hermes editable-test mode 验收。

因此,后续 3000 的主编辑器验收不能只做“截图像”。每个主编辑器改动都必须绑定一个可执行操作:

  • 如果是 published 态能力,必须先在 Wolai published 目标页执行同类操作,再在 3000 执行同类操作。
  • 如果是 owner/edit 态能力,必须先通过 wolai-aline 流程在 Wolai 目标页执行同类操作,再在 3000 执行同类操作。
  • 如果是 owner/edit 写入能力,当前 Hermes 测试页允许最小编辑验证;其他 Wolai 页面写入必须先取得沙盒页 URL 与明确授权。
  • 如果动作是在当前 Hermes 测试页做最小编辑验证,例如输入测试文本、创建临时测试块、验证 slash / toolbar / block menu / 快捷键,可按 Hermes editable-test mode 执行并记录前后证据;删除、移动、归档、发布、评论、改权限或批量修改既有非测试内容仍必须在动作发生前单独确认。

3. 当前代码落点

3.1 工作区壳与页面树

相关入口:

  • /mnt/Data1T/mnote/wolai-frontend/src/app/(app)/layout.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/components/app-layout-shell.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/lib/server/sidebar-data.ts
  • /mnt/Data1T/mnote/wolai-frontend/src/hooks/use-sidebar-data.ts
  • /mnt/Data1T/mnote/wolai-frontend/src/lib/tree-stream/use-sidebar-tree-stream.ts
  • /mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/sidebar.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/tree-shell-surface.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/tree-shell-host.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/tree-shell-dom-host.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/lib/tree-projection.ts

判断:

  • Sidebar 外壳和 tree-shell-* 是页面树像素复刻的主战场。
  • tree-shell-dom-host 承担当前树行渲染与本地展开/选中/拖拽反馈,不应再回到旧 React 树渲染器上做长期改造。
  • tree-projection 是页面树 UI 的直接 projection 输入,不应在 UI 层重新推导排序、层级或合法性。

3.2 文档页与主编辑器

相关入口:

  • /mnt/Data1T/mnote/wolai-frontend/src/app/(app)/documents/[id]/page.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/lib/documents/page-aggregate-loader.ts
  • /mnt/Data1T/mnote/wolai-frontend/src/lib/documents/page-aggregate-builder.ts
  • /mnt/Data1T/mnote/wolai-frontend/src/components/editor/document-shell.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/components/editor/document-content.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/components/editor/document-read-view.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/components/editor/leptos-tiptap-island-editor-host.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/lib/documents/page-option-semantics.ts

判断:

  • document-content.tsx 决定 Wolai 页面顶部留白、标题、正文容器、页面元信息、右侧 inspector 和 fallback banner。
  • document-read-view.tsx 决定阅读态块样式、任务块、标题层级、附件 / 引用 / 子页面等展示。
  • leptos-tiptap-island-editor-host.tsx 决定编辑态输入 surface、保存、slash、工具条、块菜单和 editor runtime page options 的接缝。
  • page-option-semantics.ts 是页面设置能否真实进入主编辑器运行时的判断边界,不能只改设置面板外观。

3.3 全局视觉 token

相关入口:

  • /mnt/Data1T/mnote/wolai-frontend/src/app/globals.css

判断:

  • 像素复刻必须先固定字体、字号、行高、颜色、圆角、hover/active token。
  • 当前全局字体口径有冲突:前面偏 Wolai 系统字体,后面 html 又偏 Inter。若不先收口字体栈,后续所有标题宽度、行高、树行密度都会偏。

4. Wolai 视觉目标合同

4.1 字体与基础排版

目标字体栈:

  • 优先中文系统字体:PingFang SCNoto Sans CJK SCMicrosoft YaHei UI
  • 英文字体跟随系统 sans-serif,不单独强行使用 Inter 作为全局主字体。

目标字号与行高:

区域 字号 行高 字重
页面主标题 34px 44px 600
首页 / 帮助页大分组标题 28px 36px 600
次级分组标题 18px 26px 600
正文基础文字 16px 24px 400
左侧树条目 14px 24px 400
顶栏文字按钮 14px 21px 400
搜索框文字 14px 22px 400

目标颜色:

语义 颜色
主标题 rgb(30, 30, 30)
正文 rgba(0, 0, 0, 0.85)
次级文字 rgba(0, 0, 0, 0.65)
弱提示 rgba(0, 0, 0, 0.35)
左侧背景 rgb(245, 245, 245)
选中强调文字 rgb(207, 86, 89)
选中强调背景 rgba(207, 86, 89, 0.15)
顶栏 hover 背景 rgb(245, 245, 245)

4.2 左侧页面树

Wolai 目标特征:

  • 左侧栏宽度约 248px - 260px,浅灰底。
  • 顶部空间名行高度约 40px,头像为 28px 左右方形圆角块。
  • 顶部快捷图标横排,图标弱色,hover 只加浅灰底。
  • 搜索框尺寸约 236px x 32px,圆角 4px,内边距约 5px 32px 5px 12px
  • 树行高度约 32px,内容行内 icon / arrow / title 对齐。
  • 当前项使用红字 + 淡红底,背景覆盖整行可点击区域。
  • 未选中 hover 使用同一红色体系,但透明度更轻。
  • 缩进按层级稳定递增,不靠文本空格。
  • 滚动条细、贴右侧、弱灰色,不抢视觉。
  • 底部垃圾桶 / 模板中心固定在侧栏底部,边界线轻。

当前 mnote 允许保留:

  • 我的页面 / Explorer 双模式。
  • 文件树作为创新入口。
  • AI / Graph / 文件等自有入口。

但这些创新必须满足:

  • 视觉密度服从 Wolai 左侧栏。
  • 选中态和 hover 态与页面树统一。
  • 不因为多了文件树而破坏 Wolai 的 32px 行节奏。

4.3 顶部导航与页面操作区

Wolai 目标特征:

  • 顶栏高度约 40px
  • 左侧是菜单按钮 + breadcrumb。
  • breadcrumb 使用图标 / 文本 / 分隔符,字号 14px,颜色弱。
  • 右侧按钮是弱文本 / 图标按钮,padding 约 2px 7px,圆角 3px
  • owner 态可见:公开状态、收藏、演示、评论、关系、邀请、历史、更多。
  • published 态可见:演示模式、搜索、开始编辑、评论、复制、开始使用 wolai。
  • 顶栏 hover 不用重色按钮,只加浅灰底。

mnote 当前差距:

  • 顶栏右侧已经有 Public、收藏、历史、AI、搜索、更多,但与 Wolai owner 态的 icon 序列和视觉轻重不同。
  • published 视角与 owner 视角没有明确组件分型。
  • breadcrumb 与页面内容标题之间的垂直节奏还需要更接近 Wolai。

4.4 主文档画布

Wolai 目标特征:

  • 主内容列在大屏中不贴左,普通文档正文列宽约 760px
  • 登录态 Hermes 页面首屏标题大约从 y=118px 开始。
  • 标题为 34px / 44px / 600,颜色接近 rgb(30,30,30)
  • 标题下方正文块紧跟,不默认显示额外元信息行和横向分割线。
  • 普通正文块使用 16px / 24px
  • 任务块 checkbox 轻边框,小尺寸,和文本基线对齐。
  • 空白区域非常克制,不用额外卡片、阴影或说明文案。

mnote 当前差距:

  • 当前本地文档页标题偏靠左且偏低,内容列与真实 Wolai 相比没有稳定对齐。
  • 当前显示“个人空间 / 工作区首页”元信息和横向分割线,这不是 Wolai 普通文档页默认观感。
  • 历史上首屏正文首块曾是“打开当前页面”链接;task130 之后这条差异已收口,当前重点转向主编辑区密度、块 hover 和 toolbar 细节。
  • 右下角绿色 AI 浮动按钮比 Wolai 更重,真实 Wolai 是更轻的 AI 方形入口和问号入口。

4.5 主编辑器块级体验

Wolai / Notion-like 目标:

  • slash 是主编辑入口之一,菜单跟随 caret。
  • 选中文本才出现浮动工具条。
  • hover 块时只露出左侧手柄,不自动弹菜单。
  • 点击左侧手柄才出现块菜单。
  • 块菜单核心动作是 turn into / duplicate / delete / drag
  • turn into 同时存在于文本工具条语境和块菜单语境,但命令上下文不同。
  • 块 identity 由 Rust EditorBlock.block_id 持有;Tiptap UniqueID 只作为浏览器 runtime 辅助。
  • 页面引用、块引用、嵌入默认位置最终必须回到 Page Aggregate / Rust artifact 边界。

4.5.1 hover 上 / 下插入块

用户补充的登录态截图显示,Wolai 的块 hover 体验还有一个非常关键的细节:当鼠标停在块左侧手柄区域时,当前块行会出现很轻的淡红背景,手柄上方和下方分别出现一条短横线;继续 hover 短横线时,短横线变成 +,并显示黑色 tooltip

  • 在上方插入块,快捷键提示为 Esc, a
  • 在下方插入块,快捷键提示为 Esc, b

这个交互不是装饰性按钮,而是 Wolai 块编辑器的“块级插入光标”。它要和块选中、拖拽手柄、块菜单、slash 菜单、快捷键一起设计,不能只在正文左侧放一个常驻加号。

当前仓库已有可复用参考:

  • /mnt/Data1T/mnote/wolai-frontend/src/components/editor/blocknote-editor.tsx 中,旧 BlockNoteView 通过 SideMenuController 注入自定义 CustomSideMenu
  • /mnt/Data1T/mnote/wolai-frontend/src/components/editor/menus/CustomSideMenu.tsx 中,WolaiDragHandleWithInsert 已实现上方插入、下方插入、手柄菜单、菜单冻结、空段落加号打开 slash、截图失焦状态重置。
  • /mnt/Data1T/mnote/wolai-frontend/src/components/editor/leptos-tiptap-inline-editor-host.tsx 当前已有较简化的块手柄和菜单,但没有复刻上 / 下短横线插入态。
  • /mnt/Data1T/mnote/rust/spikes/leptos-tiptap-spike/src/lib.rs 已有 leptos/tiptap 手柄雏形,但当前样式偏重,并且 insert_top_level_paragraph_after_html 只支持 after 插入。

旧 BlockNote 实现中最值得迁移的机制:

  • 插入控件不是放在块容器上下边界,而是围绕手柄中心点计算位置:上方插入、手柄、下方插入三者垂直对齐。
  • 非 hover 状态显示 12px 左右短横线,hover 状态切换为 Plus 图标。
  • 插入按钮尺寸约 16px,手柄按钮约 22px,按钮之间保持小间距,避免插入按钮和拖拽手柄互相遮挡 pointer event。
  • hoverArea 要比按钮视觉范围更大,避免鼠标从手柄移到插入按钮时控件闪烁。
  • 手柄菜单打开时需要冻结 hover 状态,否则菜单会因鼠标离开块行而消失。
  • 空段落的中心 + 点击应等同打开 slash 菜单,而不是直接创建第二个空段落。
  • 截图、窗口失焦、页面隐藏时要重置 hover / frozen 状态,避免手柄卡住或消失。
  • 思维导图、在线表格、附件这类高块或内部接管鼠标事件的块,需要允许常驻或更稳定的插入控件显示策略。

迁移到 leptos-tiptap 时,目标行为如下:

  • hover 普通块:左侧只显示三段控件,上短横线 / 拖拽手柄 / 下短横线;不自动打开块菜单。
  • hover 上短横线:短横线变 +tooltip 显示 在上方插入块Esc, a
  • hover 下短横线:短横线变 +tooltip 显示 在下方插入块Esc, b
  • 点击上方 +:在当前块前插入空段落,焦点进入新段落。
  • 点击下方 +:在当前块后插入空段落,焦点进入新段落。
  • Esc 进入块选择 / 块聚焦状态后,按 a 执行 before 插入,按 b 执行 after 插入。
  • 点击拖拽手柄才打开块菜单;拖拽手柄本身不和上 / 下插入按钮抢 hover。

实现边界:

  • leptos-tiptap 需要补齐 before / after 两个编辑器命令;不能继续只有 after HTML 插入。
  • 第一阶段可以先在 runtime 内插入空段落并保存正文,但正式命令口径应回到 Page Aggregate / Rust editor block model,例如 page.body.insertBlockBefore / page.body.insertBlockAfter 或等价 EditorCommand::InsertBlock { position: Before | After }
  • UI 层可以持有当前 hover block、active block、tooltip、menu open 这些临时状态,但不能把插入后的块 id 只存在前端临时结构里。
  • 视觉上应优先复刻 Wolai:轻灰短横线、浅灰 hover 背景、黑色小 tooltip、淡红块 hover 底色;不要沿用 spike 中 32px、大圆角、重阴影、绿色 accent 的手柄样式。

首轮不追求:

  • 完整协作光标。
  • 完整评论系统。
  • 完整表格编辑体验。
  • 完整图片 / 附件上传链。
  • 完整权限和发布链路。
  • 完整全局搜索索引。

4.6 操作态菜单与浮层

真实 Wolai 的体验不能只看静态首屏,必须把操作后出现的浮层也纳入复刻合同。

4.6.1 页面树 owner 态菜单

用户提供的登录态截图显示,页面树当前页 Hermes 的管理菜单为白色浮层,宽约 220px,圆角和阴影都很轻,菜单项按语义分组:

  • 打开位置:在右侧边栏打开,带快捷键提示。
  • 页面组织:移动到...嵌入到...
  • 引用复制:复制访问链接复制页面引用链接复制页面ID
  • 页面副本:拷贝副本
  • 危险或编辑动作:重命名删除

这说明页面树行不只是导航节点,还承载页面操作入口。mnote 复刻时必须把这些动作映射到正式命令:

  • 在右侧边栏打开UI state + route / side panel state。
  • 移动到...tree.subtree.move
  • 嵌入到...tree.node.embed 或 Page Aggregate embed plan。
  • 复制页面引用链接:生成 page reference artifact,不应只复制 URL。
  • 重命名page.head.updateTitle,并同步 tree projection。
  • 删除:必须走归档 / 删除确认链,不能前端直接移除节点。

首轮可以先复刻菜单壳、分组、hover、禁用态和快捷键提示;真实移动、嵌入、删除等高风险动作按后续命令合同逐步接入。

4.6.2 搜索弹层

公开页搜索和帮助中心搜索都使用居中 modal overlay

  • 背景整体变暗,侧栏和正文保持原位但失焦。
  • 搜索框宽约 680px,高约 56px,白底,圆角轻,阴影明显但不厚重。
  • 输入后出现选项行:仅匹配标题精确匹配页面内搜索
  • 结果区显示匹配数量和快捷键说明:Ctrl + Enter 新窗口打开 / Alt + Enter 右侧边栏打开
  • 结果行左侧是页面 / 块图标,中间是标题与命中摘要,命中词使用红色高亮,右侧显示所在页面或空间。

mnote 需要把搜索拆成两层:

  • 左侧栏 快速筛选页面:只过滤当前页面树,结果直接替换树列表。
  • 顶栏搜索 modal:跨页面 / 页面内搜索入口,支持结果列表、快捷键提示、打开方式提示。

首轮可以用本地 projection / 当前页面块快照生成结果,不必先接全局索引;但视觉结构、选项行和打开方式提示应先复刻。

4.6.3 published 态操作

真实 published 态存在几类弱操作入口:

  • 演示模式:点击后隐藏侧栏和顶栏,画布变成大字号演示页,只保留主题切换入口。
  • 开始编辑:未登录时弹出“登录以编辑”确认框,红色主按钮为继续,取消为弱按钮。
  • 评论:右侧滑出评论面板,顶部有 未解决(0) tab、筛选下拉、关闭按钮,空态居中。
  • Good Night:右下角主题按钮直接切换暗色主题,暗色主题不重排页面,只替换 token。

mnote 首轮不必做完整发布权限,但应该保留这套状态分型:

  • owner 编辑态。
  • published 阅读态。
  • presentation 演示态。
  • comment side panel。
  • light / dark token 切换。

这些状态大多是 UI state,但 开始编辑 是否可用、评论权限、发布状态必须来自页面权限或发布 projection,不应在前端硬猜。

4.7 帮助中心页的内在逻辑

https://www.wolai.com/wolai/xhqeop8UHpVTMUSVmgz8nq 不是普通内容页,它展示了 Wolai 页面系统的内在组织方式。

观察结论:

  • 左侧页面树是帮助主题的完整目录,根页面下挂大量子页面,既是导航也是信息架构。
  • 正文入口页不是自由排版海报,而是由页面链接、分组标题、四列目录块、子页面引用组成的“文档门户”。
  • 快速上手 / 常见问题 / 视频教程 / 使用技巧短视频 是高频入口。
  • “让我们先掌握一些基础”下的四列目录把页面按能力分组:基础操作、基础块类型、进阶块类型、媒体与文件。
  • 目录项本质上是页面引用 / 页面链接,不是普通文本。
  • 搜索可以跨整个帮助中心返回页面和块级结果,命中词红色高亮。
  • 搜索结果可以按快捷键在新窗口或右侧边栏打开,说明“右侧边栏打开”是 Wolai 页面导航模型的一等入口。

更重要的是,帮助中心中的“块引用”页直接定义了编辑器的语义模型:

  • 行内块引用:在文字中间引用另一个块,底部有圆点虚线,不能直接编辑,点击跳转原始出处。
  • 嵌入块引用:以独立块引用另一个块,左侧有圆点虚线,可以直接查看或部分编辑,但不能删除被引用块本身。
  • 页面引用:当对象是页面时,菜单从“复制块引用链接”变为“复制页面引用链接”。
  • 行内页面引用:在文本内显示页面标题。
  • 嵌入页面引用:独立引用块显示页面图标和标题。
  • 复制粘贴路径:块菜单复制引用链接,再粘贴生成引用。
  • 快捷键路径:esc 选中块,H 复制行内块引用链接,Q 复制嵌入块引用链接。
  • 嵌入到路径:cmd/alt + shift + G 打开“嵌入到”弹窗,搜索目标页面,把块嵌入到目标页面。
  • 当前页面位置快速引用:编辑时输入 [[ 搜索页面,添加页面行内引用。
  • 右侧边栏拖拽引用:从右侧边栏拖拽产生引用。
  • 引用预览和别名:悬浮行内块引用出现预览,小窗顶部可以设置别名,别名末尾显示箭头。

因此,mnote 不应把“引用”当成一个简单链接样式。它至少需要在 Page Aggregate / editor block model 中区分:

  • inline_page_reference
  • inline_block_reference
  • embedded_page_reference
  • embedded_block_reference
  • reference_alias
  • reference_preview
  • reference_source_block_id
  • reference_target_page_id

首轮实现可以降级,但语义模型不能降级成普通 URL。


5. 复刻范围分级

5.1 P0:先做像素基线

P0 只做最影响首屏观感的部分:

  • 全局字体栈与基础字号行高收口。
  • Sidebar 宽度、背景、顶部栏、树行高度、选中态、hover 态。
  • 顶栏高度、breadcrumb、右侧动作按钮轻量化。
  • 文档标题位置、字号、行高、正文列宽。
  • 默认隐藏普通文档页中的额外元信息行和分割线。
  • 右下角浮动入口减重。
  • 1392 x 1213 视口下对齐真实 Wolai 截图。

5.2 P1:补齐高频交互体验

P1 做用户会立刻感知的交互:

  • 页面树展开 / 折叠动画和 hover action。
  • 当前页祖先链展开和选中态保持。
  • 搜索框视觉与本地过滤体验。
  • 树行上下文菜单的视觉壳和核心动作入口。
  • 顶栏搜索 modal 的选项行、结果行、命中高亮和快捷键提示。
  • 评论侧栏、登录编辑确认框、演示模式的基础状态切换。
  • 文档页进入编辑后,slash、浮动工具条、左侧手柄、上 / 下插入块、块菜单的基础可用体验。
  • 页面标题编辑后,标题 / breadcrumb / sidebar / page tree / file tree 保持一致。

5.3 P2:接近 Wolai 的产品完整感

P2 做复杂但可逐步推进的部分:

  • 拖拽排序与 drop feedback。
  • page reference / block reference 的正式插入体验。
  • [[ 页面引用搜索、嵌入到... 弹窗、右侧边栏打开 / 拖拽引用。
  • 引用预览和别名。
  • 右侧评论、历史、关系图入口的真实面板。
  • published / owner / edit 三态顶栏完整切换。
  • 页面设置项与 editor runtime 的完整联动。
  • 帮助中心类多列目录块的静态展示和后续编辑支持。

5.4 明确降级项

以下功能可以先只做视觉入口或最小实现:

  • 评论协作。
  • 权限分享。
  • 发布与侵权投诉链路。
  • 全局搜索索引。
  • 完整演示模式。
  • 完整夜间主题。
  • 完整表格、图表、数据库。
  • 完整文件上传和媒体块管理。
  • 完整引用别名编辑器和跨页面引用预览缓存。

6. 单一真源边界

6.1 可以留在前端展示层的内容

以下内容允许作为前端展示或临时 UI state:

  • 色彩、字号、行高、间距、圆角、阴影。
  • Sidebar 宽度与布局。
  • 树行 hover、focus、临时 selection、drag preview。
  • 顶栏按钮排列与 hover。
  • 文档画布宽度、标题留白、正文显示密度。
  • slash 菜单开合状态。
  • 浮动工具条开合状态。
  • 块手柄 hover 状态。
  • 右下角浮动入口显示状态。

6.2 必须回到 Rust / projection / Page Aggregate 的内容

以下内容不能只在前端复刻:

  • 页面树真实层级。
  • 排序真相。
  • 当前页 active path。
  • 拖拽是否合法。
  • 新建、重命名、移动、归档、恢复结果。
  • 页面标题与 breadcrumb / sidebar / file tree 的一致性。
  • 正文保存与 conflict key。
  • 页面设置对 editor runtime 的正式语义。
  • page reference / block reference / embed 默认位置。
  • 引用类型、引用源、引用目标、引用别名、引用预览数据。
  • AI 写入标题、正文、页面设置的语义边界。

原则:

UI 可以复刻 Wolai,事实源不能复刻成第二份前端状态。

6.3 命令口径

页面树动作继续沿 tree.*

  • tree.node.create
  • tree.node.rename
  • tree.subtree.move
  • tree.node.archive
  • tree.node.restore
  • tree.node.embed

页面动作继续沿 page.*

  • page.head.updateTitle
  • page.layout.updateOptions
  • page.body.save

兼容 documents.* 可以继续存在,但不应作为新增体验的正式命令面。


7. 推荐实施路线

Phase A:建立 Wolai 视觉 token

目标:

先让字体、字号、行高、颜色和基础密度可被统一复用。

主要文件:

  • /mnt/Data1T/mnote/wolai-frontend/src/app/globals.css

工作内容:

  • 统一全局字体栈,避免 Inter 覆盖中文系统字体。
  • 建立 Wolai-like token--wolai-sidebar-bg--wolai-active-fg--wolai-active-bg--wolai-text-primary--wolai-text-secondary
  • 固定标题、正文、sidebar、topbar 的字号 / 行高。
  • 用 token 替代散落硬编码颜色。

验收:

  • local-3000 截图中标题、树行和顶栏文字宽度明显接近真实 Wolai。
  • 中文字体不再出现 Inter 优先导致的字宽偏差。

Phase B:复刻 Sidebar / 页面树首屏

目标:

让左侧页面树在密度、选中态、hover、滚动条、底部入口上接近 Wolai。

主要文件:

  • /mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/sidebar.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/tree-shell-surface.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/tree-shell-host.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/components/sidebar/tree-shell-dom-host.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/lib/tree-projection.ts

工作内容:

  • 固定侧栏宽度和背景。
  • 调整 workspace header 高度、头像尺寸、空间名截断方式。
  • 调整快捷图标行尺寸与 hover。
  • 调整页面树行高到 32px 附近。
  • 当前页改为 Wolai 红字 + 淡红底。
  • hover 态与 active 态同色系但层级更轻。
  • 缩进只由层级和 icon slot 决定。
  • 底部垃圾桶 / 模板中心与 Wolai 对齐,同时保留 mnote 自有入口时不破坏密度。
  • Explorer 作为 mnote 创新保留,但视觉上降噪,避免抢过“我的页面”主路径。

验收:

  • 对照用户提供的登录态截图,Hermes 选中行的颜色、行高、左侧缩进、滚动条位置接近 Wolai。
  • 页面树长列表滚动时不出现行高抖动。
  • 文件树创新入口仍可访问。

Phase C:复刻顶栏与 breadcrumb

目标:

让顶栏在 owner / published 两种状态下都接近 Wolai 的轻量工具条。

主要文件:

  • /mnt/Data1T/mnote/wolai-frontend/src/components/app-layout-shell.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/components/editor/document-content.tsx

工作内容:

  • 固定顶栏高度约 40px。
  • breadcrumb 文本、图标、分隔符弱化。
  • 右侧按钮统一使用轻量 icon/text button。
  • 区分 owner 态和 published 态的按钮组合。
  • 公开状态 pill 对齐 Wolai 的“全网公开 / Public”视觉。
  • 顶栏 hover 只加浅灰底,不使用重边框或大面积按钮。

验收:

  • 登录态参考图中的顶栏图标序列能在 mnote 中找到对应视觉位置。
  • published 公共页参考图中的“演示模式 / 搜索 / 开始编辑 / 评论 / 复制 / 开始使用 wolai”可先作为视觉分型,不要求一次接齐功能。

Phase D:复刻文档画布与阅读态

目标:

让普通文档页首屏像 Wolai,而不是像调试页或二级详情页。

主要文件:

  • /mnt/Data1T/mnote/wolai-frontend/src/components/editor/document-content.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/components/editor/document-read-view.tsx
  • /mnt/Data1T/mnote/wolai-frontend/src/lib/documents/page-option-semantics.ts

工作内容:

  • 标题使用 34px / 44px / 600
  • 普通正文列宽约 760px。
  • 调整首屏 top padding,使标题起点接近 Wolai。
  • 默认隐藏普通文档页的“个人空间 / 工作区首页”元信息行和横向分割线。
  • 保留页面设置控制,但把“显示元信息 / 显示结构”这类调试或增强项作为显式选项,不默认露出。
  • 阅读态任务块、段落、标题、列表、引用、代码块按 Wolai 行高和颜色重调。
  • 右下角 AI / 帮助入口减重,避免绿色大按钮抢主编辑区视觉。

验收:

  • Hermes 类普通文档页首屏只突出标题和正文块。
  • 页面不再默认出现明显不像 Wolai 的横线、meta row 或 debug outline。
  • 阅读态和编辑态在基础排版上不出现明显跳动。

Phase E:复刻主编辑器高频块交互

目标:

leptos-tiptap 的输入体验从“能编辑”推进到“像 Wolai 的块编辑器”。

主要文件:

  • /mnt/Data1T/mnote/wolai-frontend/src/components/editor/leptos-tiptap-island-editor-host.tsx
  • /mnt/Data1T/mnote/rust/crates/core-protocol/src/editor/model.rs
  • /mnt/Data1T/mnote/rust/crates/bridge-runtime/
  • /mnt/Data1T/mnote/design/05-editor-mainline/reference-code/tiptap-notion-like-registry/

工作内容:

  • slash 菜单锚定 caret。
  • selection 存在时显示浮动工具条。
  • hover 块只显示左侧手柄区,上方和下方短横线在 hover 时变成插入 +
  • 点击上方 / 下方插入控件分别创建 before / after 空段落,并把焦点移动到新段落。
  • 支持 Esc, aEsc, b 的块级插入快捷键。
  • 点击手柄打开块菜单。
  • 块菜单至少提供 turn into / duplicate / delete 的视觉与基础命令入口。
  • turn into 不直接绕过 Rust block model。
  • Tiptap UniqueID 只用于 runtime 辅助,最终块 id 对齐 Rust EditorBlock.block_id
  • 页面引用 / 块引用可先做最小插入体验,复杂搜索和预览后置。

验收:

  • 用户能在主编辑区通过 slash 插入常见块。
  • 用户选中文本时看到 Wolai-like 浮动工具条。
  • 用户 hover 块时不会被重工具条打扰,并能看到 Wolai-like 上 / 下插入短横线。
  • 用户可以通过鼠标或 Esc, a / Esc, b 在当前块前后插入空段落。
  • 块操作不会制造前端临时 id 作为持久化真相。

Phase F:用 Page Aggregate 守住一致性

目标:

复刻体验时不牺牲单一真源。

主要文件:

  • /mnt/Data1T/mnote/wolai-frontend/src/lib/documents/page-aggregate-loader.ts
  • /mnt/Data1T/mnote/wolai-frontend/src/lib/documents/page-aggregate-builder.ts
  • /mnt/Data1T/mnote/wolai-frontend/src/lib/documents/page-command-client.ts
  • /mnt/Data1T/mnote/wolai-frontend/src/app/api/documents/page/route.ts
  • /mnt/Data1T/mnote/rust/crates/core-protocol/
  • /mnt/Data1T/mnote/rust/crates/bridge-runtime/
  • /mnt/Data1T/mnote/rust/crates/mnote-web/

工作内容:

  • 新增视觉状态时,先判断它是否只是 UI state。
  • 新增页面字段时,必须归入 page_identity / page_head / page_layout / page_body / page_tree
  • 标题变更必须继续让页头、breadcrumb、sidebar、page tree、file tree 同步。
  • 正文保存继续走 page.body.save
  • 页面设置继续按 page-option-semantics 判断是否进入 island runtime。
  • 页面树动作继续走 tree.*,不新增 documents.* 长期动作。

验收:

  • 页面重命名后,所有消费者保持一致。
  • 切页、刷新、实时更新不会把 UI 压回旧标题。
  • 视觉复刻代码里没有新增第二套树排序或页面标题真相。

Phase G:截图回归与像素验收

目标:

把“像 Wolai”变成可复查、可操作、可重复的截图基线。

建议新增或复用:

  • /mnt/Data1T/mnote/scripts/task*-smoke.js
  • /mnt/Data1T/mnote/tmp/wolai-compare/

验收视口:

  • 桌面:1392 x 1213
  • 宽屏:1440 x 900
  • 窄屏:390 x 844

截图基线:

  • 真实 Wolai 登录态长页面树。
  • 真实 Wolai Hermes 普通文档页。
  • 当前 mnote 同类页面。
  • mnote 文件树创新入口展开态。

验收方式:

  • 每次验收必须按 wolai-aline skill 形成差异矩阵,并附 Wolai 截图、本地截图、动作链、DOM/ARIA 线索和剩余差异。
  • 浏览器取证必须由 subagent 执行;主线程必须复核截图,不能只接受 subagent 文本结论。
  • published 阅读态、owner 登录态、editable-test mode 都只表示取证上下文,不再作为三套独立测试方案维护。
  • 先用 Wolai 基线写出本地 RED smoke,再实现,再跑本地 smoke,再派 subagent 复测。
  • 若截图肉眼可见差异但 smoke 未捕获,先增强 smoke 或 checklist 断言,再继续实现。
  • 后续可加入截图 diff,但不能用截图 diff 替代真实交互烟测。
  • 每次改 Sidebar、topbar、document canvas、editor runtime 后都要重新截首屏,并同步更新连续 checklist 的状态。
  • 连续执行清单见 /mnt/Data1T/mnote/design/05-editor-mainline/process/5-9-wolai-aline-continuous-checklist-v1.md

owner 态交互验收清单:

  • 自动化打开 https://www.wolai.com/liaibo/ikFSSM1a4GgvmHBYFCNfVd 后确认进入登录 owner 态,而不是 published 态。
  • hover 页面树当前项 Hermes,确认 hover action 可见。
  • 打开页面树菜单,截图菜单项和分组。
  • hover 正文块 事实上,确认块背景、左侧手柄、上短横线、下短横线可见。
  • hover 上短横线,确认 tooltip 为 在上方插入块 / Esc, a
  • hover 下短横线,确认 tooltip 为 在下方插入块 / Esc, b
  • 打开块菜单,截图 AI 助理 / 转换为 / 拷贝副本 / 删除 / 复制链接 / 移动/嵌入到... / 块历史... / 评论 / 颜色 / 文字居中 / 文字翻译 / 生成海报 等入口。
  • 3000 执行同类操作并保存同视口截图。
  • 验收报告中列出 Wolai 截图、本地截图、差异结论和不可测项。

8. 验证命令建议

前端运行:

cd /mnt/Data1T/mnote/wolai-frontend && pnpm dev

前端相关测试:

cd /mnt/Data1T/mnote/wolai-frontend && pnpm test src/components/sidebar/tree-shell-host.test.tsx src/components/sidebar/tree-shell-surface.test.tsx src/components/editor/document-content.test.ts src/components/editor/leptos-tiptap-island-editor-host.test.tsx

projection / aggregate 测试:

cd /mnt/Data1T/mnote/wolai-frontend && pnpm test src/lib/tree-projection.test.ts src/lib/tree-projection-contract.test.ts src/lib/documents/page-aggregate-builder.test.ts src/lib/documents/tree-command-client.test.ts

Rust 侧测试:

cd /mnt/Data1T/mnote && cargo test -p mnote-web workspace_shell
cd /mnt/Data1T/mnote && cargo test -p bridge-runtime

浏览器验收:

  • 先按 wolai-aline skill 派 subagent 打开真实 Wolai 参考页和 http://127.0.0.1:3000/
  • 统一视口至少覆盖 1392 x 1213;涉及响应式时补 1440 x 900390 x 844
  • 每个小任务都要保存 Wolai 与本地截图,并记录入口、关闭路径、URL 变化、控件形态、控件状态、快捷键、hover/active、DOM/ARIA 线索。
  • 主线程复核截图后,把结论写入差异矩阵;发现差异先补 smoke,再改实现。
  • 对照范围至少包含左侧栏宽度、树行高度、选中态、正文标题位置、顶栏按钮密度、搜索 modal、块 hover/插入入口、右下角浮动入口。

9. 禁止事项

为避免这条线跑偏,后续实现中禁止:

  • 不把 BlockNote 写回默认主编辑器。
  • 不把 Next App Router 恢复成 3000 主入口。
  • 不在 UI 层重新拼第二份页面树、排序、标题或正文真相。
  • 不把 compat route 或 debug shell 当正式主链。
  • 不为了像素复刻绕开 tree.* / page.* 命令族。
  • 不把 Tiptap runtime 临时 id 倒灌成 Rust 持久化块 id。
  • 不把页面设置做成“保存了字段但 editor runtime 不消费”的假功能。
  • 不为了复刻 Wolai 顶栏而提前接入真实权限 / 分享 / 评论复杂链路。

10. 当前退出标准

这份方案只有在下面条件同时满足后,才能移入 done

  • 3000 首屏在左侧页面树、顶栏、文档画布三块视觉上接近真实 Wolai。
  • 页面树保留 mnote 文件树创新,但不破坏 Wolai 主路径密度。
  • 普通文档页默认不再显得像调试页或二级详情页。
  • leptos-tiptap 主编辑器具备 slash、浮动工具条、左侧手柄、上 / 下插入块、块菜单的基础 Wolai-like 行为。
  • 标题 / 正文 / 页面设置 / 页面树仍服从 Page Aggregate 与 tree-first graph kernel 主线。
  • 相关 smoke / 单测 / 截图验收有记录。
  • 连续 checklist 中 P0/P1 任务均有 Wolai 基线、本地 RED/GREEN smoke、subagent 复测截图和主线程复核结论。

当前结论:

下一步应先做 P0 像素基线和 Sidebar / 文档画布首屏对齐,再推进编辑器块级交互。功能复杂项可以降级,但页面树和主编辑器的视觉节奏必须优先向真实 Wolai 收口。