Skip to content

feat(tools): apply_patch — git-style unified-diff edit tool - #39

Merged
ayman3000 merged 1 commit into
mainfrom
feat/apply-patch-tool
Aug 4, 2026
Merged

feat(tools): apply_patch — git-style unified-diff edit tool#39
ayman3000 merged 1 commit into
mainfrom
feat/apply-patch-tool

Conversation

@ayman3000

Copy link
Copy Markdown
Owner

What

Adds apply_patch(path, patch) — a targeted edit tool. Agents can change a few lines by emitting a unified diff instead of reading the whole file and rewriting it with write_file (the cause of the read/rewrite storm on multi-file edits).

How

  • UnifiedDiff (pure, Foundation-only) — parses a git/diff -u patch and applies each hunk by matching its context; the @@ line numbers are treated as hints (nearest-hint selection + cumulative offset across hunks). All-or-nothing: any hunk that doesn't match leaves the file untouched. Trailing-newline state preserved.
  • PatchFileTool (apply_patch) — reads an existing file, applies the diff, writes atomically. requiresConfirmation (diff shows in the approval sheet). Errors name the first unmatched hunk so the model can re-read and regenerate.

Why context-matching (not strict git apply)

LLMs frequently get @@ line numbers wrong; strict git apply then rejects the whole patch. Matching on context (like Aider / Codex apply_patch / patch -F) makes LLM-generated diffs reliable — a test asserts a patch with deliberately wrong line numbers still applies.

Scope (v1)

Single existing file per call; text hunks only (no binary/rename/create — creation stays write_file). Pure-Swift, no shelling to git/patch (keeps SwiftAgentKitTools Foundation-only + cross-platform).

Testing

✅ Full suite 155 green, incl. UnifiedDiffTests (wrong line numbers, offset drift, nearest-hint, context-not-found→unchanged, trailing-newline, insert/remove-only) and apply_patch tool cases (in-place edit, missing file, non-matching hunk leaves file unchanged, requiresConfirmation).

Consumed by Naseem next (register the tool + prompt nudge) after an alpha bump. Spec in the Naseem repo: docs/superpowers/specs/2026-08-04-apply-patch-tool-design.md.

🤖 Generated with Claude Code

Adds a targeted edit tool so agents stop reading+rewriting whole files to
change a few lines.

- UnifiedDiff: Foundation-only parser + applier. Applies each hunk by matching
  its context (the @@ line numbers are hints, not authority), with nearest-hint
  selection and cumulative offset across hunks. All-or-nothing: any hunk that
  doesn't match leaves the file untouched. Preserves trailing-newline state.
- PatchFileTool (apply_patch): reads an existing file, applies a unified diff,
  writes atomically. requiresConfirmation (the diff shows in the approval
  sheet). Clear errors name the first unmatched hunk so the model can re-read
  and regenerate.

Robustness: wrong @@ numbers still apply via context (the property that makes
LLM-generated diffs usable). Tests cover offset drift, nearest-hint, context
not found → unchanged, trailing-newline preservation, insertion/removal.
Full suite: 155 green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@ayman3000
ayman3000 merged commit 1d60900 into main Aug 4, 2026
1 check passed
@ayman3000
ayman3000 deleted the feat/apply-patch-tool branch August 4, 2026 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant