diff --git a/src/renderer/src/components/settings/AgentsPane.test.tsx b/src/renderer/src/components/settings/AgentsPane.test.tsx index ff6807850cb..25cebb04b0d 100644 --- a/src/renderer/src/components/settings/AgentsPane.test.tsx +++ b/src/renderer/src/components/settings/AgentsPane.test.tsx @@ -12,7 +12,11 @@ import { getAgentWorkspaceTrustDescription, getAgentWorkspaceTrustTitle } from './agent-workspace-trust-copy' -import { getAgentAwakeDescription, getAgentAwakeTitle } from './agent-awake-copy' +import { + getAgentAwakeDescription, + getAgentAwakeLidNote, + getAgentAwakeTitle +} from './agent-awake-copy' import { getCodexTerminalServerIsolationTitle } from './codex-terminal-server-isolation-copy' import { AgentAwakeSetting } from './AgentAwakeSetting' import { AgentRuntimeSetting } from './AgentRuntimeSetting' @@ -251,7 +255,7 @@ describe('AgentsPane', () => { expect(markup).not.toContain('aria-label="Agent runtime"') expect(markup).toContain('Keep computer awake') expect(markup).toContain( - 'Choose On, Agent, or Off. Agent mode stays awake while agents are working. Caffeinate prevents idle sleep while active, but closing a MacBook lid may still put it to sleep.' + 'Choose On, Agent, or Off. Agent mode stays awake while agents are working. Orca also asks this device to stay awake when the lid is closed, subject to its power policy.' ) expect(markup).toContain('role="radiogroup"') expect(markup).toContain('>Agent<') @@ -353,6 +357,24 @@ describe('AgentsPane', () => { ) }) + it('describes macOS lid behavior without promising lid-closed wake', () => { + expect(getAgentAwakeDescription('Macintosh')).toBe( + 'Choose On, Agent, or Off. Agent mode prevents idle sleep while agents work, so long runs finish with the lid open. Closing the lid still puts this Mac to sleep.' + ) + }) + + it('picks the lid note for each platform', () => { + expect(getAgentAwakeLidNote('Macintosh')).toBe( + 'Prevents idle sleep with the lid open; closing the lid still puts this Mac to sleep.' + ) + expect(getAgentAwakeLidNote('Windows')).toBe( + "Lid-close behavior follows this device's power settings." + ) + expect(getAgentAwakeLidNote('X11; Linux x86_64')).toBe( + 'Orca also asks this device to stay awake when the lid is closed, subject to its power policy.' + ) + }) + it('updates the keep-awake mode with its legacy fallback', () => { const updateSettings = vi.fn() const element = AgentAwakeSetting({ diff --git a/src/renderer/src/components/settings/agent-awake-copy.ts b/src/renderer/src/components/settings/agent-awake-copy.ts index 4a9512ed066..81229813b91 100644 --- a/src/renderer/src/components/settings/agent-awake-copy.ts +++ b/src/renderer/src/components/settings/agent-awake-copy.ts @@ -5,6 +5,8 @@ import { searchKeywords } from './settings-search-keywords' const AGENT_AWAKE_TITLE_KEY = 'auto.components.settings.agent-awake-copy.modeTitle' const AGENT_AWAKE_DESCRIPTION_WINDOWS_KEY = 'auto.components.settings.agent-awake-copy.modeDescriptionWindows' +const AGENT_AWAKE_DESCRIPTION_MAC_KEY = + 'auto.components.settings.agent-awake-copy.modeDescriptionMac' const AGENT_AWAKE_DESCRIPTION_DEFAULT_KEY = 'auto.components.settings.agent-awake-copy.modeDescriptionDefault' @@ -31,6 +33,13 @@ export function getAgentAwakeDescription( "Choose On, Agent, or Off. Agent mode stays awake while agents are working; lid-close behavior follows this device's power settings." ) } + // macOS caffeinate can't hold a closed lid awake; Linux blocks logind's lid switch. + if (userAgent.includes('Mac')) { + return translate( + AGENT_AWAKE_DESCRIPTION_MAC_KEY, + 'Choose On, Agent, or Off. Agent mode prevents idle sleep while agents work, so long runs finish with the lid open. Closing the lid still puts this Mac to sleep.' + ) + } return translate( AGENT_AWAKE_DESCRIPTION_DEFAULT_KEY, @@ -38,6 +47,27 @@ export function getAgentAwakeDescription( ) } +export function getAgentAwakeLidNote( + userAgent = typeof navigator === 'undefined' ? '' : navigator.userAgent +): string { + if (userAgent.includes('Windows')) { + return translate( + 'auto.components.settings.agent-awake-copy.lidNoteWindows', + "Lid-close behavior follows this device's power settings." + ) + } + if (userAgent.includes('Mac')) { + return translate( + 'auto.components.settings.agent-awake-copy.lidNoteMac', + 'Prevents idle sleep with the lid open; closing the lid still puts this Mac to sleep.' + ) + } + return translate( + 'auto.components.settings.agent-awake-copy.lidNoteDefault', + 'Orca also asks this device to stay awake when the lid is closed, subject to its power policy.' + ) +} + export function getAgentAwakeSearchKeywords( userAgent = typeof navigator === 'undefined' ? '' : navigator.userAgent ): string[] { diff --git a/src/renderer/src/components/status-bar/CaffeinateStatusSegment.localization.test.tsx b/src/renderer/src/components/status-bar/CaffeinateStatusSegment.localization.test.tsx index 9a48aaaed2f..1b375a52ced 100644 --- a/src/renderer/src/components/status-bar/CaffeinateStatusSegment.localization.test.tsx +++ b/src/renderer/src/components/status-bar/CaffeinateStatusSegment.localization.test.tsx @@ -4,7 +4,11 @@ import type { ReactNode } from 'react' import { cleanup, render, screen, waitFor, within } from '@testing-library/react' import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest' import { i18n, translate } from '@/i18n/i18n' -import { getAgentAwakeModeLabel, getAgentAwakeTitle } from '../settings/agent-awake-copy' +import { + getAgentAwakeLidNote, + getAgentAwakeModeLabel, + getAgentAwakeTitle +} from '../settings/agent-awake-copy' import { CaffeinateStatusSegment } from './CaffeinateStatusSegment' const storeMocks = vi.hoisted(() => ({ @@ -197,9 +201,7 @@ describe('keep-awake copy under non-English UI languages', () => { name: '防止电脑休眠,智能体 · 生效中' }) expect(trigger.textContent).toContain('智能体') - expect(screen.getByRole('tooltip').textContent).toContain( - 'Caffeinate prevents idle sleep while active. Closing a MacBook lid may still put it to sleep.' - ) + expect(screen.getByRole('tooltip').textContent).toContain(getAgentAwakeLidNote()) const menu = screen.getByRole('menu') await waitFor(() => expect(menu.textContent).toContain('防止电脑休眠')) diff --git a/src/renderer/src/components/status-bar/CaffeinateStatusSegment.tsx b/src/renderer/src/components/status-bar/CaffeinateStatusSegment.tsx index d9bf64e77da..150a2f01dad 100644 --- a/src/renderer/src/components/status-bar/CaffeinateStatusSegment.tsx +++ b/src/renderer/src/components/status-bar/CaffeinateStatusSegment.tsx @@ -13,7 +13,11 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip import { useAppStore } from '@/store' import { isPairedWebClientWindow } from '@/lib/desktop-window-chrome' import { translate } from '@/i18n/i18n' -import { getAgentAwakeModeLabel, getAgentAwakeTitle } from '../settings/agent-awake-copy' +import { + getAgentAwakeLidNote, + getAgentAwakeModeLabel, + getAgentAwakeTitle +} from '../settings/agent-awake-copy' import { computerAwakeSettingsForMode, normalizeComputerAwakeMode, @@ -110,11 +114,7 @@ export function CaffeinateStatusSegment({ - {ariaLabel}.{' '} - {translate( - 'auto.components.status.bar.CaffeinateStatusSegment.tooltipDescription', - 'Caffeinate prevents idle sleep while active. Closing a MacBook lid may still put it to sleep.' - )} + {ariaLabel}. {getAgentAwakeLidNote()}