@d3ara1n/pi-apply-patch

中文文档
0.9.0发布于 2026/11/06Apache-2.0ES Module零依赖构建来源已验证近 30 天下载 2738

符合 Codex- compatiable freeform 应用 patch 编辑时可配置的工作空间边界

中文使用文档
文档目录10 节
  1. 依赖关系
  2. 安装
  3. 配置
  4. 工具和运输
  5. 补丁格式
  6. 投入正常化和通知
  7. 工作空间和失败行为
  8. 诊断失败
  9. 兼容性基准
  10. 发展

@d3ara1n/pi-apply-patch

npm version npm downloads license

符合编码的 apply_patch 编辑 pi,默认仅限于当前工作空间.

习惯于Codex的GPT模型可以使用熟悉的freeform补丁格式. 扩展通过 pi 的受限采样 API 注册正式的 Lark 语法,并在 TypeScript 中执行补丁解析,上下文匹配,和文件操作. 它没有额外的运行时库依赖性.

依赖关系

无。 扩展使用由主机提供的pi框架包.

安装

pi install npm:@d3ara1n/pi-apply-patch

或加进 ~/.pi/agent/settings.json数字 :

{
  "extensions": [
    "/absolute/path/to/pi-extensions/packages/pi-apply-patch"
  ]
}

更改扩展源或装入配置后, 运行 /reload 或重新启动 pi.

配置

结果向量视图和补丁路径策略可以通过 applyPatch 块中 ~/.pi/agent/settings.json (或项目一级) .pi/settings.json,哪个 完全替换全局块 :

{
  "applyPatch": {
    "contextLines": 1,
    "maxChangedLines": 10,
    "workspaceOnly": true
  }
}
  • contextLines ——被保留在已改变区域两侧的线路不变. 0 滴入周围上下文.
  • maxChangedLines 更改(-编号 :+(每个已改变的区域保留行数,计数) 包括清除量和增加量。 其余部分倒入一条提示行.
  • workspaceOnly 在工作空间内保持补丁路径。 默认 true设置 给 false 允许添加、更新、删除并移动到工作空间外; 同样的峡谷-路径和连锁检查仍然适用.

contextLines 财务报告和审定财务报表 maxChangedLines 绑起折叠的视图,这就是 TUI默认显示. ctrl+o 将工具行扩展至完整而未剪接 d. 非数值、负值或最低值以下的值回落到默认值 见上文. workspaceOnly 适用于执行和流预览读取. 更改在 /reload 或重新开始.

工具和运输

该工具的名称 apply_patch它的内部计划有一个需要的字符串属性, input。 。 。 .

用于模型 compat.supportsOpenAIGrammarTools: true,pi 广告的自由格式自定义工具 与官方 Codex Lark 语法。 模型直接发送补丁文本. Pi 将其转换为 { input: patch } 用于执行和处理自定义工具结果配对和历史重放.

当语法工具不可用时, pi 将一个功能工具广告化 input 参数。 内置的Codex模型可以启用语法工具;自定义网关模型定义必须准确声明这种能力. 一个网关必须支持相应的Freeform调用功能的自定义工具协议.

这使用了 Codex 自定义工具协议, 而不是独立的 OpenAI API 内置 type: "apply_patch" 工具。 现有的 pi 编辑工具仍然可用. 没有安装外壳命令或外壳呼叫拦截.

该工具注册于 model-only 曝光:它被宣布给模型,但代码脚本不能称它——它不在脚本中 tools 对象,其文件编辑则通过 pi 可调用的文件工具进行.

在模型流出补丁的同时,工具行预览它迄今解析出的文件. 已完成的更新使用与执行相同的解析器和匹配器在磁盘上显示diff对文件;添加显示其拟议内容并删除显示文件名. 每个部分独立地针对磁盘内容进行预览,因此同一文件中的后期操作可能与最终执行结果不同. 仍然被写入的部分以彩色补丁行形式出现. 无效或未匹配的段落显示警告而不隐藏其余补丁 。 预览读取遵循与执行相同的路径政策,包括符号链接和 workspaceOnly。预览将在执行开始时消失.

补丁格式

*** Begin Patch
*** Add File: greeting.txt
+Hello
+
+Welcome
*** Update File: src/main.ts
@@ function greet() {
-  return "Hi";
+  return "Hello";
 }
*** Update File: old-name.txt
*** Move to: docs/new-name.txt
@@
 keep this text
*** Delete File: obsolete.txt
*** End Patch

发送补丁本身没有马克当栅栏或评论. 函数调用 input 字符串; freeform calls 直接发送补丁. 此示例假设更新、 移动和删除源已经存在 .

  • 添加: 每个内容行起始 +,包括空白行(写为 +) (中文(简体) ).
  • 删除: 文件头没有尸体.
  • 更新 : 使用非空汉字开头 @@ 或者说 @@ <existing line>。前缀前上下文中包含空格,去除处包含 -,并添加 +在原始缩进之前。 空行也需要相应的前缀. 使用字形定位符,而不是像 @@ -N,M +N,M @@。 。 。 .
  • 操作顺序 : 块按补丁顺序执行。 一个路径可能出现在多个块中;每个块都使用先前操作所留下的内容,包括添加,删除和移动.
  • 洪克令: 在“更新”块内,保持文件顺序,且上下文不相重叠。 每个 hunk 匹配该块开头的文件内容; 后面的 hunk 无法匹配同一块中由更早的插入的文本 。 将附近的编辑合并为一角.
  • 定位器 : @@ text 找到一条源行,并在其后搜索。 不要将该行重复为第一个上下文或去除行. 要编辑定位行本身, 请使用赤色 @@ 与周围上下文相连接或定位更早的行.
  • 插入: 包含在具体位置插入的不变上下文。 仅包含文件附加内容的 hunk, 即使它有文本定位器 . *** End of File 在一个汉克车身主锚与文件结尾相匹配后.
  • 移动 : 地点 *** Move to: destination 紧接更新头后。 一个动作需要非空的hunk;只有上下文的hunk在重命名时保留了内容.

在构建更新前读取相关来源 。 重用已知的当前内容并重读, 当它可能是 stale. 复制已删除和上下文行字面上,并包含足够的周边上下文以区分重复片段. 将补丁保持为焦点;失败后,使用诊断和当前文件内容来纠正补丁,而不是不加修改地再发.

首先匹配精确文本的尝试,然后忽略后行的白空间,然后引导后行的白空间,然后使所选的Unicode punctuation和空格正常化. 每道通路在下一个通路之前搜索整个剩余距离,更宽放. 重复上下文被接受;成功通关中的第一个比赛获胜.

源文件开头的一个BOM作为元数据处理:第一行可以在补丁中匹配或不匹配,并更新保留. 其他地方的管理局仍然是文字内容。 LF和CRLF源行共享相同的匹配代表. 内置白空间运行,零宽字符,Unicode组成差异,以及插入或缺失的空白行不会被自动忽略.

无变化上下文行保留了原来的文字和行尾,即使在匹配时使用更松散的比较. 明确 -编号 :+ 替换按顺序继承已删除行的结束;附加行继承已删除行的最后一个结束. 插入使用上一个源行的结束,倒回下行,然后文件的第一个结束,然后是LF. 除非明确去除,否则保留现有的空白行.

添加覆盖已存在文件。 移动写入目的地,必要时覆盖,再去掉源. 覆写不要求前一个目标内容可以读取为UTF-8;当一个添加目标不能被读取时,其diff是不可用的. 缺少的目标目录被创建 .

在源路径和移动目的地中,一个领先 ~/ 扩展到当前用户的主目录,从 os.homedir()启用 ./~/file 单词 ~ 目录。 只有领先 ~/ 扩展; ~user 以及环境变量,例如 $HOME 保持文字状态。 引用是一个文件名的一部分,而不是 shell 引用 。 执行和流预览在工作空间检查前应用同样的扩展,所以 workspaceOnly: true 仍然拒绝工作空间外的扩展路径 .

投入正常化和通知

执行首先使确定性格式的变异正常化,然后严格地剖析出犬科补丁并运行通常的全patch验证. 规范化不读取源文件,也不修改匹配,路径,或写入策略.

正常化修理:

  • 缺少 + 添加文件内容行的前缀,包括空白行;
  • 后面缺少分隔符空间 @@ 在更新定位符中;
  • 一个空的更新标题,没有正文,也没有移动目的地(块被丢弃,没有更改);
  • a. 装有完整的开始/结束补丁的相匹配外标记下围栏;
  • 统一diff 数字洪克头,取而代之的是赤色 @@ 只有在那个洪克有上下文或删除的行可以找到时 纯添加的猎克保留了头并经过了正常的定位验证.
  • 在非空行前丢失的 hunk 标记 + 线条后 *** End of File,当前面的hunk是非空的,并且到下个结构边界的每行都是外加. 原 EOF 约束保留在前面的 hunk; 新的 hunk 附加. 空行,上下文,去除,以及混入其中的未知行会阻止这种修复.

现有格式相容性使用相同的正统路径:特定的异端语包,结构标记编码,被省略出的第一个hunk标记,空白的更新上下文行没有前缀,在"文件结束"后被忽略了被补上,另外还有一个最后的结束标记. 有效载荷空白和明确内容前缀仍为文字。 未知的控制标记和操作前缀的更新行不被猜测. 缺失的补丁边界从未被发明过,围网外的注释不会被丢弃. 没有操作的补丁被拒绝, 不报告为成功编辑 .

模型化工具描述和指南教导了犬科格式,而不是修复可用性或正常化规则. 规范化是执行细节,不是替代输入合同.

每个修补均在纯文本工具结果中报告,包括后来解析,校验,或写入失败时. 修复通知在可用时识别出原有的补丁行并受影响的路径;重复进行同类和路径的修复则被计算出. 修复意味着所提供的输入是非卡通的,而不是一个文件被成功修改了.

执行警告共享同一通知通道:重复上下文,非精确上下文相匹配(包括后继-白相空间相匹配),覆盖,再与已更改的源内容相匹配. 警告描述了允许的行为;它们不会放松核查。 成果保留结构化通知 details.notices;通知的失败使用明显的出错结果,因此错误旗和通知都活过框架边界。 纯文本和TUI使用同样的通知处理问题,每类最多有20个条目,并有一个省略的条目;结构化通知仍然完整.

工作空间和失败行为

工作空间是 ctx.cwd 执行时间。 默认 workspaceOnly: true,当其解密的拼写和方言位置都在工作空间内时,相对路径和绝对路径被接受. 源路径,移动目的地,已存在的同义链接,以及最近的新文件已存在的祖先都经过检查. Dangling symlinks和非文件目标被拒绝. 相同的边界规则适用于"删除":即使操作只会去除该同位素链接,在工作空间外指向的同位素链接也会被拒绝.

设定 applyPatch.workspaceOnly 改为 false 以允许添加、更新、删除并移动到工作空间外。 相对的和绝对的路径都被接受;扩展仍然解决了犬行路径,拒绝牵引的共鸣,并拒绝目录目标. 这是一种明确的选择.

延期本身进行这些检查,不与单独的许可延期合并. 路径检查不是一个OS sandbox:它们不会隔离其他进程,消除文件系统种族,或者跟踪工作空间外的硬链接目的地. 与 workspaceOnly: false, (中文(简体) ), apply_patch 可以在任何 pi 进程可以访问的地方写入或删除.

所有操作都被解析,路径被检查,文件更改在第一次写入前被验证. 校验音轨文件内容和跨操作的存在,按补丁顺序进行;它不模拟完整的目录和同义链接地形. 参与文件共享pi的突变队列,以一致顺序获得. 路径在等待后和突变前会重新检查. 对于目录同名链接下不存在的目标,pi的内置工具可以使用不同的队列键;通过这些别名同时创建并不能保证跨工具的序列化. 如果内容与校验不同,每次操作在写入和重制更新前都会重新读取其活源.

校验失败使文件不受影响 。 执行过程中的失败会留下部分更改;错误报告已完成的操作,列出未应用的操作,并找出当前在重试前检查的目标. 在准备和执行步骤之间检查取消。 允许在建文件系统写入完成; 没有回滚 .

诊断失败

当上下文匹配失败时, 错误会概括每个文件失败的hunks, 并且每个文件最多有6个hunks的详细诊断 。 每一份详细的故障报告:

  • 洪克号及其前行搜索开始于;
  • a 与预期的上下文线相连接的、明显被忽略的回声(长上下文仅显示第一行和最后一行);
  • a. 附近的候选窗口,如果找到,分类为仅白空间漂移、内容差异或空行对齐差异;
  • 最多三个显示预期文本和实际文本的不同行例,第一个不同的列(1个基于Unicode代码点)、字符代码和相邻的无形特征运行计数;额外差异被计算在内;
  • 插入或缺少匹配非空白行之间的空白行,与预期行数和实际行数相匹配;
  • 位于被搜索范围以外的精确匹配(文件更早,或文件前) *** End of File 锚)——通常是个块排列错误;
  • hunk的替换文本是否在文件中已经发生,意思是 hunk 很可能在之前应用过;
  • 一个上下文行是较长源行的前缀,这通常意味着它是从被截取的工具输出中复制出来的.

Tabs,不寻常的空格,零宽字符,方向控件,和组合标记作为可见的Unicode逃出;普通空格会保持文字化,使周围的文字保持可读性. 这些出逃是诊断标记;一个补丁必须包含字面源字符. 长行例子显示了第一个差异周围的节选. 例如,一个有两个内线空格的源, 补丁期望有一个报告:

expected: "const x = 1;"
actual:   "const  x = 1;"
first difference at column 7 (Unicode code points): expected "x" (U+0078); actual SPACE (U+0020)
adjacent invisible run: expected SPACE (U+0020) × 1 at column 6; actual SPACE (U+0020) × 2 at column 6

成功结果包含每局匹配细节 details:匹配行,哪个比较产生匹配(精确,后继-白相空间,白相空间,或Unicode正常化),以及上下文在文件中发生多少次——匹配选择第一次发生. 添加和移动覆盖现有目的地的标记,在校验和写入之间更改的源与其活性内容相匹配的注释。 为非常大的文件编列了候选人扫描的预算并跳过.

候选人发现可以倒塌入内线白相间,忽略Unicode默认的可忽略字符,使Unicode组成正常化,并调整内部空白行. 这些额外的比较只是诊断:它们不授权写入或重写补丁. 候选人搜索被限制,可能找不到候选人;一个错误不能保证一个重试成功.

成功的结果使用 Codex 摘要格式 :

Success. Updated the following files:
A src/greeting.ts
M src/main.ts
D obsolete.txt

当一个 hunk 的上下文在文件中不止发生一次,或者仅在白空或 Unicode 正常化后进行匹配时,摘要附件会发出警告,命名文件, hunk 和行,这样模型就可以验证所添加行的位置和缩进:

Warnings:
- src/main.ts hunk 2 at line 40: context occurs 3 times in the file; this occurrence was edited

失败使用 pi 的工具出错合同: 失败后通知返回 isError: true 和有条理的细节;没有通知就失败。 在 TUI 中,工具行标题包含文件计数和汇总 +N/-M (当一个文件的上一个内容无法读取时被接受,所以它不存在 diff);结果机构列出受影响的文件及其diff,被裁剪到所配置的上下文并更改了行预算,每个被裁剪的区域都用提示行来标记. ctrl+o 显示 diffs 的全部; 折叠的结果列表,每次最多8个文件。 完整的细节仍留在会话中。 RPC,print,和JSON模式在不依赖TUI组件的情况下,获得相同的纯文本工具结果.

兼容性基准

语法、解析器、匹配的通行证和固定装置基于 OpenAI 代码 b04a2c264516ec2e6b3c91dd73ad18a21fd5a88f,下面是主机的修改。 来源归属和适应细节载于 通知;此软件包在Apache-2.0下获得许可.

更新保留了前面的BOM,上下文不变的文本,现有的空白行,以及上述LF/CRLF的结尾. 这些是局部的适应,而不是被钉住的修改的默认 常态化 ToLf 行为或实验 PreserveLineEndings 执行。 在需要时,在非空文本中仍会添加一条后缀的新行。 只有BOM的结果保留了BOM而不添加一行. 仅CR分隔器不被确认为源行边界.

被公示的语法描述了正常的自由形式格式. 上游的宽放格式变体在严格剖析前通过明确的输入规范化器;局部修复情况如上所述. 空添加操作仍然被接受 。 空补丁失败, 没有移动的空更新信头会用修复通知被丢弃 。 空出显式并空出 Move 操作仍然失败 。 多种环境 *** Environment ID: 路由不支持 .

工作空间禁闭和拒绝非文件目标是明确的宿主限制.

发展

从寄存器根 :

npm test --workspace=@d3ara1n/pi-apply-patch
npm run test:integration --workspace=@d3ara1n/pi-apply-patch
npx tsc --noEmit

默认测试使用纯函数和被注入的内嵌文件系统. 上游固定文件从寄存器读取,对预验证和不支持的 CR 唯一分离器有明确的期望. 其他案例包括格式保存和只诊断的Unicode和白空间比较. 协议测试练习 pi 本地转换帮助器没有网络呼叫.

整合测试使用临时沙盒目录并进行清理. 他们进行实际的文件操作,同义链接边界,UTF-8解码,以及共享突变队列. 他们不叫模特儿 直播模型接收需要先加载扩展.

版本与发布记录

@d3ara1n/pi-apply-patch 共发布 19 个版本,首次发布于 2026/09/13;过去 12 个月发布了 19 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.9.0latest2026/11/064 天前
0.8.02026/11/065 天前
0.7.02026/11/065 天前
0.6.12026/11/065 天前
0.6.02026/10/2913 天前
0.5.22026/10/2913 天前

关于 @d3ara1n/pi-apply-patch 的常见问题

@d3ara1n/pi-apply-patch 是什么?

符合 Codex- compatiable freeform 应用 patch 编辑时可配置的工作空间边界

如何安装 @d3ara1n/pi-apply-patch?

在项目目录运行 npm install @d3ara1n/pi-apply-patch,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:typebox(*)、@earendil-works/pi-tui(*)、@earendil-works/pi-coding-agent(*)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@d3ara1n/pi-apply-patch 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/d3ara1n__pi-apply-patch 是否存在。

@d3ara1n/pi-apply-patch 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@d3ara1n/pi-apply-patch 可以商用吗?

@d3ara1n/pi-apply-patch 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@d3ara1n/pi-apply-patch 的下载量有多少?

根据 npm 官方下载统计,@d3ara1n/pi-apply-patch 在 2026/10/11 – 2026/11/09 这 30 天内被下载 2,738 次,日均约 91 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@d3ara1n/pi-apply-patch 还在维护吗?

最新版本 0.9.0 发布于 2026/11/06(4 天前);至今共发布 19 个版本,其中过去 12 个月发布了 19 个;首次发布于 2026/09/13。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。