cersei_tools/
glob_tool.rs1use super::*;
4use crate::tool_primitives::search as psearch;
5use serde::Deserialize;
6
7pub struct GlobTool;
8
9#[async_trait]
10impl Tool for GlobTool {
11 fn name(&self) -> &str {
12 "Glob"
13 }
14 fn description(&self) -> &str {
15 "Find files matching a glob pattern."
16 }
17 fn permission_level(&self) -> PermissionLevel {
18 PermissionLevel::ReadOnly
19 }
20 fn category(&self) -> ToolCategory {
21 ToolCategory::FileSystem
22 }
23
24 fn input_schema(&self) -> Value {
25 serde_json::json!({
26 "type": "object",
27 "properties": {
28 "pattern": { "type": "string", "description": "Glob pattern (e.g. **/*.rs)" },
29 "path": { "type": "string", "description": "Directory to search in" },
30 "limit": { "type": "integer", "description": "Max results to return (default 200)" }
31 },
32 "required": ["pattern"]
33 })
34 }
35
36 async fn execute(&self, input: Value, ctx: &ToolContext) -> ToolResult {
37 #[derive(Deserialize)]
38 struct Input {
39 pattern: String,
40 path: Option<String>,
41 limit: Option<usize>,
42 }
43
44 let input: Input = match serde_json::from_value(input) {
45 Ok(i) => i,
46 Err(e) => return ToolResult::error(format!("Invalid input: {}", e)),
47 };
48
49 let max_results = input.limit.unwrap_or(200);
50
51 let base_dir = input
52 .path
53 .as_ref()
54 .map(PathBuf::from)
55 .unwrap_or_else(|| ctx.working_dir.clone());
56
57 match psearch::glob(&input.pattern, &base_dir).await {
58 Ok(mut paths) => {
59 paths.sort();
60 if paths.is_empty() {
61 ToolResult::success("No files matched the pattern.")
62 } else {
63 let total = paths.len();
64 let truncated = total > max_results;
65 let output: Vec<String> = paths
66 .iter()
67 .take(max_results)
68 .map(|p| p.display().to_string())
69 .collect();
70 let mut result = output.join("\n");
71 if truncated {
72 result.push_str(&format!(
73 "\n\n[Showing {max_results} of {total} matches. Use a more specific pattern to narrow results.]"
74 ));
75 }
76 ToolResult::success(result)
77 }
78 }
79 Err(e) => ToolResult::error(format!("Glob failed: {}", e)),
80 }
81 }
82}