# @d3ara1n/pi-apply-patch 中文文档

规范地址：https://npmcn.com/package/%40d3ara1n/pi-apply-patch/

版本：0\.9\.0
npm 元数据更新时间：2026-11-06T14:29:52.764Z
中文译文更新时间：2026-11-11T08:22:23.252Z
软件包许可：Apache-2\.0

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40d3ara1n/pi-apply-patch
原文对照：https://npmcn.com/package/%40d3ara1n/pi-apply-patch/?lang=original
项目主页：https://github.com/d3ara1n/pi-extensions/tree/main/packages/pi-apply-patch#readme
源码仓库：https://github.com/d3ara1n/pi-extensions

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：139 kB，25 个文件
- 模块格式：ES Module
- TypeScript 类型：未声明
- 运行依赖：0 个
- peer 依赖：typebox \*，@earendil-works/pi-tui \*，@earendil-works/pi-coding-agent \*
- 首次发布：2026-09-12T19:31:47.664Z
- 最新版本发布：2026-11-06T14:29:52.486Z
- 近 30 天下载量：2738（2026-10-11 至 2026-11-09，npm 官方下载统计）
- 已发布版本数：19（近 12 个月 19 个）

## 中文简介

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

## 安装

```sh
npm install @d3ara1n/pi-apply-patch
```

也可以使用：`pnpm add @d3ara1n/pi-apply-patch`、`yarn add @d3ara1n/pi-apply-patch`、`bun add @d3ara1n/pi-apply-patch`

## README

# @d3ara1n/pi-apply-patch

[![npm version](https://img.shields.io/npm/v/@d3ara1n/pi-apply-patch)](https://www.npmjs.com/package/@d3ara1n/pi-apply-patch) [![npm downloads](https://img.shields.io/npm/dm/@d3ara1n/pi-apply-patch)](https://www.npmjs.com/package/@d3ara1n/pi-apply-patch) [![license](https://img.shields.io/npm/l/@d3ara1n/pi-apply-patch)](https://www.npmjs.com/package/@d3ara1n/pi-apply-patch)

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

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

## 依赖关系

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

## 安装

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

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

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

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

## 配置

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

```jsonc
{
  "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`。预览将在执行开始时消失.

## 补丁格式

```diff
*** 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逃出;普通空格会保持文字化,使周围的文字保持可读性. 这些出逃是诊断标记;一个补丁必须包含字面源字符. 长行例子显示了第一个差异周围的节选. 例如,一个有两个内线空格的源, 补丁期望有一个报告:

```text
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 摘要格式 :

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

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

```text
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`](https://github.com/openai/codex/tree/b04a2c264516ec2e6b3c91dd73ad18a21fd5a88f/codex-rs/apply-patch),下面是主机的修改。 来源归属和适应细节载于 [通知](https://npmcn.com/package/%40d3ara1n/pi-apply-patch/NOTICE);此软件包在Apache-2.0下获得许可.

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

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

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

## 发展

从寄存器根 :

```bash
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 是什么？

符合 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 和提交记录判断。

