ai_code_buddy/
lib.rs

1pub mod args;
2pub mod core;
3pub mod theme;
4pub mod version;
5
6// Re-export version constants for convenience
7pub use version::{APP_NAME, APP_VERSION};
8
9// Platform guards for GPU features to keep CI/platform builds sane
10// NVIDIA CUDA must only be built on Windows runners
11#[cfg(all(feature = "gpu-cuda", not(target_os = "windows")))]
12compile_error!(
13    "The `gpu-cuda` feature is only supported on Windows builds. Remove the feature or run on a Windows runner."
14);
15// Apple Metal must only be built on macOS
16#[cfg(all(feature = "gpu-metal", not(target_os = "macos")))]
17compile_error!(
18    "The `gpu-metal` feature is only supported on macOS builds. Remove the feature or run on a macOS runner."
19);
20
21pub mod widgets {
22    pub mod analysis;
23    pub mod overview;
24    pub mod reports;
25}
26
27pub mod widget_states {
28    pub mod analysis;
29    pub mod overview;
30    pub mod reports;
31}
32
33pub mod events {
34    pub mod analysis;
35    pub mod app;
36    pub mod overview;
37    pub mod reports;
38}
39
40pub mod bevy_states {
41    pub mod app;
42}
43
44// Re-export commonly used types for easier testing
45pub use args::{Args, OutputFormat};
46pub use core::analysis::perform_analysis;
47
48// Re-export main application functions for testing
49pub use main_functions::*;
50
51mod main_functions {
52    use crate::{args::Args, bevy_states::app::AppState, events::app::AppEvent};
53    use bevy::prelude::*;
54    use bevy_ratatui::event::{KeyEvent, MouseEvent};
55
56    pub fn initialize_app(mut next_state: ResMut<NextState<AppState>>, args: Res<Args>) {
57        println!("🚀 AI Code Buddy v{} - Initializing...", crate::APP_VERSION);
58        println!("📂 Repository: {}", args.repo_path);
59        println!(
60            "🌿 Branches: {} → {}",
61            args.source_branch, args.target_branch
62        );
63
64        next_state.set(AppState::Overview);
65    }
66
67    pub fn app_events_handler(
68        _app_state: Res<State<AppState>>,
69        mut send_app_state: ResMut<NextState<AppState>>,
70        mut app_events: EventReader<AppEvent>,
71        mut app_exit: EventWriter<AppExit>,
72    ) {
73        for event in app_events.read() {
74            match event {
75                AppEvent::SwitchTo(new_state) => {
76                    send_app_state.set(*new_state);
77                }
78                AppEvent::Exit => {
79                    app_exit.send_default();
80                }
81            }
82        }
83    }
84
85    pub fn keyboard_events_handler(
86        app_state: Res<State<AppState>>,
87        mut keyboard_events: EventReader<KeyEvent>,
88        mut overview_events: EventWriter<crate::events::overview::OverviewEvent>,
89        mut analysis_events: EventWriter<crate::events::analysis::AnalysisEvent>,
90        mut reports_events: EventWriter<crate::events::reports::ReportsEvent>,
91        mut app_events: EventWriter<AppEvent>,
92    ) {
93        let app_state = app_state.get();
94
95        for event in keyboard_events.read() {
96            // Global key bindings
97            if let crossterm::event::KeyCode::Char('q') = event.code {
98                if event.kind == crossterm::event::KeyEventKind::Release {
99                    app_events.send(AppEvent::Exit);
100                    continue;
101                }
102            }
103
104            match app_state {
105                AppState::Overview => {
106                    overview_events.send(crate::events::overview::OverviewEvent::KeyEvent(
107                        event.clone(),
108                    ));
109                }
110                AppState::Analysis => {
111                    analysis_events.send(crate::events::analysis::AnalysisEvent::KeyEvent(
112                        event.clone(),
113                    ));
114                }
115                AppState::Reports => {
116                    reports_events.send(crate::events::reports::ReportsEvent::KeyEvent(
117                        event.clone(),
118                    ));
119                }
120            }
121        }
122    }
123
124    pub fn mouse_events_handler(
125        app_state: Res<State<AppState>>,
126        mut mouse_events: EventReader<MouseEvent>,
127        mut overview_events: EventWriter<crate::events::overview::OverviewEvent>,
128        mut analysis_events: EventWriter<crate::events::analysis::AnalysisEvent>,
129        mut reports_events: EventWriter<crate::events::reports::ReportsEvent>,
130    ) {
131        let app_state = app_state.get();
132
133        for event in mouse_events.read() {
134            match app_state {
135                AppState::Overview => {
136                    overview_events
137                        .send(crate::events::overview::OverviewEvent::MouseEvent(*event));
138                }
139                AppState::Analysis => {
140                    analysis_events
141                        .send(crate::events::analysis::AnalysisEvent::MouseEvent(*event));
142                }
143                AppState::Reports => {
144                    reports_events.send(crate::events::reports::ReportsEvent::MouseEvent(*event));
145                }
146            }
147        }
148    }
149}
150pub use core::review::Review;