authorgravatar for 73941998+UtkarshUsername@users.noreply.github.comUtkarsh Patil <73941998+UtkarshUsername@users.noreply.github.com> 2026-09-01 05:18:57+05:30
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-08-31 16:48:57-07:00
log929f7e6479d00754dee4e4554b24b25478b8064d
tree3f2f057957ceaca489a8dde5856edb19ac69e283
parent41adccc83e819c286dcdf32cd8b5f55af8bb0b49
signature Signed by PGP key B5690EEEBB952194

fix(shared): preserve Windows shell PATH priority (#8748)


2 files changed, 8 insertions(+), 6 deletions(-)

packages/shared/src/shell.test.ts+5-5
......@@ -460,7 +460,7 @@ effectIt.layer(NodeServices.layer)("resolveSpawnCommand", (it) => {
460460});
461461
462462effectIt.layer(NodeServices.layer)("resolveWindowsEnvironment", (it) => {
463 it.effect("returns the baseline no-profile PATH patch when node is already available", () =>
463 it.effect("uses known CLI directories as a fallback without changing shell PATH priority", () =>
464464 Effect.gen(function* () {
465465 const readEnvironment = vi.fn(
466466 (_names: ReadonlyArray<string>, options?: { loadProfile?: boolean }) =>
......@@ -483,6 +483,8 @@ effectIt.layer(NodeServices.layer)("resolveWindowsEnvironment", (it) => {
483483 ),
484484 ).toEqual({
485485 PATH: [
486 "C:\\Shell\\Bin",
487 "C:\\Windows\\System32",
486488 "C:\\Users\\testuser\\AppData\\Roaming\\npm",
487489 "C:\\Users\\testuser\\AppData\\Local\\Programs\\nodejs",
488490 "C:\\Users\\testuser\\AppData\\Local\\Volta\\bin",
......@@ -490,8 +492,6 @@ effectIt.layer(NodeServices.layer)("resolveWindowsEnvironment", (it) => {
490492 "C:\\Users\\testuser\\.local\\bin",
491493 "C:\\Users\\testuser\\.bun\\bin",
492494 "C:\\Users\\testuser\\scoop\\shims",
493 "C:\\Shell\\Bin",
494 "C:\\Windows\\System32",
495495 ].join(";"),
496496 });
497497 expect(readEnvironment).toHaveBeenCalledTimes(1);
......@@ -532,6 +532,7 @@ effectIt.layer(NodeServices.layer)("resolveWindowsEnvironment", (it) => {
532532 PATH: [
533533 "C:\\Profile\\Node",
534534 "C:\\Windows\\System32",
535 "C:\\Shell\\Bin",
535536 "C:\\Users\\testuser\\AppData\\Roaming\\npm",
536537 "C:\\Users\\testuser\\AppData\\Local\\Programs\\nodejs",
537538 "C:\\Users\\testuser\\AppData\\Local\\Volta\\bin",
......@@ -539,7 +540,6 @@ effectIt.layer(NodeServices.layer)("resolveWindowsEnvironment", (it) => {
539540 "C:\\Users\\testuser\\.local\\bin",
540541 "C:\\Users\\testuser\\.bun\\bin",
541542 "C:\\Users\\testuser\\scoop\\shims",
542 "C:\\Shell\\Bin",
543543 ].join(";"),
544544 FNM_DIR: "C:\\Users\\testuser\\AppData\\Roaming\\fnm",
545545 FNM_MULTISHELL_PATH: "C:\\Users\\testuser\\AppData\\Local\\fnm_multishells\\123",
......@@ -576,11 +576,11 @@ effectIt.layer(NodeServices.layer)("resolveWindowsEnvironment", (it) => {
576576 ),
577577 ).toEqual({
578578 PATH: [
579 "C:\\Windows\\System32",
579580 "C:\\Users\\testuser\\AppData\\Roaming\\npm",
580581 "C:\\Users\\testuser\\.local\\bin",
581582 "C:\\Users\\testuser\\.bun\\bin",
582583 "C:\\Users\\testuser\\scoop\\shims",
583 "C:\\Windows\\System32",
584584 ].join(";"),
585585 FNM_DIR: "C:\\Users\\testuser\\AppData\\Roaming\\fnm",
586586 });
packages/shared/src/shell.ts+3-1
......@@ -728,7 +728,9 @@ export const resolveWindowsEnvironment = Effect.fn("shell.resolveWindowsEnvironm
728728 }).PATH;
729729 const mergedPath = mergePathValues(shellPath, inheritedPath, "win32");
730730 const knownCliPath = resolveKnownWindowsCliDirs(env).join(WINDOWS_PATH_DELIMITER);
731 const baselinePath = mergePathValues(knownCliPath, mergedPath, "win32");
731 // Preserve the order a user's shell uses. These directories fill gaps when
732 // desktop apps launch without the full interactive-shell PATH.
733 const baselinePath = mergePathValues(mergedPath, knownCliPath, "win32");
732734 const baselinePatch: Partial<NodeJS.ProcessEnv> = baselinePath ? { PATH: baselinePath } : {};
733735 const baselineEnv = mergeWindowsEnv(env, baselinePatch);
734736