From 048bf6e51459f629d9e242e670a2e6d3abdd992b Mon Sep 17 00:00:00 2001 From: Tommaso Sciortino Date: Fri, 24 Apr 2026 13:30:00 -0700 Subject: [PATCH] fix(cli-ui): revert backspace handling to fix Windows regression (#25941) --- .../src/ui/components/SettingsDialog.test.tsx | 2 +- .../shared/BaseSettingsDialog.test.tsx | 2 +- .../src/ui/contexts/KeypressContext.test.tsx | 86 +------------------ .../cli/src/ui/contexts/KeypressContext.tsx | 16 +--- 4 files changed, 5 insertions(+), 101 deletions(-) diff --git a/packages/cli/src/ui/components/SettingsDialog.test.tsx b/packages/cli/src/ui/components/SettingsDialog.test.tsx index 7ba451d538..9887415a57 100644 --- a/packages/cli/src/ui/components/SettingsDialog.test.tsx +++ b/packages/cli/src/ui/components/SettingsDialog.test.tsx @@ -44,7 +44,7 @@ enum TerminalKeys { LEFT_ARROW = '\u001B[D', RIGHT_ARROW = '\u001B[C', ESCAPE = '\u001B', - BACKSPACE = '\x7f', + BACKSPACE = '\u0008', CTRL_P = '\u0010', CTRL_N = '\u000E', } diff --git a/packages/cli/src/ui/components/shared/BaseSettingsDialog.test.tsx b/packages/cli/src/ui/components/shared/BaseSettingsDialog.test.tsx index c49c967714..f66af9fd17 100644 --- a/packages/cli/src/ui/components/shared/BaseSettingsDialog.test.tsx +++ b/packages/cli/src/ui/components/shared/BaseSettingsDialog.test.tsx @@ -24,7 +24,7 @@ enum TerminalKeys { LEFT_ARROW = '\u001B[D', RIGHT_ARROW = '\u001B[C', ESCAPE = '\u001B', - BACKSPACE = '\x7f', + BACKSPACE = '\u0008', CTRL_L = '\u000C', } diff --git a/packages/cli/src/ui/contexts/KeypressContext.test.tsx b/packages/cli/src/ui/contexts/KeypressContext.test.tsx index 26f1c1cf35..e7d0406dd7 100644 --- a/packages/cli/src/ui/contexts/KeypressContext.test.tsx +++ b/packages/cli/src/ui/contexts/KeypressContext.test.tsx @@ -9,17 +9,7 @@ import { act } from 'react'; import { renderHookWithProviders } from '../../test-utils/render.js'; import { createMockSettings } from '../../test-utils/settings.js'; import { waitFor } from '../../test-utils/async.js'; -import type { Mock } from 'vitest'; -import { - vi, - afterAll, - beforeAll, - describe, - it, - expect, - beforeEach, - afterEach, -} from 'vitest'; +import { vi, afterAll, beforeAll, type Mock } from 'vitest'; import { useKeypressContext, ESC_TIMEOUT, @@ -441,80 +431,6 @@ describe('KeypressContext', () => { ); }); - describe('Windows Terminal Backspace handling', () => { - afterEach(() => { - vi.unstubAllEnvs(); - }); - - it('should NOT treat \\b as ctrl when WT_SESSION is NOT present and OS is not Windows_NT', async () => { - vi.stubEnv('WT_SESSION', ''); - vi.stubEnv('OS', 'Linux'); - const { keyHandler } = await setupKeypressTest(); - - act(() => { - stdin.write('\b'); - }); - - expect(keyHandler).toHaveBeenCalledWith( - expect.objectContaining({ - name: 'backspace', - ctrl: false, - }), - ); - }); - - it('should treat \\b as ctrl when WT_SESSION IS present (even if not Windows_NT)', async () => { - vi.stubEnv('WT_SESSION', 'some-id'); - vi.stubEnv('OS', 'Linux'); - const { keyHandler } = await setupKeypressTest(); - - act(() => { - stdin.write('\b'); - }); - - expect(keyHandler).toHaveBeenCalledWith( - expect.objectContaining({ - name: 'backspace', - ctrl: true, - }), - ); - }); - - it('should treat \\b as ctrl when OS is Windows_NT', async () => { - vi.stubEnv('WT_SESSION', ''); - vi.stubEnv('OS', 'Windows_NT'); - const { keyHandler } = await setupKeypressTest(); - - act(() => { - stdin.write('\b'); - }); - - expect(keyHandler).toHaveBeenCalledWith( - expect.objectContaining({ - name: 'backspace', - ctrl: true, - }), - ); - }); - - it('should treat \\x7f as regular backspace regardless of WT_SESSION or OS', async () => { - vi.stubEnv('WT_SESSION', 'some-id'); - vi.stubEnv('OS', 'Windows_NT'); - const { keyHandler } = await setupKeypressTest(); - - act(() => { - stdin.write('\x7f'); - }); - - expect(keyHandler).toHaveBeenCalledWith( - expect.objectContaining({ - name: 'backspace', - ctrl: false, - }), - ); - }); - }); - describe('paste mode', () => { it.each([ { diff --git a/packages/cli/src/ui/contexts/KeypressContext.tsx b/packages/cli/src/ui/contexts/KeypressContext.tsx index d834608fbe..3a3961221f 100644 --- a/packages/cli/src/ui/contexts/KeypressContext.tsx +++ b/packages/cli/src/ui/contexts/KeypressContext.tsx @@ -651,20 +651,8 @@ function* emitKeys( // tab name = 'tab'; alt = escaped; - } else if (ch === '\b') { - // ctrl+h / ctrl+backspace (windows terminals send \x08 for ctrl+backspace) - name = 'backspace'; - // In Windows environments, \b is sent for Ctrl+Backspace (standard backspace is translated to \x7f). - // We scope this to Windows/WT_SESSION to avoid breaking other unixes where \b is a plain backspace. - if ( - typeof process !== 'undefined' && - (process.env?.['OS'] === 'Windows_NT' || !!process.env?.['WT_SESSION']) - ) { - ctrl = true; - } - alt = escaped; - } else if (ch === '\x7f') { - // backspace + } else if (ch === '\b' || ch === '\x7f') { + // backspace or ctrl+h name = 'backspace'; alt = escaped; } else if (ch === ESC) {