---
url: /wave-agent/specs/ui/file-selector.md
description: '`@` 触发的文件/目录选择器：快速选择、模糊搜索、目录导航与输入框上下文标签'
---

# 功能规格说明：文件选择器

**创建日期**：2026-01-22

> **平台边界**：前三个用户故事为 CLI 宿主（Ink/终端）；「插件端上下文标签」用户故事适用于插件端 webview（VSCE / JB）。

## 用户场景与测试 *（必填）*

### 用户故事：快速文件选择（优先级：P1）

作为用户，我希望通过输入 `@` 快速找到并选择文件，这样我不必手动输入完整路径。

**为什么是这个优先级**：这是改善用户在消息中引用文件效率的核心功能。

**独立测试**：可以在输入框中输入 `@`，输入部分文件名，并验证正确的文件出现在列表中且可以被选择。

**验收场景**：

1. **假设**光标在输入框中，**当**用户输入 `@` 时，**则**文件选择器必须出现
2. **假设**文件选择器已打开，**当**用户输入查询时，**则**列表必须实时过滤，排除 `.gitignore` 忽略的文件
3. **假设**文件被高亮，**当**用户按 `Enter` 或 `Tab` 时，**则**文件路径必须被插入到输入中

***

### 用户故事：目录导航（优先级：P2）

作为用户，我希望使用文件选择器浏览目录，这样我可以找到项目结构深处的文件。

**为什么是这个优先级**：项目通常有复杂的目录结构，能够浏览它们是必要的。

**独立测试**：可以输入 `@`，选择一个目录，并验证选择器现在显示该目录的内容。

**验收场景**：

1. **假设**文件选择器已打开，**当**选择目录时，**则**选择器必须更新以显示该目录的内容
2. **假设**选择器正在显示子目录，**当**用户继续输入时，**则**它必须在该子目录内搜索

***

### 用户故事：模糊搜索（优先级：P3）

作为用户，我希望模糊搜索能找到文件，即使我没有输入确切的前缀或有小拼写错误。

**为什么是这个优先级**：提高搜索功能的健壮性和易用性。

**独立测试**：可以输入 `@` 后跟一个非线性匹配文件的查询（如 "mgt" 匹配 "management"）并验证文件被找到。

**验收场景**：

1. **假设**文件选择器已打开，**当**输入模糊查询时，**则**相关文件应该仍然显示在结果中

***

### 用户故事：插件端上下文标签（优先级：P2）

作为插件端用户，我希望附加到消息的上下文（文件、图片、编辑器选区）以标签形式显示在输入框中，以便清楚知道本次发送携带了哪些上下文（哪类标签能点开见验收场景：只有选区和粘贴的图片能点，文件引用一律不能）。

**为什么是这个优先级**：上下文可见性提升信任感和可控性，但消息本身仍会以纯文本路径引用发送，属于体验增强。

**独立测试**：通过 @ 选择一个文件、从上传菜单附加一个文件、选中编辑器代码后添加选区，验证输入框中分别出现对应标签；图片文件与其它文件一样是不可点的普通标签，点击选区标签跳转到对应文件行。

**验收场景**：

1. **假设**用户通过 @ 提及选择了一个文件（**图片文件也一样**），**当**标签显示在输入框中时，**则**它就是一个普通文件引用标签：不可点击、不提供预览入口，与其它扩展名的文件没有任何差别（要看图请走粘贴，见场景 4）。
2. **假设**用户通过上传菜单附加了文件，**当**标签显示在输入框中时，**则**标签展示文件名，不可点击。
3. **假设**用户将编辑器中选中的代码添加为上下文，**当**标签显示在输入框中时，**则**标签显示"文件名 行范围"，点击可打开对应文件并定位到该行范围。
4. **假设**用户在输入框中粘贴了图片，**当**标签显示在输入框中时，**则**标签显示为"图片 N"，点击可全屏预览。
5. **假设**输入框中有上下文标签，**当**用户将光标移到标签旁按退格或删除键时，**则**标签被整体移除。
6. **假设**消息已发送，**当**该消息显示在消息历史中时，**则**其中的选区上下文与输入框中一样可点击并定位；文件引用（含图片文件）与输入框中一样不可点击，粘贴的图片标签见 `ui/image-pasting.md`。
7. **假设**消息已发送，**当**消息历史渲染上下文标签时，**则**粘贴的图片标签不再显示。

***

### 边界情况

* **空目录**：如果目录为空，选择器应该显示"未找到文件"消息或类似提示
* **权限拒绝**：如果代理没有权限读取目录，应该优雅处理错误
* **非常大的目录**：即使列出包含数千文件的目录，UI 也必须保持响应
* **路径中的特殊字符**：包含空格或特殊字符的路径在插入时必须正确转义
* **上下文标签不可编辑**：插件端输入框中的上下文标签是原子单位，不可在标签内编辑文字，只能整体删除
* **候选里还有子代理**：`@` 下拉除文件外还列出已加载的子代理（选中后 CLI 插入 `@agent:<名称>`，webview 插入可见 `@<名称>` 的标签），条目的排序与语义见 `multi-agent/subagent.md`「用户故事：显式子代理调用」
* **消息历史中的图片标签**：已发送消息历史中不渲染粘贴图片的上下文标签（避免历史消息内嵌大图）

## 假设

* `wave-agent-sdk` 中的 `searchFiles` 工具提供必要的文件系统访问
* 终端环境支持基于 Ink 的 UI 组件
* 用户对项目目录有读取权限
