diff --git a/src/browser/App.tsx b/src/browser/App.tsx index ae49a895348..7109c5a3c04 100644 --- a/src/browser/App.tsx +++ b/src/browser/App.tsx @@ -33,6 +33,7 @@ import { import { getVisibleWorkspaceIds } from "./utils/ui/workspaceDomNav"; import { useUnreadTracking } from "./hooks/useUnreadTracking"; import { useWorkspaceStoreRaw, useWorkspaceRecency } from "./stores/WorkspaceStore"; +import { getAppConfigStore } from "./stores/AppConfigStore"; import { getResponseCompleteNotificationBody, shouldNotifyOnResponseComplete, @@ -1030,6 +1031,9 @@ function AppInner() { onToggleReasoningMode: toggleReasoningModeFromPalette, getFastMode: getFastModeActive, onToggleFastMode: toggleFastMode, + // Read when the palette opens, from the shared cache (one fetch + one config subscription + // per session), so showing the state costs no IPC call (#5791). + getKeepScreenAwake: () => getAppConfigStore().getSnapshot()?.keepScreenAwake, computerUse: computerUseAvailable ? { enabled: computerUse.enabledHere, onToggle: computerUse.toggle } : null, diff --git a/src/browser/stores/AppConfigStore.ts b/src/browser/stores/AppConfigStore.ts index 586328ff91f..a313a83fef5 100644 --- a/src/browser/stores/AppConfigStore.ts +++ b/src/browser/stores/AppConfigStore.ts @@ -21,6 +21,8 @@ export interface AppConfigSnapshot { bashCollapsedSummaryMode?: BashCollapsedSummaryMode; transcriptDensity?: TranscriptDensity; agentAiDefaults?: AgentAiDefaults; + /** Read by the command palette to show the toggle's current state (#5791). */ + keepScreenAwake?: boolean; } /** @@ -96,6 +98,7 @@ export class AppConfigStore { bashCollapsedSummaryMode: config.userPreferences?.appearance?.bashCollapsedSummaryMode, transcriptDensity: config.userPreferences?.appearance?.transcriptDensity, agentAiDefaults: config.agentAiDefaults, + keepScreenAwake: config.keepScreenAwake === true, }; this.notify(); } diff --git a/src/browser/utils/commands/sources.test.ts b/src/browser/utils/commands/sources.test.ts index cdfe9f71e58..5eac0d8f51c 100644 --- a/src/browser/utils/commands/sources.test.ts +++ b/src/browser/utils/commands/sources.test.ts @@ -1319,6 +1319,25 @@ test("toggle keep screen awake command is only offered in the desktop app", () = } }); +// #5791: config-backed toggles showed no current state, unlike the local-state toggles. +test("toggle keep screen awake shows the loaded config value", () => { + const originalWindow = globalThis.window; + globalThis.window = new GlobalWindow() as unknown as Window & typeof globalThis; + globalThis.window.api = { platform: "linux", versions: {} }; + const subtitleWith = (value: boolean | undefined) => + getActions({ getKeepScreenAwake: () => value }).find( + (a) => a.id === "settings:toggle-keep-screen-awake" + )?.subtitle; + try { + expect(subtitleWith(true)).toBe("Current: On"); + expect(subtitleWith(false)).toBe("Current: Off"); + // Config not loaded yet: say what the toggle does, never guess a state. + expect(subtitleWith(undefined)).toBe("Prevent display sleep while agents are working"); + } finally { + globalThis.window = originalWindow; + } +}); + test("toggle keep screen awake command inverts the persisted config flag", async () => { const originalWindow = globalThis.window; globalThis.window = new GlobalWindow() as unknown as Window & typeof globalThis; diff --git a/src/browser/utils/commands/sources.ts b/src/browser/utils/commands/sources.ts index fb6c436f29a..dc9f295387d 100644 --- a/src/browser/utils/commands/sources.ts +++ b/src/browser/utils/commands/sources.ts @@ -131,6 +131,8 @@ export interface BuildSourcesParams { ) => void; getFastMode: () => boolean; onToggleFastMode: () => void | Promise; + /** config.json keepScreenAwake from the shared app config cache; undefined until it loads. */ + getKeepScreenAwake?: () => boolean | undefined; /** Native host computer use for the selected workspace; null when unsupported or no workspace. */ computerUse?: { enabled: boolean; onToggle: () => void | Promise } | null; /** auto-model-routing experiment: gates the composer's Auto toggles in the palette. */ @@ -393,6 +395,12 @@ function openGoalPanel(workspaceId: string, openCompleteInput = false): void { createCustomEvent(CUSTOM_EVENTS.OPEN_GOAL_TAB, { workspaceId, openCompleteInput }) ); } + +/** Subtitle for an On/Off toggle backed by config.json; `fallback` until the value is known. */ +function describeConfigToggle(value: boolean | undefined, fallback: string): string { + return value === undefined ? fallback : `Current: ${value ? "On" : "Off"}`; +} + export function buildCoreSources(p: BuildSourcesParams): Array<() => CommandAction[]> { const actions: Array<() => CommandAction[]> = []; @@ -2030,7 +2038,12 @@ export function buildCoreSources(p: BuildSourcesParams): Array<() => CommandActi { id: CommandIds.settingsToggleKeepScreenAwake(), title: "Toggle Keep Screen Awake", - subtitle: "Prevent display sleep while agents are working", + // Show the current state like the local-state toggles do (#5791). Until the config + // has loaded, describe the toggle instead of guessing a state. + subtitle: describeConfigToggle( + p.getKeepScreenAwake?.(), + "Prevent display sleep while agents are working" + ), section: section.settings, keywords: ["awake", "sleep", "screen", "display", "lock", "power", "caffeinate"], run: async () => {