//! Library entry point. `main.rs` calls `run()`. mod commands; mod creds; mod hosts; mod mcp; mod mcp_policy; mod pty; use std::sync::Arc; use crate::mcp::{McpServerHandle, McpState, PendingActions}; use crate::pty::PtyManager; pub fn run() { let _ = tracing_subscriber::fmt() .with_env_filter( tracing_subscriber::EnvFilter::try_from_default_env() .unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")), ) .with_writer(std::io::stderr) .try_init(); // keyring-core 1.x requires explicit store registration before any // Entry::new() call. We're Windows-only so the Credential Manager // backend is the only choice. Failure here means SSH passwords won't // be retrievable — log and continue (host configs still work without // saved passwords; users just see the prompt and type it manually). match windows_native_keyring_store::Store::new() { Ok(store) => keyring_core::set_default_store(store), Err(e) => tracing::warn!("keyring store init failed: {e}"), } // PtyManager and McpState are shared with the MCP server, so register // them as Arc rather than the plain T. Tauri commands access them // via `tauri::State<'_, Arc>` and deref / clone as needed. let ptys: Arc = Arc::new(PtyManager::new()); let mcp_state: Arc> = Arc::new(tokio::sync::RwLock::new(McpState::default())); // Pending action registry — separate managed state so mcp_action_reply can // grab it without needing to lock McpState or reach into TileService. let pending_actions: Arc = Arc::new(PendingActions::default()); tauri::Builder::default() .plugin(tauri_plugin_clipboard_manager::init()) .plugin(tauri_plugin_opener::init()) .manage(ptys) .manage(mcp_state) .manage(McpServerHandle::default()) .manage(pending_actions) .invoke_handler(tauri::generate_handler![ commands::list_distros, commands::spawn_pane, commands::write_to_pane, commands::resize_pane, commands::kill_pane, commands::save_workspace, commands::load_workspace, commands::list_ssh_hosts, commands::save_ssh_hosts, commands::set_host_password, commands::delete_host_password, commands::has_host_password, commands::mcp_start, commands::mcp_stop, commands::mcp_status, commands::mcp_regenerate_token, commands::mcp_update_state, commands::mcp_action_reply, commands::mcp_policy_load, commands::mcp_policy_save, commands::mcp_hard_deny_labels, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); }