You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
None => returnOk(ToolOutput::error("new_string parameter is required")),
79
103
};
104
+
if old_string.is_empty(){
105
+
returnOk(ToolOutput::error("old_string must not be empty"));
106
+
}
80
107
81
108
let replace_all = args
82
109
.get("replace_all")
83
110
.and_then(|v| v.as_bool())
84
111
.unwrap_or(false);
112
+
let dry_run = args
113
+
.get("dry_run")
114
+
.and_then(|v| v.as_bool())
115
+
.unwrap_or(false);
116
+
let max_replacements = matchpositive_usize_arg(args,"max_replacements"){
117
+
Ok(value) => value,
118
+
Err(error) => returnOk(ToolOutput::error(error)),
119
+
};
120
+
let expected_replacements = matchpositive_usize_arg(args,"expected_replacements"){
121
+
Ok(value) => value,
122
+
Err(error) => returnOk(ToolOutput::error(error)),
123
+
};
85
124
86
125
let workspace_path = match ctx.resolve_workspace_path(file_path){
87
126
Ok(path) => path,
@@ -116,31 +155,68 @@ impl Tool for EditTool {
116
155
)));
117
156
}
118
157
158
+
let replacement_count = if replace_all { count }else{1};
159
+
ifletSome(expected) = expected_replacements {
160
+
if replacement_count != expected {
161
+
returnOk(ToolOutput::error(format!(
162
+
"Replacement count mismatch in {display_path}: expected {expected} replacement(s), found {replacement_count}. Re-run dry_run to inspect the current file."
163
+
))
164
+
.with_metadata(serde_json::json!({
165
+
"file_path": file_path,
166
+
"dry_run": dry_run,
167
+
"expected_replacements": expected,
168
+
"replacement_count": replacement_count,
169
+
})));
170
+
}
171
+
}
172
+
ifletSome(maximum) = max_replacements {
173
+
if replacement_count > maximum {
174
+
returnOk(ToolOutput::error(format!(
175
+
"Edit would replace {replacement_count} occurrence(s) in {display_path}, which exceeds max_replacements={maximum}."
176
+
))
177
+
.with_metadata(serde_json::json!({
178
+
"file_path": file_path,
179
+
"dry_run": dry_run,
180
+
"max_replacements": maximum,
181
+
"replacement_count": replacement_count,
182
+
})));
183
+
}
184
+
}
185
+
119
186
let new_content = if replace_all {
120
187
content.replace(old_string, new_string)
121
188
}else{
122
189
content.replacen(old_string, new_string,1)
123
190
};
124
191
192
+
let change_metadata = || {
193
+
serde_json::json!({
194
+
"file_path": file_path,
195
+
"before": content,
196
+
"after": new_content,
197
+
"dry_run": dry_run,
198
+
"replacement_count": replacement_count,
199
+
"expected_replacements": expected_replacements,
200
+
"max_replacements": max_replacements,
201
+
})
202
+
};
203
+
if dry_run {
204
+
returnOk(ToolOutput::success(format!(
205
+
"Dry run: would replace {replacement_count} occurrence(s) in {display_path}; nothing was written"
0 commit comments