PiUI-style diff viewer replacing the stock DiffBlock for write/edit tool calls.
- Language
- JavaScript
- Branch
- master
Install
$ dsh plugin --profile web add github:lehhair/dsh-diff-viewerRun the command above in your terminal to install this plugin via the dsh CLI. You can switch Profile in the top-right corner. New to dsh? Read the beginner tutorial
Install via your agent
Install the DeepSeek Harness plugin lehhair/dsh-diff-viewer for me: review the repository at https://github.com/lehhair/dsh-diff-viewer first, then run the install command and verify the plugin loads successfully.
Paste this instruction to the DSH Web GUI assistant — it will install and verify for you.
一句话定位
为 DSH Web 的 write/edit 工具调用结果提供更易读的 diff 渲染:用单栏或双栏显示新旧内容、突出每行变更条,并对行内改动做词级高亮。
核心能力
- 接管 write/edit 工具调用的 diff 卡片渲染,复刻官方行的外观,只替换展开后的 diff 主体
- 单栏(unified)默认渲染:旧/新行号同列并排;宽度 ≥ 800px 时自动切换双栏(split)视图
- 每行变更条:新增行左侧实心绿条,删除行左侧条纹红条,行背景色延伸至最宽行
- 词级高亮:行内改动按词叠加绿/红标记,并保留 shiki 语法着色(TypeScript、shellscript、JSON)
- 长 diff 折叠:未变更的连续上下文可折叠成 "N 行未变更" 占位行,支持向上 / 向下 / 全部展开
- 窗口化渲染:固定行高下按视口位置虚拟化行元素,大 diff 不挂载全部 DOM
- 内置复制按钮(1 秒复制成功反馈),页脚显示 "+A -R · N file(s)" 汇总
技术实现
- 语言: TypeScript + React(编译产物 lib/client.js)
- 关键依赖:
diff(行级/词级 diff 计算)、shiki(语法高亮,本地内置的 TS/Bash/JSON 三个 grammar)、clsx(class 拼接) - 架构模式: 客户端插件,通过 ui-tool 的
tool.call.toolviewkeyed 槽位以 priority -1 注册edit/write两个 key,阴影覆盖官方FileMutationRow;卸载即恢复 - 入口文件: 宿主入口
src/index.ts(仅占位 apply());客户端入口src/client/index.tsx(apply 注册MutationRow),实际渲染src/client/mutation-row.tsx+src/client/DiffViewer.tsx
适用场景
当你在 DSH Web 里看着 AI 用 write/edit 工具反复改文件、原生 diff 卡片又长又难对位时,本插件把改动按行展开、加变更条、对行内改动再画一层词级高亮,长文件里的未变更段落会自动折起来。如果你常用宽屏或想把"看一下改了什么"做得更轻量,这个插件直接接管官方行,安装即生效,无需配置。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| DSH | >=0.0.1 | 由 dsh.plugin.json 的 engines.dsh 声明 |
| Node | 未声明 | 源码未声明运行时要求 |
| 平台 | 跨平台 | 不依赖原生模块,无 os/cpu 限制 |
| React | ^18.2.0 | 通过 peerDependencies 声明 |
| Cordis | ^4.0.0-rc.7 | 通过 peerDependencies 声明 |
| @deepseek-ai/dsh-client-ui-primitives / -ui-slots | * | 运行时所需的客户端包,通过 peerDependencies 声明 |
| 原生模块 | 无 | 无 native module 依赖 |
安装方式
dsh plugin --profile web add github:lehhair/dsh-diff-viewer
配置项
本插件无需额外配置。它是一个纯客户端渲染替换,不读取任何配置文件或环境变量。所有显示细节(如单/双栏切换、词级高亮、上下文折叠)由 DiffViewer 组件根据输入 diff 内容和容器宽度自动决定。
可选的组件 props(仅供上层调用方使用,普通用户无需关心):
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| viewMode | 'split' | 'unified' | 首次渲染的布局模式,宽度变化后由容器观察器自动接管 | unified |
| lang | string | 语法高亮的语言标识(ts、sh、json 等) | 由文件后缀推断 |
| maxLines | number | 行数上限,超过则内部滚动;详情面板通常不传 | 无限制 |
| className | string | 额外 class 合并到外层包装 div | — |
| labels | object | 覆盖空态/折叠/展开按钮的多语言文案 | 内置中文文案 |
常见问题
Q: 这个插件解决什么问题?
A: 它替换 DSH Web 内置的 write/edit 工具调用 diff 卡片,提供更清晰的单栏/双栏视图、变更条、词级标记与长 diff 折叠,让"看一眼改了什么"更轻量。
Q: 安装后需要做什么额外配置吗?
A: 无需任何配置。插件只注册到 ui-tool 的 diff 卡片槽位,覆盖 write/edit 两种工具调用,卸载即还原官方原版。
Q: 编辑/写入调用结果是展开还是收起?
A: edit 成功完成的结果默认展开(直接看到替换 diff),write 与运行中、出错的调用保持默认收起状态。
Q: 单栏与双栏如何选择?
A: 由容器宽度自动决定:宽度 < 800px 用单栏(unified),≥ 800px 用双栏(split)。纯新增或纯删除会强制回退单栏。
Q: 词级高亮支持哪些语言?
A: 插件内置了 TypeScript(含 ts/tsx/js/jsx)、shellscript(含 bash/sh/zsh)、JSON(含 jsonc)三套语法。其他语言不会报错,仅按纯文本渲染。
Q: 卸载后会发生什么?
A: 使用 dsh plugin --profile web remove @dsh-external/dsh-diff-viewer 即可。插件以更低的 priority 注册槽位,卸载后官方行自动恢复,不需要重启之外的额外操作。
Q: 升级时为什么会装到旧版本?
A: pnpm 会按 URL 缓存 tarball。同一 latest 链接出新版本后可能命中旧缓存,需要先 remove 再 pnpm store prune 后重装。
Q: 会影响工具调用本身吗?
A: 不会。插件只接管"渲染外观",write/edit 工具的执行流程、参数和结果都来自 DSH 宿主,插件不修改任何核心逻辑。
上手难度
入门 — 安装一条命令生效,无任何配置项;普通用户无需阅读源码即可使用。
已知问题与限制
- DSH 的
releases/latest直链在升级时可能被 pnpm 缓存命中旧 tarball,导致升级失败或装到旧版,需先dsh plugin --profile web remove再清理 pnpm store 后重装(README.md:48-52) - 直接从本地目录安装时,Windows 上
dsh plugin add <本地目录>的link:绝对路径存在 junction bug,建议先npm pack后用 tarball 安装(README.md:63) - 单栏/双栏自动切换阈值固定为 800px(
resolveDiffViewMode),未提供手动覆盖入口;纯新增或纯删除的 diff 始终强制使用单栏(src/client/DiffViewer.tsx:87-89, 876-878) - 语法高亮仅覆盖 TypeScript/shellscript/JSON 三族语言,其他语言的改动行按纯文本显示(src/client/highlight.ts:38-52)
- 暂未声明 Node 版本要求;源码中未发现 TODO/FIXME/HACK 注释
dsh-diff-viewer
DSH Web GUI 的 PiUI 风格 diff 查看器插件:替换 write/edit 工具调用的 diff 渲染(原 DiffBlock)。
- unified 单栏默认:同一 gutter 并排显示旧/新行号,无左右错位;split 双栏可选(
viewMode) - 变更条:新增实心绿条、删除条纹红条;行背景色带统一延伸到最宽行
- 词级高亮:行内改动叠加绿/红标记,shiki 语法着色(
highlightLines) - 上下文折叠:长段未变更行折叠为"
N 行未变更",向上/向下/全部展开 - 窗口化渲染:固定行高窗口化,大 diff 不挂载全部行;sticky 横向滚动条(hover 显现)
- 复制 +
└ +A -R · N file(s)页脚 - edit 结果默认展开:settled 的 edit 结果卡展开即见替换 diff(write 保持默认收起)
- PTC/Code 嵌套支持:Code Dispatch 内的 write/edit 子卡片同样接管——嵌套子调用没有 wire diff view,插件按工具自身的
presentCall语义从参数推导调用时 diff(edit 的 old_string→new_string、write 的整文件新增),错误子调用保持通用错误路径
机制
插件通过 keyed 接管替换 write/edit 的工具行渲染:ui-tool 的 tool.call.toolview 槽是开放 key 域,同一 key 以更低 priority 阴影(最低优先渲染)。插件注册 edit/write 键(priority -1),接管后的行完全复刻官方 FileMutationRow(复用官方 ToolRow 样式 + DisclosureRow/StateDot 等平台组件),只把展开后的 diff 卡换成 PiUI 风格 DiffViewer——不改任何核心,纯插件,卸载即还原官方行。
- 不限制高度:展开的 diff 直接撑开显示完整内容(不套滚动容器),窗口化渲染保证超大 diff 依然高效
- diff 数据:从工具调用的
callView/resultView的card:'diff'意图提取(running 用调用时 diff,settled 用应用后的 hunks);执行错误(无 diff 卡)走官方行的错误摘要 + IN/OUT 卡 - 嵌套兜底:Code Dispatch 子调用(PTC 模式)的
callView/resultView恒为 null(分发桥不落 presentation meta),插件回退到参数的调用时 diff——与官方行渲染同一调用的 running 态一致
效果
安装
方式一:GitHub 仓库直装(源码 + 构建产物)
lib/ 构建产物已提交进仓库,因此 github: 直装可直接工作(market 的 Install 按钮即走此路径):
dsh plugin --profile web add "github:lehhair/dsh-diff-viewer"
直装装的是仓库当前 commit 的构建产物。想要跟随最新 commit 请用 Release 资产(见下),它永远指向最新发版。
方式二:GitHub Release 构建产物(推荐,跟随发版)
每次发版后,GitHub Actions 自动构建并把 tarball 附加到 Releases 页。releases/latest 永远指向最新版本,安装链接不需要随版本改动:
# 直接用 latest 资产 URL(永远是最新版):
dsh plugin --profile web add "https://github.com/lehhair/dsh-diff-viewer/releases/latest/download/dsh-external-dsh-diff-viewer.tgz"
# 重启 dsh web 生效
dsh web
⚠️ 升级注意:pnpm 会按 URL 缓存 tarball——同一
latest链接在出新版本后可能命中旧缓存。升级失败/装到旧版时,先dsh plugin --profile web remove @dsh-external/dsh-diff-viewer,再pnpm store prune(或删除pnpm store path输出目录中的对应缓存)后重新安装。
开发环境(从源码)
# devDependencies 用 link: 指向 ../dsh2026/deepseek-harness(本地 deepseek-harness checkout)
pnpm install && pnpm run check # typecheck + test + build
# 直接安装本地目录,或 npm pack 后装 tarball:
dsh plugin --profile web add E:\dev\dsh-diff-viewer
Windows 注意:
dsh plugin add <本地目录>的link:绝对路径有 junction bug(pnpm 拼错目标)。用 tarball(npm pack后dsh plugin add *.tgz)可绕过。
发版注意:
lib/已提交,源码改动必须同时重建并提交lib/(CI 的check后会校验lib/与源码一致,不一致即失败)。
卸载
dsh plugin --profile web remove @dsh-external/dsh-diff-viewer
开发
pnpm install && pnpm run check # typecheck + test + build
测试需要 workspace 内的 @deepseek-ai/dsh-* 包(devDependencies 用 link: 指向 ../dsh2026/deepseek-harness,vitest alias 统一 react 单实例;接管行复用 ui-tool 的 ToolRow.module.css,经包导出的 src 子路径内联进 bundle)。
友情链接 / Friend Links
- DSHFind — DeepSeek Harness 插件市场与学习社区
Read the usage guide →
Install steps, key points, FAQ and compatibility for this plugin — auto-derived from indexed fields.
Listing badge
[](https://deepseek-plugin.org/plugins/lehhair/dsh-diff-viewer)Paste this markdown into your GitHub README to link back to this listing. The badge only states the listing — not a security endorsement.