From 763492d3603ee881024d09232466f701876aeafb Mon Sep 17 00:00:00 2001 From: Matt Rubens Date: Wed, 10 Sep 2025 16:55:08 -0400 Subject: [PATCH 1/4] Bust cache in generated image preview --- .../tools/__tests__/generateImageTool.test.ts | 49 +++++++++++++++++++ src/core/tools/generateImageTool.ts | 6 ++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/core/tools/__tests__/generateImageTool.test.ts b/src/core/tools/__tests__/generateImageTool.test.ts index 0a12bebbe2..3abcd04237 100644 --- a/src/core/tools/__tests__/generateImageTool.test.ts +++ b/src/core/tools/__tests__/generateImageTool.test.ts @@ -163,6 +163,55 @@ describe("generateImageTool", () => { expect(mockGenerateImage).toHaveBeenCalled() expect(mockPushToolResult).toHaveBeenCalled() }) + + it("should add cache-busting parameter to image URI", async () => { + const completeBlock: ToolUse = { + type: "tool_use", + name: "generate_image", + params: { + prompt: "Generate a test image", + path: "test-image.png", + }, + partial: false, + } + + // Mock convertToWebviewUri to return a test URI + const mockWebviewUri = "https://file+.vscode-resource.vscode-cdn.net/test/workspace/test-image.png" + mockCline.providerRef.deref().convertToWebviewUri = vi.fn().mockReturnValue(mockWebviewUri) + + // Mock the OpenRouterHandler generateImage method + const mockGenerateImage = vi.fn().mockResolvedValue({ + success: true, + imageData: "data:image/png;base64,fakebase64data", + }) + + vi.mocked(OpenRouterHandler).mockImplementation( + () => + ({ + generateImage: mockGenerateImage, + }) as any, + ) + + await generateImageTool( + mockCline as Task, + completeBlock, + mockAskApproval, + mockHandleError, + mockPushToolResult, + mockRemoveClosingTag, + ) + + // Check that cline.say was called with image data containing cache-busting parameter + expect(mockCline.say).toHaveBeenCalledWith("image", expect.stringMatching(/"imageUri":"[^"]+\?t=\d+"/)) + + // Verify the imageUri contains the cache-busting parameter + const sayCall = mockCline.say.mock.calls.find((call: any[]) => call[0] === "image") + if (sayCall) { + const imageData = JSON.parse(sayCall[1]) + expect(imageData.imageUri).toMatch(/\?t=\d+$/) + expect(imageData.imagePath).toBe("/test/workspace/test-image.png") + } + }) }) describe("missing parameters", () => { diff --git a/src/core/tools/generateImageTool.ts b/src/core/tools/generateImageTool.ts index 749e7cff9a..842b5a5efa 100644 --- a/src/core/tools/generateImageTool.ts +++ b/src/core/tools/generateImageTool.ts @@ -244,7 +244,11 @@ export async function generateImageTool( const fullImagePath = path.join(cline.cwd, finalPath) // Convert to webview URI if provider is available - const imageUri = provider?.convertToWebviewUri?.(fullImagePath) ?? vscode.Uri.file(fullImagePath).toString() + let imageUri = provider?.convertToWebviewUri?.(fullImagePath) ?? vscode.Uri.file(fullImagePath).toString() + + // Add cache-busting parameter to prevent browser caching issues + const cacheBuster = Date.now() + imageUri = imageUri.includes("?") ? `${imageUri}&t=${cacheBuster}` : `${imageUri}?t=${cacheBuster}` // Send the image with the webview URI await cline.say("image", JSON.stringify({ imageUri, imagePath: fullImagePath })) From 80876ab77eaf4ea6e25a12752043f5de781f3ad9 Mon Sep 17 00:00:00 2001 From: Roo Code Date: Wed, 10 Sep 2025 21:10:48 +0000 Subject: [PATCH 2/4] fix: normalize path separators for Windows compatibility in generateImageTool - Replace backslashes with forward slashes in imagePath to ensure consistent behavior across platforms - Fixes test failure on Windows where path.join() creates OS-specific separators --- src/core/tools/generateImageTool.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/tools/generateImageTool.ts b/src/core/tools/generateImageTool.ts index 842b5a5efa..3c207522e8 100644 --- a/src/core/tools/generateImageTool.ts +++ b/src/core/tools/generateImageTool.ts @@ -241,7 +241,9 @@ export async function generateImageTool( // Get the webview URI for the image const provider = cline.providerRef.deref() + // Use forward slashes for consistency across platforms in the imagePath const fullImagePath = path.join(cline.cwd, finalPath) + const normalizedImagePath = fullImagePath.replace(/\\/g, "/") // Convert to webview URI if provider is available let imageUri = provider?.convertToWebviewUri?.(fullImagePath) ?? vscode.Uri.file(fullImagePath).toString() @@ -250,8 +252,8 @@ export async function generateImageTool( const cacheBuster = Date.now() imageUri = imageUri.includes("?") ? `${imageUri}&t=${cacheBuster}` : `${imageUri}?t=${cacheBuster}` - // Send the image with the webview URI - await cline.say("image", JSON.stringify({ imageUri, imagePath: fullImagePath })) + // Send the image with the webview URI (use normalized path for consistency) + await cline.say("image", JSON.stringify({ imageUri, imagePath: normalizedImagePath })) pushToolResult(formatResponse.toolResult(getReadablePath(cline.cwd, finalPath))) return From 84962cfddcac5903f2ea38d3100f0cc6e1ccefdb Mon Sep 17 00:00:00 2001 From: Roo Code Date: Wed, 10 Sep 2025 21:15:13 +0000 Subject: [PATCH 3/4] Revert "fix: normalize path separators for Windows compatibility in generateImageTool" This reverts commit 80876ab77eaf4ea6e25a12752043f5de781f3ad9. --- src/core/tools/generateImageTool.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/tools/generateImageTool.ts b/src/core/tools/generateImageTool.ts index 3c207522e8..842b5a5efa 100644 --- a/src/core/tools/generateImageTool.ts +++ b/src/core/tools/generateImageTool.ts @@ -241,9 +241,7 @@ export async function generateImageTool( // Get the webview URI for the image const provider = cline.providerRef.deref() - // Use forward slashes for consistency across platforms in the imagePath const fullImagePath = path.join(cline.cwd, finalPath) - const normalizedImagePath = fullImagePath.replace(/\\/g, "/") // Convert to webview URI if provider is available let imageUri = provider?.convertToWebviewUri?.(fullImagePath) ?? vscode.Uri.file(fullImagePath).toString() @@ -252,8 +250,8 @@ export async function generateImageTool( const cacheBuster = Date.now() imageUri = imageUri.includes("?") ? `${imageUri}&t=${cacheBuster}` : `${imageUri}?t=${cacheBuster}` - // Send the image with the webview URI (use normalized path for consistency) - await cline.say("image", JSON.stringify({ imageUri, imagePath: normalizedImagePath })) + // Send the image with the webview URI + await cline.say("image", JSON.stringify({ imageUri, imagePath: fullImagePath })) pushToolResult(formatResponse.toolResult(getReadablePath(cline.cwd, finalPath))) return From d40af13a7b2c7300a1ea756a758f6a290970613e Mon Sep 17 00:00:00 2001 From: Roo Code Date: Wed, 10 Sep 2025 21:17:40 +0000 Subject: [PATCH 4/4] fix: make generateImageTool test cross-platform compatible - Update test to handle both Unix and Windows path separators - Keep the actual implementation unchanged as it correctly uses OS-specific paths - Test now checks for the appropriate path format based on process.platform --- src/core/tools/__tests__/generateImageTool.test.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/core/tools/__tests__/generateImageTool.test.ts b/src/core/tools/__tests__/generateImageTool.test.ts index 3abcd04237..422300581b 100644 --- a/src/core/tools/__tests__/generateImageTool.test.ts +++ b/src/core/tools/__tests__/generateImageTool.test.ts @@ -209,7 +209,12 @@ describe("generateImageTool", () => { if (sayCall) { const imageData = JSON.parse(sayCall[1]) expect(imageData.imageUri).toMatch(/\?t=\d+$/) - expect(imageData.imagePath).toBe("/test/workspace/test-image.png") + // Handle both Unix and Windows path separators + const expectedPath = + process.platform === "win32" + ? "\\test\\workspace\\test-image.png" + : "/test/workspace/test-image.png" + expect(imageData.imagePath).toBe(expectedPath) } }) })