hermes-agent/tests/tools/test_desktop_ui.py
Brooklyn Nicholson 70ba3c4828 feat(desktop): agent can focus panes + shared desktop-UI event bridge
Extract the open_preview emitter into a shared tools/desktop_ui bridge
(one gateway-injected sink, routed by HERMES_UI_SESSION_ID) and add a
second desktop-gated tool on top of it:

- focus_pane(chat|files|terminal|review|sessions) -> pane.reveal event.
  The desktop runs each pane's own reveal path (revealDesktopPane table)
  and only acts on the active window -- a background turn never moves the
  user's focus (desktop AGENTS.md: offer, don't hijack).

open_preview now emits through the same bridge. Both tools are check_fn
on HERMES_DESKTOP (zero footprint elsewhere), sitting beside
read_terminal/close_terminal in _HERMES_CORE_TOOLS.

Deliberately not adding run_slash: letting the agent fire slash commands
mid-turn (/model, /new, /clear) fights prompt-cache + conversation
invariants.
2026-07-22 12:13:01 -05:00

30 lines
884 B
Python

"""Tests for the desktop-only renderer-event bridge."""
import pytest
from tools import desktop_ui
@pytest.fixture(autouse=True)
def _reset_emitter():
desktop_ui.set_emitter(None)
yield
desktop_ui.set_emitter(None)
def test_unavailable_without_emitter():
assert desktop_ui.available() is False
assert desktop_ui.emit("preview.open", {"url": "x"}) is False
def test_routes_event_to_owning_window(monkeypatch):
monkeypatch.setattr(
desktop_ui, "get_session_env",
lambda name, default="": "win-7" if name == "HERMES_UI_SESSION_ID" else default,
)
seen = []
desktop_ui.set_emitter(lambda sid, event, payload: seen.append((sid, event, payload)))
assert desktop_ui.available() is True
assert desktop_ui.emit("pane.reveal", {"pane": "terminal"}) is True
assert seen == [("win-7", "pane.reveal", {"pane": "terminal"})]