Skip to content
dsh.fish
Bundle

dsh-diff-vis

DSH plugin: show a git-style file diff right inside the chat whenever the AI calls write/edit tools. Unified (top-bottom) and split (side-by-side) views with inline word highlighting, view-preference memory, zero git dependency. Written in TypeScript, built with esbuild.

Source
roushanyyzz
License
MIT
Updated
Updated 7 days ago

Readme

# dsh-diff-vis

让 AI 在对话中每修改一个文件,你就立刻看到它改了什么。

DSH(DeepSeek Harness)插件:拦截 `write` / `edit` 工具调用,在对话流的工具卡片位置直接渲染 **git 风格文件差异**——支持**上下对比**与**左右对比**,逐行高亮,零 git 依赖(自研行级 diff 算法)。**TypeScript 编写,esbuild 构建。**

> 适合**小说创作、文档写作、代码协作**等一切让 AI 反复改文件、而你想盯住每一处改动的场景。

## 特性

| 特性 | 说明 |
| --- | --- |
| 🎯 零依赖 | 不调用 git、不依赖任何外部 diff 工具;行级 LCS + 前后缀裁剪,纯 JS 实现 |
| 📍 原位展示 | 差异直接渲染在对话流中对应 write/edit 工具卡片上,无需离开对话框 |
| ↕️ 上下对比 | 删除红行 / 新增绿行 / 灰色上下文,`@@ 行号块 @@` 头部,git diff 同款布局 |
| ↔️ 左右对比 | 双栏并排;**被修改的行在同一水平线左旧右新**,行号对齐 |
| ✨ 行内高亮 | 变化的具体词语额外黄底标出(共同前缀/后缀保留),一眼看到"改了哪个词" |
| 💾 偏好记忆 | 你选过的视图(左右/上下)自动保存到浏览器 localStorage,之后的卡片默认跟随 |
| 🖱️ 点击打开 | 点击卡片头部文件名,直接在工作区打开该文件 |
| 🛡️ 大文件保护 | 超过 4M 差分单元格自动降级为整体替换视图,进程不卡死 |

## 安装

### 方式一:bundle 安装(推荐,持久生效)

本插件声明了 `dsh.bundle` 与 `dsh.client`,`dsh plugin add` 会自动挂载,重启 GUI 后永久生效:

```bash
# 从 GitHub 直接安装
dsh plugin --profile web add github:roushanyyzz/dsh-diff-vis

# 或从本地 clone 目录安装(开发模式,改动即时生效)
dsh plugin --profile web add file:D:/Plugins/dsh-diff-vis
```

安装后**重启 `dsh web`** 即可。以后每次启动都会自动加载,**不需要重复执行安装命令**。

### 方式二:动态会话插件(尝鲜,重启即失)

动态插件属于进程内存:激活后立即生效,但重启 DSH 后需要重新定义。适合尝鲜与开发测试,日常使用请用方式一。

## 架构

```
Host(进程侧)                        Client(浏览器侧)
┌─────────────────────┐            ┌──────────────────────────┐
│ tools/pre-execute   │            │ tool.call.toolview       │
│  写前读旧内容快照      │  GET       │  key: 'write' / 'edit'   │
│ tools/result        │ /dsh-diff- │  · fetch 宿主完整差异记录   │
│  写后计算行级差异      │ vis/rec ─▶ │  · 宿主不可达时本地兜底     │
│ webServer 路由       │            │  · unified / split 渲染   │
└─────────────────────┘            │  · 视图偏好 localStorage  │
                                   └──────────────────────────┘
```

数据流(双保险):

1. **host 增强**:`write`/`edit` 执行前读取磁盘旧内容 → 工具成功后计算行级 diff → 卡片通过 HTTP 拉取记录(含写前快照,覆盖写也能看到旧→新)。
2. **client 兜底**:宿主路由不可用时,直接从工具参数(write 的 `content`、edit 的 `old_string`/`new_string`)在浏览器本地计算差异,功能永不失效。

## 使用

满足以下任一情况,卡片即自动出现:

- AI 调用 `write` 写入文件 → 显示新增(绿色;覆盖已有文件时显示旧→新完整差异)
- AI 调用 `edit` 修改已有文件 → 显示精确的删行/增行与行内变化

卡片操作:

- 右上角 **上下对比 / 左右对比** 切换视图;选择会被记住,之后的卡片默认使用该视图
- 点击卡片头部**文件名**在工作区打开文件

## 开发

```bash
pnpm install          # 安装 esbuild / typescript 等开发依赖
pnpm run typecheck    # 类型检查
pnpm run build        # 构建 lib/index.js + lib/client.js
pnpm run build:host   # 只构建 host 半段
pnpm run build:client # 只构建 client 半段
```

源码结构:

```
src/
├── types.ts          # 共享类型(Cordis/DSH 最小契约面)
├── diff.ts           # 行级 diff 算法(LCS + 前后缀裁剪 + hunks)
├── index.ts          # host 半段(事件快照 + webServer 路由)
└── client/
    ├── index.tsx     # client 半段(DiffCard 组件 + slots 注册)
    └── styles.ts     # 内联样式注入
scripts/build.mjs     # esbuild 构建(host ESM / client ModuleLoader closure)
```

## 已知边界

- 差异记录保存在进程中:插件重启后历史卡片显示兜底提示,**之后的修改照常捕获**
- 目前覆盖 `write` / `edit` 两个文件改写工具;`bash`/`pwsh` 等命令产生的文件变化暂不追踪(架构留有扩展点,欢迎 PR)
- 每个卡片最多处理 8 万行输入;超大文件显示"文件过大"提示

## 开源协议

[MIT](./LICENSE)

Install

dsh plugin --profile web add github:roushanyyzz/dsh-diff-vis

Profile: web

  • This package builds from source on install. pnpm will ask you to allow its build script — that is permission to run the package’s code on your machine, outside the agent sandbox. Only allow sources you trust.
  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source