diff --git a/src/core/Cline.ts b/src/core/Cline.ts index 620ff96f9d..bd82b86bb8 100644 --- a/src/core/Cline.ts +++ b/src/core/Cline.ts @@ -90,6 +90,7 @@ import { applyDiffTool } from "./tools/applyDiffTool" import { insertContentTool } from "./tools/insertContentTool" import { searchAndReplaceTool } from "./tools/searchAndReplaceTool" import { listCodeDefinitionNamesTool } from "./tools/listCodeDefinitionNamesTool" +import { searchFilesTool } from "./tools/searchFilesTool" export type ToolResponse = string | Array type UserContent = Array @@ -1608,58 +1609,8 @@ export class Cline extends EventEmitter { ) break case "search_files": { - const relDirPath: string | undefined = block.params.path - const regex: string | undefined = block.params.regex - const filePattern: string | undefined = block.params.file_pattern - const sharedMessageProps: ClineSayTool = { - tool: "searchFiles", - path: getReadablePath(this.cwd, removeClosingTag("path", relDirPath)), - regex: removeClosingTag("regex", regex), - filePattern: removeClosingTag("file_pattern", filePattern), - } - try { - if (block.partial) { - const partialMessage = JSON.stringify({ - ...sharedMessageProps, - content: "", - } satisfies ClineSayTool) - await this.ask("tool", partialMessage, block.partial).catch(() => {}) - break - } else { - if (!relDirPath) { - this.consecutiveMistakeCount++ - pushToolResult(await this.sayAndCreateMissingParamError("search_files", "path")) - break - } - if (!regex) { - this.consecutiveMistakeCount++ - pushToolResult(await this.sayAndCreateMissingParamError("search_files", "regex")) - break - } - this.consecutiveMistakeCount = 0 - const absolutePath = path.resolve(this.cwd, relDirPath) - const results = await regexSearchFiles( - this.cwd, - absolutePath, - regex, - filePattern, - this.rooIgnoreController, - ) - const completeMessage = JSON.stringify({ - ...sharedMessageProps, - content: results, - } satisfies ClineSayTool) - const didApprove = await askApproval("tool", completeMessage) - if (!didApprove) { - break - } - pushToolResult(results) - break - } - } catch (error) { - await handleError("searching files", error) - break - } + await searchFilesTool(this, block, askApproval, handleError, pushToolResult, removeClosingTag) + break } case "browser_action": { const action: BrowserAction | undefined = block.params.action as BrowserAction diff --git a/src/core/tools/searchFilesTool.ts b/src/core/tools/searchFilesTool.ts new file mode 100644 index 0000000000..e3659da9a1 --- /dev/null +++ b/src/core/tools/searchFilesTool.ts @@ -0,0 +1,69 @@ +import { Cline } from "../Cline" +import { ToolUse } from "../assistant-message" +import { AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "./types" +import { ClineSayTool } from "../../shared/ExtensionMessage" +import { getReadablePath } from "../../utils/path" +import path from "path" +import { regexSearchFiles } from "../../services/ripgrep" + +export async function searchFilesTool( + cline: Cline, + block: ToolUse, + askApproval: AskApproval, + handleError: HandleError, + pushToolResult: PushToolResult, + removeClosingTag: RemoveClosingTag, +) { + const relDirPath: string | undefined = block.params.path + const regex: string | undefined = block.params.regex + const filePattern: string | undefined = block.params.file_pattern + const sharedMessageProps: ClineSayTool = { + tool: "searchFiles", + path: getReadablePath(cline.cwd, removeClosingTag("path", relDirPath)), + regex: removeClosingTag("regex", regex), + filePattern: removeClosingTag("file_pattern", filePattern), + } + try { + if (block.partial) { + const partialMessage = JSON.stringify({ + ...sharedMessageProps, + content: "", + } satisfies ClineSayTool) + await cline.ask("tool", partialMessage, block.partial).catch(() => {}) + return + } else { + if (!relDirPath) { + cline.consecutiveMistakeCount++ + pushToolResult(await cline.sayAndCreateMissingParamError("search_files", "path")) + return + } + if (!regex) { + cline.consecutiveMistakeCount++ + pushToolResult(await cline.sayAndCreateMissingParamError("search_files", "regex")) + return + } + cline.consecutiveMistakeCount = 0 + const absolutePath = path.resolve(cline.cwd, relDirPath) + const results = await regexSearchFiles( + cline.cwd, + absolutePath, + regex, + filePattern, + cline.rooIgnoreController, + ) + const completeMessage = JSON.stringify({ + ...sharedMessageProps, + content: results, + } satisfies ClineSayTool) + const didApprove = await askApproval("tool", completeMessage) + if (!didApprove) { + return + } + pushToolResult(results) + return + } + } catch (error) { + await handleError("searching files", error) + return + } +}