diff --git a/hermes_cli/doctor.py b/hermes_cli/doctor.py index 88c767c74..9947b67fa 100644 --- a/hermes_cli/doctor.py +++ b/hermes_cli/doctor.py @@ -97,6 +97,10 @@ def check_info(text: str): def run_doctor(args): """Run diagnostic checks.""" should_fix = getattr(args, 'fix', False) + + # Doctor runs from the interactive CLI, so CLI-gated tool availability + # checks (like cronjob management) should see the same context as `hermes`. + os.environ.setdefault("HERMES_INTERACTIVE", "1") issues = [] manual_issues = [] # issues that can't be auto-fixed diff --git a/tests/hermes_cli/test_doctor.py b/tests/hermes_cli/test_doctor.py index 5c038e3f5..f30cf87d2 100644 --- a/tests/hermes_cli/test_doctor.py +++ b/tests/hermes_cli/test_doctor.py @@ -1,14 +1,21 @@ -"""Tests for hermes doctor helpers.""" +"""Tests for hermes_cli.doctor.""" +import os +import sys +import types +from argparse import Namespace from types import SimpleNamespace +import pytest + import hermes_cli.doctor as doctor +from hermes_cli import doctor as doctor_mod from hermes_cli.doctor import _has_provider_env_config class TestProviderEnvDetection: def test_detects_openai_api_key(self): - content = "OPENAI_BASE_URL=http://localhost:1234/v1\nOPENAI_API_KEY=sk-test-key\n" + content = "OPENAI_BASE_URL=http://localhost:1234/v1\nOPENAI_API_KEY=***" assert _has_provider_env_config(content) def test_detects_custom_endpoint_without_openrouter_key(self): @@ -47,7 +54,7 @@ class TestDoctorToolAvailabilityOverrides: class TestHonchoDoctorConfigDetection: def test_reports_configured_when_enabled_with_api_key(self, monkeypatch): - fake_config = SimpleNamespace(enabled=True, api_key="honcho-test-key") + fake_config = SimpleNamespace(enabled=True, api_key="***") monkeypatch.setattr( "honcho_integration.client.HonchoClientConfig.from_global_config", @@ -57,7 +64,7 @@ class TestHonchoDoctorConfigDetection: assert doctor._honcho_is_configured_for_doctor() def test_reports_not_configured_without_api_key(self, monkeypatch): - fake_config = SimpleNamespace(enabled=True, api_key=None) + fake_config = SimpleNamespace(enabled=True, api_key="") monkeypatch.setattr( "honcho_integration.client.HonchoClientConfig.from_global_config", @@ -65,3 +72,32 @@ class TestHonchoDoctorConfigDetection: ) assert not doctor._honcho_is_configured_for_doctor() + + +def test_run_doctor_sets_interactive_env_for_tool_checks(monkeypatch, tmp_path): + """Doctor should present CLI-gated tools as available in CLI context.""" + project_root = tmp_path / "project" + hermes_home = tmp_path / ".hermes" + project_root.mkdir() + hermes_home.mkdir() + + monkeypatch.setattr(doctor_mod, "PROJECT_ROOT", project_root) + monkeypatch.setattr(doctor_mod, "HERMES_HOME", hermes_home) + monkeypatch.delenv("HERMES_INTERACTIVE", raising=False) + + seen = {} + + def fake_check_tool_availability(*args, **kwargs): + seen["interactive"] = os.getenv("HERMES_INTERACTIVE") + raise SystemExit(0) + + fake_model_tools = types.SimpleNamespace( + check_tool_availability=fake_check_tool_availability, + TOOLSET_REQUIREMENTS={}, + ) + monkeypatch.setitem(sys.modules, "model_tools", fake_model_tools) + + with pytest.raises(SystemExit): + doctor_mod.run_doctor(Namespace(fix=False)) + + assert seen["interactive"] == "1"