1515// - In `.setup()`:
1616// - Perform AppState initializations requiring AppHandle (paths, extension
1717// scan, config load).
18- // - Register frontend command handlers (`Track`).
18+ // - Register frontend command handlers (`Track` and UI response handlers ).
1919// - Launch sidecar processes (Cocoon) via `process_mgmt`.
2020// - Initialize IPC/RPC layers (`Vine`/`rpc`).
2121// - Register custom URI protocol handlers (`handlers::protocol`).
2727// path resolution.
2828// - Manages `AppState` and `AppRuntime` via Tauri's `State<T>`.
2929// - Calls `handlers::process_mgmt::launch_and_manage_cocoon`.
30- // - Calls `rpc::setup_mountain_rpc_server` (conceptual).
31- // - Registers `track::dispatch_command` and
30+ // - Calls `rpc::setup_mountain_rpc_server`.
31+ // - Registers `track::dispatch_command`,
32+ // `handlers::sky_ui_responses::sky_resolves_ui_request`, and
3233// `handlers::protocol::handle_vscode_protocol`.
3334// --------------------------------------------------------------------------------------------
3435
@@ -41,31 +42,29 @@ use log::{debug, error, info, trace, warn};
4142use tauri:: { AppHandle , Manager , Runtime as TauriRuntime , State , Window , Wry } ;
4243
4344// --- Application Modules ---
44- mod app_state;
45+ // mod app_state;
4546
46- mod environment;
47-
48- mod handlers;
47+ // mod environment;
4948
49+ // Parent module for sub-handlers
50+ // mod handlers;
5051// Centralized logger initialization
51- mod logging_setup;
52- mod mist;
53-
54- mod rpc;
52+ // mod logging_setup;
53+ // mod mist;
5554
56- mod runtime ;
55+ // mod rpc ;
5756
58- mod track ;
57+ // mod runtime ;
5958
60- mod vine ;
59+ // mod track ;
6160
62- use app_state :: AppState ;
63- use environment :: MountainEnvironment ;
64- use runtime:: AppRuntime ;
61+ // mod vine ;
62+ use crate :: app_state :: AppState ;
63+ use crate :: { environment :: MountainEnvironment , runtime:: AppRuntime } ;
6564
66- // Example struct for event payloads (may or may not be actively used in main)
6765#[ derive( Clone , serde:: Serialize ) ]
6866struct GenericPayload {
67+ // Example, may not be used directly in main
6968 message : String ,
7069}
7170
@@ -85,144 +84,99 @@ async fn main() {
8584 . manage ( initial_app_state)
8685 // AppRuntime and MountainEnvironment will be created and managed inside .setup once AppHandle is available
8786 . setup ( |app| {
88-
8987 info ! ( "[Mountain Setup] Tauri setup hook running." ) ;
9088
9189 let app_handle = app. handle ( ) ;
90+
9291 // --- Create and Manage Environment & Runtime with AppHandle ---
9392 let mountain_env_arc = Arc :: new ( MountainEnvironment :: new ( app_handle. clone ( ) ) ) ;
9493
9594 let app_runtime_arc = Arc :: new ( AppRuntime :: new ( mountain_env_arc. clone ( ) ) ) ;
9695
9796 // Manage the fully initialized AppRuntime
9897 app_handle. manage ( app_runtime_arc. clone ( ) ) ;
98+
9999 info ! ( "[Mountain Setup] MountainEnvironment and AppRuntime created and managed." ) ;
100+
100101 // --- AppState Post-Handle Initialization Task ---
101102 // This task performs initializations that require AppHandle and should run asynchronously.
102103 let post_setup_app_handle = app_handle. clone ( ) ;
103104
104105 tauri:: async_runtime:: spawn ( async move {
105106 info ! ( "[Mountain Setup Task] Starting AppState post-handle initialization..." ) ;
106107
108+ // Get managed AppState
107109 let app_state = post_setup_app_handle. state :: < AppState > ( ) ;
108110
109111 // 1. Resolve and set extension scan paths
110- let mut resolved_scan_paths: Vec < PathBuf > = Vec :: new ( ) ;
112+ // Assumes AppState.extension_scan_paths is Arc<Mutex<Vec<PathBuf>>>
113+ {
114+ let mut resolved_scan_paths: Vec < PathBuf > = Vec :: new ( ) ;
115+
116+ if let Some ( builtin_ext_dir) = post_setup_app_handle. path_resolver ( ) . resolve_resource ( "extensions/builtin" ) {
117+ if builtin_ext_dir. is_dir ( ) {
118+ info ! ( "[Mountain Setup Task] Adding builtin extension scan path: {}" , builtin_ext_dir. display( ) ) ;
119+
120+ resolved_scan_paths. push ( builtin_ext_dir) ;
121+ } else {
122+ warn ! ( "[Mountain Setup Task] Resolved builtin extension path is not a directory or does not exist: {}" , builtin_ext_dir. display( ) ) ;
123+ }
124+ } else {
125+ warn ! ( "[Mountain Setup Task] Could not resolve 'extensions/builtin' resource path." ) ;
126+ }
111127
112- if let Some ( builtin_ext_dir) = post_setup_app_handle. path_resolver ( ) . resolve_resource ( "extensions/builtin" ) {
113- info ! ( "[Mountain Setup Task] Adding builtin extension scan path: {}" , builtin_ext_dir. display( ) ) ;
114- resolved_scan_paths. push ( builtin_ext_dir) ;
115- } else {
116- warn ! ( "[Mountain Setup Task] Could not resolve 'extensions/builtin' resource path." ) ;
117- }
128+ if let Some ( user_ext_base_dir) = post_setup_app_handle. path_resolver ( ) . app_data_dir ( ) {
129+ let user_ext_dir = user_ext_base_dir. join ( "extensions" ) ;
118130
119- // TODO: Add other potential scan paths (e.g., user extensions based on config or standard locations)
120- // Example:
121- // if let Some(user_ext_dir) = post_setup_app_handle.path_resolver().app_data_dir().map(|d| d.join("extensions")) {
122- // if user_ext_dir.exists() {
123- // info!("[Mountain Setup Task] Adding user extension scan path: {}", user_ext_dir.display());
124- // resolved_scan_paths.push(user_ext_dir);
125- // }
126- // }
127- // Scope for mutable access to app_state.extension_scan_paths if it were a Mutex/RwLock
128- {
129- // For now, assuming direct vec mutation is fine if it's not Arc<Mutex<Vec<PathBuf>>>
130- // If it's plain Vec, this direct modification is problematic if AppState is shared.
131- // app_state.extension_scan_paths needs to be Arc<Mutex<Vec<PathBuf>>> or similar for this to be safe.
132- // For simplicity of this example, assuming AppState::extension_scan_paths itself might be behind a lock or is init-once.
133- // Given AppState structure, this direct modification is incorrect.
134- // Instead, it should be like:
135- // let mut scan_paths_guard = app_state.extension_scan_paths.lock().unwrap();
136-
137- // scan_paths_guard.clear();
138-
139- // scan_paths_guard.extend(resolved_scan_paths);
140-
141- // OR if extension_scan_paths is not wrapped in Arc<Mutex>:
142- // If it's a plain field, this task needs &mut AppState or similar
143- // app_state.extension_scan_paths = resolved_scan_paths;
144-
145- // Correct approach: Assuming AppState.extension_scan_paths is NOT behind a Mutex
146- // and this task owns a mutable reference or is initializing a part of it.
147- // The current `app_state.extension_scan_paths` is `Vec<PathBuf>`, not `Arc<Mutex<...>>`
148- // This indicates that `extension_scan_paths` is intended to be populated once, possibly here.
149- // If it needs to be dynamic later, AppState field type should change.
150- // For now, we'll assume this is effectively an initialization step for that field.
151- // To make this safe with `State<AppState>`, the field itself needs to be behind a Mutex
152- // or this part of initialization logic needs rethinking.
153- // Let's assume AppState holds an Arc<Mutex<Vec<PathBuf>>> for extension_scan_paths.
154- // If AppState is: pub extension_scan_paths: Vec<PathBuf>, then this is not thread safe.
155- // Reverting to original intent if it was non-Mutexed for simplicity:
156- // Clear placeholder
157- // app_state.extension_scan_paths.clear();
158- // app_state.extension_scan_paths.extend(resolved_scan_paths);
159-
160- // *This part highlights a potential design issue in the provided AppState if modification
161- // is expected from multiple places or async tasks after initial AppState::default().
162- // For the purpose of synthesis, assuming app_state.scan_extensions() internally handles
163- // how it gets/uses these paths if they are set this way.
164- // If AppState.extension_scan_paths must be mutable, it needs Arc<Mutex>.
165- // Given `state.scan_extensions().await` is called next, that method should use the paths.
166- // Let's assume AppState::default() initialized it empty and this task populates it before scan.
167- // If `scan_extensions` reads from `self.extension_scan_paths`, it will see this.
168- // THIS IS STILL NOT SAFE IF AppState IS CLONED AND SHARED WITHOUT INTERNAL MUTABILITY FOR THE VEC.
169- // Safest: AppState::extension_scan_paths: Arc<Mutex<Vec<PathBuf>>>
170- // For now, will keep the direct modification as implied by `state.extension_scan_paths.clear()`
171- // but acknowledge it's problematic without internal mutability for that field in AppState.
172- // The AppState provided DOES NOT use Arc<Mutex<Vec<PathBuf>>>, it's just Vec<PathBuf>.
173- // So, the `.manage(initial_app_state)` shares an immutable AppState.
174- // The only way to modify it is if `app_state` itself is `Arc<Mutex<AppState>>`, or
175- // its fields are `Arc<Mutex<...>>`.
176- // The current `AppState` uses `Arc<Mutex<...>>` for *most* fields, but not `extension_scan_paths`.
177- // This is a design flaw in the provided `AppState`.
178- // **Correction based on AppState structure:** `extension_scan_paths` is NOT mutable this way.
179- // It must be set during `AppState::default()` or `AppState` must be wrapped further.
180- // Alternative: clone app_state, modify, and then re-manage. But this is not ideal.
181- // **Simplifying assumption for synthesis:**
182- // `extension_scan_paths` is initialized in `AppState::default()` with these paths,
183- // or `scan_extensions` takes paths as an argument.
184- // For now, commenting out direct modification and relying on `scan_extensions` to use paths
185- // set in `AppState::default()` or another mechanism.
186- debug ! ( "[Mountain Setup Task] Extension scan paths used by scan_extensions will be from AppState::default or config." ) ;
131+ if user_ext_dir. is_dir ( ) {
132+ info ! ( "[Mountain Setup Task] Adding user extension scan path: {}" , user_ext_dir. display( ) ) ;
133+
134+ resolved_scan_paths. push ( user_ext_dir) ;
135+ } else {
136+ trace ! ( "[Mountain Setup Task] User extension path does not exist, skipping: {}" , user_ext_dir. display( ) ) ;
137+ }
138+ } else {
139+ warn ! ( "[Mountain Setup Task] Could not resolve app data directory for user extensions path." ) ;
140+ }
141+
142+ let mut scan_paths_guard = app_state. extension_scan_paths . lock ( ) . expect ( "Failed to lock extension_scan_paths for writing" ) ;
143+
144+ scan_paths_guard. clear ( ) ;
187145
146+ scan_paths_guard. extend ( resolved_scan_paths) ;
147+
148+ debug ! ( "[Mountain Setup Task] Final extension scan paths set in AppState: {:?}" , scan_paths_guard) ;
188149 }
189- // 2. Scan for extensions
150+
151+ // 2. Scan for extensions (now uses the paths set above)
190152 app_state. scan_extensions ( ) . await ;
191- // 3. Load/configure enabled proposed APIs
192- {
193- let mut proposed_apis_guard = app_state. enabled_proposed_apis . lock ( ) . expect ( "Failed to lock proposed APIs for init" ) ;
194153
195- proposed_apis_guard. insert ( "*" . to_string ( ) , vec ! [ "testProposedApi" . to_string( ) , "workspaceTrust" . to_string( ) ] ) ;
154+ // 3. Load/configure enabled proposed APIs (example)
155+ let mut proposed_apis_guard = app_state. enabled_proposed_apis . lock ( ) . expect ( "Failed to lock proposed APIs for init" ) ;
156+
157+ // For MVP, could be hardcoded or from a simple config file Mountain loads
158+ proposed_apis_guard. insert ( "*" . to_string ( ) , vec ! [ "testProposedApi" . to_string( ) , "workspaceTrust" . to_string( ) ] ) ;
159+
160+ info ! ( "[Mountain Setup Task] Enabled proposed APIs configured. Count: {}" , proposed_apis_guard. len( ) ) ;
196161
197- info ! ( "[Mountain Setup Task] Enabled proposed APIs configured. Count: {}" , proposed_apis_guard. len( ) ) ;
198- }
199-
200162 // 4. Load initial merged configuration into AppState
201163 match handlers:: config:: load_and_merge_configurations_internal ( & post_setup_app_handle, & app_state) . await {
202-
203164 Ok ( merged_config_state) => {
204-
205165 app_state. configuration . lock ( ) . expect ( "Failed to lock AppState.configuration for init load" ) . update_from ( merged_config_state) ;
206166
207167 info ! ( "[Mountain Setup Task] Initial merged configuration loaded into AppState." ) ;
208-
209168 }
210169 Err ( e) => {
211-
212170 error ! ( "[Mountain Setup Task] CRITICAL: Failed to load initial merged configurations: {}" , e) ;
213-
214171 }
215172 }
216-
217- // 5. Update workspace memento path
218- if let Some ( app_data_dir_for_memento) = post_setup_app_handle. path_resolver ( ) . app_data_dir ( ) {
219173
174+ // 5. Update workspace memento path based on initial workspace (if any)
175+ if let Some ( app_data_dir_for_memento) = post_setup_app_handle. path_resolver ( ) . app_data_dir ( ) {
220176 debug ! ( "[Mountain Setup Task] Attempting to initialize workspace memento path based on data dir: {}" , app_data_dir_for_memento. display( ) ) ;
221177
222178 if let Err ( e) = app_state. update_workspace_memento_path ( & app_data_dir_for_memento) {
223-
224179 error ! ( "[Mountain Setup Task] Failed to initialize workspace memento path: {}" , e) ;
225-
226180 }
227181 } else {
228182 warn ! ( "[Mountain Setup Task] App data directory not available for workspace memento path init at this stage." ) ;
@@ -236,7 +190,6 @@ async fn main() {
236190
237191 app. protocol ( )
238192 . register ( "vscode" , move |request| {
239-
240193 debug ! ( "[Mountain Setup Protocol] Received vscode:// request: {}" , request. uri( ) ) ;
241194
242195 handlers:: protocol:: handle_vscode_protocol ( request, protocol_handle_setup. clone ( ) )
@@ -245,10 +198,8 @@ async fn main() {
245198
246199 info ! ( "[Mountain Setup] vscode:// protocol registered." ) ;
247200
201+
248202 // --- Setup RPC Server (for Vine/Sidecar Communication) ---
249- // This setup ensures Mountain can handle incoming RPC calls.
250- // Actual dispatching of these calls to specific handlers typically happens
251- // within the Vine/RPC layer, using the AppRuntime to execute logic.
252203 let rpc_runtime_clone_setup = app_handle. state :: < Arc < AppRuntime > > ( ) . inner ( ) . clone ( ) ;
253204
254205 let rpc_app_handle_clone_setup = app_handle. clone ( ) ;
@@ -264,7 +215,6 @@ async fn main() {
264215
265216 let cocoon_app_handle = app_handle. clone ( ) ;
266217
267- // Use Tauri's async runtime for background tasks
268218 tauri:: async_runtime:: spawn ( async move {
269219 handlers:: process_mgmt:: launch_and_manage_cocoon ( cocoon_app_handle) . await ;
270220 } ) ;
@@ -278,7 +228,6 @@ async fn main() {
278228 // --- Start Native Mist WebSocket Server (Conditional) ---
279229 #[ cfg( feature = "mist_native" ) ]
280230 {
281-
282231 info ! ( "[Mountain Setup] Native Mist feature enabled. Spawning start_websocket_server task..." ) ;
283232
284233 let mist_app_handle = app_handle. clone ( ) ;
@@ -295,9 +244,9 @@ async fn main() {
295244 info ! ( "[Mountain Setup] Native Mist feature disabled." ) ;
296245 }
297246
247+
298248 // --- TODO: Start File Watchers for Configuration Files ---
299- // This would involve using a crate like `notify` to watch settings.json files
300- // and trigger a configuration reload (e.g., calling parts of the post-setup task again).
249+ // Example:
301250 // let watcher_app_handle = app_handle.clone();
302251 // tauri::async_runtime::spawn(async move {
303252 // if let Err(e) = handlers::config_watcher::start_watching_config_files(watcher_app_handle).await {
@@ -313,22 +262,21 @@ async fn main() {
313262 } )
314263 . invoke_handler ( tauri:: generate_handler![
315264 // Main entry point for frontend commands
316- track:: dispatch_command
265+ track:: dispatch_command,
266+ // Handler for UI responses from Sky
267+ handlers:: sky_ui_responses:: sky_resolves_ui_request
317268 ] )
318269 . on_window_event ( |event| match event. event ( ) {
319270 tauri:: WindowEvent :: CloseRequested { api, .. } => {
320-
321271 info ! ( "[Mountain WindowEvent] Close requested for window: {}" , event. window( ) . label( ) ) ;
322272
323273 // TODO: Implement graceful shutdown:
324274 // 1. Notify Cocoon to deactivate extensions.
325275 // 2. Wait for Cocoon to signal completion or timeout.
326276 // 3. Save AppState (mementos, dirty files via DocumentProvider effects).
327277 // 4. Allow close.
328- // For now, allow default close. To prevent for debugging:
329- // api.prevent_close();
330-
331- // warn!("[Mountain WindowEvent] Close prevention is active for debugging if uncommented.");
278+ // To prevent immediate close
279+ // Example: api.prevent_close();
332280 }
333281
334282 tauri:: WindowEvent :: Destroyed => {
@@ -338,36 +286,46 @@ async fn main() {
338286 _ => {
339287 trace ! ( "[Mountain WindowEvent] Other event on window '{}': {:?}" , event. window( ) . label( ) , event. event( ) ) ;
340288 }
289+
341290 } )
342291 . build ( tauri:: generate_context!( ) )
343- . expect ( "Error while building Mountain Tauri application" ) . run ( |app_handle_run , event| match event {
344- // Renamed app_handle to avoid conflict
292+ . expect ( "Error while building Mountain Tauri application" )
293+ . run ( |app_handle_run , event| match event {
345294 tauri:: RunEvent :: ExitRequested { api, .. } => {
346295 info ! ( "[Mountain RunEvent] Application exit requested. Performing cleanup..." ) ;
347296
348297 // TODO: Global cleanup before app exit:
298+ // Call this if async cleanup is needed
349299 // api.prevent_exit();
350-
351300 // let handle_clone_exit = app_handle_run.clone();
352301
353302 // tauri::async_runtime::spawn(async move {
354-
355303 // info!("[Mountain Exit] Signaling sidecars to terminate...");
356304
357- // Example: vine::broadcast_terminate_signal(&handle_clone_exit).await;
358- //
359- // Give time
305+ // // Example: vine::broadcast_terminate_signal(&handle_clone_exit).await;
306+
307+ // Give time for sidecars
360308 // tokio::time::sleep(std::time::Duration::from_secs(1)).await;
361309 // info!("[Mountain Exit] Exiting application now.");
310+
311+ // Exit after cleanup
362312 // handle_clone_exit.exit(0);
363313 // });
364314
315+ info ! ( "[Mountain RunEvent] Application process is beginning to exit or handling exit request." ) ;
365316 }
366-
317+
367318 tauri:: RunEvent :: Exit => {
368- info ! ( "[Mountain RunEvent] Application process is exiting." ) ;
319+ info ! ( "[Mountain RunEvent] Application has fully exited." ) ;
320+ }
321+
322+ tauri:: RunEvent :: Ready => {
323+ info ! ( "[Mountain RunEvent] Application is ready." ) ;
324+ }
325+
326+ _ => {
327+ trace ! ( "[Mountain RunEvent] Other/unhandled run event: {:?}" , event) ;
369328 }
370- _ => { }
371329 } ) ;
372330
373331 info ! ( "[Mountain Main] Application event loop finished or error occurred." ) ;
0 commit comments