(task: Task, block: ToolUse<"write_to_file">)
| 194 | } |
| 195 | |
| 196 | override async handlePartial(task: Task, block: ToolUse<"write_to_file">): Promise<void> { |
| 197 | const relPath: string | undefined = block.params.path |
| 198 | const newContent: string | undefined = block.params.content |
| 199 | |
| 200 | // Wait for path to stabilize before showing UI (prevents truncated paths) |
| 201 | if (!this.hasPathStabilized(relPath) || newContent === undefined) { |
| 202 | return |
| 203 | } |
| 204 | |
| 205 | const provider = task.providerRef.deref() |
| 206 | const state = await provider?.getState() |
| 207 | const isPreventFocusDisruptionEnabled = experiments.isEnabled( |
| 208 | state?.experiments ?? {}, |
| 209 | EXPERIMENT_IDS.PREVENT_FOCUS_DISRUPTION, |
| 210 | ) |
| 211 | |
| 212 | if (isPreventFocusDisruptionEnabled) { |
| 213 | return |
| 214 | } |
| 215 | |
| 216 | // relPath is guaranteed non-null after hasPathStabilized |
| 217 | let fileExists: boolean |
| 218 | const absolutePath = path.resolve(task.cwd, relPath!) |
| 219 | |
| 220 | if (task.diffViewProvider.editType !== undefined) { |
| 221 | fileExists = task.diffViewProvider.editType === "modify" |
| 222 | } else { |
| 223 | fileExists = await fileExistsAtPath(absolutePath) |
| 224 | task.diffViewProvider.editType = fileExists ? "modify" : "create" |
| 225 | } |
| 226 | |
| 227 | // Create parent directories early for new files to prevent ENOENT errors |
| 228 | // in subsequent operations (e.g., diffViewProvider.open) |
| 229 | if (!fileExists) { |
| 230 | await createDirectoriesForFile(absolutePath) |
| 231 | } |
| 232 | |
| 233 | const isWriteProtected = task.rooProtectedController?.isWriteProtected(relPath!) || false |
| 234 | const isOutsideWorkspace = isPathOutsideWorkspace(absolutePath) |
| 235 | |
| 236 | const sharedMessageProps: ClineSayTool = { |
| 237 | tool: fileExists ? "editedExistingFile" : "newFileCreated", |
| 238 | path: getReadablePath(task.cwd, relPath!), |
| 239 | content: newContent || "", |
| 240 | isOutsideWorkspace, |
| 241 | isProtected: isWriteProtected, |
| 242 | } |
| 243 | |
| 244 | const partialMessage = JSON.stringify(sharedMessageProps) |
| 245 | await task.ask("tool", partialMessage, block.partial).catch(() => {}) |
| 246 | |
| 247 | if (newContent) { |
| 248 | if (!task.diffViewProvider.isEditing) { |
| 249 | await task.diffViewProvider.open(relPath!) |
| 250 | } |
| 251 | |
| 252 | await task.diffViewProvider.update( |
| 253 | everyLineHasLineNumbers(newContent) ? stripLineNumbers(newContent) : newContent, |
nothing calls this directly
no test coverage detected