From 293f26589be28e4c2e559c59ed08e9eb561add5b Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 10 Jul 2026 16:57:58 +0100 Subject: [PATCH] fix: default agent sessions off --- CHANGELOG.md | 1 + Sources/CodexBar/SettingsStore.swift | 2 +- .../AgentSessionMenuDescriptorTests.swift | 41 +++++++++++++++++++ .../SettingsStoreCoverageTests.swift | 18 ++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30d632a8a8..2ecbb0836c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ - Quota warnings: add opt-in predictive pace alerts for Codex and Claude session and weekly limits, with one alert per risk episode. Thanks @vincent-peng! ### Fixed +- Agent Sessions: keep local and remote session discovery off by default while preserving the General setting for explicit opt-in. - Menus: stop completed provider cards and plan-utilization rows from remaining in “Refreshing…” while unrelated provider or token-cost work is still running. Thanks @Yuxin-Qiao! - Codex accounts: isolate authenticated OAuth and browser-cookie requests from shared URL caches and cookie stores, preventing one account's cached quota or identity response from appearing under another account and triggering false reset alerts (#1987, #2019). Thanks @harjothkhara! - Claude OAuth: honor the app's never-prompt policy in the bundled CLI and defer stale cache cleanup without touching Keychain until access is re-enabled. Thanks @Yuxin-Qiao! diff --git a/Sources/CodexBar/SettingsStore.swift b/Sources/CodexBar/SettingsStore.swift index 2d1406177c..44bed7a0be 100644 --- a/Sources/CodexBar/SettingsStore.swift +++ b/Sources/CodexBar/SettingsStore.swift @@ -474,7 +474,7 @@ extension SettingsStore { let providersSortedAlphabetically = userDefaults.object( forKey: "providersSortedAlphabetically") as? Bool ?? false let appLanguageRaw = userDefaults.string(forKey: "appLanguage") - let agentSessionsEnabled = userDefaults.object(forKey: "agentSessionsEnabled") as? Bool ?? true + let agentSessionsEnabled = userDefaults.object(forKey: "agentSessionsEnabled") as? Bool ?? false let agentSessionsManualHosts = userDefaults.string(forKey: "agentSessionsManualHosts") ?? "" return SettingsDefaultsState( refreshFrequency: refreshFrequency, diff --git a/Tests/CodexBarTests/AgentSessionMenuDescriptorTests.swift b/Tests/CodexBarTests/AgentSessionMenuDescriptorTests.swift index 24a7dc20a0..01118fe09a 100644 --- a/Tests/CodexBarTests/AgentSessionMenuDescriptorTests.swift +++ b/Tests/CodexBarTests/AgentSessionMenuDescriptorTests.swift @@ -5,6 +5,40 @@ import Testing @MainActor struct AgentSessionMenuDescriptorTests { + @Test + func `fresh settings omit agent sessions until explicitly enabled`() { + let settings = testSettingsStore(suiteName: "AgentSessionMenuDescriptorTests-default-off") + settings.statusChecksEnabled = false + let store = UsageStore( + fetcher: UsageFetcher(environment: [:]), + browserDetection: BrowserDetection(cacheTTL: 0), + settings: settings) + let session = Self.session(id: "local", host: "local-mac", activity: Date()) + + let buildDescriptor = { + MenuDescriptor.build( + provider: .codex, + store: store, + settings: settings, + account: AccountInfo(email: nil, plan: nil), + updateReady: false, + agentSessionsEnabled: settings.agentSessionsEnabled, + localAgentSessions: [session]) + } + + let disabledEntries = buildDescriptor().sections.flatMap(\.entries) + #expect(!Self.containsAgentSessions(in: disabledEntries)) + + settings.agentSessionsEnabled = true + + let enabledEntries = buildDescriptor().sections.flatMap(\.entries) + #expect(Self.containsAgentSessions(in: enabledEntries)) + #expect(enabledEntries.contains { entry in + guard case .action(_, .focusAgentSession) = entry else { return false } + return true + }) + } + @Test func `session section counts groups and renders unreachable hosts`() { let now = Date(timeIntervalSince1970: 1000) @@ -87,4 +121,11 @@ struct AgentSessionMenuDescriptorTests { transcriptPath: nil, host: host) } + + private static func containsAgentSessions(in entries: [MenuDescriptor.Entry]) -> Bool { + entries.contains { entry in + guard case let .text(title, .headline) = entry else { return false } + return title.hasPrefix("Agent Sessions (") + } + } } diff --git a/Tests/CodexBarTests/SettingsStoreCoverageTests.swift b/Tests/CodexBarTests/SettingsStoreCoverageTests.swift index a44c549c76..63363f6d3f 100644 --- a/Tests/CodexBarTests/SettingsStoreCoverageTests.swift +++ b/Tests/CodexBarTests/SettingsStoreCoverageTests.swift @@ -123,6 +123,24 @@ struct SettingsStoreCoverageTests { #expect(reloaded.copilotSettingsSnapshot(tokenOverride: nil).budgetExtrasEnabled) } + @Test + func `agent sessions default off and persist explicit opt in`() throws { + let suite = "SettingsStoreCoverageTests-agent-sessions" + let defaults = try #require(UserDefaults(suiteName: suite)) + defaults.removePersistentDomain(forName: suite) + let configStore = testConfigStore(suiteName: suite) + + let initial = Self.makeSettingsStore(userDefaults: defaults, configStore: configStore) + #expect(initial.agentSessionsEnabled == false) + #expect(defaults.object(forKey: "agentSessionsEnabled") == nil) + + initial.agentSessionsEnabled = true + #expect(defaults.object(forKey: "agentSessionsEnabled") as? Bool == true) + + let reloaded = Self.makeSettingsStore(userDefaults: defaults, configStore: configStore) + #expect(reloaded.agentSessionsEnabled) + } + @Test func `multi account menu layout persists and bridges legacy show all token accounts`() throws { let suite = "SettingsStoreCoverageTests-multi-account-layout"