feat(tui): SGR mouse fallback, focus partition highlights, multi-trigger context menus & box tui

- bin/muse-tui.py:
  * Parse raw SGR 1006 (\033[<btn;x;yM/m) and Xterm mouse escape sequences in _handle_escape_sequence fallback.
  * Multi-trigger context menus: Button 3, Button 2, Ctrl/Shift/Alt+Click, double-click, click on active item, or click [⚡] / [sid] target.
  * Render permanent [⚡] action target across all sidebar thread rows.
  * Separate focus partitions for FLEET AGENTS and SIDECHATS with partition-specific wheel scrolling and keyboard navigation (j/k, Enter, h/l).
  * Space key support in NORMAL mode to open context menus.
  * Active pane highlighting and updated footer hints.
- bin/super-cli.py:
  * Add 'box tui' command dispatching directly to muse-tui.py --mode box.
- tests:
  * Add unit tests in test_context_menus.py, test_focus_highlight.py, and test_main_nav.py (51/51 passing).
This commit is contained in:
operator
2026-10-06 19:29:22 +00:00
parent 66c8900a58
commit 4998ffddb6
5 changed files with 1936 additions and 340 deletions
+142
View File
@@ -0,0 +1,142 @@
#!/usr/bin/env python3
"""
test_focus_highlight.py — Comprehensive tests verifying active portion highlighting in MuseTUI:
1. Sidebar focused (focus_pane="sidebar", editor_mode="NORMAL") highlights sidebar header,
vertical pane divider, selected thread cursor, and bottom status bar hints.
2. Transcript focused (focus_pane="transcript", editor_mode="NORMAL") highlights transcript header,
header underline rule, vertical divider, and bottom status bar hints.
3. Composer active (editor_mode="INSERT") prominently highlights bottom composer divider
and status hints without distracting pane navigation highlights.
"""
import unittest
from unittest.mock import MagicMock
import importlib.util
from pathlib import Path
REPO_ROOT = Path("/home/super/Projects/NetVM")
TUI_PATH = REPO_ROOT / "bin" / "muse-tui.py"
spec = importlib.util.spec_from_file_location("muse_tui", str(TUI_PATH))
muse_mod = importlib.util.module_from_spec(spec)
spec.loader.exec_module(muse_mod)
class TestActivePortionHighlighting(unittest.TestCase):
def setUp(self):
self.mock_stdscr = MagicMock()
self.mock_stdscr.getmaxyx.return_value = (30, 100)
self.tui = muse_mod.MuseTUI(self.mock_stdscr, initial_mode="muse", initial_node="muse")
self.calls = []
def record_addstr(win, y, x, text, attr=0):
self.calls.append((y, x, text, attr))
self.tui.safe_addstr = record_addstr
self.tui.toast_time = 0
self.tui.data.nodes = ["muse", "646", "pip"]
self.tui.data.active_node = "muse"
self.tui.data.active_thread_id = "test_thread"
self.tui.data.active_thread_title = "Work Thread"
self.tui.data.threads_cache["muse"] = [
{"session_id": "test_thread", "title": "Work Thread", "is_main": False},
{"session_id": "main_id", "title": "Main Chat", "is_main": True},
]
self.tui.data.history_cache[("muse", "test_thread")] = [
{"role": "user", "text": "Hello agent", "seq": 1, "message_id": "m1"},
{"role": "assistant", "text": "Hello user", "seq": 2, "message_id": "m2"},
]
def test_sidebar_focused_highlight(self):
self.tui.focus_pane = "sidebar"
self.tui.editor_mode = "NORMAL"
# 1. Render Muse View
self.calls.clear()
self.tui._render_muse_view(2, 0, 24, 100)
rendered_texts = [c[2] for c in self.calls]
full_text = " ".join(rendered_texts)
# Sidebar header has [● FOCUS] badge
self.assertTrue(any("[● FOCUS] FLEET AGENTS" in t for t in rendered_texts),
f"Expected [● FOCUS] in sidebar header. Got:\n{full_text}")
# Vertical divider has heavy vertical char ┃
self.assertTrue(any("┃" in t for t in rendered_texts),
"Expected vertical divider '┃' when pane is focused")
# Transcript header does NOT have [● FOCUSED] badge
self.assertFalse(any("[● FOCUSED]" in t for t in rendered_texts),
"Transcript header should not be [● FOCUSED] when sidebar is active")
# 2. Render Bottom Bar
self.calls.clear()
self.tui._render_bottom_bar(27, 0, 3, 100)
bottom_texts = [c[2] for c in self.calls]
# Active pane divider has SIDEBAR highlight
self.assertTrue(any("ACTIVE PANE: SIDEBAR" in t for t in bottom_texts),
f"Expected ACTIVE PANE: SIDEBAR in bottom divider. Got:\n{bottom_texts}")
# Status hints show SIDEBAR FOCUSED
self.assertTrue(any("SIDEBAR FOCUSED" in t for t in bottom_texts),
f"Expected SIDEBAR FOCUSED in hints. Got:\n{bottom_texts}")
def test_transcript_focused_highlight(self):
self.tui.focus_pane = "transcript"
self.tui.editor_mode = "NORMAL"
# 1. Render Muse View
self.calls.clear()
self.tui._render_muse_view(2, 0, 24, 100)
rendered_texts = [c[2] for c in self.calls]
# Transcript header has [● FOCUSED] badge
self.assertTrue(any("[● FOCUSED] Thread:" in t for t in rendered_texts),
f"Expected [● FOCUSED] in transcript header. Got:\n{rendered_texts}")
# Transcript horizontal divider has heavy rule ━
self.assertTrue(any("━" in t for t in rendered_texts),
"Expected transcript underline divider '━' when transcript is focused")
# Sidebar header does NOT have [● FOCUS] badge
self.assertFalse(any("[● FOCUS] FLEET AGENTS" in t for t in rendered_texts),
"Sidebar should not have [● FOCUS] when transcript is active")
# 2. Render Bottom Bar
self.calls.clear()
self.tui._render_bottom_bar(27, 0, 3, 100)
bottom_texts = [c[2] for c in self.calls]
self.assertTrue(any("ACTIVE PANE: TRANSCRIPT" in t for t in bottom_texts),
f"Expected ACTIVE PANE: TRANSCRIPT in bottom divider. Got:\n{bottom_texts}")
self.assertTrue(any("TRANSCRIPT FOCUSED" in t for t in bottom_texts),
f"Expected TRANSCRIPT FOCUSED in hints. Got:\n{bottom_texts}")
def test_insert_mode_composer_highlight(self):
self.tui.editor_mode = "INSERT"
# 1. Render Bottom Bar
self.calls.clear()
self.tui._render_bottom_bar(27, 0, 3, 100)
bottom_texts = [c[2] for c in self.calls]
self.assertTrue(any("COMPOSER: INSERT MODE ACTIVE" in t for t in bottom_texts),
f"Expected COMPOSER: INSERT MODE ACTIVE in divider. Got:\n{bottom_texts}")
self.assertTrue(any("INSERT ACTIVE" in t for t in bottom_texts),
f"Expected INSERT ACTIVE in hints. Got:\n{bottom_texts}")
# 2. Render Muse View - neither pane should show [● FOCUS] / [● FOCUSED]
self.calls.clear()
self.tui._render_muse_view(2, 0, 24, 100)
rendered_texts = [c[2] for c in self.calls]
self.assertFalse(any("[● FOCUS] FLEET AGENTS" in t for t in rendered_texts),
"Sidebar should not claim active focus in INSERT mode")
self.assertFalse(any("[● FOCUSED] Thread:" in t for t in rendered_texts),
"Transcript should not claim active focus in INSERT mode")
if __name__ == "__main__":
unittest.main()