hanzo_protocol/
approvals.rs1use std::collections::HashMap;
2use std::path::PathBuf;
3
4use crate::mcp::RequestId;
5use crate::parse_command::ParsedCommand;
6use crate::protocol::FileChange;
7use schemars::JsonSchema;
8use serde::Deserialize;
9use serde::Serialize;
10use ts_rs::TS;
11
12#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
18#[serde(transparent)]
19#[ts(type = "Array<string>")]
20pub struct ExecPolicyAmendment {
21 pub command: Vec<String>,
22}
23
24impl ExecPolicyAmendment {
25 pub fn new(command: Vec<String>) -> Self {
26 Self { command }
27 }
28
29 pub fn command(&self) -> &[String] {
30 &self.command
31 }
32}
33
34impl From<Vec<String>> for ExecPolicyAmendment {
35 fn from(command: Vec<String>) -> Self {
36 Self { command }
37 }
38}
39
40#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
41#[serde(rename_all = "snake_case")]
42pub enum NetworkApprovalProtocol {
43 Http,
46 #[serde(alias = "https_connect", alias = "http-connect")]
47 Https,
48 Socks5Tcp,
49 Socks5Udp,
50}
51
52#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
53pub struct NetworkApprovalContext {
54 pub host: String,
55 pub protocol: NetworkApprovalProtocol,
56}
57
58#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
59pub struct ExecApprovalRequestEvent {
60 pub call_id: String,
62 #[serde(default, skip_serializing_if = "Option::is_none")]
67 #[ts(optional)]
68 pub approval_id: Option<String>,
69 #[serde(default)]
72 pub turn_id: String,
73 pub command: Vec<String>,
75 pub cwd: PathBuf,
77 #[serde(skip_serializing_if = "Option::is_none")]
79 pub reason: Option<String>,
80 #[serde(default, skip_serializing_if = "Option::is_none")]
82 #[ts(optional)]
83 pub network_approval_context: Option<NetworkApprovalContext>,
84 #[serde(default, skip_serializing_if = "Option::is_none")]
86 #[ts(optional)]
87 pub proposed_execpolicy_amendment: Option<ExecPolicyAmendment>,
88 pub parsed_cmd: Vec<ParsedCommand>,
89}
90
91impl ExecApprovalRequestEvent {
92 pub fn effective_approval_id(&self) -> String {
93 self.approval_id
94 .clone()
95 .unwrap_or_else(|| self.call_id.clone())
96 }
97}
98
99#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
100pub struct ElicitationRequestEvent {
101 pub server_name: String,
102 #[ts(type = "string | number")]
103 pub id: RequestId,
104 pub message: String,
105 }
109
110#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, JsonSchema, TS)]
111#[serde(rename_all = "lowercase")]
112pub enum ElicitationAction {
113 Accept,
114 Decline,
115 Cancel,
116}
117
118#[derive(Debug, Clone, Deserialize, Serialize, JsonSchema, TS)]
119pub struct ApplyPatchApprovalRequestEvent {
120 pub call_id: String,
122 #[serde(default)]
125 pub turn_id: String,
126 pub changes: HashMap<PathBuf, FileChange>,
127 #[serde(skip_serializing_if = "Option::is_none")]
129 pub reason: Option<String>,
130 #[serde(skip_serializing_if = "Option::is_none")]
132 pub grant_root: Option<PathBuf>,
133}