use std::process::Command; /// Run one dream cycle pub fn run_dream() { let memory_path = "memory/memory.md"; // 1. Check if memory is worth dreaming about let memory = std::fs::read_to_string(memory_path).unwrap_or_default(); let line_count = memory.lines().count(); if line_count < 50 { eprintln!("memory too short ({} lines), skipping dream", line_count); return; } // 2. Stop worker to prevent file races let agent_name = std::env::var("COLONY_AGENT").unwrap_or_else(|_| "agent".into()); let worker_service = format!("agent-{}-worker", agent_name); let _ = Command::new("systemctl").args(["stop", &worker_service]).status(); // 3. Announce dream let _ = Command::new("colony") .args(["post", "general", "💤 dreaming... back in a few minutes", "--type", "plan", "--quiet"]) .status(); // 4. Invoke Claude for dream cycle eprintln!("dreaming... ({} lines of memory)", line_count); let prompt = format!( "Dream cycle. Read memory/memory.md ({} lines). \ Consolidate into themes and insights. \ Write a dream summary to memory/dreams/ with today's date. \ Prune memory/memory.md to the last 100 entries. \ If you've learned something about yourself, update your CLAUDE.md \ and add a line to the evolution log section.", line_count ); let dream_ok = match Command::new("claude") .args([ "--dangerously-skip-permissions", "-p", &prompt, "--max-turns", "10", ]) .status() { Ok(s) if s.success() => { eprintln!("dream completed"); true } Ok(s) => { eprintln!("dream exited with status: {}", s); false } Err(e) => { eprintln!("failed to run claude for dream: {}", e); false } }; // 5. Restart worker let _ = Command::new("systemctl").args(["start", &worker_service]).status(); // 6. Announce return if dream_ok { let _ = Command::new("colony") .args(["post", "general", "👁 back from dreaming", "--type", "plan", "--quiet"]) .status(); } else { let _ = Command::new("colony") .args(["post", "general", "⚠ dream failed, back online", "--type", "error", "--quiet"]) .status(); } }