(
&self,
args: serde_json::Value,
ctx: ToolContext,
)
| 90 | } |
| 91 | |
| 92 | async fn execute( |
| 93 | &self, |
| 94 | args: serde_json::Value, |
| 95 | ctx: ToolContext, |
| 96 | ) -> Result<ToolResult, ToolError> { |
| 97 | let input: LsInput = serde_json::from_value(args).unwrap_or(LsInput { |
| 98 | path: None, |
| 99 | ignore: None, |
| 100 | }); |
| 101 | |
| 102 | let requested_path = input.path.unwrap_or_else(|| ".".to_string()); |
| 103 | let mut base_dir = if Path::new(&requested_path).is_absolute() { |
| 104 | PathBuf::from(&requested_path) |
| 105 | } else { |
| 106 | PathBuf::from(&ctx.directory).join(&requested_path) |
| 107 | }; |
| 108 | if let Ok(canonical) = base_dir.canonicalize() { |
| 109 | base_dir = canonical; |
| 110 | } |
| 111 | let base_dir_str = base_dir.to_string_lossy().to_string(); |
| 112 | |
| 113 | ctx.ask_permission( |
| 114 | PermissionRequest::new("list") |
| 115 | .with_pattern(&base_dir_str) |
| 116 | .with_metadata("path", serde_json::json!(&base_dir_str)) |
| 117 | .always_allow(), |
| 118 | ) |
| 119 | .await?; |
| 120 | |
| 121 | if !base_dir.exists() { |
| 122 | return Err(ToolError::FileNotFound(base_dir.display().to_string())); |
| 123 | } |
| 124 | |
| 125 | if !base_dir.is_dir() { |
| 126 | return Err(ToolError::ExecutionError(format!( |
| 127 | "{} is not a directory", |
| 128 | base_dir.display() |
| 129 | ))); |
| 130 | } |
| 131 | |
| 132 | let mut ignore_set: HashSet<String> = IGNORE_PATTERNS |
| 133 | .iter() |
| 134 | .map(|s| s.trim_end_matches('/').to_string()) |
| 135 | .collect(); |
| 136 | let mut ignore_globs: Vec<Pattern> = Vec::new(); |
| 137 | |
| 138 | if let Some(custom_ignore) = input.ignore { |
| 139 | for pattern in custom_ignore { |
| 140 | let normalized = pattern.trim_start_matches('!').trim(); |
| 141 | if normalized.is_empty() { |
| 142 | continue; |
| 143 | } |
| 144 | |
| 145 | if has_glob_meta(normalized) { |
| 146 | if let Ok(glob) = Pattern::new(normalized) { |
| 147 | ignore_globs.push(glob); |
| 148 | } |
| 149 | } else { |
nothing calls this directly
no test coverage detected