use super::super::{
get_thread_original_working_directory, get_thread_working_directory,
set_thread_working_directory, McpToolCall,
};
use anyhow::{bail, Result};
use serde_json::{json, Value};
pub async fn execute_workdir_command(call: &McpToolCall) -> Result<String> {
let reset = call
.parameters
.get("reset")
.and_then(|v| v.as_bool())
.unwrap_or(false);
if reset {
let original_dir = get_thread_original_working_directory();
set_thread_working_directory(original_dir.clone());
return Ok(json!({
"success": true,
"action": "reset",
"working_directory": original_dir.to_string_lossy(),
"message": format!("Working directory reset to: {}", original_dir.display())
})
.to_string());
}
match call.parameters.get("path") {
Some(Value::String(path_str)) if !path_str.trim().is_empty() => {
let path_str = path_str.trim();
let new_path = if std::path::Path::new(path_str).is_absolute() {
std::path::PathBuf::from(path_str)
} else {
let current = get_thread_working_directory();
current.join(path_str)
};
let canonical_path = match new_path.canonicalize() {
Ok(p) => p,
Err(e) => {
bail!(
"Path does not exist or is not accessible: {} (error: {})",
new_path.display(),
e
);
}
};
if !canonical_path.is_dir() {
bail!("Path is not a directory: {}", canonical_path.display());
}
let old_dir = get_thread_working_directory();
set_thread_working_directory(canonical_path.clone());
Ok(json!({
"success": true,
"action": "set",
"previous_directory": old_dir.to_string_lossy(),
"working_directory": canonical_path.to_string_lossy(),
"message": format!("Working directory changed from {} to {}", old_dir.display(), canonical_path.display())
}).to_string())
}
Some(_) => bail!("Parameter 'path' must be a non-empty string"),
None => {
let current_dir = get_thread_working_directory();
Ok(json!({
"success": true,
"action": "get",
"working_directory": current_dir.to_string_lossy(),
"message": format!("Current working directory: {}", current_dir.display())
})
.to_string())
}
}
}