diff --git a/crates/app/cli/src/engine.rs b/crates/app/cli/src/engine.rs new file mode 100644 index 0000000..cc4ce8e --- /dev/null +++ b/crates/app/cli/src/engine.rs @@ -0,0 +1,39 @@ +use crate::messages::Message; +use tokio::sync::mpsc; + +/// The main background task that handles logic, API calls, and state updates. +pub async fn run_engine_loop(mut rx: mpsc::Receiver) { + while let Some(msg) = rx.recv().await { + match msg { + Message::UserAction(action) => { + println!("Engine received action: {:?}", action); + // TODO: Process action + } + _ => {} + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::messages::{Message, UserAction}; + + #[tokio::test] + async fn test_engine_loop_structure() { + let (tx, rx) = mpsc::channel(1); + + // Spawn the engine loop + let handle = tokio::spawn(async move { + run_engine_loop(rx).await; + }); + + // Send a message + let msg = Message::UserAction(UserAction::Input("ping".to_string())); + assert!(tx.send(msg).await.is_ok()); + + // Cleanup: dropping tx should close rx and terminate the loop + drop(tx); + assert!(handle.await.is_ok()); + } +} diff --git a/crates/app/cli/src/main.rs b/crates/app/cli/src/main.rs index 1ae67d9..c59c591 100644 --- a/crates/app/cli/src/main.rs +++ b/crates/app/cli/src/main.rs @@ -1,5 +1,6 @@ mod commands; mod messages; +mod engine; use clap::{Parser, ValueEnum}; use color_eyre::eyre::{Result, eyre}; @@ -333,6 +334,15 @@ async fn main() -> Result<()> { let session_id = generate_session_id(); let output_format = args.output_format; + // Initialize async engine infrastructure + let (tx, rx) = tokio::sync::mpsc::channel::(100); + // Spawn the Engine Loop + tokio::spawn(async move { + engine::run_engine_loop(rx).await; + }); + // Keep tx for future use (will be passed to UI/REPL) + let _tx = tx; + if let Some(cmd) = args.cmd { match cmd { Cmd::Read { path } => {