Răsfoiți Sursa

improve search and replace tool (#2764)

* Refactor search and replace tool

* feat(search-replace): enhance search/replace tool UI and messaging

Refactor search/replace tool message structure for better consistency
Add dedicated UI component for displaying search/replace operations
Add i18n support for search/replace operations in all supported languages
Improve partial tool handling in searchAndReplaceTool

* Remove search_and_replace experiment and related references
Sam Hoang Van 8 luni în urmă
părinte
comite
80b298492c
33 a modificat fișierele cu 875 adăugiri și 356 ștergeri
  1. 0 1
      evals/packages/types/src/roo-code-defaults.ts
  2. 1 2
      evals/packages/types/src/roo-code.ts
  3. 514 97
      src/core/prompts/__tests__/__snapshots__/system.test.ts.snap
  4. 0 10
      src/core/prompts/__tests__/system.test.ts
  5. 5 8
      src/core/prompts/sections/rules.ts
  6. 28 41
      src/core/prompts/tools/search-and-replace.ts
  7. 218 145
      src/core/tools/searchAndReplaceTool.ts
  8. 0 1
      src/exports/roo-code.d.ts
  9. 0 1
      src/exports/types.ts
  10. 1 2
      src/schemas/index.ts
  11. 7 0
      src/shared/ExtensionMessage.ts
  12. 0 3
      src/shared/__tests__/experiments.test.ts
  13. 0 25
      src/shared/__tests__/modes.test.ts
  14. 0 2
      src/shared/experiments.ts
  15. 12 0
      src/shared/tools.ts
  16. 43 0
      webview-ui/src/components/chat/ChatRow.tsx
  17. 1 1
      webview-ui/src/components/chat/ChatView.tsx
  18. 0 2
      webview-ui/src/context/__tests__/ExtensionStateContext.test.tsx
  19. 3 1
      webview-ui/src/i18n/locales/ca/chat.json
  20. 3 1
      webview-ui/src/i18n/locales/de/chat.json
  21. 3 1
      webview-ui/src/i18n/locales/en/chat.json
  22. 3 1
      webview-ui/src/i18n/locales/es/chat.json
  23. 3 1
      webview-ui/src/i18n/locales/fr/chat.json
  24. 3 1
      webview-ui/src/i18n/locales/hi/chat.json
  25. 3 1
      webview-ui/src/i18n/locales/it/chat.json
  26. 3 1
      webview-ui/src/i18n/locales/ja/chat.json
  27. 3 1
      webview-ui/src/i18n/locales/ko/chat.json
  28. 3 1
      webview-ui/src/i18n/locales/pl/chat.json
  29. 3 1
      webview-ui/src/i18n/locales/pt-BR/chat.json
  30. 3 1
      webview-ui/src/i18n/locales/tr/chat.json
  31. 3 1
      webview-ui/src/i18n/locales/vi/chat.json
  32. 3 1
      webview-ui/src/i18n/locales/zh-CN/chat.json
  33. 3 1
      webview-ui/src/i18n/locales/zh-TW/chat.json

+ 0 - 1
evals/packages/types/src/roo-code-defaults.ts

@@ -56,7 +56,6 @@ export const rooCodeDefaults: RooCodeSettings = {
 	diffEnabled: true,
 	fuzzyMatchThreshold: 1.0,
 	experiments: {
-		search_and_replace: false,
 		insert_content: false,
 		powerSteering: false,
 	},

+ 1 - 2
evals/packages/types/src/roo-code.ts

@@ -271,7 +271,7 @@ export type CustomSupportPrompts = z.infer<typeof customSupportPromptsSchema>
  * ExperimentId
  */
 
-export const experimentIds = ["search_and_replace", "insert_content", "powerSteering"] as const
+export const experimentIds = ["insert_content", "powerSteering"] as const
 
 export const experimentIdsSchema = z.enum(experimentIds)
 
@@ -282,7 +282,6 @@ export type ExperimentId = z.infer<typeof experimentIdsSchema>
  */
 
 const experimentsSchema = z.object({
-	search_and_replace: z.boolean(),
 	insert_content: z.boolean(),
 	powerSteering: z.boolean(),
 })

+ 514 - 97
src/core/prompts/__tests__/__snapshots__/system.test.ts.snap

@@ -201,6 +201,42 @@ Example: Requesting to append to a log file
 </content>
 </append_to_file>
 
+## search_and_replace
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory /test/path)
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldText</search>
+<replace>newText</replace>
+</search_and_replace>
+
+2. Case-insensitive regex pattern:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldw+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
+</search_and_replace>
+
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: \`touch ./testdata/example.file\`, \`dir ./examples/model1/data/yaml\`, or \`go test ./cmd/front --config ./cmd/front/config.yml\`. If directed by the user, you may open a terminal in a different directory by using the \`cwd\` parameter.
 Parameters:
@@ -361,8 +397,9 @@ RULES
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
 - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
 - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files).
+- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files), search_and_replace (for finding and replacing individual pieces of text).
 - The append_to_file tool adds content to the end of files, such as appending new log entries or adding new data records. This tool will always add the content at the end of the file.
+- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.
 - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.
 - When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
@@ -659,53 +696,39 @@ Example: Insert a new function and its import statement
 </insert_content>
 
 ## search_and_replace
-Description: Request to perform search and replace operations on a file. Each operation can specify a search pattern (string or regex) and replacement text, with optional line range restrictions and regex flags. Shows a diff preview before applying changes.
-Parameters:
-- path: (required) The path of the file to modify (relative to the current workspace directory /test/path)
-- operations: (required) A JSON array of search/replace operations. Each operation is an object with:
-    * search: (required) The text or pattern to search for
-    * replace: (required) The text to replace matches with. If multiple lines need to be replaced, use "
-" for newlines
-    * start_line: (optional) Starting line number for restricted replacement
-    * end_line: (optional) Ending line number for restricted replacement
-    * use_regex: (optional) Whether to treat search as a regex pattern
-    * ignore_case: (optional) Whether to ignore case when matching
-    * regex_flags: (optional) Additional regex flags when use_regex is true
-Usage:
-<search_and_replace>
-<path>File path here</path>
-<operations>[
-  {
-    "search": "text to find",
-    "replace": "replacement text",
-    "start_line": 1,
-    "end_line": 10
-  }
-]</operations>
-</search_and_replace>
-Example: Replace "foo" with "bar" in lines 1-10 of example.ts
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory /test/path)
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
 <search_and_replace>
 <path>example.ts</path>
-<operations>[
-  {
-    "search": "foo",
-    "replace": "bar",
-    "start_line": 1,
-    "end_line": 10
-  }
-]</operations>
+<search>oldText</search>
+<replace>newText</replace>
 </search_and_replace>
-Example: Replace all occurrences of "old" with "new" using regex
+
+2. Case-insensitive regex pattern:
 <search_and_replace>
 <path>example.ts</path>
-<operations>[
-  {
-    "search": "old\\w+",
-    "replace": "new$&",
-    "use_regex": true,
-    "ignore_case": true
-  }
-]</operations>
+<search>oldw+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
 </search_and_replace>
 
 ## execute_command
@@ -1133,53 +1156,39 @@ Example: Requesting to append to a log file
 </append_to_file>
 
 ## search_and_replace
-Description: Request to perform search and replace operations on a file. Each operation can specify a search pattern (string or regex) and replacement text, with optional line range restrictions and regex flags. Shows a diff preview before applying changes.
-Parameters:
-- path: (required) The path of the file to modify (relative to the current workspace directory /test/path)
-- operations: (required) A JSON array of search/replace operations. Each operation is an object with:
-    * search: (required) The text or pattern to search for
-    * replace: (required) The text to replace matches with. If multiple lines need to be replaced, use "
-" for newlines
-    * start_line: (optional) Starting line number for restricted replacement
-    * end_line: (optional) Ending line number for restricted replacement
-    * use_regex: (optional) Whether to treat search as a regex pattern
-    * ignore_case: (optional) Whether to ignore case when matching
-    * regex_flags: (optional) Additional regex flags when use_regex is true
-Usage:
-<search_and_replace>
-<path>File path here</path>
-<operations>[
-  {
-    "search": "text to find",
-    "replace": "replacement text",
-    "start_line": 1,
-    "end_line": 10
-  }
-]</operations>
-</search_and_replace>
-Example: Replace "foo" with "bar" in lines 1-10 of example.ts
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory /test/path)
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
 <search_and_replace>
 <path>example.ts</path>
-<operations>[
-  {
-    "search": "foo",
-    "replace": "bar",
-    "start_line": 1,
-    "end_line": 10
-  }
-]</operations>
+<search>oldText</search>
+<replace>newText</replace>
 </search_and_replace>
-Example: Replace all occurrences of "old" with "new" using regex
+
+2. Case-insensitive regex pattern:
 <search_and_replace>
 <path>example.ts</path>
-<operations>[
-  {
-    "search": "old\\w+",
-    "replace": "new$&",
-    "use_regex": true,
-    "ignore_case": true
-  }
-]</operations>
+<search>oldw+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
 </search_and_replace>
 
 ## execute_command
@@ -1605,6 +1614,42 @@ Example: Requesting to append to a log file
 </content>
 </append_to_file>
 
+## search_and_replace
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory /test/path)
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldText</search>
+<replace>newText</replace>
+</search_and_replace>
+
+2. Case-insensitive regex pattern:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldw+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
+</search_and_replace>
+
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: \`touch ./testdata/example.file\`, \`dir ./examples/model1/data/yaml\`, or \`go test ./cmd/front --config ./cmd/front/config.yml\`. If directed by the user, you may open a terminal in a different directory by using the \`cwd\` parameter.
 Parameters:
@@ -1765,8 +1810,9 @@ RULES
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
 - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
 - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files).
+- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files), search_and_replace (for finding and replacing individual pieces of text).
 - The append_to_file tool adds content to the end of files, such as appending new log entries or adding new data records. This tool will always add the content at the end of the file.
+- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.
 - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.
 - When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
@@ -2027,6 +2073,42 @@ Example: Requesting to append to a log file
 </content>
 </append_to_file>
 
+## search_and_replace
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory /test/path)
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldText</search>
+<replace>newText</replace>
+</search_and_replace>
+
+2. Case-insensitive regex pattern:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldw+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
+</search_and_replace>
+
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: \`touch ./testdata/example.file\`, \`dir ./examples/model1/data/yaml\`, or \`go test ./cmd/front --config ./cmd/front/config.yml\`. If directed by the user, you may open a terminal in a different directory by using the \`cwd\` parameter.
 Parameters:
@@ -2187,8 +2269,9 @@ RULES
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
 - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
 - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files).
+- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files), search_and_replace (for finding and replacing individual pieces of text).
 - The append_to_file tool adds content to the end of files, such as appending new log entries or adding new data records. This tool will always add the content at the end of the file.
+- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.
 - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.
 - When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
@@ -2449,6 +2532,42 @@ Example: Requesting to append to a log file
 </content>
 </append_to_file>
 
+## search_and_replace
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory /test/path)
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldText</search>
+<replace>newText</replace>
+</search_and_replace>
+
+2. Case-insensitive regex pattern:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldw+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
+</search_and_replace>
+
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: \`touch ./testdata/example.file\`, \`dir ./examples/model1/data/yaml\`, or \`go test ./cmd/front --config ./cmd/front/config.yml\`. If directed by the user, you may open a terminal in a different directory by using the \`cwd\` parameter.
 Parameters:
@@ -2609,8 +2728,9 @@ RULES
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
 - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
 - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files).
+- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files), search_and_replace (for finding and replacing individual pieces of text).
 - The append_to_file tool adds content to the end of files, such as appending new log entries or adding new data records. This tool will always add the content at the end of the file.
+- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.
 - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.
 - When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
@@ -2871,6 +2991,42 @@ Example: Requesting to append to a log file
 </content>
 </append_to_file>
 
+## search_and_replace
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory /test/path)
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldText</search>
+<replace>newText</replace>
+</search_and_replace>
+
+2. Case-insensitive regex pattern:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldw+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
+</search_and_replace>
+
 ## browser_action
 Description: Request to interact with a Puppeteer-controlled browser. Every action, except \`close\`, will be responded to with a screenshot of the browser's current state, along with any new console logs. You may only perform one browser action per message, and wait for the user's response including a screenshot and logs to determine the next action.
 - The sequence of actions **must always start with** launching the browser at a URL, and **must always end with** closing the browser. If you need to visit a new URL that is not possible to navigate to from the current webpage, you must first close the browser, then launch again at the new URL.
@@ -3086,8 +3242,9 @@ RULES
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
 - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
 - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files).
+- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files), search_and_replace (for finding and replacing individual pieces of text).
 - The append_to_file tool adds content to the end of files, such as appending new log entries or adding new data records. This tool will always add the content at the end of the file.
+- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.
 - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.
 - When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
@@ -3349,6 +3506,42 @@ Example: Requesting to append to a log file
 </content>
 </append_to_file>
 
+## search_and_replace
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory /test/path)
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldText</search>
+<replace>newText</replace>
+</search_and_replace>
+
+2. Case-insensitive regex pattern:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldw+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
+</search_and_replace>
+
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: \`touch ./testdata/example.file\`, \`dir ./examples/model1/data/yaml\`, or \`go test ./cmd/front --config ./cmd/front/config.yml\`. If directed by the user, you may open a terminal in a different directory by using the \`cwd\` parameter.
 Parameters:
@@ -3577,8 +3770,9 @@ RULES
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
 - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
 - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files).
+- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files), search_and_replace (for finding and replacing individual pieces of text).
 - The append_to_file tool adds content to the end of files, such as appending new log entries or adding new data records. This tool will always add the content at the end of the file.
+- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.
 - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.
 - When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
@@ -3839,6 +4033,42 @@ Example: Requesting to append to a log file
 </content>
 </append_to_file>
 
+## search_and_replace
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory /test/path)
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldText</search>
+<replace>newText</replace>
+</search_and_replace>
+
+2. Case-insensitive regex pattern:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldw+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
+</search_and_replace>
+
 ## browser_action
 Description: Request to interact with a Puppeteer-controlled browser. Every action, except \`close\`, will be responded to with a screenshot of the browser's current state, along with any new console logs. You may only perform one browser action per message, and wait for the user's response including a screenshot and logs to determine the next action.
 - The sequence of actions **must always start with** launching the browser at a URL, and **must always end with** closing the browser. If you need to visit a new URL that is not possible to navigate to from the current webpage, you must first close the browser, then launch again at the new URL.
@@ -4054,8 +4284,9 @@ RULES
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
 - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
 - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files).
+- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files), search_and_replace (for finding and replacing individual pieces of text).
 - The append_to_file tool adds content to the end of files, such as appending new log entries or adding new data records. This tool will always add the content at the end of the file.
+- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.
 - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.
 - When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
@@ -4407,6 +4638,42 @@ Example: Requesting to append to a log file
 </content>
 </append_to_file>
 
+## search_and_replace
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory /test/path)
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldText</search>
+<replace>newText</replace>
+</search_and_replace>
+
+2. Case-insensitive regex pattern:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldw+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
+</search_and_replace>
+
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: \`touch ./testdata/example.file\`, \`dir ./examples/model1/data/yaml\`, or \`go test ./cmd/front --config ./cmd/front/config.yml\`. If directed by the user, you may open a terminal in a different directory by using the \`cwd\` parameter.
 Parameters:
@@ -4567,8 +4834,9 @@ RULES
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
 - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using apply_diff or write_to_file to make informed changes.
 - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- For editing files, you have access to these tools: apply_diff (for replacing lines in existing files), write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files).
+- For editing files, you have access to these tools: apply_diff (for replacing lines in existing files), write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files), search_and_replace (for finding and replacing individual pieces of text).
 - The append_to_file tool adds content to the end of files, such as appending new log entries or adding new data records. This tool will always add the content at the end of the file.
+- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.
 - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.
 - When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
@@ -4829,6 +5097,42 @@ Example: Requesting to append to a log file
 </content>
 </append_to_file>
 
+## search_and_replace
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory /test/path)
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldText</search>
+<replace>newText</replace>
+</search_and_replace>
+
+2. Case-insensitive regex pattern:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldw+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
+</search_and_replace>
+
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: \`touch ./testdata/example.file\`, \`dir ./examples/model1/data/yaml\`, or \`go test ./cmd/front --config ./cmd/front/config.yml\`. If directed by the user, you may open a terminal in a different directory by using the \`cwd\` parameter.
 Parameters:
@@ -4989,8 +5293,9 @@ RULES
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
 - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
 - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files).
+- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files), search_and_replace (for finding and replacing individual pieces of text).
 - The append_to_file tool adds content to the end of files, such as appending new log entries or adding new data records. This tool will always add the content at the end of the file.
+- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.
 - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.
 - When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
@@ -5293,6 +5598,42 @@ Example: Requesting to append to a log file
 </content>
 </append_to_file>
 
+## search_and_replace
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory /test/path)
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldText</search>
+<replace>newText</replace>
+</search_and_replace>
+
+2. Case-insensitive regex pattern:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldw+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
+</search_and_replace>
+
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: \`touch ./testdata/example.file\`, \`dir ./examples/model1/data/yaml\`, or \`go test ./cmd/front --config ./cmd/front/config.yml\`. If directed by the user, you may open a terminal in a different directory by using the \`cwd\` parameter.
 Parameters:
@@ -5515,8 +5856,9 @@ RULES
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
 - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
 - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files).
+- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files), search_and_replace (for finding and replacing individual pieces of text).
 - The append_to_file tool adds content to the end of files, such as appending new log entries or adding new data records. This tool will always add the content at the end of the file.
+- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.
 - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.
 - When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
@@ -5792,6 +6134,42 @@ Example: Requesting to append to a log file
 </content>
 </append_to_file>
 
+## search_and_replace
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory /test/path)
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldText</search>
+<replace>newText</replace>
+</search_and_replace>
+
+2. Case-insensitive regex pattern:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldw+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
+</search_and_replace>
+
 ## ask_followup_question
 Description: Ask the user a question to gather additional information needed to complete the task. This tool should be used when you encounter ambiguities, need clarification, or require more details to proceed effectively. It allows for interactive problem-solving by enabling direct communication with the user. Use this tool judiciously to maintain a balance between gathering necessary information and avoiding excessive back-and-forth.
 Parameters:
@@ -5930,8 +6308,9 @@ RULES
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
 - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
 - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files).
+- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files), search_and_replace (for finding and replacing individual pieces of text).
 - The append_to_file tool adds content to the end of files, such as appending new log entries or adding new data records. This tool will always add the content at the end of the file.
+- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.
 - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.
 - When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
@@ -6284,8 +6663,9 @@ RULES
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
 - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
 - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files).
+- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files), search_and_replace (for finding and replacing individual pieces of text).
 - The append_to_file tool adds content to the end of files, such as appending new log entries or adding new data records. This tool will always add the content at the end of the file.
+- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.
 - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.
 - When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.
@@ -6579,6 +6959,42 @@ Example: Requesting to append to a log file
 </content>
 </append_to_file>
 
+## search_and_replace
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory /test/path)
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldText</search>
+<replace>newText</replace>
+</search_and_replace>
+
+2. Case-insensitive regex pattern:
+<search_and_replace>
+<path>example.ts</path>
+<search>oldw+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
+</search_and_replace>
+
 ## execute_command
 Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: \`touch ./testdata/example.file\`, \`dir ./examples/model1/data/yaml\`, or \`go test ./cmd/front --config ./cmd/front/config.yml\`. If directed by the user, you may open a terminal in a different directory by using the \`cwd\` parameter.
 Parameters:
@@ -6807,8 +7223,9 @@ RULES
 - Before using the execute_command tool, you must first think about the SYSTEM INFORMATION context provided to understand the user's environment and tailor your commands to ensure they are compatible with their system. You must also consider if the command you need to run should be executed in a specific directory outside of the current working directory '/test/path', and if so prepend with \`cd\`'ing into that directory && then executing the command (as one command since you are stuck operating from '/test/path'). For example, if you needed to run \`npm install\` in a project outside of '/test/path', you would need to prepend with a \`cd\` i.e. pseudocode for this would be \`cd (path to project) && (command, in this case npm install)\`.
 - When using the search_files tool, craft your regex patterns carefully to balance specificity and flexibility. Based on the user's task you may use it to find code patterns, TODO comments, function definitions, or any text-based information across the project. The results include context, so analyze the surrounding code to better understand the matches. Leverage the search_files tool in combination with other tools for more comprehensive analysis. For example, use it to find specific code patterns, then use read_file to examine the full context of interesting matches before using write_to_file to make informed changes.
 - When creating a new project (such as an app, website, or any software project), organize all new files within a dedicated project directory unless the user specifies otherwise. Use appropriate file paths when writing files, as the write_to_file tool will automatically create any necessary directories. Structure the project logically, adhering to best practices for the specific type of project being created. Unless otherwise specified, new projects should be easily run without additional setup, for example most projects can be built in HTML, CSS, and JavaScript - which you can open in a browser.
-- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files).
+- For editing files, you have access to these tools: write_to_file (for creating new files or complete file rewrites), append_to_file (for appending content to the end of files), search_and_replace (for finding and replacing individual pieces of text).
 - The append_to_file tool adds content to the end of files, such as appending new log entries or adding new data records. This tool will always add the content at the end of the file.
+- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.
 - You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.
 - When using the write_to_file tool to modify a file, use the tool directly with the desired content. You do not need to display the content before using the tool. ALWAYS provide the COMPLETE file content in your response. This is NON-NEGOTIABLE. Partial updates or placeholders like '// rest of code unchanged' are STRICTLY FORBIDDEN. You MUST include ALL parts of the file, even if they haven't been modified. Failure to do so will result in incomplete or broken code, severely impacting the user's project.
 - Some modes have restrictions on which files they can edit. If you attempt to edit a restricted file, the operation will be rejected with a FileRestrictionError that will specify which file patterns are allowed for the current mode.

+ 0 - 10
src/core/prompts/__tests__/system.test.ts

@@ -171,7 +171,6 @@ describe("SYSTEM_PROMPT", () => {
 	beforeEach(() => {
 		// Reset experiments before each test to ensure they're disabled by default
 		experiments = {
-			[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: false,
 			[EXPERIMENT_IDS.INSERT_BLOCK]: false,
 		}
 	})
@@ -482,7 +481,6 @@ describe("SYSTEM_PROMPT", () => {
 		it("should disable experimental tools by default", async () => {
 			// Set experiments to explicitly disable experimental tools
 			const experimentsConfig = {
-				[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: false,
 				[EXPERIMENT_IDS.INSERT_BLOCK]: false,
 			}
 
@@ -508,7 +506,6 @@ describe("SYSTEM_PROMPT", () => {
 			// Check that experimental tool sections are not included
 			const toolSections = prompt.split("\n## ").slice(1)
 			const toolNames = toolSections.map((section) => section.split("\n")[0].trim())
-			expect(toolNames).not.toContain("search_and_replace")
 			expect(toolNames).not.toContain("insert_content")
 			expect(prompt).toMatchSnapshot()
 		})
@@ -516,7 +513,6 @@ describe("SYSTEM_PROMPT", () => {
 		it("should enable experimental tools when explicitly enabled", async () => {
 			// Set experiments for testing experimental features
 			const experimentsEnabled = {
-				[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: true,
 				[EXPERIMENT_IDS.INSERT_BLOCK]: true,
 			}
 
@@ -544,7 +540,6 @@ describe("SYSTEM_PROMPT", () => {
 			const toolNames = toolSections.map((section) => section.split("\n")[0].trim())
 
 			// Verify experimental tools are included in the prompt when enabled
-			expect(toolNames).toContain("search_and_replace")
 			expect(toolNames).toContain("insert_content")
 			expect(prompt).toMatchSnapshot()
 		})
@@ -552,7 +547,6 @@ describe("SYSTEM_PROMPT", () => {
 		it("should selectively enable experimental tools", async () => {
 			// Set experiments for testing selective enabling
 			const experimentsSelective = {
-				[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: true,
 				[EXPERIMENT_IDS.INSERT_BLOCK]: false,
 			}
 
@@ -580,14 +574,12 @@ describe("SYSTEM_PROMPT", () => {
 			const toolNames = toolSections.map((section) => section.split("\n")[0].trim())
 
 			// Verify only enabled experimental tools are included
-			expect(toolNames).toContain("search_and_replace")
 			expect(toolNames).not.toContain("insert_content")
 			expect(prompt).toMatchSnapshot()
 		})
 
 		it("should list all available editing tools in base instruction", async () => {
 			const experiments = {
-				[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: true,
 				[EXPERIMENT_IDS.INSERT_BLOCK]: true,
 			}
 
@@ -615,7 +607,6 @@ describe("SYSTEM_PROMPT", () => {
 		})
 		it("should provide detailed instructions for each enabled tool", async () => {
 			const experiments = {
-				[EXPERIMENT_IDS.SEARCH_AND_REPLACE]: true,
 				[EXPERIMENT_IDS.INSERT_BLOCK]: true,
 			}
 
@@ -640,7 +631,6 @@ describe("SYSTEM_PROMPT", () => {
 				"You should always prefer using other editing tools over write_to_file when making changes to existing files since write_to_file is much slower and cannot handle large files.",
 			)
 			expect(prompt).toContain("The insert_content tool adds lines of text to files")
-			expect(prompt).toContain("The search_and_replace tool finds and replaces text or regex in files")
 		})
 	})
 

+ 5 - 8
src/core/prompts/sections/rules.ts

@@ -19,9 +19,8 @@ function getEditingInstructions(diffStrategy?: DiffStrategy, experiments?: Recor
 	if (experiments?.["insert_content"]) {
 		availableTools.push("insert_content (for adding lines to existing files)")
 	}
-	if (experiments?.["search_and_replace"]) {
-		availableTools.push("search_and_replace (for finding and replacing individual pieces of text)")
-	}
+
+	availableTools.push("search_and_replace (for finding and replacing individual pieces of text)")
 
 	// Base editing instruction mentioning all available tools
 	if (availableTools.length > 1) {
@@ -38,11 +37,9 @@ function getEditingInstructions(diffStrategy?: DiffStrategy, experiments?: Recor
 		)
 	}
 
-	if (experiments?.["search_and_replace"]) {
-		instructions.push(
-			"- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.",
-		)
-	}
+	instructions.push(
+		"- The search_and_replace tool finds and replaces text or regex in files. This tool allows you to search for a specific regex pattern or text and replace it with another value. Be cautious when using this tool to ensure you are replacing the correct text. It can support multiple operations at once.",
+	)
 
 	if (availableTools.length > 1) {
 		instructions.push(

+ 28 - 41
src/core/prompts/tools/search-and-replace.ts

@@ -2,51 +2,38 @@ import { ToolArgs } from "./types"
 
 export function getSearchAndReplaceDescription(args: ToolArgs): string {
 	return `## search_and_replace
-Description: Request to perform search and replace operations on a file. Each operation can specify a search pattern (string or regex) and replacement text, with optional line range restrictions and regex flags. Shows a diff preview before applying changes.
-Parameters:
-- path: (required) The path of the file to modify (relative to the current workspace directory ${args.cwd.toPosix()})
-- operations: (required) A JSON array of search/replace operations. Each operation is an object with:
-    * search: (required) The text or pattern to search for
-    * replace: (required) The text to replace matches with. If multiple lines need to be replaced, use "\n" for newlines
-    * start_line: (optional) Starting line number for restricted replacement
-    * end_line: (optional) Ending line number for restricted replacement
-    * use_regex: (optional) Whether to treat search as a regex pattern
-    * ignore_case: (optional) Whether to ignore case when matching
-    * regex_flags: (optional) Additional regex flags when use_regex is true
-Usage:
-<search_and_replace>
-<path>File path here</path>
-<operations>[
-  {
-    "search": "text to find",
-    "replace": "replacement text",
-    "start_line": 1,
-    "end_line": 10
-  }
-]</operations>
-</search_and_replace>
-Example: Replace "foo" with "bar" in lines 1-10 of example.ts
+Description: Request to perform a search and replace operation on a file. Supports both literal text and regex patterns. Shows a diff preview before applying changes.
+
+Required Parameters:
+- path: The path of the file to modify (relative to the current workspace directory ${args.cwd.toPosix()})
+- search: The text or pattern to search for
+- replace: The text to replace matches with
+
+Optional Parameters:
+- start_line: Starting line number for restricted replacement (1-based)
+- end_line: Ending line number for restricted replacement (1-based)
+- use_regex: Set to "true" to treat search as a regex pattern (default: false)
+- ignore_case: Set to "true" to ignore case when matching (default: false)
+
+Notes:
+- When use_regex is true, the search parameter is treated as a regular expression pattern
+- When ignore_case is true, the search is case-insensitive regardless of regex mode
+
+Examples:
+
+1. Simple text replacement:
 <search_and_replace>
 <path>example.ts</path>
-<operations>[
-  {
-    "search": "foo",
-    "replace": "bar",
-    "start_line": 1,
-    "end_line": 10
-  }
-]</operations>
+<search>oldText</search>
+<replace>newText</replace>
 </search_and_replace>
-Example: Replace all occurrences of "old" with "new" using regex
+
+2. Case-insensitive regex pattern:
 <search_and_replace>
 <path>example.ts</path>
-<operations>[
-  {
-    "search": "old\\w+",
-    "replace": "new$&",
-    "use_regex": true,
-    "ignore_case": true
-  }
-]</operations>
+<search>old\w+</search>
+<replace>new$&</replace>
+<use_regex>true</use_regex>
+<ignore_case>true</ignore_case>
 </search_and_replace>`
 }

+ 218 - 145
src/core/tools/searchAndReplaceTool.ts

@@ -1,15 +1,65 @@
+// Core Node.js imports
 import path from "path"
 import fs from "fs/promises"
+import delay from "delay"
 
+// Internal imports
 import { Cline } from "../Cline"
-import { ToolUse, AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "../../shared/tools"
+import { AskApproval, HandleError, PushToolResult, RemoveClosingTag, ToolUse } from "../../shared/tools"
 import { formatResponse } from "../prompts/responses"
 import { ClineSayTool } from "../../shared/ExtensionMessage"
 import { getReadablePath } from "../../utils/path"
 import { fileExistsAtPath } from "../../utils/fs"
-import { addLineNumbers } from "../../integrations/misc/extract-text"
 import { RecordSource } from "../context-tracking/FileContextTrackerTypes"
 
+/**
+ * Tool for performing search and replace operations on files
+ * Supports regex and case-sensitive/insensitive matching
+ */
+
+/**
+ * Validates required parameters for search and replace operation
+ */
+async function validateParams(
+	cline: Cline,
+	relPath: string | undefined,
+	search: string | undefined,
+	replace: string | undefined,
+	pushToolResult: PushToolResult,
+): Promise<boolean> {
+	if (!relPath) {
+		cline.consecutiveMistakeCount++
+		cline.recordToolError("search_and_replace")
+		pushToolResult(await cline.sayAndCreateMissingParamError("search_and_replace", "path"))
+		return false
+	}
+
+	if (!search) {
+		cline.consecutiveMistakeCount++
+		cline.recordToolError("search_and_replace")
+		pushToolResult(await cline.sayAndCreateMissingParamError("search_and_replace", "search"))
+		return false
+	}
+
+	if (!replace) {
+		cline.consecutiveMistakeCount++
+		cline.recordToolError("search_and_replace")
+		pushToolResult(await cline.sayAndCreateMissingParamError("search_and_replace", "replace"))
+		return false
+	}
+
+	return true
+}
+
+/**
+ * Performs search and replace operations on a file
+ * @param cline - Cline instance
+ * @param block - Tool use parameters
+ * @param askApproval - Function to request user approval
+ * @param handleError - Function to handle errors
+ * @param pushToolResult - Function to push tool results
+ * @param removeClosingTag - Function to remove closing tags
+ */
 export async function searchAndReplaceTool(
 	cline: Cline,
 	block: ToolUse,
@@ -17,178 +67,201 @@ export async function searchAndReplaceTool(
 	handleError: HandleError,
 	pushToolResult: PushToolResult,
 	removeClosingTag: RemoveClosingTag,
-) {
+): Promise<void> {
+	// Extract and validate parameters
 	const relPath: string | undefined = block.params.path
-	const operations: string | undefined = block.params.operations
-
-	const sharedMessageProps: ClineSayTool = {
-		tool: "appliedDiff",
-		path: getReadablePath(cline.cwd, removeClosingTag("path", relPath)),
-	}
+	const search: string | undefined = block.params.search
+	const replace: string | undefined = block.params.replace
+	const useRegex: boolean = block.params.use_regex === "true"
+	const ignoreCase: boolean = block.params.ignore_case === "true"
+	const startLine: number | undefined = block.params.start_line ? parseInt(block.params.start_line, 10) : undefined
+	const endLine: number | undefined = block.params.end_line ? parseInt(block.params.end_line, 10) : undefined
 
 	try {
+		// Handle partial tool use
 		if (block.partial) {
-			const partialMessage = JSON.stringify({
-				path: removeClosingTag("path", relPath),
-				operations: removeClosingTag("operations", operations),
-			})
+			const partialMessageProps = {
+				tool: "searchAndReplace" as const,
+				path: getReadablePath(cline.cwd, removeClosingTag("path", relPath)),
+				search: removeClosingTag("search", search),
+				replace: removeClosingTag("replace", replace),
+				useRegex: block.params.use_regex === "true",
+				ignoreCase: block.params.ignore_case === "true",
+				startLine,
+				endLine,
+			}
+			await cline.ask("tool", JSON.stringify(partialMessageProps), block.partial).catch(() => {})
+			return
+		}
 
-			await cline.ask("tool", partialMessage, block.partial).catch(() => {})
+		// Validate required parameters
+		if (!(await validateParams(cline, relPath, search, replace, pushToolResult))) {
 			return
-		} else {
-			if (!relPath) {
-				cline.consecutiveMistakeCount++
-				cline.recordToolError("search_and_replace")
-				pushToolResult(await cline.sayAndCreateMissingParamError("search_and_replace", "path"))
-				return
-			}
+		}
 
-			if (!operations) {
-				cline.consecutiveMistakeCount++
-				cline.recordToolError("search_and_replace")
-				pushToolResult(await cline.sayAndCreateMissingParamError("search_and_replace", "operations"))
-				return
-			}
+		// At this point we know relPath, search and replace are defined
+		const validRelPath = relPath as string
+		const validSearch = search as string
+		const validReplace = replace as string
+
+		const sharedMessageProps: ClineSayTool = {
+			tool: "searchAndReplace",
+			path: getReadablePath(cline.cwd, validRelPath),
+			search: validSearch,
+			replace: validReplace,
+			useRegex: useRegex,
+			ignoreCase: ignoreCase,
+			startLine: startLine,
+			endLine: endLine,
+		}
 
-			const absolutePath = path.resolve(cline.cwd, relPath)
-			const fileExists = await fileExistsAtPath(absolutePath)
+		const absolutePath = path.resolve(cline.cwd, validRelPath)
+		const fileExists = await fileExistsAtPath(absolutePath)
+
+		if (!fileExists) {
+			cline.consecutiveMistakeCount++
+			cline.recordToolError("search_and_replace")
+			const formattedError = formatResponse.toolError(
+				`File does not exist at path: ${absolutePath}\nThe specified file could not be found. Please verify the file path and try again.`,
+			)
+			await cline.say("error", formattedError)
+			pushToolResult(formattedError)
+			return
+		}
 
-			if (!fileExists) {
-				cline.consecutiveMistakeCount++
-				cline.recordToolError("search_and_replace")
-				const formattedError = `File does not exist at path: ${absolutePath}\n\n<error_details>\nThe specified file could not be found. Please verify the file path and try again.\n</error_details>`
-				await cline.say("error", formattedError)
-				pushToolResult(formattedError)
-				return
-			}
+		// Reset consecutive mistakes since all validations passed
+		cline.consecutiveMistakeCount = 0
+
+		// Read and process file content
+		let fileContent: string
+		try {
+			fileContent = await fs.readFile(absolutePath, "utf-8")
+		} catch (error) {
+			cline.consecutiveMistakeCount++
+			cline.recordToolError("search_and_replace")
+			const errorMessage = `Error reading file: ${absolutePath}\nFailed to read the file content: ${
+				error instanceof Error ? error.message : String(error)
+			}\nPlease verify file permissions and try again.`
+			const formattedError = formatResponse.toolError(errorMessage)
+			await cline.say("error", formattedError)
+			pushToolResult(formattedError)
+			return
+		}
 
-			let parsedOperations: Array<{
-				search: string
-				replace: string
-				start_line?: number
-				end_line?: number
-				use_regex?: boolean
-				ignore_case?: boolean
-				regex_flags?: string
-			}>
-
-			try {
-				parsedOperations = JSON.parse(operations)
-
-				if (!Array.isArray(parsedOperations)) {
-					throw new Error("Operations must be an array")
-				}
-			} catch (error) {
-				cline.consecutiveMistakeCount++
-				cline.recordToolError("search_and_replace")
-				await cline.say("error", `Failed to parse operations JSON: ${error.message}`)
-				pushToolResult(formatResponse.toolError("Invalid operations JSON format"))
-				return
-			}
+		// Create search pattern and perform replacement
+		const flags = ignoreCase ? "gi" : "g"
+		const searchPattern = useRegex ? new RegExp(validSearch, flags) : new RegExp(escapeRegExp(validSearch), flags)
 
-			// Read the original file content
-			const fileContent = await fs.readFile(absolutePath, "utf-8")
-			cline.diffViewProvider.editType = "modify"
-			cline.diffViewProvider.originalContent = fileContent
-			let lines = fileContent.split("\n")
-
-			for (const op of parsedOperations) {
-				const flags = op.regex_flags ?? (op.ignore_case ? "gi" : "g")
-				const multilineFlags = flags.includes("m") ? flags : flags + "m"
-
-				const searchPattern = op.use_regex
-					? new RegExp(op.search, multilineFlags)
-					: new RegExp(escapeRegExp(op.search), multilineFlags)
-
-				if (op.start_line || op.end_line) {
-					const startLine = Math.max((op.start_line ?? 1) - 1, 0)
-					const endLine = Math.min((op.end_line ?? lines.length) - 1, lines.length - 1)
-
-					// Get the content before and after the target section
-					const beforeLines = lines.slice(0, startLine)
-					const afterLines = lines.slice(endLine + 1)
-
-					// Get the target section and perform replacement
-					const targetContent = lines.slice(startLine, endLine + 1).join("\n")
-					const modifiedContent = targetContent.replace(searchPattern, op.replace)
-					const modifiedLines = modifiedContent.split("\n")
-
-					// Reconstruct the full content with the modified section
-					lines = [...beforeLines, ...modifiedLines, ...afterLines]
-				} else {
-					// Global replacement
-					const fullContent = lines.join("\n")
-					const modifiedContent = fullContent.replace(searchPattern, op.replace)
-					lines = modifiedContent.split("\n")
-				}
-			}
+		let newContent: string
+		if (startLine !== undefined || endLine !== undefined) {
+			// Handle line-specific replacement
+			const lines = fileContent.split("\n")
+			const start = Math.max((startLine ?? 1) - 1, 0)
+			const end = Math.min((endLine ?? lines.length) - 1, lines.length - 1)
+
+			// Get content before and after target section
+			const beforeLines = lines.slice(0, start)
+			const afterLines = lines.slice(end + 1)
 
-			const newContent = lines.join("\n")
+			// Get and modify target section
+			const targetContent = lines.slice(start, end + 1).join("\n")
+			const modifiedContent = targetContent.replace(searchPattern, validReplace)
+			const modifiedLines = modifiedContent.split("\n")
 
-			cline.consecutiveMistakeCount = 0
+			// Reconstruct full content
+			newContent = [...beforeLines, ...modifiedLines, ...afterLines].join("\n")
+		} else {
+			// Global replacement
+			newContent = fileContent.replace(searchPattern, validReplace)
+		}
 
-			// Show diff preview
-			const diff = formatResponse.createPrettyPatch(relPath, fileContent, newContent)
+		// Initialize diff view
+		cline.diffViewProvider.editType = "modify"
+		cline.diffViewProvider.originalContent = fileContent
 
-			if (!diff) {
-				pushToolResult(`No changes needed for '${relPath}'`)
-				return
-			}
+		// Generate and validate diff
+		const diff = formatResponse.createPrettyPatch(validRelPath, fileContent, newContent)
+		if (!diff) {
+			pushToolResult(`No changes needed for '${relPath}'`)
+			await cline.diffViewProvider.reset()
+			return
+		}
 
-			await cline.diffViewProvider.open(relPath)
-			await cline.diffViewProvider.update(newContent, true)
+		// Show changes in diff view
+		if (!cline.diffViewProvider.isEditing) {
+			await cline.ask("tool", JSON.stringify(sharedMessageProps), true).catch(() => {})
+			await cline.diffViewProvider.open(validRelPath)
+			await cline.diffViewProvider.update(fileContent, false)
 			cline.diffViewProvider.scrollToFirstDiff()
+			await delay(200)
+		}
 
-			const completeMessage = JSON.stringify({ ...sharedMessageProps, diff: diff } satisfies ClineSayTool)
-			const didApprove = await askApproval("tool", completeMessage)
+		await cline.diffViewProvider.update(newContent, true)
 
-			if (!didApprove) {
-				await cline.diffViewProvider.revertChanges() // cline likely handles closing the diff view
-				return
-			}
+		// Request user approval for changes
+		const completeMessage = JSON.stringify({ ...sharedMessageProps, diff } satisfies ClineSayTool)
+		const didApprove = await cline
+			.ask("tool", completeMessage, false)
+			.then((response) => response.response === "yesButtonClicked")
 
-			const { newProblemsMessage, userEdits, finalContent } = await cline.diffViewProvider.saveChanges()
+		if (!didApprove) {
+			await cline.diffViewProvider.revertChanges()
+			pushToolResult("Changes were rejected by the user.")
+			await cline.diffViewProvider.reset()
+			return
+		}
 
-			if (relPath) {
-				await cline.getFileContextTracker().trackFileContext(relPath, "roo_edited" as RecordSource)
-			}
+		const { newProblemsMessage, userEdits, finalContent } = await cline.diffViewProvider.saveChanges()
 
-			cline.didEditFile = true // used to determine if we should wait for busy terminal to update before sending api request
-			if (userEdits) {
-				await cline.say(
-					"user_feedback_diff",
-					JSON.stringify({
-						tool: fileExists ? "editedExistingFile" : "newFileCreated",
-						path: getReadablePath(cline.cwd, relPath),
-						diff: userEdits,
-					} satisfies ClineSayTool),
-				)
-
-				pushToolResult(
-					`The user made the following updates to your content:\n\n${userEdits}\n\n` +
-						`The updated content, which includes both your original modifications and the user's edits, has been successfully saved to ${relPath.toPosix()}. Here is the full, updated content of the file, including line numbers:\n\n` +
-						`<final_file_content path="${relPath.toPosix()}">\n${addLineNumbers(finalContent || "")}\n</final_file_content>\n\n` +
-						`Please note:\n` +
-						`1. You do not need to re-write the file with these changes, as they have already been applied.\n` +
-						`2. Proceed with the task using this updated file content as the new baseline.\n` +
-						`3. If the user's edits have addressed part of the task or changed the requirements, adjust your approach accordingly.` +
-						`${newProblemsMessage}`,
-				)
-			} else {
-				pushToolResult(`Changes successfully applied to ${relPath.toPosix()}:\n\n${newProblemsMessage}`)
-			}
+		// Track file edit operation
+		if (relPath) {
+			await cline.getFileContextTracker().trackFileContext(relPath, "roo_edited" as RecordSource)
+		}
 
-			await cline.diffViewProvider.reset()
+		cline.didEditFile = true
 
+		if (!userEdits) {
+			pushToolResult(`The content was successfully replaced in ${relPath}.${newProblemsMessage}`)
+			await cline.diffViewProvider.reset()
 			return
 		}
+
+		const userFeedbackDiff = JSON.stringify({
+			tool: "appliedDiff",
+			path: getReadablePath(cline.cwd, relPath),
+			diff: userEdits,
+		} satisfies ClineSayTool)
+
+		await cline.say("user_feedback_diff", userFeedbackDiff)
+
+		// Format and send response with user's updates
+		const resultMessage = [
+			`The user made the following updates to your content:\n\n${userEdits}\n\n`,
+			`The updated content has been successfully saved to ${validRelPath.toPosix()}. Here is the full, updated content of the file:\n\n`,
+			`<final_file_content path="${validRelPath.toPosix()}">\n${finalContent}\n</final_file_content>\n\n`,
+			`Please note:\n`,
+			`1. You do not need to re-write the file with these changes, as they have already been applied.\n`,
+			`2. Proceed with the task using the updated file content as the new baseline.\n`,
+			`3. If the user's edits have addressed part of the task or changed the requirements, adjust your approach accordingly.`,
+			newProblemsMessage,
+		].join("")
+
+		pushToolResult(resultMessage)
+
+		// Record successful tool usage and cleanup
+		cline.recordToolUsage("search_and_replace")
+		await cline.diffViewProvider.reset()
 	} catch (error) {
-		await handleError("applying search and replace", error)
+		handleError("search and replace", error)
 		await cline.diffViewProvider.reset()
-		return
 	}
 }
 
-function escapeRegExp(string: string): string {
-	return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
+/**
+ * Escapes special regex characters in a string
+ * @param input String to escape regex characters in
+ * @returns Escaped string safe for regex pattern matching
+ */
+function escapeRegExp(input: string): string {
+	return input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
 }

+ 0 - 1
src/exports/roo-code.d.ts

@@ -288,7 +288,6 @@ type GlobalSettings = {
 	fuzzyMatchThreshold?: number | undefined
 	experiments?:
 		| {
-				search_and_replace: boolean
 				insert_content: boolean
 				powerSteering: boolean
 		  }

+ 0 - 1
src/exports/types.ts

@@ -291,7 +291,6 @@ type GlobalSettings = {
 	fuzzyMatchThreshold?: number | undefined
 	experiments?:
 		| {
-				search_and_replace: boolean
 				insert_content: boolean
 				powerSteering: boolean
 		  }

+ 1 - 2
src/schemas/index.ts

@@ -277,7 +277,7 @@ export type CustomSupportPrompts = z.infer<typeof customSupportPromptsSchema>
  * ExperimentId
  */
 
-export const experimentIds = ["search_and_replace", "insert_content", "powerSteering"] as const
+export const experimentIds = ["insert_content", "powerSteering"] as const
 
 export const experimentIdsSchema = z.enum(experimentIds)
 
@@ -288,7 +288,6 @@ export type ExperimentId = z.infer<typeof experimentIdsSchema>
  */
 
 const experimentsSchema = z.object({
-	search_and_replace: z.boolean(),
 	insert_content: z.boolean(),
 	powerSteering: z.boolean(),
 })

+ 7 - 0
src/shared/ExtensionMessage.ts

@@ -224,6 +224,7 @@ export interface ClineSayTool {
 		| "switchMode"
 		| "newTask"
 		| "finishTask"
+		| "searchAndReplace"
 	path?: string
 	diff?: string
 	content?: string
@@ -232,6 +233,12 @@ export interface ClineSayTool {
 	mode?: string
 	reason?: string
 	isOutsideWorkspace?: boolean
+	search?: string
+	replace?: string
+	useRegex?: boolean
+	ignoreCase?: boolean
+	startLine?: number
+	endLine?: number
 }
 
 // Must keep in sync with system prompt.

+ 0 - 3
src/shared/__tests__/experiments.test.ts

@@ -14,7 +14,6 @@ describe("experiments", () => {
 		it("returns false when experiment is not enabled", () => {
 			const experiments: Record<ExperimentId, boolean> = {
 				powerSteering: false,
-				search_and_replace: false,
 				insert_content: false,
 			}
 			expect(Experiments.isEnabled(experiments, EXPERIMENT_IDS.POWER_STEERING)).toBe(false)
@@ -23,7 +22,6 @@ describe("experiments", () => {
 		it("returns true when experiment is enabled", () => {
 			const experiments: Record<ExperimentId, boolean> = {
 				powerSteering: true,
-				search_and_replace: false,
 				insert_content: false,
 			}
 			expect(Experiments.isEnabled(experiments, EXPERIMENT_IDS.POWER_STEERING)).toBe(true)
@@ -31,7 +29,6 @@ describe("experiments", () => {
 
 		it("returns false when experiment is not present", () => {
 			const experiments: Record<ExperimentId, boolean> = {
-				search_and_replace: false,
 				insert_content: false,
 				powerSteering: false,
 			}

+ 0 - 25
src/shared/__tests__/modes.test.ts

@@ -258,21 +258,9 @@ describe("isToolAllowedForMode", () => {
 	describe("experimental tools", () => {
 		it("disables tools when experiment is disabled", () => {
 			const experiments = {
-				search_and_replace: false,
 				insert_content: false,
 			}
 
-			expect(
-				isToolAllowedForMode(
-					"search_and_replace",
-					"test-exp-mode",
-					customModes,
-					undefined,
-					undefined,
-					experiments,
-				),
-			).toBe(false)
-
 			expect(
 				isToolAllowedForMode("insert_content", "test-exp-mode", customModes, undefined, undefined, experiments),
 			).toBe(false)
@@ -280,21 +268,9 @@ describe("isToolAllowedForMode", () => {
 
 		it("allows tools when experiment is enabled", () => {
 			const experiments = {
-				search_and_replace: true,
 				insert_content: true,
 			}
 
-			expect(
-				isToolAllowedForMode(
-					"search_and_replace",
-					"test-exp-mode",
-					customModes,
-					undefined,
-					undefined,
-					experiments,
-				),
-			).toBe(true)
-
 			expect(
 				isToolAllowedForMode("insert_content", "test-exp-mode", customModes, undefined, undefined, experiments),
 			).toBe(true)
@@ -302,7 +278,6 @@ describe("isToolAllowedForMode", () => {
 
 		it("allows non-experimental tools when experiments are disabled", () => {
 			const experiments = {
-				search_and_replace: false,
 				insert_content: false,
 			}
 

+ 0 - 2
src/shared/experiments.ts

@@ -5,7 +5,6 @@ export type { ExperimentId }
 
 export const EXPERIMENT_IDS = {
 	INSERT_BLOCK: "insert_content",
-	SEARCH_AND_REPLACE: "search_and_replace",
 	POWER_STEERING: "powerSteering",
 } as const satisfies Record<string, ExperimentId>
 
@@ -19,7 +18,6 @@ interface ExperimentConfig {
 
 export const experimentConfigsMap: Record<ExperimentKey, ExperimentConfig> = {
 	INSERT_BLOCK: { enabled: false },
-	SEARCH_AND_REPLACE: { enabled: false },
 	POWER_STEERING: { enabled: false },
 }
 

+ 12 - 0
src/shared/tools.ts

@@ -56,6 +56,12 @@ export const toolParamNames = [
 	"follow_up",
 	"task",
 	"size",
+	"search",
+	"replace",
+	"use_regex",
+	"ignore_case",
+	"start_line",
+	"end_line",
 ] as const
 
 export type ToolParamName = (typeof toolParamNames)[number]
@@ -144,6 +150,12 @@ export interface NewTaskToolUse extends ToolUse {
 	params: Partial<Pick<Record<ToolParamName, string>, "mode" | "message">>
 }
 
+export interface SearchAndReplaceToolUse extends ToolUse {
+	name: "search_and_replace"
+	params: Required<Pick<Record<ToolParamName, string>, "path" | "search" | "replace">> &
+		Partial<Pick<Record<ToolParamName, string>, "use_regex" | "ignore_case" | "start_line" | "end_line">>
+}
+
 // Define tool group configuration
 export type ToolGroupConfig = {
 	tools: readonly string[]

+ 43 - 0
webview-ui/src/components/chat/ChatRow.tsx

@@ -295,6 +295,49 @@ export const ChatRowContent = ({
 						/>
 					</>
 				)
+			case "searchAndReplace":
+				return (
+					<>
+						<div className="flex items-center gap-2.5 mb-2.5">
+							{toolIcon("replace")}
+							<span className="font-bold">
+								{message.type === "ask"
+									? t("chat:fileOperations.wantsToSearchReplace")
+									: t("chat:fileOperations.didSearchReplace")}
+							</span>
+						</div>
+						<div className="mb-2.5">
+							<div className="flex items-center gap-2.5 mb-1.5">
+								<span className="text-vscode-descriptionForeground">Search:</span>
+								<code>{tool.search}</code>
+								{tool.useRegex && <span className="text-vscode-descriptionForeground">(regex)</span>}
+								{tool.ignoreCase && (
+									<span className="text-vscode-descriptionForeground">(case-insensitive)</span>
+								)}
+							</div>
+							<div className="flex items-center gap-2.5 mb-1.5">
+								<span className="text-vscode-descriptionForeground">Replace:</span>
+								<code>{tool.replace}</code>
+							</div>
+							{(tool.startLine !== undefined || tool.endLine !== undefined) && (
+								<div className="flex items-center gap-2.5">
+									<span className="text-vscode-descriptionForeground">Lines:</span>
+									<code>
+										{tool.startLine ?? 1} - {tool.endLine ?? "end"}
+									</code>
+								</div>
+							)}
+						</div>
+						<CodeAccordian
+							progressStatus={message.progressStatus}
+							isLoading={message.partial}
+							diff={tool.diff!}
+							path={tool.path!}
+							isExpanded={isExpanded}
+							onToggleExpand={onToggleExpand}
+						/>
+					</>
+				)
 			case "newFileCreated":
 				return (
 					<>

+ 1 - 1
webview-ui/src/components/chat/ChatView.tsx

@@ -629,7 +629,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
 				return true
 			}
 			const tool = JSON.parse(message.text)
-			return ["editedExistingFile", "appliedDiff", "newFileCreated"].includes(tool.tool)
+			return ["editedExistingFile", "appliedDiff", "newFileCreated", "searchAndReplace"].includes(tool.tool)
 		}
 		return false
 	}, [])

+ 0 - 2
webview-ui/src/context/__tests__/ExtensionStateContext.test.tsx

@@ -208,7 +208,6 @@ describe("mergeExtensionState", () => {
 			...baseState,
 			apiConfiguration: { modelMaxTokens: 1234, modelMaxThinkingTokens: 123 },
 			experiments: {
-				search_and_replace: true,
 				insert_content: true,
 			} as Record<ExperimentId, boolean>,
 		}
@@ -229,7 +228,6 @@ describe("mergeExtensionState", () => {
 		})
 
 		expect(result.experiments).toEqual({
-			search_and_replace: true,
 			insert_content: true,
 			powerSteering: true,
 		})

+ 3 - 1
webview-ui/src/i18n/locales/ca/chat.json

@@ -120,7 +120,9 @@
 		"didRead": "Roo ha llegit aquest fitxer:",
 		"wantsToEdit": "Roo vol editar aquest fitxer:",
 		"wantsToEditOutsideWorkspace": "Roo vol editar aquest fitxer fora de l'espai de treball:",
-		"wantsToCreate": "Roo vol crear un nou fitxer:"
+		"wantsToCreate": "Roo vol crear un nou fitxer:",
+		"wantsToSearchReplace": "Roo vol realitzar cerca i substitució en aquest fitxer:",
+		"didSearchReplace": "Roo ha realitzat cerca i substitució en aquest fitxer:"
 	},
 	"directoryOperations": {
 		"wantsToViewTopLevel": "Roo vol veure els fitxers de nivell superior en aquest directori:",

+ 3 - 1
webview-ui/src/i18n/locales/de/chat.json

@@ -120,7 +120,9 @@
 		"didRead": "Roo hat diese Datei gelesen:",
 		"wantsToEdit": "Roo möchte diese Datei bearbeiten:",
 		"wantsToEditOutsideWorkspace": "Roo möchte diese Datei außerhalb des Arbeitsbereichs bearbeiten:",
-		"wantsToCreate": "Roo möchte eine neue Datei erstellen:"
+		"wantsToCreate": "Roo möchte eine neue Datei erstellen:",
+		"wantsToSearchReplace": "Roo möchte Suchen und Ersetzen in dieser Datei durchführen:",
+		"didSearchReplace": "Roo hat Suchen und Ersetzen in dieser Datei durchgeführt:"
 	},
 	"directoryOperations": {
 		"wantsToViewTopLevel": "Roo möchte die Dateien auf oberster Ebene in diesem Verzeichnis anzeigen:",

+ 3 - 1
webview-ui/src/i18n/locales/en/chat.json

@@ -115,7 +115,9 @@
 		"didRead": "Roo read this file:",
 		"wantsToEdit": "Roo wants to edit this file:",
 		"wantsToEditOutsideWorkspace": "Roo wants to edit this file outside of the workspace:",
-		"wantsToCreate": "Roo wants to create a new file:"
+		"wantsToCreate": "Roo wants to create a new file:",
+		"wantsToSearchReplace": "Roo wants to perform search and replace on this file:",
+		"didSearchReplace": "Roo performed search and replace on this file:"
 	},
 	"directoryOperations": {
 		"wantsToViewTopLevel": "Roo wants to view the top level files in this directory:",

+ 3 - 1
webview-ui/src/i18n/locales/es/chat.json

@@ -120,7 +120,9 @@
 		"didRead": "Roo leyó este archivo:",
 		"wantsToEdit": "Roo quiere editar este archivo:",
 		"wantsToEditOutsideWorkspace": "Roo quiere editar este archivo fuera del espacio de trabajo:",
-		"wantsToCreate": "Roo quiere crear un nuevo archivo:"
+		"wantsToCreate": "Roo quiere crear un nuevo archivo:",
+		"wantsToSearchReplace": "Roo quiere realizar búsqueda y reemplazo en este archivo:",
+		"didSearchReplace": "Roo realizó búsqueda y reemplazo en este archivo:"
 	},
 	"directoryOperations": {
 		"wantsToViewTopLevel": "Roo quiere ver los archivos de nivel superior en este directorio:",

+ 3 - 1
webview-ui/src/i18n/locales/fr/chat.json

@@ -117,7 +117,9 @@
 		"didRead": "Roo a lu ce fichier :",
 		"wantsToEdit": "Roo veut éditer ce fichier :",
 		"wantsToEditOutsideWorkspace": "Roo veut éditer ce fichier en dehors de l'espace de travail :",
-		"wantsToCreate": "Roo veut créer un nouveau fichier :"
+		"wantsToCreate": "Roo veut créer un nouveau fichier :",
+		"wantsToSearchReplace": "Roo veut effectuer une recherche et remplacement sur ce fichier :",
+		"didSearchReplace": "Roo a effectué une recherche et remplacement sur ce fichier :"
 	},
 	"instructions": {
 		"wantsToFetch": "Roo veut récupérer des instructions détaillées pour aider à la tâche actuelle"

+ 3 - 1
webview-ui/src/i18n/locales/hi/chat.json

@@ -120,7 +120,9 @@
 		"didRead": "Roo ने इस फ़ाइल को पढ़ा:",
 		"wantsToEdit": "Roo इस फ़ाइल को संपादित करना चाहता है:",
 		"wantsToEditOutsideWorkspace": "Roo कार्यक्षेत्र के बाहर इस फ़ाइल को संपादित करना चाहता है:",
-		"wantsToCreate": "Roo एक नई फ़ाइल बनाना चाहता है:"
+		"wantsToCreate": "Roo एक नई फ़ाइल बनाना चाहता है:",
+		"wantsToSearchReplace": "Roo इस फ़ाइल में खोज और प्रतिस्थापन करना चाहता है:",
+		"didSearchReplace": "Roo ने इस फ़ाइल में खोज और प्रतिस्थापन किया:"
 	},
 	"directoryOperations": {
 		"wantsToViewTopLevel": "Roo इस निर्देशिका में शीर्ष स्तर की फ़ाइलें देखना चाहता है:",

+ 3 - 1
webview-ui/src/i18n/locales/it/chat.json

@@ -120,7 +120,9 @@
 		"didRead": "Roo ha letto questo file:",
 		"wantsToEdit": "Roo vuole modificare questo file:",
 		"wantsToEditOutsideWorkspace": "Roo vuole modificare questo file al di fuori dell'area di lavoro:",
-		"wantsToCreate": "Roo vuole creare un nuovo file:"
+		"wantsToCreate": "Roo vuole creare un nuovo file:",
+		"wantsToSearchReplace": "Roo vuole eseguire ricerca e sostituzione in questo file:",
+		"didSearchReplace": "Roo ha eseguito ricerca e sostituzione in questo file:"
 	},
 	"directoryOperations": {
 		"wantsToViewTopLevel": "Roo vuole visualizzare i file di primo livello in questa directory:",

+ 3 - 1
webview-ui/src/i18n/locales/ja/chat.json

@@ -120,7 +120,9 @@
 		"didRead": "Rooはこのファイルを読みました:",
 		"wantsToEdit": "Rooはこのファイルを編集したい:",
 		"wantsToEditOutsideWorkspace": "Rooはワークスペース外のこのファイルを編集したい:",
-		"wantsToCreate": "Rooは新しいファイルを作成したい:"
+		"wantsToCreate": "Rooは新しいファイルを作成したい:",
+		"wantsToSearchReplace": "Rooはこのファイルで検索と置換を実行したい:",
+		"didSearchReplace": "Rooはこのファイルで検索と置換を実行しました:"
 	},
 	"directoryOperations": {
 		"wantsToViewTopLevel": "Rooはこのディレクトリのトップレベルファイルを表示したい:",

+ 3 - 1
webview-ui/src/i18n/locales/ko/chat.json

@@ -120,7 +120,9 @@
 		"didRead": "Roo가 이 파일을 읽었습니다:",
 		"wantsToEdit": "Roo가 이 파일을 편집하고 싶어합니다:",
 		"wantsToEditOutsideWorkspace": "Roo가 워크스페이스 외부의 이 파일을 편집하고 싶어합니다:",
-		"wantsToCreate": "Roo가 새 파일을 만들고 싶어합니다:"
+		"wantsToCreate": "Roo가 새 파일을 만들고 싶어합니다:",
+		"wantsToSearchReplace": "Roo가 이 파일에서 검색 및 바꾸기를 수행하고 싶어합니다:",
+		"didSearchReplace": "Roo가 이 파일에서 검색 및 바꾸기를 수행했습니다:"
 	},
 	"directoryOperations": {
 		"wantsToViewTopLevel": "Roo가 이 디렉토리의 최상위 파일을 보고 싶어합니다:",

+ 3 - 1
webview-ui/src/i18n/locales/pl/chat.json

@@ -120,7 +120,9 @@
 		"didRead": "Roo przeczytał ten plik:",
 		"wantsToEdit": "Roo chce edytować ten plik:",
 		"wantsToEditOutsideWorkspace": "Roo chce edytować ten plik poza obszarem roboczym:",
-		"wantsToCreate": "Roo chce utworzyć nowy plik:"
+		"wantsToCreate": "Roo chce utworzyć nowy plik:",
+		"wantsToSearchReplace": "Roo chce wykonać wyszukiwanie i zamianę w tym pliku:",
+		"didSearchReplace": "Roo wykonał wyszukiwanie i zamianę w tym pliku:"
 	},
 	"directoryOperations": {
 		"wantsToViewTopLevel": "Roo chce zobaczyć pliki najwyższego poziomu w tym katalogu:",

+ 3 - 1
webview-ui/src/i18n/locales/pt-BR/chat.json

@@ -120,7 +120,9 @@
 		"didRead": "Roo leu este arquivo:",
 		"wantsToEdit": "Roo quer editar este arquivo:",
 		"wantsToEditOutsideWorkspace": "Roo quer editar este arquivo fora do espaço de trabalho:",
-		"wantsToCreate": "Roo quer criar um novo arquivo:"
+		"wantsToCreate": "Roo quer criar um novo arquivo:",
+		"wantsToSearchReplace": "Roo quer realizar busca e substituição neste arquivo:",
+		"didSearchReplace": "Roo realizou busca e substituição neste arquivo:"
 	},
 	"directoryOperations": {
 		"wantsToViewTopLevel": "Roo quer visualizar os arquivos de nível superior neste diretório:",

+ 3 - 1
webview-ui/src/i18n/locales/tr/chat.json

@@ -120,7 +120,9 @@
 		"didRead": "Roo bu dosyayı okudu:",
 		"wantsToEdit": "Roo bu dosyayı düzenlemek istiyor:",
 		"wantsToEditOutsideWorkspace": "Roo çalışma alanı dışındaki bu dosyayı düzenlemek istiyor:",
-		"wantsToCreate": "Roo yeni bir dosya oluşturmak istiyor:"
+		"wantsToCreate": "Roo yeni bir dosya oluşturmak istiyor:",
+		"wantsToSearchReplace": "Roo bu dosyada arama ve değiştirme yapmak istiyor:",
+		"didSearchReplace": "Roo bu dosyada arama ve değiştirme yaptı:"
 	},
 	"directoryOperations": {
 		"wantsToViewTopLevel": "Roo bu dizindeki üst düzey dosyaları görüntülemek istiyor:",

+ 3 - 1
webview-ui/src/i18n/locales/vi/chat.json

@@ -120,7 +120,9 @@
 		"didRead": "Roo đã đọc tệp này:",
 		"wantsToEdit": "Roo muốn chỉnh sửa tệp này:",
 		"wantsToEditOutsideWorkspace": "Roo muốn chỉnh sửa tệp này bên ngoài không gian làm việc:",
-		"wantsToCreate": "Roo muốn tạo một tệp mới:"
+		"wantsToCreate": "Roo muốn tạo một tệp mới:",
+		"wantsToSearchReplace": "Roo muốn thực hiện tìm kiếm và thay thế trong tệp này:",
+		"didSearchReplace": "Roo đã thực hiện tìm kiếm và thay thế trong tệp này:"
 	},
 	"directoryOperations": {
 		"wantsToViewTopLevel": "Roo muốn xem các tệp cấp cao nhất trong thư mục này:",

+ 3 - 1
webview-ui/src/i18n/locales/zh-CN/chat.json

@@ -120,7 +120,9 @@
 		"didRead": "已读取文件:",
 		"wantsToEdit": "需要编辑文件:",
 		"wantsToEditOutsideWorkspace": "需要编辑外部文件:",
-		"wantsToCreate": "需要新建文件:"
+		"wantsToCreate": "需要新建文件:",
+		"wantsToSearchReplace": "需要执行搜索和替换:",
+		"didSearchReplace": "已完成搜索和替换:"
 	},
 	"directoryOperations": {
 		"wantsToViewTopLevel": "需要查看目录文件列表:",

+ 3 - 1
webview-ui/src/i18n/locales/zh-TW/chat.json

@@ -120,7 +120,9 @@
 		"didRead": "Roo 已讀取此檔案:",
 		"wantsToEdit": "Roo 想要編輯此檔案:",
 		"wantsToEditOutsideWorkspace": "Roo 想要編輯此工作區外的檔案:",
-		"wantsToCreate": "Roo 想要建立新檔案:"
+		"wantsToCreate": "Roo 想要建立新檔案:",
+		"wantsToSearchReplace": "Roo 想要在此檔案執行搜尋和取代:",
+		"didSearchReplace": "Roo 已在此檔案執行搜尋和取代:"
 	},
 	"directoryOperations": {
 		"wantsToViewTopLevel": "Roo 想要檢視此目錄中最上層的檔案:",