add remote fleet terminal sessions

This commit is contained in:
lda committed 2026-07-15 07:33:37 +07:00 Verified
1 parent 4ecef8da38
commit 4d793136ba
24 files changed
+2386 -26

No files matched your search

+90
View File
@@ -17,6 +17,61 @@ impl RequestId {
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct TerminalId(String);
impl TerminalId {
pub fn new(value: impl Into<String>) -> Result<Self, String> {
let value = value.into();
if value.trim().is_empty() {
return Err("terminal_id must not be empty".into());
}
Ok(Self(value))
}
pub fn as_str(&self) -> &str {
&self.0
}
}
impl fmt::Display for TerminalId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AgentCapability {
Terminal,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum TerminalControl {
Resize { rows: u16, cols: u16 },
Ready,
Exited { exit_code: Option<i32> },
Error { code: String, message: String },
Close,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum TerminalAgentHandshake {
Auth {
agent_id: String,
relay_token: String,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum TerminalOperatorHandshake {
Attach { attachment_token: String },
}
impl TryFrom<String> for RequestId {
type Error = String;
@@ -153,6 +208,8 @@ pub enum CommandResult {
pub enum ClientMessage {
Hello {
agent_id: String,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
capabilities: Vec<AgentCapability>,
},
Auth {
agent_id: String,
@@ -173,6 +230,10 @@ pub enum ClientMessage {
request_id: RequestId,
error: ErrorPayload,
},
TerminalRejected {
terminal_id: TerminalId,
error: ErrorPayload,
},
}
#[derive(Clone, Debug, Serialize, Deserialize)]
@@ -183,6 +244,15 @@ pub enum ServerMessage {
command: AgentCommand,
},
SyncDeviceSnapshot,
OpenTerminal {
terminal_id: TerminalId,
relay_token: String,
rows: u16,
cols: u16,
},
CloseTerminal {
terminal_id: TerminalId,
},
}
#[cfg(test)]
@@ -232,4 +302,24 @@ mod tests {
assert!(json.contains("\"type\":\"device_snapshot\""));
assert!(json.contains("\"devices\""));
}
#[test]
fn terminal_messages_serialize_with_explicit_frame_types() {
let message = ServerMessage::OpenTerminal {
terminal_id: TerminalId::new("term-1").expect("terminal id"),
relay_token: "secret".into(),
rows: 30,
cols: 120,
};
let json = serde_json::to_string(&message).expect("serialize open terminal");
assert!(json.contains("\"type\":\"open_terminal\""));
assert!(json.contains("\"terminal_id\":\"term-1\""));
let resize = TerminalControl::Resize {
rows: 40,
cols: 160,
};
let json = serde_json::to_string(&resize).expect("serialize resize");
assert_eq!(json, r#"{"type":"resize","rows":40,"cols":160}"#);
}
}