Repository navigation
feat(desktop): resolve login-shell PATH for GUI launches (port of cline/cline#12429) - #69696
Conversation
૮ >ﻌ< ა ci reviewran on 8b3e136 — fix: resolve semantic merge conflict — startHermes update-wa
|
|
Thank you for the explicit credit and for carrying the diagnosis forward into the broader startup-level PATH solution. Resolving the login-shell PATH once for the backend is clearly stronger than my original point fix, and I appreciate you naming #43834 and the other contributors who independently mapped this bug family. I’m glad the investigation was useful. |
|
Current |
dad3653 to
38619a2
Compare
|
Refreshed against current main: |
…launched desktop (cline/cline#12429) feat(desktop): resolve the user's login-shell PATH once at startup and merge it into process.env before the backend spawns. GUI launches (Finder/Dock on macOS, desktop launchers on Linux) inherit a minimal PATH that never runs the user's shell profiles, so the backend process — and everything it spawns or probes (shutil.which availability checks like cua-driver, stdio MCP servers, Electron-side git/gh/hermes resolvers) — cannot see Homebrew-, nvm-, pyenv-, cargo-, or ~/.local/bin-installed tools. backend-env.ts's static sane-entry list covers Homebrew//usr/local but not profile-added dirs. Approach (ported from cline/cline#12429, mirrors VS Code's shell environment resolution): - new electron/shell-path.ts: run $SHELL -ilc (fallback -lc for the macOS system-bash-3.2 swallow) printing $PATH between sentinel markers so profile banners can't corrupt the capture - merge login-shell entries first, current-only entries appended, deduped via backend-env's appendUniquePathEntries - single-flight, timeout-bounded, failure-hardened: a broken or slow shell profile never blocks boot; win32 no-op - warmed at app.whenReady, awaited before backend runtime resolution 12 unit tests + live E2E verified (GUI-minimal PATH enriched with ~/.local/bin, nvm, cargo, go entries on a real shell).
…into runPrimaryBackendStartup (waitForLocalStart); drop duplicated waitForUpdateToFinish call, keep login-shell PATH merge before backend resolve
4e4c7c0 to
8b3e136
Compare
Summary
GUI-launched Hermes Desktop (Finder/Dock on macOS, desktop launchers on Linux) now resolves the user's login-shell
PATHonce at startup and merges it intoprocess.envbefore the backend spawns — so the backend subtree and the Electron-side resolvers can find Homebrew-, nvm-, pyenv-, cargo-, and~/.local/bin-installed CLIs.Ported from cline/cline#12429 (same approach as VS Code's shell environment resolution), adapted to the desktop app's existing
backend-env.tsPATH machinery.Root cause: launchd/desktop launchers hand GUI apps a minimal
PATH(/usr/bin:/bin:/usr/sbin:/sbin); shell profiles never run.backend-env.ts's static sane-entry list papers over Homebrew//usr/local, but anything only a profile adds stays invisible — breaking tool availability checks (shutil.which('cua-driver')→ computer_use schema silently missing, #51249), stdio MCP server spawns (npx/uvxfrom nvm or~/.local/bin), and the Electron-sidegit/gh/hermesresolvers (#48158). The Python terminal tool's login-shell snapshot covers agent terminal commands, but not the backend process env itself.Changes
apps/desktop/electron/shell-path.ts(new): runs$SHELL -ilc(fallback-lcfor the macOS system-bash-3.2 swallow documented intests/tools/test_find_shell.py) printing$PATHbetween sentinel markers so profile banners/motd can't corrupt the capture. Merges login-shell entries first (Homebrew/version managers win), current-only entries appended, deduped viabackend-env'sappendUniquePathEntries. Single-flight, 5s-per-attempt timeout, stdin closed, never rejects — a broken shell profile never blocks boot.win32no-op (Windows GUI apps get the user PATH from the registry env block).apps/desktop/electron/main.ts: warm the resolution atapp.whenReady; await the same single-flight promise in the local-backend start path before runtime resolution, withrememberLogbreadcrumbs.apps/desktop/electron/shell-path.test.ts(new): 12 tests — sentinel extraction under banner noise, last-marker poisoning guard, merge ordering/dedupe,-ilc→-lcfallback, failure/unchanged/win32 no-ops, single-flight memoization, never-rejects.Validation
vitest --project electron shell-path.test.tsvitest --project electron backend-env.test.tstsc -p tsconfig.electron.json --noEmiteslint+prettieron changed filesPATH=/usr/bin:/bin:/usr/sbin:/sbin)~/.local/bin, nvm node bin,~/.cargo/bin, go bin; login entries first; dedupedRelated
~/.local/bin→cua-driver/computer_use invisible)Infographic