# 5 [recycle] mnote 编辑器主线重置定稿 v2 > 更新时间:2026-04-18 > > 这份文档用于替代此前偏向“Rust-native 全自研编辑器”的主线口径。 > > 本文结论只解决两件事: > 1. 后续编辑器主线到底以谁为基准 > 2. 最近 git 历史里,哪些改动不该整包回滚,哪些应该局部撤回或降级 ## 1. 结论先行 当前应冻结为下面这条主线: > **后续编辑器的体验 benchmark 以 `Tiptap` 官方能力模型为准,Leptos 接入层以 `leptos-tiptap` 为主参考;Rust 侧继续掌握 kernel / command / projection / AI / CLI 语义主导权。** 同时固定三条边界: - `edita-core` 不再被视为主线 benchmark,只保留为 Rust-native headless block editor 的设计参考。 - `kode`、`blocks` 只作为局部参考层,不作为最终交付体验 benchmark。 - `mnote-next` 只作为内部样本和反例来源,不作为“已经验证过的主参考实现”。 一句话收口: > **我们不再把“做出一个 Rust 原生最小编辑器”当成交付目标,而是把“做出接近 Tiptap / Wolai 的实际编辑体验,同时让 Rust 继续掌握底层语义”当成交付目标。** --- ## 2. 为什么要重置口径 此前路线逐渐偏成了下面这个结构: - 用 `AI-first / CLI-first / Rust-native` 作为最高目标 - 把“最小可写闭环”当成阶段验收 - 结果自然滑向 `runtime shell + textarea + command button + debug panel` 这条路线的问题不在于“做错了”,而在于: - 它更像内核验证路线,不像产品交付路线 - 它会天然高估 `edita-core` 这类薄内核的完成度 - 它会天然低估 `Tiptap` 在 selection、IME、输入规则、历史、富文本细节上的工程积累 从当前代码看,偏移已经非常具体: - 默认文档页已经能被切到 `iframe` 挂载的 `mnote-web /document` 壳 - [page.tsx](/mnt/Data1T/mnote/wolai-frontend/src/app/(app)/documents/[id]/page.tsx) - [mnote-web-document-shell-host.tsx](/mnt/Data1T/mnote/wolai-frontend/src/app/(app)/documents/[id]/mnote-web-document-shell-host.tsx) - Rust `/document` 路由现在是 runtime/debug 壳,不是产品文档页 - [editor.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/editor.rs) - 新 smoke 脚本已经把“看到 `Document Editor Shell` + `textarea[data-block-input-id]`”当成通过标准 - [task103-document-shell-cutover-smoke.js](/mnt/Data1T/mnote/scripts/task103-document-shell-cutover-smoke.js) - [task104-document-runtime-input-smoke.js](/mnt/Data1T/mnote/scripts/task104-document-runtime-input-smoke.js) 这说明问题不是“样式没做完”,而是默认交付口径已经被带偏。 --- ## 3. 新的主线基准 ### 3.1 主 benchmark 主 benchmark 固定为两层: 1. 体验与能力模型:`Tiptap` 2. Leptos 接入层:`leptos-tiptap` 对应的设计含义是: - 需要接近 `Wolai / Notion / Tiptap` 的输入手感、selection、slash、块间过渡和工具栏组织 - 不需要为了“全 Rust”主动放弃成熟编辑器 runtime - Rust 的职责转移到更适合 Rust 的层:kernel truth、command contract、projection、AI/CLI、save pipeline ### 3.2 辅助参考层 这些库继续保留,但口径必须降级: - `edita-core` - 只参考 `Editor / Block / Command` 这种 headless 组织方式 - 不再把它视为可直接对标 `Tiptap` 体验的候选 - `blocks` - 参考文档模型、导入导出、history、diff/merge - 不负责最终交互体验 benchmark - `kode` - 参考 Leptos 下文本/Markdown/WYSIWYG 组织方式 - 适合借鉴局部实现,不适合作为当前最终产品 benchmark - `mnote-next` - 只保留为内部交互样本、历史问题样本 - 不能再作为“因为我们以前做过,所以现在能直接沿着这条线走”的依据 ### 3.3 Rust 侧的正确位置 Rust 仍然是主线,但不是靠“自己重写整套输入 runtime”来体现。 Rust 侧应继续掌握: - 文档树 / 子树 / 边 / projection - 编辑命令合同 - AI 命令合同 - CLI 批处理与自动化 - 存储、save、审计、导入导出 Rust 侧不应优先承担: - 第一阶段的人类编辑交互 runtime - 复杂 selection / IME / 富文本输入细节 - 与成熟浏览器编辑器生态重复造轮子 --- ## 4. 当前代码后的判断 ### 4.1 不建议整包回滚的部分 下面这些改动虽然和编辑器路线有关,但不应整包撤销: - `aa6ee384 feat: 接入 mnote web tree shell 与主页链路整理` - `f1c1bcf0 feat: 收口 tree-first graph 主链与前端测试修复` - `f9a45e89 feat: complete tree shell cutover and regression coverage` 原因很简单: - 这三次提交的主轴是 `tree-first graph kernel`、sidebar/tree shell、projection、stream、transport - 它们不是“文档编辑器主线基准错误”的根因 - 直接整包回滚会误伤已经有效的 tree shell 主链工作 因此: > **不建议回滚最近三次已提交主线 commit。** ### 4.2 应局部回退或降级的部分 真正需要处理的是当前工作区里把 runtime 壳推上默认主链的那一层实验改动。 优先级最高的局部回退对象: - 默认文档页中的 `mnoteWebDocumentShellEnabled` 分支 - [page.tsx](/mnt/Data1T/mnote/wolai-frontend/src/app/(app)/documents/[id]/page.tsx) - `iframe` 挂载壳本身 - [mnote-web-document-shell-host.tsx](/mnt/Data1T/mnote/wolai-frontend/src/app/(app)/documents/[id]/mnote-web-document-shell-host.tsx) - 把 runtime debug 壳当默认验收的 smoke 脚本 - [task103-document-shell-cutover-smoke.js](/mnt/Data1T/mnote/scripts/task103-document-shell-cutover-smoke.js) - [task104-document-runtime-input-smoke.js](/mnt/Data1T/mnote/scripts/task104-document-runtime-input-smoke.js) - [task105-document-runtime-transactions-smoke.js](/mnt/Data1T/mnote/scripts/task105-document-runtime-transactions-smoke.js) - [task106-document-runtime-slash-reference-smoke.js](/mnt/Data1T/mnote/scripts/task106-document-runtime-slash-reference-smoke.js) - [task107-document-runtime-save-smoke.js](/mnt/Data1T/mnote/scripts/task107-document-runtime-save-smoke.js) 这些部分的问题不是“代码质量差”,而是: - 它们把 debug/prototype 壳变成了默认产品路径 - 它们会持续把开发注意力引向 runtime shell polish,而不是真正的页面级编辑体验 因此: > **建议优先局部撤回“默认走 runtime shell”这组未提交改动。** ### 4.3 可保留但必须降级定位的部分 下面这些可以保留,但不能继续被描述成默认主编辑器: - `mnote-web` 的 `/document` 路由 - [editor.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/editor.rs) - 文档 meta/content/save API - [documents.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/documents.rs) - [query_support.rs](/mnt/Data1T/mnote/rust/crates/mnote-web/src/routes/query_support.rs) - 运行时配置里的 document shell 字段 - [runtime-config.ts](/mnt/Data1T/mnote/wolai-frontend/src/lib/runtime-config.ts) 保留条件只有一个: > **它们只能作为 debug / prototype / bridge API 存在,不能再主导默认文档页。** ### 4.4 可继续保留观察的 Rust editor core 尝试 当前未提交的这些底层尝试,不建议直接删除,但也不应被提升为主 benchmark: - [core-protocol/src/editor/mod.rs](/mnt/Data1T/mnote/rust/crates/core-protocol/src/editor/mod.rs) - [mnote-editor-core/src/lib.rs](/mnt/Data1T/mnote/rust/crates/mnote-editor-core/src/lib.rs) 原因: - 它们已经抽出了 `EditorBlockDocument / EditorCommand / CommandExecutor` 这类可复用底层合同 - 这层更像“Rust command/model spike” - 它们比 runtime shell UI 更有保留价值 但当前也要明确: - 它们还不足以支撑 `Tiptap` 级人类编辑体验 - 它们只能服务未来的命令合同、AI pipeline、导入导出和调试转换 - 不能再反向决定默认产品体验 --- ## 5. 后续开发阶段 ### 阶段 A:主链纠偏 目标: - 把默认文档页从 runtime shell 退回产品页主链 - 明确 `runtime shell = debug` 清单: - [x] 取消默认文档页对 `mnote-web document shell iframe` 的优先切换 - [x] 将 `/document` 路由和相关文案重命名为 debug/prototype - [x] 停止用 `task103-107` 这组脚本作为默认文档页主验收 - [ ] 重新把验收标准收口到“是否接近 Wolai/Tiptap 页面体验” ### 阶段 B:Leptos-Tiptap 接入最小闭环 目标: - 用 `leptos-tiptap` 验证真正的 Leptos + Tiptap 组合是否能在当前工程中跑通 清单: - [x] 建一个最小 `leptos-tiptap` 文档页 spike,不接入复杂业务,只验证真实输入体验 - [ ] 打通基础 schema:标题、段落、列表、todo、blockquote、code block - [x] 验证命令触发:slash、toggle heading、toggle list、引用插入 - [ ] 记录 CSR/SSR、构建体积、初始化耗时、输入延迟、保存触发点 补充说明(2026-04-18): - 已新增独立 spike 工程:`/mnt/Data1T/mnote/rust/spikes/leptos-tiptap-spike` - 该 spike 当前目标是先验证真实 Tiptap surface 与基础 schema/命令,不进入默认产品文档页 - 已完成 `cargo +1.89.0 check` 与 `env -u NO_COLOR trunk build --release` - 已通过本地浏览器访问 `http://127.0.0.1:8123/` 验证 CSR 页面可渲染、可输入,并能触发 heading/list/blockquote/code block/slash 引用插入 - 当前 `Todo` 仍是 HTML 占位插入,尚未拿到 `taskList/taskItem` 级真实 schema 语义,因此第二项暂不勾满 - 已记录到的观察值: - CSR:可用 - SSR:未接入 - 构建体积:`js 45K`,`wasm 592K` - 首次页面就绪时间:约 `552ms`(本地 Playwright `networkidle` 口径) - 单字符输入到保存触发点计数变化:约 `26ms` 补充说明(2026-04-19): - `Tiptap` 官方 `Notion-like template` 是 `React + Tiptap Editor + Tiptap UI Components + CLI` 的产品级模板,适合作为后续 UI benchmark,而不是当前 `Leptos` 主线的直接实现路径 - 在当前阶段,最合适的接入时机是:先把 `leptos-tiptap` 的最小输入闭环、基础 schema、保存边界和 Rust kernel 映射稳定住,再单独开一轮模板对标 spike - 这个模板的价值主要在于对标 `slash`、floating toolbar、drag & drop、emoji、mentions、collaboration、AI、context menu 等“产品级编辑体验”,不是替代我们当前的 Rust kernel / projection 主线 ### 阶段 C:Rust kernel 对接 目标: - 让 `Tiptap/leptos-tiptap` 负责编辑 surface - 让 Rust 继续掌握 document truth 清单: - [ ] 确定 Tiptap JSON / HTML / 自定义节点 与 Rust `EditorBlockDocument` 的映射边界 - [ ] 统一 save pipeline,不再维护“runtime 壳专用数据格式” - [ ] page subtree / outline / evidence 继续由 Rust 侧提供 - [ ] AI/CLI 改文档时,优先走 Rust command contract,再映射回编辑器展示 ### 阶段 D:AI-first 产品收口 目标: - 编辑器体验接近 Wolai/Tiptap - 系统语义主导权仍在 Rust/AI/CLI 清单: - [ ] 人类编辑入口只保留高频块能力,不追完整 Notion - [ ] AI 输出优先落到块级命令,而不是直接拼 HTML - [ ] debug 壳只保留给事务诊断、IME 排障、save 链路回归 - [ ] 正式文档页只保留产品级界面,不再暴露 runtime panel --- ## 6. 最终决策 最终固定如下: 1. 编辑器主 benchmark 改为 `Tiptap + leptos-tiptap`。 2. `edita-core` 不再作为主线 benchmark,只保留为 headless 设计参考。 3. 最近三次已提交的 `tree shell / tree-first graph` 主线 commit 不建议整包回滚。 4. 当前工作区里“把 runtime shell 接成默认文档页”的实验改动,建议局部撤回。 5. `mnote-editor-core` 与 `core-protocol/editor` 可以保留为底层 spike,但不得继续主导默认交付路线。 如果后续要继续补文档、排期或拆 checklist,都以本文为准,不再以此前偏向“Rust-native 全自研编辑器”的文档口径为准。