fix: resolve npx/node PATH on macOS GUI apps - #113
Merged
Conversation
macOS GUI apps launched from Finder/Dock/Spotlight inherit a minimal PATH (/usr/bin:/bin:/usr/sbin:/sbin) that excludes tools installed via Homebrew (/opt/homebrew/bin), nvm, Volta, fnm, or /usr/local/bin. This caused "Command not found: npx" errors even when npx was properly installed and worked in terminal. Add shell_env module that spawns the user's login shell ($SHELL -l -i -c) to resolve their fully-initialized PATH including entries from .zshrc, .bashrc, nvm init, Volta setup, etc. The result is cached via OnceLock. Changes: - New shell_env module resolves user's full PATH on Unix (no-op on Windows) - StdioTransport uses which::which_in() with shell PATH for command lookup - Shell PATH is injected into child process env so spawned processes (e.g., npx finding node) also get the full PATH - Falls back gracefully if shell resolution fails - Respects user-set PATH in env overrides Signed-off-by: Claude <noreply@anthropic.com> https://claude.ai/code/session_01EYZVAqzgNBAAtJptw9KRwB Signed-off-by: Claude <noreply@anthropic.com>
Unit tests for shell_env module: - merge_paths: deduplication, ordering, empty inputs, identical paths - get_shell_path: caching (OnceLock), no trailing newline, no empty entries, valid UTF-8, returns standard directories - try_resolve_path_from_shell: login shell, nonexistent shell, invalid flags Unit tests for stdio transport helpers: - resolve_command: with/without shell path, nonexistent, restricted path - inject_shell_path: adds when missing, respects existing, no-op when None - command_hint: Docker vs non-Docker hints - classify_stderr_line: error/warn/debug/info classification Integration tests: - Shell PATH finds system commands (sh, ls, env) - Shell PATH has more entries than minimal default - Child process receives injected shell PATH - User-set PATH override not clobbered by injection - StdioTransport resolves commands via shell PATH Signed-off-by: Claude <noreply@anthropic.com> https://claude.ai/code/session_01EYZVAqzgNBAAtJptw9KRwB Signed-off-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
macOS GUI apps launched from Finder/Dock/Spotlight inherit a minimal
PATH (/usr/bin:/bin:/usr/sbin:/sbin) that excludes tools installed via
Homebrew (/opt/homebrew/bin), nvm, Volta, fnm, or /usr/local/bin.
This caused "Command not found: npx" errors even when npx was properly
installed and worked in terminal.
Add shell_env module that spawns the user's login shell ($SHELL -l -i -c)
to resolve their fully-initialized PATH including entries from .zshrc,
.bashrc, nvm init, Volta setup, etc. The result is cached via OnceLock.
Changes:
(e.g., npx finding node) also get the full PATH
Signed-off-by: Claude noreply@anthropic.com
https://claude.ai/code/session_01EYZVAqzgNBAAtJptw9KRwB
Signed-off-by: Claude noreply@anthropic.com