fix local office resource editing

- add local-folder OnlyOffice sign/callback writeback and edit-tab handling

- align main resource tabs, attachment edit menu, slash isolation, and filetree context behavior

- record Sidex/Hermes gap reviews and Reasonix task checklists
This commit is contained in:
lix-2026
2026-05-21 05:40:06 +08:00
parent a29d9868f6
commit eba1010191
50 changed files with 4309 additions and 283 deletions
@@ -0,0 +1,60 @@
# Reasonix Browser TesterOffice 只读打开、编辑入口与插件噪音验证
你是浏览器测试员,不是代码修改员。
禁止修改源码、禁止 git commit、禁止回滚文件。使用真实浏览器或 Playwright 验证。所有截图和 `result.json` 写入指定输出目录。失败时保留 console/network 摘要。最终只汇报测试证据,不提出未经验证的代码结论。
## Project Root
`/mnt/Data1T/mnote`
## 输出目录
`/mnt/Data1T/mnote/tmp/reasonix-office-view-edit-plugin-2026-05-21`
## 前置
- 被测入口:`http://127.0.0.1:3000`
- 使用全新的 isolated browser context / userDataDir。
- 测试开始前清空 cookies、localStorage、sessionStorage、IndexedDB、Cache Storage。
- 默认登录:访问 `/auth`,点击“测试账号快速登录”;如失败,使用邮箱 `mnote.e2e@example.com`、密码 `MnoteE2E123!`
- 测试文件:`/home/lix/Downloads/重庆发展特殊化妆品可行性报告_政府汇报版.docx`
## 测试目标
1. 上传该 docx 后,默认打开到主编辑器右侧 resource tab,而不是浏览器 popup。
2. 默认 OnlyOffice 是只读/view 模式。
3. 三点菜单或右键菜单存在“使用编辑模式打开”入口。
4. 点击编辑入口后,记录 guard 或 `mode=edit` 的可观察证据。
5. 记录 `/api/media/sign` 对 local asset 是否还出现 404。
6. 记录 annotation/plugin 404/pageerror 是否存在;如果存在,判断是否影响主文档可见渲染。
## PASS 标准
- 截图必须显示 OnlyOffice 文档内容区或明确的 OnlyOffice 编辑器界面。
- `errorCode=-18`、WebSocket handshake failed、polling failed、连接失败、主 iframe 空白必须标记 FAIL/BLOCKED。
- 插件 404 只有在主文档已渲染且 WebSocket 正常时,才可标记为 non-critical。
## 输出格式
写入 `result.json`,至少包含:
```json
{
"status": "PASS|FAIL|BLOCKED",
"steps": [],
"assertions": [],
"screenshots": [],
"consoleErrors": [],
"networkFailures": [],
"onlyoffice": {
"iframeSrc": "",
"modeEvidence": "",
"documentKeyEvidence": "",
"mediaSignLocal404": false,
"plugin404NonCritical": null
}
}
```
同时输出简短 `final.md`,列出复现步骤、观察结果和截图路径。
@@ -0,0 +1,66 @@
# Reasonix Browser Test: Tab / Office / Upload Bugs
项目根目录:`/mnt/Data1T/mnote`
请先阅读并遵守:`/home/lix/.codex/skills/reasonix-browser-tester/SKILL.md`
## 角色
你是独立浏览器测试员,不是代码修改员。
禁止修改源码、禁止 git commit、禁止回滚文件。只允许创建测试输出目录、临时测试数据和截图。
## 测试目标
验证以下 MNote UI 行为是否真实存在,并输出可复核证据:
1. 在主 resource tab 打开时,点击左侧文件树中的主 Markdown 页面,是否能切回 page tab。
2. 点击左侧“新建页面”后,是否能切到新页面的主 Markdown page tab;文件树焦点/选中是否落在新建页面。
3. 上传并打开真实文件:
`/home/lix/Downloads/重庆发展特殊化妆品可行性报告_政府汇报版.docx`
验证是否进入主 resource tab、是否出现 `/onlyoffice` iframe、是否出现错误提示或卡死。
4. 观察上传中文文件名时浏览器是否卡死;记录 console、network、页面是否还能响应。
## 建议测试方式
- 默认入口:`http://127.0.0.1:3000`
- 使用 Playwright/Chrome。
- 优先使用 local-first 临时 workspace
- 创建临时 root。
- 写入 `.mnote/workspace.json`
- 创建 `Alpha.md``Beta.md` 等测试页面。
- 可通过 `/auth` 的“测试账号快速登录”登录。
## 断言证据
请记录:
- 当前 URL。
- `.mnote-main-tab.is-active` 的文本、`data-mnote-main-tab``data-mnote-tab-kind`
- `[data-mnote-main-tab="page"]` 是否 active。
- 左侧 filetree 行的 `data-selected` / `data-focused` / `data-active`
- Office iframe `src`
- 上传 API 响应状态和 body。
- console error/warning。
- network failed 请求。
## 输出目录
写入:
`/mnt/Data1T/mnote/tmp/reasonix-browser-test-2026-05-21-tab-office-upload/`
必须输出:
- `result.json`
- `final.md`
- 至少 3 张截图:切换前 resource tab、点击 md 后状态、docx 打开状态。失败时额外截图。
## 最终回复格式
只汇报:
- 输出目录。
- 每个测试目标 pass/fail。
- 关键失败证据。
- 未能验证的原因。
@@ -0,0 +1,57 @@
你是浏览器测试员,不是代码修改员。
禁止修改源码、禁止 git commit、禁止回滚文件。
使用真实浏览器或 Playwright 验证。
所有截图和 result.json 写入指定输出目录。
失败时保留 console/network 摘要。
最终只汇报测试证据,不提出未经验证的代码结论。
# Reasonix 浏览器测试任务:Office 中文 docx 上传并打开
## 输出目录
`/mnt/Data1T/mnote/tmp/reasonix-office-upload-open-clean-2026-05-21/`
## 测试入口
- URL: `http://127.0.0.1:3000`
- 登录:访问 `/auth`,点击“测试账号快速登录”
- 必须使用全新 isolated browser context / userDataDir。
- 测试开始前清空 cookies、localStorage、sessionStorage、IndexedDB、Cache Storage。
## 测试文件
上传真实文件:
`/home/lix/Downloads/重庆发展特殊化妆品可行性报告_政府汇报版.docx`
## 测试步骤
1. 创建临时 local-first workspace,至少包含 `Alpha.md``.mnote/workspace.json`
2. 打开 `Alpha.md` 页面。
3. 上传上述 docx 到当前页面,记录上传 API 状态、耗时、返回 asset。
4. 点击或派发真实 UI 等价操作打开该 docx 附件到主编辑器资源 tab。
5. 等待 OnlyOffice iframe 内部进入稳定状态,最长 90 秒。
6. 截图最终打开效果,截图必须显示以下之一:
- Office 文档内容区 / 编辑器 UI 已可见。
- 明确的 OnlyOffice 错误面板或连接失败信息。
7. 记录 console errors、failed requests、OnlyOffice WebSocket / polling URL。
8. 检查 WebSocket / polling URL 的 doc key 是否为安全 key,不包含 `/``:`、中文字符。
## 判定规则
- `PASS` 不能只因为 upload 200、resource tab active 或 iframe 存在。
- 如果出现 `errorCode=-18``连接失败`、WebSocket handshake failed、polling failed,标记为 `FAIL``BLOCKED`,并截图。
- 如果页面上传后卡死、刷新后无法恢复、需要重新登录,标记为 `FAIL`
- 如果 DocumentServer 未运行或代理不可达,标记为 `BLOCKED`,并记录服务状态和网络错误。
## 输出要求
- `result.json`
- `overallStatus`: `pass` / `fail` / `blocked`
- `freshContext`: 是否使用全新上下文并清空缓存
- `upload`: status、elapsedMs、asset
- `open`: tabKind、iframeSrc、officeReady、visibleTextOrError
- `onlyofficeNetwork`: websocketUrls、pollingUrls、failedRequests
- `docKeySafety`: safe、observedKeys、unsafeReasons
- `screenshots`: 最终截图路径
- `final.md`:简要步骤、观察、结论、截图路径。
@@ -0,0 +1,60 @@
# Reasonix Worker A: Local Folder Trash + Empty Workspace
Project root: `/mnt/Data1T/mnote`
## 背景
用户报告:
- 文件树删除页面后全部跑到资源垃圾箱,页面垃圾箱没有使用。
- 会突然出现“初始化的新页面”,删除后还会出现;空白页面应保持空白,不显示任何占位。
事实源:
- Review: `bugs/05-editor-mainline/process/2026-05-21-workbench-filetree-office-slash-bugs-review-v1.md`
- Checklist: `bugs/04-tree-domain/process/4-45-local-folder-page-trash-and-empty-workspace-v1.md`
## Ownership
你负责:
- `rust/crates/mnote-web/src/routes/local_folder_source.rs`
- 必要时 `rust/crates/mnote-web/src/routes/gateway.rs` 中 trash 分类/渲染的小范围补丁
- 相关 Rust tests
你不是独自在代码库中工作。不要回滚、覆盖、格式化或清理其他人/其他 worker 的改动。不要提交 git。
## 任务
1. 移除默认工作区自动创建 `初始化的新页面/初始化的新页面.md` 的行为。
2. 更新相关测试,不再断言默认页面存在。
3. 修复本地文件树删除页面 bundle 目录时被归类为 `local_directory` 资源的问题:
- 若目录内存在同名 `.md`,应按 Markdown 页面生命周期进入 trash。
- trash index 应能让页面垃圾箱识别为页面/document,而不是资源 local_directory。
4. 空 root / 空 page tree 不应投影出“初始化的新页面”。
## 关键线索
- `ensure_default_workspace_home_page` 当前会创建初始化页面。
- `trash_local_entry` 现在先解析 `local-dir:*`,导致页面 bundle 目录先走 `trash_local_directory`
- `trash_local_markdown_page` 已能删除 bundle,但需要让入口优先识别 bundle 页面。
## 验证
至少运行:
```bash
cd /mnt/Data1T/mnote/rust
cargo test -p mnote-web create_default_local_workspace_for_actor_at_base_creates_manifest_and_root_only -- --test-threads=1
cargo test -p mnote-web local_tree_command_manages_loose_markdown_like_regular_file -- --test-threads=1
cargo test -p mnote-web local_tree_command_delete_folder_moves_directory_to_trash -- --test-threads=1
```
如新增测试,请一并运行。
## 最终回复格式
- 修改文件列表
- 完成的 checklist 项
- 运行过的命令和结果
- 未完成项/风险
@@ -0,0 +1,62 @@
# Reasonix Worker AOnlyOffice local-folder 不再误请求 media/sign
你是编码 worker,不是审查员。你不独占代码库,可能有其他 worker 同时修改不同文件;不要回滚、覆盖或清理他人的改动。
## Project Root
`/mnt/Data1T/mnote`
## 背景
详见:
- `bugs/05-editor-mainline/process/2026-05-21-office-edit-sign-plugin-gap-review-v1.md`
- `bugs/05-editor-mainline/process/5-34-local-folder-media-sign-office-url-contract-v1.md`
当前 `/onlyoffice` 页面只要有 `assetId` 就请求 `/api/media/sign`。local-folder asset 形如 `local:asset:<path>`,本来应直接使用传入的 local open `fileUrl`,因此这个请求会产生误导性的 404。
## Ownership
你负责:
- `rust/crates/mnote-web/src/routes/onlyoffice.rs`
- 与 above 契约直接相关的 `mnote-web` 单测
- 更新 `bugs/05-editor-mainline/process/5-34-local-folder-media-sign-office-url-contract-v1.md` 的本轮执行记录
不要修改:
- `rust/crates/mnote-web/src/ssr/pages/layout.rs`
- ACP / Hermes 相关文件
- git 状态无关文件
## 任务
1.`/onlyoffice` 页面识别 local-folder asset / local fileUrl,并在这种情况下跳过 `/api/media/sign`
2. 保持非 local asset 仍可请求 `/api/media/sign`
3. 保持 doc key 安全化,不引入 `/``:`、中文等危险字符。
4. 补或调整单测,确保页面脚本包含该判断。
## 设计约束
- local 判断应保守:优先基于 `assetId` 前缀 `local:` / `local-file:`,以及 `fileUrl` path 为 `/api/local-folder/files/open`
- 不要把 `/api/media/sign` 改成本地文件签名端点。
- 不要改变 callback 或 edit/save 逻辑。
## 验收命令
请至少运行:
```bash
cargo test -p mnote-web onlyoffice -- --test-threads=1
```
如果失败,记录失败原因和相关输出。
## 最终输出
在 final 中列出:
- 修改文件
- 关键实现点
- 运行过的命令和结果
- 未完成项或风险
@@ -0,0 +1,48 @@
# Reasonix Worker B: Main Page Tab Title Sync
Project root: `/mnt/Data1T/mnote`
## 背景
用户报告:主 tab 的标题与实际打开页面标题不一致,不会随实际打开的 tab / 页面变化。
事实源:
- Review: `bugs/05-editor-mainline/process/2026-05-21-workbench-filetree-office-slash-bugs-review-v1.md`
- Checklist: `bugs/05-editor-mainline/process/5-28-main-page-tab-title-active-sync-v1.md`
## Ownership
你负责小范围修改:
- `rust/crates/mnote-web/src/routes/web_shell.rs` 中 page tab / `updatePaneChrome` / 标题保存同步相关逻辑
- `rust/crates/mnote-web/src/ssr/pages/document.rs` 如需要补 data 属性
- 相关 Rust tests
不要修改 OnlyOffice、文件树菜单、slash 定位、ACP/Hermes 文件。你不是独自在代码库中工作;不要回滚、覆盖、格式化或清理其他 worker 的改动。不要提交 git。
## 任务
1. `replacePaneDocument` / `updatePaneChrome(primary)` 更新 primary document 后,同步:
- `[data-mnote-main-tab="page"] .mnote-main-tab-title`
- page tab 上的 document/workspace data 属性(如需要)
2. 标题保存控制器 `updateVisibleTitle` 保存标题时,同步当前 page tab 标题。
3. 资源 tab 与 page tab 切换时,page tab 标题始终代表当前 primary document。
4. 补一个 Rust 字符串测试或现有测试断言。
## 验证
至少运行:
```bash
cd /mnt/Data1T/mnote/rust
cargo test -p mnote-web page_layout_renders_main_editor_tab_strip -- --test-threads=1
cargo test -p mnote-web document_shell_runtime_renders_resource_tab_runtime -- --test-threads=1
```
## 最终回复格式
- 修改文件列表
- 完成的 checklist 项
- 运行过的命令和结果
- 未完成项/风险
@@ -0,0 +1,68 @@
# Reasonix Worker BOffice 编辑模式菜单与 guard
你是编码 worker,不是审查员。你不独占代码库,可能有其他 worker 同时修改不同文件;不要回滚、覆盖或清理他人的改动。
## Project Root
`/mnt/Data1T/mnote`
## 背景
详见:
- `bugs/05-editor-mainline/process/2026-05-21-office-edit-sign-plugin-gap-review-v1.md`
- `bugs/05-editor-mainline/process/5-35-office-edit-mode-menu-and-guard-v1.md`
产品口径:Office 默认只读打开;三点菜单增加“使用编辑模式打开”。当前 local-folder edit/save callback 没有完整闭环,因此编辑入口不能表现成默认可保存功能。
## Ownership
你负责:
- `rust/crates/mnote-web/src/ssr/pages/layout.rs`
- 与 layout JS 字符串相关的 `mnote-web` 单测
- 更新 `bugs/05-editor-mainline/process/5-35-office-edit-mode-menu-and-guard-v1.md` 的本轮执行记录
不要修改:
- `rust/crates/mnote-web/src/routes/onlyoffice.rs`
- `rust/crates/mnote-web/src/routes/media.rs`
- ACP / Hermes 相关文件
## 任务
1. 确认 Office 默认打开路径使用 `mode=view`,尤其是 local uploaded asset 和编辑器附件点击。
2. 在正文附件三点菜单中增加“使用编辑模式打开”。
3. 在文件树 Office asset 右键菜单中增加“使用编辑模式打开”。
4. 点击编辑入口时打开 `mode=edit` 的 OnlyOffice URL。
5. 如果保存闭环未完成,给编辑入口增加 guard:
- 可以用 `window.confirm` 或明确状态标记提示“编辑保存仍在实验中,建议先备份文件”;
- 必须便于浏览器测试识别,例如设置 `data-mnote-last-office-edit-mode-requested="true"``data-mnote-last-office-edit-mode-guard="shown"`
## 设计约束
- 不默认 edit。
- 不承诺保存已闭环。
- 不影响 md/text/code 附件继续走 tiptap 渲染 / 编辑路径。
- 尽量复用现有 `buildLocalOnlyOfficeOpenUrl``buildOnlyOfficeOpenUrl``openConvexAssetFromFileTree` 等函数。
## 验收命令
请至少运行:
```bash
cargo test -p mnote-web sidebar_tree_js -- --test-threads=1
cargo test -p mnote-web onlyoffice -- --test-threads=1
```
如果失败,记录失败原因和相关输出。
## 最终输出
在 final 中列出:
- 修改文件
- 菜单项位置与 action 名称
- 默认 view 与显式 edit 的实现点
- 运行过的命令和结果
- 未完成项或风险
@@ -0,0 +1,53 @@
# Reasonix Worker C: OnlyOffice Docx Upload Open Freeze
Project root: `/mnt/Data1T/mnote`
## 背景
用户报告:上传 `DHA美黑化妆品监管综述_2026-05-16.docx` 后卡死,docx 打不开,并出现 OnlyOffice 连接失败信息。
事实源:
- Review: `bugs/05-editor-mainline/process/2026-05-21-workbench-filetree-office-slash-bugs-review-v1.md`
- Checklist: `bugs/05-editor-mainline/process/5-29-onlyoffice-docx-upload-open-freeze-v1.md`
## Ownership
你负责:
- `rust/crates/mnote-web/src/routes/onlyoffice.rs`
- `rust/crates/mnote-web/src/routes/local_folder_source.rs` 中 local file open / upload 的小范围修复
- `rust/crates/mnote-web/src/routes/web_shell.rs` 中 office resource tab 打开/错误 UI 的小范围修复
- `rust/crates/mnote-web/src/ssr/pages/layout.rs` 中附件 open URL 的小范围修复
- OnlyOffice/local upload 相关 tests
不要修改文件树 trash、默认 workspace、右键菜单结构、slash 定位、ACP/Hermes 文件。你不是独自在代码库中工作;不要回滚、覆盖、格式化或清理其他 worker 的改动。不要提交 git。
## 任务
1. 定位 docx 卡死发生层级:上传、附件插入、主 tab iframe、OnlyOffice DocumentServer 回源或错误处理。
2. 确保本地 docx 打开时:
- `fileUrl` 指向 `/api/local-folder/files/open?rootUri=...&path=...`
- `fileType=docx`
- `assetId=local-file:<relativePath>`
- 主 tab 打开优先,不默认弹出浏览器窗口。
3. OnlyOffice iframe 加载失败时显示非阻塞错误,不让主页面卡死。
4. 补 targeted test。
## 验证
至少运行:
```bash
cd /mnt/Data1T/mnote/rust
cargo test -p mnote-web local_file_open_sets_pdf_and_office_content_type -- --test-threads=1
cargo test -p mnote-web onlyoffice_page_exposes_documentserver_fetch_base_for_local_files -- --test-threads=1
cargo test -p mnote-web sidebar_tree_runtime_opens_office_assets_through_resource_shell -- --test-threads=1
```
## 最终回复格式
- 修改文件列表
- 完成的 checklist 项
- 运行过的命令和结果
- 未完成项/风险
@@ -0,0 +1,65 @@
# Reasonix Worker COnlyOffice local-folder callback 保存契约
你是编码 worker,但本任务优先做设计与最小安全实现评估。你不独占代码库,可能有其他 worker 同时修改不同文件;不要回滚、覆盖或清理他人的改动。
## Project Root
`/mnt/Data1T/mnote`
## 背景
详见:
- `bugs/05-editor-mainline/process/2026-05-21-office-edit-sign-plugin-gap-review-v1.md`
- `bugs/05-editor-mainline/process/5-36-onlyoffice-local-edit-save-callback-contract-v1.md`
ONLYOFFICE 官方口径:callback `status === 2``status === 6` 时,后端需要下载 `body.url` 并写回文件,成功返回 `{ "error": 0 }`。当前 `mnote-web` callback 代理 legacy Nextlocal-folder 写回没有闭环。
## Ownership
你负责:
- 优先更新 `bugs/05-editor-mainline/process/5-36-onlyoffice-local-edit-save-callback-contract-v1.md`
- 如判断安全且改动小,可修改:
- `rust/crates/mnote-web/src/routes/onlyoffice.rs`
- `rust/crates/adapter-onlyoffice/src/lib.rs`
- 相关单测
不要修改:
- `rust/crates/mnote-web/src/ssr/pages/layout.rs`
- ACP / Hermes 相关文件
## 任务
1. 梳理当前 callback 能否定位 local-folder 原文件。
2. 明确实现 local writeback 还缺哪些输入:rootUri、relative path、workspace/source kind、session。
3. 如果现有 URL 参数已经足够安全定位文件,则实现最小 status 2/6 下载写回。
4. 如果现有输入不足,先不要硬写实现;更新 checklist,明确缺口,并建议 Worker B 的编辑入口保持 guard。
## 必须满足的安全条件
- 写回路径必须落在当前 local root allowed roots 内。
- status 非 2/6 不写文件并返回 `{ "error": 0 }`
- 下载 URL 必须经过现有 OnlyOffice internal URL rewrite 逻辑或等价安全处理。
- 不允许从 assetId 字符串直接拼任意绝对路径写入。
## 验收命令
如改代码,请至少运行:
```bash
cargo test -p mnote-web onlyoffice_callback -- --test-threads=1
```
如果只更新设计,也请说明为什么本轮不应实现。
## 最终输出
在 final 中列出:
- 修改文件
- 是否实现代码,若未实现说明阻塞输入
- 安全边界判断
- 运行过的命令和结果
- 未完成项或风险
@@ -0,0 +1,53 @@
# Reasonix Worker D: Filetree Context Menu Sidex Alignment
Project root: `/mnt/Data1T/mnote`
## 背景
用户报告:文件树右键菜单大多没有实际作用;主页面使用右键菜单“侧边栏显示”提示暂不支持在侧栏打开资源。用户要求核对 Sidex 右键菜单,调整当前可用菜单。
事实源:
- Review: `bugs/05-editor-mainline/process/2026-05-21-workbench-filetree-office-slash-bugs-review-v1.md`
- Checklist: `bugs/05-editor-mainline/process/5-30-filetree-context-menu-sidex-alignment-v1.md`
- Sidex 参考:`reference-code/sidex-main/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts`
## Ownership
你负责:
- `rust/crates/mnote-web/src/ssr/pages/layout.rs` 中文件树右键菜单 items 和 handler 的小范围修改
- 必要时 `rust/crates/mnote-web/src/tree_shell/filetree_runtime.rs`
- 必要时 `rust/crates/mnote-web/src/routes/local_folder_source.rs``create_folder` 已有入口接线,不要大改 tree command
- 相关 tests
不要修改 Office、slash 定位、默认 workspace、ACP/Hermes 文件。你不是独自在代码库中工作;不要回滚、覆盖、格式化或清理其他 worker 的改动。不要提交 git。
## 任务
1. 对照 Sidex/VSCode ExplorerContext 的原则:只显示/启用可用动作。
2. local_folder 下:
- `New File` 继续创建页面。
- `New Folder` 接入 `create_folder` 或隐藏/禁用但不能误导。
- `Copy Path` 复制真实 relative path / asset path,不是标题。
- `Reveal` 至少滚动聚焦并记录状态。
- `Duplicate` 若没有真实 copy,隐藏或禁用。
- `Open Right` 只对页面显示;资源未支持侧栏时隐藏,避免 unsupported placeholder。
3. 更新字符串测试。
## 验证
至少运行:
```bash
cd /mnt/Data1T/mnote/rust
cargo test -p mnote-web sidebar_tree_runtime_renders_context_menu_and_scoped_title_updates -- --test-threads=1
cargo test -p mnote-web sidebar_tree_runtime_handles_navigation_drag_and_filetree_actions -- --test-threads=1
```
## 最终回复格式
- 修改文件列表
- 完成的 checklist 项
- 运行过的命令和结果
- 未完成项/风险
@@ -0,0 +1,58 @@
# Reasonix Worker DOnlyOffice annotation 插件 404/pageerror 噪音
你是编码 worker。你不独占代码库,可能有其他 worker 同时修改不同文件;不要回滚、覆盖或清理他人的改动。
## Project Root
`/mnt/Data1T/mnote`
## 背景
详见:
- `bugs/05-editor-mainline/process/2026-05-21-office-edit-sign-plugin-gap-review-v1.md`
- `bugs/05-editor-mainline/process/5-37-onlyoffice-annotation-plugin-noise-policy-v1.md`
OnlyOffice 自定义 annotation/custom assistant 插件可能产生 404 或 pageerror。需要确认来源,并让测试能区分“插件噪音”和“主文档打开失败”。
## Ownership
你负责:
- `bugs/05-editor-mainline/process/5-37-onlyoffice-annotation-plugin-noise-policy-v1.md`
- 如确认是 MNote 显式注入插件,可修改:
- `rust/crates/mnote-web/src/routes/onlyoffice.rs`
- `src/components/onlyoffice/` 下直接的自定义插件配置文件
- 相关测试
不要修改:
- `rust/crates/mnote-web/src/ssr/pages/layout.rs`
- ACP / Hermes 相关文件
- OnlyOffice 主静态资源目录的大规模文件
## 任务
1. 搜索 annotation / custom assistant / pluginsData / autostart 来源。
2. 判断 404 是否由 MNote 显式注入插件引起。
3. 如果 MNote 显式注入且当前不依赖该插件,禁用无效注入或加开关。
4. 如果是 OnlyOffice 内部可选资源,更新 checklist 说明为 non-critical,但不能吞掉 `errorCode=-18`、WebSocket failed、主 iframe 空白等真正失败。
5. 如有必要,补测试或 smoke 文档口径。
## 验收命令
请至少运行与你修改相关的测试;优先:
```bash
cargo test -p mnote-web onlyoffice -- --test-threads=1
```
## 最终输出
在 final 中列出:
- 修改文件
- 404/pageerror 来源
- 处理策略
- 运行过的命令和结果
- 未完成项或风险
@@ -0,0 +1,48 @@
# Reasonix Worker E: Slash Menu Side Pane Isolation
Project root: `/mnt/Data1T/mnote`
## 背景
用户报告:虽然侧栏打开不支持,但在主栏打开 slash 菜单时,侧栏也出现一个 slash 菜单。
事实源:
- Review: `bugs/05-editor-mainline/process/2026-05-21-workbench-filetree-office-slash-bugs-review-v1.md`
- Checklist: `bugs/05-editor-mainline/process/5-31-side-pane-slash-overlay-isolation-v1.md`
## Ownership
你负责:
- `rust/crates/mnote-web/src/routes/web_shell.rs` 中 slash menu root 选择、定位、secondary unsupported cleanup
- 必要时 `rust/spikes/leptos-tiptap-spike/src/lib.rs` 中 overlay data 属性/host 绑定
- 相关 tests
不要修改 Office、右键菜单、文件树 trash、默认 workspace、ACP/Hermes 文件。你不是独自在代码库中工作;不要回滚、覆盖、格式化或清理其他 worker 的改动。不要提交 git。
## 任务
1. `positionSlashMenuForRoot(root)` 只能定位当前 root 内的 slash menu;不能 fallback 到全局第一个 slash menu。
2. `activeEditorRootForSlashMenu()` 只选择可见且含 selection/focus 的 editor roothidden / unsupported secondary root 不应参与。
3. 打开 unsupported side target 时清理 secondary pane 遗留的 slash overlay。
4. 补字符串测试或 Rust 单测,明确覆盖“不使用全局 slash menu fallback”。
## 验证
至少运行:
```bash
cd /mnt/Data1T/mnote/rust
cargo test -p mnote-web document_shell_runtime_renders_resource_tab_runtime -- --test-threads=1
cargo test -p mnote-web document_shell_runtime_positions_slash_menu_per_editor_host -- --test-threads=1
```
如果第二个测试不存在,请新增相近测试并运行。
## 最终回复格式
- 修改文件列表
- 完成的 checklist 项
- 运行过的命令和结果
- 未完成项/风险
@@ -0,0 +1,57 @@
# Reasonix 任务:ACP permission 决策闭环
Project root: `/mnt/Data1T/mnote`
你不是唯一在代码库中工作的 agent。不要回滚、覆盖或整理与你任务无关的改动;不要提交 git;不要修改 `.gitignore``.codegraph/``auth-console.txt``auth-network.txt`
## 背景
Codex 已写 review`design/10-review/process/13-hermes-vscode-plugin-gap-review-v1.md`
本任务对应 checklist`design/07-ai/process/7-31-acp-permission-decision-loop-checklist-v1.md`
当前问题:`AcpClient` 对 incoming JSON-RPC `session/request_permission` 立即返回 unsupported/denyPage AI UI 虽有按钮,但点击不能真正影响 ACP 请求。
## Ownership
允许直接修改:
- `rust/crates/mnote-web/src/acp_client.rs`
- `rust/crates/mnote-web/src/acp_session_manager.rs`
- `rust/crates/mnote-web/src/acp_bridge.rs`
- `rust/crates/mnote-web/src/routes/hermes_client.rs`
- `rust/crates/mnote-web/src/ssr/pages/layout.rs` 中 permission 决策接线相关的小范围代码
- 相关 Rust 测试
- `design/07-ai/process/7-31-acp-permission-decision-loop-checklist-v1.md` 的执行记录
注意:`layout.rs` 可能被其他 worker 改动。只做 permission endpoint 调用与事件处理,不重排 Page AI drawer。
## 目标
实现 `permission.requested -> UI allow/deny -> ACP JSON-RPC response -> permission.allowed/denied` 的闭环。超时、缺失 pending request、缺失 run 时默认 deny 或返回清晰错误。
## 具体要求
1. `AcpClient` 支持注册 incoming request handlerhandler 可异步返回 result/error。
2. `session/request_permission` 不应立即 unsupported;应进入 pending request,向前端发 `permission.requested`
3. 增加后端 endpoint 或扩展现有 endpoint,让前端按 run id / permission id 提交 allow/deny。
4. 前端 `pageAiResolvePermission()` 必须调用后端,而不只是本地改 UI 状态。
5. 决策完成后向 SSE/UI 发送 `permission.allowed``permission.denied`
6. 补 mock ACP 测试覆盖 allow、deny、timeout/default deny。
## 验收命令
请至少运行:
```bash
cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web acp_client permission -- --test-threads=1
cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web acp_bridge permission -- --test-threads=1
cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web page_ai_uses_backend_acp_session_runtime_store -- --test-threads=1
```
## 最终回复格式
- 修改文件列表
- 关键实现说明
- 实际运行的验证命令和结果
- 未完成项 / 风险
@@ -0,0 +1,54 @@
# Reasonix 任务:ACP session info / plan UI
Project root: `/mnt/Data1T/mnote`
你不是唯一在代码库中工作的 agent。不要回滚、覆盖或整理与你任务无关的改动;不要提交 git;不要修改 `.gitignore``.codegraph/``auth-console.txt``auth-network.txt`
## 背景
Codex 已写 review`design/10-review/process/13-hermes-vscode-plugin-gap-review-v1.md`
本任务对应 checklist`design/07-ai/process/7-33-acp-session-info-plan-ui-checklist-v1.md`
当前 `AcpSessionManager` 已解析 `SessionInfoUpdate``PlanUpdate`,但 `acp_bridge.rs` 丢弃它们。
## Ownership
允许直接修改:
- `rust/crates/mnote-web/src/acp_bridge.rs`
- `rust/crates/mnote-web/src/routes/hermes_client.rs`
- `rust/crates/mnote-web/src/ssr/pages/layout.rs` 中 session info / plan event 处理的小范围代码
- 相关 Rust 测试
- `design/07-ai/process/7-33-acp-session-info-plan-ui-checklist-v1.md` 的执行记录
注意:`layout.rs` 可能被其他 worker 改动。请只做 event handling 和轻量 UI,不重排 Page AI drawer。
## 目标
`session_info_update``plan` 通过 SSE 转到 Page AI UI。session info 用于更新当前会话标题;plan 用轻量系统/状态消息展示,不写入页面正文。
## 具体要求
1. `AcpSessionEvent::SessionInfoUpdate` 转成 `session.info.updated` SSE。
2. `AcpSessionEvent::PlanUpdate` 转成 `plan.updated` SSE。
3. 前端收到 session info 后更新当前 session title,并持久化当前 session list。
4. 前端收到 plan 后渲染轻量 plan 状态,不能作为普通 assistant 正文。
5. 如果可低风险实现,解析 tool output 中 todo JSON 并复用 plan 区域展示;若风险高,可只写 TODO 到 checklist 执行记录。
6. 补 bridge 单测和 `SIDEBAR_TREE_JS` 字符串断言。
## 验收命令
请至少运行:
```bash
cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web acp_bridge -- --test-threads=1
cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web page_ai_uses_backend_acp_session_runtime_store -- --test-threads=1
```
## 最终回复格式
- 修改文件列表
- 关键实现说明
- 实际运行的验证命令和结果
- 未完成项 / 风险
@@ -0,0 +1,56 @@
# Reasonix 任务:ACP session/load 恢复
Project root: `/mnt/Data1T/mnote`
你不是唯一在代码库中工作的 agent。不要回滚、覆盖或整理与你任务无关的改动;不要提交 git;不要修改 `.gitignore``.codegraph/``auth-console.txt``auth-network.txt`
## 背景
Codex 已写 review`design/10-review/process/13-hermes-vscode-plugin-gap-review-v1.md`
本任务对应 checklist`design/07-ai/process/7-30-acp-session-load-resume-checklist-v1.md`
参考实现:`reference-code/hermes-vscode-main/src/sessionManager.ts`,重点是 `ensureSession()` 中调用 `session/load { sessionId, cwd, mcpServers: [] }`,失败再 fallback `session/new`
## Ownership
允许直接修改:
- `rust/crates/mnote-web/src/acp_session_manager.rs`
- `rust/crates/mnote-web/src/routes/hermes_client.rs`
- 与上述变更直接相关的 Rust 测试
- `design/07-ai/process/7-30-acp-session-load-resume-checklist-v1.md` 的执行记录
禁止修改:
- `rust/crates/mnote-web/src/ssr/pages/layout.rs`
- Convex schema / migrations
- 无关设计稿和 smoke 脚本
## 目标
实现或补齐 ACP `session/load` 恢复能力。恢复已有 ACP adapter session 时必须实际调用 adapterload 返回 null 或错误时 fallback 到 `session/new`
## 具体要求
1.`AcpSessionManager` 增加清晰 API,例如 `load_session(session_id, cwd)` / `ensure_session(cwd, stored_session_id)`
2. load 成功后当前 `session_id` 必须是 stored id。
3. load 失败、返回 null 或不支持时,不应让后续 prompt 继续使用 phantom id,应创建新 ACP session。
4.`routes/hermes_client.rs` ACP run 启动处接入恢复逻辑;注意区分 MNote session id、ACP session id、run id。
5. 补 mock ACP 测试:`session/load` 成功、null fallback、新建 session 后 prompt 仍可工作。
## 验收命令
请至少运行:
```bash
cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web acp_session_manager -- --test-threads=1
cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web hermes_client_acp_resume -- --test-threads=1
```
## 最终回复格式
- 修改文件列表
- 关键实现说明
- 实际运行的验证命令和结果
- 未完成项 / 风险
@@ -0,0 +1,55 @@
# Reasonix 任务:ACP tool locations 与打开动作
Project root: `/mnt/Data1T/mnote`
你不是唯一在代码库中工作的 agent。不要回滚、覆盖或整理与你任务无关的改动;不要提交 git;不要修改 `.gitignore``.codegraph/``auth-console.txt``auth-network.txt`
## 背景
Codex 已写 review`design/10-review/process/13-hermes-vscode-plugin-gap-review-v1.md`
本任务对应 checklist`design/07-ai/process/7-32-acp-tool-location-and-open-action-checklist-v1.md`
参考实现:`reference-code/hermes-vscode-main/src/protocol.ts` 会解析 `tool_call.locations[].path``src/chatPanel.ts` 在 read/edit tool 完成后打开对应 editor。
## Ownership
允许直接修改:
- `rust/crates/mnote-web/src/acp_types.rs`
- `rust/crates/mnote-web/src/acp_session_manager.rs`
- `rust/crates/mnote-web/src/acp_bridge.rs`
- `rust/crates/mnote-web/src/ssr/pages/layout.rs` 中 tool card 展示 / 打开动作小范围代码
- 相关 Rust 测试或必要 smoke
- `design/07-ai/process/7-32-acp-tool-location-and-open-action-checklist-v1.md` 的执行记录
注意:`layout.rs` 可能被其他 worker 改动。请避免大范围重排,只接线 tool locations 展示和 open action。
## 目标
保留 ACP tool `locations[]`,并在 Page AI tool card 中显示和打开。默认打开到 MNote 主编辑器资源 tab / 现有 file open resolver,不默认新浏览器窗口。
## 具体要求
1. `SessionUpdate::ToolCall` 解析 `locations: [{ path }]`
2. `AcpSessionEvent::ToolCall` 携带 locations。
3. `acp_bridge` SSE `tool.started` 包含 locations。
4. 前端 tool card 保存并显示 locations。
5. read/edit tool completed 时提供打开动作;优先复用现有主编辑器资源 tab 或已有 file open 函数。
6. 补测试覆盖 parse + SSE + 前端字符串断言。
## 验收命令
请至少运行:
```bash
cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web acp_tool -- --test-threads=1
cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web page_ai_uses_backend_acp_session_runtime_store -- --test-threads=1
```
## 最终回复格式
- 修改文件列表
- 关键实现说明
- 实际运行的验证命令和结果
- 未完成项 / 风险