diff --git a/hermes_cli/plugins.py b/hermes_cli/plugins.py index 25bf83af302..b064725186f 100644 --- a/hermes_cli/plugins.py +++ b/hermes_cli/plugins.py @@ -315,6 +315,28 @@ class PluginContext: self._llm = PluginLlm(plugin_id=plugin_id) return self._llm + # -- profile awareness -------------------------------------------------- + + @property + def profile_name(self) -> str: + """Return the active Hermes profile name (e.g. ``"default"``). + + Derived from ``HERMES_HOME`` via + :func:`hermes_cli.profiles.get_active_profile_name`, so it works in + every execution context — interactive CLI, gateway, and + kanban-spawned worker sessions alike — without depending on + ``_cli_ref`` (which is ``None`` outside an interactive CLI run). + + Returns ``"default"`` for the default profile, the profile id when + running under ``~/.hermes/profiles/``, or ``"custom"`` when + ``HERMES_HOME`` points somewhere unrecognized. + """ + try: + from hermes_cli.profiles import get_active_profile_name + return get_active_profile_name() + except Exception: + return "default" + # -- tool registration -------------------------------------------------- def register_tool( diff --git a/tests/hermes_cli/test_plugins.py b/tests/hermes_cli/test_plugins.py index effeaa0120f..16e5785c88f 100644 --- a/tests/hermes_cli/test_plugins.py +++ b/tests/hermes_cli/test_plugins.py @@ -1867,3 +1867,38 @@ class TestPluginDebugLogging: plugins_mod._PLUGINS_DEBUG = original_debug plugins_mod.logger.setLevel(original_level) plugins_mod.logger.handlers = original_handlers + + +class TestPluginContextProfileName: + """ctx.profile_name resolves from HERMES_HOME in every context.""" + + def _ctx(self): + mgr = PluginManager() + manifest = PluginManifest(name="test-plugin", source="user") + return PluginContext(manifest, mgr) + + def test_default_profile(self, tmp_path, monkeypatch): + """HERMES_HOME at the root resolves to 'default'.""" + home = tmp_path / ".hermes" + home.mkdir() + monkeypatch.setattr(Path, "home", lambda: tmp_path) + monkeypatch.setenv("HERMES_HOME", str(home)) + assert self._ctx().profile_name == "default" + + def test_named_profile(self, tmp_path, monkeypatch): + """HERMES_HOME under profiles/ resolves to that name.""" + prof = tmp_path / ".hermes" / "profiles" / "coder" + prof.mkdir(parents=True) + monkeypatch.setattr(Path, "home", lambda: tmp_path) + monkeypatch.setenv("HERMES_HOME", str(prof)) + assert self._ctx().profile_name == "coder" + + def test_works_without_cli_ref(self, tmp_path, monkeypatch): + """profile_name does not depend on _cli_ref (None in worker sessions).""" + prof = tmp_path / ".hermes" / "profiles" / "worker1" + prof.mkdir(parents=True) + monkeypatch.setattr(Path, "home", lambda: tmp_path) + monkeypatch.setenv("HERMES_HOME", str(prof)) + ctx = self._ctx() + assert ctx._manager._cli_ref is None + assert ctx.profile_name == "worker1"