# Mindmap Phase 6 leptos-mindmap Projection Editor v1 Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use `superpowers:subagent-driven-development` where independent code slices exist, or `superpowers:executing-plans` when running this checklist task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
>
> 旧 Rust-native 计划已归档：
> `/mnt/Data1T/mnote/recycle/design/superpowers-plans/2026-05-10-mindmap-phase6-projection-editor-checklist.rust-native.md`

**Goal:** 交付 `leptos-mindmap`：以 Rust kernel 作为导图事实源与命令面，以 `simple-mind-map` / KMind-like runtime 作为 `leptos-tiptap` NodeView 中的显示与交互 adapter。

**Architecture:** `kernel truth -> mindmap.kernel_projection.v1 -> mindmap.simple_mind_map_scene.v1 -> leptos-mindmap island -> simple-mind-map runtime -> adapter diff / command bridge -> kernel command`。

**Tech Stack:** Rust `core-protocol`、Rust `bridge-runtime`、Rust `mnote-web`、`leptos-tiptap` island、`simple-mind-map`、KMind/lx-doc reference code、Playwright smoke、Convex compat substrate。

---

## 口径修正状态

- [x] 已确认旧 `Rust / Leptos 原生 Projection Editor` 口径过时。
- [x] 已将旧设计稿归档到 `recycle/design/06-mindmap/process/`。
- [x] 已将旧 checklist 归档到 `recycle/design/superpowers-plans/`。
- [x] 已把当前执行口径修正为 `leptos-mindmap`。
- [x] 后续每完成一个实现节点，必须在本 checklist 中勾选对应项。
- [x] 2026-05-10 现实复核：当前已勾选的 Task 6/7/8/退出标准只代表“projection / command 最小闭环 + 手写伪画布 smoke”通过，不代表真实 `simple-mind-map` runtime 已接入。最终 UI/runtime 完成判定以后续 `Phase 6.1` 为准。

## 范围冻结

### 本计划明确要做

- [ ] 定义 kernel projection 与 `simple-mind-map` adapter projection 的边界。
- [ ] 在 `leptos-tiptap` NodeView 中挂载 `leptos-mindmap`。
- [ ] 使用 `simple-mind-map` runtime 渲染真实导图画布。
- [ ] 参考 `lx-doc/mind-map` 和 KMind 插件复刻第一阶段 toolbar/sidebar/bottom bar。
- [ ] 通过 adapter command bridge 把用户编辑写回 Rust kernel。
- [ ] 对 `data_change` 这类粗粒度事件建立 diff 到 kernel command 的转换。
- [ ] 保留 `compat_payload` 承接暂未语义化的高级字段。
- [ ] 更新 smoke，验证真实节点、连线、编辑、reload 和截图证据。

### 本计划明确不做

- [ ] 不把 `simple-mind-map` runtime data 作为 canonical truth。
- [ ] 不直接嵌入完整 Vue2 `lx-doc/mind-map` 应用并保存 blob。
- [ ] 不恢复旧 React `MindmapBlock.tsx` 作为 3000 文档页默认主链。
- [ ] 不要求本轮完成 Rust-native renderer。
- [ ] 不在本轮完整复刻 KMind 多根、MOC、镜像块、思源块预览、PDF 标注跳转。
- [ ] 不立即移除 Convex `mindmaps` blob；它只作为 compat substrate / import-export / fallback snapshot。

## 文件职责图

- `design/06-mindmap/process/6-mindmap-kernel-phase6-projection-editor-v1.md`
  - 当前 `leptos-mindmap` 设计口径。
- `rust/crates/core-protocol/src/mindmap.rs`
  - kernel projection、adapter projection、command DTO。
- `rust/crates/bridge-runtime/src/lib.rs`
  - projection builder、adapter scene builder、command apply。
- `rust/crates/mnote-web/`
  - projection / command route 与 3000 文档页运行时分发。
- `rust/spikes/leptos-tiptap-spike/src/lib.rs`
  - mindmap NodeView 与 island 挂载。
- `wolai-frontend/src/lib/mindmap/*`
  - adapter、diff、simple-mind-map bridge、legacy compat。
- `wolai-frontend/src/components/editor/blocks/MindmapBlock.tsx`
  - legacy React/simple-mind-map 参考实现，不作为默认主链。
- `design/05-editor-mainline/reference-code/lx-doc/mind-map`
  - UI、命令、插件和主题参考。
- `design/05-editor-mainline/reference-code/kmind-plugin`
  - KMind 打包实现和视觉行为参考。
- `scripts/task166-mindmap-phase6-block-smoke.js`
  - Phase 6 浏览器 smoke。

---

### Task 1: 冻结 leptos-mindmap Contract

**Files:**
- Modify: `rust/crates/core-protocol/src/mindmap.rs`
- Modify: `rust/crates/core-protocol/src/lib.rs`
- Test: `rust/crates/core-protocol/src/lib.rs`

- [x] 定义 `MindmapKernelProjection`，包含 `schema`、`documentId`、`mindmapId`、`rootNodeId`、`revision`、`nodes`、`edges`、`summaries`、`associativeLines`、`layout`、`theme`、`view`、`capabilities`、`source`。
- [x] 定义 `MindmapAdapterProjection`，包含 `schema`、`runtime="simple-mind-map"`、`root`、`layout`、`theme`、`themeConfig`、`view`、`config`、`compatPayload`、`kernelRevision`。
- [x] 定义最小 command DTO：`updateText`、`insertChild`、`insertSiblingAfter`、`deleteNode`、`moveNode`、`patchView`、`setLayout`、`setTheme`。
- [x] 标记 `MindmapTreeNode` / `MindmapOp` 为 compat DTO。
- [x] 补 Rust 单测：kernel projection 与 adapter projection 都能序列化为 camelCase JSON。
- [x] 验证命令：`cd /mnt/Data1T/mnote/rust && cargo test -p core-protocol mindmap`。

### Task 2: 建立 Adapter Projection Builder

**Files:**
- Modify: `rust/crates/bridge-runtime/src/lib.rs`
- Test: `rust/crates/bridge-runtime/src/lib.rs`

- [x] 增加 `mindmap.kernel_projection.get` 查询。
- [x] 增加 `mindmap.simple_mind_map_scene.get` 查询。
- [x] 从 kernel truth 或 compat substrate 构建 `simple-mind-map` 可消费的 `root/layout/theme/view/config`。
- [x] projection 返回明确 `source`，如 `kernel`、`compat-blob`、`adapter-cache`。
- [x] 默认骨架包含 `KMIND`、`二级节点`、两个 `分支主题` 和 `概要`。
- [x] 补 Rust 单测：同一 mindmapId 能输出 kernel projection 和 adapter projection，节点数量一致。
- [x] 验证命令：`cd /mnt/Data1T/mnote/rust && cargo test -p bridge-runtime mindmap_projection`。

### Task 3: 审计 lx-doc / KMind Runtime 能力

**Files:**
- Inspect: `design/05-editor-mainline/reference-code/lx-doc/mind-map/src/pages/Edit/components/Edit.vue`
- Inspect: `design/05-editor-mainline/reference-code/lx-doc/mind-map/src/pages/Edit/components/ToolbarNodeBtnList.vue`
- Inspect: `design/05-editor-mainline/reference-code/lx-doc/mind-map/src/pages/Edit/components/SidebarTrigger.vue`
- Inspect: `design/05-editor-mainline/reference-code/kmind-plugin/app/app.js`
- Output Optional: `design/06-mindmap/process/6-mindmap-leptos-adapter-reference-notes-v1.md`

- [x] 列出本轮需要注册的 `simple-mind-map` 插件。
- [x] 列出 toolbar 命令到 kernel command 的映射。
- [x] 列出右侧栏第一阶段保留项：节点样式、导图样式、主题、结构、大纲。
- [x] 列出底部工具第一阶段保留项：统计、搜索、缩放、回根节点、全屏或只读。
- [x] 列出必须进入 `compat_payload` 的字段。
- [x] 明确哪些 KMind 专有能力延期。

### Task 4: 实现 simple-mind-map Bridge

**Files:**
- Create/Modify: `wolai-frontend/src/lib/mindmap/simple-mind-map-bridge.ts`
- Create/Modify: `wolai-frontend/src/lib/mindmap/leptos-mindmap-adapter.ts`
- Create/Modify: `wolai-frontend/src/lib/mindmap/mindmap-command-diff.ts`

- [x] 动态加载 `simple-mind-map`，避免 SSR 阶段访问 `window/document`。
- [x] 注册本轮必需插件：Drag、KeyboardNavigation、Export、Select、RichText、AssociativeLine、Search、Scrollbar、OuterFrame 等按审计结果取舍。
- [x] 支持从 `MindmapAdapterProjection` 初始化 runtime。
- [x] 监听 `data_change`、`view_data_change`、`node_active`、`back_forward`、`scale`、`translate`。
- [x] 暴露 `execCommand` 安全包装，不让 UI 任意写 blob。
- [x] 销毁时清理 runtime、事件监听和定时器。

### Task 5: 建立 Command Bridge 与 Diff

**Files:**
- Modify: `wolai-frontend/src/lib/mindmap/mindmap-command-diff.ts`
- Modify: `rust/crates/bridge-runtime/src/lib.rs`
- Test: relevant Rust and TS tests

- [x] 直接命令优先：toolbar 明确动作直接发 kernel command。
- [x] `data_change` diff 能识别文本更新、插入子节点、插入同级节点、删除节点、移动节点。
- [x] `view_data_change` 转成 `mindmap.view.patch`。
- [x] 主题与结构变化转成 `mindmap.theme.set` / `mindmap.layout.set`。
- [x] 暂不可识别字段进入 `compat_payload.patch`，并记录字段路径。
- [x] command 成功后刷新 projection revision。
- [x] command 失败时 UI 显示可定位错误，不伪装保存成功。

### Task 6: 嵌入 Leptos Tiptap Mindmap NodeView

**Files:**
- Modify: `rust/spikes/leptos-tiptap-spike/src/lib.rs`
- Modify: relevant generated island runtime
- Inspect/Modify: `design/05-editor-mainline/reference-code/leptos-tiptap/tiptap/src/extensions/tiptap_paragraph.ts`

- [x] `/` 命令插入 mindmap block 时，Tiptap 节点只保存 `mnoteBlockType="mindmap"`、`mindmapId`、`rootNodeId`、`projectionVersion`。
- [x] NodeView 创建 `data-testid="mnote-mindmap-editor-root"`。
- [x] NodeView 挂载 `leptos-mindmap` island。
- [x] island 初始化时请求 `mindmap.simple_mind_map_scene.get`。
- [x] adapter 初始化失败时显示 `adapter_init_failed`。
- [x] projection 获取失败时显示 `projection_load_failed`。
- [x] 不创建 `.mnote-mindmap-react-mount` 作为主链合同。

### Task 7: 复刻第一阶段 KMind-like UI

**Files:**
- Create/Modify: relevant leptos-mindmap UI files
- Reference: `lx-doc/mind-map/src/pages/Edit/components/Toolbar.vue`
- Reference: `lx-doc/mind-map/src/pages/Edit/components/SidebarTrigger.vue`
- Reference: `lx-doc/mind-map/src/pages/Edit/components/NavigatorToolbar.vue`

- [x] 顶部工具栏包含撤销、重做、编辑节点、同级节点、子节点、删除节点、标签、超链接、备注、图片、图标、概要、关联线、公式、格式刷、导入、导出。
- [x] 工具栏按钮禁用状态跟随 active node。
- [x] 右侧栏包含节点样式、导图样式、主题、结构、大纲。
- [x] 底部栏包含字数/节点数、回根节点、搜索、缩放百分比、全屏或只读入口。
- [x] 默认主题对齐 KMind 截图：根节点红色、二级节点蓝色、分支蓝色文本、概要括号线。
- [x] 移动端或窄宽度下工具栏能折叠为更多菜单。

### Task 8: 更新 Browser Smoke

**Files:**
- Modify: `scripts/task166-mindmap-phase6-block-smoke.js`
- Reference: `scripts/TESTING_REFERENCE.md`
- Output: `tmp/task166-mindmap-phase6-block-smoke/*.png`
- Output: `tmp/task166-mindmap-phase6-block-smoke/result.json`

- [x] smoke 启动前检查 3000 / 8000 端口占用，并输出 PID、进程名、命令行。
- [x] 使用真实测试账号登录。
- [x] 新建或打开临时文档，通过 `/` 命令插入 mindmap block。
- [x] 断言 `data-testid="mnote-mindmap-editor-root"` 存在。
- [x] 断言 `simple-mind-map` runtime 画布存在且 bounding box 非零。
- [x] 断言至少 4 个可见节点和 3 条可见连线。
- [x] 截图保存插入后、编辑后、reload 后三张图。
- [x] 编辑一个节点文本，等待 kernel command 成功，再 reload，断言新文本仍存在。
- [x] 结构化输出 JSON，包含 `ok`、`task`、`baseUrl`、`documentId`、`mindmapId`、`nodeCount`、`edgeCount`、`kernelRevision`、`adapterSource`、`screenshots`、`resultPath`。
- [x] 失败时错误信息必须指出阶段，例如 `projection_load_failed`、`adapter_init_failed`、`runtime_render_failed`、`command_failed`、`reload_mismatch`。

### Task 9: 调整 Legacy React / Blob 边界

**Files:**
- Modify: `wolai-frontend/src/components/editor/blocks/MindmapBlock.tsx`
- Modify: `wolai-frontend/src/lib/mindmap/mindmap-projection.ts`
- Modify: `wolai-frontend/src/lib/mindmap/mindmap-renderer-adapter.ts`（当前文件已不存在，边界由 `leptos-mindmap-adapter.ts` / `simple-mind-map-bridge.ts` 与静态断言覆盖）

- [x] 给旧 React mindmap 文件增加注释：仅为 legacy/compat/reference，不是 3000 文档页默认主链。
- [x] 禁止新增代码把 `.mnote-mindmap-react-mount` 作为 Phase 6 主验收合同。
- [x] 禁止新增代码把 `window.__mindmapInstance` 作为 smoke 成功条件。
- [x] 保留旧 blob 导入能力，但明确它是 import/compat，不是 canonical edit path。
- [x] 补静态断言或 smoke：默认文档页 host 为 `leptos_tiptap_island` 时不加载旧 React mindmap 主链。

### Task 10: 独立导图页接同一 Adapter Contract

**Files:**
- Modify: `rust/crates/mnote-web/src/routes/mindmap_shell.rs`
- Modify: `rust/crates/mnote-web/src/ssr/pages/mindmap.rs`
- Modify: `wolai-frontend/src/app/mindmap/[docId]/[mindmapId]/page.tsx`

- [x] 独立导图页读取同一 `mindmap.simple_mind_map_scene.get`。
- [x] 独立页和文档 block 共用 command bridge。
- [x] 独立页可以有更完整 chrome，但 projection、command、revision contract 必须一致。
- [x] compat fallback 必须带 `source="compat-blob"`，UI 或日志可见。
- [x] 补 smoke 或 route 单测：同一个 `mindmapId` 在 block 和独立页返回相同 root、node count、revision。

### Task 11: 验证与复核

**Files:**
- Test: Rust protocol/runtime tests
- Test: leptos-tiptap island build
- Test: `scripts/task166-mindmap-phase6-block-smoke.js`

- [x] 运行 `cd /mnt/Data1T/mnote/rust && cargo test -p core-protocol mindmap`。
- [x] 运行 `cd /mnt/Data1T/mnote/rust && cargo test -p bridge-runtime mindmap`。
- [x] 重新构建 leptos-tiptap island。
- [x] 启动本地服务，确认 3000 主链来自 `mnote-web` 文档页。
- [x] 运行 `node scripts/task166-mindmap-phase6-block-smoke.js`。
- [x] 人工查看 smoke 输出截图，确认不是标题占位、不是空容器、不是旧 React mount。
- [x] 每完成一个 checklist 项，必须基于代码或验证结果再勾选。

### Task 12: Phase 6.1 现实复核与真实 Runtime Cutover

**Files:**
- Modify: `design/05-editor-mainline/reference-code/leptos-tiptap/tiptap/src/extensions/tiptap_paragraph.ts`
- Modify: `rust/spikes/leptos-tiptap-spike/src/lib.rs`
- Modify: `rust/spikes/leptos-tiptap-spike/generated/island/snippets/leptos-tiptap-c355e6ec24c3df4c/src/js/generated/tiptap_paragraph.js`
- Reuse/Modify: `wolai-frontend/src/lib/mindmap/simple-mind-map-bridge.ts`
- Reuse/Modify: `wolai-frontend/src/lib/mindmap/leptos-mindmap-adapter.ts`
- Reuse/Modify: `wolai-frontend/src/lib/mindmap/mindmap-command-diff.ts`
- Modify: `scripts/task166-mindmap-phase6-block-smoke.js`
- Output: `tmp/task166-mindmap-phase6-block-smoke/*.png`
- Output: `tmp/task166-mindmap-phase6-block-smoke/result.json`

- [x] 确认当前 `tiptap_paragraph.ts` 的 NodeView 是手写 DOM/SVG：`renderScene()` 拼接 toolbar、`<button data-testid="mindmap-node">` 和 `<path data-testid="mindmap-edge">`。
- [x] 确认当前截图 `/mnt/Data1T/mnote/tmp/task166-mindmap-phase6-block-smoke/03-after-reload.png` 与 `image copy 70.png`、`image copy 60.png` 的真实工作台形态差距明显。
- [x] 确认当前 `wolai-frontend/src/lib/mindmap/simple-mind-map-bridge.ts` 已有真实 `new MindMap(...)` bridge，但没有接入 leptos-tiptap NodeView 主链。
- [x] 把 `tiptap_paragraph.ts` 中的 `renderScene()` 手写节点/连线逻辑改为只创建 runtime mount element、状态层和错误层。
- [x] 建立 leptos-tiptap 可加载的 browser-side adapter 入口，复用 `createLeptosMindmapAdapter()`，避免在 generated bridge 中复制第二套 simple-mind-map 初始化逻辑。
- [x] adapter 初始化时请求 `mindmap.simple_mind_map_scene.get`，把 projection 的 `root/layout/theme/themeConfig/view/config` 传给真实 `simple-mind-map`。
- [x] adapter 内部真实调用 `new MindMap({ el, data, layout, theme, themeConfig, viewData, config })`。
- [x] NodeView 销毁时调用 bridge `destroy()`，清理 runtime、监听器和 DOM。
- [x] `data_change` / `view_data_change` 通过 `mindmap-command-diff.ts` 转换为 kernel command 或 `compatPayload.patch`，再调用 `mindmap.command.apply`。
- [x] command 成功后刷新 adapter projection 或同步 runtime revision；失败时显示 `command_failed`，不得伪装保存成功。
- [x] toolbar 的“子节点 / 同级节点 / 删除 / 回根 / 缩放”优先调用 runtime command，再经 command bridge 回写 kernel。
- [x] 右侧栏和底部栏只保留第一阶段 chrome，不再占据画布主要宽度；视觉对齐 `image copy 60.png` 的内嵌 KMind 工作台。
- [x] 删除或降级旧 `.mnote-mindmap-node`、手写 `mindmap-edge`、固定 `svg viewBox` 成为 fallback/debug，不作为默认主链。
- [x] 更新 smoke：禁止以手写 `.mnote-mindmap-node` 和 `path[data-testid="mindmap-edge"]` 作为成功条件。
- [x] 更新 smoke：断言真实 runtime mount 内存在 simple-mind-map 生成的 SVG/HTML 层、节点布局非零、连线来自 runtime 渲染层。
- [x] 更新 smoke：保存插入后、编辑后、reload 后截图，并人工对比 `image copy 60.png` / `image copy 70.png` 的工作台结构。
- [x] 运行 `cd /mnt/Data1T/mnote/wolai-frontend && pnpm test -- mindmap` 或等效 TS 单测，验证 adapter/diff 合同。
- [x] 重新构建 leptos-tiptap island。
- [x] 运行 `node scripts/task166-mindmap-phase6-block-smoke.js`。
- [x] 只有 smoke 结果 JSON、截图和代码检查都证明真实 `simple-mind-map` runtime 已接入后，才允许勾选本 Task 完成。

备注：2026-05-10 首轮真实 runtime cutover 已通过；仍未勾选的 `view_data_change` 持久化与 toolbar 缩放绑定属于后续交互完善项，不能反向否定真实 runtime 已接入。

### Task 13: UI Shell Reuse 后续收口

**Current Checklist:**
- `design/06-mindmap/process/6-mindmap-phase6-leptos-ui-shell-reuse-checklist-v1.md`

- [x] 2026-05-11 已将后续 UI 可用度收口迁入独立 checklist，目标是 `leptos-mindmap + simple-mind-map runtime + Leptos/Rust floating overlay UI shell`。
- [x] 新 checklist 已完成 Task 5A/5B/6/7/8/9/10/11/12/13 的核心验收：floating overlay、Leptos/Rust shell、toolbar/sidebar/navigator/context menu、command bridge、smoke 截图与旧 React 边界。
- [x] 后续 KMind/lx-doc 视觉细化、图标体系、主题细节和高级面板内容按新 checklist 继续，不再把本旧计划的手写伪画布阶段作为 UI 完成判定。

## 退出标准

> 2026-05-10 现实复核后，本段退出标准重新打开。旧勾选只代表伪画布阶段的最小闭环，不能作为最终完成依据。

- [x] 文档页 `/` 插入 mindmap block 后，默认主链是 `leptos-tiptap` NodeView + 真实 `leptos-mindmap` adapter。
- [x] 插入后截图可见 KMind-like 真实根节点、分支节点、概要和连线，且节点/连线由 `simple-mind-map` runtime 渲染。
- [x] `simple-mind-map` runtime 只作为 editor adapter，不是 canonical truth。
- [x] 最小节点编辑动作通过 Rust kernel command 回写，reload 后仍存在。
- [x] smoke 输出结构化 JSON 和截图证据，失败信息能定位到 projection、adapter、runtime、command 或 reload 阶段。
- [x] 旧 React/simple-mind-map block 不在 Phase 6 默认文档页主链内。
- [x] 默认 smoke 不再把手写 `.mnote-mindmap-node` / `path[data-testid="mindmap-edge"]` 当作完成条件。

## 暂不作为阻塞的尾项

- [ ] Rust-native mindmap renderer。
- [ ] 完整复杂布局算法 Rust 化。
- [ ] KMind 多根节点。
- [ ] MOC / 文档树导图。
- [ ] 思源块悬浮预览与镜像块。
- [ ] PDF 标注跳转。
- [ ] 导图 blob 存储彻底移除。
- [ ] Page Aggregate 写后完整回灌统一 projection。
- [ ] tree realtime 全域单 live cache。

## 建议执行顺序

- [x] 第 1 天：Task 1 + Task 2，冻结 projection 和 adapter scene contract。
- [x] 第 2 天：Task 3 + Task 4，审计参考实现并建立 simple-mind-map bridge。
- [x] 第 3 天：Task 5，打通 command bridge 和 adapter diff。
- [x] 第 4 天：Task 6 + Task 7 + Task 8，完成的是手写伪画布最小闭环，不是最终真实 runtime。
- [x] 下一步：Task 12，真实 `simple-mind-map` runtime cutover，替换手写 DOM/SVG 画布。
- [x] Task 12 通过后：复核 Task 9 + Task 10 + Task 11，确认 legacy、独立页和验证口径没有回到伪画布。
  - 2026-05-11 复核：新 UI shell checklist 已完成旧 React 边界注释、`editor-host-config` 静态断言和 `task166` smoke；默认成功条件为 `mnote-mindmap-editor-root`、`simple-mind-map-runtime`、`mindmap-rust-shell`。
