fix(gateway): inject PATH into launchd plist for macOS service#2173
Closed
hanai wants to merge 4 commits intoNousResearch:mainfrom
Closed
fix(gateway): inject PATH into launchd plist for macOS service#2173hanai wants to merge 4 commits intoNousResearch:mainfrom
hanai wants to merge 4 commits intoNousResearch:mainfrom
Conversation
launchd provides only a minimal default PATH (/usr/bin:/bin:/usr/sbin:/sbin), causing tools like ffmpeg and node to be not found when the gateway runs as a launchd agent. The systemd unit already sets PATH explicitly; apply the same fix to the launchd plist. Capture the full PATH from the user's interactive shell at plist-generation time and prepend the venv bin directory, so all user-installed tools and venv-installed packages are reachable by the agent process.
There was a problem hiding this comment.
Pull request overview
Updates the macOS launchd plist generation for the Hermes gateway service so the background service runs with an explicit PATH (mirroring the existing systemd approach) and can find user-installed binaries like Homebrew ffmpeg/node.
Changes:
- Capture the caller’s
PATHat plist-generation time and prepend the project venvbin/. - Add
EnvironmentVariables→PATHto the generated launchd plist.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
When gateway restart is triggered from within a launchd agent session (e.g. by an AI agent calling hermes gateway restart), os.environ['PATH'] already contains venv/bin from the baked-in plist environment. The previous f-string prepend would add venv/bin again, causing refresh_launchd_plist_if_needed() to detect a spurious change and rewrite the plist on every restart, accumulating duplicates over time. Use dict.fromkeys() to preserve insertion order while deduplicating, ensuring venv/bin appears first exactly once regardless of the calling environment. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
teknium1
added a commit
that referenced
this pull request
Mar 28, 2026
…service (#3585) Salvage of PR #2173 (hanai) and PR #3432 (timknip). Injects PATH, VIRTUAL_ENV, and HERMES_HOME into the macOS launchd plist so gateway subprocesses find user-installed tools (node, ffmpeg, etc.). Matches systemd unit parity with venv/bin, node_modules/.bin, and resolved node dir in PATH. Includes 7 new tests and docs updates across 4 pages. Co-Authored-By: Han <ihanai1991@gmail.com> Co-Authored-By: timknip <timknip@users.noreply.github.com>
Contributor
|
Merged via PR #3585. Your implementation was salvaged onto current main with authorship preserved — your commit is the primary author. Tests were updated to handle both venv/ and .venv/ layouts, and we added VIRTUAL_ENV + node_modules/.bin + resolved node dir for full systemd parity, plus docs across 4 pages. Thanks for the solid fix and tests! |
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.
Summary
PATH, so launchd's minimal default (/usr/bin:/bin:/usr/sbin:/sbin) was used at runtimeffmpeg(Homebrew) andnodeto be not found, even though they were available in the user's interactive shellPATHexplicitly — this PR applies the same fix to the launchd plistAt plist-generation time (i.e. when the user runs
hermes gateway installorhermes gateway startfrom their terminal), the full shellPATHis captured and baked into the plist, with the venvbindirectory prepended. This covers all user-installed tools regardless of where they are installed, without hardcoding platform-specific paths like/opt/homebrew/bin.PATH components are deduplicated using
dict.fromkeys()(preserving order) so that venv/bin appears exactly once even whengenerate_launchd_plist()is called from within a launchd agent session (e.g. when an AI agent triggershermes gateway restart). Without deduplication, each in-process restart would prepend an additional venv/bin, causingrefresh_launchd_plist_if_needed()to detect a spurious change and rewrite/reload the plist on every restart.Test plan
tests/hermes_cli/test_update_gateway_restart.py(TestLaunchdPlistPath): plist contains EnvironmentVariables/PATH key, PATH includes venv bin, PATH starts with venv bin, current process PATH is baked in at generation time, venv/bin is deduplicated when already present in PATHhermes gateway install, confirm ffmpeg is found when a Discord voice message is transcribedhermes gateway startdetects the plist change viarefresh_launchd_plist_if_needed()and reloads the service automaticallyPlatforms tested
Generated with Claude Code