48 lines
1.4 KiB
Rust
48 lines
1.4 KiB
Rust
use serde_json::{json, Value};
|
|||
|
|
use anyhow::{Result, anyhow};
|
||
|
|
use super::super::Tool;
|
||
|
|
use super::super::ToolCtx;
|
||
|
|
|
||
|
|
pub struct Cd;
|
||
|
|
|
||
|
|
impl Tool for Cd {
|
||
|
|
fn name(&self) -> &'static str {
|
||
|
|
"cd"
|
||
|
|
}
|
||
|
|
|
||
|
|
fn description(&self) -> &'static str {
|
||
|
|
"Check if a directory exists within the workspace and print its resolved path. Use this to verify a directory path before running other commands there."
|
||
|
|
}
|
||
|
|
|
||
|
|
fn parameters(&self) -> Value {
|
||
|
|
json!({
|
||
|
|
"type": "object",
|
||
|
|
"properties": {
|
||
|
|
"path": {
|
||
|
|
"type": "string",
|
||
|
|
"description": "Directory path (relative to workspace root)"
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"required": ["path"]
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
fn run(&self, ctx: &ToolCtx, args: &Value) -> Result<String> {
|
||
|
|
let rel = args.get("path")
|
||
|
|
.and_then(|v| v.as_str())
|
||
|
|
.ok_or_else(|| anyhow!("missing required argument: path"))?;
|
||
|
|
|
||
|
|
let path = super::super::resolve_path(&ctx.workspaces, rel)?;
|
||
|
|
|
||
|
|
if !path.exists() {
|
||
|
|
return Ok(format!("path '{}' does not exist (resolved to {})", rel, path.display()));
|
||
|
|
}
|
||
|
|
if !path.is_dir() {
|
||
|
|
return Ok(format!("path '{}' is not a directory (resolved to {})", rel, path.display()));
|
||
|
|
}
|
||
|
|
|
||
|
|
let canon = path.canonicalize().unwrap_or(path);
|
||
|
|
Ok(format!("{}", canon.display()))
|
||
|
|
}
|
||
|
|
}
|