use std::path::Path; /// cwd, platform, date, best-effort git status. Kept as its own block (not merged into the /// agent prompt) because Anthropic cache breakpoints need the system prompt structured as /// separate blocks (see `LlmRequest.system: Vec`). pub fn env_header(cwd: &Path) -> String { let git_status = std::process::Command::new("git") .arg("status") .arg("--short") .current_dir(cwd) .output() .ok() .filter(|o| o.status.success()) .map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string()) .filter(|s| !s.is_empty()); let mut header = format!( "Working directory: {}\nPlatform: {}\n", cwd.display(), std::env::consts::OS ); if let Some(status) = git_status { header.push_str(&format!("Git status:\n{status}\n")); } header } /// Ordered system prompt blocks: environment header, agent prompt, then project /// instructions (e.g. AGENTS.md contents). Order matches `02-engine.md`. pub fn assemble(env_header: String, agent_prompt: &str, instructions: &[String]) -> Vec { let mut blocks = vec![env_header, agent_prompt.to_string()]; blocks.extend(instructions.iter().cloned()); blocks } #[cfg(test)] mod tests { use super::*; #[test] fn env_header_includes_cwd_and_platform() { let header = env_header(Path::new(".")); assert!(header.contains("Working directory:")); assert!(header.contains(std::env::consts::OS)); } #[test] fn assemble_orders_env_agent_then_instructions() { let blocks = assemble( "ENV".to_string(), "AGENT", &["AGENTS.md contents".to_string()], ); assert_eq!(blocks, vec!["ENV", "AGENT", "AGENTS.md contents"]); } }