git_iris/mcp/tools/
utils.rs1use crate::common::DetailLevel;
6use crate::config::Config as GitIrisConfig;
7use crate::git::GitRepo;
8use rmcp::model::{Annotated, CallToolResult, Content, RawContent, RawTextContent};
9use std::sync::Arc;
10
11#[async_trait::async_trait]
15pub trait GitIrisTool {
16 async fn execute(
18 &self,
19 git_repo: Arc<GitRepo>,
20 config: GitIrisConfig,
21 ) -> Result<CallToolResult, anyhow::Error>;
22}
23
24pub fn create_text_result(text: String) -> CallToolResult {
28 CallToolResult {
29 content: vec![Content::from(Annotated {
30 raw: RawContent::Text(RawTextContent { text }),
31 annotations: None,
32 })],
33 is_error: None,
34 }
35}
36
37pub fn parse_detail_level(detail_level: &str) -> DetailLevel {
41 if detail_level.trim().is_empty() {
42 return DetailLevel::Standard;
43 }
44
45 match detail_level.trim().to_lowercase().as_str() {
46 "minimal" => DetailLevel::Minimal,
47 "detailed" => DetailLevel::Detailed,
48 _ => DetailLevel::Standard,
49 }
50}
51
52pub fn apply_custom_instructions(config: &mut crate::config::Config, custom_instructions: &str) {
54 if !custom_instructions.trim().is_empty() {
55 config.set_temp_instructions(Some(custom_instructions.to_string()));
56 }
57}
58
59pub fn validate_repository_parameter(repo: &str) -> Result<(), anyhow::Error> {
61 if repo.trim().is_empty() {
62 return Err(anyhow::anyhow!(
63 "The `repository` parameter is required and must be a valid local path or remote URL."
64 ));
65 }
66 if !(repo.starts_with("http://") || repo.starts_with("https://") || repo.starts_with("git@")) {
67 let path = std::path::Path::new(repo);
68 if !path.exists() {
69 return Err(anyhow::anyhow!(format!(
70 "The specified repository path does not exist: {}",
71 repo
72 )));
73 }
74 if !path.join(".git").exists() {
75 return Err(anyhow::anyhow!(format!(
76 "The specified path is not a git repository: {}",
77 repo
78 )));
79 }
80 }
81 Ok(())
82}
83
84pub fn resolve_git_repo(
89 repo_path: Option<&str>,
90 _default_git_repo: Arc<GitRepo>,
91) -> Result<Arc<GitRepo>, anyhow::Error> {
92 match repo_path {
93 Some(path) if !path.trim().is_empty() => {
94 if path.starts_with("http://")
95 || path.starts_with("https://")
96 || path.starts_with("git@")
97 {
98 Ok(Arc::new(GitRepo::new_from_url(Some(path.to_string()))?))
100 } else {
101 let path = std::path::Path::new(path);
103 Ok(Arc::new(GitRepo::new(path)?))
104 }
105 }
106 _ => Err(anyhow::anyhow!(
107 "The `repository` parameter is required and must be a valid local path or remote URL."
108 )),
109 }
110}