Files
mnote/design/05-editor-mainline/done/5-11-wolai-page-settings-and-ai-surface-checklist-v1.md
T
lix-2026 f292c6710a feat: EditorRuntimeActor - 三层缓存/delta/事件架构
Phase A — EditorRuntimeActor 内存缓存层
- 新增 editor_actor.rs: EditorBlockDocument 内存态 + apply_command + load_or_init
- block.rs 四个写工具(replace/insert/delete/move)接入 actor 路径
- editor_actor feature flag(MNOTE_WEB_ENABLE_EDITOR_ACTOR=true 默认开启)
- bridge-runtime 三个核心函数公开化
- rust-toolchain: 1.89 → stable(修复 spike WASM 编译阻塞)

Phase B — 编辑器增量 delta channel
- BlockDelta/DeltaOperation 类型 + actor.build_block_delta()
- leptos-tiptap spike: mnote:editor:block-delta CustomEvent 监听 + JSON patch
- DocumentAiAgentPanel: 拦截 blockDelta → window dispatchEvent
- 工具响应含 blockDelta 字段供前端消费

Phase C — 事件 stream delta
- broadcast channel 在 AppState/actor/SSE 三层贯通
- tree_events SSE 端点发 block.delta 事件
- 旧客户端降级兼容

环境修复
- rustc recursion_limit = 1024(修复 Leptos SSR 类型深度溢出)
- run-convex-deploy.js(封装 Convex function 部署到本地后端 3210)

ref: design/07-ai/process/7-13-page-block-editor-runtime-actor-v1.md
2026-05-16 22:03:30 +08:00

366 lines
19 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 5-11 [done] Wolai 页面设置与 AI 交互壳连续执行 checklist v1
> 更新时间:2026-05-06
>
> 状态说明:
> - 本清单覆盖的页面设置 A/B、页面 AI C、集成护栏 D 均已完成并有 `task160/161/162` 证据,故迁入 `done/`
> - `X1-X6` 属于明确 deferred 项,不构成这轮完成阻塞
> - 2026-05-13 追加说明:本文保留 `task161/162` 对旧 `/api/ai-agent/run -> mnote-cli` 返回链的历史验证证据;AI 长期方向已由 `design/07-ai/done/7-3-page-ai-hermes-panel-and-mnote-plugin-v1.md` 改为 Hermes 页面内客户端 + mnote Hermes skill/plugin
>
> 本清单服务于:
> - `/mnt/Data1T/mnote/design/05-editor-mainline/done/5-10-wolai-page-settings-and-ai-surface-alignment-v1.md`
>
> 执行口径继续统一服从:
> - `/home/lix/.codex/skills/wolai-aline/SKILL.md`
> - `/mnt/Data1T/mnote/design/08-wolai-aline-test-flow/process/wolai-aline-test-flow-v1.md`
## 1. 使用方式
每次只领取一个最小行为,按下面闭环推进:
1. 用一句话定义行为,例如“右上角 `...` 打开页面设置 popover 且 URL 不变”。
2. 派 subagent 先取 Wolai 基线。
3. 主线程复核截图并填写差异矩阵。
4. 新增或更新本地 smoke,先让当前实现失败。
5. 小范围实现,不新造第二份页面真相或 AI 执行面。
6. 运行本地 smoke 和相关单测。
7. 再派 subagent 对 Wolai 与本地复测。
8. 主线程复核最终截图。
9. 更新本清单状态、证据路径和剩余差异。
状态标记:
- `TODO`:未开始
- `BASELINE`Wolai 基线已取
- `RED`:本地失败 smoke 已存在
- `GREEN`:本地实现与 smoke 已通过
- `PARITY`:subagent 复测和主线程截图复核通过
- `BLOCKED`:存在阻塞
---
## 2. 当前基线证据
2026-05-06 已完成 Wolai 页面设置与 AI 界面的只读基线取证,目录:
- `/mnt/Data1T/mnote/tmp/wolai-editor-parity/page-settings-ai-baseline/`
当前已确认事实:
| 项 | Wolai 证据 | 当前结论 |
| --- | --- | --- |
| 页面设置入口 | `/mnt/Data1T/mnote/tmp/wolai-editor-parity/page-settings-ai-baseline/10-page-settings-open.png` | 右上角 `...` 打开右侧贴边 popoverURL 不变 |
| 页面设置关闭 | `/mnt/Data1T/mnote/tmp/wolai-editor-parity/page-settings-ai-baseline/11-page-settings-after-esc.png` `/mnt/Data1T/mnote/tmp/wolai-editor-parity/page-settings-ai-baseline/13-page-settings-after-outside-click.png` `/mnt/Data1T/mnote/tmp/wolai-editor-parity/page-settings-ai-baseline/15-page-settings-after-reclick.png` | `Esc`、点击空白、再次点击入口都可关闭 |
| 页面设置结构 | `/mnt/Data1T/mnote/tmp/wolai-editor-parity/page-settings-ai-baseline/10-page-settings-open.json` | 3 个 tab,内部主控件是 checkbox 形态 |
| AI 入口 | `/mnt/Data1T/mnote/tmp/wolai-editor-parity/page-settings-ai-baseline/20-ai-open.png` | 右下角浮动 `AI` 按钮打开右侧抽屉,URL 不变 |
| AI 关闭 | `/mnt/Data1T/mnote/tmp/wolai-editor-parity/page-settings-ai-baseline/21-ai-after-esc.png` `/mnt/Data1T/mnote/tmp/wolai-editor-parity/page-settings-ai-baseline/23-ai-after-outside-click.png` `/mnt/Data1T/mnote/tmp/wolai-editor-parity/page-settings-ai-baseline/27-ai-after-close-button.png` | `Esc` 和点击空白无效,只能点右上角 `X` |
| AI 结构 | `/mnt/Data1T/mnote/tmp/wolai-editor-parity/page-settings-ai-baseline/20-ai-open.json` | 标题“智能问答”,有会话区、模型区、输入框和发送按钮 |
### 2.1 用户追加截图复核(2026-05-06
用户追加的当前 `3000` 截图:
- `/mnt/Data1T/mnote/tmp/image copy 44.png`
- `/mnt/Data1T/mnote/tmp/image copy 45.png`
当前补充判断:
- `image copy 44.png``image copy 45.png` 暴露的是三类真实问题:页面设置 tab-panel 混显、页面设置保存后回退、页面 AI 抽屉没有真实文本返回。
- 这三类问题已经在本轮代码修复中逐项落地:
- `styles.rs`:补 `[hidden]` surface 样式,修复 `页面选项 / 自定义页面 / 全局选项` 混显。
- `documents.rs + bridge-runtime + document.rs + layout.rs`:修复页面设置写链、读链和 SSR 首屏注入,解决“闪一下又复原”。
- `compat.rs + layout.rs`:修复真实 `/api/ai-agent/run` 返回文本,页面 AI 默认 provider 对齐为 `hermes`
---
## 3. 通用证据矩阵
每项必须记录下列字段:
| 字段 | 要求 |
| --- | --- |
| Wolai 截图 | 绝对路径,保存在 `/mnt/Data1T/mnote/tmp/wolai-editor-parity/<task>/` |
| 本地截图 | 同视口、同动作链截图 |
| 入口 | 按钮、菜单、浮动入口、快捷键 |
| 关闭路径 | `Esc`、点击空白、再次点击入口、关闭按钮 |
| URL | 操作前后是否变化 |
| 容器类型 | `popover``drawer``sheet``modal` |
| 控件类型 | `checkbox``button``tab``textarea` 等 |
| 控件状态 | `checked``selected``focused``disabled``active` |
| DOM/ARIA | `role``aria-*``data-testid`、可聚焦性 |
| smoke | 对应 `scripts/task*-smoke.js` 或测试文件 |
| 剩余差异 | 不允许只写“基本一致” |
---
## 4. Phase A:页面设置基线与壳层
| ID | 状态 | 任务 | 验收要点 |
| --- | --- | --- | --- |
| A1 | BASELINE | Wolai 页面设置基线 | 已有 2026-05-06 Wolai 基线截图和 JSON |
| A2 | GREEN | 本地页面设置入口现状基线 | `task160` 已记录并复测当前文档页右上角 `更多` 打开页面设置容器,URL 不变 |
| A3 | GREEN | 页面设置入口 tooltip | `task160` 已断言入口 `title="页面选项和全局选项"` |
| A4 | GREEN | 页面设置容器类型 | `task160` 已断言本地打开右侧贴边 `popover`,不再是空按钮 active |
| A5 | GREEN | 页面设置 URL 合同 | `task160` 已断言打开和关闭页面设置时 URL 不变化 |
| A6 | GREEN | 页面设置关闭语义 | `task160` 已断言 `Esc`、点击空白、再次点击入口全部有效 |
| A7 | GREEN | 页面设置 3 tab | `task160` 已在真实后端端口上断言 `页面选项 / 自定义页面 / 全局选项` 的 tab-panel 隔离行为 |
| A8 | GREEN | 页面选项主控件形态 | `task160` 已断言首 tab 使用 checkbox 行,而不是旧 inspector 大块按钮 |
| A9 | GREEN | 最小设置项保留清单 | `task160` 已断言 `wideLayout / smallText / showToc / showHeadingNumbers / protectEditing` 出现在首 tab |
| A10 | GREEN | 未接通项显式降级 | `task160` 已断言 `showToc / protectEditing` 当前 disabled 且带“待接线”说明 |
### 4.1 本阶段 smoke 建议
- `scripts/task160-wolai-page-settings-shell-smoke.js`
首轮最小断言建议:
- 点击右上角 `...` 后 URL 不变
- 出现页面设置 `popover`
- 出现三 tab
- `Esc` 可关闭
- 点击页面空白可关闭
- 再次点击入口可关闭
### 4.2 task160 页面设置壳执行记录
2026-05-06 已新增并执行 `scripts/task160-wolai-page-settings-shell-smoke.js`,用于固化 A2-A7 的本地 RED 基线。
RED
- 命令:`node scripts/task160-wolai-page-settings-shell-smoke.js`
- 结果:失败
- 失败信息:`页面设置入口必须打开右侧贴边 popover`
- 当前本地状态:
- 点击右上角 `更多` 后 URL 保持文档页不变
- 顶栏 `更多` 获得焦点,但没有打开页面设置容器
- 当前页面中未出现页面设置 popover;探测到的唯一 `tablist` 仍是左侧 `我的页面 / Explorer / +`
证据路径:
- 本地点击后截图:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/task160-page-settings-shell/01-after-click-more.png`
- 本地点击后状态:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/task160-page-settings-shell/01-after-click-more.json`
- 本地失败截图:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/task160-page-settings-shell/failure.png`
- 本地失败状态:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/task160-page-settings-shell/failure-state.json`
当前判断:
- A2 已有本地基线
- A4 已形成真实 RED
- A5 目前从 failure-state 可见点击后 URL 未变化,但完整打开/关闭合同仍待容器实现后继续验证
- A6-A7 仍待容器出现后继续验证
GREEN
- 命令:`node scripts/task160-wolai-page-settings-shell-smoke.js`
- 结果:通过
- 当前通过行为:
- 右上角 `更多` 打开页面设置 `popover`
- URL 保持不变
- `Esc`、点击空白、再次点击入口均可关闭
- 顶部存在 `页面选项 / 自定义页面 / 全局选项`
- 页面设置首 tab 使用 checkbox 行
- `showToc / protectEditing` 当前显式降级
新增证据:
- `task160` 最终截图:
- `/mnt/Data1T/mnote/tmp/wolai-editor-parity/task160-page-settings-shell/01-after-click-more.png`
- `/mnt/Data1T/mnote/tmp/wolai-editor-parity/task160-page-settings-shell/02-after-esc.png`
- `/mnt/Data1T/mnote/tmp/wolai-editor-parity/task160-page-settings-shell/03-after-outside-click.png`
- `/mnt/Data1T/mnote/tmp/wolai-editor-parity/task160-page-settings-shell/04-after-reclick.png`
修复补充(2026-05-06):
-`styles.rs` 中补了 `.wolai-page-settings-section[hidden] { display: none !important; }`
- `task160` 随后已在真实后端端口 `41327` 上验证 `页面选项` 不再混出 `自定义页面` 字段,`自定义页面 / 全局选项` 的 panel 行为恢复正常
---
## 5. Phase B:页面设置动作项与现有能力接线
| ID | 状态 | 任务 | 验收要点 |
| --- | --- | --- | --- |
| B1 | GREEN | `页面历史...` 接线 | `task160` 已断言页面设置动作项可打开 Rust Web 页面历史抽屉 |
| B2 | GREEN | `公开分享页面...` 接线 | `task160` 已断言页面设置动作项可打开 Rust Web 公开分享对话框 |
| B3 | GREEN | `移动到...` 入口策略 | `task160` 已断言当前显式为 disabled/placeholder |
| B4 | GREEN | `嵌入到...` 入口策略 | `task160` 已断言当前显式为 disabled/placeholder |
| B5 | GREEN | `删除页面` 入口策略 | `task160` 已断言当前显式为 disabled/placeholder |
| B6 | GREEN | 统计信息布局 | `task160` 已断言底部存在紧凑统计信息区 |
| B7 | GREEN | 页面设置项真实生效 | `task160` 已在真实后端端口上断言 `wideLayout``layoutDensity` 持久化并在刷新后回读成功 |
### 5.1 本阶段 smoke 建议
-`task160` 基础上扩展动作项断言
- 新增针对已接通选项的可见结果断言
最低要求:
- 历史入口可打开现有历史抽屉
- 分享入口可打开现有分享对话框
- `wideLayout``smallText``layoutDensity` 这类已接通项能在页面可见变化中被捕获
### 5.2 task160 Phase B 执行记录
2026-05-06 `task160` 已继续覆盖 B1-B7,当前通过:
- `页面历史...` 可打开 `data-testid="wolai-page-history-drawer"`
- `公开分享页面...` 可打开 `data-testid="wolai-page-share-dialog"`
- `移动到... / 嵌入到... / 删除页面` 当前显式 disabled
- 页面设置底部显示字数、字符、块数、待办统计
- `wideLayout` 写链真实命中 `/api/documents/options`
- `layoutDensity` 写链真实命中 `/api/documents/options`
- `wideLayout` 打开后 `.document-shell` 宽度真实增大
修复补充(2026-05-06):
- 先修了 `mnote-web` 页面设置 route payload 与 `bridge-runtime` command plan:不再把 `workspaceId` 和一组 `null` 选项继续下发到 `documents:updateOptions`
- 再修了 `DocumentPage` 的 SSR `data-page-*` 首屏注入,以及 `SIDEBAR_TREE_JS` 初始化顺序,避免在 `__MNOTE_PAGE_AGGREGATE__` 还未进入 DOM 时把默认 page options 缓存死
- 之后通过真实后端端口 `41327` 验证:
- `/api/documents/options` 返回 200
- `/api/page-aggregate/:id` 能读回 `wideLayout=true``layoutDensity=compact`
- `task160` 刷新后 checkbox 和壳层 attr 不再回退
---
## 6. Phase C:页面 AI 入口与抽屉壳
| ID | 状态 | 任务 | 验收要点 |
| --- | --- | --- | --- |
| C1 | BASELINE | Wolai 页面 AI 基线 | 已有 2026-05-06 Wolai 基线截图和 JSON |
| C2 | GREEN | 本地页面 AI 入口现状基线 | `task161` 已记录并复测右下角 AI 可打开页面 AI 抽屉,URL 不变 |
| C3 | GREEN | 页面 AI 主入口迁到右下角 | `task161` 已断言页面级 AI 主入口为右下角浮动按钮 |
| C4 | GREEN | 顶栏 `页面AI` 降级 | `task161` 已断言顶栏不再保留 `页面AI` 主入口 |
| C5 | GREEN | 页面 AI 容器类型 | `task161` 已断言页面 AI 以右侧抽屉打开、无遮罩、不跳新页面 |
| C6 | GREEN | 页面 AI 关闭语义 | `task161` 已断言 `Esc`、点击空白无效,右上角 `X` 有效 |
| C7 | GREEN | 页面 AI 页面级绑定 | `task161` 已断言历史 `/api/ai-agent/run` 请求体携带当前 `documentId``pageOptions`;后续同类上下文应进入 Hermes run/session context |
| C8 | GREEN | 页面 AI 历史返回链不分裂 | 真实 `/api/ai-agent/run` 曾改为 `Next 兼容优先 -> 本地 mnote-cli fallback -> 旧 orchestrator 兜底``task162` 已验证真实页面可返回文本结果;长期主线已改为 Hermes client proxy + mnote plugin |
| C9 | GREEN | AI chrome 与 Wolai 接近 | `task161` 已断言标题、输入区、`新会话 / 历史会话 / mnote-cli` chrome 可见;后续文案应改为 Hermes session / model / history |
### 6.1 本阶段 smoke 建议
- 本机 gitignored `recycle/scripts/retired-ai-agent-run-smokes/task161-wolai-page-ai-shell-smoke.js`
首轮最小断言建议:
- 点击右下角 AI 后 URL 不变
- 打开右侧抽屉
- 抽屉无遮罩
- `Esc` 不关闭
- 点击页面空白不关闭
- 点右上角关闭按钮可关闭
### 6.2 task161 页面 AI 壳执行记录
2026-05-06 已新增并执行 `scripts/task161-wolai-page-ai-shell-smoke.js`,用于固化 C2-C6 的本地 RED 基线。该脚本现已随旧 `/api/ai-agent/run` smoke 迁入本机 gitignored `recycle/scripts/retired-ai-agent-run-smokes/`,只保留历史对照意义。
RED
- 历史命令:`node scripts/task161-wolai-page-ai-shell-smoke.js`;当前本机归档路径:gitignored `recycle/scripts/retired-ai-agent-run-smokes/task161-wolai-page-ai-shell-smoke.js`
- 结果:失败
- 失败信息:`页面 AI 入口必须打开右侧抽屉`
- 当前本地状态:
- 点击右下角 `AI 助手` 后 URL 保持文档页不变
- 浮动 AI 按钮没有打开抽屉
- 当前页面中未出现页面 AI 容器、关闭按钮、标题或输入框
证据路径:
- 本地点击后截图:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/task161-page-ai-shell/01-after-click-ai.png`
- 本地点击后状态:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/task161-page-ai-shell/01-after-click-ai.json`
- 本地失败截图:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/task161-page-ai-shell/failure.png`
- 本地失败状态:`/mnt/Data1T/mnote/tmp/wolai-editor-parity/task161-page-ai-shell/failure-state.json`
当前判断:
- C2 已有本地基线
- C5 已形成真实 RED
- C6 仍待抽屉出现后继续验证
- C7-C8 仍待实现阶段继续验证
GREEN
- 历史命令:`node scripts/task161-wolai-page-ai-shell-smoke.js`;当前本机归档路径:gitignored `recycle/scripts/retired-ai-agent-run-smokes/task161-wolai-page-ai-shell-smoke.js`
- 结果:通过
- 当前通过行为:
- 右下角 AI 入口打开页面级右侧抽屉
- URL 保持不变
- `Esc` 和点击空白不会关闭
- 右上角关闭按钮可关闭
- 抽屉标题、输入区、会话/模型 chrome 可见
- 发送动作在历史实现中继续命中 `/api/ai-agent/run`
- 历史请求体继续携带当前 `documentId``pageOptions`;后续应转为 Hermes run/session context
新增证据:
- `task161` 最终截图:
- `/mnt/Data1T/mnote/tmp/wolai-editor-parity/task161-page-ai-shell/01-after-click-ai.png`
- `/mnt/Data1T/mnote/tmp/wolai-editor-parity/task161-page-ai-shell/02-after-esc.png`
- `/mnt/Data1T/mnote/tmp/wolai-editor-parity/task161-page-ai-shell/03-after-outside-click.png`
- `/mnt/Data1T/mnote/tmp/wolai-editor-parity/task161-page-ai-shell/04-after-close-button.png`
修复补充(2026-05-06):
- `compat.rs``/api/ai-agent/run` 已改为:
- 先尝试代理到 Next 的 `/api/ai-agent/run`
- 失败时本地直接 `mnote-cli` host fallback
- 再失败才走旧 orchestrator
- 同时补了认证头显式转发,避免被 Next 侧 307 `/auth` 拦截
- 页面 AI drawer 默认 provider 改为 `hermes`
- 新增 `task162-wolai-page-ai-real-response-smoke.js`,并在真实后端端口 `41327` 上验证:页面 AI 不再显示 `page_ai_failed_502` / “没有返回文本结果”,而是会回填真实文本
- 2026-05-13 口径更新:上述修复只证明历史页面 AI 抽屉可返回文本,不再作为后续 AI 长期执行面依据;新的页面 AI 应直接调用 Hermes client proxy,不再通过 `/api/ai-agent/run` 的 provider / fallback 分支模拟 Hermes
### 6.3 task162 页面 AI 真实返回执行记录
2026-05-06 已新增并执行 `scripts/task162-wolai-page-ai-real-response-smoke.js`,用于补齐 C8 的真实返回验证。
- 命令:`MNOTE_UI_BASE_URL=http://127.0.0.1:41327 node scripts/task162-wolai-page-ai-real-response-smoke.js`
- 结果:通过
- 当前通过行为:
- 页面 AI 不再出现 `page_ai_failed_502`
- 不再显示“当前页面 AI 已接通 \`mnote-cli\`,但这次没有返回文本结果。”
- 页面 AI 会回填真实 `mnote-cli` 输出文本
---
## 7. Phase D:页面 AI 与页面设置的集成护栏
| ID | 状态 | 任务 | 验收要点 |
| --- | --- | --- | --- |
| D1 | GREEN | 不新造页面设置真相 | 页面设置继续围绕 `currentPageOptions -> /api/documents/options -> page.layout.updateOptions` |
| D2 | GREEN | 不新造 AI 执行面 | 历史实现围绕 `/api/ai-agent/run -> mnote-cli` 保持单链;后续不在 mnote 内新造 AI 执行面,而是调用 Hermes 并通过 mnote plugin 写回业务事实 |
| D3 | GREEN | 文档页 owner 行为合同固定 | `task160/task161` 已断言 owner 态页面设置和 AI 都不跳新页面、不改 URL |
| D4 | GREEN | mobile / 窄屏退化 | `task160/task161` 已断言移动视口下 popover / drawer 不超出视口 |
| D5 | GREEN | React compat 与 Rust SSR 边界 | 本轮实现仅落在 `mnote-web` Rust SSR 壳、脚本与样式;未再把入口回接 React compat |
| D6 | GREEN | checklist 与失败模式回填 | 已向 `wolai-aline/references/failure-patterns.md` 新增“本地 3000 进程未重启,smoke 误打旧实现” |
---
## 8. Deferred 清单
以下项当前明确延后,不混入首批验收:
| ID | 状态 | 任务 | 说明 |
| --- | --- | --- | --- |
| X1 | TODO | 演示模式 | 不是本轮页面设置与 AI 壳的主线 |
| X2 | TODO | 页面评论 | 用户已明确可延后 |
| X3 | TODO | 页面协作 | 用户已明确可延后 |
| X4 | TODO | 成员邀请 | 顶栏 owner 态能力,后续单拆 |
| X5 | TODO | 全局 AI 入口重构 | 本轮只做页面级 AI |
| X6 | TODO | 帮助浮动入口完全对齐 | 本轮优先 AI,不把帮助入口一起扩面 |
---
## 9. 完成判定
本清单只有在以下条件同时成立时,才可以视为本轮设计进入可实现状态:
- 页面设置 `popover` 行为已通过本地 smoke 和 Wolai 基线复核
- 页面 AI 抽屉行为已通过本地 smoke 和 Wolai 基线复核
- 页面设置仍然围绕 `page.layout.updateOptions`
- 页面 AI 历史验证仍然围绕 `/api/ai-agent/run -> mnote-cli`;后续执行主线改为 Hermes client proxy + mnote plugin
- deferred 项没有被误报为已完成
本轮完成后的正确口径:
> **页面设置与页面 AI 的交互壳已开始对齐 Wolai;AI 后续执行主线改为 Hermes 面板 + mnote plugin,评论、协作、成员、演示模式仍是后续独立任务。**