diff --git a/crates/agent_ui/src/acp/thread_view.rs b/crates/agent_ui/src/acp/thread_view.rs index 80b2fc649706ee90cab2c8464c82266fc9faa698..1f2feccb46e6684602affbd9716458f94de57f3c 100644 --- a/crates/agent_ui/src/acp/thread_view.rs +++ b/crates/agent_ui/src/acp/thread_view.rs @@ -2165,7 +2165,13 @@ impl AcpThreadView { if let Some(workspace) = self.workspace.upgrade() { let project = self.project.clone(); let authenticate = Self::spawn_external_agent_login( - login, workspace, project, false, true, window, cx, + login, + workspace, + project, + method.clone(), + false, + window, + cx, ); cx.notify(); self.auth_task = Some(cx.spawn_in(window, { @@ -2266,14 +2272,17 @@ impl AcpThreadView { self.thread_error.take(); configuration_view.take(); pending_auth_method.replace(method.clone()); - let authenticate = if (method.0.as_ref() == "claude-login" - || method.0.as_ref() == "spawn-gemini-cli") - && let Some(login) = self.login.clone() - { + let authenticate = if let Some(login) = self.login.clone() { if let Some(workspace) = self.workspace.upgrade() { let project = self.project.clone(); Self::spawn_external_agent_login( - login, workspace, project, false, false, window, cx, + login, + workspace, + project, + method.clone(), + false, + window, + cx, ) } else { Task::ready(Ok(())) @@ -2320,8 +2329,8 @@ impl AcpThreadView { login: task::SpawnInTerminal, workspace: Entity, project: Entity, + method: acp::AuthMethodId, previous_attempt: bool, - check_exit_code: bool, window: &mut Window, cx: &mut App, ) -> Task> { @@ -2371,25 +2380,29 @@ impl AcpThreadView { })? .await?; - if check_exit_code { - // For extension-based auth, wait for the process to exit and check exit code + let success_patterns = match method.0.as_ref() { + "claude-login" | "spawn-gemini-cli" => vec![ + "Login successful".to_string(), + "Type your message".to_string(), + ], + _ => Vec::new(), + }; + if success_patterns.is_empty() { + // No success patterns specified: wait for the process to exit and check exit code let exit_status = terminal .read_with(cx, |terminal, cx| terminal.wait_for_completed_task(cx))? .await; match exit_status { - Some(status) if status.success() => { - Ok(()) - } - Some(status) => { - Err(anyhow!("Login command failed with exit code: {:?}", status.code())) - } - None => { - Err(anyhow!("Login command terminated without exit status")) - } + Some(status) if status.success() => Ok(()), + Some(status) => Err(anyhow!( + "Login command failed with exit code: {:?}", + status.code() + )), + None => Err(anyhow!("Login command terminated without exit status")), } } else { - // For hardcoded agents (claude-login, gemini-cli): look for specific output + // Look for specific output patterns to detect successful login let mut exit_status = terminal .read_with(cx, |terminal, cx| terminal.wait_for_completed_task(cx))? .fuse(); @@ -2402,8 +2415,7 @@ impl AcpThreadView { cx.background_executor().timer(Duration::from_secs(1)).await; let content = terminal.update(cx, |terminal, _cx| terminal.get_content())?; - if content.contains("Login successful") - || content.contains("Type your message") + if success_patterns.iter().any(|pattern| content.contains(pattern)) { return anyhow::Ok(()); } @@ -2421,7 +2433,7 @@ impl AcpThreadView { } _ = exit_status => { if !previous_attempt && project.read_with(cx, |project, _| project.is_via_remote_server()) && login.label.contains("gemini") { - return cx.update(|window, cx| Self::spawn_external_agent_login(login, workspace, project.clone(), true, false, window, cx))?.await + return cx.update(|window, cx| Self::spawn_external_agent_login(login, workspace, project.clone(), method, true, window, cx))?.await } return Err(anyhow!("exited before logging in")); }