Class: Tools::Edit
Overview
Performs surgical text replacement with uniqueness constraint. Finds old_text in the file (must match exactly one location), replaces with new_text, and returns a unified diff. Falls back to whitespace-normalized fuzzy matching when exact match fails.
Normalizes BOM and CRLF line endings for matching, restoring them after the edit. Rejects ambiguous edits where old_text matches zero or multiple locations.
Constant Summary collapse
- MAX_FILE_SIZE =
10 MB
10 * 1024 * 1024
Class Method Summary collapse
Instance Method Summary collapse
- #execute(input) ⇒ String, Hash
-
#initialize(shell_session: nil) ⇒ Edit
constructor
A new instance of Edit.
Methods inherited from Base
Constructor Details
#initialize(shell_session: nil) ⇒ Edit
Returns a new instance of Edit.
40 41 42 |
# File 'lib/tools/edit.rb', line 40 def initialize(shell_session: nil, **) @working_directory = shell_session&.pwd end |
Class Method Details
.description ⇒ Object
23 24 25 |
# File 'lib/tools/edit.rb', line 23 def self.description = "Replace exact text in a file. old_text must match exactly one location; " \ "include surrounding lines for uniqueness. Use for surgical edits; " \ "use write for new files or full replacement." |
.input_schema ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/tools/edit.rb', line 27 def self.input_schema { type: "object", properties: { path: {type: "string", description: "Absolute or relative file path (relative resolved against working directory)"}, old_text: {type: "string", description: "Exact text to find (must match exactly one location — include surrounding context if needed)"}, new_text: {type: "string", description: "Replacement text (empty string to delete)"} }, required: %w[path old_text new_text] } end |
.tool_name ⇒ Object
21 |
# File 'lib/tools/edit.rb', line 21 def self.tool_name = "edit" |
Instance Method Details
#execute(input) ⇒ String, Hash
47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/tools/edit.rb', line 47 def execute(input) path, old_text, new_text = extract_params(input) return {error: "Path cannot be blank"} if path.empty? return {error: "old_text cannot be blank"} if old_text.empty? path = resolve_path(path) error = validate_file(path) return error if error edit_file(path, old_text, new_text) end |