Skip to content

Webview 工具卡片体验优化:编辑完成后流式代码块不折叠 / 报错红色凸显过强且默认展开 #156

@ZhouChaunge

Description

@ZhouChaunge

背景

write_file / str_replace_in_file / apply_patch 这类编辑工具在 webview 聊天流中以 prose tool line(.tl-wrap 形式渲染,并在行下方追加一个 流式代码预览块(<pre class="tl-stream"> 实时显示模型正在写入的内容。当前完成态(成功 / 失败)的视觉处理存在两个问题,造成用户视线被无意义地占用。

现状问题

1. 编辑完成后,流式代码块不会自动折叠

toolResult 处理时只对 _streamPre 添加了 .done 类(成功时左边条变绿、右上标签变 done),DOM 不会被收起或隐藏,导致编辑成功后那一大段刚写入的代码继续撑在对话流中,视觉非常吵。

  • 位置:media/chat.js 第 2686–2689 行
  • 相关 CSS:media/chat.css 第 213–218 行

2. 失败时红色凸显过强 + 默认展开

  • tl-stream.done.err 在完成态被强制改为红色左边条 + “failed” 标签:media/chat.css 第 216–218 行
  • prose line 非 shell/agent 分支会在失败时 自动 classList.add("open") 并把 tl-detail 设为 display:block,强制把错误文本撑开:media/chat.js 第 2762–2766 行

两者叠加在视觉上形成“红边 + 红 failed 标签 + 自动展开的错误文本块 + 仍在的流式代码块”的强烈干扰,与 GH Copilot 等参考实现的“静默呈现状态、点开查看详情”的风格不一致。

期望行为

  1. 编辑完成后(无论成功 / 失败)tl-stream 自动折叠(display:none),不再用绿 / 红色边强调状态;铅笔图标按已有逻辑回归正常色,行尾保留 +N lines / failed 等小字状态摘要。
  2. 失败时不再自动展开 tl-detail;与成功一致保持折叠。
  3. 用户感兴趣时,点击该行可同时展开 tl-detail(结果 / 错误文本)和 tl-stream(写入的代码);再次点击重新折叠。
  4. 整体风格保持现有“安静呈现 + 可点开”的工具行交互,无新增 UI 元素。

建议改动(最小变更)

A. media/chat.js 第 1317–1322 行:让 prose line 的点击 handler 联动 _streamPre

d.addEventListener("click", function(){
  if (!d.classList.contains("has-detail")) return;
  var open = d.classList.toggle("open");
  detail.style.display = open ? "block" : "none";
  var rec = toolMap.get(id);
  if (rec){
    rec._userToggled = true;
    if (rec._streamPre) rec._streamPre.style.display = open ? "block" : "none";
  }
});

B. media/chat.js 第 2686–2689 行:toolResult 收到结果时直接折叠流式预览

if (tc._streamPre){
  // 编辑完成:折叠流式代码块,不再用绿 / 红边凸显;
  // 行被标为 has-detail 后,用户点击即可同时展开 detail + 这段代码。
  tc._streamPre.style.display = "none";
  tc.root.classList.add("has-detail");
}

C. media/chat.js 第 2762–2766 行:失败不再自动展开

if (!tc._userToggled){
  tc.root.classList.remove("open");
  tc.body.style.display = "none";
}

D. media/chat.css 第 213–218 行:清理不再使用的 done / err 样式

_streamPre 完成态被折叠后不再加 .done / .err 类,下列规则可以一并删除,避免后续误用:

.tl-stream.done::before{...}       /* 删除 */
.tl-stream.done.err::before{...}   /* 删除 */
.tl-stream.done{...}               /* 删除 */
.tl-stream.done.err{...}           /* 删除 */

验证步骤

  1. 触发一次成功的 write_file(或 str_replace_in_file / apply_patch):
    • 流式代码在编辑过程中正常滚动可见。
    • 完成后流式代码块自动收起,铅笔图标变回正常灰色,行尾显示 +N lines
    • 点击该行,能同时看到结果文本和刚写入的代码;再点一次重新折叠。
  2. 触发一次失败的编辑(例如路径不在工作区内):
    • 不再看到红色左边条 / 红 failed 标签 / 自动展开的错误块。
    • 行尾显示 failed 小字 + 错误色图标即可。
    • 点击该行可展开查看完整错误文本。
  3. run_shell / web_search / spawn_agent 等其他工具的行为不受影响(这些分支没有改动)。

不在本次范围

  • addErrorCard()(顶层 chat 错误卡,.errCard)的视觉不在本次范围。
  • run_shell 失败仍保留 GH Copilot 风格的“失败自动展开 stdout”(其分支在 media/chat.js 第 2749–2766 行单独处理)。

风险

改动集中在 webview 渲染层,不涉及工具执行 / 安全边界,回归面较小。需关注:

  • _streamPre 的点击联动依赖 tc._streamPre 在点击时存在,跨 addToolLinetoolArgsDeltatoolResult 的生命周期里都已挂在 toolMap 上,逻辑可控。
  • tl-stream 删类后 CSS 中若仍有第三方扩展依赖 .tl-stream.done 选择器(应该没有),需一并通知。

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions