# 5-7 [reference] Wolai 页面树与主编辑器体验复刻方案 v1 > 更新时间:2026-04-30 > > 当前状态:`reference`。本文只保留 Wolai 体验复刻目标和取证基线;持续执行与安全边界以 `08-wolai-aline-test-flow` 和 `wolai-aline` skill 为准。 > **Wolai-aline 执行口径更新(2026-05-21):** 本文只保留体验复刻任务拆解和产品目标。所有 Wolai 对标测试、浏览器取证、编辑权限、安全边界、subagent 使用、截图复核和 smoke 补齐,统一以 `/home/lix/.codex/skills/wolai-aline` 与 `/mnt/Data1T/mnote/design/08-wolai-aline-test-flow/reference/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/done/2-2-local-first-workspace-convex-control-plane-v1.md` > - `/mnt/Data1T/mnote/design/old/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/reference/5-2-tiptap-notion-like-template-adoption-v1.md` > - `/mnt/Data1T/mnote/design/05-editor-mainline/done/5-4-leptos-tiptap-mainline-correction-v1.md` > - `/mnt/Data1T/mnote/design/05-editor-mainline/reference/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` 只作为 `recycle/` 历史参考 / 对照材料,不重新变成默认方向。 - 树、页面结构、标题、正文、页面设置不能在 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/reference/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 SC`、`Noto Sans CJK SC`、`Microsoft 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/recycle/wolai-frontend/src/components/editor/blocknote-editor.tsx` 中,旧 `BlockNoteView` 通过 `SideMenuController` 注入自定义 `CustomSideMenu`。 - `/mnt/Data1T/mnote/recycle/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, a` 和 `Esc, 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. 验证命令建议 前端运行: ```bash cd /mnt/Data1T/mnote/wolai-frontend && pnpm dev ``` 前端相关测试: ```bash 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 测试: ```bash 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 侧测试: ```bash 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 900` 和 `390 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 收口。**