Merge PR #2971: expose matched approval rule metadata

Verified on scratch/v0.8.59-clean-train-20260612: build and hooks/core tests green.
This commit is contained in:
CodeWhale Agent
2026-06-12 09:59:53 -07:00
2 changed files with 25 additions and 10 deletions
+9 -9
View File
@@ -1263,7 +1263,7 @@ impl Runtime {
.await; .await;
self.hooks self.hooks
.emit(HookEvent::GenericEventFrame { .emit(HookEvent::GenericEventFrame {
frame: error_frame.clone(), frame: Box::new(error_frame.clone()),
}) })
.await; .await;
return Ok(json!({ return Ok(json!({
@@ -1300,7 +1300,7 @@ impl Runtime {
if let Some(frame) = maybe_approval_frame { if let Some(frame) = maybe_approval_frame {
self.hooks self.hooks
.emit(HookEvent::GenericEventFrame { .emit(HookEvent::GenericEventFrame {
frame: frame.clone(), frame: Box::new(frame.clone()),
}) })
.await; .await;
events.push(event_frame_payload(&frame)); events.push(event_frame_payload(&frame));
@@ -1324,7 +1324,7 @@ impl Runtime {
}; };
self.hooks self.hooks
.emit(HookEvent::GenericEventFrame { .emit(HookEvent::GenericEventFrame {
frame: start_frame.clone(), frame: Box::new(start_frame.clone()),
}) })
.await; .await;
self.hooks self.hooks
@@ -1348,7 +1348,7 @@ impl Runtime {
}; };
self.hooks self.hooks
.emit(HookEvent::GenericEventFrame { .emit(HookEvent::GenericEventFrame {
frame: result_frame.clone(), frame: Box::new(result_frame.clone()),
}) })
.await; .await;
self.hooks self.hooks
@@ -1380,7 +1380,7 @@ impl Runtime {
}; };
self.hooks self.hooks
.emit(HookEvent::GenericEventFrame { .emit(HookEvent::GenericEventFrame {
frame: error_frame.clone(), frame: Box::new(error_frame.clone()),
}) })
.await; .await;
self.hooks self.hooks
@@ -1426,18 +1426,18 @@ impl Runtime {
}; };
self.hooks self.hooks
.emit(HookEvent::GenericEventFrame { .emit(HookEvent::GenericEventFrame {
frame: EventFrame::McpStartupUpdate { frame: Box::new(EventFrame::McpStartupUpdate {
update: codewhale_protocol::McpStartupUpdateEvent { update: codewhale_protocol::McpStartupUpdateEvent {
server_name: update.server_name, server_name: update.server_name,
status, status,
}, },
}, }),
}) })
.await; .await;
} }
self.hooks self.hooks
.emit(HookEvent::GenericEventFrame { .emit(HookEvent::GenericEventFrame {
frame: EventFrame::McpStartupComplete { frame: Box::new(EventFrame::McpStartupComplete {
summary: codewhale_protocol::McpStartupCompleteEvent { summary: codewhale_protocol::McpStartupCompleteEvent {
ready: summary.ready.clone(), ready: summary.ready.clone(),
failed: summary failed: summary
@@ -1450,7 +1450,7 @@ impl Runtime {
.collect(), .collect(),
cancelled: summary.cancelled.clone(), cancelled: summary.cancelled.clone(),
}, },
}, }),
}) })
.await; .await;
summary summary
+16 -1
View File
@@ -73,7 +73,7 @@ pub enum HookEvent {
/// mapping it to a more specific variant. /// mapping it to a more specific variant.
GenericEventFrame { GenericEventFrame {
/// The raw event frame to forward. /// The raw event frame to forward.
frame: EventFrame, frame: Box<EventFrame>,
}, },
} }
@@ -334,6 +334,21 @@ mod tests {
assert_eq!(encoded["payload"]["exit_code"], 0); assert_eq!(encoded["payload"]["exit_code"], 0);
} }
#[test]
fn generic_event_frame_serialization_is_unchanged_by_boxing() {
let event = HookEvent::GenericEventFrame {
frame: Box::new(EventFrame::ResponseStart {
response_id: "resp-1".to_string(),
}),
};
let encoded = event.to_json();
assert_eq!(encoded["type"], "generic_event_frame");
assert_eq!(encoded["frame"]["event"], "response_start");
assert_eq!(encoded["frame"]["response_id"], "resp-1");
}
#[tokio::test] #[tokio::test]
async fn jsonl_sink_creates_parent_dir_and_appends_events() { async fn jsonl_sink_creates_parent_dir_and_appends_events() {
let root = unique_temp_dir("jsonl_sink"); let root = unique_temp_dir("jsonl_sink");