Skip to main content

soma_codemode/git/
provider.rs

1use serde_json::{json, Value};
2
3use crate::ToolError;
4
5use super::command::GitCommand;
6use super::safety::validate_ref;
7
8#[derive(Debug, Clone)]
9pub struct GitProvider {
10    cwd: std::path::PathBuf,
11}
12
13impl GitProvider {
14    pub fn new(cwd: impl Into<std::path::PathBuf>) -> Self {
15        Self { cwd: cwd.into() }
16    }
17
18    pub async fn dispatch(&self, method: &str, params: Value) -> Result<Value, ToolError> {
19        match method {
20            "status" => Ok(json!({
21                "stdout": GitCommand::new(&self.cwd, ["status", "--short"]).run().await?
22            })),
23            "show_ref" => {
24                let reference = params.get("ref").and_then(Value::as_str).ok_or_else(|| {
25                    ToolError::MissingParam {
26                        message: "missing `ref`".to_string(),
27                        param: "ref".to_string(),
28                    }
29                })?;
30                validate_ref(reference)?;
31                let resolved = GitCommand::new(
32                    &self.cwd,
33                    vec![
34                        "rev-parse".to_string(),
35                        "--verify".to_string(),
36                        "--quiet".to_string(),
37                        format!("{reference}^{{object}}"),
38                    ],
39                )
40                .run()
41                .await?;
42                Ok(json!({"ref": reference, "oid": resolved.trim()}))
43            }
44            _ => Err(ToolError::UnknownAction {
45                message: format!("unknown git method `{method}`"),
46                valid: vec!["status".to_string(), "show_ref".to_string()],
47                hint: None,
48            }),
49        }
50    }
51}