(params: WriteToFileParams, task: Task, callbacks: ToolCallbacks)
| 27 | readonly name = "write_to_file" as const |
| 28 | |
| 29 | async execute(params: WriteToFileParams, task: Task, callbacks: ToolCallbacks): Promise<void> { |
| 30 | const { pushToolResult, handleError, askApproval } = callbacks |
| 31 | const relPath = params.path |
| 32 | let newContent = params.content |
| 33 | |
| 34 | if (!relPath) { |
| 35 | task.consecutiveMistakeCount++ |
| 36 | task.recordToolError("write_to_file") |
| 37 | pushToolResult(await task.sayAndCreateMissingParamError("write_to_file", "path")) |
| 38 | await task.diffViewProvider.reset() |
| 39 | return |
| 40 | } |
| 41 | |
| 42 | if (newContent === undefined) { |
| 43 | task.consecutiveMistakeCount++ |
| 44 | task.recordToolError("write_to_file") |
| 45 | pushToolResult(await task.sayAndCreateMissingParamError("write_to_file", "content")) |
| 46 | await task.diffViewProvider.reset() |
| 47 | return |
| 48 | } |
| 49 | |
| 50 | const accessAllowed = task.rooIgnoreController?.validateAccess(relPath) |
| 51 | |
| 52 | if (!accessAllowed) { |
| 53 | await task.say("rooignore_error", relPath) |
| 54 | pushToolResult(formatResponse.rooIgnoreError(relPath)) |
| 55 | return |
| 56 | } |
| 57 | |
| 58 | const isWriteProtected = task.rooProtectedController?.isWriteProtected(relPath) || false |
| 59 | |
| 60 | let fileExists: boolean |
| 61 | const absolutePath = path.resolve(task.cwd, relPath) |
| 62 | |
| 63 | if (task.diffViewProvider.editType !== undefined) { |
| 64 | fileExists = task.diffViewProvider.editType === "modify" |
| 65 | } else { |
| 66 | fileExists = await fileExistsAtPath(absolutePath) |
| 67 | task.diffViewProvider.editType = fileExists ? "modify" : "create" |
| 68 | } |
| 69 | |
| 70 | // Create parent directories early for new files to prevent ENOENT errors |
| 71 | // in subsequent operations (e.g., diffViewProvider.open, fs.readFile) |
| 72 | if (!fileExists) { |
| 73 | await createDirectoriesForFile(absolutePath) |
| 74 | } |
| 75 | |
| 76 | if (newContent.startsWith("```")) { |
| 77 | newContent = newContent.split("\n").slice(1).join("\n") |
| 78 | } |
| 79 | |
| 80 | if (newContent.endsWith("```")) { |
| 81 | newContent = newContent.split("\n").slice(0, -1).join("\n") |
| 82 | } |
| 83 | |
| 84 | if (!task.api.getModel().id.includes("claude")) { |
| 85 | newContent = unescapeHtmlEntities(newContent) |
| 86 | } |
nothing calls this directly
no test coverage detected