From 9b6490c5447c902bf80555c2baadb5de8e8e0b6e Mon Sep 17 00:00:00 2001 From: Mark Griffin Date: Tue, 18 Aug 2026 16:02:53 +0100 Subject: [PATCH] fix(shared): repair stale Windows PATH capture --- packages/shared/src/shell.test.ts | 22 ++++++++++++++++++++++ packages/shared/src/shell.ts | 14 ++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/packages/shared/src/shell.test.ts b/packages/shared/src/shell.test.ts index 89ec055f599e..1626b929ba42 100644 --- a/packages/shared/src/shell.test.ts +++ b/packages/shared/src/shell.test.ts @@ -238,6 +238,28 @@ describe("readEnvironmentFromWindowsShell", () => { ); }); + it("captures the persisted Windows PATH scopes after the process PATH", () => { + const execFile = vi.fn< + ( + file: string, + args: ReadonlyArray, + options: { encoding: "utf8"; timeout: number }, + ) => string + >( + () => + "__T3CODE_ENV_PATH_START__\nC:\\Windows\\System32;C:\\Program Files\\nodejs;C:\\Users\\testuser\\AppData\\Local\\Microsoft\\WinGet\\Links\n__T3CODE_ENV_PATH_END__\n", + ); + + expect(readEnvironmentFromWindowsShell(["PATH"], execFile)).toEqual({ + PATH: "C:\\Windows\\System32;C:\\Program Files\\nodejs;C:\\Users\\testuser\\AppData\\Local\\Microsoft\\WinGet\\Links", + }); + + const command = execFile.mock.calls[0]?.[1]?.at(-1); + expect(command).toContain("GetEnvironmentVariable('PATH', 'Process')"); + expect(command).toContain("GetEnvironmentVariable('PATH', 'Machine')"); + expect(command).toContain("GetEnvironmentVariable('PATH', 'User')"); + }); + it("strips CRLF delimiters from captured PowerShell values", () => { const execFile = vi.fn< ( diff --git a/packages/shared/src/shell.ts b/packages/shared/src/shell.ts index da6db2166765..b0da67068fc5 100644 --- a/packages/shared/src/shell.ts +++ b/packages/shared/src/shell.ts @@ -269,10 +269,20 @@ function buildWindowsEnvironmentCaptureCommand(names: ReadonlyArray): st throw new Error(`Unsupported environment variable name: ${name}`); } + const readValue = + name === "PATH" + ? [ + `$value = @([Environment]::GetEnvironmentVariable('${name}', 'Process'), [Environment]::GetEnvironmentVariable('${name}', 'Machine'), [Environment]::GetEnvironmentVariable('${name}', 'User')) | Where-Object { $null -ne $_ -and $_.Length -gt 0 }`, + "if (@($value).Count -gt 0) { Write-Output ($value -join ';') }", + ] + : [ + `$value = [Environment]::GetEnvironmentVariable('${name}')`, + "if ($null -ne $value -and $value.Length -gt 0) { Write-Output $value }", + ]; + return [ `Write-Output '${envCaptureStart(name)}'`, - `$value = [Environment]::GetEnvironmentVariable('${name}')`, - "if ($null -ne $value -and $value.Length -gt 0) { Write-Output $value }", + ...readValue, `Write-Output '${envCaptureEnd(name)}'`, ]; }),