Files
deepseek-harness/.agents/notes/implemented/bug-fix/2026-07-27-tui-diff-card-redundant-path-header.zh.md
T
Turtle 4c5f92e0fd feat(tui): personal TUI rework, integrating upstream model reasoning-effort selection
Consolidates the personal dsh-tui customizations (module split into
components/session/extension, prompt template + running-glyph indicator,
copyable transcript, tool-card headers, timing placement, XML tool output,
status/footer rework) and ports upstream's model reasoning-effort selector
(Shift+Tab effort cycling, effort-aware /model, footer, and /status) onto
the personal module layout.
2026-07-27 18:55:13 +08:00

2.5 KiB
Raw Blame History

Agent Note: TUI diff 卡片重复打印文件路径

Status: implemented

English | 中文

Problem

edit 与 write 工具卡片会把目标路径打印两次。两者的 presentCall/presentResult 返回的 diff 卡片,标题为 Edit <path>/Write <path>,而其唯一的 FileDiff 又携带相同的 path。TUI 的 diffLines 无条件地将 palette.bold(diff.path) 渲染为每文件的表头,因此单文件编辑会渲染成:

✓ Edit src/foo.ts
src/foo.ts
- old
+ new

既有的快照 fixture 掩盖了这个问题:它把编辑卡片标题设为 Edit renderer(不含路径),并让结果包含两个 diff,于是标题从未与某个 diff 路径匹配,表头也就不显得冗余。

Decision

diffLines 新增 showPath 参数;当一个 diff 卡片只有一个 diff、且生效标题(resultView?.title ?? callView.title)已包含该 diff 的路径时,ToolCardComponent.renderBody 抑制每文件表头。多文件 diff 卡片保留全部每文件表头。空白或空路径同样落入这条 String.includes 判定之下,这正是有意去除的噪声。

抑制逻辑放在 TUI 渲染层,而非各工具的 present 方法中,因为这种冗余是所有当前及未来单文件 diff 卡片共有的展示问题;工具仍在标题和 diff 中同时给出路径,从而非 TUI 消费方依旧能拿到它。

Alternatives considered

  • 从 edit/write 卡片标题中去掉路径。已否决:标题是可快速扫读的摘要行,去掉路径会削弱它,而且需要在每个工具里重复处理。
  • 一律去掉每文件表头。已否决:多文件结果 diff(以及未来任何多文件 diff 卡片)确实需要每文件表头。

Consequences

该启发式是子串匹配,因此若标题恰好包含某个单一 diff 的路径,即便是偶然匹配也会抑制表头;对真实的产出方而言标题恰为 Verb <path>,故在实践中是正确的。快照 edit fixture 现在与生产一致:单个 diff,其路径正是标题所命名,从而证明表头被去除;而多文件表头保留由 tui.spec.ts 的 edit fixture(Edit files 标题下的 a.txt/b.txt)覆盖。

Testing

tui.spec.ts 新增一个聚焦用例,断言标题为 Edit src/only.ts 的单 diff 卡片中路径恰好出现一次。advanced-cards-* 无密钥快照已重新录制,展示标题行紧接 diff 正文、不再有重复的路径表头。