From af126c3420f91ecdb60a456788f999285d94d3d7 Mon Sep 17 00:00:00 2001 From: Fishsb Date: Sat, 5 Sep 2026 17:08:12 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20=E5=85=BC=E5=AE=B9=E6=96=B0=E7=89=88?= =?UTF-8?q?=20DSH=20diff=20=E6=95=B0=E6=8D=AE=E5=A5=91=E7=BA=A6=EF=BC=8C?= =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=8D=A1=E7=89=87=E9=9D=99=E9=BB=98=E5=A4=B1?= =?UTF-8?q?=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DSH 0.1.2-rc.1 重构了 edit/write 工具卡的数据流:旧插件读取的 block.callView/resultView.card === 'diff' 结构已被整体移除,改为组件内 diffCardModel(block) 现算(settled 取 block.meta.diffs,PTC 子调用标记 从 callId ':code:' 改为 parentCallId)。由于槽位 shadowing 优先级选举 正常工作(priority -1 遮蔽内置 0),卡片被本插件接管但提取不到任何 diff 数据,静默降级为无内容摘要卡——表现为接管后红绿 diff 消失 (issue #3)。 extractDiffs 改为三层取数,新旧 DSH 双兼容: 1. settled 且非错误:优先 block.meta.diffs(与内置 appliedDiffs 同构, 含多 hunk 真实应用 diff) 2. PTC 子调用 / running / meta 缺失兜底:从 args 意图构建 (parentCallId 新标记,兼容旧 ':code:';argsRaw/name 防御性双取) 3. 旧版 DSH:保留 callView/resultView.card === 'diff' 回归读取 行级去重与字符级高亮算法不变。新版形状 5 例 + 旧版形状 3 例 + 边界 5 例共 13 项行为测试全过。 --- lib/client.js | 63 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/lib/client.js b/lib/client.js index d38147c..90e8388 100644 --- a/lib/client.js +++ b/lib/client.js @@ -160,32 +160,49 @@ window.__ModuleLoader__.load({ } function extractDiffs(block) { - // PTC 模式:从 argsRaw 动态构建 diffs - // callId 包含 ':code:' 表示这是 run_code 的子调用 - if (typeof block.callId === 'string' && block.callId.includes(':code:')) { - // RunningToolCall 的 argsRaw 在 block 上,ToolResultNode 的 argsRaw 在 block.call 上 - const argsRaw = block.call ? block.call.argsRaw : block.argsRaw - const name = block.call ? block.call.name : block.name - if (name === 'edit' || name === 'write') { - try { - const args = JSON.parse(argsRaw) - if (args && typeof args === 'object') { - const filePath = args.file_path - if (typeof filePath === 'string' && filePath !== '') { - if (name === 'write' && typeof args.content === 'string') { - return narrowDiffs([{ path: filePath, oldText: null, newText: args.content }]) - } - if (name === 'edit' && typeof args.old_string === 'string' && typeof args.new_string === 'string') { - return narrowDiffs([{ path: filePath, oldText: args.old_string || null, newText: args.new_string }]) - } + const done = 'kind' in block + // PTC 子调用标记:新版 DSH 用 parentCallId;旧版 callId 含 ':code:',双兼容 + const subCall = block.parentCallId !== void 0 || + (typeof block.callId === 'string' && block.callId.includes(':code:')) + + // settled 且非错误:优先取真实应用的 diff(新版 DSH 在 block.meta.diffs, + // 与内置 diffCardModel/appliedDiffs 同构 {path, oldText, newText},含多 hunk) + if (done && !subCall && !block.isError) { + const meta = block.meta + if (meta !== null && typeof meta === 'object' && !Array.isArray(meta)) { + const diffs = meta.diffs + if (Array.isArray(diffs) && diffs.length > 0) { + const n = narrowDiffs(diffs) + if (n !== null) return n + } + } + } + + // 子调用 / running / 兜底:从参数意图构建 diff。 + // running block 的 argsRaw/name 在 block 顶层,settled 在 block.call 上(防御性双取) + // settled 失败(非子调用)不显示意图 diff,与内置 diffCardModel 一致 + if (done && !subCall && block.isError) return null + const argsRaw = (block.call ? block.call.argsRaw : block.argsRaw) ?? '' + const name = block.call ? block.call.name : block.name + if (name === 'edit' || name === 'write') { + try { + const args = JSON.parse(argsRaw) + if (args && typeof args === 'object') { + const filePath = args.file_path + if (typeof filePath === 'string' && filePath !== '') { + if (name === 'write' && typeof args.content === 'string') { + return narrowDiffs([{ path: filePath, oldText: null, newText: args.content }]) + } + if (name === 'edit' && typeof args.old_string === 'string' && typeof args.new_string === 'string') { + return narrowDiffs([{ path: filePath, oldText: args.old_string || null, newText: args.new_string }]) } } - } catch {} - } + } + } catch {} } - - // 标准模式:从 callView 或 resultView 提取 diffs - if (!('kind' in block)) { + + // 旧版 DSH(<0.1.x 重构前):callView/resultView.card === 'diff' + if (!done) { const call = block.callView && block.callView.card === 'diff' ? block.callView : null return call ? narrowDiffs(call.diffs) : null } From ffeee270ed34f9c06c002efb999aa4d3022cba27 Mon Sep 17 00:00:00 2001 From: betterer <54624517+better-er@users.noreply.github.com> Date: Tue, 8 Sep 2026 04:45:35 +0800 Subject: [PATCH 2/2] =?UTF-8?q?style:=20=E7=B2=BE=E7=AE=80=20extractDiffs?= =?UTF-8?q?=20=E6=B3=A8=E9=87=8A=EF=BC=8C=E5=8E=BB=E6=8E=89=E5=8F=A5?= =?UTF-8?q?=E5=86=85=E7=A1=AC=E6=8D=A2=E8=A1=8C=E4=B8=8E=E8=A7=A3=E9=87=8A?= =?UTF-8?q?=E6=80=A7=E6=8B=AC=E5=8F=B7=EF=BC=8C=E7=BB=9F=E4=B8=80=E5=8F=A5?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/client.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/client.js b/lib/client.js index 90e8388..4efa22a 100644 --- a/lib/client.js +++ b/lib/client.js @@ -165,8 +165,8 @@ window.__ModuleLoader__.load({ const subCall = block.parentCallId !== void 0 || (typeof block.callId === 'string' && block.callId.includes(':code:')) - // settled 且非错误:优先取真实应用的 diff(新版 DSH 在 block.meta.diffs, - // 与内置 diffCardModel/appliedDiffs 同构 {path, oldText, newText},含多 hunk) + // settled 且非错误:取真实应用的 diff,新版 DSH 存放在 block.meta.diffs。 + // 结构与内置 diffCardModel/appliedDiffs 同构,支持多 hunk。 if (done && !subCall && !block.isError) { const meta = block.meta if (meta !== null && typeof meta === 'object' && !Array.isArray(meta)) { @@ -178,9 +178,9 @@ window.__ModuleLoader__.load({ } } - // 子调用 / running / 兜底:从参数意图构建 diff。 - // running block 的 argsRaw/name 在 block 顶层,settled 在 block.call 上(防御性双取) - // settled 失败(非子调用)不显示意图 diff,与内置 diffCardModel 一致 + // 子调用 / running / 兜底:没有真实 diff,改为从参数意图推断。 + // running 的 argsRaw/name 在 block 顶层,settled 的挪到 block.call 上,两处兼容。 + // settled 失败同样不显示意图 diff,与内置 diffCardModel 一致。 if (done && !subCall && block.isError) return null const argsRaw = (block.call ? block.call.argsRaw : block.argsRaw) ?? '' const name = block.call ? block.call.name : block.name @@ -201,7 +201,7 @@ window.__ModuleLoader__.load({ } catch {} } - // 旧版 DSH(<0.1.x 重构前):callView/resultView.card === 'diff' + // 旧版 DSH 在 0.1.x 重构前没有以上字段,回退从 callView/resultView 读 diff。 if (!done) { const call = block.callView && block.callView.card === 'diff' ? block.callView : null return call ? narrowDiffs(call.diffs) : null