elizaos_plugin_code/actions/
git.rs1use async_trait::async_trait;
2use serde_json::Value;
3
4use crate::service::CoderService;
5use crate::{Action, ActionExample, ActionResult};
6
7pub struct GitAction;
8
9#[async_trait]
10impl Action for GitAction {
11 fn name(&self) -> &str {
12 "GIT"
13 }
14
15 fn similes(&self) -> Vec<&str> {
16 vec!["GIT_COMMAND", "GIT_RUN"]
17 }
18
19 fn description(&self) -> &str {
20 "Run a git command (restricted)."
21 }
22
23 async fn validate(&self, _message: &Value, _state: &Value) -> bool {
24 true
25 }
26
27 async fn handler(
28 &self,
29 message: &Value,
30 state: &Value,
31 service: Option<&mut CoderService>,
32 ) -> ActionResult {
33 let Some(svc) = service else {
34 return ActionResult {
35 success: false,
36 text: "Coder service is not available.".to_string(),
37 data: None,
38 error: Some("missing_service".to_string()),
39 };
40 };
41
42 let args = state.get("args").and_then(|v| v.as_str()).unwrap_or("");
43 if args.trim().is_empty() {
44 return ActionResult {
45 success: false,
46 text: "Missing args.".to_string(),
47 data: None,
48 error: Some("missing_args".to_string()),
49 };
50 }
51
52 let conv = message
53 .get("room_id")
54 .and_then(|v| v.as_str())
55 .or_else(|| message.get("agent_id").and_then(|v| v.as_str()))
56 .unwrap_or("default");
57
58 match svc.git(conv, args).await {
59 Ok(result) => ActionResult {
60 success: result.success,
61 text: if result.success {
62 result.stdout
63 } else {
64 result.stderr
65 },
66 data: None,
67 error: None,
68 },
69 Err(err) => ActionResult {
70 success: false,
71 text: err.to_string(),
72 data: None,
73 error: Some("git_failed".to_string()),
74 },
75 }
76 }
77
78 fn examples(&self) -> Vec<ActionExample> {
79 vec![ActionExample {
80 user_message: "git status".to_string(),
81 agent_response: "Running git…".to_string(),
82 }]
83 }
84}