diff --git a/src/core/tools/applyDiffTool.ts b/src/core/tools/applyDiffTool.ts index d18adaa8d0..43de5af988 100644 --- a/src/core/tools/applyDiffTool.ts +++ b/src/core/tools/applyDiffTool.ts @@ -11,7 +11,7 @@ import path from "path" import fs from "fs/promises" import { RecordSource } from "../context-tracking/FileContextTrackerTypes" import { telemetryService } from "../../services/telemetry/TelemetryService" - +import { unescapeHtmlEntities } from "../../utils/text-normalization" export async function applyDiffTool( cline: Cline, block: ToolUse, @@ -21,7 +21,11 @@ export async function applyDiffTool( removeClosingTag: RemoveClosingTag, ) { const relPath: string | undefined = block.params.path - const diffContent: string | undefined = block.params.diff + let diffContent: string | undefined = block.params.diff + + if (diffContent && !cline.api.getModel().id.includes("claude")) { + diffContent = unescapeHtmlEntities(diffContent) + } const sharedMessageProps: ClineSayTool = { tool: "appliedDiff", diff --git a/src/core/tools/executeCommandTool.ts b/src/core/tools/executeCommandTool.ts index 79f89f092d..5a70c657ac 100644 --- a/src/core/tools/executeCommandTool.ts +++ b/src/core/tools/executeCommandTool.ts @@ -2,6 +2,7 @@ import { Cline } from "../Cline" import { ToolUse } from "../assistant-message" import { AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "./types" import { formatResponse } from "../prompts/responses" +import { unescapeHtmlEntities } from "../../utils/text-normalization" export async function executeCommandTool( cline: Cline, @@ -32,8 +33,8 @@ export async function executeCommandTool( return } - // unescape html entities (e.g. < -> <) - command = command.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&") + // Unescape HTML entities + command = unescapeHtmlEntities(command) cline.consecutiveMistakeCount = 0 diff --git a/src/core/tools/writeToFileTool.ts b/src/core/tools/writeToFileTool.ts index 25f3a72df2..6a012537f6 100644 --- a/src/core/tools/writeToFileTool.ts +++ b/src/core/tools/writeToFileTool.ts @@ -14,6 +14,7 @@ import { isPathOutsideWorkspace } from "../../utils/pathUtils" import { everyLineHasLineNumbers } from "../../integrations/misc/extract-text" import delay from "delay" import { detectCodeOmission } from "../../integrations/editor/detect-omission" +import { unescapeHtmlEntities } from "../../utils/text-normalization" export async function writeToFileTool( cline: Cline, @@ -60,13 +61,7 @@ export async function writeToFileTool( } if (!cline.api.getModel().id.includes("claude")) { - // it seems not just llama models are doing cline, but also gemini and potentially others - if (newContent.includes(">") || newContent.includes("<") || newContent.includes(""")) { - newContent = newContent - .replace(/>/g, ">") - .replace(/</g, "<") - .replace(/"/g, '"') - } + newContent = unescapeHtmlEntities(newContent) } // Determine if the path is outside the workspace diff --git a/src/utils/__tests__/text-normalization.test.ts b/src/utils/__tests__/text-normalization.test.ts index da7184d889..5908ffc55b 100644 --- a/src/utils/__tests__/text-normalization.test.ts +++ b/src/utils/__tests__/text-normalization.test.ts @@ -1,4 +1,4 @@ -import { normalizeString } from "../text-normalization" +import { normalizeString, unescapeHtmlEntities } from "../text-normalization" describe("Text normalization utilities", () => { describe("normalizeString", () => { @@ -30,4 +30,50 @@ describe("Text normalization utilities", () => { expect(normalizeString(input)).toBe('Let\'s test this-with some "fancy" punctuation... and spaces') }) }) + + describe("unescapeHtmlEntities", () => { + test("unescapes basic HTML entities", () => { + expect(unescapeHtmlEntities("<div>Hello</div>")).toBe("