From 25d35529e7f16cea67e0cd66ff6d00d2d65fc666 Mon Sep 17 00:00:00 2001 From: "Dhanji R. Prasanna" Date: Thu, 15 Jan 2026 21:05:13 +0530 Subject: [PATCH] Fix --accept flag being passed through to g3 in studio run When --accept was passed after positional args (e.g., 'studio run --agent carmack task --accept'), clap's trailing_var_arg captured it as part of g3_args instead of parsing it as the studio flag. This caused g3 to error with 'unexpected argument --accept'. - Extract filter_accept_flag() helper to detect and remove --accept from trailing args - Set auto_accept=true if --accept found in either position - Add 5 unit tests for the filtering logic --- crates/studio/src/main.rs | 65 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/crates/studio/src/main.rs b/crates/studio/src/main.rs index 9ebcb8b..cbc6868 100644 --- a/crates/studio/src/main.rs +++ b/crates/studio/src/main.rs @@ -123,8 +123,24 @@ fn get_repo_root() -> Result { Ok(PathBuf::from(path)) } +/// Filter --accept from g3_args and return (filtered_args, was_accept_present) +/// This handles the case where --accept is passed after positional args, +/// which clap's trailing_var_arg captures instead of parsing as our flag. +fn filter_accept_flag(g3_args: &[String]) -> (Vec, bool) { + let accept_in_args = g3_args.iter().any(|arg| arg == "--accept"); + let filtered: Vec = g3_args + .iter() + .filter(|arg| *arg != "--accept") + .cloned() + .collect(); + (filtered, accept_in_args) +} + /// Run a new g3 session (foreground, tails output) fn cmd_run(agent: Option<&str>, auto_accept: bool, g3_args: &[String]) -> Result<()> { + let (g3_args, accept_in_args) = filter_accept_flag(g3_args); + let auto_accept = auto_accept || accept_in_args; + let g3_binary = get_g3_binary_path()?; let repo_root = get_repo_root()?; // Use "single" as the agent name for non-agent runs @@ -459,3 +475,52 @@ fn extract_session_summary(session: &Session) -> Option { None } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_filter_accept_flag_removes_accept() { + let args = vec!["task".to_string(), "--accept".to_string()]; + let (filtered, found) = filter_accept_flag(&args); + assert!(found); + assert_eq!(filtered, vec!["task".to_string()]); + } + + #[test] + fn test_filter_accept_flag_no_accept() { + let args = vec!["task".to_string(), "--verbose".to_string()]; + let (filtered, found) = filter_accept_flag(&args); + assert!(!found); + assert_eq!(filtered, vec!["task".to_string(), "--verbose".to_string()]); + } + + #[test] + fn test_filter_accept_flag_empty() { + let args: Vec = vec![]; + let (filtered, found) = filter_accept_flag(&args); + assert!(!found); + assert!(filtered.is_empty()); + } + + #[test] + fn test_filter_accept_flag_accept_in_middle() { + let args = vec![ + "task".to_string(), + "--accept".to_string(), + "--other".to_string(), + ]; + let (filtered, found) = filter_accept_flag(&args); + assert!(found); + assert_eq!(filtered, vec!["task".to_string(), "--other".to_string()]); + } + + #[test] + fn test_filter_accept_flag_only_accept() { + let args = vec!["--accept".to_string()]; + let (filtered, found) = filter_accept_flag(&args); + assert!(found); + assert!(filtered.is_empty()); + } +}