From 42bffa276fd1b7de6207b8f841065603c634978c Mon Sep 17 00:00:00 2001 From: Shri Date: Wed, 18 Feb 2026 11:49:24 -0800 Subject: [PATCH] Fix UI bugs: welcome screen keybinds, group headers, deletion nav, command palette gaps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix wrong shortcut on welcome screen (k -> d for Delete Session) - Use __version__ instead of hardcoded version on welcome screen - Fix group header ordering: mount before first group member, not at top - Fix session deletion to jump to nearest neighbor instead of first session - Wire show_diff (v) and set_group (w) into command palette and COMMAND_MODE_MAP - Fix solarized dark/light hover states using distinct background colors - Use unicode arrows (▶/▼) for group headers instead of ASCII (>/v) --- tame/app.py | 21 +++++++++++++++++---- tame/ui/themes/builtin/solarized_dark.tcss | 2 +- tame/ui/themes/builtin/solarized_light.tcss | 2 +- tame/ui/widgets/command_palette.py | 2 ++ tame/ui/widgets/session_sidebar.py | 13 +++++++++++-- tame/ui/widgets/session_viewer.py | 5 +++-- 6 files changed, 35 insertions(+), 10 deletions(-) diff --git a/tame/app.py b/tame/app.py index a73a307..9ddbe31 100644 --- a/tame/app.py +++ b/tame/app.py @@ -149,6 +149,8 @@ class TAMEApp(App): "z": "pause_all", "u": "check_usage", "x": "clear_notifications", + "w": "set_group", + "v": "show_diff", "q": "quit", } @@ -648,6 +650,18 @@ def _confirm_kill_session(self, confirmed: bool | None) -> None: if session_id is None: return + # Determine the neighbor to switch to before removing the session + sessions = self._session_manager.list_sessions() + ids = [s.id for s in sessions] + next_session_id: str | None = None + try: + idx = ids.index(session_id) + if len(ids) > 1: + # Prefer the next session, fall back to previous + next_session_id = ids[idx + 1] if idx + 1 < len(ids) else ids[idx - 1] + except ValueError: + pass + # Clean up git worktree if one was created for this session try: session = self._session_manager.get_session(session_id) @@ -674,10 +688,9 @@ def _confirm_kill_session(self, confirmed: bool | None) -> None: sidebar.remove_session(session_id) viewer.remove_session(session_id) - # Switch to the next available session or clear - sessions = self._session_manager.list_sessions() - if sessions: - self._select_session(sessions[0].id) + # Switch to the nearest neighbor or clear + if next_session_id is not None: + self._select_session(next_session_id) else: self._active_session_id = None header = self.query_one(HeaderBar) diff --git a/tame/ui/themes/builtin/solarized_dark.tcss b/tame/ui/themes/builtin/solarized_dark.tcss index ed85bb9..12cccee 100644 --- a/tame/ui/themes/builtin/solarized_dark.tcss +++ b/tame/ui/themes/builtin/solarized_dark.tcss @@ -34,7 +34,7 @@ Screen { } .session-item:hover { - background: #073642; + background: #0a4a5c; } .session-item.--highlight { diff --git a/tame/ui/themes/builtin/solarized_light.tcss b/tame/ui/themes/builtin/solarized_light.tcss index 73a104f..eeb872a 100644 --- a/tame/ui/themes/builtin/solarized_light.tcss +++ b/tame/ui/themes/builtin/solarized_light.tcss @@ -34,7 +34,7 @@ Screen { } .session-item:hover { - background: #eee8d5; + background: #ddd6c1; } .session-item.--highlight { diff --git a/tame/ui/widgets/command_palette.py b/tame/ui/widgets/command_palette.py index 8b37251..5bd0866 100644 --- a/tame/ui/widgets/command_palette.py +++ b/tame/ui/widgets/command_palette.py @@ -25,6 +25,8 @@ ("z", "pause_all", "Pause All"), ("u", "check_usage", "Check Usage"), ("x", "clear_notifications", "Clear Notifications"), + ("w", "set_group", "Set Group"), + ("v", "show_diff", "Git Diff"), ("q", "quit", "Quit"), ] diff --git a/tame/ui/widgets/session_sidebar.py b/tame/ui/widgets/session_sidebar.py index 10c20a0..e6475ff 100644 --- a/tame/ui/widgets/session_sidebar.py +++ b/tame/ui/widgets/session_sidebar.py @@ -34,7 +34,7 @@ def on_mount(self) -> None: self._render_label() def _render_label(self) -> None: - arrow = ">" if self._collapsed else "v" + arrow = "▶" if self._collapsed else "▼" self.update(f"{arrow} {self._group_name}") @property @@ -120,7 +120,16 @@ def _ensure_group_header(self, group: str) -> None: header = GroupHeader(group) header.id = header_id scroll = self.query_one("#session-scroll", VerticalScroll) - scroll.mount(header, before=0) + # Find the first session in this group to insert the header before it + first_in_group = None + for item in scroll.query(SessionListItem): + if item.has_class(f"group-{group}"): + first_in_group = item + break + if first_in_group is not None: + scroll.mount(header, before=first_in_group) + else: + scroll.mount(header) def remove_session(self, session_id: str) -> None: """Remove a session item by its session_id.""" diff --git a/tame/ui/widgets/session_viewer.py b/tame/ui/widgets/session_viewer.py index 3faeaeb..4d19da5 100644 --- a/tame/ui/widgets/session_viewer.py +++ b/tame/ui/widgets/session_viewer.py @@ -11,6 +11,7 @@ from textual.timer import Timer from textual.widget import Widget +from tame import __version__ from tame.session.output_buffer import OutputBuffer from tame.ui.events import ViewerResized @@ -449,12 +450,12 @@ def _render_welcome(self) -> Text: " |_/_/ \\_\\_| |_|___|", ] subtitle = "Terminal Agent Management Environment" - version = "v0.1.0" + version = f"v{__version__}" shortcuts = [ ("Ctrl+Space", "Open Command Palette"), (" c", "New Session"), + (" d", "Delete Session"), (" n / p", "Next / Prev Session"), - (" k", "Kill Session"), (" s", "Toggle Sidebar"), (" q", "Quit"), ]