feat(init): add fuzzy edit replacers and edits-based apply-patchset#698
feat(init): add fuzzy edit replacers and edits-based apply-patchset#698
Conversation
Semver Impact of This PR🟡 Minor (new features) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨
Bug Fixes 🐛Dashboard
Other
Internal Changes 🔧
🤖 This preview updates automatically when you update the PR. |
|
Codecov Results 📊✅ 134 passed | Total: 134 | Pass Rate: 100% | Execution Time: 0ms 📊 Comparison with Base Branch
✨ No test changes detected All tests are passing successfully. ✅ Patch coverage is 100.00%. Project has 1513 uncovered lines. Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
- Coverage 95.48% 95.43% -0.05%
==========================================
Files 224 226 +2
Lines 32591 33072 +481
Branches 0 0 —
==========================================
+ Hits 31115 31559 +444
- Misses 1476 1513 +37
- Partials 0 0 —Generated by Codecov Action |
6774576 to
b0cee7f
Compare
Port opencode's 9-strategy fuzzy matching chain as replacers.ts for finding and replacing text in files despite minor whitespace, indentation, or escape differences from LLM output. Extend apply-patchset so modify actions use edits (oldString/newString pairs) applied sequentially with the fuzzy replacer chain. Create actions still use full-content patch strings. Errors pinpoint the exact failing edit by file and index. Made-with: Cursor
b0cee7f to
1c79754
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1c79754. Configure here.

Summary
Adds a fuzzy find-and-replace engine (ported from opencode) and extends
apply-patchsetto supportoldString/newStringedit pairs for file modifications.Currently the codemod-planner outputs the complete file content for every modification, which wastes output tokens and makes retry expensive. This PR adds the client-side infrastructure for a more efficient approach: the server can send targeted edits instead, and the CLI applies them with fuzzy matching that tolerates minor whitespace/indentation differences from LLM output.
What's new
replacers.ts-- 9 cascading fuzzy matching strategies (exact, line-trimmed, block-anchor+Levenshtein, whitespace-normalized, indentation-flexible, escape-normalized, trimmed-boundary, context-aware, multi-occurrence). Pure string functions, zero external deps.ApplyPatchsetPatchtype -- Extended to support{ action: "modify", edits: [{ oldString, newString }] }alongside the existing{ action: "modify", patch: "full content" }.applySinglePatchin local-ops -- When a modify patch has aneditsarray, applies each edit sequentially using the fuzzy replacer. On failure, returns a pinpointed error:"Edit #N failed on 'file.ts': Could not find oldString...".Backward compatibility
Patches with
action: "modify"and apatchfield (noedits) still use the existing full-content write path. Old server versions work with this client unchanged.Server-side counterpart
This PR is client-only. The server-side changes (updating
codemodEntrySchema, agent instructions, andbuildPatches()in cli-init-api) will come in a separate PR.Test plan
replace()covering each fuzzy strategy and real-world Sentry codemod scenariosapply-patchset: success, failure, fuzzy matching, backward compat, mixed create+edits batchMade with Cursor