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

34 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-08-14 11:46 +0000

1"""Fleet screen: thin host for FleetBody (GPU table + placement editor).""" 

2 

3from __future__ import annotations 

4 

5from typing import ClassVar 

6 

7from textual.app import ComposeResult 

8from textual.binding import Binding, BindingType 

9from textual.screen import Screen 

10 

11from lilbee.cli.tui.app import LilbeeApp 

12from lilbee.cli.tui.browse_bindings import browse_back_bindings 

13from lilbee.cli.tui.widgets.fleet_body import FleetBody 

14 

15 

16class FleetScreen(Screen[None]): 

17 """GPU fleet viewer and interactive placement editor.""" 

18 

19 # Lilbee always hosts screens on a LilbeeApp, so narrowing the type lets 

20 # the screen call switch_view without per-call type: ignore comments. 

21 app: LilbeeApp # type: ignore[assignment] 

22 

23 CSS_PATH = "fleet.tcss" 

24 AUTO_FOCUS = ".dev-toggle" 

25 HELP = "Configure GPU placement. ctrl+r preview, ctrl+s apply, ctrl+x auto, q back." 

26 

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

28 *browse_back_bindings(), 

29 # priority so they fire even when a button/editor child has focus. 

30 Binding("ctrl+r", "preview", "Preview", show=False, priority=True), 

31 Binding("ctrl+s", "apply", "Apply", show=True, priority=True), 

32 Binding("ctrl+x", "clear", "Auto", show=False, priority=True), 

33 ] 

34 

35 def compose(self) -> ComposeResult: 

36 from textual.widgets import Footer 

37 

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

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

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

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

42 

43 with TopBars(): 

44 yield ViewTabs() 

45 yield FleetBody() 

46 with BottomBars(): 

47 yield TaskBar() 

48 yield Footer() 

49 

50 def action_preview(self) -> None: 

51 """Delegate preview to FleetBody.""" 

52 self.query_one(FleetBody).action_preview() 

53 

54 def action_apply(self) -> None: 

55 """Delegate apply to FleetBody.""" 

56 self.query_one(FleetBody).action_apply() 

57 

58 def action_clear(self) -> None: 

59 """Delegate clear (auto) to FleetBody.""" 

60 self.query_one(FleetBody).action_clear() 

61 

62 def action_go_back(self) -> None: 

63 """Return to the view the user came from via the guarded switch_view.""" 

64 self.app.go_back()