Back to home@lzxcs

file-diff-pro

产物文件点击弹窗查看本轮 diff(代码类文件);非代码文件维持桌面打开。

Stars
0
Language
JavaScript
Created
Aug 26, 2026
Updated
Aug 26, 2026

Introduction

file-diff-pro

安装(Install)

需要 DSH(DeepSeek Harness)与 web profile(dsh web):

# 1. 安装插件(pnpm git 依赖)
dsh plugin --profile web add github:lzxcs/file-diff-pro
# 2. 在 ~/.dsh/profiles/web/cordis.patch.yml 末尾追加注入块:
- insert:
    - id: file-diff-pro
      name: 'file-diff-pro'
# 3. 重启 DSH Web(托盘菜单 → DSH Web 重启),浏览器 Ctrl+F5 刷新页面

卸载:dsh plugin --profile web remove file-diff-pro,并删掉 cordis.patch.yml 中的注入块。

Web GUI 插件:把会话末尾"产物"行的代码类文件芯片点击行为改为弹出 diff 弹窗,展示该文件在本轮会话中的全部改动;非代码文件维持原有行为(直接桌面打开)。

功能

  • 弹窗 diff(GitHub commit-diff 风格):点击代码类文件(扩展名内置表)→ 居中模态弹窗,聚合该文件本轮全部 hunk(edit/write 工具自带 oldText/newText),LCS 行对齐渲染:删除行红色 -、新增行绿色 +、上下文中性色,变更行内的词级高亮(LCS 词对齐,只标真正变化的片段),文件头统计条(本轮修改 +N −M · N 处修改 + GitHub 式 change-stat 方块条)+ 复制路径按钮(octicon-copy);多 hunk 文件每个 hunk 有吸顶头部(修改 N/M + 本 hunk +a −b 徽章,滚动时钉在弹窗顶部;单 hunk 文件省略该头——统计已在文件级出现一次,不重复);仿 GitHub 的交互基线:
    • 长 diff 折叠窗口:总行数 > 40 时默认只显示首 20 行 + 尾 20 行,中间为截断条 [↑ 收起] N 行已折叠 [↓ 展开](octicon fold-up/fold-down,点一次展开一批 20 行,可逐批收到全开);文件头 展开全部 文字按钮一键全开(评审后从图标改文字,防不可发现),展开后翻转为 收起(GitHub 只出不进,这里保留回退路径——无死路)。
    • rich / source 视图切换:文件头 segmented control(octicon codefile 图标,同 GitHub file-header:code=source、file=rich)——rich = 词级 LCS 渲染视图(默认),source = 纯行级 diff(同款行着色与符号列,但不做词级标记)。
    • Unified / Split 布局切换:文件头 segmented control(文字按钮「Unified」⟷「Split」,同 GitHub commit 页 diff=split):split = 左右并排对照——修改对(删除行 + 替换它的新增行)在同一行左右并排(旧行左列、新行右列,词级高亮分饰两侧),上下文行左右都填充;不成对的新增/删除行各占一侧、对侧为淡色空单元格(整行读作一条色带);两列等宽(1fr/1fr),超宽行在格内细微滚动;折叠条与多 hunk 头是 body 级整宽行(横向滚动时不随内容滚出)。对齐模型实证自 ?diff=split 的真实 DOM([旧行号|旧文本][新行号|新文本])。
    • 弹窗滚动区显式主题化 ::-webkit-scrollbar(暗色圆角 thumb、透明轨道——任何宿主下不出现默认亮色滚动条);底部"在编辑器中打开"调宿主打开器,ESC / 点击遮罩 / 关闭按钮 / 自动聚焦均可交互,深色 + 明色双主题均可(宿主 token),有过场动画并尊重 prefers-reduced-motion不显示行号——宿主 hunk 数据不含文件偏移,画假行号会误导。
  • 代码判定:内置常见代码/脚本/标记扩展名表(js jsx ts tsx cjs mjs py sh ps1 psm1 bat cmd go rs java c h cpp cc hpp cs rb php lua sql html css scss less json yaml yml toml ini vue svelte md);不在表内的文件(图片、二进制等)点击直接走原 openFile 桌面打开。凡本轮确实产出过 hunks 的文件(无论扩展名,如 .cjs),点击一律进 diff 弹窗——扩展名表只用于判断"无 diff 数据"文件的归属(此时代码文件弹提示、其他走桌面打开)。
  • 优雅回退:本插件通过 conversation.chat.turnTail chain(priority -1)接管产物行:有产物 至少一个产物有 diff 数据 → 正常接管(有数据的代码文件弹 diff,无数据的代码文件也弹窗显示提示 + "在编辑器中打开",避免系统"打开方式"对话框);产物全部为代码文件但都无 diff 数据 → 同样接管(提示弹窗);产物含非代码文件且无任何 diff 数据 → decline,内置产物行原样出现(非代码维持桌面打开)。

结构

  • lib/index.js — Node half:空 apply(v1 无宿主路由,diff 数据完全来自会话 tool/result 事件)。
  • lib/client.js — Browser half:window.__ModuleLoader__.load 惰性 CJS 工厂:
    • 注册 file-diffs 会话节点定义(仿 ui-deliverables 的 deliverables):turn/start 起状态,tool/call 记录调用视图(match.view.for === 'call'),tool/result(append surface)以结果视图(match.view.for === 'result',权威)优先、调用视图兜底,把 diff 卡片的 hunks 按路径聚合,发布为 turn 数据键 file-diffs(⚠ hunks 只读 match.view——消息内容 content[0] 上不存在 resultView/callView 字段);
    • conversation.chat.turnTail chain 条目 { priority: -1, select }:select 返回 { paths, files } 或 null(decline 回退);
    • FileDiffModal 为 GitHub commit-diff 风格实现:buildItems 把 hunks 摊平成渲染流(hunk 头 + LCS 对齐行),planFold/shrinkFold 纯函数管理折叠窗口(首尾 20 行、逐批 20 行展开),octicons(fold-up/fold-down/unfold/code/file)为 GitHub 原版 SVG path;视图状态(rich/source × unified/split)各司其职——split 以单一 fdpc-splitgrid 渲染所有可见旧/新单元格,折叠条与 hunk 头作整宽项插在行间。

安装(本 profile)

  • package.json dependencies 加 "file-diff-pro": "file:./file-diff-pro"
  • cordis.patch.yml insert 行 { id: file-diff-pro, name: 'file-diff-pro' }
  • pnpm-workspace.yaml packages 加入 file-diff-pro
  • pnpm install 后刷新页面(浏览器半边按请求读取)。

维护提示:与 edit-diff-pro 相同,改 lib/client.js 后刷新页面即生效;若 pnpm install 清掉 node_modules\file-diff-pro 的链接,用 junction 重建指向本目录。

已知限制

  • v1 不显示绝对行号(hunk 数据不含文件偏移,只含 ±3 行上下文;展示的是 hunk 序数 修改 N/M 而非文件行号)。折叠窗口同样按 hunk payload 的行数计数(非文件行区间)。Split 视图两侧同样无行号,列内超长内容随 body 横向滚动(GitHub 行为一致)。需要真实行号时仿 edit-diff-pro 加回环 read 路由。
  • 接管产物行后不再渲染内置行的"在文件夹中显示"(隐藏文件时)入口;非代码 chip 仍可桌面打开。
  • 收尾正文的行内文件提及链接不受本插件影响(仍走原桌面打开)。