# 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/recycle/scripts/task103-document-shell-cutover-smoke.js)
  - [task104-document-runtime-input-smoke.js](/mnt/Data1T/mnote/recycle/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/recycle/scripts/task103-document-shell-cutover-smoke.js)
  - [task104-document-runtime-input-smoke.js](/mnt/Data1T/mnote/recycle/scripts/task104-document-runtime-input-smoke.js)
  - [task105-document-runtime-transactions-smoke.js](/mnt/Data1T/mnote/recycle/scripts/task105-document-runtime-transactions-smoke.js)
  - [task106-document-runtime-slash-reference-smoke.js](/mnt/Data1T/mnote/recycle/scripts/task106-document-runtime-slash-reference-smoke.js)
  - [task107-document-runtime-save-smoke.js](/mnt/Data1T/mnote/recycle/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 全自研编辑器”的文档口径为准。
