chore: align local-first control plane and editor fixes

- wire SQLite control-plane access/session paths into Rust web local-folder routes

- preserve local Markdown attachment semantics across upload, reload, and secondary-pane resource tabs

- refresh design governance docs, Reasonix task templates, and bug records

- retire root .mcp.json local MCP config
This commit is contained in:
lix-2026
2026-05-23 23:38:42 +08:00
parent 42fb58310c
commit 5f97800489
110 changed files with 5344 additions and 889 deletions
@@ -0,0 +1,438 @@
# 6 [reference] Mindmap Kernel Phase 6leptos-mindmap Projection Editor v1
> 更新时间:2026-05-10
>
> 当前状态:`reference`。本文保留 mindmap Phase 6 总设计;已完成 UI shell reuse 归档到 `design/06-mindmap/done/`,后续新工作需另拆小 checklist。
>
> 当前口径:`leptos-mindmap`
>
> 旧稿归档:
> - `/mnt/Data1T/mnote/recycle/design/06-mindmap/process/6-mindmap-kernel-phase6-projection-editor-v1.rust-native-2026-05-10.md`
>
> 当前主线依据:
> - `/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/03-rust-web/reference/3-rust-web-long-term-architecture-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/reference-code/lx-doc/mind-map`
> - `/mnt/Data1T/mnote/design/05-editor-mainline/reference-code/kmind-plugin`
> - `/mnt/Data1T/mnote/design/05-editor-mainline/reference-code/siyuan-kmind-plugin`
## 1. 文档目的
这份文档重新修正 Mindmap Phase 6 的落地口径。
旧稿把 Phase 6 定义为 `Rust / Leptos 原生 Projection Editor`,并把 `simple-mind-map` 排除在本轮 runtime 主链之外。该口径在长期上最干净,但在当前阶段等同于用 Rust 重写 `lx-doc/mind-map` / `simple-mind-map` 的编辑器和布局引擎,短期会继续产出可验证但不可用的导图纵切。
当前口径改为:
> **leptos-mindmapRust kernel 持有导图事实源与命令语义,`simple-mind-map` / KMind-like runtime 作为 Leptos 文档页中的编辑器 adapter。**
这份文档回答的是:
> **如何在不放弃 tree-first graph kernel 的前提下,先交付接近 KMind 可用度的导图编辑器。**
## 2. 先给结论
Phase 6 不再以 Rust 自绘导图 renderer 为第一目标。
Phase 6 的主目标是建立:
```text
kernel truth
-> mindmap.kernel_projection.v1
-> mindmap.simple_mind_map_scene.v1
-> leptos-mindmap editor island
-> simple-mind-map / KMind-like runtime
-> adapter diff / command bridge
-> kernel command
```
其中:
- Rust kernel 是事实源。
- `simple-mind-map` 是显示与交互 runtime。
- `leptos-mindmap` 是二者之间的稳定 adapter。
- `lx-doc/mind-map` 和 KMind 插件是行为、视觉、工具栏、侧栏和主题的参考实现。
- 旧 React `MindmapBlock.tsx` 只能作为 legacy/compat 参考,不作为当前文档页主链。
- TypeScript NodeView / bridge 只允许作为 `leptos-tiptap``simple-mind-map` 的薄兼容层;toolbar、sidebar、navigator、context menu 等 UI shell 的长期归属应逐步迁到 Leptos/Rust 组件,避免继续扩散 React/Vue/TS UI 运行时。
这不是“直接嵌入 `lx-doc/mind-map` 保存 blob”,也不是“立即 Rust 重写 `lx-doc/mind-map`”。它是中间路线:
> **Rust 内核 + lx-doc/KMind 级显示编辑体验。**
## 3. 三条路线的定位
### 3.1 Rust 重写 lx-doc/mind-map
这是长期最干净的路线。
优点:
- kernel、projection、layout、hit-test、selection、history 都能完全统一。
- AI/CLI 可直接操作导图内核,不被前端库字段绑架。
- 长期不受 `simple-mind-map` 事件粒度、数据格式和插件边界限制。
问题:
- 实际上要重写的是 `simple-mind-map` 引擎,而不只是 `lx-doc/mind-map` 的 Vue UI。
- 需要自研布局、节点测量、连线、概要、外框、关联线、拖拽、快捷键、导入导出、主题、MiniMap、富文本等完整编辑器能力。
- 短期会牺牲可用体验。
结论:
> 保留为长期方向和后续 Rust-native engine 路线,但不再作为 Phase 6 的主验收。
### 3.2 Rust 内核 + lx-doc/mind-map 显示
这是当前推荐路线,即 `leptos-mindmap`
优点:
- 能快速获得接近 KMind 的可用编辑体验。
- Rust kernel 仍然持有事实源、projection 和 command。
- 可以逐步把 `simple-mind-map` 字段提升为 kernel-native 语义。
-`leptos-tiptap` 的定位一致:前端编辑器是 runtime,不是系统事实源。
问题:
- `simple-mind-map` 的事件不一定足够细,需要 adapter diff。
- 高级能力短期可能需要 `compat_payload`
- 必须严格防止回退成“保存整棵前端 blob”。
结论:
> 作为 Phase 6 主线。
### 3.3 直接嵌入 lx-doc/mind-map
这是最快路线,但不作为主线。
优点:
- 最快得到完整 UI。
- 迁移成本看起来最低。
问题:
- `lx-doc/mind-map` 会重新成为事实源。
- 长期仍保存 `simple-mind-map` blob。
- kernel、AI、Page Aggregate、tree realtime 只能在外围补偿。
结论:
> 只可作为短期 demo 或对照,不作为 mnote 主线。
## 4. leptos-mindmap 的边界
`leptos-mindmap` 是一个编辑器 adapter,不是新的事实源。
它负责:
-`leptos-tiptap` NodeView 中挂载导图编辑器。
- 把 kernel projection 转成 `simple-mind-map` 可消费的数据。
- 初始化并管理 `simple-mind-map` runtime 和必要插件。
- 监听导图数据与视图变化。
- 把变化转成 kernel command 或 adapter diff。
- 渲染 KMind-like toolbar、右侧样式栏、底部工具和错误状态。
- 承载 floating overlay canvas shell,并逐步把 UI shell 从临时 TypeScript DOM 渲染迁回 Leptos/Rust 组件边界。
它不负责:
- 长期保存整棵导图 blob。
- 绕过 kernel command 直接把前端 runtime 数据写成 canonical truth。
- 在 UI 层创造第二套树真相、顺序真相或引用边真相。
-`window.__mindmapInstance`、React mount 点或占位 DOM 作为完成判定。
- 把 TypeScript NodeView 扩写成长期 UI 框架;TS 只保留 tiptap / runtime bridge、动态加载、事件转发和最小 DOM mount 职责。
## 5. 数据分层
### 5.1 kernel truth
长期事实源应表达:
- `Mindmap`
- `MindmapNode`
- parent / child order
- collapsed state
- summary / generalization
- associative line
- node style
- link / reference edge
- theme / layout / view state
这些字段应属于 kernel 或 kernel projection,不能只存在于 `simple-mind-map` blob。
### 5.2 mindmap.kernel_projection.v1
这是稳定投影,供 AI、CLI、独立页、文档页和后续 Rust-native renderer 使用。
它应包含:
- `schema`
- `documentId`
- `mindmapId`
- `rootNodeId`
- `revision`
- `nodes`
- `edges`
- `summaries`
- `associativeLines`
- `layout`
- `theme`
- `view`
- `capabilities`
- `source`
### 5.3 mindmap.simple_mind_map_scene.v1
这是 adapter projection,只服务 `simple-mind-map` runtime。
它应包含:
- `root`
- `layout`
- `theme`
- `themeConfig`
- `view`
- `config`
- `compatPayload`
- `projectionRevision`
- `kernelRevision`
注意:这层可以长得像 `simple-mind-map`,但它不是 canonical truth。
### 5.4 compat_payload
短期无法语义化的字段进入 `compat_payload`
允许先放入:
- 高级节点样式
- 图片
- 公式
- 附件
- 富文本片段
- 第三方插件私有字段
- KMind 专有扩展
但每个字段必须有提升策略,不能无限期成为黑箱。
## 6. 命令桥接
Phase 6 最小命令集:
- `mindmap.node.update_text`
- `mindmap.node.insert_child`
- `mindmap.node.insert_sibling_after`
- `mindmap.node.delete`
- `mindmap.node.move`
- `mindmap.view.patch`
- `mindmap.layout.set`
- `mindmap.theme.set`
- `mindmap.summary.set`
- `mindmap.associative_line.upsert`
桥接方式分两级。
### 6.1 直接命令
如果 toolbar 或快捷键能明确知道用户意图,直接发 kernel command。
示例:
- 点击“子节点” -> `mindmap.node.insert_child`
- 点击“同级节点” -> `mindmap.node.insert_sibling_after`
- 节点文本提交 -> `mindmap.node.update_text`
- 删除节点 -> `mindmap.node.delete`
### 6.2 adapter diff
如果 `simple-mind-map` 只给出 `data_change`,则对比上一份 adapter projection 和当前 runtime data。
diff 输出:
- 可识别变化转 kernel command。
- 暂不可识别变化转 `compat_payload.patch`,并打上 `source="adapter-diff"`
禁止把整棵 runtime data 直接作为 canonical success。
## 7. UI 对标范围
第一阶段对标 `image copy 60.png` 和 KMind/lx-doc 体验,但不追全量功能。
必须有:
- 顶部工具栏:撤销、重做、编辑节点、同级节点、子节点、删除节点、标签、超链接、备注、图片、图标、概要、关联线、公式、格式刷、导入、导出。
- 中央画布:真实节点、连线、pan、zoom、选择、双击编辑、键盘基本操作。
- 右侧触发栏:节点样式、导图样式、主题、结构、大纲。
- 底部工具:节点数/字数、回到根节点、搜索、缩放百分比、全屏或只读入口。
- 错误状态:projection 获取失败、command 失败、adapter diff 失败要可定位。
可延期:
- 完整主题设计器。
- 多根节点。
- 思源块悬浮预览。
- 镜像块。
- MOC 模式。
- PDF 标注跳转。
- 全量 XMind/Freemind 导入导出。
## 8. 代码落点建议
### 8.1 Rust 协议层
- `rust/crates/core-protocol/src/mindmap.rs`
- 定义 kernel projection DTO。
- 定义 adapter projection DTO。
- 定义 command DTO。
- 标记旧 `MindmapTreeNode` / `MindmapOp` 为 compat。
### 8.2 Rust runtime 层
- `rust/crates/bridge-runtime/src/lib.rs`
- 构建 `mindmap.kernel_projection.v1`
- 构建 `mindmap.simple_mind_map_scene.v1`
- 执行 kernel command。
- 维护 compat snapshot。
### 8.3 Rust Web 层
- `rust/crates/mnote-web/`
- 暴露 projection / command route。
- 保持 3000 是前端公开入口。
- 不在 Rust Web 内联第三方编辑器业务逻辑。
### 8.4 Leptos / Tiptap 层
- `rust/spikes/leptos-tiptap-spike/src/lib.rs`
- 提供 mindmap NodeView。
- 挂载 `leptos-mindmap` island。
- Tiptap 节点只保存 `mindmapId/rootNodeId/projectionVersion` 等引用。
### 8.5 前端 adapter 层
建议新增或收口到:
- `wolai-frontend/src/lib/mindmap/leptos-mindmap-adapter.ts`
- `wolai-frontend/src/lib/mindmap/simple-mind-map-bridge.ts`
- `wolai-frontend/src/lib/mindmap/mindmap-command-diff.ts`
实际目录可随现有 runtime 打包方式调整,但职责必须清楚。
## 9. 验收标准
Phase 6 新验收不再要求 Rust 自绘 scene。
必须验证:
- 文档页 `/` 插入 mindmap block 后进入 `leptos-tiptap` NodeView。
- NodeView 挂载 `leptos-mindmap`
- 画布由 `simple-mind-map` / KMind-like runtime 渲染真实节点与连线。
- 默认骨架可见 `KMIND``二级节点`、两个 `分支主题``概要`
- 修改节点文本后通过 kernel command 回写。
- reload 后从 kernel projection 恢复修改结果。
- smoke 输出结构化 JSON 和截图。
- 失败时能定位到 projection、adapter init、runtime render、diff、command 或 reload 阶段。
明确不通过:
- 只看到标题或空容器。
- 只断言 React mount 点。
- 只断言 `window.__mindmapInstance`
- 只保存整棵 blob 且无 kernel command。
-`simple-mind-map` runtime data 当成唯一事实源。
## 10. 2026-05-10 现实复核:当前实现差距
当前代码已打通 `mindmap.simple_mind_map_scene.get``mindmap.command.apply`、reload 后文本保留和最小 smoke,但这只能证明 projection / command 的纵切闭环。
它还不能证明 `leptos-mindmap` 已完成。
已确认的差距:
- `leptos-tiptap` NodeView 当前仍在 `tiptap_paragraph.ts` 内手写 DOM。
- 当前所谓 `simple-mind-map-runtime` 只是一个带 `data-runtime="simple-mind-map"` 的容器,不是 `new MindMap(...)` 创建的真实实例。
- 节点是手写 `<button data-testid="mindmap-node">`
- 连线是手写 `<svg><path>`,坐标来自 adapter projection 的简化布局,因此会出现错位。
- toolbar、右侧栏和底部栏只是静态 KMind-like chrome,并未真正绑定 `simple-mind-map` runtime 的 active node、history、scale、search、style、theme、layout 等能力。
- 当前 smoke 断言的是伪 DOM/SVG 可见,而不是 runtime 布局、runtime 连线或真实 `MindMap` instance。
因此,当前状态应被标记为:
> **Phase 6-Aprojection / command 最小闭环通过;Phase 6.1:真实 simple-mind-map runtime cutover 尚未完成。**
后续执行必须先完成 Phase 6.1,不能继续把手写 DOM/SVG 画布美化成最终实现。
Phase 6.1 的硬性完成判定:
- NodeView 只创建 mount element,不再手写节点和连线。
- browser-side adapter bundle 调用 `createLeptosMindmapAdapter()` 或同等桥接入口。
- adapter 内部真实执行 `new MindMap({ el, data, layout, theme, viewData, config })`
- 节点、连线、概要、外框、关联线由 `simple-mind-map` runtime 负责布局和渲染。
- smoke 能证明真实 runtime 存在,且不再以 `.mnote-mindmap-node` / 手写 `<path data-testid="mindmap-edge">` 作为成功条件。
### 10.1 2026-05-10 Phase 6.1 首轮落地状态
本轮已经完成真实 runtime cutover 的首轮落地:
- `leptos-tiptap` NodeView 不再手写默认节点和连线,而是挂载 `data-testid="simple-mind-map-runtime"`
- NodeView 通过 `createLeptosMindmapAdapter()` 初始化真实 `simple-mind-map` runtime。
- `simple-mind-map-bridge` 真实执行 `new MindMap(...)`,并注册到 `window.__MNOTE_LEPTOS_MINDMAP_BRIDGES__` 供 smoke 验证。
- `task166-mindmap-phase6-block-smoke.js` 已改为检查真实 runtime、bridge snapshot、非零节点树和 reload 后文本保留,不再依赖 `.mnote-mindmap-node` / `mindmap-edge`
- 最新 smoke 输出:`/mnt/Data1T/mnote/tmp/task166-mindmap-phase6-block-smoke/result.json`,截图包括 `01-after-insert.png``02-after-edit.png``03-after-reload.png`
仍未视为完成的尾项:
- `view_data_change` 还没有持久化为 kernel command;当前只记录 view event,避免拖拽/缩放造成 POST -> remount 循环。
- toolbar 缩放按钮还没有真正绑定 runtime zoom command。
- `RichText` 插件暂不默认启用;它会把纯文本节点转换成 HTML 字符串,当前先保护 Rust kernel 文本语义。
- 视觉上已经是真实 `simple-mind-map` 工作台,但还未达到 `image copy 60.png` / `image copy 70.png` 的完整 KMind 体验对齐。
### 10.2 2026-05-11 UI shell reuse 收口状态
Phase 6 后续 UI 可用度收口转入:
- `/mnt/Data1T/mnote/design/06-mindmap/done/6-mindmap-phase6-leptos-ui-shell-reuse-checklist-v1.md`
本轮已经把默认宿主修正为 floating overlay canvas shell,并把 toolbar、sidebar、count、navigator 迁到 Leptos/Rust shell 边界:
- `simple-mind-map` runtime 充满块内画布底层。
- toolbar、右侧栏、统计、navigator、MiniMap 作为 overlay 浮在画布上,不再挤压 runtime。
- TypeScript NodeView 保留为 Tiptap NodeView、runtime bridge、事件转发和 context menu 过渡层,不再作为长期 UI shell 宿主。
- `simple-mind-map-bridge` 默认尊重 `fit:true`,初始视口能看到完整示例导图。
- `task166-mindmap-phase6-block-smoke.js` 已覆盖 toolbar/sidebar/navigator/context menu、command bridge、compat patch、reload 与截图证据。
- 2026-05-11 最新截图:`/mnt/Data1T/mnote/tmp/task166-mindmap-phase6-block-smoke/01-after-insert-floating-overlay.png``04-after-reload.png`
剩余视觉差异不改变 kernel-first 主合同:默认主题色、图标体系、工具栏分组密度和高级面板内容仍需继续对齐 KMind/lx-doc。
## 11. 后续 Rust-native 路线
Rust 重写仍然是长期可选路线,但应独立成后续阶段。
后续可以启动:
- Rust mindmap engine candidate spike。
- 布局 crate 评估:`diagramma-layout``dagre/dugong``manatee`
- Headless Rust layout engine。
- Rust scene renderer。
- Rust hit-test / selection / history。
这些不再阻塞 Phase 6 的可用编辑器交付。
## 12. 迁移原则
- 先保证可用编辑体验,再逐步提升语义。
- adapter 可以兼容 `simple-mind-map` 字段,但字段所有权要写清楚。
- 每个从 blob 中提升出来的语义,都要有 kernel command 和 projection 表达。
- 不把 `lx-doc/mind-map` 的 Vue2 应用结构直接搬入 mnote。
- 可以参考 KMind 的 UI 与行为,但不要复制它的思源插件耦合。
## 13. 当前执行口径
当前 Phase 6 的一句话口径:
> **用 leptos-mindmap 把 Rust kernel projection 接到 KMind-like 导图编辑器上,先得到可用体验,同时保持 kernel 是事实源。**