diff --git a/src/renderer/src/components/settings/DeveloperPermissionsPane.test.tsx b/src/renderer/src/components/settings/DeveloperPermissionsPane.test.tsx deleted file mode 100644 index a1da4dd9640..00000000000 --- a/src/renderer/src/components/settings/DeveloperPermissionsPane.test.tsx +++ /dev/null @@ -1,52 +0,0 @@ -// @vitest-environment happy-dom - -import { act } from 'react' -import { createRoot, type Root } from 'react-dom/client' -import { afterEach, beforeEach, expect, it, vi } from 'vitest' -import type { DeveloperPermissionState } from '../../../../shared/developer-permissions-types' -import { FULL_DISK_ACCESS_SETTINGS_TARGET_ID } from '@/lib/settings-navigation-types' -import { DeveloperPermissionsPane } from './DeveloperPermissionsPane' - -let container: HTMLDivElement -let root: Root - -beforeEach(() => { - Object.assign(window, { - api: { - developerPermissions: { - getStatus: vi.fn( - async (): Promise => [ - { id: 'full-disk-access', status: 'denied' } - ] - ), - request: vi.fn() - } - } - }) - container = document.createElement('div') - document.body.appendChild(container) - root = createRoot(container) -}) - -afterEach(async () => { - await act(async () => root.unmount()) - container.remove() - Reflect.deleteProperty(window, 'api') -}) - -it('highlights the Full Disk Access row for a targeted Settings navigation', async () => { - await act(async () => { - root.render( - - ) - }) - - const row = container.querySelector( - `[data-settings-section="${FULL_DISK_ACCESS_SETTINGS_TARGET_ID}"]` - ) - expect(row?.dataset.highlighted).toBe('true') - expect(row?.className).toContain('data-[highlighted=true]:ring-annotation-highlight/60') - - await act(async () => root.render()) - expect(row?.dataset.highlighted).toBeUndefined() -}) diff --git a/src/renderer/src/components/settings/DeveloperPermissionsPane.tsx b/src/renderer/src/components/settings/DeveloperPermissionsPane.tsx index 012d52af3ec..aa5b5a5694b 100644 --- a/src/renderer/src/components/settings/DeveloperPermissionsPane.tsx +++ b/src/renderer/src/components/settings/DeveloperPermissionsPane.tsx @@ -23,10 +23,6 @@ import { Button } from '../ui/button' import { translate } from '@/i18n/i18n' export { getDeveloperPermissionsPaneSearchEntries } from './developer-permissions-search' -type DeveloperPermissionsPaneProps = { - highlightedSettingId?: string | null -} - type PermissionDefinition = { id: DeveloperPermissionId label: string @@ -206,9 +202,7 @@ function statusClass(status: DeveloperPermissionStatus | undefined): string { return 'border-border bg-muted text-muted-foreground' } -export function DeveloperPermissionsPane({ - highlightedSettingId = null -}: DeveloperPermissionsPaneProps): React.JSX.Element { +export function DeveloperPermissionsPane(): React.JSX.Element { const [states, setStates] = useState([]) const [loading, setLoading] = useState(true) const [pendingId, setPendingId] = useState(null) @@ -346,15 +340,9 @@ export function DeveloperPermissionsPane({ {PERMISSIONS.map((permission) => { const status = stateById.get(permission.id) const pending = pendingId === permission.id - const settingId = `developer-permissions-${permission.id}` return ( -
+
{permission.icon}
diff --git a/src/renderer/src/components/settings/Settings.tsx b/src/renderer/src/components/settings/Settings.tsx index 17a251bea15..71db4c822de 100644 --- a/src/renderer/src/components/settings/Settings.tsx +++ b/src/renderer/src/components/settings/Settings.tsx @@ -177,7 +177,6 @@ const SETTINGS_NAV_GROUP_BY_ID = new Map( const SHORTCUTS_ESCAPE_CONFIRM_TOAST_ID = 'shortcuts-escape-confirm' const SHORTCUTS_ESCAPE_CONFIRM_WINDOW_MS = 2200 -const SETTINGS_TARGET_HIGHLIGHT_MS = 3_000 function getSettingsSectionId( pane: SettingsNavTarget, @@ -373,9 +372,6 @@ function Settings(): React.JSX.Element { getInitialMountedSectionIds ) const [pendingNavRequestTick, setPendingNavRequestTick] = useState(0) - const [highlightedSettingsTargetId, setHighlightedSettingsTargetId] = useState( - null - ) const [quickCommandAddIntentSignal, setQuickCommandAddIntentSignal] = useState(0) const [sshHostAddIntentSignal, setSshHostAddIntentSignal] = useState(0) const [remoteServerAddIntentSignal, setRemoteServerAddIntentSignal] = useState(0) @@ -450,17 +446,6 @@ function Settings(): React.JSX.Element { } }, []) - useEffect(() => { - if (!highlightedSettingsTargetId) { - return - } - const timeout = window.setTimeout( - () => setHighlightedSettingsTargetId(null), - SETTINGS_TARGET_HIGHLIGHT_MS - ) - return () => window.clearTimeout(timeout) - }, [highlightedSettingsTargetId]) - const requestFontSuggestions = useCallback((): void => { if (installedFontsLoadedRef.current || installedFontsLoadPromiseRef.current) { return @@ -676,11 +661,6 @@ function Settings(): React.JSX.Element { } pendingNavSectionRef.current = paneSectionId pendingScrollTargetRef.current = settingsNavigationTarget.sectionId ?? paneSectionId - setHighlightedSettingsTargetId( - settingsNavigationTarget.pane === 'developer-permissions' - ? (settingsNavigationTarget.sectionId ?? null) - : null - ) // Why: ensure Appearance's nested status-bar section is open before scrolling so the row is visible. if (settingsNavigationTarget.pane === 'appearance') { const accordion = resolveAppearanceAccordionDeepLink(settingsNavigationTarget.sectionId) @@ -1716,9 +1696,7 @@ function Settings(): React.JSX.Element { searchEntries={getSectionSearchEntries('developer-permissions')} > {isSectionMounted('developer-permissions') ? ( - + ) : null} ) : null} diff --git a/src/renderer/src/hooks/useMacosTccPromptNotice.test.tsx b/src/renderer/src/hooks/useMacosTccPromptNotice.test.tsx index 50fbd156ea3..14ae07e6b51 100644 --- a/src/renderer/src/hooks/useMacosTccPromptNotice.test.tsx +++ b/src/renderer/src/hooks/useMacosTccPromptNotice.test.tsx @@ -9,7 +9,6 @@ import { UI_LANGUAGE_SPANISH } from '../../../shared/ui-language' import { useAppStore } from '@/store' import { usePluginLanguagePackStore } from '@/store/plugin-language-packs' import { i18n } from '@/i18n/i18n' -import { FULL_DISK_ACCESS_SETTINGS_TARGET_ID } from '@/lib/settings-navigation-types' import { MacosTccPromptNoticeHost } from './MacosTccPromptNoticeHost' import { useMacosTccPromptNotice } from './useMacosTccPromptNotice' @@ -96,7 +95,7 @@ it('isolates plugin language-pack discovery from its parent render path', async expect(subscribeToMacosTccPromptNotice).toHaveBeenCalledOnce() }) -it('connects the notice to the macOS prompt and keeps it open until closed', async () => { +it('keeps the notice open until the user closes it', async () => { useAppStore.setState({ settings: { ...getDefaultSettings('/tmp'), uiLanguage: 'en' } }) @@ -112,13 +111,6 @@ it('connects the notice to the macOS prompt and keeps it open until closed', asy showNotice?.({ promptCount: 1 }, acknowledge) - expect(toastWarning).toHaveBeenCalledWith( - 'Seeing “Orca would like to access…”?', - expect.objectContaining({ - description: - 'That macOS message appears when an agent or terminal tool accesses protected files. macOS names Orca because Orca launched the tool. Grant Full Disk Access to Orca and Orca Helper to reduce future prompts.' - }) - ) const options = toastWarning.mock.calls[0]?.[1] as | { duration?: number; onDismiss?: () => void } | undefined @@ -149,9 +141,4 @@ it('acknowledges when opening Settings closes the notice', async () => { | undefined options?.action?.onClick() expect(acknowledge).toHaveBeenCalledOnce() - expect(useAppStore.getState().settingsNavigationTarget).toEqual({ - pane: 'developer-permissions', - repoId: null, - sectionId: FULL_DISK_ACCESS_SETTINGS_TARGET_ID - }) }) diff --git a/src/renderer/src/hooks/useMacosTccPromptNotice.ts b/src/renderer/src/hooks/useMacosTccPromptNotice.ts index 2416be1f99c..5da212cab49 100644 --- a/src/renderer/src/hooks/useMacosTccPromptNotice.ts +++ b/src/renderer/src/hooks/useMacosTccPromptNotice.ts @@ -6,7 +6,6 @@ import { useAppStore } from '@/store' import { usePluginLanguagePackStore } from '@/store/plugin-language-packs' import { translate } from '@/i18n/i18n' import { resolveUiLocale } from '@/i18n/supported-languages' -import { FULL_DISK_ACCESS_SETTINGS_TARGET_ID } from '@/lib/settings-navigation-types' import { dismissMacosTccPromptNotice, subscribeToMacosTccPromptNotice @@ -42,12 +41,12 @@ export function useMacosTccPromptNotice(): void { toast.warning( translate( 'auto.hooks.useMacosTccPromptNotice.title', - 'Seeing “Orca would like to access…”?' + 'Reduce repeated macOS file-access prompts' ), { description: translate( 'auto.hooks.useMacosTccPromptNotice.description', - 'That macOS message appears when an agent or terminal tool accesses protected files. macOS names Orca because Orca launched the tool. Grant Full Disk Access to Orca and Orca Helper to reduce future prompts.' + 'macOS attributes file access by your agents and terminal tools to Orca. Granting Full Disk Access reduces these prompts.' ), duration: Infinity, onDismiss: acknowledge, @@ -56,11 +55,7 @@ export function useMacosTccPromptNotice(): void { onClick: () => { acknowledge() openSettingsPage() - openSettingsTarget({ - pane: 'developer-permissions', - repoId: null, - sectionId: FULL_DISK_ACCESS_SETTINGS_TARGET_ID - }) + openSettingsTarget({ pane: 'developer-permissions', repoId: null }) } }, cancel: { diff --git a/src/renderer/src/i18n/locales/en.json b/src/renderer/src/i18n/locales/en.json index a81dc475471..cf6ea8d4b5d 100644 --- a/src/renderer/src/i18n/locales/en.json +++ b/src/renderer/src/i18n/locales/en.json @@ -826,8 +826,8 @@ "pasteTooLarge": "Paste is too large." }, "useMacosTccPromptNotice": { - "title": "Seeing “Orca would like to access…”?", - "description": "That macOS message appears when an agent or terminal tool accesses protected files. macOS names Orca because Orca launched the tool. Grant Full Disk Access to Orca and Orca Helper to reduce future prompts.", + "title": "Reduce repeated macOS file-access prompts", + "description": "macOS attributes file access by your agents and terminal tools to Orca. Granting Full Disk Access reduces these prompts.", "openSettings": "Open Settings", "dismiss": "Don't show again" } diff --git a/src/renderer/src/lib/settings-navigation-types.ts b/src/renderer/src/lib/settings-navigation-types.ts index 45efa2031e2..3ce9ffea086 100644 --- a/src/renderer/src/lib/settings-navigation-types.ts +++ b/src/renderer/src/lib/settings-navigation-types.ts @@ -56,8 +56,6 @@ const SETTINGS_NAV_TARGET_SET: ReadonlySet = new Set(SETTINGS_NAV_TARGET const SETTINGS_NAV_INTENT_SET: ReadonlySet = new Set(SETTINGS_NAV_INTENTS) export type SettingsNavTarget = (typeof SETTINGS_NAV_TARGETS)[number] -export const FULL_DISK_ACCESS_SETTINGS_TARGET_ID = 'developer-permissions-full-disk-access' - export type SettingsNavigationTarget = { pane: SettingsNavTarget repoId: string | null