use std::path::PathBuf; use std::sync::Mutex; use tokio::sync::watch; pub struct SessionState { pub project_root: Mutex>, pub cancel_tx: watch::Sender, pub cancel_rx: watch::Receiver, } impl Default for SessionState { fn default() -> Self { let (cancel_tx, cancel_rx) = watch::channel(false); Self { project_root: Mutex::new(None), cancel_tx, cancel_rx, } } } impl SessionState { pub fn get_project_root(&self) -> Result { let root_guard = self.project_root.lock().map_err(|e| e.to_string())?; let root = root_guard.as_ref().ok_or_else(|| { // TRACE:MERGE-DEBUG — remove once root cause is found crate::slog_error!( "[MERGE-DEBUG] get_project_root() called but project_root is None! \ Backtrace hint: check caller in MCP tool handler." ); "No project is currently open.".to_string() })?; Ok(root.clone()) } }