refactor: externalize local upload helpers

Add local-upload-runtime.js as a browser runtime module for upload and attachment helper functions, with sidebar fallback wrappers and a fixed runtime asset route.

While validating task479, fix the editor attachment delete path so DOM-selected local attachment links are mapped back to a Tiptap text selection before delete_selection(), preserving undo history and adjacent links.
This commit is contained in:
lix-2026
2026-05-24 22:42:53 +08:00
parent 418f8ff8b0
commit 0a03572601
10 changed files with 353 additions and 19 deletions
@@ -417,6 +417,55 @@ CodeGraph 复核:
- `codegraph_search startWithWebSocket` -> `rust/crates/mnote-web/browser/tree-live-controller.js`
- `codegraph_search startWithSseFallback` -> `rust/crates/mnote-web/browser/tree-live-controller.js`
### 9.4 Batch 3 执行记录(2026-05-24
Reasonix implementation run
- run id: `reasonix-2026-05-24T14-22-14-401Z-ea414358`
- worktree: `/mnt/Data1T/mnote-wt-3-19-local-upload-b3`
- 结果:未采纳。该 run 卡在提交 plan 后没有产生工作区 diff,也没有写出 handoff;主控终止残留 runner / acp 进程并删除临时 worktree。
Codex 主控直接完成的最小切片:
- 新增 `rust/crates/mnote-web/browser/local-upload-runtime.js`
- 新增固定 asset route`GET /api/mnote-browser-runtime/local-upload-runtime.js`
- `PageLayout``SIDEBAR_TREE_JS` 前注入 `type="module"` 外置脚本。
- `SIDEBAR_TREE_JS` 中以下上传/附件展示 helper 先做 runtime 代理,保留原实现 fallback
- `uploadedAssetTitle`
- `uploadedAssetUrl`
- `localAssetOpenUrl`
- `uploadedAssetType`
- `fileTreeIconKindForFileName`
- `isLocalUploadedAsset`
- `uploadedAssetExtension`
- `isNonOfficeAttachmentName`
- `attachmentExtensionFromFileName`
- `isPdfAttachmentFileName`
- `isCodeAttachmentFileName`
- `inferCodeAttachmentLanguage`
- `attachmentClassForFileName`
- `uploadedAttachmentClass`
- `uploadedFileSize`
采纳边界:
- 本批次不迁移 `uploadFileToMediaAsset``insertUploadedAssetIntoEditor``uploadFilesWithResolvedTarget` 主流程。
- 本批次不修改 `/api/local-folder/assets/upload` 请求字段、secondary pane 目标选择、resource tab、OnlyOffice、PDF/code 打开逻辑。
验证:
```bash
node --check rust/crates/mnote-web/browser/local-upload-runtime.js
cargo fmt --manifest-path rust/Cargo.toml --all --check
cargo test -p mnote-web sidebar_upload_runtime_routes_local_markdown_assets_to_local_folder
node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js
```
结果:
- `local-upload-runtime.js` route 返回 `200``content-type=application/javascript; charset=utf-8`
- `task479` 最终 `ok=true`,覆盖主编辑区上传目录、filetree folder drop、broken link 保留、无 active document 附件 tab、文件树滚动、标题来源、单附件删除保留相邻附件。
## 10. 分阶段执行清单
### P0:定位辅助与基线保护
@@ -439,7 +488,7 @@ CodeGraph 复核:
### P1:外置 resource open / local upload adapter
- [x] 新增 `rust/crates/mnote-web/browser/resource-open-runtime.js`
- [ ] 新增 `rust/crates/mnote-web/browser/local-upload-runtime.js`,或先与 resource open 合并为单个不超过 800 行的 `resource-open-runtime.js`
- [x] 新增 `rust/crates/mnote-web/browser/local-upload-runtime.js`,或先与 resource open 合并为单个不超过 800 行的 `resource-open-runtime.js`
- [x] 第一刀只迁 `layout.rs` 中 resource open 的纯函数和 bridge`web_shell.rs` 的 resource tab DOM、session、pane host 生命周期保持在后续 `document-pane-host-runtime.js` 批次。
- [ ]`SIDEBAR_TREE_JS` / `web_shell.rs` 中迁出资源打开路径适配,不改变现有 open intent
- page row -> 当前 pane page tab
@@ -282,6 +282,7 @@ Codex 主控复核修正:
- worker 初版把底层错误格式化为 `删除附件引用失败:{e}`,调用处也会加同一前缀;主控已改为 `error.to_string()`,避免用户反馈重复。
- worker 初版自报 `cargo check` 通过依赖临时 `reference-code` symlink;主控在 worktree 和主工作区分别重新验证。
- Reasonix runner 写出 completed 后底层 `reasonix acp` 残留,主控已清理本轮进程。
- 后续 `task479` 暴露 DOM `range.selectNode(link)` + `Backspace` 场景下 Tiptap selection 可能未同步,导致相邻附件删除检查失败;主控已在 `history_safe_commands` 删除前把 DOM 选中的本地附件链接映射回 Tiptap text selection,再调用 `delete_selection()`
已通过验证:
@@ -293,6 +294,9 @@ Codex 主控复核修正:
- 结果:`ok=true`
- 步骤:`uploaded -> selected -> deleted -> undo -> redo`
- 证据:`tmp/task488-local-attachment-link-delete-undo-smoke/result.json``tmp/task488-local-attachment-link-delete-undo-smoke/after-redo.png`
- `node scripts/task479-local-folder-markdown-resource-lifecycle-smoke.js`
- 结果:`ok=true`
- 覆盖:单附件 `Backspace` 删除保留相邻附件、真实附件文件不被级联删除、刷新后被删引用不回来。
- `codegraph index . --force && codegraph status .`
- 结果:索引 318 个文件,状态 up to date。
- 复核:`delete_selected_attachment_link_with_history``selected_local_attachment_link_text``is_local_attachment_link_selected` 均可通过 CodeGraph 搜索定位到 `editor_runtime/*`