Skip to content
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/goose/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ rmcp = { workspace = true, features = [
"transport-streamable-http-client",
"transport-streamable-http-client-reqwest",
] }
oauth2 = "5.0"
anyhow = { workspace = true }
thiserror = { workspace = true }
futures = { workspace = true }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,9 @@ mod tests {
let path1 = save_full_output("first", "test_reuse", dir.path()).unwrap();
let path2 = save_full_output("second", "test_reuse", dir.path()).unwrap();
assert_eq!(path1, path2);
assert_eq!(std::fs::read_to_string(&path2).unwrap(), "second");
// Note: we intentionally don't assert file content here because
// parallel tests (render_output_truncates_*) share the same static
// temp file and can overwrite the content between our write and read.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, this appears to be a flaky test. Looks like removing this assert loses very little actual test usefulness, so this seems fine to me

}

#[test]
Expand Down
16 changes: 14 additions & 2 deletions crates/goose/src/oauth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use axum::response::Html;
use axum::routing::get;
use axum::Router;
use minijinja::render;
use oauth2::TokenResponse;
use rmcp::transport::auth::{CredentialStore, OAuthState, StoredCredentials};
use rmcp::transport::AuthorizationManager;
use serde::Deserialize;
Expand Down Expand Up @@ -101,12 +102,23 @@ pub async fn oauth_flow(
.into_authorization_manager()
.ok_or_else(|| anyhow::anyhow!("Failed to get authorization manager"))?;

let granted_scopes: Vec<String> = token_response
.as_ref()
.and_then(|tr| tr.scopes())
.map(|scopes| scopes.iter().map(|s| s.to_string()).collect())
.unwrap_or_default();

credential_store
.save(StoredCredentials {
client_id,
token_response,
granted_scopes: vec![],
token_received_at: None,
granted_scopes,
token_received_at: Some(
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|duration| duration.as_secs())
.unwrap_or(0),
),
})
.await?;

Expand Down
5 changes: 2 additions & 3 deletions ui/desktop/src/__tests__/sessions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ describe('session reuse scoping (fix for #7601)', () => {

const allSessions = [emptySessionA, emptySessionB, usedSession];

it('window A only reuses its own active empty session, not window B\'s', () => {
it("window A only reuses its own active empty session, not window B's", () => {
// Window A has emptySessionA active, Window B has emptySessionB active.
// Under the old logic, both would grab emptySessionA (the first in the list).
const windowAResult = findReusableSession(allSessions, 'empty-a');
Expand Down Expand Up @@ -95,8 +95,7 @@ describe('session reuse scoping (fix for #7601)', () => {

it('demonstrates the old bug: global find would give same session to both windows', () => {
// Old logic (before fix) - both windows get the same session.
const oldLogicFind = (sessions: Session[]) =>
sessions.find((s) => shouldShowNewChatTitle(s));
const oldLogicFind = (sessions: Session[]) => sessions.find((s) => shouldShowNewChatTitle(s));

const windowAOld = oldLogicFind(allSessions);
const windowBOld = oldLogicFind(allSessions);
Expand Down
1 change: 0 additions & 1 deletion ui/desktop/src/goosed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { Buffer } from 'node:buffer';
import { status } from './api';
import { Client, createClient, createConfig } from './api/client';


export interface Logger {
info: (...args: unknown[]) => void;
error: (...args: unknown[]) => void;
Expand Down