diff --git a/package-lock.json b/package-lock.json index b7e12732..fe7291bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,7 @@ }, "devDependencies": { "@types/mime-types": "^2.1.4", + "@types/minimatch": "^5.1.2", "@vitest/coverage-v8": "^3.1.1", "esbuild": "^0.25.4", "eslint": "^9.24.0", diff --git a/package.json b/package.json index 483cd711..44e784ad 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ ], "devDependencies": { "@types/mime-types": "^2.1.4", + "@types/minimatch": "^5.1.2", "@vitest/coverage-v8": "^3.1.1", "esbuild": "^0.25.4", "eslint": "^9.24.0", @@ -55,13 +56,12 @@ "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", "globals": "^16.0.0", + "json": "^11.0.0", "lodash": "^4.17.21", "memfs": "^4.17.2", "prettier": "^3.5.3", "react-devtools-core": "^4.28.5", "typescript-eslint": "^8.30.1", - "yargs": "^17.7.2", - "json": "^11.0.0" - }, - "dependencies": {} + "yargs": "^17.7.2" + } } diff --git a/packages/core/src/tools/edit.test.ts b/packages/core/src/tools/edit.test.ts index 87ae3b6f..603128bc 100644 --- a/packages/core/src/tools/edit.test.ts +++ b/packages/core/src/tools/edit.test.ts @@ -547,4 +547,57 @@ describe('EditTool', () => { ); }); }); + + describe('getDescription', () => { + it('should return "No file changes to..." if old_string and new_string are the same', () => { + const testFileName = 'test.txt'; + const params: EditToolParams = { + file_path: path.join(rootDir, testFileName), + old_string: 'identical_string', + new_string: 'identical_string', + }; + // shortenPath will be called internally, resulting in just the file name + expect(tool.getDescription(params)).toBe( + `No file changes to ${testFileName}`, + ); + }); + + it('should return a snippet of old and new strings if they are different', () => { + const testFileName = 'test.txt'; + const params: EditToolParams = { + file_path: path.join(rootDir, testFileName), + old_string: 'this is the old string value', + new_string: 'this is the new string value', + }; + // shortenPath will be called internally, resulting in just the file name + // The snippets are truncated at 30 chars + '...' + expect(tool.getDescription(params)).toBe( + `${testFileName}: this is the old string value => this is the new string value`, + ); + }); + + it('should handle very short strings correctly in the description', () => { + const testFileName = 'short.txt'; + const params: EditToolParams = { + file_path: path.join(rootDir, testFileName), + old_string: 'old', + new_string: 'new', + }; + expect(tool.getDescription(params)).toBe(`${testFileName}: old => new`); + }); + + it('should truncate long strings in the description', () => { + const testFileName = 'long.txt'; + const params: EditToolParams = { + file_path: path.join(rootDir, testFileName), + old_string: + 'this is a very long old string that will definitely be truncated', + new_string: + 'this is a very long new string that will also be truncated', + }; + expect(tool.getDescription(params)).toBe( + `${testFileName}: this is a very long old string... => this is a very long new string...`, + ); + }); + }); }); diff --git a/packages/core/src/tools/edit.ts b/packages/core/src/tools/edit.ts index e02ee1c8..5e488bcd 100644 --- a/packages/core/src/tools/edit.ts +++ b/packages/core/src/tools/edit.ts @@ -379,6 +379,9 @@ Expectation for required parameters: params.new_string.split('\n')[0].substring(0, 30) + (params.new_string.length > 30 ? '...' : ''); + if (params.old_string === params.new_string) { + return `No file changes to ${shortenPath(relativePath)}`; + } return `${shortenPath(relativePath)}: ${oldStringSnippet} => ${newStringSnippet}`; }