Skip to content

功能规格说明:桌面端原型预览 ​

用户场景与测试 ​

用户故事:localhost 原型预览(优先级:P2) ​

作为用户,当 agent 为我启动了本地开发服务器(如 Vite 原型)后,我希望点击消息列表中的 localhost 链接时在应用右侧打开预览面板,而不是跳转到外部浏览器,以便我边对话边看原型。

为什么是这个优先级:预览面板是「指哪改哪」闭环的载体,没有它元素评论无从谈起;但应用基础对话能力不依赖它。

独立测试:让 agent 启动一个 localhost dev server,点击消息中的 localhost 链接,验证右侧预览面板加载页面;点击非 localhost 链接验证仍用外部浏览器打开。

验收场景:

  1. 假设消息列表中渲染了 localhost 链接(localhost、127.0.0.1、[::1],任意端口),当用户点击,则必须在右侧预览面板打开并加载该 URL——新增/激活 preview tab 与隧道复用的实例语义见 desktop-panels.md「右侧面板 · 一级 Tab 栏与实例语义」场景 1-2,此处不重复。
  2. 假设用户点击非 localhost 的 http(s) 链接,则必须用系统默认浏览器打开,行为与现状一致。
  3. 假设预览面板已打开,当用户点击对应 tab 的关闭按钮,则关闭该 preview tab 即关闭对应预览;关闭最后一个 tab 时右侧面板随之一并收起(不显示空态,见 desktop-panels.md「右侧面板 · 一级 Tab 栏与实例语义」场景 10);再次点击 localhost 链接可重新打开。
  4. 假设预览中的 dev server 支持热更新,当 agent 修改源文件,则预览必须通过 dev server 自身的热更新机制自动反映改动;面板同时必须提供手动刷新按钮,且刷新必须绕过 HTTP 缓存(强制重新加载),确保 dev server 更新后的内容立即可见、不被过期缓存遮挡。
  5. 假设预览面板已打开,当用户点击「在浏览器打开」,则必须用系统默认浏览器打开当前预览 URL。
  6. 假设目标 localhost 服务不可达(未启动/已停止/端口错误),当预览加载失败,则面板必须显示可操作的错误提示(如「无法连接」+ 重试),而不是白屏。
  7. 假设预览页面自身的内容宽度超出面板可视宽度(如桌面布局的管理后台页面在窄面板中),当页面加载完成或面板宽度变化,则预览必须自动等比缩小页面内容以完整适配面板宽度(只缩小、不放大),确保超出部分可见且可点击/可选择,而不是被裁剪后无法操作;页面自身已完整适配面板宽度时不得放大页面内容(对齐 Claude Desktop 浏览器面板的缩放适配行为)。
  8. 假设页面在窄面板下已按宽度缩小适配(zoom < 100%),当预览面板进入全屏(面板被 CSS 撑宽、对话列隐藏)或该 preview tab 从 display:none 恢复可见(tab 切换/折叠后再展开,重挂载触发 resize),则必须按面板当时的实际宽度重新计算缩放比例——页面能放下时恢复到 100%,仍放不下时放大到恰好适配当前全屏宽度;不得沿用进入全屏/恢复前按窄面板算出的缩小比例(否则页面只占面板左上角一小块、其余留白)。

用户故事:本地 HTML 文件预览(优先级:P2) ​

作为桌面端用户,当 agent 为我生成或修改了一个本地 HTML 文件后,我希望点击消息中的该文件路径时在右侧预览面板看到渲染后的页面(而非源代码),以便直接核对 agent 产出的页面效果;页面打开不了时回退到文件面板查看源码,源码与渲染两条路都可达。

为什么是这个优先级:agent 产出单文件 HTML(数据报表、原型页、可视化)是高频场景,现状点击 .html 路径只能看到源代码高亮,核对效果必须跳出到外部浏览器;预览面板与 tab 基础设施均已存在,本故事只是把「本地文件」接入同一条预览管线(对齐 Claude 桌面端 Code 标签页:.html/.htm/.svg/.pdf/视频 点击走预览,失败回落文件面板;本故事范围仅 .html/.htm)。

独立测试:让 agent 在本地会话生成一个引用同目录 ./style.css 与 ./app.js 的 report.html,点击消息中的路径,验证预览面板新增 preview tab 且页面带样式/脚本完整渲染;再次点击同一路径验证激活既有 tab 不新增;点击另一 .html 验证新增 tab;让 agent edit 该文件并成功,验证预览自动重载为最新内容;删除文件后再点击,验证回落文件面板并显示其既有错误态;远程会话重复上述路径点击,验证主体内容渲染。IDE 插件(VS Code/JetBrains)中点击同一路径,验证仍由 IDE 编辑器打开(行为不变)。

验收场景:

  1. 假设本地会话消息中出现 .html/.htm 文件路径(read/write/edit 工具头或行内路径链接),当用户点击,则在右侧预览面板打开并渲染该文件(新增 preview tab,实例语义见 desktop-panels.md「右侧面板 · 一级 Tab 栏与实例语义」场景 1),且页面内的相对资源(./style.css、./app.js、./img/ 等同目录及子目录引用)必须正常加载——宿主以文件所在目录为服务根重托管该文件(具体机制由技术方案定),不得因相对路径解析不到而裸奔;同一文件被多处引用(<link>/<script>/<img>)经同一服务根命中。
  2. 假设同一会话中已打开某 .html 的 preview tab,当用户再次点击消息中同一文件的路径(按规范绝对路径判等,含 .. 归并后等价的路径),则激活该既有 tab 并重新加载最新内容,不新增 tab;点击不同 .html 文件则新增 tab(preview 多实例语义不变,本条为其按「文件路径」判等的例外条款,对应远端 localhost 链接的隧道复用例外见 desktop-panels.md 场景 2)。
  3. 假设远程会话(host 非 local)消息中出现 .html/.htm 文件路径,当用户点击,则同样在预览面板渲染该文件(宿主读取远端文件内容后重托管);首版为内容级重托管——页面对外部相对资源的引用(同目录 css/js/图片)允许缺失,页面按浏览器原生降级渲染(无样式/裂图不算错误、不弹提示),页面主体(HTML 结构与内联样式/脚本)必须可见。
  4. 假设被点击的 .html 文件不存在、不可读或超出可预览大小上限,当用户点击,则回退到文件面板并按其既有失败语义展示(desktop-file-panel.md 场景 16:面板内错误提示,不弹「打开文件失败」系统消息);宿主重托管能力不可用时同样回退文件面板展示源码,不得白屏或无响应。
  5. 假设某 .html 的 preview tab 处于激活状态,当agent 对该文件执行 write/edit 工具并成功完成,则该 preview tab 自动重新加载最新内容(与文件面板自动刷新的触发条件一致,见 desktop-file-panel.md「文件面板自动刷新」);手动刷新按钮同样可用且绕过缓存(沿用本规格 localhost 预览场景 4 的语义);agent 修改的是其他文件(如被引用的 ./style.css)时不自动重载,由用户手动刷新。
  6. 假设本地 .html 的 preview tab 打开中,当用户点击「在浏览器打开」,则用系统默认浏览器打开该文件(渲染语义与面板一致:同目录相对资源可用),沿用本规格场景 5 的按钮语义。
  7. 假设preview tab 打开的是本地 .html 文件,当查看 tab 标签,则沿用 desktop-panels.md 场景 3 的标题语义(页面 <title> → 文件名回退),不显示完整路径。
  8. 假设本地 .html 重托管服务已建立,当服务收到对其服务根之外路径的请求(目录穿越,如 ../../settings.json)或对非该会话已预览文件的请求,则必须拒绝(403/404),服务仅对本机回环地址可达;tab 关闭且无其他 tab 复用该服务时,服务必须随之销毁(不残留进程/端口)。
  9. 假设用户在 VS Code/JetBrains 插件中点击同样的 .html 路径,当点击发生,则行为与现状完全一致(IDE 编辑器打开),本故事全部能力为桌面端独有。

用户故事:预览页元素评论(优先级:P2) ​

作为用户,我希望在预览面板里悬停高亮某个元素、点击它并写下评论,评论连同元素上下文一起追加到消息输入框,以便我连续评论多个元素后统一发给 agent,agent 精确理解我指的是哪里并据此修改原型。

为什么是这个优先级:这是「指哪改哪」闭环的核心交互,是本特性区别于「单纯开个浏览器」的价值所在。

独立测试:打开预览 → 开启元素拾取 → 悬停验证高亮 → 点击元素 → 输入评论并添加 → 验证评论连同元素上下文追加到消息输入框(不直接发送)→ 再拾取另一元素添加第二条评论 → 验证两条评论都在输入框中,发送后聊天中出现一条含全部评论的用户消息。

验收场景:

  1. 假设预览面板已加载页面,当用户开启「元素拾取」模式,则鼠标悬停的元素必须显示高亮轮廓,且页面自身交互(点击、链接跳转、表单提交)被拾取拦截。
  2. 假设拾取模式已开启,当用户点击某元素,则必须显示跟随该元素的浮层评论卡片:评论输入框底部左侧显示元素标签名、右侧为无文字的圆形添加图标按钮;被选元素保持定格高亮;用户可回车或点击添加图标提交评论,可通过点击卡片外空白处取消,取消后回到悬停拾取状态、可改选其他元素。
  3. 假设用户提交评论,则不得直接发送给 agent,必须将评论追加到消息列表下方的输入框中,追加内容包含:页面 URL、元素 CSS 选择器、元素摘要、评论文本;输入框已有内容时必须保留并在其后追加;由用户在输入框中统一编辑后手动发送,发送后的消息呈现与普通用户消息一致。
  4. 假设拾取模式已开启,当用户再次点击拾取开关,则必须退出拾取模式、恢复页面正常交互;提交评论后必须保持拾取模式、回到悬停拾取状态,用户可连续拾取多个元素逐条添加评论(支持连续评论)。
  5. 假设页面发生导航或整体刷新,则拾取模式必须重置为关闭状态,防止拾取脚本随页面重建失效后界面状态不一致。
  6. 假设拾取模式已开启,当用户点击一个不可交互的元素(disabled 表单控件、fieldset[disabled] 内的控件、aria-disabled 行),则必须与可交互元素行为一致:弹出浮层评论卡片并定格高亮该元素;命中的是禁用控件内部的子元素时以该子元素为评论目标(与可交互元素的命中层级一致,也与悬停高亮一致)。pointer-events: none 的元素不参与命中,命中的是其后方元素(同样与悬停高亮一致)。

用户故事:预览面板全屏(优先级:P2) ​

作为桌面端用户,我希望预览面板可以全屏(占满内容区),以便专注查看网页/应用预览效果。

为什么是这个优先级:原型 InspectorPanel.vue 标签栏提供「全屏预览」按钮(toggleFullscreen),设计师 zip 对比(2026-08-29)确认 wave 缺失;全屏形态在原型 CSS 中定义为面板占满内容区、对话区隐藏(.inspector-fullscreen)。全屏按钮作用于整个槽位(tab 化模型下位于 tab 栏右端),槽位整体收起由头部按钮承载(见 desktop-panels.md「右侧面板 · 展开/折叠、空间守卫与欢迎页共存」)。

独立测试:打开预览面板,验证 tab 栏右端「全屏预览」按钮点击后整个槽位占满内容区(对话区隐藏)、按钮图标切换,再次点击或按 Esc 还原布局。

验收场景:

  1. 假设预览 tab 处于激活状态且槽位 tab 栏存在,当用户点击 tab 栏右端「全屏预览」按钮,则整个槽位占满内容区(对话区与其它 tab 隐藏),按钮图标切换为「退出全屏」。
  2. 假设槽位处于全屏状态,当用户再次点击「退出全屏」按钮或按 Esc,则退出全屏并恢复原布局(对话区与其它 tab 按全屏前的 tab 集合与宽度还原)。
  3. 假设槽位含多个 tab(多实例 preview 或混合类型),当槽位全屏,则仅当前激活 tab 的面板显示;还原后各 tab 宽度与激活态保持全屏前状态。
  4. 假设槽位全屏期间会话仍在运行,当查看对话状态,则消息流式更新不受影响(对话区隐藏但会话照常进行,退出全屏后可见最新消息)。
  5. 假设槽位处于全屏状态(此时对话区已隐藏、无可视退出入口),当用户关闭最后一个 tab(面板随之一并收起)或在侧边栏切换到另一会话,则退出全屏并恢复对话区——任何关闭/切换路径都不得让全屏状态残留(残留会同时隐藏对话区与面板区,内容区黑屏且无任何 UI 可恢复,见 PM bug 3465519197988352)。

边界情况 ​

  • 预览目标服务不可达:预览加载失败时必须显示错误提示与重试入口,不得白屏或影响聊天区。
  • 拾取脚本注入失败(页面异常、加载中途开启拾取等):必须提示「该页面暂不支持元素拾取」并保持面板可用,不得崩溃。
  • 被评论元素随后被 agent 改动:评论携带的是提交时刻的上下文快照;选择器失效不构成错误,后续评论需重新拾取。
  • HTML 文件含脚本错误或引用网络资源失败:预览按浏览器原生行为渲染(控制台错误不影响面板),不得因页面自身 JS 报错而判定预览失败;页面 <script> 在预览中允许执行(与外部浏览器打开同语义),风险面由场景 9 的服务根隔离与本机回环限制兜底。
  • 重托管与文件落盘的竞态(agent streaming 写入中途点击路径):读到什么渲染什么,文件随后写完由场景 5 的自动重载收敛到最终态,不对半成品文件做特殊提示。
  • 元素拾取与本地文件预览的叠加:首版不承诺本地文件预览 tab 支持元素拾取/评论(该能力面向 dev server 原型),叠加适配留待后续按需求排期。

非目标(明确排除) ​

  • IDE 插件的预览与元素评论:预览面板与元素拾取评论为 desktop 独有,VSCE/JetBrains 不提供。
  • URL 到源码文件的精确定位(如通过构建工具插件注入源码位置信息):首版不做,依赖 agent 会话上下文与元素评论上下文定位。
  • 拾取模式的键盘快捷键(Esc 退出等):首版不做,仅通过开关按钮管理拾取状态。
  • 元素截图:首版评论消息不附带元素截图,仅携带页面 URL、CSS 选择器与元素摘要等文本上下文。
  • .html/.htm 以外的扩展名路由到文件预览:Claude 桌面端把 .svg/.pdf/视频也划入预览类;wave 首版仅 .html/.htm——.svg 维持文件面板图片内联现状(desktop-file-panel.md 场景 15/19),.pdf/视频维持现状(源码/外部打开)。
  • 远程会话的目录级重托管:首版远程会话为内容级重托管(场景 3),相对资源经宿主 SSH 桥解析的目录级能力不做;若体验不可接受再按本故事场景 1 的本地语义扩展。
  • 预览到源码的直达入口(预览工具栏「查看源码」按钮等):不做;源码查看走消息路径点击的回退链(场景 4)或文件面板既有入口,对齐 Claude 桌面端(预览面板无跳源码按钮)。
  • preview tab 内的渲染/源码双视图切换(对齐 Claude 桌面端 artifact 页的 Preview/Code 分段控件):不做。