deepseek_rust_cli/tools/
git_tools.rs1use std::{collections::HashMap, path::Path};
2
3use anyhow::Result;
4use async_trait::async_trait;
5use serde_json::Value;
6
7use crate::{agent::types::UndoAction, tools, tools::base::Tool};
8
9pub struct GitStatusTool;
10#[async_trait]
11impl Tool for GitStatusTool {
12 fn name(&self) -> &str {
13 "git_status"
14 }
15 async fn execute(
16 &self,
17 args: &HashMap<String, Value>,
18 _undo: &mut Vec<UndoAction>,
19 _cwd: Option<&Path>,
20 ) -> Result<String> {
21 let path = args.get("path").and_then(|v| v.as_str());
22 tools::git_ops::git_status(path).await
23 }
24}
25
26pub struct GitDiffTool;
27#[async_trait]
28impl Tool for GitDiffTool {
29 fn name(&self) -> &str {
30 "git_diff"
31 }
32 async fn execute(
33 &self,
34 args: &HashMap<String, Value>,
35 _undo: &mut Vec<UndoAction>,
36 _cwd: Option<&Path>,
37 ) -> Result<String> {
38 let path = args.get("path").and_then(|v| v.as_str());
39 let staged = args
40 .get("staged")
41 .and_then(|v| v.as_bool())
42 .unwrap_or(false);
43 tools::git_ops::git_diff(path, staged).await
44 }
45}
46
47pub struct GitLogTool;
48#[async_trait]
49impl Tool for GitLogTool {
50 fn name(&self) -> &str {
51 "git_log"
52 }
53 async fn execute(
54 &self,
55 args: &HashMap<String, Value>,
56 _undo: &mut Vec<UndoAction>,
57 _cwd: Option<&Path>,
58 ) -> Result<String> {
59 let path = args.get("path").and_then(|v| v.as_str());
60 let count = args
61 .get("count")
62 .and_then(|v| v.as_u64())
63 .map(|v| v as usize);
64 tools::git_ops::git_log(path, count).await
65 }
66}
67
68pub struct GitBranchTool;
69#[async_trait]
70impl Tool for GitBranchTool {
71 fn name(&self) -> &str {
72 "git_branch"
73 }
74 async fn execute(
75 &self,
76 args: &HashMap<String, Value>,
77 _undo: &mut Vec<UndoAction>,
78 _cwd: Option<&Path>,
79 ) -> Result<String> {
80 let path = args.get("path").and_then(|v| v.as_str());
81 let action = args.get("action").and_then(|v| v.as_str());
82 let name = args.get("name").and_then(|v| v.as_str());
83 tools::git_ops::git_branch(path, action, name).await
84 }
85}
86
87pub struct GitAddTool;
88#[async_trait]
89impl Tool for GitAddTool {
90 fn name(&self) -> &str {
91 "git_add"
92 }
93 async fn execute(
94 &self,
95 args: &HashMap<String, Value>,
96 _undo: &mut Vec<UndoAction>,
97 _cwd: Option<&Path>,
98 ) -> Result<String> {
99 let path = args.get("path").and_then(|v| v.as_str());
100 let files = args.get("files").and_then(|v| v.as_str());
101 tools::git_ops::git_add(path, files).await
102 }
103}
104
105pub struct GitCommitTool;
106#[async_trait]
107impl Tool for GitCommitTool {
108 fn name(&self) -> &str {
109 "git_commit"
110 }
111 async fn execute(
112 &self,
113 args: &HashMap<String, Value>,
114 _undo: &mut Vec<UndoAction>,
115 _cwd: Option<&Path>,
116 ) -> Result<String> {
117 let path = args.get("path").and_then(|v| v.as_str());
118 let message = args
119 .get("message")
120 .and_then(|v| v.as_str())
121 .ok_or_else(|| anyhow::anyhow!("Missing 'message'"))?;
122 tools::git_ops::git_commit(path, message).await
123 }
124}
125
126pub struct GitPushTool;
127#[async_trait]
128impl Tool for GitPushTool {
129 fn name(&self) -> &str {
130 "git_push"
131 }
132 async fn execute(
133 &self,
134 args: &HashMap<String, Value>,
135 _undo: &mut Vec<UndoAction>,
136 _cwd: Option<&Path>,
137 ) -> Result<String> {
138 let path = args.get("path").and_then(|v| v.as_str());
139 let remote = args.get("remote").and_then(|v| v.as_str());
140 let branch = args.get("branch").and_then(|v| v.as_str());
141 tools::git_ops::git_push(path, remote, branch).await
142 }
143}
144
145pub struct GitPullTool;
146#[async_trait]
147impl Tool for GitPullTool {
148 fn name(&self) -> &str {
149 "git_pull"
150 }
151 async fn execute(
152 &self,
153 args: &HashMap<String, Value>,
154 _undo: &mut Vec<UndoAction>,
155 _cwd: Option<&Path>,
156 ) -> Result<String> {
157 let path = args.get("path").and_then(|v| v.as_str());
158 let remote = args.get("remote").and_then(|v| v.as_str());
159 let branch = args.get("branch").and_then(|v| v.as_str());
160 tools::git_ops::git_pull(path, remote, branch).await
161 }
162}
163
164pub struct GitCheckoutTool;
165#[async_trait]
166impl Tool for GitCheckoutTool {
167 fn name(&self) -> &str {
168 "git_checkout"
169 }
170 async fn execute(
171 &self,
172 args: &HashMap<String, Value>,
173 _undo: &mut Vec<UndoAction>,
174 _cwd: Option<&Path>,
175 ) -> Result<String> {
176 let path = args.get("path").and_then(|v| v.as_str());
177 let target = args
178 .get("target")
179 .and_then(|v| v.as_str())
180 .ok_or_else(|| anyhow::anyhow!("Missing 'target'"))?;
181 tools::git_ops::git_checkout(path, target).await
182 }
183}
184
185pub struct GitCloneTool;
186#[async_trait]
187impl Tool for GitCloneTool {
188 fn name(&self) -> &str {
189 "git_clone"
190 }
191 async fn execute(
192 &self,
193 args: &HashMap<String, Value>,
194 _undo: &mut Vec<UndoAction>,
195 _cwd: Option<&Path>,
196 ) -> Result<String> {
197 let url = args
198 .get("url")
199 .and_then(|v| v.as_str())
200 .ok_or_else(|| anyhow::anyhow!("Missing 'url'"))?;
201 let dest = args.get("dest").and_then(|v| v.as_str());
202 tools::git_ops::git_clone(url, dest).await
203 }
204}
205
206pub struct GitRemoteListTool;
207#[async_trait]
208impl Tool for GitRemoteListTool {
209 fn name(&self) -> &str {
210 "git_remote_list"
211 }
212 async fn execute(
213 &self,
214 args: &HashMap<String, Value>,
215 _undo: &mut Vec<UndoAction>,
216 _cwd: Option<&Path>,
217 ) -> Result<String> {
218 let path = args.get("path").and_then(|v| v.as_str());
219 tools::git_ops::git_remote_list(path).await
220 }
221}
222
223pub struct GitStashTool;
224#[async_trait]
225impl Tool for GitStashTool {
226 fn name(&self) -> &str {
227 "git_stash"
228 }
229 async fn execute(
230 &self,
231 args: &HashMap<String, Value>,
232 _undo: &mut Vec<UndoAction>,
233 _cwd: Option<&Path>,
234 ) -> Result<String> {
235 let path = args.get("path").and_then(|v| v.as_str());
236 let action = args.get("action").and_then(|v| v.as_str());
237 tools::git_ops::git_stash(path, action).await
238 }
239}