背景
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 等参考实现的“静默呈现状态、点开查看详情”的风格不一致。
期望行为
- 编辑完成后(无论成功 / 失败),
tl-stream 自动折叠(display:none),不再用绿 / 红色边强调状态;铅笔图标按已有逻辑回归正常色,行尾保留 +N lines / failed 等小字状态摘要。
- 失败时不再自动展开
tl-detail;与成功一致保持折叠。
- 用户感兴趣时,点击该行可同时展开
tl-detail(结果 / 错误文本)和 tl-stream(写入的代码);再次点击重新折叠。
- 整体风格保持现有“安静呈现 + 可点开”的工具行交互,无新增 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{...} /* 删除 */
验证步骤
- 触发一次成功的
write_file(或 str_replace_in_file / apply_patch):
- 流式代码在编辑过程中正常滚动可见。
- 完成后流式代码块自动收起,铅笔图标变回正常灰色,行尾显示
+N lines。
- 点击该行,能同时看到结果文本和刚写入的代码;再点一次重新折叠。
- 触发一次失败的编辑(例如路径不在工作区内):
- 不再看到红色左边条 / 红
failed 标签 / 自动展开的错误块。
- 行尾显示
failed 小字 + 错误色图标即可。
- 点击该行可展开查看完整错误文本。
run_shell / web_search / spawn_agent 等其他工具的行为不受影响(这些分支没有改动)。
不在本次范围
addErrorCard()(顶层 chat 错误卡,.errCard)的视觉不在本次范围。
run_shell 失败仍保留 GH Copilot 风格的“失败自动展开 stdout”(其分支在 media/chat.js 第 2749–2766 行单独处理)。
风险
改动集中在 webview 渲染层,不涉及工具执行 / 安全边界,回归面较小。需关注:
_streamPre 的点击联动依赖 tc._streamPre 在点击时存在,跨 addToolLine → toolArgsDelta → toolResult 的生命周期里都已挂在 toolMap 上,逻辑可控。
tl-stream 删类后 CSS 中若仍有第三方扩展依赖 .tl-stream.done 选择器(应该没有),需一并通知。
背景
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 行media/chat.css第 213–218 行2. 失败时红色凸显过强 + 默认展开
tl-stream.done.err在完成态被强制改为红色左边条 + “failed” 标签:media/chat.css第 216–218 行classList.add("open")并把tl-detail设为display:block,强制把错误文本撑开:media/chat.js第 2762–2766 行两者叠加在视觉上形成“红边 + 红 failed 标签 + 自动展开的错误文本块 + 仍在的流式代码块”的强烈干扰,与 GH Copilot 等参考实现的“静默呈现状态、点开查看详情”的风格不一致。
期望行为
tl-stream自动折叠(display:none),不再用绿 / 红色边强调状态;铅笔图标按已有逻辑回归正常色,行尾保留+N lines/failed等小字状态摘要。tl-detail;与成功一致保持折叠。tl-detail(结果 / 错误文本)和tl-stream(写入的代码);再次点击重新折叠。建议改动(最小变更)
A.
media/chat.js第 1317–1322 行:让 prose line 的点击 handler 联动_streamPreB.
media/chat.js第 2686–2689 行:toolResult收到结果时直接折叠流式预览C.
media/chat.js第 2762–2766 行:失败不再自动展开D.
media/chat.css第 213–218 行:清理不再使用的 done / err 样式_streamPre完成态被折叠后不再加.done/.err类,下列规则可以一并删除,避免后续误用:验证步骤
write_file(或str_replace_in_file/apply_patch):+N lines。failed标签 / 自动展开的错误块。failed小字 + 错误色图标即可。run_shell/web_search/spawn_agent等其他工具的行为不受影响(这些分支没有改动)。不在本次范围
addErrorCard()(顶层 chat 错误卡,.errCard)的视觉不在本次范围。run_shell失败仍保留 GH Copilot 风格的“失败自动展开 stdout”(其分支在media/chat.js第 2749–2766 行单独处理)。风险
改动集中在 webview 渲染层,不涉及工具执行 / 安全边界,回归面较小。需关注:
_streamPre的点击联动依赖tc._streamPre在点击时存在,跨addToolLine→toolArgsDelta→toolResult的生命周期里都已挂在toolMap上,逻辑可控。tl-stream删类后 CSS 中若仍有第三方扩展依赖.tl-stream.done选择器(应该没有),需一并通知。