From fd29933a6d44fdb1168fed5a50df07aba84c8387 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Sun, 29 Mar 2026 21:54:36 -0700 Subject: [PATCH] fix: use argparse entrypoint in top-level launcher (#3874) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ./hermes convenience script still used the legacy Fire-based cli.main wrapper, which doesn't support subcommands (gateway, cron, doctor, etc.). The installed 'hermes' command already uses hermes_cli.main:main (argparse) — this aligns the launcher. Salvaged from PR #2009 by gito369. --- hermes | 11 ++++---- tests/hermes_cli/test_launcher.py | 42 +++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 6 deletions(-) create mode 100644 tests/hermes_cli/test_launcher.py diff --git a/hermes b/hermes index f0feeb2b..3172ca91 100755 --- a/hermes +++ b/hermes @@ -1,12 +1,11 @@ #!/usr/bin/env python3 """ -Hermes Agent CLI Launcher +Hermes Agent CLI launcher. -This is a convenience wrapper to launch the Hermes CLI. -Usage: ./hermes [options] +This wrapper should behave like the installed `hermes` command, including +subcommands such as `gateway`, `cron`, and `doctor`. """ if __name__ == "__main__": - from cli import main - import fire - fire.Fire(main) + from hermes_cli.main import main + main() diff --git a/tests/hermes_cli/test_launcher.py b/tests/hermes_cli/test_launcher.py new file mode 100644 index 00000000..9c3cea85 --- /dev/null +++ b/tests/hermes_cli/test_launcher.py @@ -0,0 +1,42 @@ +"""Tests for the top-level `./hermes` launcher script.""" + +import runpy +import sys +import types +from pathlib import Path + + +def test_launcher_delegates_to_argparse_entrypoint(monkeypatch): + """`./hermes` should use `hermes_cli.main`, not the legacy Fire wrapper.""" + launcher_path = Path(__file__).resolve().parents[2] / "hermes" + called = [] + + fake_main_module = types.ModuleType("hermes_cli.main") + + def fake_main(): + called.append("hermes_cli.main") + + fake_main_module.main = fake_main + monkeypatch.setitem(sys.modules, "hermes_cli.main", fake_main_module) + + fake_cli_module = types.ModuleType("cli") + + def legacy_cli_main(*args, **kwargs): + raise AssertionError("launcher should not import cli.main") + + fake_cli_module.main = legacy_cli_main + monkeypatch.setitem(sys.modules, "cli", fake_cli_module) + + fake_fire_module = types.ModuleType("fire") + + def legacy_fire(*args, **kwargs): + raise AssertionError("launcher should not invoke fire.Fire") + + fake_fire_module.Fire = legacy_fire + monkeypatch.setitem(sys.modules, "fire", fake_fire_module) + + monkeypatch.setattr(sys, "argv", [str(launcher_path), "gateway", "status"]) + + runpy.run_path(str(launcher_path), run_name="__main__") + + assert called == ["hermes_cli.main"]