dsh-diff-writer
v0.3.0
Published
Precise file editing for DeepSeek Harness: apply search/replace patches to files instead of full-file rewrites, minimizing accidental changes.
Readme
dsh-diff-writer
精确文件编辑插件(v0.2.1):用 search/replace 补丁和行号模式补丁修改文件,避免整文件覆盖带来的误改风险。与 dsh-file-manager-cli(整体读写)和 dsh-git-helper(提交)形成互补的文件工作流。
代码地址
- GitHub: https://github.com/geeklei/dsh-plugins/tree/main/dsh-diff-writer
- NPM: https://www.npmjs.com/package/dsh-diff-writer
安装
npm install dsh-diff-writer使用说明
基本用法
import { apply_patch } from "./index.js"
// 示例:修改配置文件中的特定值
await apply_patch({
path: "config.json",
patches: [
{
search: '"debug": false',
replace: '"debug": true',
all: true
},
{
search: '"port": 3000',
replace: '"port": 8080'
}
]
})行号模式补丁
// 示例:使用行号范围删除和插入
await apply_patch({
path: "README.md",
patches: [
{
startLine: 10,
endLine: 15,
replace: "" // 删除第 10-15 行
},
{
startLine: 20,
endLine: 20,
replace: "# 新增内容\n" // 在第 20 行前插入
}
]
})新建文件
// 示例:创建新文件
await apply_patch({
path: "new-file.js",
create: true,
patches: [
{
search: "",
replace: "console.log('Hello World!')"
}
]
})预览模式(dry-run)
apply_patch 与 apply_patches 都支持 dry_run: true,先看改动再决定是否落地:
await apply_patch({
path: "src/app.js",
patches: [{ search: "const DEBUG = false", replace: "const DEBUG = true" }],
dry_run: true
})
// [dry-run] src/app.js
// 修改:12 行 → 12 行,替换 1 处
// @@ -3,1 +3,1 @@
// ...
// - const DEBUG = false
// + const DEBUG = true预览输出包含文件路径、行数变化、替换处数与统一 diff 片段(默认前后各 3 行上下文,超过 40 行的增删块会被截断说明)。
工具详解
apply_patch
对目标文件按顺序应用一组补丁,支持两种补丁模式。
| 参数 | 类型 | 说明 |
| --------- | ------- | --------------------------------------------------- |
| path | string | 必填,目标文件路径(相对或绝对,必须在工作目录内) |
| patches | array | 必填,补丁列表,按顺序应用 |
| create | boolean | 可选,文件不存在时创建新文件(此时 patches 可为空) |
| dry_run | boolean | 可选,true 时只输出改动预览,不写入磁盘 |
apply_patches(多文件批量)
一次调用对多个文件应用补丁,适合同一批改动的跨文件落地。
| 参数 | 类型 | 说明 |
| --------- | ------- | ------------------------------------------------------------- |
| files | array | 必填,文件列表,每项为 { path, patches, create? },语义同 apply_patch |
| dry_run | boolean | 可选,true 时逐个输出预览,不写入磁盘 |
批量语义:先对全部文件做校验与计算,任一文件出错则整体不写入(此时磁盘上不留任何修改);全部通过后才逐个原子写入。单次最多 20 个文件、每文件最多 20 个补丁。
补丁模式
1. Search/Replace 模式
{
search: "要匹配的内容",
replace: "替换后的内容",
all?: false // 可选,默认 false,仅替换唯一匹配处
}2. 行号模式
{
startLine: 10, // 起始行号(1 基)
endLine: 20, // 结束行号(包含)
replace: "替换内容" // 空字符串表示删除该行范围
}匹配规则:
search必须与文件内容精确匹配(含缩进与换行)- 默认只替换唯一匹配处;匹配 0 处或多处都会报错,多处在场时报错并提示匹配数量
all: true时全量替换所有匹配- 空
search不允许;空replace表示删除 - 补丁按顺序执行,任一补丁失败立即中止,失败的补丁之前的修改已落盘(不自动回滚),未执行的补丁不生效
安全边界:
- 所有路径必须在当前工作目录内,越界路径直接拒绝
- 文件大小上限 2MB
- 单次调用最多 20 个补丁
create=true不能用于已存在的文件- 原子写入:先写临时文件再 rename,杜绝半写状态
- 批量模式先整体校验再写入,避免"改了一半"的中间状态
dry_run=true只读不写,可安全用于任何目标路径
Roadmap(v0.4 候选)
- 正则模式补丁(pattern/replace)
- 补丁分组与回滚(失败时按组撤销已落盘改动)
- 与 dsh-hash-checksum 联动,预览中附带改动前后摘要
安全边界
- 写盘需显式确认:
apply_patch会直接修改目标文件,调用前请确认目标与范围。 - 行号边界校验:越界行号会被拒绝,不会产生半截文件。
- 不做隐式备份:本插件不自动备份,建议配合 dsh-hash-checksum 记录改动前后摘要。
- 编码保持:以 UTF-8 读写;非 UTF-8 文件可能出现乱码风险。
- 范围可控:仅改动指定行区间,区间外内容原样保留。
FAQ
Q: 补丁失败后怎么办?
A: 补丁失败时会立即中止执行,失败的补丁之前的修改已经写入文件(不自动回滚)。你需要根据错误信息修复问题后重试整个操作。建议在非生产环境或使用版本控制操作。
Q: 为什么搜索内容必须精确匹配?
A: 精确匹配确保不会意外修改相似但不完全相同的内容,避免产生误改。如果需要模糊匹配,可以扩展搜索内容包含更多上下文使其唯一。
Q: 如何处理多处匹配的情况?
A: 有两种方式:
- 增加搜索内容的上下文,确保唯一匹配
- 使用
all: true参数替换所有匹配处(需谨慎使用)
Q: 行号模式和搜索模式有什么区别?
A: 行号模式适用于:
- 已知具体行号范围的编辑
- 需要精确控制行位置的场景
- 结构化文件的修改
搜索模式适用于:
- 内容相关的编辑
- 不确定行号但知道内容的情况
- 需要跨行匹配的场景
Q: 文件大小和性能限制
A:
- 最大支持 2MB 文件
- 单次调用最多 20 个补丁
- 补丁按顺序执行,前一个失败后不再执行后续补丁
版本历史
0.3.0(2026-09-30)
- 新增
apply_patches工具:多文件批量补丁,先整体校验再写入 apply_patch与apply_patches新增dry_run预览模式,输出统一 diff 片段- 新增变更预览渲染:公共前缀/后缀裁剪 + 上下文与截断提示
- 补齐测试至 35 项断言
0.2.1(2026-09-16)
- 完善 README:补齐匹配规则、安全边界、Roadmap 说明
- 补充代码地址、发布地址、FAQ 与使用示例
0.2.0(2026-09-13)
- 新增行号模式补丁:
{ startLine, endLine, replace } - 实现原子写入:临时文件 + rename,杜绝半写状态
- 增强补丁参数描述,行号越界明确报错
- 支持创建空文件(
create=true且patches=[])
0.1.0(2026-09-05)
- 初始版本,支持 search/replace 补丁模式
- 实现多补丁顺序执行、唯一匹配防护、全量替换
- 添加安全边界:工作目录限制、文件大小限制、补丁数量限制
测试
npm test覆盖所有核心功能:
- 唯一匹配替换
- 多处匹配防护
- all 全量替换
- 多补丁顺序执行
- 失败中止
- create 新建文件
- 路径越界拒绝
- 行号模式补丁
- 原子写入验证
开发和贡献
本地开发
cd dsh-diff-writer
npm install
npm test发布新版本
- 更新
package.json中的版本号 - 运行
npm test确保测试通过 - 提交代码并打标签
- 发布到 npm:
npm publish
典型场景
1. 精确修改长文件中的几行
用户:把配置文件第 42-45 行换成新内容
apply_patch 按行号范围替换,避免整文件重写带来的意外改动。
2. 大文件局部修补
用户:这个 3000 行的文件只改一处,不要重写整个文件
按行号打补丁,改动范围可控、可复核。
3. 与 diff 结果配合
用户:先看看差异,再决定改不改
先用 dsh-text-diff 得到差异,确认后用 apply_patch 落地。
4. 批量文件的一致性修补
用户:这几个文件都要把同一段替换掉
对每个文件分别调用,补丁范围明确,失败时不会留下半个文件。
其他插件集成说明
| 协作插件 | 集成方式 |
|---|---|
| dsh-text-diff | 改动前用 diff_text 预览差异,确认后再用本插件落盘 |
| dsh-line-ops | extract_lines 取出目标行内容,apply_patch 负责写回 |
| dsh-regex-lab | 先用 replace_preview 预览正则替换结果,再按行号精确写入 |
| dsh-hash-checksum | 补丁前后计算文件摘要,确认只有预期文件被改动 |
| dsh-fs-inspector | 改动前用 recent_files 确认目标文件与备份状态 |
