diff --git a/src/main/providers/local-pty-utils-windows-fallback.test.ts b/src/main/providers/local-pty-utils-windows-fallback.test.ts index 48b35cd27c0..0de16d03f17 100644 --- a/src/main/providers/local-pty-utils-windows-fallback.test.ts +++ b/src/main/providers/local-pty-utils-windows-fallback.test.ts @@ -76,13 +76,13 @@ describe('spawnShellWithFallback on Windows', () => { 1, PWSH7, attempts[0].shellArgs, - expect.objectContaining({ cwd: 'C:\\repo' }) + expect.objectContaining({ cwd: 'C:\\repo', useConptyDll: true }) ) expect(ptySpawn).toHaveBeenNthCalledWith( 2, WINDOWS_POWERSHELL, attempts[1].shellArgs, - expect.objectContaining({ cwd: 'C:\\repo' }) + expect.objectContaining({ cwd: 'C:\\repo', useConptyDll: true }) ) }) diff --git a/src/main/providers/local-pty-utils.ts b/src/main/providers/local-pty-utils.ts index 0ad6effc9c9..c8eb87c249d 100644 --- a/src/main/providers/local-pty-utils.ts +++ b/src/main/providers/local-pty-utils.ts @@ -160,6 +160,14 @@ export type ShellSpawnResult = { * executables with per-shell args, so when the primary fails we retry with the * next safe shell instead of leaving the user with no terminal. */ +// Why: match the daemon spawn path (pty-subprocess.ts) — the bundled ConPTY +// has the modern wrap-marker behavior xterm expects; legacy system ConPTY can +// corrupt full-width TUI rows in scrollback. Without this, degraded-mode and +// fresh-local spawns silently behave differently from daemon terminals. +function windowsConptyDllOptions(): { useConptyDll: true } | Record { + return process.platform === 'win32' ? { useConptyDll: true } : {} +} + function spawnWindowsFallbackChain( params: ShellSpawnParams, primaryError: string @@ -174,7 +182,8 @@ function spawnWindowsFallbackChain( cols, rows, cwd: attempt.effectiveCwd, - env + env, + ...windowsConptyDllOptions() }) console.warn( `[pty] Primary shell "${params.shellPath}" failed (${primaryError}), fell back to "${attempt.shellPath}"` @@ -217,7 +226,14 @@ export function spawnShellWithFallback(params: ShellSpawnParams): ShellSpawnResu if (!primaryError) { try { return { - process: ptySpawn(shellPath, shellArgs, { name: termName, cols, rows, cwd, env }), + process: ptySpawn(shellPath, shellArgs, { + name: termName, + cols, + rows, + cwd, + env, + ...windowsConptyDllOptions() + }), shellPath } } catch (err) {