Concepts
Wizard
Session-based wizard framework for guided onboarding and configuration flows.
The wizard module provides a session-based wizard framework for onboarding and configuration flows. It guides users through multi-step setup processes with deferred promises and stateful sessions.
Design Philosophy
- Session-based state machine — Wizard progress is persisted across interactions
- Deferred promises — Each step can collect data without blocking the overall flow
- Channel-agnostic — Works via CLI, RPC, or any interface
Architecture
Client WizardSession WizardFlow
│ │ │
│── wizard.start ──────────────▶│ │
│ │── run(prompter) ──────────────▶│
│◀── { step: intro } ───────────│◀── prompt(intro) ──────────────│
│ │ │
│── wizard.next { null } ──────▶│ │
│◀── { step: select } ──────────│◀── prompt(select) ─────────────│
│ │ │
│── wizard.next { "local" } ───▶│ │
│ │── answer("local") ────────────▶│
│◀── { step: text } ────────────│◀── prompt(text) ───────────────│
│ │ │
│── wizard.cancel ─────────────▶│ │
│◀── { done: true } ────────────│ │Core Components
WizardSession
Manages the wizard lifecycle:
pub struct WizardSession {
flow: Box<dyn WizardFlow>,
state: WizardState,
}
impl WizardSession {
pub async fn start(
&mut self,
) -> Result<WizardStep> { /* ... */ }
pub async fn next(
&mut self,
answer: Option<String>,
) -> Result<WizardNextResult> { /* ... */ }
pub fn cancel(&mut self,
) -> WizardStatus { /* ... */ }
}WizardFlow
Defines the sequence of steps:
pub trait WizardFlow: Send + Sync {
async fn run(
&self,
prompter: &dyn WizardPrompter,
) -> Result<()>;
}WizardPrompter
Abstracts user interaction:
pub trait WizardPrompter: Send + Sync {
fn intro(&self, title: &str, description: &str) -> ProgressHandle;
fn text(&self, prompt: &str) -> Result<String>;
fn select(&self, prompt: &str, options: &[WizardOption]) -> Result<String>;
fn confirm(&self, prompt: &str) -> Result<bool>;
}Implementations:
CliPrompter— Command-line prompts (stub, TODO: integrate dialoguer)RpcPrompter— JSON-RPC based prompts for remote clients
WizardStep
pub struct WizardStep {
pub step_type: StepType,
pub prompt: String,
pub options: Vec<WizardOption>,
}
pub enum StepType {
Intro,
Text,
Select,
Confirm,
Complete,
}Onboarding Flow
Built-in wizard for initial setup:
pub struct QuickSetupFlow;
pub struct ProviderSetupFlow;Collects:
- AI provider selection (OpenAI, Anthropic, etc.)
- API key configuration
- Messaging app preferences
- Thinking level preference
Safety Properties
- Atomic counter —
AtomicU64for step counting (no lock overhead) - Lock recovery —
unwrap_or_else(|e| e.into_inner())for RwLock - Dynamic width — Box width calculated from title length
- No unwrap in production — All user paths return
Result
Code Location
src/wizard/mod.rs— Module entry pointsrc/wizard/session.rs—WizardSessionandWizardFlowtraitsrc/wizard/prompter.rs— Prompter trait and implementationssrc/wizard/types.rs— Step types and optionssrc/wizard/flows/— Built-in flows (onboarding, provider setup)
See Also
- Configuration — Configuration system
- Installation — Initial setup