diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index baea678..8ef2246 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -91,9 +91,29 @@ pub fn data_directory() -> PathBuf { PathBuf::from(".") } +fn write_log(path: &std::path::Path, msg: &str) -> std::io::Result<()> { + use std::io::Write; + let mut f = std::fs::OpenOptions::new().create(true).append(true).open(path)?; + let elapsed = std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap_or_default() + .as_secs(); + writeln!(f, "[{}] {}", elapsed, msg) +} + #[cfg_attr(mobile, tauri::mobile_entry_point)] pub fn run() { - let app_state = AppState::new(data_directory()).expect("Failed to init AppState"); + // Initialize file-based logging to data_dir/wraith.log + let log_path = data_directory().join("wraith.log"); + let _ = write_log(&log_path, "=== Wraith starting ==="); + + let app_state = match AppState::new(data_directory()) { + Ok(s) => s, + Err(e) => { + let _ = write_log(&log_path, &format!("FATAL: AppState init failed: {}", e)); + panic!("Failed to init AppState: {}", e); + } + }; app_state.theme.seed_builtins(); tauri::Builder::default() @@ -109,25 +129,30 @@ pub fn run() { } // Start MCP and error watcher — completely non-fatal. - // These are nice-to-have services that must never crash the app. { use tauri::Manager; + let log_file = data_directory().join("wraith.log"); + let _ = write_log(&log_file, "Setup: starting MCP and error watcher"); + if let Ok(state) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| { app.state::().inner().clone_services() })) { let (ssh, rdp, sftp, scrollback, watcher) = state; + let _ = write_log(&log_file, "Setup: cloned services OK"); let app_handle = app.handle().clone(); mcp::error_watcher::start_error_watcher(watcher, scrollback.clone(), app_handle); + let _ = write_log(&log_file, "Setup: error watcher started"); + let log_file2 = log_file.clone(); tauri::async_runtime::spawn(async move { match mcp::server::start_mcp_server(ssh, rdp, sftp, scrollback).await { - Ok(port) => log::info!("MCP server started on localhost:{}", port), - Err(e) => log::error!("Failed to start MCP server: {}", e), + Ok(port) => { let _ = write_log(&log_file2, &format!("MCP server started on localhost:{}", port)); } + Err(e) => { let _ = write_log(&log_file2, &format!("MCP server FAILED: {}", e)); } } }); } else { - log::error!("MCP/error watcher startup failed — continuing without MCP"); + let _ = write_log(&log_file, "MCP startup panicked — continuing without MCP"); } }