fix: GitHub Copilot auth fails to open browser in Desktop app (#6957) (#8019)

Signed-off-by: Douwe Osinga <douwe@squareup.com>
Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
jh-block
2026-03-26 19:03:44 +01:00
committed by GitHub
parent 2977512bb5
commit 11f46dc0e0
9 changed files with 147 additions and 7 deletions
+1
View File
@@ -69,6 +69,7 @@ rmcp = { workspace = true, features = [
"transport-streamable-http-client-reqwest",
] }
oauth2 = { version = "5.0", default-features = false }
arboard = { workspace = true }
anyhow = { workspace = true }
thiserror = { workspace = true }
futures = { workspace = true }
+31 -2
View File
@@ -266,9 +266,13 @@ pub struct ConfigKey {
pub secret: bool,
/// Optional default value for the key
pub default: Option<String>,
/// Whether this key should be configured using OAuth device code flow
/// Whether this key should be configured using an OAuth flow
/// When true, the provider's configure_oauth() method will be called instead of prompting for manual input
pub oauth_flow: bool,
/// Whether this OAuth flow uses the device code grant (RFC 8628)
/// When true, the user must enter a verification code in the browser
#[serde(default)]
pub device_code_flow: bool,
/// Whether this key should be shown prominently during provider setup
/// (onboarding, settings modal, CLI configure)
#[serde(default)]
@@ -290,6 +294,7 @@ impl ConfigKey {
secret,
default: default.map(|s| s.to_string()),
oauth_flow: false,
device_code_flow: false,
primary,
}
}
@@ -301,11 +306,12 @@ impl ConfigKey {
secret,
default: Some(T::DEFAULT.to_string()),
oauth_flow: false,
device_code_flow: false,
primary,
}
}
/// Create a new ConfigKey that uses OAuth device code flow for configuration
/// Create a new ConfigKey that uses an OAuth flow for configuration
///
/// This is used for providers that support OAuth authentication instead of manual API key entry.
/// When oauth_flow is true, the configuration system will call the provider's configure_oauth() method.
@@ -322,6 +328,29 @@ impl ConfigKey {
secret,
default: default.map(|s| s.to_string()),
oauth_flow: true,
device_code_flow: false,
primary,
}
}
/// Create a new ConfigKey that uses OAuth device code flow (RFC 8628) for configuration
///
/// Similar to new_oauth, but indicates the provider uses the device code grant where the user
/// must enter a verification code in the browser.
pub fn new_oauth_device_code(
name: &str,
required: bool,
secret: bool,
default: Option<&str>,
primary: bool,
) -> Self {
Self {
name: name.to_string(),
required,
secret,
default: default.map(|s| s.to_string()),
oauth_flow: true,
device_code_flow: true,
primary,
}
}
+11 -1
View File
@@ -285,6 +285,16 @@ impl GithubCopilotProvider {
async fn login(&self) -> Result<String> {
let device_code_info = self.get_device_code().await?;
if let Ok(mut clipboard) = arboard::Clipboard::new() {
if let Err(e) = clipboard.set_text(&device_code_info.user_code) {
tracing::warn!("Failed to copy verification code to clipboard: {}", e);
}
}
if let Err(e) = webbrowser::open(&device_code_info.verification_uri) {
tracing::warn!("Failed to open browser: {}", e);
}
println!(
"Please visit {} and enter code {}",
device_code_info.verification_uri, device_code_info.user_code
@@ -402,7 +412,7 @@ impl ProviderDef for GithubCopilotProvider {
GITHUB_COPILOT_DEFAULT_MODEL,
GITHUB_COPILOT_KNOWN_MODELS.to_vec(),
GITHUB_COPILOT_DOC_URL,
vec![ConfigKey::new_oauth(
vec![ConfigKey::new_oauth_device_code(
"GITHUB_COPILOT_TOKEN",
true,
true,