- Startseite
- Plugins
- UI-Erweiterungen
- dsh-inline-diff (plugin)
dsh-inline-diff (plugin)
him666233/dsh-inline-diff/plugin
Inline diff cards for every edit, write and str_replace_editor call: old/new line numbers, character-level highlighting, 57-language detection with a red/green-safe syntax palette, a side-by-side viewer, Read-row line ranges, and a settings page for display style and highlighting.
Installation
dsh plugin --profile web add github:him666233/dsh-inline-diffDieses Plugin befindet sich im Unterverzeichnis plugin des Repositorys.
README
DSH Inline Diff · 内联差异
中文(默认)| English
原创声明(重要):本项目是完全原创的作品,与 JanEickholt/dsh-inline-diff 以及任何其他同名插件、仓库或项目没有任何关系。本项目没有参考、复制或移植上述项目;两者的实现方式、模块划分、代码组织与最终渲染效果完全不同。部分功能相似(对话内联差异展示)纯属雷同巧合——本项目是在完成实现之后搜索同类插件时,才发现存在同名/相似项目。本项目不是任何其他项目的衍生作品、复刻作品或分支,请勿混用或混淆。英文声明见 README.en.md。
在 DeepSeek Harness 的对话流里,为每一次文件修改就地渲染可展开的差异卡片,并提供左右对照、行内字符级高亮、移动块/被动行号说明和读取行范围展示;1.1.0 起还会自动识别被修改文件的语言,在内联卡片与放大弹窗中显示语言徽章并按语言做语法高亮(配色刻意避开红绿,避免与新增/删除标记混淆);1.2.0 起命令与工具卡片用 IN/OUT 两段独立色条分别表达输入与输出状态;1.2.5 起行号列带「旧 / 新」图例,放大弹窗的说明横幅与设置弹窗标题栏保持固定;1.2.6 起外壳与弹窗颜色严格跟随当前主题(官方原版主题与第三方皮肤均可正确切换);1.3.0 起提供完整的中英双语界面与文档,并可在设置页独立切换语言(默认中文)。命令、搜索、网页与通用工具调用还可切换为默认展开 IN/OUT 的「展开风格」。
作者:Him666233 · 仓库:Him666233/dsh-inline-diff · npm:@him666233/dsh-inline-diff · License:MIT
中文为主;插件内部名称、设置项和 UI 全部使用中性描述,不包含第三方产品品牌字样。 本仓库的「展开风格」指展开式、平板式、类现代编码代理的透明输出效果。
截图
以下截图在关闭第三方主题、官方原版外观下生成(深色为主,另附浅色外观),示例内容仅用于展示插件行为,不包含第三方主题或桌宠素材;文件卡片为默认的「展开风格」,命令/工具行截图展示开启对应「展开风格」后的效果。截图流程:先关闭正在使用的第三方主题 → 切换界面语言 / 明暗外观 → 分中文、英文各截一套 → 再恢复原主题与外观。中文截图位于
docs/,英文截图位于docs/en/,文件名一一对应。实际外壳颜色会跟随当前主题与明暗外观变化。
内联差异卡片
编辑/写入工具调用在原位置显示修改对比:绿色新增、红色删除、精确旧/新行号,行内变化只高亮真正改动的片段;每个修改点的行号列上方都有「旧 / 新」图例。

语言识别与语法高亮
按文件路径自动识别 57 种语言,在卡片头部文件路径旁与放大弹窗副标题显示语言徽章,并按识别结果做避开红绿的语法高亮;设置页内可展开查看支持的语言列表。

移动块与被动行号
完全相同的连续代码块纯粹移动时,删除侧标「移至 新 Lx–Ly」、新增侧标「移自 旧 Lx–Ly」;两个修改点之间的未改区段显示旧→新行号范围与「行号顺延 ±N」。

左右对照放大
点击「放大」打开全屏对照。变更块模式按修改点分组、每个修改点横条滚动时吸顶;顶部「全文对照」按修改前/后整份文件逐行对齐。


命令与工具行(展开风格)
命令执行与其它工具调用默认展开 IN/OUT,输入段与输出段各自独立滚动并各自显示状态;失败会区分输入侧与输出侧。搜索/网页工具行使用同一套行样式。



读取行范围
Read 工具行保留 DSH 原生卡片与展开行为;折叠时在文件名右侧显示本次读取的实际行范围,单行、连续范围与多个不连续范围均支持。

设置面板
界面语言切换、原创声明、四项展示风格、三类卡片各自的外壳/内部配色、语法高亮四项设置都在同一个面板;弹窗标题栏固定,内容区域独立滚动。


浅色外观
插件读取宿主实际解析出的明暗外观:浅色外观下外壳转为主题浅色、内部切换为官方浅色代码区,字色同步转深。

功能
- 逐次内联差异:
edit/write/str_replace_editor每次调用单独一张卡片,不等待整轮结束。 - 精确行号与「旧 / 新」图例:旧文件行号、新文件行号双栏显示;每个修改点的横条下方有一行与行号列对齐的「旧 / 新」图例(有精确行号时显示),删除行的旧行号、增加行的新行号分别用红/绿系轻微染色并加粗。只有一侧行号的修改点(新建文件或纯删除)只显示实际存在的那一侧图例,例如新建文件只显示「新」。多修改点各有独立表头,写明
旧 Lx–Ly → 新 Lm–Ln与+/−统计。 - 行内字符级高亮:替换行只把真正变化的 token 标深红/深绿,避免整行染色;同一处替换中两侧共享的空白与标点会并入改动区,连成一条连续高亮带,不会切成零散词块(真正共享的单词仍留白)。孤立的空白/标点差异不会被误标成改动。
- 移动识别:完全相同的连续代码块纯粹移动时,删除侧标「移至 新 Lx–Ly」、新增侧标「移自 旧 Lx–Ly」,多行移动给出完整目标范围;边界空行不影响识别。单行移动按显示宽度判定(CJK/全角按 2 格计,≥12 格才标注),多行移动最多识别 120 行。
- 被动行号位移:未改区段显示「N 行未修改」、旧→新行号范围与「行号顺延 ±N」,用于说明插入/删除/移动造成的被动换行。
- 左右对照:变更块模式按修改点分组;全文对照模式对整份修改前/后文件逐行对齐,超过 4000 行时截断并提示。
- 固定表头与说明横幅:内联卡片和放大弹窗里的文件/修改点横条滚动时吸顶;放大弹窗的说明横幅(历史回放、行号待定、全文对照不可用等)与「修改前/修改后」栏固定在标题下方,滚动条只属于对比内容区域,不会盖住它们。
- 文件语言自动识别:按文件路径识别 57 种语言与标记格式;识别顺序为「复合扩展名 → 特殊文件名 → 普通扩展名 → 无扩展名脚本的 shebang 首行」。
.d.ts/.min.js等复合扩展名,Dockerfile(含Dockerfile.dev)/Makefile/CMakeLists.txt/nginx.conf/Jenkinsfile/Cargo.toml/.env/.editorconfig/Gemfile/.bashrc等特殊文件名,以及#!/usr/bin/env node等脚本首行都会参与识别;.txt/.log/LICENSE/.gitignore/go.mod等显式文本文件标记为纯文本并跳过高亮。 - 语言徽章:卡片头部文件路径旁与放大弹窗副标题处显示中性小徽章,可设为短代码 / 全名 / 隐藏(「隐藏」隐藏全部徽章,含纯文本与未知语言);徽章可见时,识别不到语言按「未知语言」设置显示虚线徽章或完全不显示,纯文本文件显示「纯文本」标记。
- 语法高亮:内联卡片与左右对照弹窗(变更块与全文对照)中的所有代码行按语言着色;配色被约束在蓝→紫区间(色相 180°–285°),红、绿、橙、黄、品红及其相近色一律不参与高亮——红绿只用于新增/删除语义,两类颜色不会混淆。每个前景色在官方深色/浅色代码底色上的对比度 ≥ 4.5:1,在增删行与行内改动底色上仍可读。关闭高亮、未知语言与纯文本时回退默认前景色,浅色/深色外观下都保证可读。
- 字体强调:开启时关键词、类型、函数名与标签加粗,注释斜体,链接下划线;关闭后只保留颜色区分。
- 紧凑行号栏:行号栏收窄、内容与边框留白,代码正文起点更靠左;新增/删除行的整行底色与左侧色条仍通栏延伸到卡片/弹窗边缘。
- 读取范围外显:Read 行折叠时显示
L x – L y(单行L x、未知结尾L x 起,多范围用·分隔,最多 4 段后以…省略);展开时自动隐藏,不覆盖 DSH 原生展示。 - 四项展示选项:文件修改卡片、命令执行行、其它工具调用可选「展开风格 / DSH 原生」;过程折叠可选「不折叠 / DSH 原生」。
- 命令执行行:
bash/pwsh/win_bash使用终端图标、等宽标题与类终端布局,头部显示状态与非零退出码;IN/OUT 各自独立滚动(IN 限高更矮),滚动条贴卡片右边缘。 - 搜索与网页工具行:
grep/glob/web_search/web_fetch也纳入「其它工具调用」的展开风格,显示类别图标、关键词/路径/URL 摘要、匹配数/文件数/来源数/HTTP 状态徽标,以及默认展开的 IN/OUT。 - 工具行差异化:命令行使用终端图标、等宽标题和绿色强调;搜索类工具使用放大镜图标,网页类工具使用地球图标;通用工具调用带「工具调用」标签。所有展开风格工具行与内联差异卡片共用同一款「轨迹」胶囊按钮。
- IN/OUT 分段状态:命令执行卡片与其它工具调用卡片的左侧色条按「输入 / 输出」两段独立显示状态——IN 段:准备参数 / 参数已提交等待输出=主题色(脉动)、输入侧完成=绿色、输入侧失败=红色;OUT 段:执行中=主题色(脉动,含「执行中…」占位)、输出成功=绿色、执行失败 / 非零退出码 / 被信号中止=红色、用户中止=警告色。错误会按
INVALID_ARGS/UNKNOWN_TOOL/ABORTED_BEFORE_DISPATCH(输入侧)与其余执行期错误(输出侧)分别归因,缺少错误码时若原始参数不是合法 JSON 对象也归为输入侧;输入输出互不干扰,输入侧失败时 OUT 段标为「跳过」并保持中性色。 - 分段文字配色:输入侧失败时 IN 区代码为红字,输出侧失败时 OUT 区代码为红字;正常内容使用跟随内部配色与浅色/深色外观的默认前景色,浅色内部配色下不会出现浅底浅字。运行/准备中的分段色条按状态做明暗呼吸(脉动);标签与分隔线也使用内部配色 token。
- 壳 / 内双色层(三类卡片统一支持):文件修改卡片、命令执行卡片、其它工具调用卡片都使用同一套「外壳 + 内部」结构。外壳、标题条、文件条与设置弹窗使用当前主题自身的外壳色(第三方主题会呈现它自己的色调);派生颜色在
body层解析,因此官方主题(token 定义在body)与皮肤主题(token 定义在:root)都能正确跟随,切换官方/原版外观不会残留上一个主题的色调。内部差异行、命令执行与工具 IO 内容使用 DSH 官方外观的代码块底色(深色近黑偏灰、浅色近白),并配对应的明暗前景色。命令执行卡片不再出现整卡绿色蒙层;状态由头部状态点/标签、非零退出码与 IN/OUT 分段色条共同表达;失败文本只出现在对应的 IN / OUT 段内,卡片在 IO 面板处结束,不会在面板下方再追加重复错误行或额外外壳。 - 每类卡片独立配色:设置里文件修改卡片、命令执行行、其它工具调用各自拥有「外壳配色 / 内部配色」选项——外壳可选自动(主题+外观)/ 浅色 / 深色,内部可选自动(官方外观)/ 浅色 / 深色 / 与外壳一致(即统一底色,不再拼色),三类互不影响。
- 外观自适应(浅色 / 深色 / 跟随系统):插件读取宿主实际解析出的明暗外观(
color-scheme):深色外观下外壳呈主题的深色色调、内部为官方深灰代码区;浅色外观下外壳变为主题的浅色/近白、内部变为官方浅色代码区,字色同步转为深色,避免浅底浅字或灰蒙蒙。 - 不透明表面:第三方主题的卡片/弹层 token 常常是半透明的;插件在主题色之下垫了一层不透明底色,保证卡片、差异弹窗和设置窗口都可读,不会透出壁纸。设置弹窗的弹层表面取自主题分层 token(
bg-layer-2)而不是遮罩用的bg-overlay——官方深色主题下前者是#2c2c2e深灰、后者是中间灰,用后者会把整块面板冲成发白的灰色。 - 外观细节对齐官方:卡片使用宿主圆角 token,IN/OUT 竖条为 2.5px 左描边并沿卡片底部圆角收尾,两段之间只保留一根细分隔线;放大弹窗与设置弹窗自身裁剪圆角,滚动条按区域分别贴边或内缩。
- 大文件 / 历史回放降级:超出预算时退回工具元数据差异块并明确提示;历史回放无法全文对照或无法定位行号时,放大弹窗内说明原因并置灰「全文对照」。
- 主题安全与配色安全:外壳、文字与边框默认取自宿主主题 token(
--dsw-alias-*);语法高亮的前景色使用插件自带的受限调色板——蓝→紫、避开红绿、按深色/浅色分别校准对比度,其余颜色不写死;跟随 DSH 原生主题、第三方主题和明暗模式。配色安全由单元测试断言,任何引入红/绿高亮色的改动都会让测试失败。
兼容性
| 环境 | 支持情况 |
|---|---|
| DSH 桌面端(Desktop profile) | ✅ 已验证 |
| DSH Web UI(Web profile) | ✅ 代码兼容;需在该 profile 单独安装本插件 |
| 浏览器 / Electron 内嵌 WebView | ✅ 客户端使用标准 Web platform |
| 第三方主题 / 桌宠 / 皮肤 | ✅ 颜色跟随主题 token;已适配会拦截点击重放折叠的主题(如 claude-style):卡片头部带 aria-haspopup 豁免、只响应真实用户手势,主题与桌宠属于外部插件,不影响本插件安装 |
| 启动动画类插件(自定义开场动画等) | ✅ 互不接管 slot;动画关键帧与样式使用插件命名空间(dsh-inline-diff-*);Read 范围观察器只响应 Read 行相关变更 |
DSH 版本范围(engines.dsh):>=0.2.2-rc.1 <0.3.0。当前版本在 DeepSeek Harness 0.2.2-rc.1(desktop profile)实测通过。
插件在 plugin/package.json 声明了 engines.dsh;DSH 插件加载器会校验该范围,不在范围内时拒绝自动加载,避免把未验证的宿主版本当成可用环境。插件清单同时声明 dsh.client.platform: web,Host 端只使用通用的 webServer、tools/result 与 Node.js 文件读取能力,不依赖 Electron 或桌面专属 API。
注意:DSH 插件按 profile 独立安装。桌面端与 Web UI 端若使用不同 profile,需要分别在对应 profile 中安装一次;本插件不会自动跨 profile 同步。DSH 升级到
0.3.0或更高版本前,请等待本插件发布新的兼容版本。
安装
方式一:从 npm 安装(推荐)
npm 包自 1.3.0 起提供,包名
@him666233/dsh-inline-diff。
dsh plugin add @him666233/dsh-inline-diff
也可以在 DSH Web UI 的「插件 → 添加插件」里直接输入包名安装(等价入口)。命令会把包装进当前 profile 的 node_modules,并自动把该包登记到 profile 的 dsh.profile.bundles;DSH 校验 engines.dsh 与 bundle patch 通过后加载本插件。
- 桌面端与 Web UI 若使用不同 profile,请分别在各自 profile 中安装一次(
dsh plugin --profile <name> add @him666233/dsh-inline-diff); - 安装后刷新页面或重启 DSH 生效;首次安装需要能访问 npm 源(默认 npm 官方源,DSH 在源不可用时回退 npmmirror)。
方式二:本地目录 / 离线安装
- 下载本仓库或 Release 中的插件包并解压;
- 打开 DSH 插件管理页 →「添加插件」,输入解压后
plugin/目录的绝对路径(也接受本地压缩包); - 刷新或重启 DSH。
插件包目录 plugin/ 自带 package.json、client.js、index.js、cordis.patch.yml、locale 和 icon,可直接被 DSH 作为本地 bundle 加载。
方式三:手动 link 安装(开发调试)
把 <repo>/plugin 链接到目标 profile:
cd ~/.dsh/profiles/<profile>
pnpm add link:/absolute/path/to/dsh-inline-diff/plugin
然后在同一 profile 的 package.json 中加入:
{
"dependencies": {
"@him666233/dsh-inline-diff": "link:/absolute/path/to/dsh-inline-diff/plugin"
},
"dsh": {
"profile": {
"bundles": ["@him666233/dsh-inline-diff"]
}
}
}
重启 DSH 后生效。桌面端和 Web UI 若使用不同 profile,请分别在各自 profile 中执行。
方式四:从 GitHub Release 安装(离线包)
- 打开 Releases 下载当前版本的
dsh-inline-diff-<版本>-plugin.zip(插件包)或dsh-inline-diff-<版本>.zip(完整源码包); - 解压后按「方式二」把
plugin/目录的绝对路径交给「添加插件」; - 校验下载文件:
SHA256SUMS.txt中的哈希应与 Release 页面一致(Windows 可用certutil -hashfile <文件> SHA256核对)。
Release 附件(zip、
SHA256SUMS.txt、发行说明)是发布资产,不进入源码仓库;仓库里的release/目录只是维护者本地的打包产物目录(已在.gitignore中忽略)。
升级与卸载
- 升级(npm 安装的版本):
dsh plugin add @him666233/dsh-inline-diff@<版本>;或在插件页卸载后重新安装最新版。第三方组合包不提供原地升级按钮。 - 卸载:
dsh plugin remove @him666233/dsh-inline-diff,或在插件页点击「卸载」(需确认)。 - 本地 link / Release 安装的版本:替换
plugin/目录后刷新或重启;卸载时在 profile 的package.json中移除依赖与dsh.profile.bundles中的条目。 - 同一个 profile 中不要同时保留 link 版与 npm 版,否则会重复注册同一批 slot(表现为卡片重复或报重复 key)。
界面语言与文档语言
- 界面语言:1.3.0 起可在插件设置页选择「中文(默认)/ English / 跟随 DSH」,切换立即生效、无需刷新;默认中文,不会改动 DSH 全局语言设置。
- 文档语言:中文为主文档(本文件),英文文档见 README.en.md;npm 包内同时提供
README.en.md与README.md。
从源码构建
npm install
npm run build # -> plugin/client.js + plugin/cordis.patch.yml(包名从 plugin/package.json 读取)
npm run check # 语法 / JSON 校验,并校验已提交的 client.js、cordis.patch.yml 与源码/包名一致
npm test # 差异引擎、卡片模型、语言识别、高亮配色、工具状态、read range、i18n 与安全回归单元测试(共 124 项)
需要 Node.js 20+,构建期依赖 esbuild 与 highlight.js(语法模块会随 client.js 一起打包)。插件运行时无额外依赖,只使用 React 与宿主提供的 Web 服务。
使用
内联卡片
在对话中定位到 编辑 / 写入 / 替换编辑 卡片:
- 点击卡片头部:展开或折叠逐行差异;
- 点击「放大」按钮或底部「左右对照」链接:打开左右对照弹窗;
- 点击右上角「轨迹」胶囊按钮(内联卡片、命令执行行与其它工具行共用):跳转到对应轨迹位置;
- 点击标题中的文件路径:在宿主文件面板中打开该文件(宿主提供该能力时);
- 行号列上方的「旧 / 新」图例标明两列行号的归属:删除行的旧行号用红系染色、增加行的新行号用绿系染色,行号错位时也能分辨哪一列属于修改前、哪一列属于修改后;
- 卡片展示的是该次编辑的执行快照,不会随文件后续改动自动刷新;放大弹窗的「全文对照」同样是这份快照。数据来源、刷新规则与弹窗层级详见 显示行为说明。
内联卡片内容区最高 360px,超过后卡片内部滚动;折叠状态下差异区最多展示 42 行(按修改点顺序分配行预算),其余行通过「放大」查看。
命令与工具行(展开风格)
把「命令执行行」和/或「其它工具调用」设为「展开风格」后:
- 命令执行行以终端样式展示 IN/OUT 两段:IN 是命令文本(参数异常时回退为原始参数),OUT 是输出文本,两段各自独立滚动、独立状态色条;头部状态点、非零退出码与状态标签共同表达结果;
- 其它工具调用(普通、详情、搜索与网页类)默认展开 IN/OUT,并保留折叠按钮;标题使用中文工具名(如
grep= 搜索文件内容、glob= 搜索文件、web_search= 网页搜索、web_fetch= 抓取网页); - 搜索/网页行摘要显示搜索关键词与路径、文件名模式与路径、搜索词或抓取 URL;已结束调用显示匹配数、命中文件数、来源数或 HTTP 状态徽标;
- 输入侧失败(参数/派发问题)时 IN 色条变红,OUT 段标为「跳过」并展示错误摘要;输出侧失败(执行报错、非零退出码、信号中止)时 OUT 色条变红;用户中止显示警告色;
- 切换回「DSH 原生」会释放本插件的注册,恢复官方搜索/网页富结果卡片与官方命令行。
设置项
界面语言(1.3.0 新增,独立于 DSH 全局语言):
| 设置项 | 选项 | 说明 |
|---|---|---|
| 界面语言 / Language | 中文(默认) / English / 跟随 DSH | 插件自身界面的语言。默认中文;选择「跟随 DSH」时跟随 DSH 全局语言设置。切换立即生效、无需刷新,不会改动 DSH 全局语言,也不影响其它插件。文档语言:中文为默认(本文件),英文见 README.en.md。 |
设置页顶部同时展示一条醒目的原创声明:本项目为完全原创作品,与任何同名/相似插件(包括 JanEickholt/dsh-inline-diff)没有任何关系,详见文首声明。
四项展示风格(默认:文件修改卡片=展开风格,命令执行行、其它工具调用、过程折叠=DSH 原生):
| 设置项 | 选项 | 说明 |
|---|---|---|
| 文件修改卡片 | 展开风格 / DSH 原生 | 展开风格 = 本插件的逐次内联差异卡片;DSH 原生 = 官方文件修改行;下方可单独设置外壳/内部配色 |
| 命令执行行 | 展开风格 / DSH 原生 | 展开风格 = 默认展开 IN/OUT 的扁平命令卡片;DSH 原生 = 官方 bash / pwsh / win_bash 行;下方可单独设置外壳/内部配色 |
| 其它工具调用 | 展开风格 / DSH 原生 | 展开风格 = 普通/详情/搜索/网页类工具默认展开 IN/OUT(含 grep / glob / web_search / web_fetch);读取、待办、提问、图片等富结果卡片保持原生;下方可单独设置外壳/内部配色。开启本项会即时生效,并在「过程折叠」为 DSH 原生时自动把它切到「不折叠」,否则已完成的工具行会被 DSH 折叠组遮住 |
| 过程折叠(整份对话) | 不折叠 / DSH 原生 | 不折叠 = 写入 DSH ui-chat.transcriptView = verbose 偏好;DSH 原生 = 保留用户已有偏好;切回时会尽量恢复启用前的值 |
语法高亮与语言徽章(1.1.0 新增,独立于上面的展示风格):
| 设置项 | 选项 | 说明 |
|---|---|---|
| 语法高亮 | 开启 / 关闭 | 按识别到的语言为卡片与放大弹窗的代码行着色;关闭后使用当前浅色/深色外观的默认前景色 |
| 语言标识 | 短代码 / 全名 / 隐藏 | 全部语言徽章的样式;短代码如 TS、MD,全名如 TypeScript。选择「隐藏」时隐藏全部徽章(含纯文本与未知语言);「未知语言」设置只在徽章可见时生效 |
| 未知语言 | 显示“未知语言” / 不显示 | 识别不到语言时的处理(虚线徽章或隐藏);此时不做语法高亮 |
| 字体强调 | 颜色 + 字体样式 / 仅颜色 | 开启时关键词/类型/函数名/标签加粗、注释斜体、链接下划线;关闭后只保留颜色区分 |
设置页内还可展开「支持的语言」查看当前兼容的 57 种语言(按名称排序,纯文本不在列表中)。
设置入口:
- 侧边栏底部:差异样式(打开同一套设置弹窗);
- DSH 设置页:内联差异(设置面板标题为「内联差异 · 显示样式」)。
设置保存在浏览器 localStorage(键 dsh-inline-diff.settings.v4);旧 v3 / v2 值会在首次加载时迁移为新值并删除旧键(旧 v1 键在保存时一并清理)。过程折叠选项通过 DSH 官方 configForms 服务写入,可随时恢复。「恢复默认」会把所有选项与 DSH 对话记录偏好恢复为默认值;若「其它工具调用」因此发生变化,页面会自动刷新一次以应用变化。
读取行范围
Read 工具行折叠时,范围标签位于文件名右侧;多段不连续读取用 · 分隔,超过 4 段后以 … 省略。展开该行后标签自动隐藏,完全显示 DSH 原生 Read 卡片内容。调用尚未结束时按 offset / limit 参数预估范围;结束后以工具结果中的实际行号为准。
项目结构
dsh-inline-diff/
├─ src/client/ # 浏览器端源码(一个文件只做一类事)
│ ├─ index.jsx # 插件入口 / slot 注册 / 设置驱动的重注册
│ ├─ project.js # 作者、仓库、版本等身份信息(单一来源)
│ ├─ i18n.js # 双语核心:语言解析、字典翻译、回退链、组件包装
│ ├─ locales.js # 中英文字典(zh / en)
│ ├─ components.jsx # 内联差异卡片与左右对照弹窗
│ ├─ diff.js # 行对齐 / hunk / 移动 / 行内 token diff / 行号定位
│ ├─ model.js # 工具调用 → 卡片模型(含预览与降级模型)
│ ├─ tool-status.js # IN/OUT 分段状态与失败归因(纯函数)
│ ├─ languages.js # 语言注册表 / 路径与 shebang 识别
│ ├─ highlight.js # highlight.js token 提取、逐行缓存与预算
│ ├─ syntax-styles.js # 语法高亮配色、字体强调与语言徽章样式
│ ├─ enhanced-tools.jsx # 展开风格工具调用行(搜索/网页/普通/详情)
│ ├─ enhanced-shell.jsx # 展开风格命令执行行(bash/pwsh/win_bash)
│ ├─ read-range.js # Read 行范围提取(纯函数)
│ ├─ read-range-dom.js # 页面级 Read 范围挂载(MutationObserver)
│ ├─ settings.js # 设置存储、迁移、默认值与 DSH 偏好联动
│ ├─ settings-ui.jsx # 设置页/弹窗(含语言切换与原创声明)
│ ├─ styles.js # 主题 token 与卡片/弹窗样式
│ └─ api.js / store.js # Host 通信 / 弹窗状态
├─ plugin/ # 可安装插件包(Host + 构建产物 client.js + locale + icon)
│ ├─ index.js # Host 半区:快照 LRU 与只读文件 API
│ ├─ client.js # 构建产物(勿手改;由 build.mjs 生成)
│ ├─ cordis.patch.yml # 构建产物(bundle 插件行,包名自动写入)
│ ├─ package.json # npm 包清单(dsh.bundle.patch / engines.dsh / dsh.client)
│ └─ README.md / README.en.md # npm 页面文档(中/英)
├─ tests/ # 纯 Node 单元测试(差异、模型、语言、高亮、配色、状态、read range、i18n、安全)
├─ docs/ # 中文截图与说明文档
│ ├─ display-behavior.md # 显示行为说明(中文)
│ ├─ display-behavior.en.md # 显示行为说明(英文)
│ ├─ publish.md # 发布到 npm / GitHub 的维护者指南
│ └─ en/ # 英文界面截图(与中文截图同名)
├─ release/ # 本地发行版打包产物(已在 .gitignore 忽略,作为 GitHub Release 资产上传)
├─ scripts/ # 维护脚本(不属于插件运行时)
│ ├─ set-package-name.mjs # 一键改 npm 包名(同步 manifest / patch / client.js / README)
│ └─ build-release.mjs # 一键打包 GitHub Release 附件(两个 zip / SHA256SUMS / 发布完整性校验)
├─ .github/workflows/ci.yml # CI:npm run check + npm test
├─ build.mjs # esbuild 打包 / 构建校验(包名单一来源)
├─ package.json # 工作区清单(private,仅开发用)
├─ README.md / README.en.md # 主文档(中文 / 英文)
├─ CHANGELOG.md / LICENSE
约定:
src/client/一个文件只负责一类职责;plugin/只放可安装产物;docs/只放文档与截图;release/只放打包产物;测试全部在tests/。新增文件前先确认它属于哪一层,不要混放。
内联卡片、放大弹窗与设置弹窗的显示细节见 docs/display-behavior.md。
内部实现
Host 端
- 监听
tools/result,对成功的edit/write截取{ path, before, after, operation },按「会话 + 调用 ID」保存为内存快照(LRU:最多 240 条、每侧文本上限 4MB,并额外限制总量 64MB;任一预算超限时从最旧条目淘汰;超大写入不保存快照,卡片退化为差异块模式); - 提供只读 API,所有路径(含
/ping、404、405)先经过浏览器信任边界校验:- 准入优先复用 DSH
connection服务的admit(req)(官方 Host / Origin / 跨站围栏 + HttpOnly、SameSite=Strict 的浏览器会话 Cookie); - 无
connection服务的嵌入式 profile 回退本地围栏:Host必须是 loopback 或监听器绑定地址、Origin必须同 authority、拒绝sec-fetch-site: cross-site;任何异常都不 fail-open; POST /dsh-inline-diff/api/snapshot:按sessionId + callId返回快照;POST /dsh-inline-diff/api/read:在请求方给定的根目录内读取文件(realpath 两层 containment;单文件上限 2MB;15 秒读超时;最多 8 个并发读取,超限返回 429/504;二进制返回binary,并剥离 UTF-8 BOM);GET /dsh-inline-diff/api/ping:健康检查(返回当前快照条数),同样受准入保护(浏览器 profile 需要会话 Cookie);
- 准入优先复用 DSH
POST请求体上限 1MB、仅接受application/json、10 秒读取超时(超限返回 413 / 415 / 408);响应统一带nosniff/no-store/referrer-policy/Cross-Origin-Resource-Policy头;错误使用语义化状态码与固定文案,不回显文件系统错误、绝对路径或堆栈;- 快照只存在内存、不落盘;应用重启后历史卡片退化为“修改块 + 当前文件定位行号”的展示,因此「全文对照」不可用。
Client 端
- 通过
ctx.slots以 keyedtool.call.toolview接管edit/write/str_replace_editor的文件卡片、bash/pwsh/win_bash的命令行、以及普通/详情/搜索/网页类工具行;不 shadowconversation.chat.node的 tool-call 条目——dsh ≥0.2.2-rc.1 的官方 Tool 层(@deepseek-ai/dsh-client-ui-tool)拥有该条目并声明tool.call.toolview子槽,重复声明会抛slot "tool.call.toolview" is already declared,因此插件只做 keyed 注册,由官方 tool-call 树按工具名分发;未注册的工具沿用官方通用行; - 展示风格变化时释放并重建这组注册:切回 DSH 原生后官方富结果卡片原样恢复;
- 轨迹跳转统一为带文字的「轨迹」胶囊按钮,内联差异卡片与所有展开风格工具行位置一致;
- 纯浏览器侧实现 LCS 对齐(单侧 4000 行 / 250 万格预算,超限退化为前后缀+替换块的粗对齐)、上下文 ±3 行的 hunk 分组、行内 token diff(单行 4000 字符、16 万格、整段 200 万格预算)、移动块配对(2 行以上或单行显示宽度 ≥12 格,最多 120 行,容忍边界空行)、被动位移 gap、超大文件预算回退;
- 语言识别与高亮:
languages.js在模块加载期构建扩展名/文件名 Map(O(1) 查询);highlight.js用 highlight.js 语法把可用全文的每一侧各分词一次,再把高亮 HTML 解析回逐行 token 区间并按行号索引(历史回放没有完整全文时按修改块本地分词),结果以 WeakMap 缓存在 diff 上;单侧超过 200k 字符或 4000 行、单行超过 2000 字符时自动放弃高亮并回退默认前景色; - IN/OUT 分段状态由
tool-status.js的纯函数推导(输入侧错误码、参数合法性回退、非零退出码与中止标记),渲染层按状态给分段色条与文字着色;状态变化以描边颜色明暗呼吸表达脉动; - 配色安全由
syntax-styles.js的单一调色板生成 CSS,并由tests/syntax-palette.test.mjs断言色相窗口(180°–285°)、WCAG 对比度与红绿增删底色上的可读性,任何引入红/绿高亮的改动都会让测试失败; - 明暗外观通过监听根元素的
color-scheme同步到data-dsh-inline-diff-appearance,再结合每张卡片的data-shell-tone/data-inner-tone选择外壳与内部配色; - Read 范围使用页面级
MutationObserver挂载到官方 Read 行文件名后,只响应 Read 行相关 DOM 变更、首帧后再扫描,不依赖某一条内部渲染路径; - 全屏弹窗与设置弹窗通过 React Portal 挂到
document.body,避免被第三方浮动层遮挡;点击遮罩或按 Esc 关闭。
多级回退与容错
每类功能都按「主路径 → 回退 → 显示降级 → 明确说明」设计,极端情况下宁可降级展示也不崩溃:
| 场景 | 主路径 | 回退 1 | 回退 2(最终) |
|---|---|---|---|
| 修改前全文 | Host 内存执行快照 | /read 读取当前文件补齐行号 | 工具结果 meta.diffs 差异块 + 「行号待定 / 不保存执行快照」说明 |
| 全文对照 | 快照全文精确对齐 | 超大文件粗对齐(截断到 4000 行) | 页签置灰 + 弹窗内原因说明 |
| 超大输入 | 完整 diff(20 万行物化预算内) | 差异块 / 仅统计 + 「文件过大」降级提示 | 不渲染逐行内容,页面不冻结 |
| 语法高亮 | 逐语言 highlight.js 分词 | 超预算 / 未知语言 / 纯文本 → 默认前景色 | 语言徽章与语言识别仍生效 |
| 高亮 HTML 解析 | 逐行 token 区间 | 纯文本逐行重建(硬校验) | 放弃高亮,按纯文本展示 |
| 界面语言 | 设置的语言字典 | 中文 zh 字典 | 直接显示 key 本身(不抛错) |
| 设置读取 | localStorage 存档 | 内存默认值 | 存档损坏 / 超长 → 丢弃并回退默认值 |
| 语言识别 | 扩展名 / 特殊文件名 / shebang | 纯文本标记 | 不做高亮 |
| Host API 准入 | DSH connection.admit | 本地 loopback / 绑定地址围栏 | 403 拒绝,客户端 api 返回 null,卡片降级显示 |
| 工具视图注册 | keyed tool.call.toolview 接管 | 注册失败时释放并恢复官方行 | 官方通用行(不抛错中断整组注册) |
上表对应实现分散在各模块注释中;新增功能时请沿用同样的回退层级,并在最终回退处给出可读的原因说明,而不是静默失败或抛错。
数据与隐私
- 无网络请求、无遥测、无外部服务;不读取 DSH 会话外文件;
- Host 只读 API 有浏览器信任边界与输入/超时/并发上限(见上文 Host 端);客户端无
innerHTML/dangerouslySetInnerHTML/eval,高亮 HTML 只被解析为纯文本 token; - 快照有条数与总字节双预算,diff 物化有行数/单行上限,超限时降级展示而不是卡死;
- 只有显示所需的修改前后文本在 Host 内存中短暂保留;默认不写磁盘;
- 设置(含界面语言)只写入浏览器 localStorage;不包含文件内容;
- 颜色全部由宿主主题 token 派生,插件不附带壁纸或人物素材。
已知限制
- 全文对照依赖快照:应用重启后的历史回放无法还原修改前全文,页签置灰并在放大弹窗显示原因。
str_replace_editor走无快照降级路径:Host 只为edit/write保存执行快照;str_replace_editor卡片展示工具结果中的修改块并尽量按当前文件定位行号,「全文对照」不可用。该工具不产生执行快照,卡片与放大弹窗用「不保存执行快照」的专用说明,而不是历史回放措辞(历史回放措辞只用于edit/write快照丢失的情况)。- 全文对照是执行快照:同一张卡片始终展示当次编辑的修改前/后全文,不会自动刷新成文件最新版本;要查看最新内容,请打开最新一次编辑的卡片。数据来源与刷新规则见 显示行为说明。
- 大文件全文对照滚动:行数较多时快速滚动可能出现短暂的渲染闪烁;内容来自静态快照,不受影响(详见 显示行为说明)。
- 历史回放行号:快照丢失后会按当前文件重新定位修改块;若该文件随后又被改动导致无法唯一定位,行号会标记为「行号待定」,放大弹窗会说明只能展示修改块。删除型修改块没有足够的上下文锚点时也可能无法定位。
- 超大文件:任一侧 > 4000 行或对齐预算(250 万格)超限时降级为差异块模式,关闭移动识别;有工具元数据差异块时「全文对照」不可用,仅有粗对齐结果时全文对照会截断到 4000 行。
- 超大输入的物化预算(1.3.0 新增):浏览器侧在拆分逐行对象之前先测量文本预算;任一侧超过 20 万行或单行超过 100 万字符时不再物化逐行内容,只保留准确行数与增删统计并显示「文件过大」降级提示(避免 4MB 级输入生成数百万行对象导致页面冻结/OOM)。
- 移动识别:只识别完全相同的连续行块;移动同时伴随内容修改的块按普通增删显示;单行移动需显示宽度 ≥12 格,多行移动超过 120 行不标注。粗对齐模式(超大文件)下关闭移动识别。
- 接管的工具:文件修改卡片仅支持 DSH 原生
edit/write/str_replace_editor;apply_patch与手工写入保持 DSH 原生展示,不会生成内联差异卡片。 - 配色设置的作用范围:文件/命令/工具三类卡片的「外壳 / 内部配色」只作用于对应的工具卡片;放大弹窗与设置弹窗跟随宿主当前外观(浅色 / 深色)与主题外壳色,不套用单张卡片的配色选项。
- 语法高亮为词法级:高亮只依赖语言语法(highlight.js grammar),不依赖语言服务;TOML 使用 INI 语法、JSONC 使用 JSON 语法、Vue / Svelte / Astro 使用 HTML/XML 语法做近似高亮;历史回放没有完整全文时,跨行结构(块注释、模板字符串等)按修改块局部推断,可能比全文模式略保守;行内 token 高亮超出单行/整段预算时该行回退为纯色。
- 高亮预算:任一侧超过 200k 字符或 4000 行、或单行超过 2000 字符时不高亮,回退默认前景色;语言徽章与语言识别仍然生效。
- 语言标识:「语言标识 = 隐藏」隐藏全部语言徽章(含纯文本标记与未知语言徽章),「未知语言」选项只在徽章可见时生效;语言识别与语法高亮仍照常工作。
- 富结果卡片:读取、待办、提问、图片等富结果卡片不纳入展开风格,保持 DSH 原生交互。
- 搜索/网页行交互:展开风格下搜索/网页调用以 IN/OUT 原文展示;官方卡片里的「点击匹配文件打开」「点击 URL 打开新标签页」等交互只保留在「DSH 原生」模式。
- 展开风格的工具覆盖范围:命令执行、通用、详情、搜索与网页工具行通过
tool.call.toolview的 keyed 注册接管,只对插件登记过的工具名生效;未登记的工具在 dsh ≥0.2.2-rc.1 下沿用官方通用行(插件不再覆盖整棵 tool-call 树,避免与官方 Tool 层重复声明子槽)。 - 跨 profile:插件按 profile 安装,不自动同步。
- 界面语言只作用于本插件:1.3.0 的语言设置只影响本插件自己的界面文案,不修改 DSH 全局语言,也不影响其它插件;选择「跟随 DSH」时随 DSH 全局语言切换(无法识别 host 语言或缺少对应字典时按中文兜底)。
- 文档与截图为中英两套:中文为默认主文档(
README.md、docs/*.md),英文为对照文档(README.en.md、docs/*.en.md);截图分别放在docs/与docs/en/,文件名一一对应。
开发与贡献
npm install
npm run build
npm run check
npm test
- 修改
src/client/后需要重新执行npm run build,安装的是plugin/中构建后的client.js;npm run check会校验已提交的client.js、cordis.patch.yml与源码、包名一致; - 提交前请确保
npm run check与npm test通过;测试覆盖差异对齐、卡片模型、语言识别、highlight.js token 提取、语法高亮配色安全约束、IN/OUT 失败归因、read range、行号图例单侧适配(gutterSides)、i18n 语言解析/回退与安全回归; - 新增界面文案必须同时写入
src/client/locales.js的zh与en字典(两边键集合保持一致),默认语言为中文;新增/修改代码写详细中文注释,并说明失败时的回退路径; - 项目身份集中维护在
src/client/project.js;仓库改名时同步更新该文件、package.json的homepage/repository/bugs及 README 链接即可; - 文档:中文为主(
README.md、docs/*.md),英文为对照(README.en.md、docs/*.en.md);截图中文放docs/、英文放docs/en/,文件名一一对应; - 发布流程:
- npm:见 docs/publish.md,
node build.mjs→node build.mjs --check→npm test→cd plugin && npm publish;换 npm 包名用node scripts/set-package-name.mjs <新包名>(同步 manifest、cordis.patch.yml、client.js模块 id 与 README); - 发行版:
node scripts/build-release.mjs生成release/下两个 zip 与SHA256SUMS.txt(含版本/包名/构建产物一致性校验,旧版本自动归档到release/archive/); - GitHub:源码只提交仓库内文件;
release/下的两个 zip、SHA256SUMS.txt与发行说明作为 GitHub Release 附件上传,不进入源码历史。
- npm:见 docs/publish.md,
更新日志
当前版本:1.3.0(2026-11-08)。版本日期索引:
| 版本 | 发布日期 | 摘要 |
|---|---|---|
| 1.3.0 | 2026-11-08 | 中英双语界面与设置页语言切换(默认中文)、英文文档与双语截图、设置页/文档原创声明、安全加固、详细中文注释与多级回退、首次发布 npm 包 |
| 1.2.6 | 2026-11-07 | 官方主题外壳配色、命令失败卡片底部多余外壳、行号图例对齐与单侧适配、徽章隐藏语义等修复 |
| 1.2.5 | 2026-11-07 | 行号「旧/新」图例、弹窗说明横幅与设置页标题固定、滚动条内缩 |
| 1.2.4 | 2026-11-07 | IN/OUT 滚动条贴边、放大弹窗「修改前/后」栏归入标题并修正横条层级 |
| 1.2.3 | 2026-11-06 | 恢复卡片底部圆角,IN/OUT 竖条改为跟随圆角曲线的左描边 |
| 1.2.2 | 2026-11-06 | IN/OUT 竖条顶格连通、行内高亮降噪与移动标注一致性 |
| 1.2.1 | 2026-11-06 | 移除与官方 Tool 层重复的 conversation.chat.node 槽声明 |
| 1.2.0 | 2026-11-06 | 命令执行 / 工具调用卡片 IN/OUT 分段状态与配色 |
| 1.1.1 | 2026-11-06 | 行内字符级高亮连续化 |
| 1.1.0 | 2026-11-06 | 文件卡片语言识别、语法高亮与可配置语言徽章 |
| 1.0.1 | 2026-11-05 | 搜索/网页工具行展开风格、统一轨迹按钮与文案 |
| 1.0.0 | 2026-11-05 | 首个公开开源版本 |
| 0.2.2 | 2026-11-03 | 行内高亮、移动范围、测试 |
| 0.2.1 | 2026-11-03 | 安装与样式修复 |
| 0.2.0 | 2026-11-03 | 展开风格与工具行配置 |
| 0.1.0 | 2026-11-02 | 内部原型 |
详细变更见 CHANGELOG.md。
License
Ähnliche Plugins
dsh-web (dsh-task-board)
zhu1090093659/dsh-web
dsh-web (dsh-web-all)
zhu1090093659/dsh-web
dsh-TUI
ccch1mneyyy/dsh-tui
dsh-web-ui (dsh-task-board)
zhu1090093659/dsh-web-ui