#[allow(dead_code)] pub(crate) struct SlashCtx<'a> {
pub session: &'a AgentSession,
pub state: &'a mut AppState,
pub ui_tx: &'a mpsc::UnboundedSender<UiEvent>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[allow(dead_code)] pub(crate) enum SlashOutcome {
Handled,
NotHandled,
Quit,
}
#[derive(Debug, Clone)]
#[allow(dead_code)] pub(crate) struct CompletionEntry {
pub display: String,
pub canonical: String,
pub description: String,
pub is_extension: bool,
}
mod builtin;
pub(crate) mod registry;
use super::app::{AppState, NotificationKind, UiEvent};
use crate::app::agent_session::AgentSession;
use tokio::sync::mpsc;
pub(crate) struct SlashCompletion {
pub name: String,
pub description: String,
pub is_arg: bool,
}
pub(crate) fn handle_slash_command(
input: &str,
session: &AgentSession,
state: &mut AppState,
running: &mut bool,
ui_tx: &mpsc::UnboundedSender<UiEvent>,
) -> bool {
let trimmed = input.trim();
let cmd = if let Some(space) = trimmed.find(' ') {
&trimmed[..space]
} else {
trimmed
};
{
let mut registry = registry::SlashRegistry::builtins();
registry.sync_extensions(state.wasm_ext.as_ref());
let mut ctx = SlashCtx {
session,
state,
ui_tx,
};
match registry.dispatch(input, &mut ctx) {
SlashOutcome::Handled => return true,
SlashOutcome::Quit => {
*running = false;
return true;
}
SlashOutcome::NotHandled => {} }
}
state.add_notification(
format!("Unknown command: {}", cmd),
NotificationKind::Warning,
);
false
}