Files
hermes-agent/tests/hermes_cli/test_node_runtime_npm_resolution.py
teknium1 b63c138d78 fix: Hermes never falls back to the user's node/npm/npx/uv
Maintainer ruling: only Hermes and only its packaged package managers
(uv/pip/node/npm) are ever used; no PATH fallback when the managed tool is
missing, no "prefer the user's if new enough".

- hermes_constants.find_node_executable: node/npm/npx resolve to PM's
  installed copy or None. Every caller already pm.ensure()s on None, so a
  missing runtime is now provisioned instead of silently borrowing the
  user's Node (native-addon ABI / npm cache mismatches).
- agent/lsp/install._install_npm: pm.ensure('npm') when PM npm is absent,
  instead of failing over to whatever npm is on PATH.
- gateway._append_node_dir_for_service: stop baking the invoker's PATH node
  dir into generated systemd/launchd units.
- main_install_repair._resolve_node_runtime_npm: drop the PATH re-scan for
  another npm.
- source_build.source_product_current: run the freshness reader only with
  PM's node.
- doctor: Node/npm rows and npm audit use PM's copies (Termux APT distro
  keeps its system Node).
- install.sh ensure_uv / install.ps1 Get-Uv: always stage the pinned uv
  artifact; delete the "uv on PATH if new enough" developer shortcut.
2026-09-27 22:04:26 -07:00

31 lines
1.4 KiB
Python

"""POSIX npm path classification: only Windows shims are refused (#112041, #30271)."""
from __future__ import annotations
import os
from unittest.mock import patch
from hermes_cli.main_install_repair import _is_windows_npm_path, _resolve_node_runtime_npm
def test_windows_npm_path_refuses_windows_shims_but_not_native_data_mounts():
"""A ``/mnt/<drive>`` WSL interop path or a ``.cmd`` shim is Windows npm; a native Linux
data mount such as ``/mnt/data`` is not — a folder prefix alone is not a Windows tell."""
assert _is_windows_npm_path("/mnt/c/Program Files/nodejs/npm")
assert _is_windows_npm_path("/mnt/d/nodejs/npm")
assert _is_windows_npm_path("C:\\nodejs\\npm.cmd")
assert not _is_windows_npm_path("/mnt/data/hermes/home/.local/bin/npm")
assert not _is_windows_npm_path("/usr/bin/npm")
def test_resolve_node_runtime_npm_never_rescans_path_past_a_windows_shim(monkeypatch):
"""A Windows npm shim is refused on a POSIX host, and no other npm is hunted down on the
user's PATH: Hermes runs only its PM-managed toolchain."""
monkeypatch.setenv("PATH", os.pathsep.join(["/mnt/c/Program Files/nodejs", "/mnt/data/node/bin"]))
with (
patch("hermes_constants.find_node_executable", return_value="/mnt/c/Program Files/nodejs/npm"),
patch("shutil.which", return_value="/mnt/data/node/bin/npm"),
):
assert _resolve_node_runtime_npm() is None