Răsfoiți Sursa

Strip BOM when applying diffs

Matt Rubens 9 luni în urmă
părinte
comite
4cf7754e65

+ 2 - 1
jest.config.js

@@ -30,9 +30,10 @@ module.exports = {
 		"^strip-ansi$": "<rootDir>/src/__mocks__/strip-ansi.js",
 		"^default-shell$": "<rootDir>/src/__mocks__/default-shell.js",
 		"^os-name$": "<rootDir>/src/__mocks__/os-name.js",
+		"^strip-bom$": "<rootDir>/src/__mocks__/strip-bom.js",
 	},
 	transformIgnorePatterns: [
-		"node_modules/(?!(@modelcontextprotocol|delay|p-wait-for|globby|serialize-error|strip-ansi|default-shell|os-name)/)",
+		"node_modules/(?!(@modelcontextprotocol|delay|p-wait-for|globby|serialize-error|strip-ansi|default-shell|os-name|strip-bom)/)",
 	],
 	roots: ["<rootDir>/src", "<rootDir>/webview-ui/src"],
 	modulePathIgnorePatterns: [".vscode-test"],

+ 17 - 5
package-lock.json

@@ -51,6 +51,7 @@
 				"sound-play": "^1.1.0",
 				"string-similarity": "^4.0.4",
 				"strip-ansi": "^7.1.0",
+				"strip-bom": "^5.0.0",
 				"tmp": "^0.2.3",
 				"tree-sitter-wasms": "^0.1.11",
 				"turndown": "^7.2.0",
@@ -10782,6 +10783,15 @@
 				"node": ">=8"
 			}
 		},
+		"node_modules/jest-runtime/node_modules/strip-bom": {
+			"version": "4.0.0",
+			"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
+			"integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
+			"dev": true,
+			"engines": {
+				"node": ">=8"
+			}
+		},
 		"node_modules/jest-simple-dot-reporter": {
 			"version": "1.0.5",
 			"resolved": "https://registry.npmjs.org/jest-simple-dot-reporter/-/jest-simple-dot-reporter-1.0.5.tgz",
@@ -14170,12 +14180,14 @@
 			}
 		},
 		"node_modules/strip-bom": {
-			"version": "4.0.0",
-			"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
-			"integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
-			"dev": true,
+			"version": "5.0.0",
+			"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-5.0.0.tgz",
+			"integrity": "sha512-p+byADHF7SzEcVnLvc/r3uognM1hUhObuHXxJcgLCfD194XAkaLbjq3Wzb0N5G2tgIjH0dgT708Z51QxMeu60A==",
 			"engines": {
-				"node": ">=8"
+				"node": ">=12"
+			},
+			"funding": {
+				"url": "https://github.com/sponsors/sindresorhus"
 			}
 		},
 		"node_modules/strip-final-newline": {

+ 2 - 1
package.json

@@ -265,8 +265,8 @@
 		"@anthropic-ai/sdk": "^0.37.0",
 		"@anthropic-ai/vertex-sdk": "^0.7.0",
 		"@aws-sdk/client-bedrock-runtime": "^3.706.0",
-		"@google/generative-ai": "^0.18.0",
 		"@google-cloud/vertexai": "^1.9.3",
+		"@google/generative-ai": "^0.18.0",
 		"@mistralai/mistralai": "^1.3.6",
 		"@modelcontextprotocol/sdk": "^1.0.1",
 		"@types/clone-deep": "^4.0.4",
@@ -304,6 +304,7 @@
 		"sound-play": "^1.1.0",
 		"string-similarity": "^4.0.4",
 		"strip-ansi": "^7.1.0",
+		"strip-bom": "^5.0.0",
 		"tmp": "^0.2.3",
 		"tree-sitter-wasms": "^0.1.11",
 		"turndown": "^7.2.0",

+ 13 - 0
src/__mocks__/strip-bom.js

@@ -0,0 +1,13 @@
+// Mock implementation of strip-bom
+module.exports = function stripBom(string) {
+	if (typeof string !== "string") {
+		throw new TypeError("Expected a string")
+	}
+
+	// Removes UTF-8 BOM
+	if (string.charCodeAt(0) === 0xfeff) {
+		return string.slice(1)
+	}
+
+	return string
+}

+ 7 - 2
src/integrations/editor/DiffViewProvider.ts

@@ -7,6 +7,7 @@ import { formatResponse } from "../../core/prompts/responses"
 import { DecorationController } from "./DecorationController"
 import * as diff from "diff"
 import { diagnosticsToProblemsString, getNewDiagnostics } from "../diagnostics"
+import stripBom from "strip-bom"
 
 export const DIFF_VIEW_URI_SCHEME = "cline-diff"
 
@@ -104,7 +105,7 @@ export class DiffViewProvider {
 		const edit = new vscode.WorkspaceEdit()
 		const rangeToReplace = new vscode.Range(0, 0, endLine + 1, 0)
 		const contentToReplace = accumulatedLines.slice(0, endLine + 1).join("\n") + "\n"
-		edit.replace(document.uri, rangeToReplace, contentToReplace)
+		edit.replace(document.uri, rangeToReplace, stripBom(stripBom(contentToReplace)))
 		await vscode.workspace.applyEdit(edit)
 		// Update decorations
 		this.activeLineController.setActiveLine(endLine)
@@ -128,7 +129,11 @@ export class DiffViewProvider {
 			}
 			// Apply the final content
 			const finalEdit = new vscode.WorkspaceEdit()
-			finalEdit.replace(document.uri, new vscode.Range(0, 0, document.lineCount, 0), accumulatedContent)
+			finalEdit.replace(
+				document.uri,
+				new vscode.Range(0, 0, document.lineCount, 0),
+				stripBom(stripBom(accumulatedContent)),
+			)
 			await vscode.workspace.applyEdit(finalEdit)
 			// Clear all decorations at the end (after applying final edit)
 			this.fadedOverlayController.clear()