generated from nhcarrigan/template
132 lines
4.1 KiB
Rust
132 lines
4.1 KiB
Rust
use parking_lot::Mutex;
|
|
use std::collections::HashMap;
|
|
use std::sync::Arc;
|
|
use tauri::AppHandle;
|
|
|
|
use crate::config::ClaudeStartOptions;
|
|
use crate::stats::UsageStats;
|
|
use crate::wsl_bridge::WslBridge;
|
|
|
|
pub struct BridgeManager {
|
|
bridges: HashMap<String, WslBridge>,
|
|
app_handle: Option<AppHandle>,
|
|
}
|
|
|
|
impl BridgeManager {
|
|
pub fn new() -> Self {
|
|
BridgeManager {
|
|
bridges: HashMap::new(),
|
|
app_handle: None,
|
|
}
|
|
}
|
|
|
|
pub fn set_app_handle(&mut self, app: AppHandle) {
|
|
self.app_handle = Some(app);
|
|
}
|
|
|
|
pub fn start_claude(
|
|
&mut self,
|
|
conversation_id: &str,
|
|
options: ClaudeStartOptions,
|
|
) -> Result<(), String> {
|
|
// Check if a bridge already exists for this conversation
|
|
if self.bridges.get(conversation_id).map(|b| b.is_running()).unwrap_or(false) {
|
|
return Err("Claude is already running for this conversation".to_string());
|
|
}
|
|
|
|
let app = self.app_handle.as_ref()
|
|
.ok_or_else(|| "App handle not set".to_string())?
|
|
.clone();
|
|
|
|
// Create a new bridge for this conversation
|
|
let mut bridge = WslBridge::new_with_conversation_id(conversation_id.to_string());
|
|
|
|
// Start the Claude process
|
|
bridge.start(app, options)?;
|
|
|
|
// Store the bridge
|
|
self.bridges.insert(conversation_id.to_string(), bridge);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
pub fn stop_claude(&mut self, conversation_id: &str) -> Result<(), String> {
|
|
if let Some(bridge) = self.bridges.get_mut(conversation_id) {
|
|
let app = self.app_handle.as_ref()
|
|
.ok_or_else(|| "App handle not set".to_string())?;
|
|
bridge.stop(app);
|
|
Ok(())
|
|
} else {
|
|
Err("No Claude instance found for this conversation".to_string())
|
|
}
|
|
}
|
|
|
|
pub fn interrupt_claude(&mut self, conversation_id: &str) -> Result<(), String> {
|
|
if let Some(bridge) = self.bridges.get_mut(conversation_id) {
|
|
let app = self.app_handle.as_ref()
|
|
.ok_or_else(|| "App handle not set".to_string())?;
|
|
bridge.interrupt(app)
|
|
} else {
|
|
Err("No Claude instance found for this conversation".to_string())
|
|
}
|
|
}
|
|
|
|
pub fn send_prompt(&mut self, conversation_id: &str, message: String) -> Result<(), String> {
|
|
if let Some(bridge) = self.bridges.get_mut(conversation_id) {
|
|
bridge.send_message(&message)
|
|
} else {
|
|
Err("No Claude instance found for this conversation".to_string())
|
|
}
|
|
}
|
|
|
|
pub fn is_claude_running(&self, conversation_id: &str) -> bool {
|
|
self.bridges.get(conversation_id)
|
|
.map(|b| b.is_running())
|
|
.unwrap_or(false)
|
|
}
|
|
|
|
pub fn get_working_directory(&self, conversation_id: &str) -> Result<String, String> {
|
|
self.bridges.get(conversation_id)
|
|
.map(|b| b.get_working_directory().to_string())
|
|
.ok_or_else(|| "No Claude instance found for this conversation".to_string())
|
|
}
|
|
|
|
pub fn get_usage_stats(&self, conversation_id: &str) -> Result<UsageStats, String> {
|
|
self.bridges.get(conversation_id)
|
|
.map(|b| b.get_stats())
|
|
.ok_or_else(|| "No Claude instance found for this conversation".to_string())
|
|
}
|
|
|
|
pub fn cleanup_stopped_bridges(&mut self) {
|
|
// Remove bridges that are no longer running
|
|
self.bridges.retain(|_, bridge| bridge.is_running());
|
|
}
|
|
|
|
pub fn stop_all(&mut self) {
|
|
if let Some(app) = &self.app_handle {
|
|
for (_, bridge) in self.bridges.iter_mut() {
|
|
bridge.stop(app);
|
|
}
|
|
}
|
|
self.bridges.clear();
|
|
}
|
|
|
|
pub fn get_active_conversations(&self) -> Vec<String> {
|
|
self.bridges.keys()
|
|
.filter(|id| self.bridges.get(*id).map(|b| b.is_running()).unwrap_or(false))
|
|
.cloned()
|
|
.collect()
|
|
}
|
|
}
|
|
|
|
impl Default for BridgeManager {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
|
|
pub type SharedBridgeManager = Arc<Mutex<BridgeManager>>;
|
|
|
|
pub fn create_shared_bridge_manager() -> SharedBridgeManager {
|
|
Arc::new(Mutex::new(BridgeManager::new()))
|
|
} |