diff --git a/crates/g3-cli/src/lib.rs b/crates/g3-cli/src/lib.rs index 1ca997d..4730a3e 100644 --- a/crates/g3-cli/src/lib.rs +++ b/crates/g3-cli/src/lib.rs @@ -94,6 +94,10 @@ pub struct Cli { #[arg(long, default_value = "5")] pub max_turns: usize, + /// Override requirements text for autonomous mode (instead of reading from requirements.md) + #[arg(long, value_name = "TEXT")] + pub requirements: Option, + /// Use retro terminal UI (inspired by 80s sci-fi) #[arg(long)] pub retro: bool, @@ -174,7 +178,13 @@ pub async fn run() -> Result<()> { // Create project model let project = if cli.autonomous { - Project::new_autonomous(workspace_dir.clone())? + if let Some(requirements_text) = cli.requirements { + // Use requirements text override + Project::new_autonomous_with_requirements(workspace_dir.clone(), requirements_text)? + } else { + // Use traditional requirements.md file + Project::new_autonomous(workspace_dir.clone())? + } } else { Project::new(workspace_dir.clone()) }; @@ -933,11 +943,12 @@ async fn run_autonomous( // Check if requirements exist if !project.has_requirements() { output.print("❌ Error: requirements.md not found in workspace directory"); - output.print(" Please create a requirements.md file with your project requirements at:"); - output.print(&format!( - " {}/requirements.md", - project.workspace().display() - )); + output.print(" Please either:"); + output.print(" 1. Create a requirements.md file with your project requirements at:"); + output.print(&format!(" {}/requirements.md", project.workspace().display())); + output.print(" 2. Or use the --requirements flag to provide requirements text directly:"); + output.print(" g3 --autonomous --requirements \"Your requirements here\""); + output.print(""); // Generate final report even for early exit let elapsed = start_time.elapsed(); @@ -977,7 +988,7 @@ async fn run_autonomous( let requirements = match project.read_requirements()? { Some(content) => content, None => { - output.print("❌ Error: Could not read requirements.md"); + output.print("❌ Error: Could not read requirements (neither --requirements flag nor requirements.md file provided)"); // Generate final report even for early exit let elapsed = start_time.elapsed(); @@ -1014,7 +1025,12 @@ async fn run_autonomous( } }; - output.print("📋 Requirements loaded from requirements.md"); + // Display appropriate message based on requirements source + if project.requirements_text.is_some() { + output.print("📋 Requirements loaded from --requirements flag"); + } else { + output.print("📋 Requirements loaded from requirements.md"); + } output.print("🔄 Starting coach-player feedback loop..."); // Check if implementation files already exist diff --git a/crates/g3-core/src/project.rs b/crates/g3-core/src/project.rs index 242b8ce..5028455 100644 --- a/crates/g3-core/src/project.rs +++ b/crates/g3-core/src/project.rs @@ -11,6 +11,9 @@ pub struct Project { /// Path to the requirements document (for autonomous mode) pub requirements_path: Option, + /// Override requirements text (takes precedence over requirements_path) + pub requirements_text: Option, + /// Whether the project is in autonomous mode pub autonomous: bool, @@ -33,6 +36,7 @@ impl Project { Self { workspace_dir, requirements_path: None, + requirements_text: None, autonomous: false, name, session_id: None, @@ -53,6 +57,18 @@ impl Project { Ok(project) } + /// Create a project for autonomous mode with requirements text override + pub fn new_autonomous_with_requirements(workspace_dir: PathBuf, requirements_text: String) -> Result { + let mut project = Self::new(workspace_dir.clone()); + project.autonomous = true; + project.requirements_text = Some(requirements_text); + + // Don't look for requirements.md file when text is provided + // The text override takes precedence + + Ok(project) + } + /// Set the workspace directory and update related paths pub fn set_workspace(&mut self, workspace_dir: PathBuf) { self.workspace_dir = workspace_dir.clone(); @@ -78,7 +94,8 @@ impl Project { /// Check if requirements file exists pub fn has_requirements(&self) -> bool { - self.requirements_path.is_some() + // Has requirements if either text override is provided or requirements file exists + self.requirements_text.is_some() || self.requirements_path.is_some() } /// Check if implementation files exist in the workspace @@ -125,7 +142,11 @@ impl Project { /// Read the requirements file content pub fn read_requirements(&self) -> Result> { - if let Some(ref path) = self.requirements_path { + // Prioritize requirements text override + if let Some(ref text) = self.requirements_text { + Ok(Some(text.clone())) + } else if let Some(ref path) = self.requirements_path { + // Fall back to reading from file Ok(Some(std::fs::read_to_string(path)?)) } else { Ok(None)