* Executes the edit operation with the given parameters. * @param params Parameters for the edit operation * @returns Result of the edit operation
(signal: AbortSignal)
| 312 | * @returns Result of the edit operation |
| 313 | */ |
| 314 | async execute(signal: AbortSignal): Promise<ToolResult> { |
| 315 | let editData: CalculatedEdit; |
| 316 | try { |
| 317 | editData = await this.calculateEdit(this.params, signal); |
| 318 | } catch (error) { |
| 319 | const errorMsg = error instanceof Error ? error.message : String(error); |
| 320 | return { |
| 321 | llmContent: `Error preparing edit: ${errorMsg}`, |
| 322 | returnDisplay: `Error preparing edit: ${errorMsg}`, |
| 323 | error: { |
| 324 | message: errorMsg, |
| 325 | type: ToolErrorType.EDIT_PREPARATION_FAILURE, |
| 326 | }, |
| 327 | }; |
| 328 | } |
| 329 | |
| 330 | if (editData.error) { |
| 331 | return { |
| 332 | llmContent: editData.error.raw, |
| 333 | returnDisplay: `Error: ${editData.error.display}`, |
| 334 | error: { |
| 335 | message: editData.error.raw, |
| 336 | type: editData.error.type, |
| 337 | }, |
| 338 | }; |
| 339 | } |
| 340 | |
| 341 | try { |
| 342 | this.ensureParentDirectoriesExist(this.params.file_path); |
| 343 | fs.writeFileSync(this.params.file_path, editData.newContent, 'utf8'); |
| 344 | |
| 345 | let displayResult: ToolResultDisplay; |
| 346 | if (editData.isNewFile) { |
| 347 | displayResult = `Created ${shortenPath(makeRelative(this.params.file_path, this.config.getTargetDir()))}`; |
| 348 | } else { |
| 349 | // Generate diff for display, even though core logic doesn't technically need it |
| 350 | // The CLI wrapper will use this part of the ToolResult |
| 351 | const fileName = path.basename(this.params.file_path); |
| 352 | const fileDiff = Diff.createPatch( |
| 353 | fileName, |
| 354 | editData.currentContent ?? '', // Should not be null here if not isNewFile |
| 355 | editData.newContent, |
| 356 | 'Current', |
| 357 | 'Proposed', |
| 358 | DEFAULT_DIFF_OPTIONS, |
| 359 | ); |
| 360 | const originallyProposedContent = |
| 361 | this.params.ai_proposed_string || this.params.new_string; |
| 362 | const diffStat = getDiffStat( |
| 363 | fileName, |
| 364 | editData.currentContent ?? '', |
| 365 | originallyProposedContent, |
| 366 | this.params.new_string, |
| 367 | ); |
| 368 | displayResult = { |
| 369 | fileDiff, |
| 370 | fileName, |
| 371 | originalContent: editData.currentContent, |
nothing calls this directly
no test coverage detected