From deb9f3c1bd3286c246df6392d95c5ea050b86769 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Thu, 3 Sep 2026 17:00:26 -0700 Subject: [PATCH] =?UTF-8?q?simplify(compat):=20hermes=5Fcli/commands=20?= =?UTF-8?q?=E2=80=94=20drop=20the=20last=20PEP=20562=20lazy=20re-export=20?= =?UTF-8?q?hook=20(25=20names),=20repoint=2010=20callers=20+=2011=20test?= =?UTF-8?q?=20files=20to=20commands=5Fplatforms/commands=5Fcompletion?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- gateway/relay/ws_transport.py | 2 +- gateway/run.py | 2 +- hermes_cli/cli_tui_mixin.py | 2 +- hermes_cli/commands.py | 23 --------- hermes_cli/commands_platforms.py | 8 +-- hermes_cli/slack_cli.py | 4 +- plugins/platforms/discord/adapter.py | 2 +- plugins/platforms/slack/adapter.py | 4 +- plugins/platforms/telegram/adapter.py | 4 +- plugins/platforms/telegram/inline_picker.py | 2 +- tests/agent/test_plan_prompt.py | 2 +- tests/gateway/test_background_command.py | 2 +- tests/gateway/test_discord_slash_commands.py | 4 +- .../test_reload_skills_discord_resync.py | 4 +- tests/gateway/test_telegram_forum_commands.py | 4 +- tests/hermes_cli/test_approvals_command.py | 11 ++--- .../test_at_context_completion_filter.py | 2 +- tests/hermes_cli/test_commands.py | 49 ++++++------------- .../test_discord_skill_clamp_warning.py | 4 +- tests/hermes_cli/test_path_completion.py | 2 +- tests/test_tui_gateway_server.py | 2 +- tui_gateway/methods_complete.py | 2 +- 22 files changed, 44 insertions(+), 97 deletions(-) diff --git a/gateway/relay/ws_transport.py b/gateway/relay/ws_transport.py index 3dfbedae22..fbf35539d7 100644 --- a/gateway/relay/ws_transport.py +++ b/gateway/relay/ws_transport.py @@ -122,7 +122,7 @@ def _normalize_slack_parent_command(text: str, message_type: MessageType) -> tup if not parent_parts or parent_parts[0] != "/hermes": return text, message_type - from hermes_cli.commands import slack_subcommand_map + from hermes_cli.commands_platforms import slack_subcommand_map payload = parent_parts[1].strip() if len(parent_parts) > 1 else "" subcommand_map = slack_subcommand_map() diff --git a/gateway/run.py b/gateway/run.py index 8f93ea28de..b45327d6ce 100644 --- a/gateway/run.py +++ b/gateway/run.py @@ -829,7 +829,7 @@ def _telegramize_command_mentions(text: str, platform: Any) -> str: if platform_value != "telegram": return text - from hermes_cli.commands import _sanitize_telegram_name + from hermes_cli.commands_platforms import _sanitize_telegram_name def _replace(match: re.Match[str]) -> str: sanitized = _sanitize_telegram_name(match.group(1)) diff --git a/hermes_cli/cli_tui_mixin.py b/hermes_cli/cli_tui_mixin.py index 07338043b2..10512f74e7 100644 --- a/hermes_cli/cli_tui_mixin.py +++ b/hermes_cli/cli_tui_mixin.py @@ -15,7 +15,7 @@ import threading import time from agent.interrupt_compat import request_hard_interrupt -from hermes_cli.commands import SlashCommandAutoSuggest, SlashCommandCompleter +from hermes_cli.commands_completion import SlashCommandAutoSuggest, SlashCommandCompleter from pathlib import Path from prompt_toolkit.filters import Condition from prompt_toolkit.history import FileHistory diff --git a/hermes_cli/commands.py b/hermes_cli/commands.py index 13173f05f1..7441606d0f 100644 --- a/hermes_cli/commands.py +++ b/hermes_cli/commands.py @@ -467,26 +467,3 @@ def _iter_plugin_command_entries() -> list[tuple[str, str, str]]: return [(name, str(meta.get("description") or f"Run /{name}"), str(meta.get("args_hint") or "").strip()) for name, meta in commands.items() if isinstance(name, str) and isinstance(meta, dict)] - - -# Lazy re-exports (PEP 562): platform derivations and the prompt_toolkit completer live in -# sibling modules; their names stay importable here (``from hermes_cli.commands import X``, -# ``patch("hermes_cli.commands.X")``) while this module stays import-light for the gateway. -_LAZY_EXPORTS: dict[str, str] = {name: "hermes_cli.commands_platforms" for name in ( - "_CMD_NAME_LIMIT", "_DEFAULT_TELEGRAM_MENU_MAX_COMMANDS", "_SLACK_RESERVED_COMMANDS", - "_SLACK_VIA_HERMES_ONLY", "_TELEGRAM_MENU_PRIORITY", "_clamp_command_names", - "_collect_gateway_skill_entries", "_iter_gateway_skills", "_prioritize_telegram_menu_candidates", - "_requires_argument", "_sanitize_slack_name", "_sanitize_telegram_name", - "_telegram_command_menu_config", "_truncate_desc", "discord_skill_commands_by_category", - "slack_app_manifest", "slack_native_slashes", "slack_subcommand_map", "telegram_bot_commands", - "telegram_menu_commands", "telegram_menu_max_commands")} -_LAZY_EXPORTS.update({name: "hermes_cli.commands_completion" for name in ( - "SlashCommandCompleter", "SlashCommandAutoSuggest", "_file_size_label", "_short_desc")}) - - -def __getattr__(name: str): - module = _LAZY_EXPORTS.get(name) - if module is None: - raise AttributeError(f"module {__name__!r} has no attribute {name!r}") - import importlib - return getattr(importlib.import_module(module), name) diff --git a/hermes_cli/commands_platforms.py b/hermes_cli/commands_platforms.py index cbccf01a68..db664155c6 100644 --- a/hermes_cli/commands_platforms.py +++ b/hermes_cli/commands_platforms.py @@ -148,9 +148,7 @@ def _prioritize_telegram_menu_candidates( """Order ``(final_name, description, source, raw_name)`` candidates; the default priority applies to core only, "replace" mode ignores it. ``raw_name`` is the pre-clamp name so a configured long command stays addressable.""" - # Lazy origin import: tests patch ``hermes_cli.commands._telegram_command_menu_config``. - from hermes_cli.commands import _telegram_command_menu_config as menu_config - menu_cfg = menu_config() + menu_cfg = _telegram_command_menu_config() configured_rank = _sanitized_rank(menu_cfg["priority"]) default_rank = _sanitized_rank(_TELEGRAM_MENU_PRIORITY) tiers = _TELEGRAM_PRIORITY_TIERS[menu_cfg["priority_mode"]] @@ -272,9 +270,7 @@ def telegram_menu_commands(max_commands: int = 100) -> tuple[list[tuple[str, str telegram-disabled skills excluded). Tiers keep relative order unless named in ``platforms.telegram.extra.command_menu.priority`` — applied *before* the cap, so a prioritized dynamic command can displace an unprioritized core command.""" - # Lazy origin import: tests patch ``hermes_cli.commands.telegram_bot_commands``. - from hermes_cli.commands import telegram_bot_commands as bot_commands - core_commands = list(bot_commands(include_plugins=False)) + core_commands = list(telegram_bot_commands(include_plugins=False)) entries, hidden_count = _collect_gateway_skill_entries( platform="telegram", max_slots=None, reserved_names={n for n, _ in core_commands}, desc_limit=40, sanitize_name=_sanitize_telegram_name) diff --git a/hermes_cli/slack_cli.py b/hermes_cli/slack_cli.py index 354133d2a3..1c89955d8e 100644 --- a/hermes_cli/slack_cli.py +++ b/hermes_cli/slack_cli.py @@ -18,7 +18,7 @@ def _build_full_manifest( Other sections (OAuth scopes, socket mode) are sensible Hermes defaults, tweakable in the Slack UI after pasting. """ - from hermes_cli.commands import slack_app_manifest + from hermes_cli.commands_platforms import slack_app_manifest if messaging_experience is None: messaging_experience = "assistant" if include_assistant else "none" messaging_experience = str(messaging_experience).strip().lower() @@ -113,7 +113,7 @@ def slack_manifest_command(args) -> int: messaging_experience = "assistant" if slashes_only: - from hermes_cli.commands import slack_app_manifest + from hermes_cli.commands_platforms import slack_app_manifest manifest = slack_app_manifest()["features"]["slash_commands"] else: manifest = _build_full_manifest( diff --git a/plugins/platforms/discord/adapter.py b/plugins/platforms/discord/adapter.py index 6101704e57..09422b9693 100644 --- a/plugins/platforms/discord/adapter.py +++ b/plugins/platforms/discord/adapter.py @@ -4671,7 +4671,7 @@ class DiscordAdapter(BasePlatformAdapter): def _refresh_skill_catalog_state(self) -> None: """Re-scan disk and repopulate ``self._skill_entries``/``_skill_lookup`` in place. No Discord API calls: autocomplete and handler read these attributes directly.""" - from hermes_cli.commands import discord_skill_commands_by_category + from hermes_cli.commands_platforms import discord_skill_commands_by_category reserved = getattr(self, "_skill_group_reserved_names", set()) categories, uncategorized, hidden = discord_skill_commands_by_category( reserved_names=set(reserved), diff --git a/plugins/platforms/slack/adapter.py b/plugins/platforms/slack/adapter.py index 0ad49182de..6afa048c8c 100644 --- a/plugins/platforms/slack/adapter.py +++ b/plugins/platforms/slack/adapter.py @@ -1479,7 +1479,7 @@ class SlackAdapter(BasePlatformAdapter): # Every COMMAND_REGISTRY command is a native slash via one regex matcher. Commands must # ALSO be declared in the app manifest (`hermes slack manifest`): Socket Mode won't # deliver undeclared commands at all. - from hermes_cli.commands import slack_native_slashes + from hermes_cli.commands_platforms import slack_native_slashes _slash_names = [name for name, _d, _h in slack_native_slashes()] if _slash_names: _slash_pattern = re.compile( @@ -5257,7 +5257,7 @@ class SlackAdapter(BasePlatformAdapter): if slash_name not in {"hermes", ""}: return f"/{slash_name}" if not raw_text else f"/{slash_name} {raw_text}" legacy_text = raw_text.strip() - from hermes_cli.commands import slack_subcommand_map + from hermes_cli.commands_platforms import slack_subcommand_map subcommand_map = slack_subcommand_map() subcommand_map["compact"] = "/compress" first_word = legacy_text.split()[0] if legacy_text.split() else "" diff --git a/plugins/platforms/telegram/adapter.py b/plugins/platforms/telegram/adapter.py index 9d4737371e..36da8a65fb 100644 --- a/plugins/platforms/telegram/adapter.py +++ b/plugins/platforms/telegram/adapter.py @@ -2522,7 +2522,7 @@ class TelegramAdapter(BasePlatformAdapter): """Register the command menu (from COMMAND_REGISTRY) in every scope — Telegram picks the narrowest matching one per chat type; forum topics are handled lazily by _ensure_forum_commands.""" from telegram import BotCommand, BotCommandScopeAllPrivateChats, BotCommandScopeAllGroupChats, BotCommandScopeDefault - from hermes_cli.commands import telegram_menu_commands, telegram_menu_max_commands + from hermes_cli.commands_platforms import telegram_menu_commands, telegram_menu_max_commands if not self._bot: return # Telegram allows 100 commands but has an undocumented ~4KB payload limit; default cap 60. @@ -5630,7 +5630,7 @@ class TelegramAdapter(BasePlatformAdapter): if chat_id in self._forum_command_registered: return from telegram import BotCommand, BotCommandScopeChat - from hermes_cli.commands import telegram_menu_commands, telegram_menu_max_commands + from hermes_cli.commands_platforms import telegram_menu_commands, telegram_menu_max_commands menu_commands, _ = telegram_menu_commands(max_commands=telegram_menu_max_commands()) bot_commands = [BotCommand(name, desc) for name, desc in menu_commands] await self._bot.set_my_commands(bot_commands, scope=BotCommandScopeChat(chat_id=chat_id)) diff --git a/plugins/platforms/telegram/inline_picker.py b/plugins/platforms/telegram/inline_picker.py index fa3267ac54..59b00b7760 100644 --- a/plugins/platforms/telegram/inline_picker.py +++ b/plugins/platforms/telegram/inline_picker.py @@ -33,7 +33,7 @@ def collect_inline_catalog() -> List[Dict[str, str]]: catalog.append({"name": name, "description": desc or ""}) try: - from hermes_cli.commands import _collect_gateway_skill_entries, _sanitize_telegram_name, telegram_bot_commands + from hermes_cli.commands_platforms import _collect_gateway_skill_entries, _sanitize_telegram_name, telegram_bot_commands except Exception: # pragma: no cover - defensive logger.debug("inline picker: commands registry unavailable", exc_info=True) return catalog diff --git a/tests/agent/test_plan_prompt.py b/tests/agent/test_plan_prompt.py index 63cf357ce9..87abbe0f26 100644 --- a/tests/agent/test_plan_prompt.py +++ b/tests/agent/test_plan_prompt.py @@ -68,7 +68,7 @@ class TestPlanRegistryWiring: assert "plan" in GATEWAY_KNOWN_COMMANDS def test_plan_in_telegram_bot_commands(self): - from hermes_cli.commands import telegram_bot_commands + from hermes_cli.commands_platforms import telegram_bot_commands names = {n for n, _ in telegram_bot_commands()} assert "plan" in names diff --git a/tests/gateway/test_background_command.py b/tests/gateway/test_background_command.py index c137542285..c240abcdfc 100644 --- a/tests/gateway/test_background_command.py +++ b/tests/gateway/test_background_command.py @@ -193,7 +193,7 @@ class TestBackgroundInCLICommands: def test_bg_autocompletes(self): """The /bg and /btw commands appear in autocomplete results.""" pytest.importorskip("prompt_toolkit") - from hermes_cli.commands import SlashCommandCompleter + from hermes_cli.commands_completion import SlashCommandCompleter from prompt_toolkit.document import Document completer = SlashCommandCompleter() diff --git a/tests/gateway/test_discord_slash_commands.py b/tests/gateway/test_discord_slash_commands.py index 4f602a8768..e636901a70 100644 --- a/tests/gateway/test_discord_slash_commands.py +++ b/tests/gateway/test_discord_slash_commands.py @@ -530,7 +530,7 @@ def test_register_skill_command_callback_dispatches_by_name(adapter): ] with patch( - "hermes_cli.commands.discord_skill_commands_by_category", + "hermes_cli.commands_platforms.discord_skill_commands_by_category", return_value=(mock_categories, mock_uncategorized, 0), ): adapter._register_slash_commands() @@ -580,7 +580,7 @@ def test_register_skill_command_payload_fits_discord_8kb_limit(adapter): ] with patch( - "hermes_cli.commands.discord_skill_commands_by_category", + "hermes_cli.commands_platforms.discord_skill_commands_by_category", return_value=(large_categories, [], 0), ): adapter._register_slash_commands() diff --git a/tests/gateway/test_reload_skills_discord_resync.py b/tests/gateway/test_reload_skills_discord_resync.py index fa1b6bcf3f..e14562ce6b 100644 --- a/tests/gateway/test_reload_skills_discord_resync.py +++ b/tests/gateway/test_reload_skills_discord_resync.py @@ -69,7 +69,7 @@ class TestRefreshSkillGroup: ) monkeypatch.setattr( - "hermes_cli.commands.discord_skill_commands_by_category", + "hermes_cli.commands_platforms.discord_skill_commands_by_category", fake_collector, ) @@ -113,7 +113,7 @@ class TestRegisterSkillGroupUsesInstanceState: 0, ) monkeypatch.setattr( - "hermes_cli.commands.discord_skill_commands_by_category", + "hermes_cli.commands_platforms.discord_skill_commands_by_category", fake_collector, ) diff --git a/tests/gateway/test_telegram_forum_commands.py b/tests/gateway/test_telegram_forum_commands.py index 4ab831e2dd..9cdbe3a109 100644 --- a/tests/gateway/test_telegram_forum_commands.py +++ b/tests/gateway/test_telegram_forum_commands.py @@ -35,7 +35,7 @@ async def test_ensure_forum_commands_registers_once(): adapter = _make_test_adapter() msg = _forum_message(chat_id=-123, is_forum=True) - with patch("hermes_cli.commands.telegram_menu_commands") as mock_menu: + with patch("hermes_cli.commands_platforms.telegram_menu_commands") as mock_menu: mock_menu.return_value = ([("new", "Start new session"), ("help", "Show help")], 0) with patch("telegram.BotCommand") as MockBotCommand: instances = [] @@ -73,7 +73,7 @@ async def test_ensure_forum_commands_race_safety(): adapter = _make_test_adapter() msg = _forum_message(chat_id=-789, is_forum=True) - with patch("hermes_cli.commands.telegram_menu_commands") as mock_menu: + with patch("hermes_cli.commands_platforms.telegram_menu_commands") as mock_menu: mock_menu.return_value = ([("new", "Start new session")], 0) with patch("telegram.BotCommand"): with patch("telegram.BotCommandScopeChat"): diff --git a/tests/hermes_cli/test_approvals_command.py b/tests/hermes_cli/test_approvals_command.py index 011ba7de2c..470869b616 100644 --- a/tests/hermes_cli/test_approvals_command.py +++ b/tests/hermes_cli/test_approvals_command.py @@ -6,14 +6,9 @@ from unittest.mock import MagicMock, patch import yaml from cli import HermesCLI -from hermes_cli.commands import ( - GATEWAY_KNOWN_COMMANDS, - SUBCOMMANDS, - SlashCommandCompleter, - gateway_help_lines, - resolve_command, - telegram_bot_commands, -) +from hermes_cli.commands import GATEWAY_KNOWN_COMMANDS, SUBCOMMANDS, gateway_help_lines, resolve_command +from hermes_cli.commands_completion import SlashCommandCompleter +from hermes_cli.commands_platforms import telegram_bot_commands from prompt_toolkit.completion import CompleteEvent from prompt_toolkit.document import Document diff --git a/tests/hermes_cli/test_at_context_completion_filter.py b/tests/hermes_cli/test_at_context_completion_filter.py index d6121753c8..1ba0bfee1e 100644 --- a/tests/hermes_cli/test_at_context_completion_filter.py +++ b/tests/hermes_cli/test_at_context_completion_filter.py @@ -14,7 +14,7 @@ from __future__ import annotations from pathlib import Path from typing import Iterable -from hermes_cli.commands import SlashCommandCompleter +from hermes_cli.commands_completion import SlashCommandCompleter def _run(tmp_path: Path, word: str) -> list[tuple[str, str]]: diff --git a/tests/hermes_cli/test_commands.py b/tests/hermes_cli/test_commands.py index 3f290e05d3..70fb910bbe 100644 --- a/tests/hermes_cli/test_commands.py +++ b/tests/hermes_cli/test_commands.py @@ -3,30 +3,9 @@ from prompt_toolkit.completion import CompleteEvent from prompt_toolkit.document import Document -from hermes_cli.commands import ( - COMMAND_REGISTRY, - COMMANDS, - COMMANDS_BY_CATEGORY, - CommandDef, - GATEWAY_KNOWN_COMMANDS, - SUBCOMMANDS, - SlashCommandAutoSuggest, - SlashCommandCompleter, - _CMD_NAME_LIMIT, - _SLACK_RESERVED_COMMANDS, - _SLACK_VIA_HERMES_ONLY, - _clamp_command_names, - _sanitize_telegram_name, - command_desktop_meta, - gateway_help_lines, - infer_argument_mode, - resolve_command, - slack_app_manifest, - slack_native_slashes, - slack_subcommand_map, - telegram_bot_commands, - telegram_menu_commands, -) +from hermes_cli.commands import COMMAND_REGISTRY, COMMANDS, COMMANDS_BY_CATEGORY, CommandDef, GATEWAY_KNOWN_COMMANDS, SUBCOMMANDS, command_desktop_meta, gateway_help_lines, infer_argument_mode, resolve_command +from hermes_cli.commands_completion import SlashCommandAutoSuggest, SlashCommandCompleter +from hermes_cli.commands_platforms import _CMD_NAME_LIMIT, _SLACK_RESERVED_COMMANDS, _SLACK_VIA_HERMES_ONLY, _clamp_command_names, _sanitize_telegram_name, slack_app_manifest, slack_native_slashes, slack_subcommand_map, telegram_bot_commands, telegram_menu_commands def _completions(completer: SlashCommandCompleter, text: str): @@ -589,7 +568,7 @@ class TestGatewaySkillCollector: def test_long_skill_name_clamped_but_cmd_key_retained(self, tmp_path): from unittest.mock import patch - from hermes_cli.commands import _collect_gateway_skill_entries + from hermes_cli.commands_platforms import _collect_gateway_skill_entries long_name = "this-is-a-very-long-skill-name-that-exceeds-limit" skills_dir = tmp_path / "skills" @@ -617,7 +596,7 @@ class TestGatewaySkillCollector: def test_cap_trims_skills_only(self, tmp_path): from unittest.mock import patch - from hermes_cli.commands import _collect_gateway_skill_entries + from hermes_cli.commands_platforms import _collect_gateway_skill_entries skills_dir = tmp_path / "skills" skills_dir.mkdir() @@ -814,11 +793,11 @@ class TestTelegramMenuCommands: menu_cfg = {"max_commands": 2, "priority_mode": "prepend", "priority": ["gym"]} with ( - patch("hermes_cli.commands.telegram_bot_commands", return_value=fake_core), + patch("hermes_cli.commands_platforms.telegram_bot_commands", return_value=fake_core), patch("agent.skill_commands.get_skill_commands", return_value=fake_cmds), patch("hermes_cli.plugins.get_plugin_commands", return_value=fake_plugins), patch("tools.skills_tool.SKILLS_DIR", local_dir), - patch("hermes_cli.commands._telegram_command_menu_config", return_value=menu_cfg), + patch("hermes_cli.commands_platforms._telegram_command_menu_config", return_value=menu_cfg), ): menu, hidden = telegram_menu_commands(max_commands=len(fake_core)) @@ -855,10 +834,10 @@ class TestTelegramMenuCommands: menu_cfg = {"max_commands": 2, "priority_mode": "prepend", "priority": []} with ( - patch("hermes_cli.commands.telegram_bot_commands", return_value=fake_core), + patch("hermes_cli.commands_platforms.telegram_bot_commands", return_value=fake_core), patch("agent.skill_commands.get_skill_commands", return_value=fake_cmds), patch("tools.skills_tool.SKILLS_DIR", local_dir), - patch("hermes_cli.commands._telegram_command_menu_config", return_value=menu_cfg), + patch("hermes_cli.commands_platforms._telegram_command_menu_config", return_value=menu_cfg), ): menu, hidden = telegram_menu_commands(max_commands=2) @@ -891,10 +870,10 @@ class TestTelegramMenuCommands: } with ( - patch("hermes_cli.commands.telegram_bot_commands", return_value=fake_core), + patch("hermes_cli.commands_platforms.telegram_bot_commands", return_value=fake_core), patch("agent.skill_commands.get_skill_commands", return_value=fake_cmds), patch("tools.skills_tool.SKILLS_DIR", local_dir), - patch("hermes_cli.commands._telegram_command_menu_config", return_value=menu_cfg), + patch("hermes_cli.commands_platforms._telegram_command_menu_config", return_value=menu_cfg), ): menu, hidden = telegram_menu_commands(max_commands=1) @@ -922,7 +901,7 @@ class TestTelegramMenuCommands: patch("hermes_cli.plugins.get_plugin_commands", return_value=fake_plugins), patch("agent.skill_commands.get_skill_commands", return_value={}), patch("tools.skills_tool.SKILLS_DIR", local_dir), - patch("hermes_cli.commands._telegram_command_menu_config", return_value=menu_cfg), + patch("hermes_cli.commands_platforms._telegram_command_menu_config", return_value=menu_cfg), ): menu, hidden = telegram_menu_commands(max_commands=1) @@ -957,7 +936,7 @@ class TestTelegramMenuCommands: def test_scalar_configured_priority_is_accepted_as_one_command(self): """The config CLI's scalar value form must work for a single priority.""" from unittest.mock import patch - from hermes_cli.commands import _telegram_command_menu_config + from hermes_cli.commands_platforms import _telegram_command_menu_config raw_config = { "platforms": { @@ -980,7 +959,7 @@ class TestTelegramMenuCommands: # Discord skill commands grouped by category # --------------------------------------------------------------------------- -from hermes_cli.commands import discord_skill_commands_by_category # noqa: E402 +from hermes_cli.commands_platforms import discord_skill_commands_by_category class TestDiscordSkillCommandsByCategory: diff --git a/tests/hermes_cli/test_discord_skill_clamp_warning.py b/tests/hermes_cli/test_discord_skill_clamp_warning.py index 8ea645a7bb..dcf88e4063 100644 --- a/tests/hermes_cli/test_discord_skill_clamp_warning.py +++ b/tests/hermes_cli/test_discord_skill_clamp_warning.py @@ -23,7 +23,7 @@ def test_clamp_collision_emits_warning_naming_both_skills( tmp_path: Path, caplog ) -> None: """Two skills with identical first 32 chars — warning names both.""" - from hermes_cli.commands import discord_skill_commands_by_category + from hermes_cli.commands_platforms import discord_skill_commands_by_category # Craft cmd_keys that share the first 32 chars. # 40-char prefix 'skill-collision-prefix-identical-first-32' @@ -98,7 +98,7 @@ def test_long_skill_name_preserves_cmd_key_through_by_category( This is the actual runtime path used by the Discord adapter via ``_refresh_skill_catalog_state``. """ - from hermes_cli.commands import discord_skill_commands_by_category + from hermes_cli.commands_platforms import discord_skill_commands_by_category skills_dir = tmp_path / "skills" skills_dir.mkdir() diff --git a/tests/hermes_cli/test_path_completion.py b/tests/hermes_cli/test_path_completion.py index 76a2721707..5ebd9163a0 100644 --- a/tests/hermes_cli/test_path_completion.py +++ b/tests/hermes_cli/test_path_completion.py @@ -7,7 +7,7 @@ import pytest from prompt_toolkit.document import Document from prompt_toolkit.formatted_text import to_plain_text -from hermes_cli.commands import SlashCommandCompleter, _file_size_label +from hermes_cli.commands_completion import SlashCommandCompleter, _file_size_label def _display_names(completions): diff --git a/tests/test_tui_gateway_server.py b/tests/test_tui_gateway_server.py index 24dd4a4f8a..ec28bc1191 100644 --- a/tests/test_tui_gateway_server.py +++ b/tests/test_tui_gateway_server.py @@ -11527,7 +11527,7 @@ def test_plugins_list_surfaces_loader_error(monkeypatch): def test_complete_slash_surfaces_completer_error(monkeypatch): with patch( - "hermes_cli.commands.SlashCommandCompleter", + "hermes_cli.commands_completion.SlashCommandCompleter", side_effect=Exception("no completer"), ): resp = server.handle_request( diff --git a/tui_gateway/methods_complete.py b/tui_gateway/methods_complete.py index ab238e4027..a7e5decc11 100644 --- a/tui_gateway/methods_complete.py +++ b/tui_gateway/methods_complete.py @@ -226,7 +226,7 @@ def _(rid, params: dict) -> dict: text = params.get("text", "") if not text.startswith("/"): return _ok(rid, {"items": []}) - from hermes_cli.commands import SlashCommandCompleter + from hermes_cli.commands_completion import SlashCommandCompleter from prompt_toolkit.document import Document from prompt_toolkit.formatted_text import to_plain_text from agent.skill_commands import get_skill_commands