use crate::transport::SpawnOptions;
use crate::core::types::CliTool;
use std::io;
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum MessageClass {
AiResponse,
InfoMessage,
Error,
UiElement,
UserEcho,
ThinkingIndicator,
ToolApproval,
Menu,
PromptReady,
Raw,
}
#[derive(Debug, Clone, Default)]
pub struct MessageMetadata {
pub tool: CliTool,
pub turn: Option<u32>,
pub is_partial: bool,
pub tool_name: Option<String>,
pub elapsed_secs: Option<u32>,
}
impl MessageMetadata {
pub fn for_tool(tool: CliTool) -> Self {
Self {
tool,
turn: None,
is_partial: false,
tool_name: None,
elapsed_secs: None,
}
}
}
#[derive(Debug, Clone)]
pub struct ParsedMessage {
pub class: MessageClass,
pub content: String,
pub metadata: MessageMetadata,
}
pub trait OutputParser: Send {
fn feed(&mut self, data: &str);
fn parse(&mut self) -> Vec<ParsedMessage>;
fn extract_ai_text(&self, raw_cleaned: &str) -> String;
fn classify(&self, text: &str) -> MessageClass;
fn buffer(&self) -> &str;
fn clear(&mut self);
fn tool(&self) -> CliTool;
}
pub trait PromptSubmitter: Send {
fn send_prompt(&self, writer: &mut dyn io::Write, prompt: &str) -> io::Result<()>;
fn send_command(&self, writer: &mut dyn io::Write, command: &str) -> io::Result<()>;
fn send_control(&self, writer: &mut dyn io::Write, bytes: &[u8]) -> io::Result<()>;
fn handle_startup(&self, output: &str) -> StartupAction;
fn tool(&self) -> CliTool;
fn requires_char_by_char(&self) -> bool {
false }
}
#[derive(Debug, Clone)]
pub enum StartupAction {
Ready,
SendInput(String),
Waiting,
}
pub trait CliCommandBuilder {
fn build_command(&self, opts: &SpawnOptions) -> std::process::Command;
}