diff --git a/hermes_cli/banner.py b/hermes_cli/banner.py index 077ee41f0a2..ef592beb7fd 100644 --- a/hermes_cli/banner.py +++ b/hermes_cli/banner.py @@ -199,7 +199,7 @@ def _fetch_pypi_latest(package: str = "hermes-agent") -> Optional[str]: return None -def _check_via_pypi() -> Optional[int]: +def check_via_pypi() -> Optional[int]: """Compare installed version against PyPI latest. Returns 0 if up-to-date, 1 if behind, None on failure. @@ -255,7 +255,7 @@ def check_for_updates() -> Optional[int]: if not (repo_dir / ".git").exists(): repo_dir = hermes_home / "hermes-agent" if not (repo_dir / ".git").exists(): - behind = _check_via_pypi() + behind = check_via_pypi() else: behind = _check_via_local_git(repo_dir) diff --git a/hermes_cli/dep_ensure.py b/hermes_cli/dep_ensure.py index c06fc6db80a..3312726c36d 100644 --- a/hermes_cli/dep_ensure.py +++ b/hermes_cli/dep_ensure.py @@ -41,15 +41,15 @@ _DEP_DESCRIPTIONS = { def _has_system_browser() -> bool: - for name in ("google-chrome", "google-chrome-stable", "chromium", "chromium-browser"): + for name in ("google-chrome", "google-chrome-stable", "chromium", "chromium-browser", "chrome"): if shutil.which(name): return True return False def _has_hermes_agent_browser() -> bool: - hermes_home = os.environ.get("HERMES_HOME", str(Path.home() / ".hermes")) - return (Path(hermes_home) / "node_modules" / ".bin" / "agent-browser").is_file() + from hermes_constants import get_hermes_home + return (get_hermes_home() / "node_modules" / ".bin" / "agent-browser").is_file() def _find_install_script( diff --git a/hermes_cli/main.py b/hermes_cli/main.py index 121b77b0f91..41c4a23f932 100644 --- a/hermes_cli/main.py +++ b/hermes_cli/main.py @@ -7419,21 +7419,24 @@ def _finalize_update_output(state): def _cmd_update_check(): """Implement ``hermes update --check``: fetch and report without installing.""" + from hermes_cli.config import detect_install_method + method = detect_install_method(PROJECT_ROOT) + if method == "pip": + from hermes_cli.config import recommended_update_command + from hermes_cli.banner import check_via_pypi + result = check_via_pypi() + if result is None: + print("✗ Could not reach PyPI to check for updates.") + sys.exit(1) + elif result == 0: + print("✓ Already up to date.") + else: + print("⚕ Update available on PyPI.") + print(f" Run '{recommended_update_command()}' to install.") + return + git_dir = PROJECT_ROOT / ".git" if not git_dir.exists(): - from hermes_cli.config import detect_install_method, recommended_update_command - if detect_install_method(PROJECT_ROOT) == "pip": - from hermes_cli.banner import _check_via_pypi - result = _check_via_pypi() - if result is None: - print("✗ Could not reach PyPI to check for updates.") - sys.exit(1) - elif result == 0: - print("✓ Already up to date.") - else: - print(f"⚕ Update available on PyPI.") - print(f" Run '{recommended_update_command()}' to install.") - return print("✗ Not a git repository — cannot check for updates.") sys.exit(1) @@ -7712,15 +7715,15 @@ def cmd_update(args): def _cmd_update_pip(args): """Update Hermes via pip (for PyPI installs).""" from hermes_cli import __version__ - from hermes_cli.config import recommended_update_command_for_method print(f"→ Current version: {__version__}") print("→ Checking PyPI for updates...") - cmd_str = recommended_update_command_for_method("pip") - cmd = cmd_str.split() - if cmd[0] == "pip": - cmd = [sys.executable, "-m", "pip"] + cmd[1:] + uv = shutil.which("uv") + if uv: + cmd = [uv, "pip", "install", "--upgrade", "hermes-agent"] + else: + cmd = [sys.executable, "-m", "pip", "install", "--upgrade", "hermes-agent"] print(f"→ Running: {' '.join(cmd)}") result = subprocess.run(cmd) diff --git a/tests/hermes_cli/test_banner_pip_update.py b/tests/hermes_cli/test_banner_pip_update.py index a0e9266f698..205c97488a9 100644 --- a/tests/hermes_cli/test_banner_pip_update.py +++ b/tests/hermes_cli/test_banner_pip_update.py @@ -1,29 +1,29 @@ from unittest.mock import patch -def test_check_via_pypi_detects_update(): - """_check_via_pypi returns 1 when PyPI has newer version.""" - from hermes_cli.banner import _check_via_pypi +def testcheck_via_pypi_detects_update(): + """check_via_pypi returns 1 when PyPI has newer version.""" + from hermes_cli.banner import check_via_pypi with patch("hermes_cli.banner.VERSION", "0.12.0"): with patch("hermes_cli.banner._fetch_pypi_latest", return_value="0.13.0"): - result = _check_via_pypi() + result = check_via_pypi() assert result == 1 -def test_check_via_pypi_up_to_date(): - """_check_via_pypi returns 0 when versions match.""" - from hermes_cli.banner import _check_via_pypi +def testcheck_via_pypi_up_to_date(): + """check_via_pypi returns 0 when versions match.""" + from hermes_cli.banner import check_via_pypi with patch("hermes_cli.banner.VERSION", "0.13.0"): with patch("hermes_cli.banner._fetch_pypi_latest", return_value="0.13.0"): - result = _check_via_pypi() + result = check_via_pypi() assert result == 0 -def test_check_via_pypi_network_failure(): - """_check_via_pypi returns None on network error.""" - from hermes_cli.banner import _check_via_pypi +def testcheck_via_pypi_network_failure(): + """check_via_pypi returns None on network error.""" + from hermes_cli.banner import check_via_pypi with patch("hermes_cli.banner._fetch_pypi_latest", return_value=None): - result = _check_via_pypi() + result = check_via_pypi() assert result is None diff --git a/tests/hermes_cli/test_update_check.py b/tests/hermes_cli/test_update_check.py index 92cd2d2e14c..8a68d6a178d 100644 --- a/tests/hermes_cli/test_update_check.py +++ b/tests/hermes_cli/test_update_check.py @@ -70,7 +70,7 @@ def test_check_for_updates_no_git_dir(tmp_path, monkeypatch): monkeypatch.setattr(banner, "__file__", str(fake_banner)) monkeypatch.setenv("HERMES_HOME", str(tmp_path)) with patch("hermes_cli.banner.subprocess.run") as mock_run: - with patch("hermes_cli.banner._check_via_pypi", return_value=0): + with patch("hermes_cli.banner.check_via_pypi", return_value=0): result = banner.check_for_updates() assert result == 0 mock_run.assert_not_called()