// Claude Desktop — Session-Verwaltung // Sessions bleiben permanent gespeichert bis der User sie löscht use std::sync::{Arc, Mutex}; use tauri::{AppHandle, Manager}; use crate::db::{self, Session}; // ============ Tauri Commands ============ /// Neue Session erstellen #[tauri::command] pub async fn create_session( app: AppHandle, title: String, working_dir: Option, ) -> Result { let session = Session { id: uuid::Uuid::new_v4().to_string(), claude_session_id: None, title, working_dir, message_count: 0, token_input: 0, token_output: 0, cost_usd: 0.0, status: "active".to_string(), created_at: chrono::Local::now().to_rfc3339(), updated_at: chrono::Local::now().to_rfc3339(), last_message: None, }; let state = app.state::>>(); let db = state.lock().unwrap(); db.create_session(&session).map_err(|e| e.to_string())?; // Als aktive Session speichern db.set_setting("active_session_id", &session.id).map_err(|e| e.to_string())?; println!("📝 Neue Session: {} ({})", session.title, session.id); Ok(session) } /// Session aktualisieren (nach Nachrichten, Token-Update, etc.) #[tauri::command] pub async fn update_session( app: AppHandle, session: Session, ) -> Result<(), String> { let state = app.state::>>(); let db = state.lock().unwrap(); db.update_session(&session).map_err(|e| e.to_string()) } /// Alle Sessions laden #[tauri::command] pub async fn list_sessions( app: AppHandle, limit: Option, ) -> Result, String> { let limit = limit.unwrap_or(50); let state = app.state::>>(); let db = state.lock().unwrap(); db.load_sessions(limit).map_err(|e| e.to_string()) } /// Session nach ID laden #[tauri::command] pub async fn get_session( app: AppHandle, id: String, ) -> Result, String> { let state = app.state::>>(); let db = state.lock().unwrap(); db.get_session(&id).map_err(|e| e.to_string()) } /// Session löschen #[tauri::command] pub async fn delete_session( app: AppHandle, id: String, ) -> Result<(), String> { let state = app.state::>>(); let db = state.lock().unwrap(); db.delete_session(&id).map_err(|e| e.to_string())?; // Falls es die aktive Session war, Setting löschen if let Ok(Some(active_id)) = db.get_setting("active_session_id") { if active_id == id { let _ = db.set_setting("active_session_id", ""); } } println!("🗑️ Session gelöscht: {}", id); Ok(()) } /// Session fortsetzen — setzt die aktive Session und gibt die claude_session_id zurück #[tauri::command] pub async fn resume_session( app: AppHandle, id: String, ) -> Result { let state = app.state::>>(); let db = state.lock().unwrap(); let session = db.get_session(&id) .map_err(|e| e.to_string())? .ok_or_else(|| format!("Session {} nicht gefunden", id))?; // Als aktive Session setzen db.set_setting("active_session_id", &session.id).map_err(|e| e.to_string())?; println!("▶️ Session fortgesetzt: {} (claude: {:?})", session.title, session.claude_session_id); Ok(session) } /// Aktive Session holen (nach App-Start) #[tauri::command] pub async fn get_active_session( app: AppHandle, ) -> Result, String> { let state = app.state::>>(); let db = state.lock().unwrap(); if let Ok(Some(id)) = db.get_setting("active_session_id") { if !id.is_empty() { return db.get_session(&id).map_err(|e| e.to_string()); } } Ok(None) } /// Claude Session-ID speichern (kommt von der Bridge nach erstem Request) #[tauri::command] pub async fn set_claude_session_id( app: AppHandle, session_id: String, claude_session_id: String, ) -> Result<(), String> { let state = app.state::>>(); let db = state.lock().unwrap(); if let Ok(Some(mut session)) = db.get_session(&session_id) { session.claude_session_id = Some(claude_session_id.clone()); db.update_session(&session).map_err(|e| e.to_string())?; println!("🔗 Claude Session-ID gesetzt: {} → {}", session_id, claude_session_id); } Ok(()) }