---
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.