feat(gateway): unify setup flows, load platforms dynamically from registry
Merge the two gateway setup paths (hermes setup gateway + hermes gateway setup) to use a single _unified_platforms() list that merges built-in _PLATFORMS with dynamically registered plugin entries from platform_registry. - Add setup_fn field to PlatformEntry for plugin setup flows - _unified_platforms() merges built-ins with registry entries by key - setup_gateway() now uses unified list instead of hardcoded _GATEWAY_PLATFORMS tuple list - gateway_setup() uses same unified list, plugin entries appear alongside built-ins with no [plugin] suffix - _platform_status() handles plugin platforms via registry check_fn - Plugin platforms with setup_fn get called directly; plugins without get a generic env-var display fallback IRC and other plugin platforms now appear automatically in the setup menu when registered via platform_registry.register(). feat(gateway): surface disabled platform plugins in setup and auto-enable on select Platform plugins under plugins/platforms/* (IRC, etc.) were gated behind plugins.enabled, so `hermes gateway setup` wouldn't list them until the user ran `hermes plugins enable <name>` first. Now the setup menu always surfaces them as "plugin disabled — select to enable", and picking one adds it to plugins.enabled before running its setup flow. Along the way, unify the two gateway setup flows so `hermes setup gateway` and `hermes gateway setup` both read from the same platform list (built-in _PLATFORMS + platform_registry entries), dispatch through a single _configure_platform() helper, and share _platform_status(). Deletes the dead bespoke wrappers in setup.py (_setup_whatsapp, _setup_weixin, _setup_email, etc.) that duplicated logic now covered by the registry path or _setup_standard_platform. Also: - PlatformEntry gains a plugin_name field so the registry knows which plugin owns each entry (required for auto-enable). - PluginContext.register_platform auto-stamps plugin_name from the manifest so plugins don't have to pass it explicitly. - PluginManager now scans plugins/platforms/* as its own category root, one level below the bundled plugin scan. - Fix IRC plugin discovery: rename PLUGIN.yaml → plugin.yaml (the scanner is case-sensitive) and add the missing __init__.py that _load_directory_module requires.
This commit is contained in:
@@ -163,12 +163,13 @@ def test_setup_gateway_skips_service_install_when_systemctl_missing(monkeypatch,
|
||||
"WEBHOOK_ENABLED": "",
|
||||
}
|
||||
|
||||
import hermes_cli.gateway as gateway_mod
|
||||
|
||||
monkeypatch.setattr(setup_mod, "get_env_value", lambda key: env.get(key, ""))
|
||||
monkeypatch.setattr(gateway_mod, "get_env_value", lambda key: env.get(key, ""))
|
||||
monkeypatch.setattr(setup_mod, "prompt_yes_no", lambda *args, **kwargs: False)
|
||||
monkeypatch.setattr("platform.system", lambda: "Linux")
|
||||
|
||||
import hermes_cli.gateway as gateway_mod
|
||||
|
||||
monkeypatch.setattr(gateway_mod, "supports_systemd_services", lambda: False)
|
||||
monkeypatch.setattr(gateway_mod, "is_macos", lambda: False)
|
||||
monkeypatch.setattr(gateway_mod, "_is_service_installed", lambda: False)
|
||||
@@ -201,12 +202,13 @@ def test_setup_gateway_in_container_shows_docker_guidance(monkeypatch, capsys):
|
||||
"WEBHOOK_ENABLED": "",
|
||||
}
|
||||
|
||||
import hermes_cli.gateway as gateway_mod
|
||||
|
||||
monkeypatch.setattr(setup_mod, "get_env_value", lambda key: env.get(key, ""))
|
||||
monkeypatch.setattr(gateway_mod, "get_env_value", lambda key: env.get(key, ""))
|
||||
monkeypatch.setattr(setup_mod, "prompt_yes_no", lambda *args, **kwargs: False)
|
||||
monkeypatch.setattr("platform.system", lambda: "Linux")
|
||||
|
||||
import hermes_cli.gateway as gateway_mod
|
||||
|
||||
monkeypatch.setattr(gateway_mod, "supports_systemd_services", lambda: False)
|
||||
monkeypatch.setattr(gateway_mod, "is_macos", lambda: False)
|
||||
monkeypatch.setattr(gateway_mod, "_is_service_installed", lambda: False)
|
||||
|
||||
@@ -529,10 +529,16 @@ class TestGetSectionConfigSummary:
|
||||
assert result == "gpt-5"
|
||||
|
||||
def test_gateway_matches_platform_registry(self):
|
||||
"""Every platform in _GATEWAY_PLATFORMS should be recognised by its
|
||||
own env-var sentinel — i.e. the summary must not drift from the
|
||||
"""Every built-in platform should be recognised by its primary
|
||||
env-var sentinel — i.e. the summary must not drift from the
|
||||
registry used by the setup checklist."""
|
||||
for label, env_var, _fn in setup_mod._GATEWAY_PLATFORMS:
|
||||
from hermes_cli.gateway import _PLATFORMS
|
||||
|
||||
for plat in _PLATFORMS:
|
||||
label = plat["label"]
|
||||
env_var = plat.get("token_var")
|
||||
if not env_var:
|
||||
continue
|
||||
def env_side(key, _target=env_var):
|
||||
return "x" if key == _target else ""
|
||||
with patch.object(setup_mod, "get_env_value", side_effect=env_side):
|
||||
|
||||
Reference in New Issue
Block a user