[FEATURE] Edit tool: boundary-anchored wildcard for `old_string` to reduce recitation overhead
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
The Edit tool requires old_string to exactly reproduce the content being replaced, character-for-character including whitespace. This creates asymmetric friction:
- Adding code is cheap — specify the insertion point and new content
- Removing or replacing code is expensive — the entire block must be recited verbatim
When replacing a 40-line function requires reproducing all 40 lines but wrapping it requires only specifying an insertion point, the path of least resistance becomes shimming, wrapping, and building alongside. Over many sessions this compounds into layered, backward-compatible cruft that's hard to trace back to any single decision.
The friction is particularly relevant for code cleanup and simplification tasks. When the tool makes it easier to add code than to remove or reshape it, the natural outcome is codebases that grow in complexity even when the intent is to simplify. Reducing the cost of replacement-shaped edits to match insertion-shaped edits removes this bias.
Proposed Solution
Allow a single wildcard marker (e.g. ~~~~~) in old_string that means "match everything between the lines above and below":
old_string:
function handleAuth(req, res) {
~~~~~
}
new_string:
function handleAuth(req, res) {
const token = validateToken(req);
return { authenticated: !!token };
}
This matches the full function body regardless of length. Only the boundary lines need to be unique — same uniqueness requirement as today's exact matching, just without the recitation.
The replacement effort for a 5-line block and a 500-line block becomes identical.
Properties:
- One reserved token added to
old_string— no new parameters, no changes tonew_string, no changes to output format - Same ambiguity model as current Edit — if boundaries aren't unique, the edit fails. Add more context lines to disambiguate.
- One wildcard per edit — keeps matching unambiguous
Alternative Solutions
Currently running a boundary-anchored edit tool as a personal MCP server, which works well but requires explicit CLAUDE.md instructions to prefer it over the built-in Edit tool. Integrating the wildcard into the native Edit tool would eliminate this friction.
See also #25775 (hash-based line addressing) which addresses the broader exact-match problem but requires changes to Read output format and a new addressing system. This proposal is narrower in scope — a single-token extension to the existing interface.
Priority
High - Significant impact on productivity
Feature Category
File operations
Use Case Example
- Read a file containing a 60-line function that needs to be rewritten
- Today: reproduce all 60 lines in
old_stringcharacter-for-character, hope whitespace matches, retry on failure - With wildcard: specify the function signature and closing brace with
~~~~~between them, write the new implementation innew_string - Same precision (boundaries must be unique), fraction of the output tokens, no whitespace failure mode for the interior lines
This applies to any replacement where the boundaries are more recognizable than the contents — function rewrites, config block updates, replacing multi-line imports, swapping out class implementations.
Additional Context
_No response_
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗