feat: add visible pod discovery tools

This commit is contained in:
2026-05-23 12:04:45 +09:00
parent cfb5fa89f1
commit fd1b06198e
11 changed files with 1229 additions and 14 deletions
+81
View File
@@ -43,6 +43,18 @@ pub enum Method {
kind: CompletionKind,
prefix: String,
},
/// List Pods visible to this Pod from durable Pod state. This is not a
/// host-wide Pod universe query.
ListVisiblePods,
/// Inspect one Pod by name if its state exists and it is visible to this Pod.
InspectPod {
name: String,
},
/// Attach to a visible live Pod, or restore it from durable Pod state when
/// it is not live. Missing state and not-visible state are distinct errors.
AttachOrRestorePod {
name: String,
},
}
/// Typed lifecycle events sent from a child Pod to its parent.
@@ -393,6 +405,20 @@ pub enum Event {
kind: CompletionKind,
entries: Vec<CompletionEntry>,
},
/// Reply to `Method::ListVisiblePods`. Payload is a stable JSON value so
/// the Pod crate can evolve discovery fields without introducing a protocol
/// dependency on session-store.
VisiblePods {
pods: serde_json::Value,
},
/// Reply to `Method::InspectPod`.
PodInspection {
pod: serde_json::Value,
},
/// Reply to `Method::AttachOrRestorePod`.
PodAttachRestore {
result: serde_json::Value,
},
Alert(Alert),
/// Pod has started compacting the current session.
///
@@ -1215,4 +1241,59 @@ mod tests {
other => panic!("expected UserMessage, got {other:?}"),
}
}
#[test]
fn pod_discovery_methods_roundtrip() {
let methods = [
Method::ListVisiblePods,
Method::InspectPod {
name: "child".into(),
},
Method::AttachOrRestorePod {
name: "child".into(),
},
];
for method in methods {
let json = serde_json::to_string(&method).unwrap();
let decoded: Method = serde_json::from_str(&json).unwrap();
match (decoded, method) {
(Method::ListVisiblePods, Method::ListVisiblePods)
| (Method::InspectPod { .. }, Method::InspectPod { .. })
| (Method::AttachOrRestorePod { .. }, Method::AttachOrRestorePod { .. }) => {}
(decoded, expected) => panic!("decoded {decoded:?}, expected {expected:?}"),
}
}
}
#[test]
fn pod_discovery_events_roundtrip() {
let events = [
Event::VisiblePods {
pods: serde_json::json!([{ "pod_name": "child" }]),
},
Event::PodInspection {
pod: serde_json::json!({ "pod_name": "child" }),
},
Event::PodAttachRestore {
result: serde_json::json!({ "action": "attach" }),
},
];
for event in events {
let json = serde_json::to_string(&event).unwrap();
let decoded: Event = serde_json::from_str(&json).unwrap();
match (decoded, event) {
(Event::VisiblePods { pods }, Event::VisiblePods { pods: expected }) => {
assert_eq!(pods, expected)
}
(Event::PodInspection { pod }, Event::PodInspection { pod: expected }) => {
assert_eq!(pod, expected)
}
(
Event::PodAttachRestore { result },
Event::PodAttachRestore { result: expected },
) => assert_eq!(result, expected),
(decoded, expected) => panic!("decoded {decoded:?}, expected {expected:?}"),
}
}
}
}