move startup orchestration from mind to event_loop

The top-level run() that creates Mind, wires channels, spawns the
Mind event loop, and starts the UI event loop is orchestration —
it belongs with the UI entry point, not in the cognitive layer.

Renamed to event_loop::start(cli). mind/mod.rs is now purely the
Mind struct: state machine, MindCommand, and the run loop.

Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
Kent Overstreet 2026-04-05 04:29:56 -04:00
parent e449cda40f
commit 57b0f94b54
3 changed files with 38 additions and 40 deletions

View file

@ -18,6 +18,37 @@ use crate::user::ui_channel::{self, UiMessage};
pub use crate::mind::MindCommand;
/// Top-level entry point — creates Mind and UI, wires them together.
pub async fn start(cli: crate::user::CliArgs) -> Result<()> {
let (config, _figment) = crate::config::load_session(&cli)?;
if config.app.debug {
unsafe { std::env::set_var("POC_DEBUG", "1") };
}
let (ui_tx, ui_rx) = ui_channel::channel();
let (turn_tx, turn_rx) = tokio::sync::mpsc::channel(1);
let (mind_tx, mind_rx) = tokio::sync::mpsc::unbounded_channel();
let mut mind = crate::mind::Mind::new(config, ui_tx.clone(), turn_tx);
mind.init().await;
let ui_agent = mind.agent.clone();
let shared_mind = mind.shared.clone();
let shared_context = mind.agent.lock().await.shared_context.clone();
let shared_active_tools = mind.agent.lock().await.active_tools.clone();
let turn_watch = mind.turn_watch();
tokio::spawn(async move {
mind.run(mind_rx, turn_rx).await;
});
run(
tui::App::new(String::new(), shared_context, shared_active_tools),
ui_agent, shared_mind, turn_watch, mind_tx, ui_tx, ui_rx,
).await
}
fn send_help(ui_tx: &ui_channel::UiSender) {
let commands = &[
("/quit", "Exit consciousness"),

View file

@ -757,7 +757,7 @@ pub async fn main() {
return;
}
if let Err(e) = crate::mind::run(cli).await {
if let Err(e) = crate::user::event_loop::start(cli).await {
let _ = crossterm::terminal::disable_raw_mode();
let _ = crossterm::execute!(
std::io::stdout(),