From cda4280d74580c1e19ac1dfaed59b62b66a881cf Mon Sep 17 00:00:00 2001 From: Shardul Natu <43422294+kiranani@users.noreply.github.com> Date: Thu, 4 Sep 2025 10:20:40 -0700 Subject: [PATCH] fix(diffstats): Always return diff stats from EditTool (#7489) Co-authored-by: Shnatu --- packages/core/src/tools/edit.test.ts | 15 ++++++++++- packages/core/src/tools/edit.ts | 38 +++++++++++----------------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/packages/core/src/tools/edit.test.ts b/packages/core/src/tools/edit.test.ts index 03627dc085..7b98083e31 100644 --- a/packages/core/src/tools/edit.test.ts +++ b/packages/core/src/tools/edit.test.ts @@ -476,7 +476,20 @@ describe('EditTool', () => { expect(result.llmContent).toMatch(/Created new file/); expect(fs.existsSync(newFilePath)).toBe(true); expect(fs.readFileSync(newFilePath, 'utf8')).toBe(fileContent); - expect(result.returnDisplay).toBe(`Created ${newFileName}`); + + const display = result.returnDisplay as FileDiff; + expect(display.fileDiff).toMatch(/\+Content for the new file\./); + expect(display.fileName).toBe(newFileName); + expect((result.returnDisplay as FileDiff).diffStat).toStrictEqual({ + model_added_lines: 1, + model_removed_lines: 0, + model_added_chars: 25, + model_removed_chars: 0, + user_added_lines: 0, + user_removed_lines: 0, + user_added_chars: 0, + user_removed_chars: 0, + }); }); it('should return error if old_string is not found in file', async () => { diff --git a/packages/core/src/tools/edit.ts b/packages/core/src/tools/edit.ts index f3ed36c798..cb0418b1e4 100644 --- a/packages/core/src/tools/edit.ts +++ b/packages/core/src/tools/edit.ts @@ -13,7 +13,6 @@ import type { ToolInvocation, ToolLocation, ToolResult, - ToolResultDisplay, } from './tools.js'; import { BaseDeclarativeTool, Kind, ToolConfirmationOutcome } from './tools.js'; import { ToolErrorType } from './tool-error.js'; @@ -362,7 +361,6 @@ class EditToolInvocation implements ToolInvocation { .getFileSystemService() .writeTextFile(this.params.file_path, editData.newContent); - let displayResult: ToolResultDisplay; const fileName = path.basename(this.params.file_path); const originallyProposedContent = this.params.ai_proposed_content || editData.newContent; @@ -373,27 +371,21 @@ class EditToolInvocation implements ToolInvocation { editData.newContent, ); - if (editData.isNewFile) { - displayResult = `Created ${shortenPath(makeRelative(this.params.file_path, this.config.getTargetDir()))}`; - } else { - // Generate diff for display, even though core logic doesn't technically need it - // The CLI wrapper will use this part of the ToolResult - const fileDiff = Diff.createPatch( - fileName, - editData.currentContent ?? '', // Should not be null here if not isNewFile - editData.newContent, - 'Current', - 'Proposed', - DEFAULT_DIFF_OPTIONS, - ); - displayResult = { - fileDiff, - fileName, - originalContent: editData.currentContent, - newContent: editData.newContent, - diffStat, - }; - } + const fileDiff = Diff.createPatch( + fileName, + editData.currentContent ?? '', // Should not be null here if not isNewFile + editData.newContent, + 'Current', + 'Proposed', + DEFAULT_DIFF_OPTIONS, + ); + const displayResult = { + fileDiff, + fileName, + originalContent: editData.currentContent, + newContent: editData.newContent, + diffStat, + }; // Log file operation for telemetry (without diff_stat to avoid double-counting) const mimetype = getSpecificMimeType(this.params.file_path);