use anyhow::Result;
use shell_words::split as shell_split;
use vtcode_core::utils::ansi::{AnsiRenderer, MessageStyle};
use super::rendering::{render_loop_usage, render_mcp_usage, render_schedule_usage};
use super::{McpCommandAction, ScheduleCommandAction, SlashCommandOutcome};
pub(super) fn handle_mcp_command(
args: &str,
renderer: &mut AnsiRenderer,
) -> Result<SlashCommandOutcome> {
if args.is_empty() {
return Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::Interactive,
});
}
let tokens = match shell_split(args) {
Ok(tokens) => tokens,
Err(err) => {
renderer.line(
MessageStyle::Error,
&format!("Failed to parse arguments: {}", err),
)?;
return Ok(SlashCommandOutcome::Handled);
}
};
if tokens.is_empty() {
return Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::Interactive,
});
}
let subcommand = tokens[0].to_ascii_lowercase();
match subcommand.as_str() {
"status" | "overview" => Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::Overview,
}),
"list" | "providers" => Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::ListProviders,
}),
"tools" => Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::ListTools,
}),
"refresh" | "reload" => Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::RefreshTools,
}),
"config" => {
if tokens.len() > 1 {
let mode = tokens[1].to_ascii_lowercase();
match mode.as_str() {
"edit" | "--edit" => Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::EditConfig,
}),
"show" | "list" | "status" => Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::ShowConfig,
}),
other if other.starts_with("--") => {
if other == "--edit" {
Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::EditConfig,
})
} else {
render_mcp_usage(renderer)?;
Ok(SlashCommandOutcome::Handled)
}
}
_ => {
render_mcp_usage(renderer)?;
Ok(SlashCommandOutcome::Handled)
}
}
} else {
Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::ShowConfig,
})
}
}
"edit" => Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::EditConfig,
}),
"repair" | "fix" => Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::Repair,
}),
"diagnose" | "diagnostics" | "health" => Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::Diagnose,
}),
"login" => {
if tokens.len() < 2 {
render_mcp_usage(renderer)?;
return Ok(SlashCommandOutcome::Handled);
}
Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::Login(tokens[1].clone()),
})
}
"logout" => {
if tokens.len() < 2 {
render_mcp_usage(renderer)?;
return Ok(SlashCommandOutcome::Handled);
}
Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::Logout(tokens[1].clone()),
})
}
"help" | "--help" => {
render_mcp_usage(renderer)?;
Ok(SlashCommandOutcome::Handled)
}
other if other.starts_with("--") => {
if other == "--list" {
return Ok(SlashCommandOutcome::ManageMcp {
action: McpCommandAction::ListProviders,
});
}
render_mcp_usage(renderer)?;
Ok(SlashCommandOutcome::Handled)
}
_ => {
render_mcp_usage(renderer)?;
Ok(SlashCommandOutcome::Handled)
}
}
}
pub(super) fn handle_loop_command(
args: &str,
renderer: &mut AnsiRenderer,
) -> Result<SlashCommandOutcome> {
match vtcode_core::scheduler::parse_loop_command(args) {
Ok(command) => Ok(SlashCommandOutcome::ManageLoop { command }),
Err(err) => {
renderer.line(MessageStyle::Error, &err.to_string())?;
render_loop_usage(renderer)?;
Ok(SlashCommandOutcome::Handled)
}
}
}
pub(super) fn handle_schedule_command(
args: &str,
renderer: &mut AnsiRenderer,
) -> Result<SlashCommandOutcome> {
let trimmed = args.trim();
if trimmed.is_empty() {
return Ok(SlashCommandOutcome::ManageSchedule {
action: ScheduleCommandAction::Interactive,
});
}
let tokens = match shell_split(trimmed) {
Ok(tokens) => tokens,
Err(err) => {
renderer.line(
MessageStyle::Error,
&format!("Failed to parse arguments: {}", err),
)?;
render_schedule_usage(renderer)?;
return Ok(SlashCommandOutcome::Handled);
}
};
if tokens.is_empty() {
render_schedule_usage(renderer)?;
return Ok(SlashCommandOutcome::Handled);
}
match tokens[0].to_ascii_lowercase().as_str() {
"list" => Ok(SlashCommandOutcome::ManageSchedule {
action: ScheduleCommandAction::Browse,
}),
"delete" | "remove" | "cancel" => {
let Some(id) = tokens.get(1) else {
return Ok(SlashCommandOutcome::ManageSchedule {
action: ScheduleCommandAction::DeleteInteractive,
});
};
Ok(SlashCommandOutcome::ManageSchedule {
action: ScheduleCommandAction::Delete { id: id.clone() },
})
}
"create" if tokens.len() == 1 => Ok(SlashCommandOutcome::ManageSchedule {
action: ScheduleCommandAction::CreateInteractive,
}),
"create" => match vtcode_core::scheduler::parse_schedule_create_tokens(&tokens[1..]) {
Ok(input) => Ok(SlashCommandOutcome::ManageSchedule {
action: ScheduleCommandAction::Create { input },
}),
Err(err) => {
renderer.line(MessageStyle::Error, &err.to_string())?;
render_schedule_usage(renderer)?;
Ok(SlashCommandOutcome::Handled)
}
},
"help" | "--help" => {
render_schedule_usage(renderer)?;
Ok(SlashCommandOutcome::Handled)
}
_ => {
render_schedule_usage(renderer)?;
Ok(SlashCommandOutcome::Handled)
}
}
}