storkit: merge 429_story_interactive_project_setup_wizard_for_new_storkit_projects
This commit is contained in:
@@ -2,6 +2,7 @@ use crate::http::context::{AppContext, PermissionDecision};
|
||||
use crate::http::workflow::{PipelineState, load_pipeline_state};
|
||||
use crate::io::onboarding;
|
||||
use crate::io::watcher::WatcherEvent;
|
||||
use crate::io::wizard;
|
||||
use crate::llm::chat;
|
||||
use crate::llm::types::Message;
|
||||
use crate::log_buffer;
|
||||
@@ -46,6 +47,16 @@ enum WsRequest {
|
||||
},
|
||||
}
|
||||
|
||||
/// Serialisable summary of a single wizard step for WebSocket broadcast.
|
||||
#[derive(Serialize, Clone)]
|
||||
pub struct WizardStepInfo {
|
||||
pub step: String,
|
||||
pub label: String,
|
||||
pub status: String,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub content: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
/// WebSocket response messages sent by the server.
|
||||
@@ -125,6 +136,13 @@ enum WsResponse {
|
||||
OnboardingStatus {
|
||||
needs_onboarding: bool,
|
||||
},
|
||||
/// Sent on connect when a setup wizard is active. Contains the full
|
||||
/// wizard state so the frontend can render the step-by-step UI.
|
||||
WizardState {
|
||||
steps: Vec<WizardStepInfo>,
|
||||
current_step_index: usize,
|
||||
completed: bool,
|
||||
},
|
||||
/// Streaming token from a `/btw` side question response.
|
||||
SideQuestionToken {
|
||||
content: String,
|
||||
@@ -219,6 +237,35 @@ pub async fn ws_handler(ws: WebSocket, ctx: Data<&Arc<AppContext>>) -> impl poem
|
||||
});
|
||||
}
|
||||
|
||||
// Push wizard state if an active wizard exists.
|
||||
{
|
||||
if let Ok(root) = ctx.state.get_project_root()
|
||||
&& let Some(ws) = wizard::WizardState::load(&root)
|
||||
{
|
||||
let steps: Vec<WizardStepInfo> = ws
|
||||
.steps
|
||||
.iter()
|
||||
.map(|s| WizardStepInfo {
|
||||
step: serde_json::to_value(s.step)
|
||||
.ok()
|
||||
.and_then(|v| v.as_str().map(String::from))
|
||||
.unwrap_or_default(),
|
||||
label: s.step.label().to_string(),
|
||||
status: serde_json::to_value(&s.status)
|
||||
.ok()
|
||||
.and_then(|v| v.as_str().map(String::from))
|
||||
.unwrap_or_default(),
|
||||
content: s.content.clone(),
|
||||
})
|
||||
.collect();
|
||||
let _ = tx.send(WsResponse::WizardState {
|
||||
steps,
|
||||
current_step_index: ws.current_step_index(),
|
||||
completed: ws.completed,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Push recent server log entries so the client has history on connect.
|
||||
{
|
||||
let entries = log_buffer::global().get_recent_entries(100, None, None);
|
||||
|
||||
Reference in New Issue
Block a user