diff options
| author | shrutip90 <[email protected]> | 2025-08-19 21:20:41 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-08-20 04:20:41 +0000 |
| commit | d250293c2e0a4a50f5ef6b4b6cd3257730338d13 (patch) | |
| tree | da91b3cc7af02e40bc80df6857a2b2abcc12d4e3 /packages/cli/src/ui/hooks | |
| parent | 179f1414daf9058a05d38a170c0d36ca9f2b8547 (diff) | |
Ignore workspace settings for untrusted folders (#6606)
Diffstat (limited to 'packages/cli/src/ui/hooks')
| -rw-r--r-- | packages/cli/src/ui/hooks/useAuthCommand.ts | 8 | ||||
| -rw-r--r-- | packages/cli/src/ui/hooks/useEditorSettings.test.tsx (renamed from packages/cli/src/ui/hooks/useEditorSettings.test.ts) | 72 | ||||
| -rw-r--r-- | packages/cli/src/ui/hooks/useEditorSettings.ts | 15 | ||||
| -rw-r--r-- | packages/cli/src/ui/hooks/useFolderTrust.ts | 7 | ||||
| -rw-r--r-- | packages/cli/src/ui/hooks/useThemeCommand.ts | 10 |
5 files changed, 73 insertions, 39 deletions
diff --git a/packages/cli/src/ui/hooks/useAuthCommand.ts b/packages/cli/src/ui/hooks/useAuthCommand.ts index e57a11af..b92fe604 100644 --- a/packages/cli/src/ui/hooks/useAuthCommand.ts +++ b/packages/cli/src/ui/hooks/useAuthCommand.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { useState, useCallback, useEffect } from 'react'; +import { useState, useCallback, useEffect, useContext } from 'react'; import { LoadedSettings, SettingScope } from '../../config/settings.js'; import { AuthType, @@ -13,6 +13,7 @@ import { getErrorMessage, } from '@google/gemini-cli-core'; import { runExitCleanup } from '../../utils/cleanup.js'; +import { SettingsContext } from '../contexts/SettingsContext.js'; export const useAuthCommand = ( settings: LoadedSettings, @@ -22,6 +23,7 @@ export const useAuthCommand = ( const [isAuthDialogOpen, setIsAuthDialogOpen] = useState( settings.merged.selectedAuthType === undefined, ); + const settingsContext = useContext(SettingsContext); const openAuthDialog = useCallback(() => { setIsAuthDialogOpen(true); @@ -56,7 +58,7 @@ export const useAuthCommand = ( if (authType) { await clearCachedCredentialFile(); - settings.setValue(scope, 'selectedAuthType', authType); + settingsContext?.settings.setValue(scope, 'selectedAuthType', authType); if ( authType === AuthType.LOGIN_WITH_GOOGLE && config.isBrowserLaunchSuppressed() @@ -75,7 +77,7 @@ Logging in with Google... Please restart Gemini CLI to continue. setIsAuthDialogOpen(false); setAuthError(null); }, - [settings, setAuthError, config], + [settingsContext, setAuthError, config], ); const cancelAuthentication = useCallback(() => { diff --git a/packages/cli/src/ui/hooks/useEditorSettings.test.ts b/packages/cli/src/ui/hooks/useEditorSettings.test.tsx index 7b056c2a..f1d65056 100644 --- a/packages/cli/src/ui/hooks/useEditorSettings.test.ts +++ b/packages/cli/src/ui/hooks/useEditorSettings.test.tsx @@ -23,6 +23,8 @@ import { checkHasEditorType, allowEditorTypeInSandbox, } from '@google/gemini-cli-core'; +import { SettingsContext } from '../contexts/SettingsContext.js'; +import { type ReactNode } from 'react'; vi.mock('@google/gemini-cli-core', async () => { const actual = await vi.importActual('@google/gemini-cli-core'); @@ -43,13 +45,23 @@ describe('useEditorSettings', () => { (item: Omit<HistoryItem, 'id'>, timestamp: number) => void >; + const wrapper = ({ children }: { children: ReactNode }) => ( + <SettingsContext.Provider + value={{ settings: mockLoadedSettings, recomputeSettings: () => {} }} + > + {children} + </SettingsContext.Provider> + ); + beforeEach(() => { vi.resetAllMocks(); - - mockLoadedSettings = { - setValue: vi.fn(), - } as unknown as LoadedSettings; - + mockLoadedSettings = new LoadedSettings( + { path: '', settings: {} }, + { path: '', settings: {} }, + { path: '', settings: {} }, + [], + ); + mockLoadedSettings.setValue = vi.fn(); mockSetEditorError = vi.fn(); mockAddItem = vi.fn(); @@ -63,16 +75,18 @@ describe('useEditorSettings', () => { }); it('should initialize with dialog closed', () => { - const { result } = renderHook(() => - useEditorSettings(mockLoadedSettings, mockSetEditorError, mockAddItem), + const { result } = renderHook( + () => useEditorSettings(mockSetEditorError, mockAddItem), + { wrapper }, ); expect(result.current.isEditorDialogOpen).toBe(false); }); it('should open editor dialog when openEditorDialog is called', () => { - const { result } = renderHook(() => - useEditorSettings(mockLoadedSettings, mockSetEditorError, mockAddItem), + const { result } = renderHook( + () => useEditorSettings(mockSetEditorError, mockAddItem), + { wrapper }, ); act(() => { @@ -83,8 +97,9 @@ describe('useEditorSettings', () => { }); it('should close editor dialog when exitEditorDialog is called', () => { - const { result } = renderHook(() => - useEditorSettings(mockLoadedSettings, mockSetEditorError, mockAddItem), + const { result } = renderHook( + () => useEditorSettings(mockSetEditorError, mockAddItem), + { wrapper }, ); act(() => { result.current.openEditorDialog(); @@ -94,8 +109,9 @@ describe('useEditorSettings', () => { }); it('should handle editor selection successfully', () => { - const { result } = renderHook(() => - useEditorSettings(mockLoadedSettings, mockSetEditorError, mockAddItem), + const { result } = renderHook( + () => useEditorSettings(mockSetEditorError, mockAddItem), + { wrapper }, ); const editorType: EditorType = 'vscode'; @@ -125,8 +141,9 @@ describe('useEditorSettings', () => { }); it('should handle clearing editor preference (undefined editor)', () => { - const { result } = renderHook(() => - useEditorSettings(mockLoadedSettings, mockSetEditorError, mockAddItem), + const { result } = renderHook( + () => useEditorSettings(mockSetEditorError, mockAddItem), + { wrapper }, ); const scope = SettingScope.Workspace; @@ -155,8 +172,9 @@ describe('useEditorSettings', () => { }); it('should handle different editor types', () => { - const { result } = renderHook(() => - useEditorSettings(mockLoadedSettings, mockSetEditorError, mockAddItem), + const { result } = renderHook( + () => useEditorSettings(mockSetEditorError, mockAddItem), + { wrapper }, ); const editorTypes: EditorType[] = ['cursor', 'windsurf', 'vim']; @@ -184,8 +202,9 @@ describe('useEditorSettings', () => { }); it('should handle different setting scopes', () => { - const { result } = renderHook(() => - useEditorSettings(mockLoadedSettings, mockSetEditorError, mockAddItem), + const { result } = renderHook( + () => useEditorSettings(mockSetEditorError, mockAddItem), + { wrapper }, ); const editorType: EditorType = 'vscode'; @@ -213,8 +232,9 @@ describe('useEditorSettings', () => { }); it('should not set preference for unavailable editors', () => { - const { result } = renderHook(() => - useEditorSettings(mockLoadedSettings, mockSetEditorError, mockAddItem), + const { result } = renderHook( + () => useEditorSettings(mockSetEditorError, mockAddItem), + { wrapper }, ); mockCheckHasEditorType.mockReturnValue(false); @@ -233,8 +253,9 @@ describe('useEditorSettings', () => { }); it('should not set preference for editors not allowed in sandbox', () => { - const { result } = renderHook(() => - useEditorSettings(mockLoadedSettings, mockSetEditorError, mockAddItem), + const { result } = renderHook( + () => useEditorSettings(mockSetEditorError, mockAddItem), + { wrapper }, ); mockAllowEditorTypeInSandbox.mockReturnValue(false); @@ -253,8 +274,9 @@ describe('useEditorSettings', () => { }); it('should handle errors during editor selection', () => { - const { result } = renderHook(() => - useEditorSettings(mockLoadedSettings, mockSetEditorError, mockAddItem), + const { result } = renderHook( + () => useEditorSettings(mockSetEditorError, mockAddItem), + { wrapper }, ); const errorMessage = 'Failed to save settings'; diff --git a/packages/cli/src/ui/hooks/useEditorSettings.ts b/packages/cli/src/ui/hooks/useEditorSettings.ts index 60c16798..bd6f72bb 100644 --- a/packages/cli/src/ui/hooks/useEditorSettings.ts +++ b/packages/cli/src/ui/hooks/useEditorSettings.ts @@ -4,14 +4,15 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { useState, useCallback } from 'react'; -import { LoadedSettings, SettingScope } from '../../config/settings.js'; +import { useState, useCallback, useContext } from 'react'; +import { SettingScope } from '../../config/settings.js'; import { type HistoryItem, MessageType } from '../types.js'; import { allowEditorTypeInSandbox, checkHasEditorType, EditorType, } from '@google/gemini-cli-core'; +import { SettingsContext } from '../contexts/SettingsContext.js'; interface UseEditorSettingsReturn { isEditorDialogOpen: boolean; @@ -24,11 +25,11 @@ interface UseEditorSettingsReturn { } export const useEditorSettings = ( - loadedSettings: LoadedSettings, setEditorError: (error: string | null) => void, addItem: (item: Omit<HistoryItem, 'id'>, timestamp: number) => void, ): UseEditorSettingsReturn => { const [isEditorDialogOpen, setIsEditorDialogOpen] = useState(false); + const settingsContext = useContext(SettingsContext); const openEditorDialog = useCallback(() => { setIsEditorDialogOpen(true); @@ -45,7 +46,11 @@ export const useEditorSettings = ( } try { - loadedSettings.setValue(scope, 'preferredEditor', editorType); + settingsContext?.settings.setValue( + scope, + 'preferredEditor', + editorType, + ); addItem( { type: MessageType.INFO, @@ -59,7 +64,7 @@ export const useEditorSettings = ( setEditorError(`Failed to set editor preference: ${error}`); } }, - [loadedSettings, setEditorError, addItem], + [settingsContext, setEditorError, addItem], ); const exitEditorDialog = useCallback(() => { diff --git a/packages/cli/src/ui/hooks/useFolderTrust.ts b/packages/cli/src/ui/hooks/useFolderTrust.ts index 28b82b30..560a2260 100644 --- a/packages/cli/src/ui/hooks/useFolderTrust.ts +++ b/packages/cli/src/ui/hooks/useFolderTrust.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { useState, useCallback, useEffect } from 'react'; +import { useState, useCallback, useEffect, useContext } from 'react'; import { Settings, LoadedSettings } from '../../config/settings.js'; import { FolderTrustChoice } from '../components/FolderTrustDialog.js'; import { @@ -13,6 +13,7 @@ import { isWorkspaceTrusted, } from '../../config/trustedFolders.js'; import * as process from 'process'; +import { SettingsContext } from '../contexts/SettingsContext.js'; export const useFolderTrust = ( settings: LoadedSettings, @@ -20,6 +21,7 @@ export const useFolderTrust = ( ) => { const [isTrusted, setIsTrusted] = useState<boolean | undefined>(undefined); const [isFolderTrustDialogOpen, setIsFolderTrustDialogOpen] = useState(false); + const settingsContext = useContext(SettingsContext); const { folderTrust, folderTrustFeature } = settings.merged; useEffect(() => { @@ -60,8 +62,9 @@ export const useFolderTrust = ( setIsTrusted(trusted); setIsFolderTrustDialogOpen(false); onTrustChange(trusted); + settingsContext?.recomputeSettings(); }, - [onTrustChange, folderTrust, folderTrustFeature], + [onTrustChange, folderTrust, folderTrustFeature, settingsContext], ); return { diff --git a/packages/cli/src/ui/hooks/useThemeCommand.ts b/packages/cli/src/ui/hooks/useThemeCommand.ts index cf881f53..06d1c5b1 100644 --- a/packages/cli/src/ui/hooks/useThemeCommand.ts +++ b/packages/cli/src/ui/hooks/useThemeCommand.ts @@ -4,10 +4,11 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { useState, useCallback, useEffect } from 'react'; +import { useState, useCallback, useEffect, useContext } from 'react'; import { themeManager } from '../themes/theme-manager.js'; -import { LoadedSettings, SettingScope } from '../../config/settings.js'; // Import LoadedSettings, AppSettings, MergedSetting -import { type HistoryItem, MessageType } from '../types.js'; +import { HistoryItem, MessageType } from '../types.js'; +import { SettingScope } from '../../config/settings.js'; +import { SettingsContext } from '../contexts/SettingsContext.js'; import process from 'node:process'; interface UseThemeCommandReturn { @@ -21,11 +22,12 @@ interface UseThemeCommandReturn { } export const useThemeCommand = ( - loadedSettings: LoadedSettings, setThemeError: (error: string | null) => void, addItem: (item: Omit<HistoryItem, 'id'>, timestamp: number) => void, ): UseThemeCommandReturn => { const [isThemeDialogOpen, setIsThemeDialogOpen] = useState(false); + const settingsContext = useContext(SettingsContext); + const loadedSettings = settingsContext!.settings; // Check for invalid theme configuration on startup useEffect(() => { |
