# 4-46 FileTree / Editor Context Menu Download v1

> 状态：done
>
> 日期：2026-05-21
>
> Owner：FileTree action layer / editor attachment context menu

## 1. 问题

- 文件树 asset/resource 行右键菜单没有 `下载` 动作，虽然后端已有 `/api/local-folder/files/open?download=true` 下载入口。
- 主编辑器附件当前主要依赖 hover 后的更多按钮打开附件菜单，真实右键附件链接没有复用同一套菜单。
- 本地文件下载响应只有 `Content-Disposition: attachment`，缺少 filename，浏览器可能无法使用原文件名保存，中文文件名尤其不稳定。

## 2. 目标

- 文件树 asset 右键菜单显示 `下载`。
- 点击文件树 asset 下载时复用现有 attachment 下载链路，并记录 `data-mnote-filetree-last-action=download` / `data-mnote-filetree-last-action-status=requested`。
- 文件树已选中多个 asset/resource 时，右键任一已选文件执行 `下载` 会批量下载当前选择集中的资源文件。
- 文件树主 Markdown 文件行和本地文件夹行也应支持下载；文件夹下载为 `.tar` 包。
- 文件拖到本地文件树文件夹时，应上传到该文件夹路径，不应因缺少 `rootUri` 或 `documentId` 报错。
- 主编辑器附件右键打开附件 context menu，菜单内容与 hover 更多按钮一致。
- 本地文件下载响应带 `filename` 与 `filename*`，支持中文文件名。

## 3. Checklist

- [x] 文件树 asset 菜单增加 `download` 动作。
- [x] `handleTreeContextMenuAction` 处理 filetree asset `download`。
- [x] `Ctrl/Cmd` 多选和 `Shift` 范围多选后支持文件树 asset 批量下载。
- [x] 文件树主 Markdown 文件行支持下载原始 `.md` 文件。
- [x] 文件树本地文件夹行支持下载 `.tar` 包。
- [x] 文件拖到本地文件树文件夹时使用目标文件夹 `targetRelativePath` 上传。
- [x] 主编辑器附件链接右键打开 attachment menu。
- [x] `/api/local-folder/files/open?download=true` 响应补 `Content-Disposition` 文件名。
- [x] Rust contract / route 测试覆盖新增行为。
- [x] Reasonix 浏览器截图复核右键菜单与下载入口。
- [x] Codex post-fix browser smoke 复核文件树 asset 单文件下载与 Ctrl/Cmd、Shift 多选下载。

## 4. 验收

- `cargo test -p mnote-web sidebar_tree_runtime_renders_context_menu_and_scoped_title_updates -- --test-threads=1`
- `cargo test -p mnote-web local_file_open_download_sets_content_disposition_filename -- --test-threads=1`
- `cargo test -p mnote-web local_folder_open_downloads_directory_as_tar -- --test-threads=1`
- `cargo test -p mnote-web web_shell -- --test-threads=1`
- `node --check scripts/task476-filetree-editor-context-menu-download-smoke.js`
- `node scripts/task476-filetree-editor-context-menu-download-smoke.js`
- Reasonix pre-fix browser result：`tmp/reasonix-filetree-editor-context-menu-2026-05-21/result.json`
- Codex post-fix browser result：`tmp/task476-filetree-editor-context-menu-download-smoke/result.json`

## 4.1 执行记录

- 2026-05-21：Reasonix 浏览器测试确认：文件树 asset 右键菜单缺少 `download`，主编辑器附件 hover/菜单下载可用。
- 2026-05-21：已补 filetree asset `download` 菜单项和 action handler，下载时复用 attachment 下载链并记录 filetree action 状态。
- 2026-05-21：已补文件树多选下载，右键已选资源时按当前选择集批量触发浏览器下载；`task476` smoke 覆盖 `Ctrl` 多选 2 个文件与 `Shift` 范围多选 3 个文件。
- 2026-05-21：已补主 Markdown 文件行下载、文件夹 `.tar` 下载和拖到文件夹上传；`task476` smoke 覆盖 `README.md` 下载、`README.tar` 下载，以及 `README/drag-upload-note.txt` 上传落盘。
- 2026-05-21：已补主编辑器附件链接真实右键菜单，右键打开与 hover 更多按钮一致的 attachment menu。
- 2026-05-21：已补 local-folder open 下载文件名：`Content-Disposition` 同时提供 ASCII fallback `filename` 与 UTF-8 `filename*`。
- 2026-05-21：`task476` post-fix browser smoke 通过；文件树 asset 单文件下载得到浏览器 suggested filename `report-a.pdf`，`Ctrl/Cmd` 多选下载得到 `report-a.pdf` / `report-c.pdf`，`Shift` 范围下载得到 `report-a.pdf` / `report-b.pdf` / `report-c.pdf`。该 smoke 中编辑器附件链接未渲染为可见项，作为本轮文件树多选下载的非阻塞项记录为 `editor_attachment_not_visible`。

## 5. 非目标

- 不一次性实现 attachment 菜单中所有历史占位动作。
- 不改变文件树删除语义。
- 不重构完整 command service。
