use crate::*; use std::error::Error; use std::io::Write; use std::thread; pub fn get_user_input(prompt: &str) -> Result> { println!("{}", prompt); let mut response = String::new(); std::io::stdin().read_line(&mut response)?; return Ok(response.trim().to_string()); } pub fn cli(mut state: AppState, main_rx: Receiver) { println!("Starting tetanus CLI..."); let (input_tx, input_rx) = channel::(); thread::spawn(move || { let stdin = io::stdin(); let mut input_buffer = String::new(); loop { input_buffer.clear(); if stdin.read_line(&mut input_buffer).is_ok() { let trimmed = input_buffer.trim().to_string(); if !trimmed.is_empty() { if input_tx.send(trimmed).is_err() { break; } } } } }); print!("tetanus> "); let _ = io::stdout().flush(); loop { while let Ok(msg) = main_rx.try_recv() { match msg { ToolMessage::Output(txt) => { println!("\n[result] {}", txt); state.log.push(txt.clone()); state.output.push(txt.clone()); } _ => {} } } while let Ok(user_input) = input_rx.try_recv() { state.curent_intput = user_input.clone(); state.history.push(user_input.clone()); match user_input.as_str() { "exit" | "quit" => { println!("shutting down..."); return; } "reload-modules" => { println!("reloadling modules..."); state.initialize_modules(); } "help" => { println!("\nAvailable Built-In & Custom Script Modules:"); for (name, cmd) in &state.module_loader.commands { println!(" - {:<15} (Outputs: {})", name, cmd.output_type); if !cmd.help.is_empty() { println!(" Help: {}", cmd.help.trim()); } } println!(); } // Everything else gets dynamically routed to your Rhai engine execution matrix! command_name => { if state.module_loader.commands.contains_key(command_name) { println!( "[Worker] Dispatching script '{}' to Rayon engine layer...", command_name ); if let Err(e) = state.execute_command(command_name, None) { eprintln!("[Error] Failed running script: {}", e); } } else { println!("[Error] Command '{}' unrecognized.", command_name); } } } print!("tetanus> "); let _ = io::stdout().flush(); } } }