--- description: "Parse Codex-style patches and apply hunks to text without filesystem I/O." kind: "package-library" --- # dsh-fs-patch English | [中文](README.zh.md) ## Summary Parse a complete Codex-style patch into ordered file operations with `parsePatch`, then apply update hunks to LF-normalized text with `applyHunks`. Both functions work on caller-supplied strings without filesystem access. Syntax errors throw with the original input line; matching returns new text or a structured failure. ## Table of Contents - [Use this package](#use-this-package) - [Compatibility](#compatibility) - [Understand the implementation](#understand-the-implementation) - [Further Exploration](#further-exploration) - [Known Limitations and Deferred Work](#known-limitations-and-deferred-work) - [Dev Note](#dev-note) ## Use this package Operations and hunks contain only JSON-serializable values, and parsing retains repeated paths in input order as unresolved strings. ```ts import { applyHunks, parsePatch } from '@deepseek-ai/dsh-fs-patch' const operations = parsePatch('*** Begin Patch\n*** Update File: hello.txt\n-hello\n+hi\n*** End Patch') const operation = operations[0] if (operation?.kind === 'update') { const result = applyHunks('hello\n', operation.hunks) // { ok: true, after: 'hi\n' } } ``` Malformed input throws `PatchParseError` with a one-based `lineNumber` and a corrective `reason`. Locations count leading blank lines and heredoc wrappers in the original input. `applyHunks` returns `{ ok: true, after }` or `{ ok: false, failure }` without mutating its inputs. A match failure reports the hunk's patch line, the `context` or `oldLines` stage, the sequential search cursor, and the original unmatched pattern; a trailing-empty-line retry still reports the original pattern. Returning rather than throwing lets callers collect match failures across file operations. ## Compatibility The reference is [OpenAI Codex rust-v0.158.0](https://github.com/openai/codex/tree/rust-v0.158.0/codex-rs/apply-patch/src): `parser.rs` and `streaming_parser.rs` for syntax, and `seek_sequence.rs` and `file_update.rs` for matching and `NormalizeToLf` reconstruction. `text_file.rs` documents the separate line-preserving representation. The [parser tests](tests/parse.spec.ts) and [text tests](tests/apply.spec.ts) adapt selected upstream cases, including `file_update_tests.rs` and `lib.rs`. The [LICENSE](LICENSE) retains OpenAI attribution and Apache-2.0 terms alongside the MIT license for DeepSeek contributions. ### Parsing | Input | Parsed result | |---|---| | Begin/End Patch; Add/Delete/Update File headers | Ordered operations; an empty patch and an empty added file are accepted. | | Added file lines prefixed by `+` | Prefix removed; each line contributes a final LF. | | Update lines prefixed by space, `+`, or `-` | Context, insertion, or deletion; a bare empty line is empty context. | | First update without `@@`; later `@@` or `@@ text` | Ordered hunks with an optional context anchor; empty hunks are rejected. | | Move to immediately after Update File | Destination on the update; a move without a nonempty hunk is rejected. | | End of File after a hunk | EOF flag; following blank lines are ignored and further content requires a new hunk or file header. | | LF/CRLF, outer Unicode whitespace, indented headers | Codex trimming rules use Unicode `White_Space`, including U+0085 and excluding BOM (U+FEFF). Indented markers inside updates remain context. Content whitespace is retained. | | Literal `< ## Understand the implementation
Implementation internals — click to expand The [parser](src/parse.ts) builds syntax records without a Session or provider dependency. The [text updater](src/apply.ts) locates every hunk against the original text before constructing a complete result. The [types](src/types.ts) carry syntax locations and match failures; the [filesystem reference](../../../docs/subsystems/filesystem.md#patch-syntax-records) owns the public type definitions.
## Further Exploration - [Filesystem package group](../README.md) — providers, policies, and file tools. - [Apply patch file editing](../../../.agents/notes/implemented/feature/2026-09-28-apply-patch-file-editing.md) — decision record. ## Known Limitations and Deferred Work - Text updates implement only `NormalizeToLf`; callers own line-ending conversion. - The public API accepts complete strings, not streaming deltas. ### Dev Note
Working context for maintainers — click to expand None.