summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui/hooks
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/ui/hooks')
-rw-r--r--packages/cli/src/ui/hooks/useAuthCommand.ts8
-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.ts15
-rw-r--r--packages/cli/src/ui/hooks/useFolderTrust.ts7
-rw-r--r--packages/cli/src/ui/hooks/useThemeCommand.ts10
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(() => {