story-kit: merge 117_story_show_startup_reconciliation_progress_in_ui

This commit is contained in:
Dave
2026-02-23 22:50:57 +00:00
parent e3d9813707
commit 85fddcb71a
7 changed files with 341 additions and 8 deletions

View File

@@ -79,6 +79,14 @@ enum WsResponse {
ToolActivity {
tool_name: String,
},
/// Real-time progress from the server startup reconciliation pass.
/// `status` is one of: "checking", "gates_running", "advanced", "skipped",
/// "failed", "done". `story_id` is empty for the overall "done" event.
ReconciliationProgress {
story_id: String,
status: String,
message: String,
},
}
impl From<WatcherEvent> for WsResponse {
@@ -155,6 +163,30 @@ pub async fn ws_handler(ws: WebSocket, ctx: Data<&Arc<AppContext>>) -> impl poem
}
});
// Subscribe to startup reconciliation events and forward them to the client.
let tx_reconcile = tx.clone();
let mut reconcile_rx = ctx.reconciliation_tx.subscribe();
tokio::spawn(async move {
loop {
match reconcile_rx.recv().await {
Ok(evt) => {
if tx_reconcile
.send(WsResponse::ReconciliationProgress {
story_id: evt.story_id,
status: evt.status,
message: evt.message,
})
.is_err()
{
break;
}
}
Err(tokio::sync::broadcast::error::RecvError::Lagged(_)) => continue,
Err(tokio::sync::broadcast::error::RecvError::Closed) => break,
}
}
});
// Map of pending permission request_id → oneshot responder.
// Permission requests arrive from the MCP `prompt_permission` tool via
// `ctx.perm_rx` and are forwarded to the client as `PermissionRequest`.