From f30e88e9a9cb8c4f65693396f49a9fb4de1f2ef9 Mon Sep 17 00:00:00 2001 From: Roo Code Date: Mon, 6 Oct 2025 13:05:36 +0000 Subject: [PATCH 1/2] fix: add UTF-8 encoding support for VSCode terminal output on Windows - Add LANG and LC_ALL environment variables set to en_US.UTF-8 - Add Windows-specific CHCP=65001 for UTF-8 code page support - Update tests to verify UTF-8 encoding environment variables - This fixes non-ASCII characters (Cyrillic, Chinese, Hindi, etc.) being displayed as '?' or diamond symbols Fixes #8530 --- src/integrations/terminal/Terminal.ts | 11 +++++ .../__tests__/TerminalRegistry.spec.ts | 43 +++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/src/integrations/terminal/Terminal.ts b/src/integrations/terminal/Terminal.ts index 8bf2072f3d..3a2abdd2bb 100644 --- a/src/integrations/terminal/Terminal.ts +++ b/src/integrations/terminal/Terminal.ts @@ -157,6 +157,17 @@ export class Terminal extends BaseTerminal { // VTE must be disabled because it prevents the prompt command from executing // See https://wiki.gnome.org/Apps/Terminal/VTE VTE_VERSION: "0", + + // Ensure UTF-8 encoding for proper Unicode character display + // This fixes issues with non-ASCII characters (Cyrillic, Chinese, Hindi, etc.) + // being displayed as "?" or diamond symbols in terminal output + LANG: "en_US.UTF-8", + LC_ALL: "en_US.UTF-8", + } + + // On Windows, set the code page to UTF-8 (65001) for proper Unicode support + if (process.platform === "win32") { + env.CHCP = "65001" } // Set Oh My Zsh shell integration if enabled diff --git a/src/integrations/terminal/__tests__/TerminalRegistry.spec.ts b/src/integrations/terminal/__tests__/TerminalRegistry.spec.ts index d3912caf47..0d18ca24ec 100644 --- a/src/integrations/terminal/__tests__/TerminalRegistry.spec.ts +++ b/src/integrations/terminal/__tests__/TerminalRegistry.spec.ts @@ -48,6 +48,8 @@ describe("TerminalRegistry", () => { PAGER, VTE_VERSION: "0", PROMPT_EOL_MARK: "", + LANG: "en_US.UTF-8", + LC_ALL: "en_US.UTF-8", }, }) }) @@ -69,6 +71,8 @@ describe("TerminalRegistry", () => { PROMPT_COMMAND: "sleep 0.05", VTE_VERSION: "0", PROMPT_EOL_MARK: "", + LANG: "en_US.UTF-8", + LC_ALL: "en_US.UTF-8", }, }) } finally { @@ -91,6 +95,8 @@ describe("TerminalRegistry", () => { VTE_VERSION: "0", PROMPT_EOL_MARK: "", ITERM_SHELL_INTEGRATION_INSTALLED: "Yes", + LANG: "en_US.UTF-8", + LC_ALL: "en_US.UTF-8", }, }) } finally { @@ -112,11 +118,48 @@ describe("TerminalRegistry", () => { VTE_VERSION: "0", PROMPT_EOL_MARK: "", POWERLEVEL9K_TERM_SHELL_INTEGRATION: "true", + LANG: "en_US.UTF-8", + LC_ALL: "en_US.UTF-8", }, }) } finally { Terminal.setTerminalZshP10k(false) } }) + + it("adds CHCP=65001 on Windows for UTF-8 support", () => { + // Mock platform as Windows + const originalPlatform = process.platform + Object.defineProperty(process, "platform", { + value: "win32", + writable: true, + configurable: true, + }) + + try { + TerminalRegistry.createTerminal("/test/path", "vscode") + + expect(mockCreateTerminal).toHaveBeenCalledWith({ + cwd: "/test/path", + name: "Roo Code", + iconPath: expect.any(Object), + env: { + PAGER: "", + VTE_VERSION: "0", + PROMPT_EOL_MARK: "", + LANG: "en_US.UTF-8", + LC_ALL: "en_US.UTF-8", + CHCP: "65001", + }, + }) + } finally { + // Restore original platform + Object.defineProperty(process, "platform", { + value: originalPlatform, + writable: true, + configurable: true, + }) + } + }) }) }) From 1781e3f58d4fe48280e40aefe2b84d05bd2e6cf7 Mon Sep 17 00:00:00 2001 From: Roo Code Date: Mon, 6 Oct 2025 13:09:33 +0000 Subject: [PATCH 2/2] fix: properly implement UTF-8 support for Windows terminals - Add LANG and LC_ALL environment variables for UTF-8 encoding - Prepend 'chcp 65001' command on Windows to set code page to UTF-8 - Handle both PowerShell and CMD syntax for code page switching - Remove incorrect CHCP environment variable approach - Update tests to reflect the corrected implementation This properly fixes non-ASCII characters (Cyrillic, Chinese, Hindi, etc.) being displayed as '?' or diamond symbols in terminal output on Windows. Fixes #8530 --- src/integrations/terminal/Terminal.ts | 5 --- src/integrations/terminal/TerminalProcess.ts | 22 ++++++++---- .../__tests__/TerminalRegistry.spec.ts | 35 ------------------- 3 files changed, 16 insertions(+), 46 deletions(-) diff --git a/src/integrations/terminal/Terminal.ts b/src/integrations/terminal/Terminal.ts index 3a2abdd2bb..bfeae3e8f8 100644 --- a/src/integrations/terminal/Terminal.ts +++ b/src/integrations/terminal/Terminal.ts @@ -165,11 +165,6 @@ export class Terminal extends BaseTerminal { LC_ALL: "en_US.UTF-8", } - // On Windows, set the code page to UTF-8 (65001) for proper Unicode support - if (process.platform === "win32") { - env.CHCP = "65001" - } - // Set Oh My Zsh shell integration if enabled if (Terminal.getTerminalZshOhMy()) { env.ITERM_SHELL_INTEGRATION_INSTALLED = "Yes" diff --git a/src/integrations/terminal/TerminalProcess.ts b/src/integrations/terminal/TerminalProcess.ts index eb0424fe8d..fe45f2f427 100644 --- a/src/integrations/terminal/TerminalProcess.ts +++ b/src/integrations/terminal/TerminalProcess.ts @@ -114,9 +114,21 @@ export class TerminalProcess extends BaseTerminalProcess { (defaultWindowsShellProfile === null || (defaultWindowsShellProfile as string)?.toLowerCase().includes("powershell")) - if (isPowerShell) { - let commandToExecute = command + let commandToExecute = command + + // On Windows, prepend chcp 65001 to set UTF-8 code page for proper Unicode support + // This fixes issues with non-ASCII characters being displayed as "?" or diamond symbols + if (process.platform === "win32") { + if (isPowerShell) { + // PowerShell syntax: use semicolon to chain commands and redirect output to null + commandToExecute = `chcp 65001 > $null ; ${command}` + } else { + // CMD syntax: use && to chain commands and redirect output to nul + commandToExecute = `chcp 65001 > nul && ${command}` + } + } + if (isPowerShell) { // Only add the PowerShell counter workaround if enabled if (Terminal.getPowershellCounter()) { commandToExecute += ` ; "(Roo/PS Workaround: ${this.terminal.cmdCounter++})" > $null` @@ -126,12 +138,10 @@ export class TerminalProcess extends BaseTerminalProcess { if (Terminal.getCommandDelay() > 0) { commandToExecute += ` ; start-sleep -milliseconds ${Terminal.getCommandDelay()}` } - - terminal.shellIntegration.executeCommand(commandToExecute) - } else { - terminal.shellIntegration.executeCommand(command) } + terminal.shellIntegration.executeCommand(commandToExecute) + this.isHot = true // Wait for stream to be available diff --git a/src/integrations/terminal/__tests__/TerminalRegistry.spec.ts b/src/integrations/terminal/__tests__/TerminalRegistry.spec.ts index 0d18ca24ec..657433f23a 100644 --- a/src/integrations/terminal/__tests__/TerminalRegistry.spec.ts +++ b/src/integrations/terminal/__tests__/TerminalRegistry.spec.ts @@ -126,40 +126,5 @@ describe("TerminalRegistry", () => { Terminal.setTerminalZshP10k(false) } }) - - it("adds CHCP=65001 on Windows for UTF-8 support", () => { - // Mock platform as Windows - const originalPlatform = process.platform - Object.defineProperty(process, "platform", { - value: "win32", - writable: true, - configurable: true, - }) - - try { - TerminalRegistry.createTerminal("/test/path", "vscode") - - expect(mockCreateTerminal).toHaveBeenCalledWith({ - cwd: "/test/path", - name: "Roo Code", - iconPath: expect.any(Object), - env: { - PAGER: "", - VTE_VERSION: "0", - PROMPT_EOL_MARK: "", - LANG: "en_US.UTF-8", - LC_ALL: "en_US.UTF-8", - CHCP: "65001", - }, - }) - } finally { - // Restore original platform - Object.defineProperty(process, "platform", { - value: originalPlatform, - writable: true, - configurable: true, - }) - } - }) }) })