agent_tui/daemon/
usecase_container.rs

1use std::sync::Arc;
2use std::sync::atomic::AtomicUsize;
3use std::time::Instant;
4
5use crate::daemon::metrics::DaemonMetrics;
6use crate::daemon::repository::SessionRepository;
7use crate::daemon::usecases::{
8    AccessibilitySnapshotUseCaseImpl, AssertUseCaseImpl, AttachUseCaseImpl, CleanupUseCaseImpl,
9    ClearUseCaseImpl, ClickUseCaseImpl, ConsoleUseCaseImpl, CountUseCaseImpl,
10    DoubleClickUseCaseImpl, ErrorsUseCaseImpl, FillUseCaseImpl, FindUseCaseImpl, FocusUseCaseImpl,
11    GetFocusedUseCaseImpl, GetTextUseCaseImpl, GetTitleUseCaseImpl, GetValueUseCaseImpl,
12    HealthUseCaseImpl, IsCheckedUseCaseImpl, IsEnabledUseCaseImpl, IsFocusedUseCaseImpl,
13    IsVisibleUseCaseImpl, KeydownUseCaseImpl, KeystrokeUseCaseImpl, KeyupUseCaseImpl,
14    KillUseCaseImpl, MetricsUseCaseImpl, MultiselectUseCaseImpl, PtyReadUseCaseImpl,
15    PtyWriteUseCaseImpl, RecordStartUseCaseImpl, RecordStatusUseCaseImpl, RecordStopUseCaseImpl,
16    ResizeUseCaseImpl, RestartUseCaseImpl, ScrollIntoViewUseCaseImpl, ScrollUseCaseImpl,
17    SelectAllUseCaseImpl, SelectUseCaseImpl, SessionsUseCaseImpl, SnapshotUseCaseImpl,
18    SpawnUseCaseImpl, ToggleUseCaseImpl, TraceUseCaseImpl, TypeUseCaseImpl, WaitUseCaseImpl,
19};
20
21/// Container holding all use case implementations.
22///
23/// This enables dependency injection and makes handlers testable
24/// by allowing different use case implementations to be injected.
25pub struct UseCaseContainer<R: SessionRepository + 'static> {
26    pub session: SessionUseCases<R>,
27    pub elements: ElementUseCases<R>,
28    pub input: InputUseCases<R>,
29    pub recording: RecordingUseCases<R>,
30    pub diagnostics: DiagnosticsUseCases<R>,
31    pub wait: WaitUseCaseImpl<R>,
32}
33
34/// Session-related use cases.
35pub struct SessionUseCases<R: SessionRepository + 'static> {
36    pub spawn: SpawnUseCaseImpl<R>,
37    pub kill: KillUseCaseImpl<R>,
38    pub sessions: SessionsUseCaseImpl<R>,
39    pub restart: RestartUseCaseImpl<R>,
40    pub attach: AttachUseCaseImpl<R>,
41    pub resize: ResizeUseCaseImpl<R>,
42    pub cleanup: CleanupUseCaseImpl<R>,
43    pub assert: AssertUseCaseImpl<R>,
44}
45
46/// Element-related use cases.
47pub struct ElementUseCases<R: SessionRepository + 'static> {
48    pub snapshot: SnapshotUseCaseImpl<R>,
49    pub accessibility_snapshot: AccessibilitySnapshotUseCaseImpl<R>,
50    pub click: ClickUseCaseImpl<R>,
51    pub dbl_click: DoubleClickUseCaseImpl<R>,
52    pub fill: FillUseCaseImpl<R>,
53    pub find: FindUseCaseImpl<R>,
54    pub scroll: ScrollUseCaseImpl<R>,
55    pub count: CountUseCaseImpl<R>,
56    pub focus: FocusUseCaseImpl<R>,
57    pub clear: ClearUseCaseImpl<R>,
58    pub select_all: SelectAllUseCaseImpl<R>,
59    pub toggle: ToggleUseCaseImpl<R>,
60    pub select: SelectUseCaseImpl<R>,
61    pub multiselect: MultiselectUseCaseImpl<R>,
62    // Query use cases
63    pub get_text: GetTextUseCaseImpl<R>,
64    pub get_value: GetValueUseCaseImpl<R>,
65    pub is_visible: IsVisibleUseCaseImpl<R>,
66    pub is_focused: IsFocusedUseCaseImpl<R>,
67    pub is_enabled: IsEnabledUseCaseImpl<R>,
68    pub is_checked: IsCheckedUseCaseImpl<R>,
69    pub get_focused: GetFocusedUseCaseImpl<R>,
70    pub get_title: GetTitleUseCaseImpl<R>,
71    pub scroll_into_view: ScrollIntoViewUseCaseImpl<R>,
72}
73
74/// Input-related use cases.
75pub struct InputUseCases<R: SessionRepository + 'static> {
76    pub keystroke: KeystrokeUseCaseImpl<R>,
77    pub type_text: TypeUseCaseImpl<R>,
78    pub keydown: KeydownUseCaseImpl<R>,
79    pub keyup: KeyupUseCaseImpl<R>,
80}
81
82/// Recording-related use cases.
83pub struct RecordingUseCases<R: SessionRepository + 'static> {
84    pub record_start: RecordStartUseCaseImpl<R>,
85    pub record_stop: RecordStopUseCaseImpl<R>,
86    pub record_status: RecordStatusUseCaseImpl<R>,
87}
88
89/// Diagnostics-related use cases.
90pub struct DiagnosticsUseCases<R: SessionRepository + 'static> {
91    pub trace: TraceUseCaseImpl<R>,
92    pub console: ConsoleUseCaseImpl<R>,
93    pub errors: ErrorsUseCaseImpl<R>,
94    pub pty_read: PtyReadUseCaseImpl<R>,
95    pub pty_write: PtyWriteUseCaseImpl<R>,
96    pub health: HealthUseCaseImpl<R>,
97    pub metrics: MetricsUseCaseImpl<R>,
98}
99
100impl<R: SessionRepository + 'static> UseCaseContainer<R> {
101    /// Create a new UseCaseContainer with all use cases initialized.
102    pub fn new(
103        repository: Arc<R>,
104        metrics: Arc<DaemonMetrics>,
105        start_time: Instant,
106        active_connections: Arc<AtomicUsize>,
107    ) -> Self {
108        Self {
109            session: SessionUseCases {
110                spawn: SpawnUseCaseImpl::new(Arc::clone(&repository)),
111                kill: KillUseCaseImpl::new(Arc::clone(&repository)),
112                sessions: SessionsUseCaseImpl::new(Arc::clone(&repository)),
113                restart: RestartUseCaseImpl::new(Arc::clone(&repository)),
114                attach: AttachUseCaseImpl::new(Arc::clone(&repository)),
115                resize: ResizeUseCaseImpl::new(Arc::clone(&repository)),
116                cleanup: CleanupUseCaseImpl::new(Arc::clone(&repository)),
117                assert: AssertUseCaseImpl::new(Arc::clone(&repository)),
118            },
119            elements: ElementUseCases {
120                snapshot: SnapshotUseCaseImpl::new(Arc::clone(&repository)),
121                accessibility_snapshot: AccessibilitySnapshotUseCaseImpl::new(Arc::clone(
122                    &repository,
123                )),
124                click: ClickUseCaseImpl::new(Arc::clone(&repository)),
125                dbl_click: DoubleClickUseCaseImpl::new(Arc::clone(&repository)),
126                fill: FillUseCaseImpl::new(Arc::clone(&repository)),
127                find: FindUseCaseImpl::new(Arc::clone(&repository)),
128                scroll: ScrollUseCaseImpl::new(Arc::clone(&repository)),
129                count: CountUseCaseImpl::new(Arc::clone(&repository)),
130                focus: FocusUseCaseImpl::new(Arc::clone(&repository)),
131                clear: ClearUseCaseImpl::new(Arc::clone(&repository)),
132                select_all: SelectAllUseCaseImpl::new(Arc::clone(&repository)),
133                toggle: ToggleUseCaseImpl::new(Arc::clone(&repository)),
134                select: SelectUseCaseImpl::new(Arc::clone(&repository)),
135                multiselect: MultiselectUseCaseImpl::new(Arc::clone(&repository)),
136                get_text: GetTextUseCaseImpl::new(Arc::clone(&repository)),
137                get_value: GetValueUseCaseImpl::new(Arc::clone(&repository)),
138                is_visible: IsVisibleUseCaseImpl::new(Arc::clone(&repository)),
139                is_focused: IsFocusedUseCaseImpl::new(Arc::clone(&repository)),
140                is_enabled: IsEnabledUseCaseImpl::new(Arc::clone(&repository)),
141                is_checked: IsCheckedUseCaseImpl::new(Arc::clone(&repository)),
142                get_focused: GetFocusedUseCaseImpl::new(Arc::clone(&repository)),
143                get_title: GetTitleUseCaseImpl::new(Arc::clone(&repository)),
144                scroll_into_view: ScrollIntoViewUseCaseImpl::new(Arc::clone(&repository)),
145            },
146            input: InputUseCases {
147                keystroke: KeystrokeUseCaseImpl::new(Arc::clone(&repository)),
148                type_text: TypeUseCaseImpl::new(Arc::clone(&repository)),
149                keydown: KeydownUseCaseImpl::new(Arc::clone(&repository)),
150                keyup: KeyupUseCaseImpl::new(Arc::clone(&repository)),
151            },
152            recording: RecordingUseCases {
153                record_start: RecordStartUseCaseImpl::new(Arc::clone(&repository)),
154                record_stop: RecordStopUseCaseImpl::new(Arc::clone(&repository)),
155                record_status: RecordStatusUseCaseImpl::new(Arc::clone(&repository)),
156            },
157            diagnostics: DiagnosticsUseCases {
158                trace: TraceUseCaseImpl::new(Arc::clone(&repository)),
159                console: ConsoleUseCaseImpl::new(Arc::clone(&repository)),
160                errors: ErrorsUseCaseImpl::new(Arc::clone(&repository)),
161                pty_read: PtyReadUseCaseImpl::new(Arc::clone(&repository)),
162                pty_write: PtyWriteUseCaseImpl::new(Arc::clone(&repository)),
163                health: HealthUseCaseImpl::new(
164                    Arc::clone(&repository),
165                    Arc::clone(&metrics),
166                    start_time,
167                    Arc::clone(&active_connections),
168                ),
169                metrics: MetricsUseCaseImpl::new(
170                    Arc::clone(&repository),
171                    metrics,
172                    start_time,
173                    active_connections,
174                ),
175            },
176            wait: WaitUseCaseImpl::new(repository),
177        }
178    }
179}