DeepSeek Harness:edit/write 工具卡片的 diff 路径重复显示问题与 TUI 渲染层去重方案
发布时间:2026/9/5 21:35:42 锦皓数字建站

DeepSeek Harnessedit/write 工具卡片的 diff 路径重复显示问题与 TUI 渲染层去重方案【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness本文基于 DeepSeek Harness 仓库的归档技术笔记 2026-07-27-tui-diff-card-redundant-path-header.md完整还原一次 TUI终端界面渲染缺陷的发现、决策与验证过程。读完本文你将掌握edit/write工具卡片中 diff 数据的产生与流转链路、单文件 diff 卡片标题与文件头之间路径冗余的成因以及在“渲染层”而非“工具层”解决展示类冗余的设计取舍与测试加固手法。一、问题路径在卡片中出现了两次Harness 的edit和write工具在执行成功后会产出一张“diff 卡片”每个工具的presentCall/presentResult呈现器presenter返回一张卡片其标题为Edit path/Write path同时卡片内唯一一个FileDiff条目又携带同一个path。TUI 侧的diffLines渲染函数此前无条件地把palette.bold(diff.path)渲染成每个文件的小节头。于是对单文件编辑用户看到的是✓ Edit src/foo.ts src/foo.ts - old new路径src/foo.ts在视觉上出现了两次一次在卡片标题行一次在 diff 正文的文件头。值得注意的是原有快照夹具snapshot fixture反而掩盖了这个 bug它把 edit 卡片的标题写成Edit renderer不含路径并给结果放了两个 diff。由于标题与任何 diff 的路径都不匹配文件头看起来毫无冗余快照测试自然通过。这个细节是本文一个可复用的教训快照夹具如果不贴近生产数据形状就可能在“恰好不触发缺陷分支”的情况下长期隐藏问题。在仓库中FileDiff数据模型的来源可以印证这一链路diff.ts 中的computeHunkDiffs(path, before, after)对 before/after 文本做统一 diffunified diff上下文行数常量DIFF_CONTEXT 3为每个 hunk 产出一个FileDiff并把传入的path打在每个 diff 上——即“每个 diff 都带路径”是数据层的既定行为并非 TUI 的误用。edit.ts 中edit工具通过output.presentationMeta把computeHunkDiffs(...)的结果挂到结果元数据上供呈现器在会话重放replay时重建 diff 卡片。也就是说工具层在标题和 diff 中“双份携带路径”是有意的数据设计非 TUI 消费者如 web 端、快照序列化仍然需要这份完整信息。二、决策showPath开关 渲染层条件抑制修复方案分两步全部落在 TUI 渲染侧diffLines新增一个showPath布尔标志调用方决定本次渲染是否输出每文件头ToolCardComponent.renderBody对 diff 卡片做抑制判断当卡片内恰好只有一个 diff且“有效卡片标题”已经包含该 diff 的路径时抑制这个文件的文件头。其中“有效卡片标题”的取法是resultView?.title ?? callView.title——结果视图有标题时优先用它否则回退到调用视图的标题。两个边界行为是刻意设计多文件 diff 卡片保留所有文件头。多文件结果以及任何未来的多文件 diff 卡片确实需要每文件头来区分块归属空路径或空白路径的 diff会在同一个String.includes检查下被一并抑制——笔记将其定性为“预期的噪音消除”而不是误伤。为什么抑制逻辑放在渲染层而不是各工具的 presenter这是笔记中值得单独强调的架构判断冗余是展示问题presentation concern由每一个当前与未来的单文件 diff 卡片共同共享。若把去重逻辑写进edit/write各自的 presenter则每个新工具都要重复一遍而放在 TUI 渲染器里所有 diff 卡片包括未来新增的自动受益。同时工具侧保持“标题与 diff 双份携带路径”的产出不变非 TUI 消费者不受任何影响。这个分层与仓库中呈现器的职责划分一致从源码结构看工具包如 tool-fs负责产出结构化的FileDiff元数据而各 UI 表面web 端 ui-tool 包 中的ToolCard相关组件等各自决定如何呈现——本 bug 的修复正是把“呈现决策”留给了呈现层。三、备选方案与取舍笔记记录了两条被否决的路径其否决理由对理解“为什么最终方案长这样”很关键备选方案否决理由从edit/write卡片标题中移除路径标题是可扫读scannable的摘要行去掉路径会削弱它而且该修改需要在每个工具里重复实现无条件移除每文件头多文件结果 diff及未来多文件卡片确实需要每文件头一刀切会造成信息缺失最终方案是两者的折中按“单 diff 标题已含路径”这一条件精准抑制既不牺牲标题的摘要能力也不破坏多文件场景。四、已知局限子串匹配的启发式风险抑制判断本质是一个子串匹配String.includes因此存在理论误伤如果标题碰巧包含了某个单 diff 的路径例如标题本身只是引用了别的上下文文件头也会被抑制。笔记给出的定性是对真实的卡片生产方edit/write而言标题恰好就是Verb path形式所以实践中该启发式是正确的。这是一个典型的“在真实数据分布下成立的启发式”文档如实记录了其失效条件incidental match而不是把子串匹配包装成精确匹配。阅读此类渲染层启发式时可以把这条写进代码注释或评审 checklist任何includes型判断都应明确它依赖的标题格式契约。五、测试加固让夹具贴近生产形状修复的验证分两层tui.spec.ts新增聚焦用例断言对于标题为Edit src/only.ts的单 diff 卡片该路径恰好出现一次——直接锁定“不再重复”这一行为契约而非依赖像素级快照advanced-cards-*无 key 快照重录re-record重录后的快照显示标题行之后紧跟 diff 正文、中间没有重复的路径头。与此同时多文件头保留的场景由tui.spec.ts中的edit夹具继续覆盖a.txt/b.txt两个文件位于Edit files标题之下确保“抑制逻辑没有把多文件头也吞掉”。配套的快照夹具形状也被修正以贴近生产edit夹具现在是“一个 diff且标题指名了该 diff 的路径”——正是触发抑制分支的形状从而证明文件头确实被丢弃。这与第一节的教训闭环夹具形状从“恰好不触发缺陷分支”变为“正面覆盖决策分支”。六、延伸diff 卡片的数据链路源码印证结合仓库源码可以把这条 bug 涉及的数据流完整串起来执行edit.ts 的execute完成原子编辑返回{ path, before, after }元数据presentationMeta调用 computeHunkDiffs 生成FileDiff[]每个 hunk 一个 diffDIFF_CONTEXT 3行上下文纯插入用oldText: null元数据随会话日志持久化diffsFromMetadiff.ts在重放时对不透明的meta做防御性收窄——畸形数据返回undefined让呈现回退而不抛异常呈现工具呈现器把FileDiff[]组装成DiffCallView/DiffResultView类型定义见 presentation.ts标题为Edit path/Write path渲染TUI 的ToolCardComponent.renderBody→diffLines完成最终像素输出本 bug 的抑制逻辑即位于第 4 步。需要说明的是diffLines、showPath与ToolCardComponent为 TUI 终端渲染侧的组件笔记归档于 2026-07-31Status: implemented其具体文件路径未在该笔记中列出本文对其的描述以笔记原文为准。而第 1–3 步的数据链路可由上述仓库源码直接验证。七、可复用的经验小结展示类去重放渲染层当冗余是“每个表面都会遇到”的展示问题时把它收敛到共享渲染器而不是散落到每个数据生产方快照夹具要覆盖决策分支夹具数据形状若不触发目标分支测试通过等于没测修复后应让夹具“正面命中”新逻辑行为断言优先于快照“路径恰好出现一次”这样的计数断言比重录快照更能表达行为契约如实记录启发式边界子串匹配的误伤条件、多文件保留策略都写进了决策记录后续维护者不必重新推导取舍。【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。