searchFilesTool.ts 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import path from "path"
  2. import { Task } from "../task/Task"
  3. import { ToolUse, AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "../../shared/tools"
  4. import { ClineSayTool } from "../../shared/ExtensionMessage"
  5. import { getReadablePath } from "../../utils/path"
  6. import { isPathOutsideWorkspace } from "../../utils/pathUtils"
  7. import { regexSearchFiles } from "../../services/ripgrep"
  8. export async function searchFilesTool(
  9. cline: Task,
  10. block: ToolUse,
  11. askApproval: AskApproval,
  12. handleError: HandleError,
  13. pushToolResult: PushToolResult,
  14. removeClosingTag: RemoveClosingTag,
  15. ) {
  16. const relDirPath: string | undefined = block.params.path
  17. const regex: string | undefined = block.params.regex
  18. const filePattern: string | undefined = block.params.file_pattern
  19. const absolutePath = relDirPath ? path.resolve(cline.cwd, relDirPath) : cline.cwd
  20. const isOutsideWorkspace = isPathOutsideWorkspace(absolutePath)
  21. const sharedMessageProps: ClineSayTool = {
  22. tool: "searchFiles",
  23. path: getReadablePath(cline.cwd, removeClosingTag("path", relDirPath)),
  24. regex: removeClosingTag("regex", regex),
  25. filePattern: removeClosingTag("file_pattern", filePattern),
  26. isOutsideWorkspace,
  27. }
  28. try {
  29. if (block.partial) {
  30. const partialMessage = JSON.stringify({ ...sharedMessageProps, content: "" } satisfies ClineSayTool)
  31. await cline.ask("tool", partialMessage, block.partial).catch(() => {})
  32. return
  33. } else {
  34. if (!relDirPath) {
  35. cline.consecutiveMistakeCount++
  36. cline.recordToolError("search_files")
  37. pushToolResult(await cline.sayAndCreateMissingParamError("search_files", "path"))
  38. return
  39. }
  40. if (!regex) {
  41. cline.consecutiveMistakeCount++
  42. cline.recordToolError("search_files")
  43. pushToolResult(await cline.sayAndCreateMissingParamError("search_files", "regex"))
  44. return
  45. }
  46. cline.consecutiveMistakeCount = 0
  47. const results = await regexSearchFiles(
  48. cline.cwd,
  49. absolutePath,
  50. regex,
  51. filePattern,
  52. cline.rooIgnoreController,
  53. )
  54. const completeMessage = JSON.stringify({ ...sharedMessageProps, content: results } satisfies ClineSayTool)
  55. const didApprove = await askApproval("tool", completeMessage)
  56. if (!didApprove) {
  57. return
  58. }
  59. pushToolResult(results)
  60. return
  61. }
  62. } catch (error) {
  63. await handleError("searching files", error)
  64. return
  65. }
  66. }