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:
+566
@@ -0,0 +1,566 @@
|
||||
# 1-1 [reference] Tree-First Graph 内核实施清单 v2
|
||||
|
||||
> 更新时间:2026-04-16
|
||||
>
|
||||
> 当前状态:`reference`。本文保留 kernel 分阶段全景与历史状态口径;当前执行顺序以 `design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.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-1-rust-web-long-term-checklist-v2.md`
|
||||
> - `/mnt/Data1T/mnote/harness-tasks.json`
|
||||
|
||||
## 1. 这版为什么要重写
|
||||
|
||||
`v1` 已经把长期方向改到了 `tree-first graph kernel`,方向是对的,但完成口径仍然偏乐观。
|
||||
|
||||
当前真实代码已经证明:
|
||||
|
||||
- Kernel 文档、Rust 类型、query/command 协议、`mnote-web` kernel route 不是空想,已经存在
|
||||
- 但 Sidebar、搜索、AI、Mindmap、阅读页、`BlockNote` 还没有真正切到 kernel projection 主路径
|
||||
- `mnote-web` 的 kernel route 已接到真实 `sidebar.dataset.list` query plan,但仍保留 fixture/testing fallback,不能写成“主流量切换完成”
|
||||
|
||||
因此 `v2` 的目的不是推翻之前工作,而是把长期清单统一到:
|
||||
|
||||
> **既承认已落地的 Rust kernel 代码,也不再把骨架、样板和 host/runtime 拆分误写成长期阶段已完成。**
|
||||
|
||||
> 说明(2026-04-22):
|
||||
> 这份清单仍保留为 `Kernel Phase` 全景参考,但当前第一优先级已经转移到
|
||||
> `Page Aggregate`、`tree command cutover`、`tree realtime event stream`。
|
||||
> 当前执行优先级请先看 `/mnt/Data1T/mnote/design/01-05-current-priority-overview.md`。
|
||||
|
||||
---
|
||||
|
||||
## 2. 状态口径
|
||||
|
||||
### `DONE`
|
||||
|
||||
- 已有真实代码进入主线
|
||||
- 不只是文档或骨架
|
||||
- 对应阶段的最小目标已经成立
|
||||
|
||||
### `PARTIAL`
|
||||
|
||||
- 已有真实代码和明确接缝
|
||||
- 但主路径仍未完成切换
|
||||
- 仍存在 fixture/testing fallback、旧对象模型或重前端壳残留
|
||||
|
||||
### `NOT_STARTED`
|
||||
|
||||
- 还停留在设计、口径或局部能力
|
||||
- 尚未形成稳定主链
|
||||
|
||||
---
|
||||
|
||||
## 3. 当前总判断
|
||||
|
||||
当前基线应统一理解为:
|
||||
|
||||
- `Kernel Phase 0`:`DONE`
|
||||
- `Kernel Phase 1`:`DONE`
|
||||
- `Kernel Phase 2`:`DONE`
|
||||
- `Kernel Phase 3`:`DONE`
|
||||
- `Kernel Phase 4`:`DONE`
|
||||
- `Kernel Phase 5`:`PARTIAL`
|
||||
- `Kernel Phase 6`:`PARTIAL`
|
||||
- `Kernel Phase 7`:`PARTIAL`
|
||||
- `Kernel Phase 8`:`PARTIAL`
|
||||
- `Kernel Phase 9`:`NOT_STARTED`
|
||||
|
||||
一句话总结:
|
||||
|
||||
> **Kernel 基础层与 Rust Web 承载层已经进入真实主线,树域 consumer 已统一到稳定 projection family;但旧前端壳仍然是主要执行面,下一步才是独立 Rust Web tree shell 重构。**
|
||||
|
||||
### 面向“全部用 Rust 重写”的附加口径
|
||||
|
||||
如果把长期总目标进一步固定为:
|
||||
|
||||
> **主执行面最终也迁到 Rust 家族,而不只是“Rust 拥有 kernel 语义”。**
|
||||
|
||||
那么当前状态应再补一层判断:
|
||||
|
||||
- `Kernel Phase 0-4` 解决的是“树域真相和协议先收口”
|
||||
- 但距离“主要 UI 执行面改由 Rust 承接”还差一个关键中段:
|
||||
- `Sidebar / 页面树 / 文件树` 独立 Rust Web 子系统重构
|
||||
- 这一步不是可选优化,而是旧前端壳退场前必须先完成的第一块主执行面切换
|
||||
|
||||
也就是说:
|
||||
|
||||
> **如果目标是“全部用 Rust 重写”,那么当前最优先的下一步,不是继续在旧 React 壳里打补丁,而是启动树域独立 Rust Web 重构。**
|
||||
|
||||
---
|
||||
|
||||
## 4. 新架构的真实验收定义
|
||||
|
||||
只有同时满足下面几条,才能说新架构真正成立。
|
||||
|
||||
| 验收项 | 当前状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| Rust 中存在统一的 kernel node / edge / projection / subtree 真相层 | `DONE` | `core-protocol` 已落地 |
|
||||
| Rust 中存在统一的 kernel query / command 面 | `DONE` | `bridge-runtime` 已支持 kernel 查询与写协议 |
|
||||
| Rust Web 能承接 kernel route | `DONE` | `mnote-web` 已具备通用 query transport、kernel/bridge/compat route、测试专用 fixture 边界,以及可切到真实 Sidebar 流量的兼容入口 |
|
||||
| Sidebar / 页面树 / 文件树直接消费 kernel projection | `PARTIAL` | 前端主 Sidebar 已以 `kernelSidebarTree` 作为主树来源,但仍是重客户端壳,其他树域仍残留旧拼树 helper |
|
||||
| 搜索直接消费 kernel-aware 检索结果 | `PARTIAL` | cron 已有 `kernel-aware refresh` 过渡链,搜索结果也已带 `nodeId` / `subtreeRootId` / `evidence`,但仍是 LightRAG 过渡口径,不是 kernel 真相层检索 |
|
||||
| 阅读页直接消费 page subtree projection | `PARTIAL` | `DocumentReadView` 已直接消费 `pageSubtree`,但 projection 仍在前端读链内生成,不是 Rust/kernel 真相层输出 |
|
||||
| AI 直接面向 node / subtree / edge 操作 | `PARTIAL` | AI runtime 与 Hermes bridge 已开始携带 `node` / `subtree` / `outline` / `evidence` 上下文,但还不是完整的 kernel-first tool 面 |
|
||||
| Mindmap 正式退化为 projection / editor | `PARTIAL` | 理念已定,独立页已去 stub,但数据真相尚未下沉到 kernel |
|
||||
| `BlockNote` 只负责内容节点编辑 | `PARTIAL` | 阅读态已先走 `pageSubtree`,编辑器也已按需挂载,但外围 panel / drawer 仍集中在 `DocumentContent` |
|
||||
| 旧前端壳不再承担对象真相 | `NOT_STARTED` | 当前主入口仍是 Next/React |
|
||||
|
||||
---
|
||||
|
||||
## 5. Kernel Phase 0:边界冻结与术语统一
|
||||
|
||||
**当前状态:`DONE`**
|
||||
|
||||
### 已落地
|
||||
|
||||
- `tree-first-graph-kernel-v1.md` 已冻结:
|
||||
- `node`
|
||||
- `edge`
|
||||
- `projection`
|
||||
- `subtree`
|
||||
- `content node`
|
||||
- `reference edge`
|
||||
- `summary node`
|
||||
- `index node`
|
||||
- 已明确四层边界:
|
||||
- 事实源
|
||||
- 投影
|
||||
- 编辑器
|
||||
- 外挂
|
||||
- 已明确:
|
||||
- `Mindmap` 不是事实源
|
||||
- `BlockNote` 不是事实源
|
||||
- 页面树/文件树不是事实源
|
||||
|
||||
### 完成判定
|
||||
|
||||
- 后续长期任务不再把导图页、页面树、`BlockNote` 文档结构当作独立真相层
|
||||
|
||||
---
|
||||
|
||||
## 6. Kernel Phase 1:Node / Edge / Projection 基础模型落地
|
||||
|
||||
**当前状态:`DONE`**
|
||||
|
||||
### 已落地
|
||||
|
||||
- `rust/crates/core-protocol/src/kernel.rs` 已存在统一类型
|
||||
- `rust/crates/core-protocol/src/lib.rs` 已导出 kernel 类型
|
||||
|
||||
### 已有能力
|
||||
|
||||
- `KernelNode`
|
||||
- `KernelEdge`
|
||||
- `KernelProjectionRequest`
|
||||
- `KernelProjectionResult`
|
||||
- `KernelSubtreeRef`
|
||||
- `KernelSubtreeResult`
|
||||
- `KernelAuditStamp`
|
||||
- `KernelNodeType`
|
||||
- `KernelEdgeType`
|
||||
- `KernelProjectionKind`
|
||||
|
||||
### 当前结论
|
||||
|
||||
- 这一阶段不应再回退为“只有文档设计”
|
||||
- 这里已经是实际代码事实
|
||||
|
||||
---
|
||||
|
||||
## 7. Kernel Phase 2:Kernel Query / Command / Subtree / Graph Traversal 协议落地
|
||||
|
||||
**当前状态:`DONE`**
|
||||
|
||||
### 已落地
|
||||
|
||||
- `rust/crates/bridge-runtime/src/lib.rs` 已支持:
|
||||
- `kernel.node.get`
|
||||
- `kernel.subtree.get`
|
||||
- `kernel.children.list`
|
||||
- `kernel.edges.list`
|
||||
- `kernel.graph.traverse`
|
||||
- `kernel.project_view`
|
||||
- `kernel.node.create`
|
||||
- `kernel.node.update`
|
||||
- `kernel.subtree.move`
|
||||
- `kernel.edge.attach`
|
||||
- `kernel.edge.detach`
|
||||
- `rust/crates/storage-convex-bridge/src/mapping.rs` 已补 kernel query / command 映射
|
||||
|
||||
### 当前结论
|
||||
|
||||
- 这一阶段也不应再写成“待设计”
|
||||
- 真实缺口不在协议是否存在,而在谁来真正消费这些协议
|
||||
|
||||
---
|
||||
|
||||
## 8. Kernel Phase 3:Rust Web 接入 kernel,成为主承载层
|
||||
|
||||
**当前状态:`DONE`**
|
||||
|
||||
### 已落地
|
||||
|
||||
- `rust/crates/mnote-web/` 已进入 workspace
|
||||
- 已存在 `axum` app/router/context/middleware 骨架
|
||||
- 已有 kernel route:
|
||||
- `/api/kernel/projections/sidebar`
|
||||
- `/api/kernel/subtree`
|
||||
- `/api/kernel/edges`
|
||||
- `/api/kernel/graph`
|
||||
- sidebar kernel route 已通过 `sidebar.dataset.list` runtime plan + 通用 Convex query transport 读取真实数据集
|
||||
- 已新增真实 workspace / bridge 查询 route:
|
||||
- `/api/bridge/workspace`
|
||||
- `/api/bridge/request`
|
||||
- `/api/bridge/trace`
|
||||
- 已新增 Next 兼容切流入口:
|
||||
- `/api/compat/next/sidebar`
|
||||
- `MNOTE_WEB_QUERY_FIXTURES_JSON` + `allow_dev_fixtures` 已把 fixture 收紧到测试/开发边界
|
||||
- `/api/sidebar` 与服务端 Sidebar 首包当前已优先走 Rust bridge query + source-specific transport;Convex transport 仅属于显式 cloud / compat source,正式同源 `3000` 主链不再依赖 `MNOTE_WEB_BASE_URL` 或 `mnote-web` 的 Sidebar compat route
|
||||
- `mnote-web` transport 已优先转发真实 `Authorization`,否则才退回开发态 admin/dev identity
|
||||
- 已有 kernel / bridge 路由测试,说明 route 不只是声明
|
||||
|
||||
### 已完成判定
|
||||
|
||||
- Sidebar 这条 kernel 查询主链已不依赖生产态 fixture fallback
|
||||
- `mnote-web` 已不再只有 Sidebar 单点 transport,而是能承接更广的 query / bridge 主链
|
||||
- Next -> Rust Web 的第一条真实切流边界已经明确并可启用
|
||||
|
||||
### 当前保留边界
|
||||
|
||||
- `kernel.subtree.get` / `kernel.project_view` 仍主要建立在 `sidebar.dataset.list` 这一份页面树数据集之上
|
||||
- 更广义的 node pool、reference edge、summary/index node 真相层,仍属于后续阶段
|
||||
- `mnote-web` 还不是整个产品的唯一 Web 入口,这属于更后的双栈收缩问题
|
||||
|
||||
### 完成判定
|
||||
|
||||
- 至少一条不依赖 fixture fallback 的 kernel 查询主链已在 `mnote-web` 上稳定运行
|
||||
- 至少一条真实 workspace / bridge 查询主链已通过 `mnote-web` 对外提供
|
||||
- 至少一条真实前端流量已具备默认切到 `mnote-web` 的兼容边界
|
||||
|
||||
---
|
||||
|
||||
## 9. Kernel Phase 4:Sidebar / 页面树 / 文件树切到 kernel projection
|
||||
|
||||
**当前状态:`DONE`**
|
||||
|
||||
### 本阶段边界
|
||||
|
||||
这个阶段只解决一件事:
|
||||
|
||||
> **把树域 consumer 全部统一到稳定的 kernel projection / tree protocol。**
|
||||
|
||||
这里刻意**不**包含:
|
||||
|
||||
- 独立 Rust Web tree shell
|
||||
- `Leptos` / `Dioxus` / `Yew` 树域 UI 重写
|
||||
- Sidebar 整体壳替换
|
||||
|
||||
这些属于 `Phase 4` 完成之后的独立大任务,即:
|
||||
|
||||
- [sidebar-pagetree-filetree-rust-web-rebuild-v1.md](/mnt/Data1T/mnote/design/04-tree-domain/process/4-sidebar-pagetree-filetree-rust-web-rebuild-v1.md)
|
||||
|
||||
### 已落地
|
||||
|
||||
- [x] Sidebar 已有服务端首包
|
||||
- [x] Rust runtime 已能把 `sidebar.dataset.list` 转为统一 kernel subtree / projection 结果
|
||||
- [x] `sidebar-data.ts` 已生成 `kernel_sidebar_projection` 与 `kernelSidebarTree`
|
||||
- [x] 前端主 Sidebar 已以 `sidebarData.kernelSidebarTree` 作为初始化与同步的主树来源
|
||||
- [x] 已新增统一 `page_tree` projection protocol:
|
||||
- `rowId`
|
||||
- `nodeId`
|
||||
- `parentNodeId`
|
||||
- `projectionKind`
|
||||
- `depth`
|
||||
- `position`
|
||||
- `capabilities`
|
||||
- `resourceMeta`
|
||||
- [x] `PrivateTree` 已改为直接消费 `page_tree` projection 可见行,而不是自行 flatten 嵌套树
|
||||
- [x] 文件树已改为只消费 `page_tree projection + asset 映射`,`buildVisibleRows(...)` 收口为 projection -> visible rows
|
||||
- [x] `move-embed picker` 空查询态已直接消费 `kernelSidebarTree -> page_tree projection`,不再调用 `buildDocumentTree(...)`
|
||||
- [x] `SidebarInitialData` / `sidebar-data.ts` 已将 `kernelSidebarProjection` 与 `kernelSidebarTree` 收紧为主路径必备字段,不再在映射阶段对缺失 projection 做主路径 fallback
|
||||
|
||||
### 本阶段完成后仍保留的问题
|
||||
|
||||
- 前端主 Sidebar 仍是超大客户端组件
|
||||
- 页面树 / 文件树 / picker 虽已统一协议,Rust Web 3000 主文档壳也已补齐 create/delete 与页面内 mindmap create 的 no-refresh 回显;但这只代表主入口局部刷新链路已闭环,不等于 Sidebar 整体壳已完成 Rust 化瘦身
|
||||
- 文件树中的 `asset-folder` / `asset` / `index` 仍由前端 adapter 基于现有数据集补齐,不是 Rust 直接输出的 `file_tree projection`
|
||||
- `buildDocumentTree(...)` 仍保留在兼容 helper 与旧单测中,但已退出树域主路径
|
||||
- 现在可以进入树域 Rust Web 壳重写,但不能把这一步与本阶段混写成同一任务
|
||||
|
||||
### 下一阶段任务
|
||||
|
||||
- 独立推进 [sidebar-pagetree-filetree-rust-web-rebuild-v1.md](/mnt/Data1T/mnote/design/04-tree-domain/process/4-sidebar-pagetree-filetree-rust-web-rebuild-v1.md)
|
||||
- 继续把当前 `page_tree` / `file_tree` protocol 下沉成更稳定的 Rust Web route / shell;验收必须以 `3000 /documents/<id>` 主文档壳为准,`/tree` debug route 与 3001/Next 不能替代主链验收
|
||||
- 继续缩小 Sidebar 超大客户端壳,只保留局部交互岛
|
||||
- 让文件树中的更宽对象投影逐步由 Rust projection 直接输出
|
||||
|
||||
### 面向“全部用 Rust 重写”的优先级解释
|
||||
|
||||
如果长期目标只是“Rust 持有语义”,这里可以被理解为下一批独立大任务。
|
||||
|
||||
但如果长期目标已经固定为“全部用 Rust 重写”,那么这里应升级为:
|
||||
|
||||
- **最近主线 P0**
|
||||
- **旧前端壳的第一块正式替换带**
|
||||
- **后续阅读页 / 搜索 / AI / Mindmap Rust 化之前的必经步骤**
|
||||
|
||||
原因是:
|
||||
|
||||
- 树域是工作区主导航与对象结构入口,替换价值最高
|
||||
- `page_tree / file_tree` 协议已经冻结,返工风险最低
|
||||
- 当前 Sidebar 仍是旧前端壳里最重、最容易继续扩散语义的一块
|
||||
- 如果不先把树域执行面剥离出来,后续文档页、搜索页、导图页 Rust 化会继续被旧壳牵制
|
||||
|
||||
### 完成判定
|
||||
|
||||
- [x] 主 Sidebar 以及相关树域已直接消费 kernel projection
|
||||
- [x] 页面树 / 文件树 / 嵌入移动器等不再通过旧对象数组拼树
|
||||
- [x] tree row / projection protocol 已冻结,足以支撑下一步独立 Rust Web tree shell 重构
|
||||
- [x] 当前 React/Next 树域可以继续作为 consumer 壳存在,但不再定义树结构真相
|
||||
|
||||
---
|
||||
|
||||
## 10. Kernel Phase 5:结构知识刷新与 kernel-aware 检索
|
||||
|
||||
**当前状态:`PARTIAL`**
|
||||
|
||||
### 新口径
|
||||
|
||||
这阶段不再按“单独搭一个 RAG 系统”来定义。
|
||||
|
||||
长期正确方向是:
|
||||
|
||||
- 用 cron 定时刷新知识
|
||||
- 直接把结构知识写回 kernel
|
||||
- 用 kernel-aware 检索命中 node / subtree / evidence
|
||||
|
||||
这与传统 `LightRAG-first` 不同,更接近:
|
||||
|
||||
- Karpathy 的知识刷新思路:https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f
|
||||
- `llmwiki-cli` 这类结构化知识索引方案:https://github.com/doum1004/llmwiki-cli;https://github.com/stellarlinkco/llm-wiki/blob/main/README.zh-CN.md
|
||||
- `Mindmap` / `BookMindmap` / 章节树 / 书籍子树作为结构索引投影
|
||||
|
||||
当前已经有直接代码证据,但只能算过渡态:
|
||||
|
||||
- `convex/crons.ts` 已新增 `kernel_aware_refresh_daily_transition`
|
||||
- `convex/jobs.ts` 已新增 `enqueueKernelAwareRefresh`、`enqueueKernelAwareRefreshSweep` 与 `refresh.kernel_aware_transition`
|
||||
- 刷新结果已带 `nodeIds`、`subtreeRootIds`、`evidenceAssetIds`
|
||||
- 搜索结果类型与 adapter 已返回 `nodeId` / `subtreeRootId` / `evidence`
|
||||
|
||||
但这条链目前仍通过 `LightRAG` 过渡入库,还不能写成“kernel 真相层知识刷新已完成”。
|
||||
|
||||
### 已落地
|
||||
|
||||
- 已有 cron 驱动的 `kernel-aware refresh` 过渡入口
|
||||
- 已有工作空间成员校验与刷新目标选择:
|
||||
- workspace
|
||||
- document
|
||||
- mindmap
|
||||
- asset
|
||||
- 已有搜索结果结构化返回:
|
||||
- `nodeId`
|
||||
- `subtreeRootId`
|
||||
- `evidence`
|
||||
- recent / 常规搜索在缺失 Rust evidence 时,也会补齐最小 evidence fallback
|
||||
|
||||
### 当前真实问题
|
||||
|
||||
- 结构知识仍未直接写回 kernel node / edge
|
||||
- `summary node`、`ai_note node`、`index node`、`reference edge` 还没有形成真实 kernel 写链
|
||||
- `BookMindmap` / 章节树还没有形成统一 kernel index 主链
|
||||
- 当前刷新任务仍是 `kernel_aware_transition`,不是最终的 kernel truth pipeline
|
||||
- 搜索虽已消费 kernel-aware 结果形状,但还没有 server-first 搜索页或 Rust Web 检索壳
|
||||
|
||||
### 下一阶段必须完成
|
||||
|
||||
- 把 `kernel_aware_transition` 从 LightRAG 过渡链继续收口到真实 kernel 节点/边写链
|
||||
- 明确 `summary node`、`ai_note node`、`index node`、`reference edge` 的真实写入协议
|
||||
- 把增量刷新输入继续稳定到:
|
||||
- workspace
|
||||
- page
|
||||
- subtree
|
||||
- book
|
||||
- pdf
|
||||
- 把刷新输出真正落到:
|
||||
- `summary node`
|
||||
- `ai_note node`
|
||||
- `index node`
|
||||
- `reference edge`
|
||||
- `book subtree`
|
||||
- `chapter subtree`
|
||||
- 把检索面继续推进到:
|
||||
- 按 node type 过滤
|
||||
- 按 subtree 过滤
|
||||
- 按 edge 过滤
|
||||
- 返回正文/附件/页码/证据回查
|
||||
- 定义残留 `LightRAG` 的过渡边界与移除计划
|
||||
|
||||
### 完成判定
|
||||
|
||||
- 至少一条 cron 驱动的知识刷新链能稳定更新 kernel 节点/边
|
||||
- 至少一条搜索链能直接返回 kernel node / subtree / evidence
|
||||
|
||||
---
|
||||
|
||||
## 11. Kernel Phase 6:Mindmap 降级为 projection / editor
|
||||
|
||||
**当前状态:`PARTIAL`**
|
||||
|
||||
### 已落地
|
||||
|
||||
- 理念上已经确认 `Mindmap` 不是中心
|
||||
- Rust 侧已有 Mindmap 对象协议
|
||||
- 独立导图页已先在服务端获取 initial projection,再进入客户端页面壳
|
||||
- 独立导图页已直接使用 `StandaloneMindmapView`,不再以 `editorStub` 作为入口
|
||||
- `MindmapBlock.tsx` 已出现 `standalone` / `documentBridge` 边界
|
||||
- 文档内嵌导图已默认走 preview-first 入口
|
||||
|
||||
### 当前真实问题
|
||||
|
||||
- 独立导图页仍是客户端重壳,并且仍复用同一个重型 `MindmapBlock` 族组件
|
||||
- 文档内嵌导图虽然已经 preview-first,但进入编辑/沉浸态后仍复用同一个重型 `MindmapSurfaceView`
|
||||
- 导图操作尚未直接回写统一 kernel subtree
|
||||
|
||||
### 下一阶段必须完成
|
||||
|
||||
- 继续把独立导图页壳从文档编辑上下文与共享重组件中拆开
|
||||
- 内嵌导图改为轻预览/轻编辑入口
|
||||
- 把导图编辑动作收口为 kernel command
|
||||
|
||||
### 完成判定
|
||||
|
||||
- 独立导图页与文档内嵌导图都只作为 kernel projection / editor 入口,而不是独立事实源
|
||||
|
||||
---
|
||||
|
||||
## 12. Kernel Phase 7:文档阅读页与 AI 面板切到 kernel projection
|
||||
|
||||
**当前状态:`PARTIAL`**
|
||||
|
||||
### 已落地
|
||||
|
||||
- 阅读态/编辑态已经分离
|
||||
- `DocumentContent` 已生成 `pageSubtree`
|
||||
- `DocumentReadView` 已直接消费 `pageSubtree`
|
||||
- 阅读态结构面板已直接消费 `outline` / `evidence`
|
||||
- `BlockNote` 默认不再首屏强挂
|
||||
- AI 已做 host/runtime 拆分
|
||||
- 历史 React 页面 AI runtime 曾向旧 AI route 发送 `node` / `subtree` / `outline` / `evidence`;该证据只保留为过渡记录
|
||||
- 2026-05-14 起当前页面 AI 主线已改为 Hermes client proxy + mnote Hermes plugin/tool:页面上下文进入 Hermes run/session context,最新页面事实由 Hermes 通过 `mnote.page.get` 等工具回读,不再把旧 `/api/ai-agent/run` 写成长期入口
|
||||
|
||||
### 当前真实问题
|
||||
|
||||
- 阅读页已经是 page subtree projection 驱动,但 projection 仍在前端读链内生成,不是 Rust/kernel 真相层直接输出
|
||||
- `DocumentContent` 仍集中挂载 `DocumentAiAgentPanel`、`DocumentHistoryDrawer`、`DocumentCommentsDrawer`、`PageBacklinksPanel`、`PageOptionsSidebar`
|
||||
- 当前页面 AI 的会话真相已交给 Hermes;剩余问题是继续把 `node` / `subtree` / `edge` 工具契约下沉到 Rust kernel 稳定协议,而不是回到页面级私有 AI runtime
|
||||
- 搜索/AI/阅读页之间虽然开始共享 `node` / `subtree` / `outline` / `evidence` 口径,但还没有统一到稳定的 node / subtree / edge 真相协议面
|
||||
|
||||
### 下一阶段必须完成
|
||||
|
||||
- 把 page subtree projection 从前端读链继续下沉到更稳定的 Rust/kernel 输出边界
|
||||
- 阅读页大纲、回链、结构信息改读 kernel edge / subtree
|
||||
- mnote Hermes plugin tools 继续扩展为直接面向 node / subtree / edge
|
||||
- AI 可以创建:
|
||||
- `summary node`
|
||||
- `ai_note node`
|
||||
- `reference edge`
|
||||
- 搜索与 AI 共用 kernel-aware 检索上下文
|
||||
|
||||
### 完成判定
|
||||
|
||||
- 阅读页与 AI 至少各有一条主路径直接消费 kernel projection
|
||||
|
||||
---
|
||||
|
||||
## 13. Kernel Phase 8:BlockNote 退化为内容编辑挂件
|
||||
|
||||
**当前状态:`PARTIAL`**
|
||||
|
||||
### 已落地
|
||||
|
||||
- `src/lib/documents/page-subtree.ts` 已显式定义 `pageSubtree`
|
||||
- `DocumentContent` 已把阅读态与编辑态拆开
|
||||
- `DocumentContent` 已通过 `isEditing` / `keepEditorMounted` 让 `BlockNote` 按需挂载
|
||||
- 阅读态已不再默认依赖 `BlockNote` 才能渲染正文
|
||||
|
||||
### 当前真实问题
|
||||
|
||||
- 页面结构仍未与 `BlockNote` 内容结构彻底解耦
|
||||
- `DocumentContent` 仍挂着大量外围 panel / drawer
|
||||
- page subtree 与 content node 的边界还没有正式回写到 kernel / editor 分层
|
||||
|
||||
### 下一阶段必须完成
|
||||
|
||||
- 把 page subtree 与 content node 的边界继续固化到更稳定的 kernel / editor 分层
|
||||
- 明确哪些节点继续由 `BlockNote` 编辑
|
||||
- 明确哪些结构节点改由 kernel-aware editor 处理
|
||||
- 把外围 panel 从编辑宿主中继续拆走
|
||||
|
||||
### 完成判定
|
||||
|
||||
- 页面结构不再由 `BlockNote` 数据结构定义
|
||||
- `BlockNote` 只承担内容节点编辑
|
||||
|
||||
---
|
||||
|
||||
## 14. Kernel Phase 9:旧前端壳与旧对象模型下线
|
||||
|
||||
**当前状态:`NOT_STARTED`**
|
||||
|
||||
### 当前真实问题
|
||||
|
||||
- 当前主应用入口仍是 Next App Router
|
||||
- 当前主文档页、主 Sidebar、主搜索、主导图页都仍运行在旧前端壳内
|
||||
|
||||
### 下一阶段必须完成
|
||||
|
||||
- 盘点旧对象真相残留
|
||||
- 盘点旧 helper / adapter 残留
|
||||
- 删除已被 kernel projection 替代的旧 route
|
||||
- 删除已被 kernel command/query 替代的旧 adapter
|
||||
- 明确最终双栈收缩与切流计划
|
||||
|
||||
### 完成判定
|
||||
|
||||
- 旧前端壳与旧对象模型都不再承担主事实来源
|
||||
|
||||
---
|
||||
|
||||
## 15. 推荐执行顺序
|
||||
|
||||
如果按当前真实代码继续推进,建议顺序是:
|
||||
|
||||
1. 维持 `Kernel Phase 4` 已完成口径,不再回头重做 consumer 统一
|
||||
2. 立即启动 `Phase 4` 后继任务:
|
||||
- [sidebar-pagetree-filetree-rust-web-rebuild-v1.md](/mnt/Data1T/mnote/design/04-tree-domain/process/4-sidebar-pagetree-filetree-rust-web-rebuild-v1.md)
|
||||
3. 在树域 Rust Web 子系统形成稳定主链后,再继续把文档阅读页的 `page subtree / read_view` 下沉到 Rust 输出边界
|
||||
4. 再推进 `Kernel Phase 5`
|
||||
5. 再推进 `Kernel Phase 6`
|
||||
6. 再推进 `Kernel Phase 7`
|
||||
7. 最后进入 `Kernel Phase 8` 和 `Kernel Phase 9`
|
||||
|
||||
原因很简单:
|
||||
|
||||
- 旧 `Phase 4` 的目标已经完成,真正未完成的是“树域执行面 Rust 化”
|
||||
- 树域是所有主页面里最先具备 Rust 化条件的一块,因为 projection / command protocol 已经先被冻结
|
||||
- 文档阅读页、搜索、AI、Mindmap 后续都会依赖这条更稳定的树域与 projection 分发主链
|
||||
- 如果继续把精力分散到旧 React 壳上的局部修补,会拖慢真正的执行面切换
|
||||
- 知识刷新与 kernel-aware 检索仍然重要,但它们更适合在树域主承载面开始切换后并行推进,而不是抢在前面替代主导航改造
|
||||
|
||||
---
|
||||
|
||||
## 16. 最终结论
|
||||
|
||||
当前最准确的表述不是“长期阶段已经做完”,而是:
|
||||
|
||||
> **Kernel 基础层已经做出来了,真正难的部分才刚开始,也就是让所有主视图与主工具链逐步切到 kernel projection。**
|
||||
|
||||
所以后续主线必须固定为:
|
||||
|
||||
> **先完成树域的 kernel projection 统一,再基于稳定协议做 Sidebar / 页面树 / 文件树的独立 Rust Web 重构;之后再并行推进结构知识刷新、Mindmap、阅读页、AI、`BlockNote` 与旧壳退场。**
|
||||
|
||||
如果把总目标进一步固定为“全部用 Rust 重写”,则这里还应再明确一句:
|
||||
|
||||
> **下一步应该继续的,不是旧定义里的 `Kernel Phase 4` 本身,而是它的后继任务,也就是 `Sidebar / 页面树 / 文件树 Rust Web 重构`;这是旧前端壳退场前最值得优先拿下的第一块执行面。**
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
# 1-2 [reference] Tree-First Graph 产品愿景进展评估 v1
|
||||
|
||||
> 更新时间:2026-05-19
|
||||
>
|
||||
> 当前状态:`reference`。本文保留产品愿景进展评估,不作为当前 active implementation checklist。
|
||||
>
|
||||
> **目的**:对照原始产品愿景(Wolai 编辑体验 + VSCode 文件树 + simple-mindmap + OnlyOffice + AI 操作一切),评估当前代码在 1.0 MVP 后的实际进展和剩余的缺口。
|
||||
>
|
||||
> 关联:
|
||||
> - `design/01-05-current-priority-overview.md`
|
||||
> - `design/10-review/done/11-current-full-architecture-review-v1.md`
|
||||
> - `CURRENT_ARCHITECTURE.md`
|
||||
> - `design/11-wolai/help-center-reference.md` — Wolai 帮助中心功能对照基准
|
||||
|
||||
## 1. 一句话结论
|
||||
|
||||
核心链路已经全部立住,但 AI 对思维导图和 Office 文件的操作是明确的功能缺口,其余模块处于"已可用、收口中"状态。
|
||||
|
||||
---
|
||||
|
||||
## 2. 各模块状态
|
||||
|
||||
### 2.1 Wolai 编辑体验 + UI — ✅ 收口中
|
||||
|
||||
#### 架构层
|
||||
|
||||
| 子能力 | 状态 | 关键证据 |
|
||||
|--------|------|----------|
|
||||
| 默认编辑器已切到 leptos-tiptap island | DONE | `design/05-editor-mainline/done/5-4-leptos-tiptap-mainline-correction-v1.md` |
|
||||
| Page Aggregate 读链已切到 Rust projection | DONE | `design/05-editor-mainline/done/5-5-1-page-aggregate-contract-v1.md` |
|
||||
| 文档页入口优先消费 Rust page-aggregate 快照 | DONE | `CURRENT_ARCHITECTURE.md` §2.5 |
|
||||
| 前端壳已切换到 Rust SSR(`:3000`)| DONE | `CURRENT_ARCHITECTURE.md` §3.1 |
|
||||
| Page Aggregate 写链(标题/正文/设置)smoke 通过 | DONE | `scripts/task110-*`, `task-page-aggregate-*-smoke.js` |
|
||||
| 页面设置运行时语义 / 页头回流 / AI 设置面未完全闭环 | PROCESS | `design/05-editor-mainline/reference/5-5-page-aggregate-single-truth-alignment-v1.md` |
|
||||
| Wolai UI 行为持续对齐 | PROCESS | `design/05-editor-mainline/reference/5-9-wolai-aline-continuous-checklist-v1.md` |
|
||||
| `documents.content` 仍是兼容后备而非唯一真源 | PARTIAL | `CURRENT_ARCHITECTURE.md` §3.2 |
|
||||
|
||||
#### 基础块类型覆盖(对照 Wolai 帮助中心)
|
||||
|
||||
| 块类型 | Wolai | mnote | 备注 |
|
||||
|--------|-------|-------|------|
|
||||
| 文本 | ✅ | ✅ | |
|
||||
| 标题 H1/H2/H3 | ✅ | ✅ | |
|
||||
| 无序列表 | ✅ | ✅ | |
|
||||
| 有序列表 | ✅ | ✅ | |
|
||||
| 待办列表(checkbox)| ✅ | ✅ | |
|
||||
| **折叠列表(toggle)** | ✅ | ❌ | 缺口 |
|
||||
| 页面块(subpage)| ✅ | Partial | Tiptap 嵌入页 |
|
||||
| 引述文字(blockquote)| ✅ | ✅ | |
|
||||
| **着重文字(callout)** | ✅ | ❌ | 缺口 |
|
||||
| 代码片段 | ✅ | ✅ | |
|
||||
| 数学公式 | ✅ | ✅ | LaTeX |
|
||||
| 分割线 | ✅ | ✅ | |
|
||||
|
||||
#### 进阶块类型覆盖(仅基础级引用)
|
||||
|
||||
| 块类型 | Wolai | mnote | 备注 |
|
||||
|--------|-------|-------|------|
|
||||
| 简单表格 | ✅ | ✅ | Tiptap table |
|
||||
| **数据表格(database)** | ✅ | ❌ | 缺口,类似 Notion DB |
|
||||
| 统计图表 | ✅ | ❌ | |
|
||||
| Mermaid 绘图 | ✅ | ❌ | |
|
||||
| 思维导图 | ✅ | ✅ | Phase 6 leptos-mindmap |
|
||||
| 页面目录(TOC)| ✅ | ❌ | |
|
||||
| 网址书签 | ✅ | ✅ | |
|
||||
| 嵌入第三方应用 | ✅ | Partial | OnlyOffice 已接,其他待定 |
|
||||
| 文件附件 | ✅ | ✅ | OnlyOffice adapter |
|
||||
| 按钮 / 进度条 / 仪表数字 | ✅ | ❌ | 基础缺口 |
|
||||
|
||||
#### 基础操作覆盖
|
||||
|
||||
| 操作 | Wolai | mnote | 备注 |
|
||||
|------|-------|-------|------|
|
||||
| 基本编辑(输入/换行/拖拽/缩进)| ✅ | ✅ | |
|
||||
| `/` 快捷命令菜单 | ✅ | ✅ | Tiptap slash command |
|
||||
| **模板创建页面** | ✅ | ❌ | 缺口 |
|
||||
| 页面选项/设置 | ✅ | ✅ | Page Aggregate 写链已通 |
|
||||
| **页面关系图** | ✅ | ❌ | 缺口 |
|
||||
| 全局搜索(Ctrl+P)| ✅ | ✅ | Search modal smoke 通过 |
|
||||
| **导入/导出** | ✅ | ❌ | 缺口(Local/Cloud 桥接仅 P3) |
|
||||
| 垃圾桶 | ✅ | ✅ | `tree.resource.*` 实现 |
|
||||
| **回收站恢复位置+reveal** | ✅ | ✅ | 已实现(`design/04-tree-domain/process/4-28`) |
|
||||
| 个人设置(主题/语言)| ✅ | Partial | 暗色模式有,设置 UI 不全 |
|
||||
| 图标/表情选择器 | ✅ | Partial | |
|
||||
| **快捷方式/星标栏** | ✅ | ❌ | 缺口 |
|
||||
|
||||
完整对照表见 `design/11-wolai/help-center-reference.md`。
|
||||
|
||||
### 2.2 VSCode 文件树 — ✅ 大部完成
|
||||
|
||||
| 子能力 | 状态 | 关键证据 |
|
||||
|--------|------|----------|
|
||||
| VSCode Explorer 对标设计 | DONE | `design/04-tree-domain/done/4-20-vscode-explorer-file-tree-alignment-v1.md` |
|
||||
| 三层模型(Resource → File → Page Tree)固定 | DONE | `design/04-tree-domain/done/4-24-resource-tree-filetree-pagetree-source-contract-checklist-v1.md` |
|
||||
| `tree.*` 命令切流(Stage 2)| DONE | `design/04-tree-domain/done/4-6-tree-command-protocol-cutover-stage2-v1.md` |
|
||||
| 文件树资源行与页面命令分离 | DONE | `bugs/04-tree-domain/done/4-46-filetree-resource-row-document-command-leak-v1.md` |
|
||||
| 垃圾箱恢复位置记录 + reveal/focus | DONE | `design/04-tree-domain/process/4-28-trash-restore-location-reveal-focus-v1.md` §2 |
|
||||
| 资源生命周期命令 `tree.resource.*`(核心 cutover 已完成,局部尾项由后续文档承接)| DONE/PARTIAL tails | `design/04-tree-domain/done/4-27-resource-lifecycle-command-cutover-v1.md`,尾项见 `4-28` / `4-34` / `4-44` / `4-45` |
|
||||
| 双浏览器 no-refresh(页面 + 文件 + 垃圾箱实时同步)| PROCESS | `design/04-tree-domain/process/4-34-filetree-trash-dual-browser-no-refresh-v1.md` |
|
||||
| Local/Cloud 桥接 | P3 CANDIDATE | `design/04-tree-domain/reference/4-23-local-cloud-explicit-bridge-p3-candidate-v1.md` |
|
||||
|
||||
### 2.3 Simple-mindmap — ✅ 编辑器完成,AI 未覆盖
|
||||
|
||||
| 子能力 | 状态 | 关键证据 |
|
||||
|--------|------|----------|
|
||||
| Phase 6 口径修正(Rust kernel + simple-mind-map adapter)| DONE | `design/06-mindmap/reference/6-mindmap-kernel-phase6-projection-editor-v1.md` §2 |
|
||||
| Leptos UI shell | DONE | git `c64487c6` |
|
||||
| 即时显示修复 | DONE | git `3be102a4` |
|
||||
| Filetree 切换稳定 | DONE | git `b300562a` |
|
||||
| KMind 级详细验收 | DONE | `design/06-mindmap/done/6-mindmap-phase6-kmind-parity-detail-checklist-v1.md` |
|
||||
| **AI 读写思维导图(增删改节点)** | **GAP** | Hermes manifest 无 `mnote.mindmap.*` 工具 |
|
||||
|
||||
### 2.4 OnlyOffice — ✅ 打开/链路完成,AI 未覆盖
|
||||
|
||||
| 子能力 | 状态 | 关键证据 |
|
||||
|--------|------|----------|
|
||||
| adapter-onlyoffice crate | DONE | `rust/crates/adapter-onlyoffice/` |
|
||||
| Rust 路由 | DONE | `rust/crates/mnote-web/src/routes/onlyoffice.rs` |
|
||||
| Docker 部署 | DONE | `infra/onlyoffice/docker-compose.yml` |
|
||||
| 附件打开链路修复 | DONE | git `7bd0c9e9` |
|
||||
| Kernel 工具(session/签名/proxy/callback/forcesave)| DONE | `core-protocol/src/tool.rs` `ONLYOFFICE_TOOL_*` |
|
||||
| **AI 读写 Office 文件内容(.docx/.xlsx/.pptx)** | **GAP** | 无 `mnote.office.*` Hermes 工具 |
|
||||
|
||||
### 2.5 AI 操作文档 — ✅ 主线已完成
|
||||
|
||||
| 子能力 | 状态 | 关键证据 |
|
||||
|--------|------|----------|
|
||||
| 在线文档 markdown 级读写 | DONE | `mnote.doc.markdown_edit` + `mnote.doc.fetch`,smoke 验证通过 |
|
||||
| 本地 `.md` 文件读/写 | DONE/PARTIAL | `mnote.doc.fetch` 已支持本地文件,写侧仍在过渡(`design/03-rust-web/process/3-13`)|
|
||||
| 结构性块操作(移动/插入/删除)| DONE | `mnote.block.*` 工具群,Hermes 完整 smoke |
|
||||
| 工具权限 / dryRun / 幂等 / revision 约束 | DONE | `bugs/07-ai/done/7-22` ~ `7-30` |
|
||||
| ACP runtime + UI | DONE | `design/07-ai/done/7-25-acp-session-runtime-enhancement-plan-v1.md` |
|
||||
| Phase C(流式 apply / review session)| FROZEN | `design/07-ai/process/7-14` — 当前不实施 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 缺口汇总
|
||||
|
||||
| 缺口 | 分类 | 说明 |
|
||||
|------|------|------|
|
||||
| AI 操作思维导图 | 功能缺失 | Hermes 13 个工具没有 mindmap 操作。AI 无法在导图中增删改节点 |
|
||||
| AI 操作 Office 文件 | 功能缺失 | 无 `mnote.office.*` 工具。OnlyOffice 可手动编辑,但 AI 无法读写 `.docx`/`.xlsx`/`.pptx` 内容 |
|
||||
|
||||
用户确认 "日记" 即当前主编辑区(Tiptap / `.md` 文件),不构成独立缺口。
|
||||
|
||||
---
|
||||
|
||||
## 4. 当前架构收口主线(已完成进度 ~70%)
|
||||
|
||||
```
|
||||
第一优先:Page Aggregate 单一真源 ████████████░░░░░░ 70%
|
||||
└─ EditorBlockDocument 原生落库 ██████░░░░░░░░░░░░ 40%
|
||||
└─ 页面设置运行时闭环 ████████░░░░░░░░░░ 50%
|
||||
└─ AI 写入链走统一 markdown_edit 口径 ██████████████░░░░ 80%
|
||||
|
||||
第二优先:Tree Command Cutover ████████████░░░░░░ 70%
|
||||
└─ tree.resource.* 命令收口 ██████████░░░░░░░░ 60%
|
||||
└─ 资源 rename 补全 ████░░░░░░░░░░░░░░ 30%
|
||||
|
||||
第三优先:Tree Realtime Event Stream ██████████████░░░░ 80%
|
||||
└─ WS 主链已上线 (57ec8322) ████████████████░░ 90%
|
||||
└─ 双浏览器 no-refresh 统一 live cache ██████░░░░░░░░░░░░ 45%
|
||||
└─ SSE fallback / 补偿链减少 ██████████░░░░░░░░ 60%
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 后续方向建议
|
||||
|
||||
1. **继续推进三条架构收口主线**(Page Aggregate → Tree Command → Tree Realtime),这是当前最优先的工程投入点。
|
||||
2. **确认两个功能缺口是否需要本轮填补**:AI 操作思维导图和 Office 文件。如果需要在 MVP 后立即补齐,需要为 `mnote.mindmap.*` 和 `mnote.office.*` 工具做设计;如果可推迟,则当前架构收口完成后再说。
|
||||
3. Local/Cloud 桥接(P3 candidate)和 Phase C AI(流式 apply)属于明确的"下一轮"范围,不在此轮冲刺内。
|
||||
@@ -0,0 +1,206 @@
|
||||
# 1-4 [reference] 下一阶段执行路线图 v1
|
||||
|
||||
> 创建时间:2026-05-19
|
||||
>
|
||||
> 当前状态:`reference`
|
||||
>
|
||||
> 归档说明(2026-05-22):本文保留下一阶段路线推导;当前可执行入口已收敛到 `design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md`,不再从本文直接派发实现。
|
||||
>
|
||||
> 上位依据:
|
||||
> - `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/done/1-3-current-priority-execution-checklist-v1.md`
|
||||
> - `/mnt/Data1T/mnote/design/05-editor-mainline/reference/5-14-zed-lapce-vscode-reference-adoption-matrix-v1.md`
|
||||
> - `/mnt/Data1T/mnote/CURRENT_ARCHITECTURE.md`
|
||||
> - `/mnt/Data1T/mnote/ARCHITECTURE.md`
|
||||
>
|
||||
> 目标:把当前已经推进到混合态的主线,收口成一条更清晰的下一阶段路线,避免“功能继续堆、底座继续散”的问题。
|
||||
|
||||
---
|
||||
|
||||
## 1. 结论
|
||||
|
||||
下一阶段不是全量重写,也不是继续优先补 UI 功能,而是:
|
||||
|
||||
> **以架构收口为主,带着产品化闭环往前推。**
|
||||
|
||||
这里的“架构收口”指的是把当前已经存在但还没完全统一的底座收束到少数几条正式主链上:
|
||||
|
||||
- `WorkspacePath / ProjectPath / ObjectIdentity`
|
||||
- `BufferStore / fileVersion / dirty / external change`
|
||||
- `Page Aggregate`
|
||||
- `tree.*` / `tree.resource.*`
|
||||
- `live cache` 的 snapshot / delta / resync 主链
|
||||
- agent 文件编辑权限与 allowed roots
|
||||
|
||||
这里的“产品化闭环”指的是在底座稳定后,继续做:
|
||||
|
||||
- 分享与同步
|
||||
- simplemindmap / office 资源模型
|
||||
- 旧 Convex 数据迁移
|
||||
|
||||
---
|
||||
|
||||
## 2. 为什么不是先做功能补全
|
||||
|
||||
`1-3` 里已经完成了比较多的可见功能:
|
||||
|
||||
- 管理员目录授权控制面。
|
||||
- VSCode-like 冲突处理 UI。
|
||||
- agent changed files / diff 审计。
|
||||
- 本地搜索、反链、资源引用索引。
|
||||
|
||||
`5-14` 也说明了一个更底层的事实:
|
||||
|
||||
- Zed 更适合作为主架构参考。
|
||||
- Lapce 更适合作为轻量实现参考。
|
||||
- SideX 更适合作为 VS Code 行为迁移到 Rust 后端的桥接参考。
|
||||
- 官方 VS Code 只适合作为行为规格参考。
|
||||
|
||||
这意味着当前真正缺的不是“再加一个功能”,而是:
|
||||
|
||||
> **把这些功能压在同一套身份、版本、命令、搜索和 watcher 主链上。**
|
||||
|
||||
如果继续优先做功能补全,结果通常是:
|
||||
|
||||
- 新功能依赖旧兼容面。
|
||||
- 新能力继续长在不同命令面上。
|
||||
- UI 看起来越来越完整,但底层真相越来越散。
|
||||
|
||||
---
|
||||
|
||||
## 3. 下一阶段三段式推进
|
||||
|
||||
### 3.1 阶段 A:架构收口
|
||||
|
||||
这是当前最优先的阶段。
|
||||
|
||||
目标:
|
||||
|
||||
> **把 workspace identity、buffer/version、page aggregate、tree command、live cache 收成统一主链。**
|
||||
|
||||
应优先推进的事:
|
||||
|
||||
- 统一 `WorkspacePath` / `ProjectPath` / `ObjectIdentity`。
|
||||
- 统一 `BufferStore` / dirty / save / external change 模型。
|
||||
- 继续瘦身 `documents.*`,新增只走 `tree.*` / `tree.resource.*`。
|
||||
- 让 `Page Aggregate` 继续成为页面主投影唯一入口。
|
||||
- 统一 Sidebar / filetree / page subtree / WS / SSE 到同一 live cache。
|
||||
- 让 agent 文件编辑权限、allowed roots、symlink escape、文件版本仲裁保持一致。
|
||||
|
||||
不该做的事:
|
||||
|
||||
- 不重建通用 IDE 壳。
|
||||
- 不优先做 terminal / debugger / extension host。
|
||||
- 不继续扩展旧兼容命令面。
|
||||
|
||||
### 3.2 阶段 B:资源与共享产品化
|
||||
|
||||
架构收口后,第二阶段做产品化闭环。
|
||||
|
||||
目标:
|
||||
|
||||
> **把 simplemindmap / office / 分享 / AI 访问权限纳入同一套资源与权限模型。**
|
||||
|
||||
应优先推进的事:
|
||||
|
||||
- `share grant` 与 `local access grant` 的关系。
|
||||
- `shared AI session` 的权限边界。
|
||||
- `tree.resource.*` 的资源创建 / 重命名 / 移动 / 删除 / 恢复。
|
||||
- simplemindmap / office 的 ObjectIdentity 和 Resource Tree 映射。
|
||||
|
||||
### 3.3 阶段 C:迁移与运营闭环
|
||||
|
||||
最后做迁移和收尾。
|
||||
|
||||
目标:
|
||||
|
||||
> **把旧 Convex 资产迁移成本变成可视、可回滚、可验证的产品流程。**
|
||||
|
||||
应优先推进的事:
|
||||
|
||||
- Convex workspace 导出到本地 root。
|
||||
- dry run。
|
||||
- 备份。
|
||||
- 冲突报告。
|
||||
- 回滚。
|
||||
|
||||
---
|
||||
|
||||
## 4. 和 `1-3` / `5-14` 的关系
|
||||
|
||||
### 4.1 `1-3` 负责告诉我们“当前还剩什么没收口”
|
||||
|
||||
`1-3` 已经把主线拆得很清楚:
|
||||
|
||||
- P0 到 P3 基本是已完成或接近完成的产品能力。
|
||||
- P4 到 P7 仍然是后续主线。
|
||||
- 其中 P7 明确指出:Page Aggregate / tree command / realtime 兼容链还要继续瘦身。
|
||||
|
||||
### 4.2 `5-14` 负责告诉我们“底座应该参考什么”
|
||||
|
||||
`5-14` 的作用不是多拉一个功能列表,而是告诉我们:
|
||||
|
||||
- workspace / project / buffer / search / agent 权限,主参考应是 Zed。
|
||||
- RPC / proxy / config / keymap 的轻量 Rust 组织方式,可以参考 Lapce 和 SideX。
|
||||
- VS Code 只用于行为规格校准。
|
||||
|
||||
### 4.3 合起来的结论
|
||||
|
||||
两份文档合起来,结论就是:
|
||||
|
||||
> **下一阶段的主线是“架构收口 + 产品化闭环”,不是“全量功能扩展”也不是“推倒重写”。**
|
||||
|
||||
---
|
||||
|
||||
## 5. 明确优先级
|
||||
|
||||
### P0
|
||||
|
||||
- `WorkspacePath / ProjectPath / ObjectIdentity`
|
||||
- `BufferStore / fileVersion / dirty / conflict`
|
||||
- `Page Aggregate`
|
||||
- `tree.*` / `tree.resource.*`
|
||||
- `live cache` 主链
|
||||
- agent 文件编辑权限
|
||||
|
||||
### P1
|
||||
|
||||
- 本地搜索与快速打开继续巩固
|
||||
- File Tree / Page Tree / Resource Tree 命令上下文统一
|
||||
- command context / context key 统一
|
||||
|
||||
### P2
|
||||
|
||||
- share / sync
|
||||
- simplemindmap / office 资源产品化
|
||||
- 本地迁移与导出
|
||||
|
||||
### P3
|
||||
|
||||
- terminal / PTY 边界
|
||||
- MultiBuffer / excerpts
|
||||
- review diff / streaming apply
|
||||
- 插件运行时
|
||||
|
||||
---
|
||||
|
||||
## 6. 当前不做什么
|
||||
|
||||
- 不把 MNote 拉成通用 IDE。
|
||||
- 不先做 extension host / debugger / terminal 优先级升级。
|
||||
- 不让 `documents.*` 继续长成新主命令面。
|
||||
- 不把 Tauri desktop shell 当成当前主壳方向。
|
||||
- 不把 UI 功能增长误当成主线前进。
|
||||
|
||||
---
|
||||
|
||||
## 7. 下一步建议
|
||||
|
||||
接下来最合理的动作是:
|
||||
|
||||
1. 先按 `1-4` 这条路线图推进架构收口。
|
||||
2. 在 `1-3` 里把 `P7` 拆成明确的收口子任务。
|
||||
3. 等底座稳定后,再把 `P4-P6` 推成产品化闭环。
|
||||
|
||||
一句话结论:
|
||||
|
||||
> **先收口主链,再做产品化。**
|
||||
+698
@@ -0,0 +1,698 @@
|
||||
# 1-5 [reference] 下一阶段顺序执行 checklist v1
|
||||
|
||||
> 创建时间:2026-05-19
|
||||
>
|
||||
> 当前状态:`reference`
|
||||
>
|
||||
> 归档说明(2026-05-22):本文是历史顺序清单,部分条目已被后续 Batch / done 文档覆盖;当前只作为参考,不再作为 active process 队列。
|
||||
>
|
||||
> 上位依据:
|
||||
> - `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/reference/1-4-next-phase-execution-roadmap-v1.md`
|
||||
> - `/mnt/Data1T/mnote/design/01-tree-first-graph-kernel/done/1-3-current-priority-execution-checklist-v1.md`
|
||||
> - `/mnt/Data1T/mnote/design/05-editor-mainline/reference/5-14-zed-lapce-vscode-reference-adoption-matrix-v1.md`
|
||||
>
|
||||
> 目标:给出一份可以顺序执行、每一步都有完成验收、且标明参考源码位置的下一阶段执行清单。
|
||||
|
||||
---
|
||||
|
||||
## 0. 执行原则
|
||||
|
||||
- [ ] 每个阶段必须先补或确认测试,再改实现。
|
||||
- [ ] 每个阶段只能收口当前主链,不新增通用 IDE 产品面。
|
||||
- [ ] 新增长期命令必须优先走 `tree.*` / `tree.resource.*` / `page.*`,不能继续扩 `documents.*`。
|
||||
- [ ] 涉及本地文件写入时,必须携带 workspace identity、allowed roots、expected file version。
|
||||
- [ ] 涉及 UI / live stream 时,必须补 browser smoke 或复用既有 smoke。
|
||||
- [ ] 每完成一个阶段,必须把验证命令和 smoke 证据写回本文件或 `1-3`。
|
||||
|
||||
---
|
||||
|
||||
## 1. Phase A0:建立执行基线
|
||||
|
||||
目标:
|
||||
|
||||
> **确认当前 P0-P3 既有能力仍然稳定,避免在架构收口前带着红灯推进。**
|
||||
|
||||
### 1.1 基线验证
|
||||
|
||||
- [ ] 运行 Rust 格式检查。
|
||||
- 命令:`cargo fmt --check --all --manifest-path rust/Cargo.toml`
|
||||
- 完成验收:命令通过。
|
||||
|
||||
- [ ] 运行 local-first 权限与 workspace 基线测试。
|
||||
- 命令:`cargo test -p mnote-web local_folder -- --nocapture`
|
||||
- 命令:`cargo test -p mnote-web local_access_policy -- --nocapture`
|
||||
- 命令:`cargo test -p mnote-web hermes_client_local_acp -- --nocapture`
|
||||
- 完成验收:三组测试通过。
|
||||
|
||||
- [ ] 运行 Page Aggregate / tree command 基线测试。
|
||||
- 命令:`cargo test -p mnote-web page_aggregate -- --nocapture`
|
||||
- 命令:`cargo test -p mnote-web tree_command -- --nocapture`
|
||||
- 完成验收:两组测试通过。
|
||||
|
||||
- [ ] 运行 local-first guard。
|
||||
- 命令:`npm run check:local-first-convex-guard`
|
||||
- 完成验收:命令通过,新增路径没有把 Convex 恢复成默认正文主存储。
|
||||
|
||||
### 1.2 基线 smoke
|
||||
|
||||
- [ ] 冲突 UI smoke。
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task451-local-markdown-conflict-resolution-ui-smoke.js`
|
||||
- 完成验收:tiptap 与外部/agent 写入冲突仍能显示、合并、保存。
|
||||
|
||||
- [ ] 本地搜索索引 smoke。
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task452-local-search-index-browser-smoke.js`
|
||||
- 完成验收:新建、重命名、搜索、反链、标签仍稳定。
|
||||
|
||||
- [ ] agent changed files smoke。
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task453-local-folder-page-ai-changed-files-smoke.js`
|
||||
- 完成验收:AI 写入后 UI 能显示 `agent.changed_files`。
|
||||
|
||||
---
|
||||
|
||||
## 2. Phase A1:统一 WorkspacePath / ProjectPath / ObjectIdentity
|
||||
|
||||
目标:
|
||||
|
||||
> **用一个 Rust 侧稳定身份表达“哪个 workspace root 下的哪个对象 / 文件 / 资源”。**
|
||||
|
||||
### 2.1 当前代码锚点
|
||||
|
||||
- MNote:
|
||||
- `rust/crates/core-protocol/src/kernel.rs`
|
||||
- `KernelObjectIdentity`
|
||||
- `PageBodyWriteRequest`
|
||||
- `rust/crates/core-protocol/src/lib.rs`
|
||||
- `rust/crates/mnote-web/src/routes/local_folder_source.rs`
|
||||
- `rust/crates/mnote-web/src/ssr/pages/layout.rs`
|
||||
- `fileObjectIdentity`
|
||||
- `readFileTreeObjectIdentity`
|
||||
- `rust/crates/mnote-web/src/routes/tree.rs`
|
||||
|
||||
### 2.2 参考代码位置
|
||||
|
||||
- Zed:
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/project/src/project.rs`
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/project/src/worktree_store.rs`
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/worktree/src/worktree.rs`
|
||||
- SideX:
|
||||
- `design/05-editor-mainline/reference-code/sidex-main/crates/sidex-workspace/src/path_util.rs`
|
||||
- `design/05-editor-mainline/reference-code/sidex-main/crates/sidex-workspace/src/multi_root.rs`
|
||||
- `design/05-editor-mainline/reference-code/sidex-main/crates/sidex-workspace/src/workspace.rs`
|
||||
|
||||
### 2.3 顺序任务
|
||||
|
||||
- [ ] 盘点当前所有 path key / object key。
|
||||
- 搜索命令:`rg -n "ObjectIdentity|objectIdentity|rootUri|relativePath|fileVersion|documentId" rust/crates/mnote-web rust/crates/core-protocol -S`
|
||||
- 完成验收:列出哪些入口仍只用 `documentId`、绝对路径或前端拼接 key。
|
||||
|
||||
- [ ] 在 `core-protocol` 中明确 `WorkspacePath` 或等价结构。
|
||||
- 建议字段:`workspace_id`、`root_uri`、`root_id`、`relative_path`、`source_kind`、`object_identity`、`resource_kind`。
|
||||
- 完成验收:结构能表达页面 `.md`、mindmap、office、附件、目录节点。
|
||||
|
||||
- [ ] 给 local folder file tree 输出稳定 identity。
|
||||
- 重点文件:`rust/crates/mnote-web/src/routes/local_folder_source.rs`
|
||||
- 完成验收:File Tree row、Page Tree row、Resource row 均能携带统一 identity,不再由前端临时猜测。
|
||||
|
||||
- [ ] 前端 sidebar/filetree 消费统一 identity。
|
||||
- 重点文件:`rust/crates/mnote-web/src/ssr/pages/layout.rs`
|
||||
- 完成验收:`fileObjectIdentity` / `readFileTreeObjectIdentity` 不再作为事实源,只作为兼容读取层。
|
||||
|
||||
### 2.4 验收
|
||||
|
||||
- [ ] 单测覆盖 identity 序列化与反序列化。
|
||||
- 建议命令:`cargo test -p core-protocol object_identity -- --nocapture`
|
||||
|
||||
- [ ] local folder tree 测试覆盖页面 `.md` 和资源对象 identity。
|
||||
- 建议命令:`cargo test -p mnote-web local_folder -- --nocapture`
|
||||
|
||||
- [ ] 浏览器 smoke 覆盖 filetree active reveal 和标题同步。
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task438-filetree-title-md-active-reveal-smoke.js`
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task440-page-title-filetree-md-sync-smoke.js`
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] 本地页面、资源、附件、目录节点都能映射到同一套 workspace identity。
|
||||
- [ ] UI 不再需要通过文件名或 DOM 属性临时反推对象身份。
|
||||
|
||||
---
|
||||
|
||||
## 3. Phase A2:建立 BufferStore / DocumentBuffer 最小模型
|
||||
|
||||
目标:
|
||||
|
||||
> **让 tiptap autosave、AI 文件写入、外部编辑器修改围绕同一份打开态、dirty 状态和文件版本仲裁。**
|
||||
|
||||
### 3.1 当前代码锚点
|
||||
|
||||
- `rust/crates/core-protocol/src/kernel.rs`
|
||||
- `PageBodyWriteRequest.expected_file_version`
|
||||
- `rust/crates/mnote-web/src/routes/documents.rs`
|
||||
- `/api/page-body/write`
|
||||
- `/api/documents/save` compat
|
||||
- `rust/crates/mnote-web/src/routes/local_folder_source.rs`
|
||||
- `write_local_markdown_page_body`
|
||||
- `save_local_markdown_page`
|
||||
- `rust/crates/mnote-web/src/routes/web_shell.rs`
|
||||
- `conflictDetectionKey`
|
||||
- `fileVersion`
|
||||
- `rust/crates/mnote-web/src/routes/editor.rs`
|
||||
|
||||
### 3.2 参考代码位置
|
||||
|
||||
- Zed:
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/project/src/buffer_store.rs`
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/editor/src/editor.rs`
|
||||
- Lapce:
|
||||
- `design/05-editor-mainline/reference-code/lapce/lapce-app/src/doc.rs`
|
||||
- VS Code:
|
||||
- `design/05-editor-mainline/reference-code/vscode/src/vs/platform/files`
|
||||
- `design/05-editor-mainline/reference-code/vscode/src/vs/workbench/services/filesConfiguration`
|
||||
|
||||
### 3.3 顺序任务
|
||||
|
||||
- [ ] 盘点所有文件写入口。
|
||||
- 搜索命令:`rg -n "documents.save|page.body.save|page-body/write|write_local_markdown|expectedFileVersion|conflictDetectionKey" rust/crates -S`
|
||||
- 完成验收:列出 tiptap、Hermes tool、page save、documents compat、外部 watcher 入口。
|
||||
|
||||
- [ ] 定义 `DocumentBuffer` 最小字段。
|
||||
- 建议字段:`workspace_path`、`file_version`、`base_content_hash`、`current_content_hash`、`dirty_state`、`external_change_state`、`last_loaded_at`、`last_saved_at`。
|
||||
- 完成验收:字段能覆盖 clean、dirty、stale、external modified、deleted 五种状态。
|
||||
|
||||
- [ ] 让 `/api/page-body/write` 成为本地 `.md` 正文写入主入口。
|
||||
- 重点文件:`rust/crates/mnote-web/src/routes/documents.rs`
|
||||
- 完成验收:本地 markdown 写入必须携带 `expectedFileVersion`;`documents/save` 只作为 compat adapter。
|
||||
|
||||
- [ ] 把冲突 UI 的 source 数据改为来自 buffer 状态。
|
||||
- 重点文件:`rust/crates/mnote-web/src/ssr/pages/layout.rs`
|
||||
- 完成验收:冲突面板能显示 editor base version、disk version、source actor。
|
||||
|
||||
### 3.4 验收
|
||||
|
||||
- [ ] stale 写入被拒绝。
|
||||
- 命令:`cargo test -p mnote-web local_folder_documents_save_rejects_stale_expected_file_version -- --nocapture`
|
||||
|
||||
- [ ] Page Body 写入测试通过。
|
||||
- 命令:`cargo test -p mnote-web page_aggregate -- --nocapture`
|
||||
|
||||
- [ ] 冲突 UI smoke 通过。
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task451-local-markdown-conflict-resolution-ui-smoke.js`
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] tiptap、AI、外部修改共享同一版本仲裁模型。
|
||||
- [ ] 外部文件变更不能静默覆盖 dirty buffer。
|
||||
- [ ] `documents/save` 不再被新增路径当作长期主入口。
|
||||
|
||||
---
|
||||
|
||||
## 4. Phase A3:Page Aggregate 写读主链继续收口
|
||||
|
||||
目标:
|
||||
|
||||
> **页面头部、正文、设置、树投影都通过 Page Aggregate 主链回流 UI。**
|
||||
|
||||
### 4.1 当前代码锚点
|
||||
|
||||
- `rust/crates/core-protocol/src/page_aggregate.rs`
|
||||
- `rust/crates/mnote-web/src/routes/documents.rs`
|
||||
- `rust/crates/mnote-web/src/ssr/pages/document.rs`
|
||||
- `rust/crates/mnote-web/src/ssr/pages/layout.rs`
|
||||
- `rust/crates/bridge-runtime/src/lib.rs`
|
||||
- `rust/crates/storage-convex-bridge/src/mapping.rs`
|
||||
|
||||
### 4.2 参考代码位置
|
||||
|
||||
- Zed:
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/project/src/project.rs`
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/project/src/worktree_store.rs`
|
||||
- VS Code:
|
||||
- `design/05-editor-mainline/reference-code/vscode/src/vs/workbench/contrib/files`
|
||||
|
||||
### 4.3 顺序任务
|
||||
|
||||
- [ ] 盘点仍直接拼 `meta + content` 或读取 `documents.content` 的 runtime 路径。
|
||||
- 搜索命令:`rg -n "documents.content|getContent|getMeta|meta \\+ content|page_aggregate|pageAggregate" rust/crates wolai-frontend src -S`
|
||||
- 完成验收:列出仍存在的 runtime fallback,并标记 `compat only` 或待删除。
|
||||
|
||||
- [ ] 标题、正文、页面设置写入后只触发 Page Aggregate refresh。
|
||||
- 重点文件:`rust/crates/mnote-web/src/routes/documents.rs`
|
||||
- 重点文件:`rust/crates/mnote-web/src/ssr/pages/layout.rs`
|
||||
- 完成验收:写入后 UI 更新来源能追溯到 Page Aggregate,而不是局部补偿状态。
|
||||
|
||||
- [ ] 明确 `documents.*` 在 Page Aggregate 中的兼容边界。
|
||||
- 重点文件:`rust/crates/storage-convex-bridge/src/mapping.rs`
|
||||
- 完成验收:新增语义不再加到 `documents.*`,旧命令只作为 adapter。
|
||||
|
||||
### 4.4 验收
|
||||
|
||||
- [ ] Page Aggregate Rust 测试通过。
|
||||
- 命令:`cargo test -p mnote-web page_aggregate -- --nocapture`
|
||||
- 命令:`cargo test -p bridge-runtime page_aggregate -- --nocapture`
|
||||
|
||||
- [ ] 页面标题、正文、设置 smoke 通过。
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task110-page-title-single-truth-smoke.js`
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task-page-aggregate-body-sync-smoke.js`
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task-page-aggregate-options-sync-smoke.js`
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task-page-aggregate-refresh-persistence-smoke.js`
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] 文档页不再新增 `meta + content` 拼装真相。
|
||||
- [ ] 标题、正文、页面设置刷新后仍一致。
|
||||
- [ ] Page Aggregate provenance 能清楚区分 local markdown、compat join、kernel projection。
|
||||
|
||||
---
|
||||
|
||||
## 5. Phase A4:tree command / tree.resource command 收口
|
||||
|
||||
目标:
|
||||
|
||||
> **页面和资源操作统一走 `tree.*` / `tree.resource.*`,`documents.*` 只保留兼容。**
|
||||
|
||||
### 5.1 当前代码锚点
|
||||
|
||||
- `rust/crates/mnote-web/src/routes/tree.rs`
|
||||
- `rust/crates/bridge-runtime/src/lib.rs`
|
||||
- `rust/crates/storage-convex-bridge/src/mapping.rs`
|
||||
- `rust/crates/mnote-cli/src/lib.rs`
|
||||
- `rust/crates/mnote-web/src/transport/convex.rs`
|
||||
|
||||
### 5.2 参考代码位置
|
||||
|
||||
- Zed:
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/project_panel/src/project_panel.rs`
|
||||
- VS Code:
|
||||
- `design/05-editor-mainline/reference-code/vscode/src/vs/platform/commands`
|
||||
- `design/05-editor-mainline/reference-code/vscode/src/vs/workbench/contrib/files`
|
||||
- SideX:
|
||||
- `design/05-editor-mainline/reference-code/sidex-main/src-tauri/src/commands/fs.rs`
|
||||
- `design/05-editor-mainline/reference-code/sidex-main/crates/sidex-workspace/src/file_operations.rs`
|
||||
|
||||
### 5.3 顺序任务
|
||||
|
||||
- [ ] 盘点仍使用 `documents.*` 的命令入口。
|
||||
- 搜索命令:`rg -n "\"documents\\.|documents\\." rust/crates infra src wolai-frontend -S`
|
||||
- 完成验收:输出保留清单,逐项标记为 `compat adapter`、`test fixture`、`must cutover`。
|
||||
|
||||
- [ ] 将新增页面操作固定为 `tree.node.*`。
|
||||
- 完成验收:新建、重命名、移动、归档、恢复、删除不再新增 `documents.*` 调用。
|
||||
|
||||
- [ ] 将资源操作固定为 `tree.resource.*`。
|
||||
- 完成验收:mindmap、office、附件 rename/move/archive/restore/purge 都有正式命令名。
|
||||
|
||||
- [ ] mnote-cli 中历史 `documents.*` 命令降级为 compat。
|
||||
- 重点文件:`rust/crates/mnote-cli/src/lib.rs`
|
||||
- 完成验收:CLI 新增命令使用 `tree.*` 或 `tree.resource.*`。
|
||||
|
||||
### 5.4 验收
|
||||
|
||||
- [ ] tree command 单测通过。
|
||||
- 命令:`cargo test -p mnote-web tree_command -- --nocapture`
|
||||
- 命令:`cargo test -p bridge-runtime tree_command -- --nocapture`
|
||||
|
||||
- [ ] 文件树操作 smoke 通过。
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task179-tree-create-delete-no-reload-smoke.js`
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task446-tree-rename-dual-browser-live-smoke.js`
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task447-tree-move-order-dual-browser-live-smoke.js`
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] 新增长期命令面不再出现 `documents.*`。
|
||||
- [ ] `storage-convex-bridge` 只把正式命令映射到 Convex 兼容 mutation。
|
||||
- [ ] 资源生命周期命令能统一产生 tree stream delta hint。
|
||||
|
||||
---
|
||||
|
||||
## 6. Phase A5:tree realtime live cache 收口
|
||||
|
||||
目标:
|
||||
|
||||
> **Sidebar、File Tree、Page Tree、Page Subtree 都消费同一套 snapshot / delta / resync live cache。**
|
||||
|
||||
### 6.1 当前代码锚点
|
||||
|
||||
- `rust/crates/mnote-web/src/routes/sse.rs`
|
||||
- `rust/crates/mnote-web/src/routes/realtime_ws.rs`
|
||||
- `rust/crates/mnote-web/src/ssr/pages/layout.rs`
|
||||
- `tree:snapshot`
|
||||
- `tree:delta`
|
||||
- `tree:resync`
|
||||
- `deltaNeedsProjectionRefresh`
|
||||
- `rust/crates/bridge-runtime/src/lib.rs`
|
||||
- `tree_stream_delta_hint`
|
||||
- `materialize_tree_stream_delta`
|
||||
|
||||
### 6.2 参考代码位置
|
||||
|
||||
- Zed:
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/worktree/src/worktree.rs`
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/project/src/worktree_store.rs`
|
||||
- Lapce:
|
||||
- `design/05-editor-mainline/reference-code/lapce/lapce-proxy/src/watcher.rs`
|
||||
- SideX:
|
||||
- `design/05-editor-mainline/reference-code/sidex-main/crates/sidex-workspace/src/watcher.rs`
|
||||
|
||||
### 6.3 顺序任务
|
||||
|
||||
- [ ] 盘点所有 tree/page/filetree 刷新来源。
|
||||
- 搜索命令:`rg -n "tree:snapshot|tree:delta|tree:resync|EventSource|WebSocket|poll|refetch|preferred snapshot|pageSubtree" rust/crates/mnote-web/src -S`
|
||||
- 完成验收:标出 WS 主链、SSE fallback、polling/refetch 补偿链。
|
||||
|
||||
- [ ] 明确 WS 是主链、SSE 是 fallback。
|
||||
- 重点文件:`rust/crates/mnote-web/src/ssr/pages/layout.rs`
|
||||
- 完成验收:SSE 不和 WS 并行长期消费同一事件,只有 WS 不可用时 fallback。
|
||||
|
||||
- [ ] delta 能处理时直接 apply,不能处理时 resync。
|
||||
- 重点文件:`rust/crates/mnote-web/src/ssr/pages/layout.rs`
|
||||
- 重点文件:`rust/crates/bridge-runtime/src/lib.rs`
|
||||
- 完成验收:`deltaNeedsProjectionRefresh` 不再成为常态路径。
|
||||
|
||||
- [ ] 删除或降级不必要的 polling / refetch 补偿链。
|
||||
- 完成验收:页面/文件树操作不靠定时轮询才能稳定。
|
||||
|
||||
### 6.4 验收
|
||||
|
||||
- [ ] realtime route 单测通过。
|
||||
- 命令:`cargo test -p mnote-web tree_realtime -- --nocapture`
|
||||
- 命令:`cargo test -p mnote-web local_folder -- --nocapture`
|
||||
|
||||
- [ ] 双浏览器 live smoke 通过。
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task446-tree-rename-dual-browser-live-smoke.js`
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task447-tree-move-order-dual-browser-live-smoke.js`
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task448-tree-resync-recovery-dual-browser-smoke.js`
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task449-tree-sse-reconnect-snapshot-recovery-smoke.js`
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] 双浏览器页面、文件、垃圾箱操作不刷新页面也能同步。
|
||||
- [ ] WS 主链可用时 SSE 只作为 fallback。
|
||||
- [ ] resync 是异常恢复路径,不是每次 delta 后的默认补偿。
|
||||
|
||||
---
|
||||
|
||||
## 7. Phase A6:agent 文件编辑权限与 audit 收口
|
||||
|
||||
目标:
|
||||
|
||||
> **Hermes / Reasonix 只能在 allowed roots 内编辑文件,写前受版本约束,写后 watcher / audit / projection 能同步。**
|
||||
|
||||
### 7.1 当前代码锚点
|
||||
|
||||
- `rust/crates/core-protocol/src/ai.rs`
|
||||
- `AiAccessScope`
|
||||
- `allowed_roots`
|
||||
- `rust/crates/mnote-web/src/routes/hermes_client.rs`
|
||||
- `acp_allowed_roots_env_for_payload`
|
||||
- `local_agent_audit_collect_snapshot`
|
||||
- `local_agent_audit_finalize_run`
|
||||
- `rust/crates/mnote-web/src/routes/hermes_tools.rs`
|
||||
- `local_agent_audit_record_write_rejected`
|
||||
- `local_agent_audit_record_tool_write`
|
||||
- `rust/crates/mnote-web/src/hermes_tools/doc.rs`
|
||||
- `rust/crates/mnote-web/src/hermes_tools/page.rs`
|
||||
|
||||
### 7.2 参考代码位置
|
||||
|
||||
- Zed:
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/agent/src/tools/edit_file_tool.rs`
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/agent/src/tools/read_file_tool.rs`
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/agent/src/tools/write_file_tool.rs`
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/agent/src/tools/edit_session.rs`
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/agent/src/tool_permissions.rs`
|
||||
- SideX:
|
||||
- `design/05-editor-mainline/reference-code/sidex-main/src-tauri/src/commands/validation.rs`
|
||||
- `design/05-editor-mainline/reference-code/sidex-main/src-tauri/src/commands/fs.rs`
|
||||
|
||||
### 7.3 顺序任务
|
||||
|
||||
- [ ] 盘点所有 agent 写入口。
|
||||
- 搜索命令:`rg -n "mnote.doc.markdown_edit|mnote.page.save|mnote.block|allowed_roots|AiAccessScope|write_rejected|agent_audit" rust/crates/mnote-web/src rust/crates/core-protocol/src -S`
|
||||
- 完成验收:列出 Hermes tool、Reasonix/ACP、agent native file edit、MNote tool 写入入口。
|
||||
|
||||
- [ ] allowed roots 校验统一到一个 Rust helper。
|
||||
- 完成验收:所有写入口共用同一套 root canonicalization、symlink escape、read/write permission 校验。
|
||||
|
||||
- [ ] agent 写入前读取当前 file version。
|
||||
- 完成验收:MNote tool 写入必须携带 `expectedFileVersion`;agent native 写入完成后必须进入 audit + watcher 同步路径。
|
||||
|
||||
- [ ] audit event 统一 run id 和 changed files 结构。
|
||||
- 重点文件:`rust/crates/mnote-web/src/routes/hermes_client.rs`
|
||||
- 完成验收:agent native 写入和 MNote tool 写入可归入同一个 run audit。
|
||||
|
||||
### 7.4 验收
|
||||
|
||||
- [ ] allowed roots env 测试通过。
|
||||
- 命令:`cargo test -p mnote-web acp_allowed_roots -- --nocapture`
|
||||
|
||||
- [ ] audit 单测通过。
|
||||
- 命令:`cargo test -p mnote-web local_agent_audit_snapshot_detects_changed_files -- --nocapture`
|
||||
- 命令:`cargo test -p mnote-web hermes_tools_markdown_edit_shared_read -- --nocapture`
|
||||
- 命令:`cargo test -p mnote-web hermes_tools_page_save_local_folder_writes_markdown_file -- --nocapture`
|
||||
|
||||
- [ ] changed files smoke 通过。
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task453-local-folder-page-ai-changed-files-smoke.js`
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] read grant 下写入被拒绝并记录 audit。
|
||||
- [ ] write grant 下写入后 UI 能显示 changed files。
|
||||
- [ ] agent 不能通过 symlink 或 `..` 逃出 allowed roots。
|
||||
|
||||
---
|
||||
|
||||
## 8. Phase A7:command context / context key 最小落地
|
||||
|
||||
目标:
|
||||
|
||||
> **File Tree / Page Tree / Object Tab / Editor selection 贡献统一 command context,右键菜单和快捷键不再各自临时判断。**
|
||||
|
||||
### 8.1 当前代码锚点
|
||||
|
||||
- `rust/crates/mnote-web/src/ssr/pages/layout.rs`
|
||||
- `rust/crates/mnote-web/src/routes/tree.rs`
|
||||
- `rust/crates/core-protocol/src/command.rs`
|
||||
|
||||
### 8.2 参考代码位置
|
||||
|
||||
- VS Code:
|
||||
- `design/05-editor-mainline/reference-code/vscode/src/vs/platform/contextkey`
|
||||
- `design/05-editor-mainline/reference-code/vscode/src/vs/platform/commands`
|
||||
- SideX:
|
||||
- `design/05-editor-mainline/reference-code/sidex-main/crates/sidex-keymap/src/context.rs`
|
||||
- `design/05-editor-mainline/reference-code/sidex-main/crates/sidex-keymap/src/resolver.rs`
|
||||
- Lapce:
|
||||
- `design/05-editor-mainline/reference-code/lapce/lapce-app/src/command.rs`
|
||||
- `design/05-editor-mainline/reference-code/lapce/lapce-app/src/keypress/loader.rs`
|
||||
|
||||
### 8.3 顺序任务
|
||||
|
||||
- [x] 盘点当前菜单、快捷键、按钮 enablement 条件。
|
||||
- 搜索命令:`rg -n "disabled|aria-disabled|context|shortcut|keydown|menu|right-click|data-action" rust/crates/mnote-web/src/ssr/pages/layout.rs -S`
|
||||
- 完成验收:列出至少 filetree、pagetree、editor、AI panel 的条件来源。
|
||||
- **执行记录(Batch C Worker C)**:FileTree 右键菜单(delete-trash/rename/new-file/new-folder/paste-into 共 5 项,均携带 `when`)和 Delete/Backspace 快捷键已审计并完成上下文接入。AI panel 条件由 `ai.canWrite` 在 hermes_tools 守卫中消费。
|
||||
|
||||
- [x] 定义 MNote 最小 command context。
|
||||
- 完成 key:`workspace.sourceKind`、`workspace.readonly`、`tree.focusKind`、`tree.selectionCount`、`tree.selectionResourceKind`、`editor.dirty`、`editor.hasSelection`、`ai.canWrite` 共 8 个 key。
|
||||
- 完成验收:这些 key 已覆盖当前右键菜单、快捷键和 AI write guard enablement。
|
||||
- **代码证明**:`rust/crates/core-protocol/src/command.rs` 中 `CommandContext` 结构体包含全部 8 个字段;7 个单测覆盖 when 求值全路径。
|
||||
|
||||
- [x] 先在 Rust 侧定义 context schema,再让前端消费。
|
||||
- Rust 侧:`core-protocol/src/command.rs` — `CommandContext` + `WhenExprNode` + `evaluate_when` / `check_when` / `is_command_enabled`。
|
||||
- 前端侧(SSR `layout.rs`):`buildSidebarFileTreeContext()` + `evaluateSidebarFileTreeWhen()` 两个 JS 等价物用于右键菜单启禁。
|
||||
- 完成验收:FileTree 右键菜单和 Delete/Backspace 共享同一 `evaluateSidebarFileTreeWhen` 路径。
|
||||
|
||||
### 8.4 验收
|
||||
|
||||
- [x] command context 单测覆盖 `when` 判断。
|
||||
- 命令:`cargo test -p core-protocol command_context -- --nocapture`
|
||||
- **结果(2026-05-21)**:7 passed — 覆盖 key、`!key`、`==`、`!=`、`&&`、`||`、括号分组、number comparison、parse error fallback、`ai.canWrite` gate、`workspace.readonly` gate。
|
||||
|
||||
- [x] 文件树 DnD / readonly conflict smoke 通过。
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task431-vscode-explorer-dnd-readonly-conflict-smoke.js`
|
||||
- **证据**:`tmp/task431-vscode-explorer-dnd-readonly-conflict-smoke/result.json` — `ok: true`,readonly-target 和 readonly-source 均返回 400。
|
||||
|
||||
完成标准:
|
||||
|
||||
- [x] 同一命令在菜单、快捷键、按钮上使用同一 context 判断。
|
||||
- FileTree 右键菜单(delete-trash/rename/new-file/new-folder/paste-into)与 Delete/Backspace 快捷键共享 `evaluateSidebarFileTreeWhen` 路径。
|
||||
- **保留的缺口**:editor/object tab 上下文尚未接入 command context;AI tool 写入守卫 `ensure_write_authorized` 是独立路径(读 `args.commandContext`,非前端 context key)。
|
||||
- [x] readonly / read grant / selected resource kind 的禁用态一致。
|
||||
- FileTree 右键菜单 readonly 禁用已通过 `!workspace.readonly` when 表达式统一实现。
|
||||
|
||||
---
|
||||
|
||||
## 9. Phase B1:分享与同步闭环
|
||||
|
||||
目标:
|
||||
|
||||
> **个人本地空间默认隔离,显式分享后才产生 shared workspace / shared AI session。**
|
||||
|
||||
### 9.1 当前代码锚点
|
||||
|
||||
- `rust/crates/mnote-web/src/routes/local_access_policy.rs`
|
||||
- `rust/crates/mnote-web/src/routes/hermes_client.rs`
|
||||
- `rust/crates/core-protocol/src/ai.rs`
|
||||
- `recycle/20260522-convex-runtime-retirement/infra/convex/`(历史 Convex 自托管对照;不作为 active 部署入口)
|
||||
|
||||
### 9.2 参考代码位置
|
||||
|
||||
- VS Code:
|
||||
- `design/05-editor-mainline/reference-code/vscode/src/vs/platform/files`
|
||||
- Zed:
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/collab`
|
||||
- 仅参考权限和协作边界,不采用完整协作产品。
|
||||
|
||||
### 9.3 顺序任务
|
||||
|
||||
- [ ] 定义 share grant 与 local access grant 的关系。
|
||||
- 完成验收:share grant 不自动扩大本机文件系统权限。
|
||||
|
||||
- [ ] shared AI session 只消费 share grant 允许的资源。
|
||||
- 完成验收:shared AI session 不能访问 owner 本机未授权 root。
|
||||
|
||||
- [ ] 同步 cache 目录设计。
|
||||
- 完成验收:cache 中保留来源、版本、actor、权限、冲突信息。
|
||||
|
||||
- [ ] 同步冲突复用 Phase A2 冲突 UI。
|
||||
- 完成验收:冲突报告包含 local、remote、base、actor。
|
||||
|
||||
### 9.4 验收
|
||||
|
||||
- [ ] 单测:share read 不允许写入。
|
||||
- [ ] 单测:shared AI session 不扩大 workspace root。
|
||||
- [ ] browser smoke:共享页面只读用户无法通过 AI 写入正文。
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] share / sync 不破坏 local-first 权限模型。
|
||||
- [ ] shared AI session 不能越权读写。
|
||||
|
||||
---
|
||||
|
||||
## 10. Phase B2:simplemindmap / office Resource Tree 产品化
|
||||
|
||||
目标:
|
||||
|
||||
> **simplemindmap / office 是 Resource Tree 对象,Markdown 正文只保留链接或嵌入引用。**
|
||||
|
||||
### 10.1 当前代码锚点
|
||||
|
||||
- `rust/crates/mnote-web/src/routes/mindmap_api.rs`
|
||||
- `rust/crates/mnote-web/src/routes/mindmap_shell.rs`
|
||||
- `rust/crates/mnote-web/src/ssr/pages/mindmap.rs`
|
||||
- `rust/crates/mnote-web/src/routes/tree.rs`
|
||||
- `rust/crates/bridge-runtime/src/lib.rs`
|
||||
- `src/components/onlyoffice/`
|
||||
|
||||
### 10.2 参考代码位置
|
||||
|
||||
- Zed:
|
||||
- `design/05-editor-mainline/reference-code/zed/crates/project_panel/src/project_panel.rs`
|
||||
- VS Code:
|
||||
- `design/05-editor-mainline/reference-code/vscode/src/vs/workbench/contrib/files`
|
||||
- SideX:
|
||||
- `design/05-editor-mainline/reference-code/sidex-main/crates/sidex-workspace/src/file_tree.rs`
|
||||
|
||||
### 10.3 顺序任务
|
||||
|
||||
- [ ] 盘点 simplemindmap object identity、保存路径、打开路径。
|
||||
- 搜索命令:`rg -n "mindmap|tree.resource.mindmap|resource:mindmap|mindmapId" rust/crates src -S`
|
||||
- 完成验收:列出所有 mindmap 创建、打开、保存、删除路径。
|
||||
|
||||
- [ ] 盘点 office object identity、保存路径、打开路径。
|
||||
- 搜索命令:`rg -n "onlyoffice|office|tree.resource.office|resource:office|assetId" rust/crates src -S`
|
||||
- 完成验收:列出所有 office 创建、打开、保存、删除路径。
|
||||
|
||||
- [ ] 统一资源生命周期到 `tree.resource.*`。
|
||||
- 完成验收:rename / move / archive / restore / purge 不再走 document command。
|
||||
|
||||
- [ ] Markdown 中只写资源引用。
|
||||
- 完成验收:mindmap / office 内容不塞回 `.md` 正文真相。
|
||||
|
||||
### 10.4 验收
|
||||
|
||||
- [ ] 单测:resource rename 不走 document command。
|
||||
- [ ] 单测:mindmap resource 删除 / 恢复不破坏 markdown 页面。
|
||||
- [ ] browser smoke:mindmap 长中文保存和 index.md 不互相污染。
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task443-filetree-mindmap-click-active-row-smoke.js`
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task445-filetree-mindmap-switch-no-flicker-smoke.js`
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] Page Tree 只做页面导航投影。
|
||||
- [ ] File Tree 能显示资源行。
|
||||
- [ ] Resource Tree 才是资源归属真相。
|
||||
|
||||
---
|
||||
|
||||
## 11. Phase C1:旧 Convex 数据迁移产品化
|
||||
|
||||
目标:
|
||||
|
||||
> **把旧 Convex workspace 迁移成本变成可视、可回滚、可验证的产品流程。**
|
||||
|
||||
### 11.1 当前代码锚点
|
||||
|
||||
- `rust/crates/storage-convex-bridge/src/mapping.rs`
|
||||
- `rust/crates/mnote-web/src/transport/convex.rs`
|
||||
- `rust/crates/mnote-web/src/routes/local_folder_source.rs`
|
||||
- `scripts/task444-convex-workspace-export-local-fixture-smoke.js`
|
||||
|
||||
### 11.2 参考代码位置
|
||||
|
||||
- VS Code:
|
||||
- `design/05-editor-mainline/reference-code/vscode/src/vs/workbench/contrib/files/browser/fileImportExport.ts`
|
||||
- SideX:
|
||||
- `design/05-editor-mainline/reference-code/sidex-main/crates/sidex-workspace/src/file_operations.rs`
|
||||
|
||||
### 11.3 顺序任务
|
||||
|
||||
- [ ] 设计 dry run 导出计划。
|
||||
- 完成验收:计划列出页面、资源、附件、目标路径、冲突项,不写文件。
|
||||
|
||||
- [ ] 导出前生成 backup / manifest。
|
||||
- 完成验收:manifest 能记录本次新增、覆盖、跳过、失败。
|
||||
|
||||
- [ ] 目标 root 同名冲突不覆盖。
|
||||
- 完成验收:生成冲突报告,用户明确选择前不写入。
|
||||
|
||||
- [ ] 回滚按 manifest 删除新增或恢复备份。
|
||||
- 完成验收:回滚后 root 回到导出前状态。
|
||||
|
||||
- [ ] 导出完成后重建本地索引。
|
||||
- 完成验收:迁移后页面可搜索,资源引用可查。
|
||||
|
||||
### 11.4 验收
|
||||
|
||||
- [ ] Convex fixture 导出 smoke 通过。
|
||||
- 命令:`PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH=/usr/bin/google-chrome-stable node scripts/task444-convex-workspace-export-local-fixture-smoke.js`
|
||||
|
||||
- [ ] 新增 smoke:同名文件冲突时不覆盖。
|
||||
|
||||
- [ ] 新增 smoke:回滚后 root 回到导出前状态。
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] 迁移支持 dry run。
|
||||
- [ ] 迁移支持备份、冲突报告、回滚。
|
||||
- [ ] 迁移后 local index 可用。
|
||||
|
||||
---
|
||||
|
||||
## 12. 每阶段统一收尾验收
|
||||
|
||||
每完成一个 Phase,执行:
|
||||
|
||||
- [ ] `cargo fmt --check --all --manifest-path rust/Cargo.toml`
|
||||
- [ ] `git diff --check -- <changed-files>`
|
||||
- [ ] 与阶段相关的 Rust 单测。
|
||||
- [ ] 与阶段相关的 browser smoke。
|
||||
- [ ] `npm run check:local-first-convex-guard`
|
||||
- [ ] 把验证证据写回本 checklist。
|
||||
|
||||
阶段迁移到 `done/` 的标准:
|
||||
|
||||
- [ ] checklist 项全部勾选。
|
||||
- [ ] 真实代码已落地。
|
||||
- [ ] 单测与 smoke 有证据。
|
||||
- [ ] 不再依赖临时 compat 作为新增能力主路径。
|
||||
@@ -0,0 +1,721 @@
|
||||
# 1 [reference] Tree-First Graph 内核方案 v1
|
||||
|
||||
> 更新时间:2026-04-22
|
||||
>
|
||||
> 当前状态:`reference`。本文是 tree-first graph kernel 的长期架构边界,不是当前可直接执行的 checklist;执行入口见 `design/01-tree-first-graph-kernel/process/1-8-mvp-post-process-execution-order-v1.md`。
|
||||
>
|
||||
> 当前优先级入口:
|
||||
> - `/mnt/Data1T/mnote/design/01-05-current-priority-overview.md`
|
||||
>
|
||||
> 关联文档:
|
||||
> - `/mnt/Data1T/mnote/design/03-rust-web/reference/3-rust-web-long-term-architecture-v1.md`
|
||||
> - `/mnt/Data1T/mnote/design/03-rust-web/reference/3-1-rust-web-long-term-checklist-v2.md`
|
||||
> - `/mnt/Data1T/mnote/ARCHITECTURE.md`
|
||||
|
||||
## 1. 文档目的
|
||||
|
||||
本文回答的不是“页面如何加速”,而是更底层的问题:
|
||||
|
||||
> **mnote 长期到底应该以什么作为统一对象内核。**
|
||||
|
||||
在前一轮讨论里,方向经历了一个重要修正:
|
||||
|
||||
- 不是让 `Mindmap` 成为系统主投影
|
||||
- 也不是让“导图页面”变成新的系统中心
|
||||
- 而是让 **`tree-first graph` 成为统一结构内核**
|
||||
- `Mindmap` 只是这个内核的一种可视化挂件
|
||||
|
||||
这份文档的目标,是把这个判断正式固定下来。
|
||||
|
||||
---
|
||||
|
||||
## 2. 先给结论
|
||||
|
||||
结论只有一句:
|
||||
|
||||
> **mnote 的长期核心不应是 `BlockNote-first`,也不应是 `Mindmap-first`,而应是 `tree-first graph kernel`。**
|
||||
|
||||
也就是说:
|
||||
|
||||
- **树** 是主骨架
|
||||
- **图** 是横向引用扩展
|
||||
- **Mindmap** 是树/图的一种空间化视图
|
||||
- **Sidebar / 页面树 / 文件树 / 文档阅读页 / 搜索结果 / AI 面板** 都只是同一内核的不同投影
|
||||
|
||||
因此,长期正确方向不是:
|
||||
|
||||
- “把所有东西都画成导图”
|
||||
|
||||
而是:
|
||||
|
||||
- “让所有对象共享同一份结构内核,再让不同视图各自投影”
|
||||
|
||||
---
|
||||
|
||||
## 3. 为什么不是 Mindmap-first
|
||||
|
||||
虽然 Mindmap 在结构表达上很强,但它不适合被定义为主中心。
|
||||
|
||||
原因有四个。
|
||||
|
||||
### 3.1 导图 UI 不是所有场景的最佳交互
|
||||
|
||||
下面这些场景不适合被强行导图化:
|
||||
|
||||
- Sidebar 导航
|
||||
- 文件树浏览
|
||||
- 文档阅读
|
||||
- 搜索结果浏览
|
||||
- 历史版本查看
|
||||
- AI 工具面板
|
||||
|
||||
这些场景里,很多时候:
|
||||
|
||||
- 列表更合适
|
||||
- 树表更合适
|
||||
- 阅读流更合适
|
||||
- 搜索结果卡片更合适
|
||||
|
||||
所以:
|
||||
|
||||
> **导图是一种强表达能力的视图,不是所有结构都应默认进入的主视图。**
|
||||
|
||||
### 3.2 如果 Mindmap 成为主中心,系统会被导图交互绑架
|
||||
|
||||
一旦把 Mindmap 当主投影,后面很容易出现:
|
||||
|
||||
- 结构建模被导图控件的数据形状反向约束
|
||||
- 页面/文件/章节/引用都被迫适配导图编辑器
|
||||
- 视图层规则污染对象层规则
|
||||
|
||||
这会让“结构内核”被“某种 UI 控件”夺走主导权。
|
||||
|
||||
### 3.3 当前本地代码已经说明 Mindmap 更像重操作壳
|
||||
|
||||
当前:
|
||||
|
||||
- [`MindmapBlock.tsx`](/mnt/Data1T/mnote/wolai-frontend/src/components/editor/blocks/MindmapBlock.tsx)
|
||||
|
||||
同时承担:
|
||||
|
||||
- 内嵌块
|
||||
- 独立页
|
||||
- 工具栏
|
||||
- 右键菜单
|
||||
- 导航器
|
||||
- 缩略图
|
||||
- 本地全屏视图
|
||||
|
||||
这说明它当前的本质更接近:
|
||||
|
||||
- 一个前端重交互操作层
|
||||
|
||||
而不是:
|
||||
|
||||
- 一个稳定、极简、内核级结构模型
|
||||
|
||||
### 3.4 Mindmap 已经适合退到“挂件层”
|
||||
|
||||
真正更合理的位置是:
|
||||
|
||||
- 它继续保留
|
||||
- 但作为 `tree-first graph kernel` 的挂件和投影
|
||||
- 而不是事实源
|
||||
|
||||
---
|
||||
|
||||
## 4. 为什么是 Tree-First Graph
|
||||
|
||||
这是因为 mnote 当前最稳定、最通用、最可渐进迁移的共同语义,本质上是:
|
||||
|
||||
- **父子层级**
|
||||
- **局部子树**
|
||||
- **对象引用**
|
||||
|
||||
这正对应:
|
||||
|
||||
- 树
|
||||
- 子树
|
||||
- 图边
|
||||
|
||||
### 4.1 树是最自然的主骨架
|
||||
|
||||
下面这些天然就是树:
|
||||
|
||||
- 工作区结构
|
||||
- 页面树
|
||||
- 文件树
|
||||
- 文档大纲
|
||||
- PDF 章节结构
|
||||
- 页面内部结构
|
||||
- 导图节点结构
|
||||
|
||||
因此“树优先”不是一种美学偏好,而是数据现实。
|
||||
|
||||
### 4.2 图是必须存在的扩展层
|
||||
|
||||
但系统又不可能只有树,因为还存在:
|
||||
|
||||
- 双向引用
|
||||
- 页面引用页面
|
||||
- 块引用块
|
||||
- 摘要引用原文
|
||||
- PDF 章节引用页码/附件
|
||||
- AI 生成节点引用证据节点
|
||||
|
||||
这些都不是父子关系,而是横向边。
|
||||
|
||||
所以系统最终一定是:
|
||||
|
||||
- 树作为主骨架
|
||||
- 图作为引用扩展
|
||||
|
||||
也就是:
|
||||
|
||||
> **tree-first graph**
|
||||
|
||||
### 4.3 这种结构最适合 Rust 内核化
|
||||
|
||||
因为它天然适合:
|
||||
|
||||
- typed node
|
||||
- typed edge
|
||||
- subtree query
|
||||
- graph traversal
|
||||
- object projection
|
||||
- CLI / AI tool 直接操作
|
||||
|
||||
这比“以某个前端编辑器数据格式为真相”更适合进入 Rust core。
|
||||
|
||||
---
|
||||
|
||||
## 5. 内核定义
|
||||
|
||||
## 5.1 统一内核
|
||||
|
||||
长期建议把 mnote 的结构真相定义为:
|
||||
|
||||
- `WorkspaceKernel`
|
||||
- `Node`
|
||||
- `Edge`
|
||||
- `Projection`
|
||||
|
||||
### 5.1.1 当前已落地的 Rust 类型
|
||||
|
||||
2026-04-16 这轮已经在 Rust `core-protocol` 中补入统一 kernel 类型定义,入口文件为:
|
||||
|
||||
- `/mnt/Data1T/mnote/rust/crates/core-protocol/src/kernel.rs`
|
||||
|
||||
当前已落下的主类型包括:
|
||||
|
||||
- `KernelNode`
|
||||
- `KernelEdge`
|
||||
- `KernelProjectionRequest`
|
||||
- `KernelProjectionResult`
|
||||
- `KernelSubtreeRef`
|
||||
- `KernelSubtreeResult`
|
||||
- `KernelGetNode`
|
||||
- `KernelGetSubtree`
|
||||
- `KernelListChildren`
|
||||
- `KernelListEdges`
|
||||
- `KernelTraverseGraph`
|
||||
- `KernelCreateNode`
|
||||
- `KernelUpdateNode`
|
||||
- `KernelMoveSubtree`
|
||||
- `KernelAttachEdge`
|
||||
- `KernelDetachEdge`
|
||||
|
||||
这意味着这份文档里的 kernel 语义已经不再只是概念,而是进入了 Rust 可复用协议层。
|
||||
|
||||
### 5.2 Node
|
||||
|
||||
每个对象都是带类型的节点。
|
||||
|
||||
候选节点类型包括:
|
||||
|
||||
- `workspace`
|
||||
- `folder`
|
||||
- `page`
|
||||
- `section`
|
||||
- `paragraph`
|
||||
- `asset`
|
||||
- `book`
|
||||
- `pdf`
|
||||
- `mindmap`
|
||||
- `mindmap_node`
|
||||
- `table`
|
||||
- `query_view`
|
||||
- `summary`
|
||||
- `ai_note`
|
||||
- `reference_anchor`
|
||||
|
||||
当前 Rust 中的最小首批节点类型已经固定为:
|
||||
|
||||
- `workspace`
|
||||
- `folder`
|
||||
- `page`
|
||||
- `section`
|
||||
- `asset`
|
||||
- `book`
|
||||
- `pdf`
|
||||
- `mindmap`
|
||||
- `mindmap_node`
|
||||
- `summary`
|
||||
- `ai_note`
|
||||
- `reference_anchor`
|
||||
- `content_node`
|
||||
- `index_node`
|
||||
|
||||
注意:
|
||||
|
||||
> **这里的关键不是名字,而是“页面、文件、书籍、摘要、AI 结果不再分属不同系统,而是同一内核里的 typed node”。**
|
||||
|
||||
### 5.3 Edge
|
||||
|
||||
边分成两类:
|
||||
|
||||
#### A. 骨架边
|
||||
|
||||
- `parent_of`
|
||||
- `child_of`
|
||||
- `contains`
|
||||
|
||||
#### B. 扩展边
|
||||
|
||||
- `references`
|
||||
- `backlinks_to`
|
||||
- `source_of`
|
||||
- `derived_from`
|
||||
- `summarizes`
|
||||
- `indexes`
|
||||
- `points_to`
|
||||
|
||||
当前 Rust 中的最小首批边类型已经固定为:
|
||||
|
||||
- `parent_of`
|
||||
- `child_of`
|
||||
- `contains`
|
||||
- `references`
|
||||
- `backlinks_to`
|
||||
- `source_of`
|
||||
- `derived_from`
|
||||
- `summarizes`
|
||||
- `indexes`
|
||||
- `points_to`
|
||||
|
||||
这样:
|
||||
|
||||
- 树结构靠骨架边维持
|
||||
- 网状关系靠扩展边表达
|
||||
|
||||
### 5.4 Projection
|
||||
|
||||
Projection 不是数据真相,只是同一内核的不同投影。
|
||||
|
||||
长期主要投影包括:
|
||||
|
||||
- Sidebar tree
|
||||
- 页面树
|
||||
- 文件树
|
||||
- 文档阅读流
|
||||
- Mindmap
|
||||
- 搜索结果页
|
||||
- AI 操作视图
|
||||
- 未来可能的关系图 / 时间线 / 表格视图
|
||||
|
||||
当前 Rust 中已经固定的投影种类包括:
|
||||
|
||||
- `sidebar_tree`
|
||||
- `page_tree`
|
||||
- `file_tree`
|
||||
- `mindmap`
|
||||
- `read_view`
|
||||
- `search_results`
|
||||
- `rag_index`
|
||||
|
||||
### 5.5 四层边界
|
||||
|
||||
为了避免后续又把前端页面壳误当事实源,当前主线边界固定为四层:
|
||||
|
||||
1. **事实源**
|
||||
- 统一 `tree-first graph kernel`
|
||||
- 只承载 `node / edge / subtree / audit`
|
||||
- 不承载具体前端 UI 状态
|
||||
2. **投影**
|
||||
- `sidebar tree`
|
||||
- `page tree`
|
||||
- `file tree`
|
||||
- `mindmap projection`
|
||||
- `read view`
|
||||
- `search / rag projection`
|
||||
3. **编辑器**
|
||||
- `BlockNote`
|
||||
- `Mindmap canvas`
|
||||
- `OnlyOffice`
|
||||
- 未来其他专用内容编辑器
|
||||
4. **外挂 / 挂件**
|
||||
- AI 面板
|
||||
- 评论
|
||||
- 历史
|
||||
- 回链
|
||||
- 右侧辅助信息面板
|
||||
|
||||
固定规则是:
|
||||
|
||||
- 事实源只在 kernel
|
||||
- 投影不拥有对象真相
|
||||
- 编辑器不等于对象模型
|
||||
- 外挂只消费 kernel 或 projection,不再私自定义第二套对象真相
|
||||
|
||||
### 5.6 术语冻结
|
||||
|
||||
这一轮同时把后续文档和任务要共用的术语冻结如下:
|
||||
|
||||
- `node`
|
||||
指统一内核中的 typed object
|
||||
- `edge`
|
||||
指节点之间的 typed relation
|
||||
- `projection`
|
||||
指从 kernel 派生出的视图结果,不是事实源
|
||||
- `subtree`
|
||||
指从某个 root node 出发的一段有界层级结构
|
||||
- `content node`
|
||||
指以正文载荷为主的节点,适合交给 BlockNote 之类编辑器处理
|
||||
- `reference edge`
|
||||
指非父子关系的引用边,例如页面引用、证据引用、来源引用
|
||||
- `summary node`
|
||||
指对某段 subtree 或 source node 做摘要后的节点
|
||||
- `index node`
|
||||
指为搜索/RAG 建立的结构索引节点
|
||||
|
||||
### 5.7 现阶段并入策略
|
||||
|
||||
当前主线按下面的口径迁移:
|
||||
|
||||
- 暂时继续存在,但应逐步并入 kernel 的对象:
|
||||
- 页面
|
||||
- Sidebar 数据集
|
||||
- 搜索结果对象
|
||||
- 导图树数据
|
||||
- 当前明确不是事实源、只保留为编辑或展示壳:
|
||||
- BlockNote 文档结构
|
||||
- Mindmap 前端画布状态
|
||||
- OnlyOffice 页面壳
|
||||
- 各类 AI host / panel 本地状态
|
||||
|
||||
---
|
||||
|
||||
## 6. 与当前系统的关系
|
||||
|
||||
## 6.1 与 Sidebar / 页面树 / 文件树的关系
|
||||
|
||||
这些都不应再视为独立系统。
|
||||
|
||||
长期应改成:
|
||||
|
||||
- 同一份结构内核
|
||||
- 在 Sidebar 中投影为导航树
|
||||
- 在文件页中投影为文件树
|
||||
- 在某些对象页中投影为结构树
|
||||
|
||||
所以:
|
||||
|
||||
> **Sidebar 不是“一个前端导航组件”,而是 kernel 的树投影。**
|
||||
|
||||
## 6.2 与 Mindmap 的关系
|
||||
|
||||
Mindmap 不再是中心,而是:
|
||||
|
||||
- kernel 的空间化图形视图
|
||||
- 适合做结构浏览、重组、章节展开、节点重排
|
||||
|
||||
但它不再是:
|
||||
|
||||
- 唯一主视图
|
||||
- 唯一对象真相
|
||||
|
||||
### 6.3 与 BlockNote 的关系
|
||||
|
||||
长期上,`BlockNote` 应从“系统底座”降级为:
|
||||
|
||||
- 内容编辑挂件
|
||||
- 某类页面内容编辑器
|
||||
|
||||
而不是:
|
||||
|
||||
- 页面结构本体
|
||||
- 工作区结构内核
|
||||
|
||||
也就是说,未来不是:
|
||||
|
||||
- 页面 = BlockNote 文档
|
||||
|
||||
而更接近:
|
||||
|
||||
- 页面 = kernel 子树
|
||||
- BlockNote = 某类内容节点的编辑器
|
||||
|
||||
### 6.4 与 AI 的关系
|
||||
|
||||
AI 不应直接面对“页面壳”和“前端控件”,而应直接面对 kernel。
|
||||
|
||||
长期上 AI 更适合操作:
|
||||
|
||||
- 节点
|
||||
- 子树
|
||||
- 引用边
|
||||
- 结构索引
|
||||
- 节点摘要
|
||||
|
||||
例如:
|
||||
|
||||
- 创建节点
|
||||
- 拆分章节为子树
|
||||
- 为节点补 refs
|
||||
- 生成 summary 节点
|
||||
- 把 PDF 章节树挂到 book 节点下
|
||||
|
||||
这比“模拟导图 UI 操作”或“模拟 BlockNote 操作”更稳定。
|
||||
|
||||
### 6.5 与 RAG 的关系
|
||||
|
||||
RAG 不再只是:
|
||||
|
||||
- 文本块检索
|
||||
|
||||
而应演进为:
|
||||
|
||||
- 结构索引检索 + 正文证据回查
|
||||
|
||||
例如:
|
||||
|
||||
- 一本书先变成书籍节点
|
||||
- 再生成章节树
|
||||
- 再生成章节子树摘要
|
||||
- 再用节点 refs 指回原始页码、附件、正文块
|
||||
|
||||
这样检索时可以:
|
||||
|
||||
1. 先命中结构层
|
||||
2. 再下钻子树
|
||||
3. 再回查原文证据
|
||||
|
||||
这正适合复杂文档。
|
||||
|
||||
---
|
||||
|
||||
## 7. 结合 BookRAG 的启发
|
||||
|
||||
用户提到的 `BookRAG` 给出的核心启发,不是“做一个导图页面”,而是:
|
||||
|
||||
> **复杂文档应该先被抽成层级结构索引,再做检索与生成。**
|
||||
|
||||
这和 mnote 非常契合。
|
||||
|
||||
### 7.1 书籍对象的建议形态
|
||||
|
||||
长期上可以采用:
|
||||
|
||||
- 一个 `book` 节点
|
||||
- 一个 canonical 章节树
|
||||
- 每章是一个 subtree
|
||||
- 每小节是更深层节点
|
||||
- 节点 refs 指向:
|
||||
- 页码
|
||||
- PDF
|
||||
- 原文块
|
||||
- 摘要
|
||||
- AI 生成说明
|
||||
|
||||
### 7.2 不建议直接复制很多份 chapter mindmap 实体
|
||||
|
||||
更好的方式是:
|
||||
|
||||
- 逻辑上是一棵 canonical tree
|
||||
- 章节导图只是 subtree projection
|
||||
- 需要时再做缓存或派生视图
|
||||
|
||||
否则会出现:
|
||||
|
||||
- 多份结构副本
|
||||
- 同步成本
|
||||
- 版本冲突
|
||||
|
||||
### 7.3 这和当前 Rust Mindmap 协议是兼容的
|
||||
|
||||
当前 Rust 已经有:
|
||||
|
||||
- `MindmapTreeNode`
|
||||
- `MindmapOp`
|
||||
- `mindmap_get_subtree`
|
||||
- `mindmap_outline_to_mindmap`
|
||||
|
||||
这意味着:
|
||||
|
||||
- 以树为真相
|
||||
- 以子树为检索和投影单位
|
||||
|
||||
并不是从零开始。
|
||||
|
||||
---
|
||||
|
||||
## 8. 这条路线和“主 Mindmap”有什么本质差异
|
||||
|
||||
两者差异很大。
|
||||
|
||||
### 8.1 错误路线
|
||||
|
||||
错误路线是:
|
||||
|
||||
- 整个工作区变成一个超级导图页面
|
||||
- 所有东西都围绕导图控件组织
|
||||
- UI 形态决定对象语义
|
||||
|
||||
### 8.2 正确路线
|
||||
|
||||
正确路线是:
|
||||
|
||||
- 整个工作区共享一份结构内核
|
||||
- Mindmap 只是可视化挂件
|
||||
- 列表、树表、阅读流、搜索结果也都是合法投影
|
||||
- 对象语义先于 UI 形态存在
|
||||
|
||||
---
|
||||
|
||||
## 9. 长期分层建议
|
||||
|
||||
## 9.1 Kernel Layer
|
||||
|
||||
Rust 内核负责:
|
||||
|
||||
- typed node
|
||||
- typed edge
|
||||
- subtree query
|
||||
- graph traversal
|
||||
- projection query
|
||||
- 权限
|
||||
- trace
|
||||
- 版本
|
||||
- 审计
|
||||
|
||||
## 9.2 Service Layer
|
||||
|
||||
Rust Web 层负责:
|
||||
|
||||
- API
|
||||
- SSR 页面壳
|
||||
- SSE / WS
|
||||
- 结构查询
|
||||
- AI bridge
|
||||
- projection 请求分发
|
||||
|
||||
## 9.3 Projection Layer
|
||||
|
||||
不同前端视图负责:
|
||||
|
||||
- Sidebar tree projection
|
||||
- 阅读页 projection
|
||||
- Mindmap projection
|
||||
- 搜索 projection
|
||||
- AI 操作 projection
|
||||
|
||||
## 9.4 Editor Layer
|
||||
|
||||
编辑器只是挂件:
|
||||
|
||||
- BlockNote
|
||||
- Mindmap canvas
|
||||
- OnlyOffice
|
||||
- 未来别的专用编辑器
|
||||
|
||||
它们都不再是系统底座。
|
||||
|
||||
---
|
||||
|
||||
## 10. 为什么这条路线更适合替代 BlockNote 世界
|
||||
|
||||
因为它不是“再造一个更大的前端编辑器”,而是:
|
||||
|
||||
- 先把页面结构、对象结构和引用结构收口
|
||||
- 再让 BlockNote 退化成一个专用内容编辑挂件
|
||||
|
||||
长期上,页面不再被定义成:
|
||||
|
||||
- 一个 block 文档
|
||||
|
||||
而更接近:
|
||||
|
||||
- 一个子树容器
|
||||
|
||||
这样未来才可能逐步实现:
|
||||
|
||||
- 页面结构独立于 BlockNote
|
||||
- 页面中的某些内容节点仍可用 BlockNote 编辑
|
||||
- 某些结构节点则改用别的编辑/操作方式
|
||||
|
||||
这比一次性整体替掉 BlockNote 更现实。
|
||||
|
||||
---
|
||||
|
||||
## 11. 风险与约束
|
||||
|
||||
### 11.1 不要把整个 workspace 真存成一条超大 JSON 树
|
||||
|
||||
逻辑上统一成一棵树,不等于物理上只能是一条大对象。
|
||||
|
||||
长期更合理的是:
|
||||
|
||||
- 逻辑统一
|
||||
- 物理分片
|
||||
- 子树加载
|
||||
- 局部版本
|
||||
- 局部缓存
|
||||
|
||||
### 11.2 不要让 Projection 反向定义内核
|
||||
|
||||
例如:
|
||||
|
||||
- Mindmap 控件的数据格式
|
||||
- BlockNote 的块数据结构
|
||||
- Sidebar 某次渲染需要的 rows
|
||||
|
||||
这些都不能反过来定义 kernel 真相。
|
||||
|
||||
### 11.3 不要过早把所有内容节点都树化成同一种文本节点
|
||||
|
||||
结构树适合表达:
|
||||
|
||||
- 层级
|
||||
- 目录
|
||||
- 引用
|
||||
- 摘要
|
||||
- 索引
|
||||
|
||||
但富文本正文仍然可能需要自己的内容模型。
|
||||
|
||||
所以长期更合理的是:
|
||||
|
||||
- 树/图内核负责结构
|
||||
- 内容节点负责正文
|
||||
- 两者通过 typed node 接口连接
|
||||
|
||||
---
|
||||
|
||||
## 12. 最终结论
|
||||
|
||||
最终结论可以固定成下面这句话:
|
||||
|
||||
> **mnote 的长期方向不是 Mindmap-first,而是 Tree-First Graph Kernel;Mindmap 只是其中一种挂件、投影和操作器。**
|
||||
|
||||
这意味着:
|
||||
|
||||
- 页面树、文件树、Mindmap、RAG 结构索引、AI 结构操作,本质上都应收口到同一结构内核
|
||||
- `BlockNote` 不再是系统定义页面的唯一方式
|
||||
- Rust 最终不只是承接 API 或导图对象,而是承接整个统一结构真相
|
||||
|
||||
如果后续继续推进,真正该优先做的不是“先重写导图 UI”,而是:
|
||||
|
||||
1. 定义统一 kernel node / edge 模型
|
||||
2. 定义 subtree / projection / reference 查询协议
|
||||
3. 让 Sidebar、搜索、AI、Mindmap 开始直接消费 kernel
|
||||
4. 最后再逐步边缘化 `BlockNote`
|
||||
Reference in New Issue
Block a user