diff --git a/hive-matrix-mcp/src/wake.rs b/hive-matrix-mcp/src/wake.rs index 34e09dcd..5ce5b8e5 100644 --- a/hive-matrix-mcp/src/wake.rs +++ b/hive-matrix-mcp/src/wake.rs @@ -28,24 +28,37 @@ pub const WAKE_BODY_TRUNCATE: usize = 100; /// control socket at `socket`. Best-effort: returns Err on any plumbing /// failure; callers log + ignore so a wake delivery hiccup doesn't tear /// down the matrix sync loop. +/// +/// Wire format matches `hive_sh4re::Request` tagged with `"cmd"` per +/// `#[serde(tag = "cmd", rename_all = "snake_case")]`. Must be `"cmd"`, +/// not `"kind"` — the harness deserialises against the hive-sh4re type +/// and silently discards requests that don't match. pub async fn send_wake(socket: &Path, body: impl AsRef) -> Result<()> { + use tokio::io::AsyncBufReadExt; + let payload = serde_json::json!({ - "kind": "wake", + "cmd": "wake", "from": "matrix", "body": body.as_ref(), }); let line = format!("{}\n", serde_json::to_string(&payload)?); - let mut stream = UnixStream::connect(socket) + let stream = UnixStream::connect(socket) .await .with_context(|| format!("connect hyperhive socket {}", socket.display()))?; - stream + let (read, mut write) = stream.into_split(); + write .write_all(line.as_bytes()) .await .with_context(|| format!("write wake to {}", socket.display()))?; - stream + write .shutdown() .await .with_context(|| format!("shutdown write to {}", socket.display()))?; + // Drain the response line so the server doesn't get ECONNRESET on + // its write-back. We don't act on the response — best-effort wake. + let mut reader = tokio::io::BufReader::new(read); + let mut _resp = String::new(); + let _ = reader.read_line(&mut _resp).await; Ok(()) }