fix(mcp): move uv/uvx known-dir table into hermes_platform resolver
The #37589 uv/uvx fallback spelled its directory table (~/.local/bin, /opt/homebrew/bin, /usr/local/bin) inline in _launcher_fallback, which the managed-runtime ratchet flags as an unreviewed known_path_table outside hermes_platform/. known_dirs is the module whose contract is 'every table in Hermes lives here', so add uv_tool_dirs() there and compose it at the call site. Behavior is unchanged: same four directories probed in the same order (managed <home>/bin first, then uv's install order), bare uv/uvx still resolves under a GUI-style PATH that lacks them.
This commit is contained in:
@@ -25,6 +25,17 @@ def rust_tool_dirs() -> tuple[str, ...]:
|
|||||||
return ("~/.cargo/bin",) if _POSIX else ("%USERPROFILE%/.cargo/bin",)
|
return ("~/.cargo/bin",) if _POSIX else ("%USERPROFILE%/.cargo/bin",)
|
||||||
|
|
||||||
|
|
||||||
|
def uv_tool_dirs() -> tuple[str, ...]:
|
||||||
|
"""uv's install locations outside PATH, in uv's own install order: the per-user
|
||||||
|
installer's ``~/.local/bin`` (every OS — that is where uv's docs put it), then
|
||||||
|
Homebrew (Apple Silicon ``/opt``, Intel / from-source ``/usr/local``). The tilde
|
||||||
|
form is deliberate: callers that only ``expanduser`` (the stdio launcher
|
||||||
|
fallback) get the same result as ``locate_command``'s expandvars+expanduser."""
|
||||||
|
if _POSIX:
|
||||||
|
return ("~/.local/bin", "/opt/homebrew/bin", "/usr/local/bin")
|
||||||
|
return ("~/.local/bin",)
|
||||||
|
|
||||||
|
|
||||||
def node_tool_dirs() -> tuple[str, ...]:
|
def node_tool_dirs() -> tuple[str, ...]:
|
||||||
return ("~/.npm-global/bin", "~/.bun/bin", "~/.volta/bin") if _POSIX else ("%APPDATA%/npm", "%USERPROFILE%/.bun/bin", "%LOCALAPPDATA%/Volta/bin")
|
return ("~/.npm-global/bin", "~/.bun/bin", "~/.volta/bin") if _POSIX else ("%APPDATA%/npm", "%USERPROFILE%/.bun/bin", "%LOCALAPPDATA%/Volta/bin")
|
||||||
|
|
||||||
|
|||||||
@@ -172,18 +172,18 @@ def _launcher_fallback(command: str, *, windows: Optional[bool] = None) -> str:
|
|||||||
``uv``/``uvx``: GUI launches (the Electron desktop app, macOS LaunchAgents) inherit the bare
|
``uv``/``uvx``: GUI launches (the Electron desktop app, macOS LaunchAgents) inherit the bare
|
||||||
``/usr/bin:/bin:/usr/sbin:/sbin`` PATH, which carries none of uv's install locations, so a bare
|
``/usr/bin:/bin:/usr/sbin:/sbin`` PATH, which carries none of uv's install locations, so a bare
|
||||||
``command: uvx`` MCP server fails with ENOENT at ``execvp`` from Desktop even though it works
|
``command: uvx`` MCP server fails with ENOENT at ``execvp`` from Desktop even though it works
|
||||||
from an interactive terminal (#37589). Probed in the order uv's own docs install it: the
|
from an interactive terminal (#37589). The directory table lives in
|
||||||
Hermes-managed ``<home>/bin`` first, then the per-user installer's ``~/.local/bin``, then
|
``hermes_platform.resolver.known_dirs.uv_tool_dirs`` (probed in the order uv's own docs install
|
||||||
Homebrew (Apple Silicon ``/opt``, Intel ``/usr/local``)."""
|
it: the per-user installer first, then Homebrew); the Hermes-managed ``<home>/bin`` is probed
|
||||||
|
before it."""
|
||||||
from hermes_constants import get_hermes_home
|
from hermes_constants import get_hermes_home
|
||||||
|
from hermes_platform.resolver.known_dirs import uv_tool_dirs
|
||||||
home = os.path.expanduser("~")
|
home = os.path.expanduser("~")
|
||||||
if command in {"uv", "uvx"}:
|
if command in {"uv", "uvx"}:
|
||||||
directories = [
|
# expanduser: the table carries the ``~`` form so both this walk and
|
||||||
os.path.join(str(get_hermes_home()), "bin"),
|
# locate_command's expandvars+expanduser agree on one spelling.
|
||||||
os.path.join(home, ".local", "bin"), # uv's official installer
|
directories = [os.path.join(str(get_hermes_home()), "bin"),
|
||||||
os.path.join(os.sep, "opt", "homebrew", "bin"), # Apple Silicon Homebrew
|
*(os.path.expanduser(d) for d in uv_tool_dirs())]
|
||||||
os.path.join(os.sep, "usr", "local", "bin"), # Intel Homebrew / from-source
|
|
||||||
]
|
|
||||||
else:
|
else:
|
||||||
from hermes_constants import iter_hermes_node_dirs
|
from hermes_constants import iter_hermes_node_dirs
|
||||||
# /usr/local/bin: canonical Node location (from-source Linux, Hermes Docker image, Intel
|
# /usr/local/bin: canonical Node location (from-source Linux, Hermes Docker image, Intel
|
||||||
|
|||||||
Reference in New Issue
Block a user