From 0c26446e158b4ff5c890a0c0f21acaa7adbedb9c Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Thu, 3 Sep 2026 00:11:01 -0700 Subject: [PATCH] refactor(hermes_cli): inline _try_poll, hoist datetime import, share _kv/_detail and _header/_lines --- hermes_cli/setup_summary.py | 13 ++++--------- hermes_cli/setup_terminal.py | 3 +-- hermes_cli/setup_whatsapp_cloud.py | 4 +--- hermes_cli/status.py | 6 +++--- hermes_cli/status_auth.py | 4 ++-- hermes_cli/telegram_managed_bot.py | 18 ++++++------------ 6 files changed, 17 insertions(+), 31 deletions(-) diff --git a/hermes_cli/setup_summary.py b/hermes_cli/setup_summary.py index 8ad2fa90c9..4b66eb73e8 100644 --- a/hermes_cli/setup_summary.py +++ b/hermes_cli/setup_summary.py @@ -204,10 +204,8 @@ def _print_cmd_rows(rows): def _print_section_header(title): - print(_setup.color("─" * 60, _setup.Colors.DIM)) - print() - print(_setup.color(title, _setup.Colors.CYAN, _setup.Colors.BOLD)) - print() + print(_setup.color("─" * 60, _setup.Colors.DIM), end="\n\n") + print(_setup.color(title, _setup.Colors.CYAN, _setup.Colors.BOLD), end="\n\n") def _print_setup_summary(config: dict, hermes_home): @@ -251,8 +249,7 @@ def _print_setup_summary(config: dict, hermes_home): for line in _DONE_BANNER: print(_setup.color(line, _setup.Colors.GREEN)) print() - print(_setup.color(f"📁 All your files are in {_dhh()}/:", _setup.Colors.CYAN, _setup.Colors.BOLD)) - print() + print(_setup.color(f"📁 All your files are in {_dhh()}/:", _setup.Colors.CYAN, _setup.Colors.BOLD), end="\n\n") for label, value in (("Settings:", f" {_setup.get_config_path()}"), ("API Keys:", f" {_setup.get_env_path()}"), ("Data:", f" {hermes_home}/cron/, sessions/, logs/")): print(f" {_setup.color(label, _setup.Colors.YELLOW)}{value}") @@ -262,9 +259,7 @@ def _print_setup_summary(config: dict, hermes_home): _print_cmd_rows(_EDIT_WIZARD_ROWS) print() _print_cmd_rows(_EDIT_CONFIG_ROWS) - print(" Set a specific value") - print() - print(" Or edit the files directly:") + print(" Set a specific value\n\n Or edit the files directly:") for path in (_setup.get_config_path(), _setup.get_env_path()): print(f" {_setup.color(f'nano {path}', _setup.Colors.DIM)}") print() diff --git a/hermes_cli/setup_terminal.py b/hermes_cli/setup_terminal.py index 7ec7b268f8..1ed55818a9 100644 --- a/hermes_cli/setup_terminal.py +++ b/hermes_cli/setup_terminal.py @@ -270,8 +270,7 @@ def _setup_backend_plugin(config: dict, backend: str) -> None: _BUILTIN_TERMINAL_BACKENDS = [ ("local", "Local - run directly on this machine (default)"), ("docker", "Docker - isolated container with configurable resources"), - ("modal", "Modal - serverless cloud sandbox"), - ("ssh", "SSH - run on a remote machine"), + ("modal", "Modal - serverless cloud sandbox"), ("ssh", "SSH - run on a remote machine"), ("daytona", "Daytona - persistent cloud development environment"), ("vercel_sandbox", "Vercel Sandbox - cloud microVM with snapshot filesystem persistence")] _TERMINAL_BACKEND_SETUP = { diff --git a/hermes_cli/setup_whatsapp_cloud.py b/hermes_cli/setup_whatsapp_cloud.py index 912b22e5f9..44750bd9f5 100644 --- a/hermes_cli/setup_whatsapp_cloud.py +++ b/hermes_cli/setup_whatsapp_cloud.py @@ -132,9 +132,7 @@ def _prompt_validated( # --- Wizard def _header(title: str) -> None: - print("─" * 50) - print(title) - print("─" * 50) + _lines("─" * 50, title, "─" * 50) def _lines(*lines: str) -> None: diff --git a/hermes_cli/status.py b/hermes_cli/status.py index fd0eeea74a..1bbfd6de33 100644 --- a/hermes_cli/status.py +++ b/hermes_cli/status.py @@ -40,12 +40,12 @@ def _row(name: str, ok: bool, text: str, width: int = 12, sep: str = " ") -> No def _detail(label: str, value) -> None: """Print an indented ``label: value`` detail line under a status row.""" - print(f" {label:<12}{value}") + _kv(label, value, " ", 12) -def _kv(label: str, value) -> None: +def _kv(label: str, value, indent: str = " ", width: int = 14) -> None: """Print a `` Label: value`` line (label padded to the 14-col status layout).""" - print(f" {label:<14}{value}") + print(f"{indent}{label:<{width}}{value}") def _kv_flag(label: str, ok, on: str, off: str) -> None: diff --git a/hermes_cli/status_auth.py b/hermes_cli/status_auth.py index 2d4fa3981c..84b2baadf9 100644 --- a/hermes_cli/status_auth.py +++ b/hermes_cli/status_auth.py @@ -2,6 +2,8 @@ Origin helpers (``_row``, ``_first_env_value``, ...) are resolved through the ``hermes_cli.status`` module object so tests that monkeypatch that module keep working.""" +from datetime import datetime, timezone + from hermes_cli.auth import AuthError from hermes_cli.nous_account import ( format_nous_portal_entitlement_message, get_nous_portal_account_info) @@ -14,7 +16,6 @@ def _format_iso_timestamp(value) -> str: text = value.strip() if isinstance(value, str) else "" if not text: return "(unknown)" - from datetime import datetime, timezone try: parsed = datetime.fromisoformat(text[:-1] + "+00:00" if text.endswith("Z") else text) except Exception: @@ -25,7 +26,6 @@ def _format_iso_timestamp(value) -> str: def _qwen_expiry(expires_at_ms) -> str: - from datetime import datetime, timezone return datetime.fromtimestamp(int(expires_at_ms) / 1000, tz=timezone.utc).isoformat() diff --git a/hermes_cli/telegram_managed_bot.py b/hermes_cli/telegram_managed_bot.py index b25c64f7b3..79054f7c72 100644 --- a/hermes_cli/telegram_managed_bot.py +++ b/hermes_cli/telegram_managed_bot.py @@ -84,8 +84,7 @@ def print_qr_code(url: str, *, include_link: bool = True) -> None: def create_pairing( api_url: str | None = None, bot_name: str = DEFAULT_BOT_NAME, timeout: float = 10.0 ) -> TelegramPairing | None: - """POST a pairing; returns deep link, QR payload, public id and the secret poll token (used - only as a bearer credential while polling).""" + """POST a pairing; the returned poll token is only used as a bearer credential while polling.""" try: resp = httpx.post(f"{_api_url(api_url)}/v1/telegram/pairings", json={"bot_name": bot_name}, timeout=timeout) if resp.status_code not in (200, 201): @@ -122,14 +121,6 @@ def poll_pairing_result_once( _parse_owner_user_id(data.get("owner_user_id"))) -def _try_poll(api_url: str | None, pairing: TelegramPairing) -> TelegramBotSetupResult | None: - """One poll attempt; transport/JSON errors count as 'not ready yet'.""" - try: - return poll_pairing_result_once(api_url, pairing) - except (httpx.HTTPError, ValueError): - return None - - def poll_for_setup_result( api_url: str | None, pairing: TelegramPairing, timeout: float = DEFAULT_POLL_TIMEOUT, interval: float = POLL_INTERVAL, on_tick=None) -> Optional[TelegramBotSetupResult]: @@ -140,8 +131,11 @@ def poll_for_setup_result( while time.monotonic() < deadline: if on_tick: on_tick(time.monotonic() - start) - if result := _try_poll(api_url, pairing): - return result + try: # transport/JSON errors count as 'not ready yet' + if result := poll_pairing_result_once(api_url, pairing): + return result + except (httpx.HTTPError, ValueError): + pass time.sleep(interval) return None