use super::OnboardingStep;
pub const SETUP_COMMANDS: &[(&str, OnboardingStep)] = &[
("/models", OnboardingStep::ProviderAuth),
("/workspace", OnboardingStep::Workspace),
("/channels", OnboardingStep::Channels),
("/voice", OnboardingStep::VoiceSetup),
("/image", OnboardingStep::ImageSetup),
("/daemon", OnboardingStep::Daemon),
("/brain", OnboardingStep::BrainSetup),
("/doctor", OnboardingStep::HealthCheck),
];
pub const LEGACY_ONBOARD_SUBCOMMANDS: &[(&str, OnboardingStep)] = &[
("provider", OnboardingStep::ProviderAuth),
("workspace", OnboardingStep::Workspace),
("channels", OnboardingStep::Channels),
("voice", OnboardingStep::VoiceSetup),
("image", OnboardingStep::ImageSetup),
("daemon", OnboardingStep::Daemon),
("brain", OnboardingStep::BrainSetup),
];
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum DeepLink {
FullWizard,
Step(OnboardingStep),
Unknown(String),
}
pub fn is_setup_command(command: &str) -> bool {
SETUP_COMMANDS.iter().any(|(name, _)| *name == command)
}
pub fn resolve<'a>(command: &str, input: &'a str) -> (DeepLink, &'a str) {
if let Some((_, step)) = SETUP_COMMANDS.iter().find(|(name, _)| *name == command) {
let arg = if *step == OnboardingStep::Channels {
input.split_whitespace().nth(1).unwrap_or("")
} else {
""
};
return (DeepLink::Step(*step), arg);
}
let suffix: &'a str = input
.strip_prefix("/onboard")
.unwrap_or("")
.trim_start_matches(':');
let mut parts = suffix.split_whitespace();
let head = parts.next().unwrap_or("");
let arg = parts.next().unwrap_or("");
if head.is_empty() {
return (DeepLink::FullWizard, "");
}
match LEGACY_ONBOARD_SUBCOMMANDS
.iter()
.find(|(name, _)| *name == head)
{
Some((_, step)) => (DeepLink::Step(*step), arg),
None => (DeepLink::Unknown(head.to_string()), ""),
}
}
pub fn unknown_suffix_message(suffix: &str) -> String {
let valid = SETUP_COMMANDS
.iter()
.map(|(name, _)| format!("`{name}`"))
.collect::<Vec<_>>()
.join(", ");
format!(
"⚠️ Unknown setup step `{suffix}`. Setup commands: {valid}. \
Bare `/onboard` runs the full wizard."
)
}