# 5-42 local Markdown 图片尖括号链接与 OCR 任务入口回归

## 状态

- 状态：done
- owner：05-editor-mainline
- 发现时间：2026-06-01
- 修复时间：2026-06-01

## 现象

默认测试账号的 local-folder 页面中，上传图片后 Markdown 正文出现 `![name](<./name.png>)` 形式的 CommonMark 链接目标，页面内图片显示为破损图。点击资源 tab 的“生成 OCR”后，如果 MinerU token 缺失导致 `/api/local-folder/ocr/jobs` 返回 401，右下角/任务入口没有任何可见任务，只能在资源 tab 状态里看到失败文本。

同时用户期望 OCR 任务入口移到右上角 topbar 固定图标区，避免继续使用右下角悬浮入口。

## 根因

- 浏览器端 `document-tiptap-conversion-runtime.js` 在把 local Markdown 图片 src 转成 `/api/local-folder/files/open` 时，没有解包 CommonMark `<...>` 链接目标，导致请求 path 携带 `%3C` / `%3E`。
- `document-resource-tab-runtime.js` 的 OCR 创建失败分支只更新当前资源面板状态，没有构造失败 job 并写入全局 OCR 任务列表。
- OCR 任务入口由运行时动态创建在右下角 dock，未接入 Wolai topbar action 区。

## 修复

- 本地资源路径规范化前统一解包 `<...>` Markdown 链接目标。
- OCR 创建开始时写入 running 任务，请求失败时写入 failed 任务，任务抽屉可见错误信息与重试入口。
- 在 topbar 增加 OCR 任务图标，运行时复用该按钮切换任务抽屉；右下角悬浮按钮移除，仅保留右上角抽屉。

## 验证

- `node --check rust/crates/mnote-web/browser/document-tiptap-conversion-runtime.js`
- `node --check rust/crates/mnote-web/browser/document-resource-tab-runtime.js`
- `node --check scripts/task526-local-folder-ocr-api-smoke.js`
- `cargo fmt --check --all`
- `cargo test --manifest-path rust/Cargo.toml -p bridge-runtime local_markdown_image_legacy_projection_exposes_image_attrs -- --nocapture`
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web markdown_image_parses_as_image_block -- --nocapture`
- `cargo test --manifest-path rust/Cargo.toml -p mnote-web local_markdown_save_rewrites_local_file_open_url_to_markdown_relative_path -- --nocapture`
- `scripts/task526-local-folder-ocr-api-smoke.js` 覆盖：
  - `![photo](<./Page.assets/photo.png>)` 渲染出的图片 `naturalWidth > 0`，且请求 URL 不含 `%3C` / `%3E`。
  - OCR 任务入口位于 `.wolai-topbar-actions`。
  - mock OCR 成功任务可在任务抽屉中显示。
  - 模拟 401 失败后，任务抽屉显示 failed row 与 `local_ocr_job_failed_401`。
  - OCR sidecar 可作为 Markdown resource tab 打开。
