From 9c5974735efc19e36bacadf5eb4972c2ed478228 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Thu, 23 Apr 2026 07:08:24 +0700 Subject: [PATCH] Fix desktop CLI environment boundary --- .../src/daemon/node-entrypoint-runner.test.ts | 18 +++++++++++++++++ .../src/daemon/node-entrypoint-runner.ts | 20 +++++++++++++------ .../src/integrations/cli-install-path.test.ts | 4 ++-- .../src/integrations/cli-install-path.ts | 4 ++++ 4 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 packages/desktop/src/daemon/node-entrypoint-runner.test.ts diff --git a/packages/desktop/src/daemon/node-entrypoint-runner.test.ts b/packages/desktop/src/daemon/node-entrypoint-runner.test.ts new file mode 100644 index 000000000..74ffd1ee9 --- /dev/null +++ b/packages/desktop/src/daemon/node-entrypoint-runner.test.ts @@ -0,0 +1,18 @@ +import { describe, expect, it } from "vitest"; +import { sanitizeNodeEntrypointEnv } from "./node-entrypoint-runner"; + +describe("node-entrypoint-runner", () => { + it("removes Electron node-mode env before loading the target entrypoint", () => { + const env = { + ELECTRON_RUN_AS_NODE: "1", + ELECTRON_NO_ATTACH_CONSOLE: "1", + PATH: "/usr/bin", + }; + + sanitizeNodeEntrypointEnv(env); + + expect(env).toEqual({ + PATH: "/usr/bin", + }); + }); +}); diff --git a/packages/desktop/src/daemon/node-entrypoint-runner.ts b/packages/desktop/src/daemon/node-entrypoint-runner.ts index e90579ae2..ed8930d7d 100644 --- a/packages/desktop/src/daemon/node-entrypoint-runner.ts +++ b/packages/desktop/src/daemon/node-entrypoint-runner.ts @@ -1,6 +1,11 @@ import { pathToFileURL } from "node:url"; -async function main(): Promise { +export function sanitizeNodeEntrypointEnv(env: NodeJS.ProcessEnv = process.env): void { + delete env.ELECTRON_RUN_AS_NODE; + delete env.ELECTRON_NO_ATTACH_CONSOLE; +} + +export async function main(): Promise { const [argvMode, entryPath, ...args] = process.argv.slice(2); if (argvMode !== "bare" && argvMode !== "node-script") { throw new Error(`Unsupported node entrypoint argv mode: ${argvMode ?? ""}`); @@ -13,11 +18,14 @@ async function main(): Promise { argvMode === "bare" ? [process.argv[0] ?? "node", ...args] : [process.argv[0] ?? "node", entryPath, ...args]; + sanitizeNodeEntrypointEnv(); await import(pathToFileURL(entryPath).href); } -void main().catch((error) => { - const message = error instanceof Error ? (error.stack ?? error.message) : String(error); - process.stderr.write(`${message}\n`); - process.exit(1); -}); +if (require.main === module) { + void main().catch((error) => { + const message = error instanceof Error ? (error.stack ?? error.message) : String(error); + process.stderr.write(`${message}\n`); + process.exit(1); + }); +} diff --git a/packages/desktop/src/integrations/cli-install-path.test.ts b/packages/desktop/src/integrations/cli-install-path.test.ts index f07598b25..5148e0015 100644 --- a/packages/desktop/src/integrations/cli-install-path.test.ts +++ b/packages/desktop/src/integrations/cli-install-path.test.ts @@ -2,7 +2,7 @@ import { describe, expect, it } from "vitest"; import { resolveCliInstallSourcePath } from "./cli-install-path"; describe("cli-install-path", () => { - it("uses the packaged executable on supported unix platforms", () => { + it("uses the bundled shim for packaged macOS installs", () => { expect( resolveCliInstallSourcePath({ platform: "darwin", @@ -10,7 +10,7 @@ describe("cli-install-path", () => { executablePath: "/Applications/Paseo.app/Contents/MacOS/Paseo", shimPath: "/Applications/Paseo.app/Contents/Resources/bin/paseo", }), - ).toBe("/Applications/Paseo.app/Contents/MacOS/Paseo"); + ).toBe("/Applications/Paseo.app/Contents/Resources/bin/paseo"); }); it("prefers the original AppImage path on linux", () => { diff --git a/packages/desktop/src/integrations/cli-install-path.ts b/packages/desktop/src/integrations/cli-install-path.ts index 245e5d17f..c0ecd27f8 100644 --- a/packages/desktop/src/integrations/cli-install-path.ts +++ b/packages/desktop/src/integrations/cli-install-path.ts @@ -13,6 +13,10 @@ export function resolveCliInstallSourcePath(input: { return input.shimPath; } + if (input.platform === "darwin") { + return input.shimPath; + } + if (input.platform === "linux") { const appImagePath = input.appImagePath?.trim(); if (appImagePath) {