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, + }) + } + }) }) })