list_worktrees_tool.rs

 1use std::sync::Arc;
 2
 3use anyhow::Result;
 4use assistant_tool::Tool;
 5use gpui::{App, Entity, Task};
 6use language_model::LanguageModelRequestMessage;
 7use project::Project;
 8use schemars::JsonSchema;
 9use serde::{Deserialize, Serialize};
10
11#[derive(Debug, Serialize, Deserialize, JsonSchema)]
12pub struct ListWorktreesToolInput {}
13
14pub struct ListWorktreesTool;
15
16impl Tool for ListWorktreesTool {
17    fn name(&self) -> String {
18        "list-worktrees".into()
19    }
20
21    fn description(&self) -> String {
22        "Lists all worktrees in the current project. Use this tool when you need to find available worktrees and their IDs.".into()
23    }
24
25    fn input_schema(&self) -> serde_json::Value {
26        serde_json::json!(
27            {
28                "type": "object",
29                "properties": {},
30                "required": []
31            }
32        )
33    }
34
35    fn run(
36        self: Arc<Self>,
37        _input: serde_json::Value,
38        _messages: &[LanguageModelRequestMessage],
39        project: Entity<Project>,
40        cx: &mut App,
41    ) -> Task<Result<String>> {
42        cx.spawn(|cx| async move {
43            cx.update(|cx| {
44                #[derive(Debug, Serialize)]
45                struct WorktreeInfo {
46                    id: usize,
47                    root_name: String,
48                    root_dir: Option<String>,
49                }
50
51                let worktrees = project.update(cx, |project, cx| {
52                    project
53                        .visible_worktrees(cx)
54                        .map(|worktree| {
55                            worktree.read_with(cx, |worktree, _cx| WorktreeInfo {
56                                id: worktree.id().to_usize(),
57                                root_dir: worktree
58                                    .root_dir()
59                                    .map(|root_dir| root_dir.to_string_lossy().to_string()),
60                                root_name: worktree.root_name().to_string(),
61                            })
62                        })
63                        .collect::<Vec<_>>()
64                });
65
66                if worktrees.is_empty() {
67                    return Ok("No worktrees found in the current project.".to_string());
68                }
69
70                let mut result = String::from("Worktrees in the current project:\n\n");
71                for worktree in worktrees {
72                    result.push_str(&serde_json::to_string(&worktree)?);
73                }
74
75                Ok(result)
76            })?
77        })
78    }
79}