feat(proto): EventLog/MarkRead commands and Event/EventsRead events

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 06:54:05 +07:00
parent fc13e4340c
commit 5a8596dd0b
+81
View File
@@ -1,4 +1,5 @@
use serde::{Deserialize, Serialize};
use crate::event::{EventRecord, MarkReadTarget};
use crate::ids::{GroupId, SurfaceId, WorkspaceId};
use crate::layout::LayoutNode;
use crate::status::SurfaceState;
@@ -116,6 +117,11 @@ pub enum Cmd {
},
DeleteGroup { group_id: GroupId },
SetState { surface_id: SurfaceId, state: SurfaceState },
EventLog {
#[serde(default, skip_serializing_if = "Option::is_none")]
limit: Option<u32>,
},
MarkRead { target: MarkReadTarget },
Status,
Shutdown,
}
@@ -134,6 +140,8 @@ pub enum Evt {
GroupsChanged { groups: Vec<Group> },
SurfaceRestarted { surface_id: SurfaceId },
State { surface_id: SurfaceId, state: SurfaceState },
Event { record: EventRecord },
EventsRead { ids: Vec<u64> },
}
#[cfg(test)]
@@ -262,4 +270,77 @@ mod tests {
let back: Envelope = serde_json::from_str(&j).unwrap();
assert_eq!(back, evt);
}
#[test]
fn event_log_cmd_round_trips() {
let env = Envelope::Req { id: 1, cmd: Cmd::EventLog { limit: Some(50) } };
let j = serde_json::to_string(&env).unwrap();
assert!(j.contains(r#""cmd":"event_log""#));
let back: Envelope = serde_json::from_str(&j).unwrap();
assert_eq!(back, env);
}
#[test]
fn mark_read_cmd_round_trips() {
let env = Envelope::Req {
id: 2,
cmd: Cmd::MarkRead { target: crate::event::MarkReadTarget::All },
};
let j = serde_json::to_string(&env).unwrap();
assert!(j.contains(r#""cmd":"mark_read""#));
let back: Envelope = serde_json::from_str(&j).unwrap();
assert_eq!(back, env);
}
#[test]
fn event_evt_round_trips() {
let evt = Envelope::Evt(Evt::Event {
record: crate::event::EventRecord {
id: 3,
surface_id: SurfaceId("s_1".into()),
workspace_id: WorkspaceId("w_1".into()),
workspace_name: "p".into(),
agent_label: None,
kind: crate::event::EventKind::Done,
ts: 1,
read: false,
},
});
let j = serde_json::to_string(&evt).unwrap();
assert!(j.contains(r#""evt":"event""#));
let back: Envelope = serde_json::from_str(&j).unwrap();
assert_eq!(back, evt);
}
#[test]
fn events_read_evt_round_trips() {
let evt = Envelope::Evt(Evt::EventsRead { ids: vec![1, 2, 3] });
let j = serde_json::to_string(&evt).unwrap();
assert!(j.contains(r#""evt":"events_read""#));
let back: Envelope = serde_json::from_str(&j).unwrap();
assert_eq!(back, evt);
}
#[test]
fn event_log_cmd_no_limit_round_trips() {
let env = Envelope::Req { id: 9, cmd: Cmd::EventLog { limit: None } };
let j = serde_json::to_string(&env).unwrap();
assert!(j.contains(r#""cmd":"event_log""#));
assert!(j.contains(r#""args":{}"#), "no-limit serializes to empty args, got: {j}");
let back: Envelope = serde_json::from_str(&j).unwrap();
assert_eq!(back, env);
}
#[test]
fn mark_read_cmd_ids_and_surface_round_trip() {
let ids = Envelope::Req { id: 10, cmd: Cmd::MarkRead { target: crate::event::MarkReadTarget::Ids(vec![1, 2]) } };
let j = serde_json::to_string(&ids).unwrap();
assert!(j.contains(r#""target":"ids""#));
assert_eq!(serde_json::from_str::<Envelope>(&j).unwrap(), ids);
let surf = Envelope::Req { id: 11, cmd: Cmd::MarkRead { target: crate::event::MarkReadTarget::Surface(SurfaceId("s_3".into())) } };
let j = serde_json::to_string(&surf).unwrap();
assert!(j.contains(r#""target":"surface""#));
assert_eq!(serde_json::from_str::<Envelope>(&j).unwrap(), surf);
}
}