fix(terminal): harden relay lifecycle and session cleanup
- bound relay input and detach saturated output transports - drain PTY output after child exit - make terminal close lifecycle race-safe - prune expired CC sessions and audit closure reasons - require matching agent hello/auth identities - validate terminal IDs and PTY dimensions
This commit is contained in:
10 files changed
+408
-115
No files matched your search
@@ -17,7 +17,7 @@ impl RequestId {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize)]
|
||||
#[serde(transparent)]
|
||||
pub struct TerminalId(String);
|
||||
|
||||
@@ -41,6 +41,24 @@ impl fmt::Display for TerminalId {
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for TerminalId {
|
||||
type Error = String;
|
||||
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
Self::new(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for TerminalId {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let raw = String::deserialize(deserializer)?;
|
||||
Self::try_from(raw).map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum AgentCapability {
|
||||
@@ -297,6 +315,16 @@ mod tests {
|
||||
assert!(err.contains("must not be empty"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn terminal_id_deserialization_enforces_validation() {
|
||||
let valid: TerminalId = serde_json::from_str(r#""term-1""#).expect("valid terminal id");
|
||||
assert_eq!(valid.as_str(), "term-1");
|
||||
|
||||
let error = serde_json::from_str::<TerminalId>(r#"" ""#)
|
||||
.expect_err("empty terminal id must fail");
|
||||
assert!(error.to_string().contains("must not be empty"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn client_result_with_devs_serializes() {
|
||||
let msg = ClientMessage::Result {
|
||||
|
||||
Reference in new issue
Block a user