From 624ce11ee846b57b59ca2e031f34e25813137c4d Mon Sep 17 00:00:00 2001 From: alt-glitch Date: Fri, 15 May 2026 12:02:44 +0000 Subject: [PATCH] feat(config): detect pip install method and recommend correct update command Adds detect_install_method() to identify nixos/homebrew/git/pip installs, and recommended_update_command_for_method() to return the right upgrade command for each method. Updates recommended_update_command() to use these for pip-installed instances (no .git dir, not managed). --- hermes_cli/config.py | 33 ++++++++++++++++- .../hermes_cli/test_pip_install_detection.py | 37 +++++++++++++++++++ 2 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 tests/hermes_cli/test_pip_install_detection.py diff --git a/hermes_cli/config.py b/hermes_cli/config.py index a560e1e6a1e..10dd7b46412 100644 --- a/hermes_cli/config.py +++ b/hermes_cli/config.py @@ -199,9 +199,40 @@ def get_managed_update_command() -> Optional[str]: return None +def detect_install_method(project_root: Optional[Path] = None) -> str: + """Detect how Hermes was installed: 'nixos', 'homebrew', 'git', or 'pip'.""" + managed = get_managed_system() + if managed: + return managed.lower().replace(" ", "-") + if project_root is None: + project_root = Path(__file__).parent.parent.resolve() + if (project_root / ".git").is_dir(): + return "git" + return "pip" + + +def recommended_update_command_for_method(method: str) -> str: + """Return the update command for a given install method.""" + if method == "nixos": + return "sudo nixos-rebuild switch" + if method == "homebrew": + return "brew upgrade hermes-agent" + if method == "pip": + import shutil + uv = shutil.which("uv") + if uv: + return "uv pip install --upgrade hermes-agent" + return "pip install --upgrade hermes-agent" + return "hermes update" + + def recommended_update_command() -> str: """Return the best update command for the current installation.""" - return get_managed_update_command() or "hermes update" + managed_cmd = get_managed_update_command() + if managed_cmd: + return managed_cmd + method = detect_install_method() + return recommended_update_command_for_method(method) def format_managed_message(action: str = "modify this Hermes installation") -> str: diff --git a/tests/hermes_cli/test_pip_install_detection.py b/tests/hermes_cli/test_pip_install_detection.py new file mode 100644 index 00000000000..b0f4cbd75ad --- /dev/null +++ b/tests/hermes_cli/test_pip_install_detection.py @@ -0,0 +1,37 @@ +from pathlib import Path +from unittest.mock import patch + + +def test_pip_install_detected_when_no_git_dir(tmp_path): + """When PROJECT_ROOT has no .git, detect as pip install.""" + with patch("hermes_cli.config.get_managed_system", return_value=None): + from hermes_cli.config import detect_install_method + method = detect_install_method(project_root=tmp_path) + assert method == "pip" + + +def test_git_install_detected_when_git_dir_exists(tmp_path): + """When PROJECT_ROOT has .git, detect as git install.""" + (tmp_path / ".git").mkdir() + with patch("hermes_cli.config.get_managed_system", return_value=None): + from hermes_cli.config import detect_install_method + method = detect_install_method(project_root=tmp_path) + assert method == "git" + + +def test_managed_install_takes_precedence(tmp_path): + """When HERMES_MANAGED is set, that takes precedence over git detection.""" + (tmp_path / ".git").mkdir() + with patch("hermes_cli.config.get_managed_system", return_value="NixOS"): + from hermes_cli.config import detect_install_method + method = detect_install_method(project_root=tmp_path) + assert method == "nixos" + + +def test_recommended_update_command_pip(): + """Pip installs recommend pip install --upgrade.""" + from hermes_cli.config import recommended_update_command_for_method + cmd = recommended_update_command_for_method("pip") + assert "pip install" in cmd or "uv pip install" in cmd + assert "--upgrade" in cmd + assert "hermes-agent" in cmd