Coverage for src/lilbee/cli/tui/screens/sessions.py: 100%

37 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-09-28 17:20 +0000

1"""Full-screen Sessions view: browse and manage saved conversations.""" 

2 

3from __future__ import annotations 

4 

5from typing import TYPE_CHECKING, ClassVar 

6 

7from textual import on 

8from textual.app import ComposeResult 

9from textual.binding import BindingType 

10from textual.screen import Screen 

11 

12from lilbee.cli.tui.browse_bindings import BROWSE_LIST_BINDINGS, browse_back_bindings 

13from lilbee.cli.tui.widgets.session_list import SessionListPanel 

14 

15if TYPE_CHECKING: 

16 from lilbee.cli.tui.app import LilbeeApp 

17 

18 

19class SessionsScreen(Screen[None]): 

20 """Manage saved conversations: filter, resume, rename, delete, new.""" 

21 

22 app: LilbeeApp # type: ignore[assignment] 

23 

24 CSS_PATH = "sessions.tcss" 

25 

26 # The panel binds the list keys (j / k / g / G) with priority while focus is 

27 # inside it; these copies reach the panel from anywhere else on the screen. 

28 BINDINGS: ClassVar[list[BindingType]] = [ 

29 *browse_back_bindings(), 

30 *BROWSE_LIST_BINDINGS, 

31 ] 

32 

33 def compose(self) -> ComposeResult: 

34 from textual.widgets import Footer 

35 

36 from lilbee.cli.tui.widgets.bottom_bars import BottomBars 

37 from lilbee.cli.tui.widgets.status_bar import ViewTabs 

38 from lilbee.cli.tui.widgets.task_bar import TaskBar 

39 from lilbee.cli.tui.widgets.top_bars import TopBars 

40 

41 with TopBars(): 

42 yield ViewTabs() 

43 yield SessionListPanel(focus_filter=False) 

44 with BottomBars(): 

45 yield TaskBar() 

46 yield Footer() 

47 

48 def action_go_back(self) -> None: 

49 self.app.go_back() 

50 

51 async def action_cursor_down(self) -> None: 

52 await self.query_one(SessionListPanel).action_cursor_down() 

53 

54 async def action_cursor_up(self) -> None: 

55 await self.query_one(SessionListPanel).action_cursor_up() 

56 

57 async def action_jump_top(self) -> None: 

58 await self.query_one(SessionListPanel).action_jump_top() 

59 

60 async def action_jump_bottom(self) -> None: 

61 await self.query_one(SessionListPanel).action_jump_bottom() 

62 

63 @on(SessionListPanel.CloseRequested) 

64 def _on_close(self, _event: SessionListPanel.CloseRequested) -> None: 

65 # Same semantics as q: return to where the user came from. 

66 self.app.go_back()