use std::fs; use std::path::PathBuf; use serde_json::{json, Value}; use anyhow::{Result, anyhow}; use super::super::Tool; use super::super::ToolCtx; use super::super::resolve_path; use super::helpers::arg_str; pub struct Delete; impl Tool for Delete { fn name(&self) -> &'static str { "delete" } fn description(&self) -> &'static str { "Delete a file or empty directory. Will not delete non-empty directories." } fn parameters(&self) -> Value { json!({ "type": "object", "properties": { "path": { "type": "string", "description": "Path to the file or directory to delete (relative to workspace root)" } }, "required": ["path"] }) } fn run(&self, ctx: &ToolCtx, args: &Value) -> Result { let rel = arg_str(args, "path")?; let path: PathBuf = resolve_path(&ctx.workspaces, &rel)?; if !path.exists() { return Ok(format!("path '{}' does not exist (resolved to {})", rel, path.display())); } let metadata = path.metadata() .map_err(|e| anyhow!("failed to read metadata for '{}': {}", rel, e))?; if metadata.is_dir() { let is_empty = fs::read_dir(&path) .map_err(|e| anyhow!("failed to read directory '{}': {}", rel, e))? .next() .is_none(); if is_empty { fs::remove_dir(&path) .map_err(|e| anyhow!("failed to remove directory '{}': {}", rel, e))?; Ok(format!("removed empty directory {}", rel)) } else { anyhow::bail!("directory '{}' is not empty (refusing to delete)", rel); } } else { fs::remove_file(&path) .map_err(|e| anyhow!("failed to delete '{}': {}", rel, e))?; Ok(format!("deleted {}", rel)) } } }