Skip to content

功能规格说明:桌面端文件面板 ​

本面板为「源码/文本」视图:.html/.htm 路径的点击在桌面端优先进入预览面板渲染(见 desktop-preview.md「本地 HTML 文件预览」),该预览失败时回退本面板;本面板自身不因该故事改变行为。

用户场景与测试 ​

用户故事:文件面板(优先级:P1) ​

作为 CodeWave IDE 桌面端用户,我希望点击 read/edit/write 工具中的文件路径时在应用内打开一个只读文件面板查看文件内容,以便无需离开对话即可核对 agent 读写过的文件。远程 SSH 会话是引入该面板的契机——远程路径无法在本地打开(当前会报「打开文件失败」,甚至误打开同名文件);面板统一承载本地与远程的文件查看,本地会话额外提供「在默认应用中打开」以便跳出到外部编辑器。

为什么是这个优先级:远程会话点击工具路径当前会在本地尝试打开而报「打开文件失败」,是远程会话体验的直接缺陷;文件面板补齐该缺口,并统一本地/远程的文件查看入口。

独立测试:远程会话中点击 read 工具路径,验证 file 面板从远端读取并展示内容(行号、长行水平滚动、代码高亮);本地会话点击同一路径验证 file 面板从本地读取并展示,且「在默认应用中打开」按钮可用;点击另一条消息的路径验证替换显示;通过空态入口/「+」菜单/菜单栏「面板 → 文件」打开 file tab(未加载文件时显示占位),菜单栏项再次触发即关闭;点击含 . / .. 段的相对路径,验证按规范绝对路径读取、回填路径与面板标题均无冗余 .. 残留。

验收场景:

  1. 假设用户处于远程主机会话(host 非 local),当点击 read 工具的文件路径,则在右上角打开 file 面板,从远端读取该文件并显示内容,且不得出现「打开文件失败」系统消息。
  2. 假设用户处于本地主机会话,当点击 read 工具的文件路径,则在右上角打开 file 面板,从本地读取该文件并显示内容。
  3. 假设用户处于任意主机会话,当点击 edit/write 工具的文件路径,则 file 面板展示该文件的内容(edit 展示新版本)。
  4. 假设用户处于任意主机会话,当点击带起止行信息的文件提及/ContextTag,则 file 面板打开后滚动定位到对应行区间。
  5. 假设本地 file 面板已打开,当点击标题栏的「在默认应用中打开」按钮,则通过系统默认应用打开该本地文件(远程会话隐藏该按钮)。
  6. 假设file 面板已打开,当用户点击另一条消息的文件路径,则面板内容替换为新文件(单文件替换语义),标题同步更新,面板保持原位(不得因再次点击而移动行/位置)。
  7. 假设file 面板已打开,当再次点击当前已显示文件的路径,则重新读取并刷新内容。
  8. 假设file 面板已打开,当点击标题栏的复制按钮,则将完整文件路径(远程为远端路径)复制到剪贴板。
  9. 假设file 面板已打开,当用户关闭 file tab,则该文件查看视图关闭,不残留读取进程或端口转发资源;折叠(头部按钮)仅隐藏槽位并保留 tab(见 desktop-panels.md「右侧面板 · 展开/折叠、空间守卫与欢迎页共存」)。
  10. 假设分屏中有多个会话,当切换分屏焦点,则各分屏的 file 面板打开状态与文件内容相互独立(复用面板组按会话隔离规则)。
  11. 假设file 面板宽度较窄,当文件行超出面板宽度,则内容水平滚动而非折行,行号列固定不随水平滚动。
  12. 假设打开的是 markdown 文件,当面板加载完成,则按渲染后的 markdown 展示(复用现有 marked 渲染管线),而非纯文本。
  13. 假设打开的是代码文件,当面板加载完成,则按扩展名匹配进行轻量语法高亮;未知扩展名回退纯文本。
  14. 假设文件过大或为二进制,当面板读取该文件,则截断/拒读并给出提示,不得阻塞渲染或乱码展示。
  15. 假设打开的是图片(本地或远端,如 previewImage),当面板加载完成,则在面板内联展示图片预览(渲染后的图片,而非 base64 文本或裂图)。
  16. 假设文件不存在或不可读(远端或本地),当面板读取失败,则在面板内显示错误提示,不弹「打开文件失败」系统消息。
  17. 假设用户通过空态入口/「+」菜单打开 file tab(file 为唯一实例入口,open-or-activate:已有 file tab 只激活不新建),当file tab 已打开但尚未加载任何文件,则显示「点击消息中的文件路径查看」占位。
  18. 假设file 面板已打开或未打开,当用户点击菜单栏「面板 → 文件」菜单项,则按 desktop-panels.md「边界情况 · 菜单栏『面板』项与快捷键」的开/关切换语义处理:无 file tab 时打开/激活唯一 file tab(未加载过文件时显示占位提示),已有 file tab 时关闭;行为与预览/差异/终端面板菜单项一致。文件面板不设快捷键(与 Claude Code Desktop 一致,且 Ctrl+Shift+F 与 Windows 输入法简繁切换冲突)。
  19. 假设远端主机的 MIME 类型识别不可用(如缺少 file 命令或版本不支持常用探测参数),当面板打开扩展名为常见图片格式(png/jpg/jpeg/gif/webp/bmp/ico/svg)的远端文件,则仍按扩展名识别为图片并内联展示,不得误报「二进制文件无法在面板中显示」。
  20. 假设file 面板内联展示图片(本地或远端,含消息中的图片),当右键点击图片并选择「复制图片」,则图片被复制到系统剪贴板,可在其他应用或聊天输入框直接粘贴。
  21. 假设打开请求携带的路径含 . / .. 段(如消息中 `../sibling-repo/src/a.ts` 按会话 workdir 归并后),当面板读取并回填,则宿主按规范绝对路径(折叠 . 与 ..、无残留冗余段)读取,且回填给面板的 fileView.path 同为规范路径——面板标题显示规范路径(而非 …/proj/../sibling-repo/src/a.ts 这类含 .. 的串),复制路径、标题相对化、自动刷新比对均基于该规范路径;本地与远端会话行为一致,路径不存在时仍按场景 16 在面板内提示错误。归一化为纯词法折叠,不解析符号链接。

用户故事:文件面板自动刷新(优先级:P1) ​

作为 CodeWave IDE 桌面端用户,我希望 agent 对面板当前显示的文件执行 write/edit 工具且成功后,面板自动重新读取该文件并展示最新内容,以便在 agent 修改文件后无需手动再次点击路径即可核对最新结果。

为什么是这个优先级:agent 修改文件是高频操作;若面板停留在旧内容,用户核对时会误以为修改未生效,反复手动点击路径既打断流程也容易遗漏。自动刷新让「工具完成 → 面板即最新」无需额外操作,与 diff 面板的已读/最新语义一致。

独立测试:打开 file 面板显示文件 A → 在对话中让 agent 对文件 A 执行 write/edit 并成功 → 面板自动更新为最新内容且不滚动跳位;agent 对文件 B 执行 write/edit 或对文件 A 执行失败 → 面板保持不变;以含 ../ 的相对路径打开文件 A 后触发 write/edit,验证仍能自动刷新。

验收场景:

  1. 假设file 面板已打开显示文件 A,当agent 对文件 A 执行 write 工具且成功完成,则面板自动重新读取文件 A 并展示最新内容,用户无需再次点击路径。
  2. 假设file 面板已打开显示文件 A,当agent 对文件 A 执行 edit 工具且成功完成(含同一文件多次 edit),则面板自动刷新为最新内容。
  3. 假设file 面板已打开显示文件 A,当agent 对文件 B(非当前显示文件)执行 write/edit 并成功,则面板保持文件 A 不变,不因其他文件的写操作而刷新。
  4. 假设file 面板已打开显示文件 A,当agent 对文件 A 的 write/edit 执行失败或被权限拒绝,则面板不刷新,保持失败前的内容。
  5. 假设file 面板已打开显示文件 A,当write/edit 工具仍在执行中(streaming/running 阶段),则面板不提前刷新,仅在工具完成(end)后刷新一次。
  6. 假设file 面板已打开显示文件 A 且自动刷新触发,当刷新完成,则面板内容替换为最新内容,滚动位置不产生明显跳动(软刷新语义,与再次点击同一路径一致)。
  7. 假设用户通过含 . / .. 段的路径打开文件 A(如 `../sibling-repo/src/a.ts`),当 agent 随后对同一文件 A 执行 write/edit 并成功,则面板照常自动刷新:面板的打开路径与工具的displayPath/绝对路径都按同一套规范折叠(工具侧已由 path.resolve 归一)后可比对命中,不得因一侧是 …/proj/../sibling-repo/src/a.ts、另一侧是 …/sibling-repo/src/a.ts 而比对失败导致不刷新。

用户故事:文件面板文件搜索(优先级:P2) ​

作为 CodeWave IDE 桌面端用户,我希望在 file 面板顶部的搜索框中输入文件名片段即可查找并打开工作区文件,以便无需在消息流中翻找文件路径就能直接查看任意文件内容。搜索框复用输入框 @ 文件搜索的既有数据流(requestFileSuggestions → fileSuggestionsResponse),搜索范围与 @ 一致(锚定会话根目录,本地与远端通用);下拉在面板顶部搜索框下方朝下展开(与 @ 在输入框下方朝上展开的方向相反)。

为什么是这个优先级:file 面板当前只能通过点击消息中的文件路径打开文件;通过空态/「+」菜单打开 file tab 且未加载任何文件时仅有占位提示,缺乏主动查找入口。搜索框补全面板的"主动打开"能力;数据流与组件(建议下拉、请求/响应去重)均已存在可复用,宿主零改动,改动集中在共享 webview 侧,风险低。

独立测试:通过空态入口/「+」菜单打开 file tab(未加载任何文件时为占位态),在顶部搜索框输入文件名片段,验证建议下拉朝下展开、键盘与点击选中后在既有 file tab 中打开该文件(路径切换软刷新,不新增第二个 file tab;先显示加载中状态);回归输入框 @ 文件搜索,验证其行为不变。

验收场景:

  1. 假设file 面板已打开(含未打开任何文件的占位态),当聚焦顶部搜索框,则立即以空关键字请求并朝下展开建议下拉,展示工作区顶部文件(等效文件选择器)。
  2. 假设用户在搜索框输入文件名片段,当停止输入约 200ms,则发送 requestFileSuggestions 请求并展示匹配文件;目录项不展示(面板无法显示目录),避免误选报「无法在面板中显示目录」。
  3. 假设建议下拉已展示,当按 ↓/↑ 移动选中项并按 Enter 确认,则在面板中打开该文件(同点击消息文件路径:替换当前显示、先显示加载中、带行定位),搜索框清空、下拉关闭。
  4. 假设建议下拉已展示,当点击某个建议项,则等效于键盘 Enter 选中(打开文件并清空搜索)。
  5. 假设建议下拉已展示,当按 Esc 或点击下拉外部,则下拉关闭、搜索状态复位。
  6. 假设搜索请求尚未返回,当用户继续输入,则过期请求的响应被忽略(按 requestId 去重),仅最新关键字的结果生效,不出现结果闪烁覆盖。
  7. 假设搜索无匹配结果,当下拉展示,则显示「未找到匹配的文件」空态提示。
  8. 假设处于远端主机会话,当在搜索框选中远端文件,则面板从该远端主机读取并展示文件内容(打开请求携带会话对应的 host,路径为远端路径)。
  9. 假设分屏中存在多个会话,当在某一分屏的面板中搜索,则结果锚定该分屏所属会话的工作目录;各分屏面板的搜索状态相互独立,broadcast 响应按各自 requestId 隔离,不串扰。
  10. 假设输入框 @ 文件搜索正被使用,当本功能上线,则其行为不变(下拉朝上、键盘导航、插入语义均保持原样)。

用户故事:文件拖拽上传(优先级:P1) ​

作为 CodeWave IDE 桌面端用户,我希望把本地文件直接拖入对话面板任意位置即可上传到当前对话,以便无需先点「+」菜单再选文件,上传成功后文件路径以标签形式出现在输入框里待发送。

为什么是这个优先级:文件上传是对话中高频操作,拖拽是桌面端最自然的文件输入方式;现有上传只能通过「+」菜单逐次选择,拖拽大幅降低操作成本。

独立测试:将本地文件拖入对话面板(标题栏/消息列表/输入框均触发),验证全屏拖拽遮罩出现、拖离消失、松开后文件上传且路径标签插入当前分屏输入框;双分屏下分别拖入两个 pane 验证互不串扰。

验收场景:

  1. 假设用户从系统文件管理器拖拽一个或多个文件,当文件拖入对话面板范围(标题栏、消息列表、输入框任一区域),则面板出现全屏拖拽遮罩,提示「释放以上传文件」及支持多文件的说明。
  2. 假设拖拽遮罩已出现,当用户将文件拖离面板范围,则遮罩消失(拖拽计数防抖,快速进出不误触发)。
  3. 假设拖拽遮罩已出现且文件位于面板内,当用户松开鼠标,则遮罩清除、文件开始上传,上传成功后文件路径以标签形式插入当前对话输入框(与「+」菜单上传插入行为一致)。
  4. 假设文件拖入面板,当拖拽进行中,则不拦截正常消息输入等操作(输入框可继续输入,拖拽仅改变面板显示状态)。
  5. 假设桌面端存在多个分屏(pane),当用户将文件拖入某个分屏,则该分屏独立响应拖拽(遮罩显示在该分屏内),上传成功回包按 paneId 路由,仅目标分屏的输入框插入路径标签,其他分屏不串扰。
  6. 假设用户拖入的文件读取失败,当上传流程报错,则显示既有错误提示(如「读取文件失败」),不残留拖拽遮罩。
  7. 假设用户拖拽的不是文件而是会话条目或分屏标题(用于并排分屏/重排布局),当其经过对话面板,则不显示上传遮罩,仅显示分屏重排的插入位置指示——两类拖拽的视觉反馈互不混淆。

非目标(明确排除) ​

  • 文件面板的编辑能力:file 面板只读,不做编辑、保存、重命名等写操作;写操作仍由 agent 工具完成。
  • 目录树与文件浏览:file 面板仅按路径查看单个文件,不做目录树、跨目录浏览与文件管理;file tab 内搜索入口为工作区级「搜索→打开」能力,不构成目录树/浏览。
  • 本地会话的 file 面板不替代编辑器:本地会话中文件查看由 file 面板承载,需要真正编辑时通过「在默认应用中打开」跳出到外部编辑器/IDE,file 面板自身不做编辑。
  • IDE 插件的 file 面板:VSCE/JetBrains 不提供该面板,其 openFile 由 IDE 自身处理(含 IDE 的 Remote-SSH 能力)。
  • 语法高亮的语言覆盖:仅覆盖常用语言子集(highlight.js common 集),未覆盖语言纯文本展示。
  • 文件内搜索与符号跳转:不做文件内文本搜索、符号跳转等编辑器能力;file tab 内搜索入口为跨文件查找并打开,不涉及文件内定位。