From 6da71eef8f181d37c2a346f482f3e39f7ed1fc1d Mon Sep 17 00:00:00 2001 From: Pape Mamadou Diagne <66137298+Pape45@users.noreply.github.com> Date: Mon, 27 Jul 2026 16:39:21 +0200 Subject: [PATCH] fix(platform): discover Nix agent CLIs --- packages/platform/src/toolchain.ts | 10 ++++++---- packages/platform/tests/index.test.ts | 7 +++++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/packages/platform/src/toolchain.ts b/packages/platform/src/toolchain.ts index 7322e7b6f69..2c375478bce 100644 --- a/packages/platform/src/toolchain.ts +++ b/packages/platform/src/toolchain.ts @@ -3,7 +3,7 @@ * * User-level toolchain bin discovery. Single source of truth for the CLI * install locations a GUI-launched daemon must search even under a stripped - * PATH — npm/pnpm/bun/cargo/deno/go/pyenv prefixes, version-manager shims + * PATH — npm/pnpm/bun/cargo/deno/go/pyenv/Nix prefixes, version-manager shims * (asdf, volta, mise, nvm, fnm), and per-version Node install roots. Pure path * assembly plus best-effort directory probing; no process, command, or proxy * concerns. @@ -16,8 +16,9 @@ export type WellKnownUserToolchainOptions = { // Override homedir() so callers in sandboxed tests or namespaced launches // can substitute a fixture directory. Falls back to os.homedir(). home?: string; - // Include /opt/homebrew/bin and /usr/local/bin in the result. Defaults to - // true on POSIX so GUI-launched processes (which inherit a minimal PATH + // Include /opt/homebrew/bin, /usr/local/bin, and + // /run/current-system/sw/bin in the result. Defaults to true on POSIX so + // GUI-launched processes (which inherit a minimal PATH // from launchd / desktop launchers) still see Homebrew-installed CLIs; // defaults to false on Windows because those paths are POSIX-only. includeSystemBins?: boolean; @@ -125,6 +126,7 @@ export function wellKnownUserToolchainBins( join(home, ".asdf", "shims"), join(home, "Library", "pnpm"), join(home, ".cargo", "bin"), + join(home, ".nix-profile", "bin"), // Common user-level npm prefixes for sudo-free global installs. // ~/.npm-global is the dominant non-canonical convention shipped // in most third-party "fix npm EACCES" tutorials, and @@ -168,7 +170,7 @@ export function wellKnownUserToolchainBins( } if (includeSystemBins) { - dirs.push("/opt/homebrew/bin", "/usr/local/bin"); + dirs.push("/opt/homebrew/bin", "/usr/local/bin", "/run/current-system/sw/bin"); } // Per-version Node toolchains: scan the install root and surface every // version directory's bin folder. Best-effort — missing roots simply diff --git a/packages/platform/tests/index.test.ts b/packages/platform/tests/index.test.ts index 98b1b190e3d..3ab658c83c9 100644 --- a/packages/platform/tests/index.test.ts +++ b/packages/platform/tests/index.test.ts @@ -799,6 +799,7 @@ describe("wellKnownUserToolchainBins", () => { expect(dirs).toContain(join(home, ".asdf", "shims")); expect(dirs).toContain(join(home, "Library", "pnpm")); expect(dirs).toContain(join(home, ".cargo", "bin")); + expect(dirs).toContain(join(home, ".nix-profile", "bin")); } finally { rmSync(home, { recursive: true, force: true }); } @@ -1122,23 +1123,25 @@ describe("wellKnownUserToolchainBins", () => { } }); - it("includes /opt/homebrew/bin and /usr/local/bin when includeSystemBins is true", () => { + it("includes Homebrew, local, and Nix system bins when includeSystemBins is true", () => { const home = mkdtempSync(join(tmpdir(), "wkutb-sys-")); try { const dirs = wellKnownUserToolchainBins({ home, env: {}, includeSystemBins: true }); expect(dirs).toContain("/opt/homebrew/bin"); expect(dirs).toContain("/usr/local/bin"); + expect(dirs).toContain("/run/current-system/sw/bin"); } finally { rmSync(home, { recursive: true, force: true }); } }); - it("omits /opt/homebrew/bin and /usr/local/bin when includeSystemBins is false", () => { + it("omits Homebrew, local, and Nix system bins when includeSystemBins is false", () => { const home = mkdtempSync(join(tmpdir(), "wkutb-nosys-")); try { const dirs = wellKnownUserToolchainBins({ home, env: {}, includeSystemBins: false }); expect(dirs).not.toContain("/opt/homebrew/bin"); expect(dirs).not.toContain("/usr/local/bin"); + expect(dirs).not.toContain("/run/current-system/sw/bin"); } finally { rmSync(home, { recursive: true, force: true }); }