From cadd271a078993cc5adcfcd11ef8564ef7449a76 Mon Sep 17 00:00:00 2001 From: Serendeep Date: Sat, 22 Aug 2026 13:04:23 +0200 Subject: [PATCH 1/2] fix(shared): hydrate PATH with Nushell login shells --- packages/shared/src/shell.test.ts | 20 ++++++++++++++++++++ packages/shared/src/shell.ts | 17 ++++++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/packages/shared/src/shell.test.ts b/packages/shared/src/shell.test.ts index 89ec055f599e..34a797ca0002 100644 --- a/packages/shared/src/shell.test.ts +++ b/packages/shared/src/shell.test.ts @@ -122,6 +122,26 @@ describe("readPathFromLaunchctl", () => { }); describe("readEnvironmentFromLoginShell", () => { + it("uses Nushell-compatible syntax for a nu login shell", () => { + const execFile = vi.fn< + ( + file: string, + args: ReadonlyArray, + options: { encoding: "utf8"; timeout: number }, + ) => string + >(() => "__T3CODE_ENV_PATH_START__\n/a:/b\n__T3CODE_ENV_PATH_END__\n"); + + expect(readEnvironmentFromLoginShell("/opt/homebrew/bin/nu", ["PATH"], execFile)).toEqual({ + PATH: "/a:/b", + }); + + const command = execFile.mock.calls[0]?.[1][1]; + expect(command).toContain("do --ignore-errors { printenv PATH }"); + expect(command).not.toContain("|| true"); + expect(command).toContain("__T3CODE_ENV_PATH_START__"); + expect(command).toContain("__T3CODE_ENV_PATH_END__"); + }); + it("extracts multiple environment variables from a login shell command", () => { const execFile = vi.fn< ( diff --git a/packages/shared/src/shell.ts b/packages/shared/src/shell.ts index da6db2166765..5792a03cbff2 100644 --- a/packages/shared/src/shell.ts +++ b/packages/shared/src/shell.ts @@ -245,16 +245,27 @@ function envCaptureEnd(name: string): string { return `__T3CODE_ENV_${name}_END__`; } -function buildEnvironmentCaptureCommand(names: ReadonlyArray): string { +function isNushellExecutable(shell: string): boolean { + const executableName = NodePath.basename(shell).toLowerCase(); + return executableName === "nu" || executableName === "nu.exe"; +} + +function buildEnvironmentCaptureCommand(shell: string, names: ReadonlyArray): string { + const isNushell = isNushellExecutable(shell); + return names .map((name) => { if (!SHELL_ENV_NAME_PATTERN.test(name)) { throw new Error(`Unsupported environment variable name: ${name}`); } + const readVariable = isNushell + ? `do --ignore-errors { printenv ${name} }` + : `printenv ${name} || true`; + return [ `printf '%s\\n' '${envCaptureStart(name)}'`, - `printenv ${name} || true`, + readVariable, `printf '%s\\n' '${envCaptureEnd(name)}'`, ].join("; "); }) @@ -312,7 +323,7 @@ export const readEnvironmentFromLoginShell: ShellEnvironmentReader = ( return {}; } - const output = execFile(shell, ["-ilc", buildEnvironmentCaptureCommand(names)], { + const output = execFile(shell, ["-ilc", buildEnvironmentCaptureCommand(shell, names)], { encoding: "utf8", timeout: 5000, }); From ea33634ae4138bb3a33d4672f84ea83ca5521793 Mon Sep 17 00:00:00 2001 From: Serendeep Date: Sat, 22 Aug 2026 13:41:22 +0200 Subject: [PATCH 2/2] fix(shared): preserve Nushell probe output --- packages/shared/src/shell.test.ts | 6 +++--- packages/shared/src/shell.ts | 12 ++++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/packages/shared/src/shell.test.ts b/packages/shared/src/shell.test.ts index 34a797ca0002..c6411fa4988f 100644 --- a/packages/shared/src/shell.test.ts +++ b/packages/shared/src/shell.test.ts @@ -136,10 +136,10 @@ describe("readEnvironmentFromLoginShell", () => { }); const command = execFile.mock.calls[0]?.[1][1]; - expect(command).toContain("do --ignore-errors { printenv PATH }"); + expect(command).toBe( + "print '__T3CODE_ENV_PATH_START__'; try { printenv PATH } catch { print '' }; print '__T3CODE_ENV_PATH_END__'", + ); expect(command).not.toContain("|| true"); - expect(command).toContain("__T3CODE_ENV_PATH_START__"); - expect(command).toContain("__T3CODE_ENV_PATH_END__"); }); it("extracts multiple environment variables from a login shell command", () => { diff --git a/packages/shared/src/shell.ts b/packages/shared/src/shell.ts index 5792a03cbff2..e5ca01f0fa58 100644 --- a/packages/shared/src/shell.ts +++ b/packages/shared/src/shell.ts @@ -259,13 +259,17 @@ function buildEnvironmentCaptureCommand(shell: string, names: ReadonlyArray