diff options
| author | shrutip90 <[email protected]> | 2025-08-14 11:15:48 -0700 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-08-14 18:15:48 +0000 |
| commit | 69c55827239b5c937c177eef4b4fbcc2758ef23e (patch) | |
| tree | f2dc2f1a55e64cd9a235bcf0e3d9caaa7f552b7c /packages/cli/src | |
| parent | 69d666cfafe97e49a6cacb306df9a737d4aa9f20 (diff) | |
feat: Show untrusted status in the Footer (#6210)
Co-authored-by: Jacob Richman <[email protected]>
Diffstat (limited to 'packages/cli/src')
| -rw-r--r-- | packages/cli/src/config/config.test.ts | 9 | ||||
| -rw-r--r-- | packages/cli/src/config/config.ts | 2 | ||||
| -rw-r--r-- | packages/cli/src/config/trustedFolders.test.ts | 21 | ||||
| -rw-r--r-- | packages/cli/src/config/trustedFolders.ts | 11 | ||||
| -rw-r--r-- | packages/cli/src/ui/App.test.tsx | 41 | ||||
| -rw-r--r-- | packages/cli/src/ui/App.tsx | 6 | ||||
| -rw-r--r-- | packages/cli/src/ui/components/Footer.test.tsx | 53 | ||||
| -rw-r--r-- | packages/cli/src/ui/components/Footer.tsx | 8 | ||||
| -rw-r--r-- | packages/cli/src/ui/hooks/useFolderTrust.test.ts | 44 | ||||
| -rw-r--r-- | packages/cli/src/ui/hooks/useFolderTrust.ts | 82 |
10 files changed, 219 insertions, 58 deletions
diff --git a/packages/cli/src/config/config.test.ts b/packages/cli/src/config/config.test.ts index 69985867..e4535fca 100644 --- a/packages/cli/src/config/config.test.ts +++ b/packages/cli/src/config/config.test.ts @@ -1809,7 +1809,14 @@ describe('loadCliConfig trustedFolder', () => { description, } of testCases) { it(`should be correct for: ${description}`, async () => { - (isWorkspaceTrusted as vi.Mock).mockReturnValue(mockTrustValue); + (isWorkspaceTrusted as vi.Mock).mockImplementation( + (settings: Settings) => { + const featureIsEnabled = + (settings.folderTrustFeature ?? false) && + (settings.folderTrust ?? true); + return featureIsEnabled ? mockTrustValue : true; + }, + ); const argv = await parseArguments(); const settings: Settings = { folderTrustFeature, folderTrust }; const config = await loadCliConfig(settings, [], 'test-session', argv); diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index 296d140d..f50cafd4 100644 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -321,7 +321,7 @@ export async function loadCliConfig( const folderTrustFeature = settings.folderTrustFeature ?? false; const folderTrustSetting = settings.folderTrust ?? true; const folderTrust = folderTrustFeature && folderTrustSetting; - const trustedFolder = folderTrust ? isWorkspaceTrusted() : true; + const trustedFolder = isWorkspaceTrusted(settings); const allExtensions = annotateActiveExtensions( extensions, diff --git a/packages/cli/src/config/trustedFolders.test.ts b/packages/cli/src/config/trustedFolders.test.ts index 67bf9cfc..5f613e63 100644 --- a/packages/cli/src/config/trustedFolders.test.ts +++ b/packages/cli/src/config/trustedFolders.test.ts @@ -35,6 +35,7 @@ import { TrustLevel, isWorkspaceTrusted, } from './trustedFolders.js'; +import { Settings } from './settings.js'; vi.mock('fs', async (importOriginal) => { const actualFs = await importOriginal<typeof fs>(); @@ -130,6 +131,10 @@ describe('Trusted Folders Loading', () => { describe('isWorkspaceTrusted', () => { let mockCwd: string; const mockRules: Record<string, TrustLevel> = {}; + const mockSettings: Settings = { + folderTrustFeature: true, + folderTrust: true, + }; beforeEach(() => { vi.spyOn(process, 'cwd').mockImplementation(() => mockCwd); @@ -153,51 +158,51 @@ describe('isWorkspaceTrusted', () => { it('should return true for a directly trusted folder', () => { mockCwd = '/home/user/projectA'; mockRules['/home/user/projectA'] = TrustLevel.TRUST_FOLDER; - expect(isWorkspaceTrusted()).toBe(true); + expect(isWorkspaceTrusted(mockSettings)).toBe(true); }); it('should return true for a child of a trusted folder', () => { mockCwd = '/home/user/projectA/src'; mockRules['/home/user/projectA'] = TrustLevel.TRUST_FOLDER; - expect(isWorkspaceTrusted()).toBe(true); + expect(isWorkspaceTrusted(mockSettings)).toBe(true); }); it('should return true for a child of a trusted parent folder', () => { mockCwd = '/home/user/projectB'; mockRules['/home/user/projectB/somefile.txt'] = TrustLevel.TRUST_PARENT; - expect(isWorkspaceTrusted()).toBe(true); + expect(isWorkspaceTrusted(mockSettings)).toBe(true); }); it('should return false for a directly untrusted folder', () => { mockCwd = '/home/user/untrusted'; mockRules['/home/user/untrusted'] = TrustLevel.DO_NOT_TRUST; - expect(isWorkspaceTrusted()).toBe(false); + expect(isWorkspaceTrusted(mockSettings)).toBe(false); }); it('should return undefined for a child of an untrusted folder', () => { mockCwd = '/home/user/untrusted/src'; mockRules['/home/user/untrusted'] = TrustLevel.DO_NOT_TRUST; - expect(isWorkspaceTrusted()).toBeUndefined(); + expect(isWorkspaceTrusted(mockSettings)).toBeUndefined(); }); it('should return undefined when no rules match', () => { mockCwd = '/home/user/other'; mockRules['/home/user/projectA'] = TrustLevel.TRUST_FOLDER; mockRules['/home/user/untrusted'] = TrustLevel.DO_NOT_TRUST; - expect(isWorkspaceTrusted()).toBeUndefined(); + expect(isWorkspaceTrusted(mockSettings)).toBeUndefined(); }); it('should prioritize trust over distrust', () => { mockCwd = '/home/user/projectA/untrusted'; mockRules['/home/user/projectA'] = TrustLevel.TRUST_FOLDER; mockRules['/home/user/projectA/untrusted'] = TrustLevel.DO_NOT_TRUST; - expect(isWorkspaceTrusted()).toBe(true); + expect(isWorkspaceTrusted(mockSettings)).toBe(true); }); it('should handle path normalization', () => { mockCwd = '/home/user/projectA'; mockRules[`/home/user/../user/${path.basename('/home/user/projectA')}`] = TrustLevel.TRUST_FOLDER; - expect(isWorkspaceTrusted()).toBe(true); + expect(isWorkspaceTrusted(mockSettings)).toBe(true); }); }); diff --git a/packages/cli/src/config/trustedFolders.ts b/packages/cli/src/config/trustedFolders.ts index 9da27c80..876c2eb3 100644 --- a/packages/cli/src/config/trustedFolders.ts +++ b/packages/cli/src/config/trustedFolders.ts @@ -8,6 +8,7 @@ import * as fs from 'fs'; import * as path from 'path'; import { homedir } from 'os'; import { getErrorMessage, isWithinRoot } from '@google/gemini-cli-core'; +import { Settings } from './settings.js'; import stripJsonComments from 'strip-json-comments'; export const TRUSTED_FOLDERS_FILENAME = 'trustedFolders.json'; @@ -109,7 +110,15 @@ export function saveTrustedFolders( } } -export function isWorkspaceTrusted(): boolean | undefined { +export function isWorkspaceTrusted(settings: Settings): boolean | undefined { + const folderTrustFeature = settings.folderTrustFeature ?? false; + const folderTrustSetting = settings.folderTrust ?? true; + const folderTrustEnabled = folderTrustFeature && folderTrustSetting; + + if (!folderTrustEnabled) { + return true; + } + const { rules, errors } = loadTrustedFolders(); if (errors.length > 0) { diff --git a/packages/cli/src/ui/App.test.tsx b/packages/cli/src/ui/App.test.tsx index c797b778..64cd5842 100644 --- a/packages/cli/src/ui/App.test.tsx +++ b/packages/cli/src/ui/App.test.tsx @@ -163,6 +163,7 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => { getCurrentIde: vi.fn(() => 'vscode'), getDetectedIdeDisplayName: vi.fn(() => 'VSCode'), })), + isTrustedFolder: vi.fn(() => true), }; }); @@ -1118,5 +1119,45 @@ describe('App UI', () => { await Promise.resolve(); expect(lastFrame()).toContain('Do you trust this folder?'); }); + + it('should display the folder trust dialog when the feature is enabled but the folder is not trusted', async () => { + const { useFolderTrust } = await import('./hooks/useFolderTrust.js'); + vi.mocked(useFolderTrust).mockReturnValue({ + isFolderTrustDialogOpen: true, + handleFolderTrustSelect: vi.fn(), + }); + mockConfig.isTrustedFolder.mockReturnValue(false); + + const { lastFrame, unmount } = render( + <App + config={mockConfig as unknown as ServerConfig} + settings={mockSettings} + version={mockVersion} + />, + ); + currentUnmount = unmount; + await Promise.resolve(); + expect(lastFrame()).toContain('Do you trust this folder?'); + }); + + it('should not display the folder trust dialog when the feature is disabled', async () => { + const { useFolderTrust } = await import('./hooks/useFolderTrust.js'); + vi.mocked(useFolderTrust).mockReturnValue({ + isFolderTrustDialogOpen: false, + handleFolderTrustSelect: vi.fn(), + }); + mockConfig.isTrustedFolder.mockReturnValue(false); + + const { lastFrame, unmount } = render( + <App + config={mockConfig as unknown as ServerConfig} + settings={mockSettings} + version={mockVersion} + />, + ); + currentUnmount = unmount; + await Promise.resolve(); + expect(lastFrame()).not.toContain('Do you trust this folder?'); + }); }); }); diff --git a/packages/cli/src/ui/App.tsx b/packages/cli/src/ui/App.tsx index 5d4643e5..2c17315f 100644 --- a/packages/cli/src/ui/App.tsx +++ b/packages/cli/src/ui/App.tsx @@ -171,6 +171,9 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => { const [editorError, setEditorError] = useState<string | null>(null); const [footerHeight, setFooterHeight] = useState<number>(0); const [corgiMode, setCorgiMode] = useState(false); + const [isTrustedFolderState, setIsTrustedFolder] = useState( + config.isTrustedFolder(), + ); const [currentModel, setCurrentModel] = useState(config.getModel()); const [shellModeActive, setShellModeActive] = useState(false); const [showErrorDetails, setShowErrorDetails] = useState<boolean>(false); @@ -254,7 +257,7 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => { const { isFolderTrustDialogOpen, handleFolderTrustSelect } = useFolderTrust( settings, - config, + setIsTrustedFolder, ); const { @@ -1198,6 +1201,7 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => { promptTokenCount={sessionStats.lastPromptTokenCount} nightly={nightly} vimMode={vimModeEnabled ? vimMode : undefined} + isTrustedFolder={isTrustedFolderState} /> </Box> </Box> diff --git a/packages/cli/src/ui/components/Footer.test.tsx b/packages/cli/src/ui/components/Footer.test.tsx index 5e79eea4..e3673dfe 100644 --- a/packages/cli/src/ui/components/Footer.test.tsx +++ b/packages/cli/src/ui/components/Footer.test.tsx @@ -103,4 +103,57 @@ describe('<Footer />', () => { expect(lastFrame()).toContain(defaultProps.model); expect(lastFrame()).toMatch(/\(\d+% context[\s\S]*left\)/); }); + + describe('sandbox and trust info', () => { + it('should display untrusted when isTrustedFolder is false', () => { + const { lastFrame } = renderWithWidth(120, { + ...defaultProps, + isTrustedFolder: false, + }); + expect(lastFrame()).toContain('untrusted'); + }); + + it('should display custom sandbox info when SANDBOX env is set', () => { + vi.stubEnv('SANDBOX', 'gemini-cli-test-sandbox'); + const { lastFrame } = renderWithWidth(120, { + ...defaultProps, + isTrustedFolder: undefined, + }); + expect(lastFrame()).toContain('test'); + vi.unstubAllEnvs(); + }); + + it('should display macOS Seatbelt info when SANDBOX is sandbox-exec', () => { + vi.stubEnv('SANDBOX', 'sandbox-exec'); + vi.stubEnv('SEATBELT_PROFILE', 'test-profile'); + const { lastFrame } = renderWithWidth(120, { + ...defaultProps, + isTrustedFolder: true, + }); + expect(lastFrame()).toMatch(/macOS Seatbelt.*\(test-profile\)/s); + vi.unstubAllEnvs(); + }); + + it('should display "no sandbox" when SANDBOX is not set and folder is trusted', () => { + // Clear any SANDBOX env var that might be set. + vi.stubEnv('SANDBOX', ''); + const { lastFrame } = renderWithWidth(120, { + ...defaultProps, + isTrustedFolder: true, + }); + expect(lastFrame()).toContain('no sandbox'); + vi.unstubAllEnvs(); + }); + + it('should prioritize untrusted message over sandbox info', () => { + vi.stubEnv('SANDBOX', 'gemini-cli-test-sandbox'); + const { lastFrame } = renderWithWidth(120, { + ...defaultProps, + isTrustedFolder: false, + }); + expect(lastFrame()).toContain('untrusted'); + expect(lastFrame()).not.toMatch(/test-sandbox/s); + vi.unstubAllEnvs(); + }); + }); }); diff --git a/packages/cli/src/ui/components/Footer.tsx b/packages/cli/src/ui/components/Footer.tsx index aaf6c176..09b94ec1 100644 --- a/packages/cli/src/ui/components/Footer.tsx +++ b/packages/cli/src/ui/components/Footer.tsx @@ -32,6 +32,7 @@ interface FooterProps { promptTokenCount: number; nightly: boolean; vimMode?: string; + isTrustedFolder?: boolean; } export const Footer: React.FC<FooterProps> = ({ @@ -47,6 +48,7 @@ export const Footer: React.FC<FooterProps> = ({ promptTokenCount, nightly, vimMode, + isTrustedFolder, }) => { const { columns: terminalWidth } = useTerminalSize(); @@ -90,7 +92,7 @@ export const Footer: React.FC<FooterProps> = ({ )} </Box> - {/* Middle Section: Centered Sandbox Info */} + {/* Middle Section: Centered Trust/Sandbox Info */} <Box flexGrow={isNarrow ? 0 : 1} alignItems="center" @@ -99,7 +101,9 @@ export const Footer: React.FC<FooterProps> = ({ paddingX={isNarrow ? 0 : 1} paddingTop={isNarrow ? 1 : 0} > - {process.env.SANDBOX && process.env.SANDBOX !== 'sandbox-exec' ? ( + {isTrustedFolder === false ? ( + <Text color={theme.status.warning}>untrusted</Text> + ) : process.env.SANDBOX && process.env.SANDBOX !== 'sandbox-exec' ? ( <Text color="green"> {process.env.SANDBOX.replace(/^gemini-(?:cli-)?/, '')} </Text> diff --git a/packages/cli/src/ui/hooks/useFolderTrust.test.ts b/packages/cli/src/ui/hooks/useFolderTrust.test.ts index e565ab05..3103cab4 100644 --- a/packages/cli/src/ui/hooks/useFolderTrust.test.ts +++ b/packages/cli/src/ui/hooks/useFolderTrust.test.ts @@ -7,7 +7,6 @@ import { vi } from 'vitest'; import { renderHook, act } from '@testing-library/react'; import { useFolderTrust } from './useFolderTrust.js'; -import { type Config } from '@google/gemini-cli-core'; import { LoadedSettings } from '../../config/settings.js'; import { FolderTrustChoice } from '../components/FolderTrustDialog.js'; import { @@ -25,9 +24,10 @@ vi.mock('process', () => ({ describe('useFolderTrust', () => { let mockSettings: LoadedSettings; - let mockConfig: Config; let mockTrustedFolders: LoadedTrustedFolders; let loadTrustedFoldersSpy: vi.SpyInstance; + let isWorkspaceTrustedSpy: vi.SpyInstance; + let onTrustChange: (isTrusted: boolean | undefined) => void; beforeEach(() => { mockSettings = { @@ -38,10 +38,6 @@ describe('useFolderTrust', () => { setValue: vi.fn(), } as unknown as LoadedSettings; - mockConfig = { - isTrustedFolder: vi.fn().mockReturnValue(undefined), - } as unknown as Config; - mockTrustedFolders = { setValue: vi.fn(), } as unknown as LoadedTrustedFolders; @@ -49,7 +45,9 @@ describe('useFolderTrust', () => { loadTrustedFoldersSpy = vi .spyOn(trustedFolders, 'loadTrustedFolders') .mockReturnValue(mockTrustedFolders); + isWorkspaceTrustedSpy = vi.spyOn(trustedFolders, 'isWorkspaceTrusted'); (process.cwd as vi.Mock).mockReturnValue('/test/path'); + onTrustChange = vi.fn(); }); afterEach(() => { @@ -57,34 +55,39 @@ describe('useFolderTrust', () => { }); it('should not open dialog when folder is already trusted', () => { - (mockConfig.isTrustedFolder as vi.Mock).mockReturnValue(true); + isWorkspaceTrustedSpy.mockReturnValue(true); const { result } = renderHook(() => - useFolderTrust(mockSettings, mockConfig), + useFolderTrust(mockSettings, onTrustChange), ); expect(result.current.isFolderTrustDialogOpen).toBe(false); + expect(onTrustChange).toHaveBeenCalledWith(true); }); it('should not open dialog when folder is already untrusted', () => { - (mockConfig.isTrustedFolder as vi.Mock).mockReturnValue(false); + isWorkspaceTrustedSpy.mockReturnValue(false); const { result } = renderHook(() => - useFolderTrust(mockSettings, mockConfig), + useFolderTrust(mockSettings, onTrustChange), ); expect(result.current.isFolderTrustDialogOpen).toBe(false); + expect(onTrustChange).toHaveBeenCalledWith(false); }); it('should open dialog when folder trust is undefined', () => { - (mockConfig.isTrustedFolder as vi.Mock).mockReturnValue(undefined); + isWorkspaceTrustedSpy.mockReturnValue(undefined); const { result } = renderHook(() => - useFolderTrust(mockSettings, mockConfig), + useFolderTrust(mockSettings, onTrustChange), ); expect(result.current.isFolderTrustDialogOpen).toBe(true); + expect(onTrustChange).toHaveBeenCalledWith(undefined); }); it('should handle TRUST_FOLDER choice', () => { + isWorkspaceTrustedSpy.mockReturnValue(undefined); const { result } = renderHook(() => - useFolderTrust(mockSettings, mockConfig), + useFolderTrust(mockSettings, onTrustChange), ); + isWorkspaceTrustedSpy.mockReturnValue(true); act(() => { result.current.handleFolderTrustSelect(FolderTrustChoice.TRUST_FOLDER); }); @@ -95,13 +98,16 @@ describe('useFolderTrust', () => { TrustLevel.TRUST_FOLDER, ); expect(result.current.isFolderTrustDialogOpen).toBe(false); + expect(onTrustChange).toHaveBeenLastCalledWith(true); }); it('should handle TRUST_PARENT choice', () => { + isWorkspaceTrustedSpy.mockReturnValue(undefined); const { result } = renderHook(() => - useFolderTrust(mockSettings, mockConfig), + useFolderTrust(mockSettings, onTrustChange), ); + isWorkspaceTrustedSpy.mockReturnValue(true); act(() => { result.current.handleFolderTrustSelect(FolderTrustChoice.TRUST_PARENT); }); @@ -111,13 +117,16 @@ describe('useFolderTrust', () => { TrustLevel.TRUST_PARENT, ); expect(result.current.isFolderTrustDialogOpen).toBe(false); + expect(onTrustChange).toHaveBeenLastCalledWith(true); }); it('should handle DO_NOT_TRUST choice', () => { + isWorkspaceTrustedSpy.mockReturnValue(undefined); const { result } = renderHook(() => - useFolderTrust(mockSettings, mockConfig), + useFolderTrust(mockSettings, onTrustChange), ); + isWorkspaceTrustedSpy.mockReturnValue(false); act(() => { result.current.handleFolderTrustSelect(FolderTrustChoice.DO_NOT_TRUST); }); @@ -127,11 +136,13 @@ describe('useFolderTrust', () => { TrustLevel.DO_NOT_TRUST, ); expect(result.current.isFolderTrustDialogOpen).toBe(false); + expect(onTrustChange).toHaveBeenLastCalledWith(false); }); it('should do nothing for default choice', () => { + isWorkspaceTrustedSpy.mockReturnValue(undefined); const { result } = renderHook(() => - useFolderTrust(mockSettings, mockConfig), + useFolderTrust(mockSettings, onTrustChange), ); act(() => { @@ -143,5 +154,6 @@ describe('useFolderTrust', () => { expect(mockTrustedFolders.setValue).not.toHaveBeenCalled(); expect(mockSettings.setValue).not.toHaveBeenCalled(); expect(result.current.isFolderTrustDialogOpen).toBe(true); + expect(onTrustChange).toHaveBeenCalledWith(undefined); }); }); diff --git a/packages/cli/src/ui/hooks/useFolderTrust.ts b/packages/cli/src/ui/hooks/useFolderTrust.ts index 6458d4aa..28b82b30 100644 --- a/packages/cli/src/ui/hooks/useFolderTrust.ts +++ b/packages/cli/src/ui/hooks/useFolderTrust.ts @@ -4,42 +4,68 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { useState, useCallback } from 'react'; -import { type Config } from '@google/gemini-cli-core'; -import { LoadedSettings } from '../../config/settings.js'; +import { useState, useCallback, useEffect } from 'react'; +import { Settings, LoadedSettings } from '../../config/settings.js'; import { FolderTrustChoice } from '../components/FolderTrustDialog.js'; -import { loadTrustedFolders, TrustLevel } from '../../config/trustedFolders.js'; +import { + loadTrustedFolders, + TrustLevel, + isWorkspaceTrusted, +} from '../../config/trustedFolders.js'; import * as process from 'process'; -export const useFolderTrust = (settings: LoadedSettings, config: Config) => { - const [isFolderTrustDialogOpen, setIsFolderTrustDialogOpen] = useState( - config.isTrustedFolder() === undefined, - ); +export const useFolderTrust = ( + settings: LoadedSettings, + onTrustChange: (isTrusted: boolean | undefined) => void, +) => { + const [isTrusted, setIsTrusted] = useState<boolean | undefined>(undefined); + const [isFolderTrustDialogOpen, setIsFolderTrustDialogOpen] = useState(false); + + const { folderTrust, folderTrustFeature } = settings.merged; + useEffect(() => { + const trusted = isWorkspaceTrusted({ + folderTrust, + folderTrustFeature, + } as Settings); + setIsTrusted(trusted); + setIsFolderTrustDialogOpen(trusted === undefined); + onTrustChange(trusted); + }, [onTrustChange, folderTrust, folderTrustFeature]); - const handleFolderTrustSelect = useCallback((choice: FolderTrustChoice) => { - const trustedFolders = loadTrustedFolders(); - const cwd = process.cwd(); - let trustLevel: TrustLevel; + const handleFolderTrustSelect = useCallback( + (choice: FolderTrustChoice) => { + const trustedFolders = loadTrustedFolders(); + const cwd = process.cwd(); + let trustLevel: TrustLevel; - switch (choice) { - case FolderTrustChoice.TRUST_FOLDER: - trustLevel = TrustLevel.TRUST_FOLDER; - break; - case FolderTrustChoice.TRUST_PARENT: - trustLevel = TrustLevel.TRUST_PARENT; - break; - case FolderTrustChoice.DO_NOT_TRUST: - trustLevel = TrustLevel.DO_NOT_TRUST; - break; - default: - return; - } + switch (choice) { + case FolderTrustChoice.TRUST_FOLDER: + trustLevel = TrustLevel.TRUST_FOLDER; + break; + case FolderTrustChoice.TRUST_PARENT: + trustLevel = TrustLevel.TRUST_PARENT; + break; + case FolderTrustChoice.DO_NOT_TRUST: + trustLevel = TrustLevel.DO_NOT_TRUST; + break; + default: + return; + } - trustedFolders.setValue(cwd, trustLevel); - setIsFolderTrustDialogOpen(false); - }, []); + trustedFolders.setValue(cwd, trustLevel); + const trusted = isWorkspaceTrusted({ + folderTrust, + folderTrustFeature, + } as Settings); + setIsTrusted(trusted); + setIsFolderTrustDialogOpen(false); + onTrustChange(trusted); + }, + [onTrustChange, folderTrust, folderTrustFeature], + ); return { + isTrusted, isFolderTrustDialogOpen, handleFolderTrustSelect, }; |
