diff --git a/packages/cli/src/config/trustedFolders.test.ts b/packages/cli/src/config/trustedFolders.test.ts index 79330f1713..446586719d 100644 --- a/packages/cli/src/config/trustedFolders.test.ts +++ b/packages/cli/src/config/trustedFolders.test.ts @@ -4,17 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -// Mock 'os' first. import * as osActual from 'node:os'; -vi.mock('os', async (importOriginal) => { - const actualOs = await importOriginal(); - return { - ...actualOs, - homedir: vi.fn(() => '/mock/home/user'), - platform: vi.fn(() => 'linux'), - }; -}); - +import { ideContextStore } from '@google/gemini-cli-core'; import { describe, it, @@ -28,7 +19,6 @@ import { import * as fs from 'node:fs'; import stripJsonComments from 'strip-json-comments'; import * as path from 'node:path'; - import { loadTrustedFolders, USER_TRUSTED_FOLDERS_PATH, @@ -37,6 +27,14 @@ import { } from './trustedFolders.js'; import type { Settings } from './settings.js'; +vi.mock('os', async (importOriginal) => { + const actualOs = await importOriginal(); + return { + ...actualOs, + homedir: vi.fn(() => '/mock/home/user'), + platform: vi.fn(() => 'linux'), + }; +}); vi.mock('fs', async (importOriginal) => { const actualFs = await importOriginal(); return { @@ -47,7 +45,6 @@ vi.mock('fs', async (importOriginal) => { mkdirSync: vi.fn(), }; }); - vi.mock('strip-json-comments', () => ({ default: vi.fn((content) => content), })); @@ -256,17 +253,11 @@ describe('isWorkspaceTrusted', () => { }); }); -import { getIdeTrust } from '@google/gemini-cli-core'; - -vi.mock('@google/gemini-cli-core', async (importOriginal) => { - const actual = await importOriginal>(); - return { - ...actual, - getIdeTrust: vi.fn(), - }; -}); - describe('isWorkspaceTrusted with IDE override', () => { + afterEach(() => { + ideContextStore.clear(); + }); + const mockSettings: Settings = { security: { folderTrust: { @@ -276,7 +267,7 @@ describe('isWorkspaceTrusted with IDE override', () => { }; it('should return true when ideTrust is true, ignoring config', () => { - vi.mocked(getIdeTrust).mockReturnValue(true); + ideContextStore.set({ workspaceState: { isTrusted: true } }); // Even if config says don't trust, ideTrust should win. vi.spyOn(fs, 'readFileSync').mockReturnValue( JSON.stringify({ [process.cwd()]: TrustLevel.DO_NOT_TRUST }), @@ -285,7 +276,7 @@ describe('isWorkspaceTrusted with IDE override', () => { }); it('should return false when ideTrust is false, ignoring config', () => { - vi.mocked(getIdeTrust).mockReturnValue(false); + ideContextStore.set({ workspaceState: { isTrusted: false } }); // Even if config says trust, ideTrust should win. vi.spyOn(fs, 'readFileSync').mockReturnValue( JSON.stringify({ [process.cwd()]: TrustLevel.TRUST_FOLDER }), @@ -294,7 +285,6 @@ describe('isWorkspaceTrusted with IDE override', () => { }); it('should fall back to config when ideTrust is undefined', () => { - vi.mocked(getIdeTrust).mockReturnValue(undefined); vi.spyOn(fs, 'existsSync').mockReturnValue(true); vi.spyOn(fs, 'readFileSync').mockReturnValue( JSON.stringify({ [process.cwd()]: TrustLevel.TRUST_FOLDER }), @@ -310,7 +300,7 @@ describe('isWorkspaceTrusted with IDE override', () => { }, }, }; - vi.mocked(getIdeTrust).mockReturnValue(false); + ideContextStore.set({ workspaceState: { isTrusted: false } }); expect(isWorkspaceTrusted(settings)).toBe(true); }); }); diff --git a/packages/cli/src/config/trustedFolders.ts b/packages/cli/src/config/trustedFolders.ts index 952110a772..01119104f5 100644 --- a/packages/cli/src/config/trustedFolders.ts +++ b/packages/cli/src/config/trustedFolders.ts @@ -10,7 +10,7 @@ import { homedir } from 'node:os'; import { getErrorMessage, isWithinRoot, - getIdeTrust, + ideContextStore, } from '@google/gemini-cli-core'; import type { Settings } from './settings.js'; import stripJsonComments from 'strip-json-comments'; @@ -182,7 +182,7 @@ export function isWorkspaceTrusted(settings: Settings): boolean | undefined { return true; } - const ideTrust = getIdeTrust(); + const ideTrust = ideContextStore.get()?.workspaceState?.isTrusted; if (ideTrust !== undefined) { return ideTrust; } diff --git a/packages/cli/src/core/initializer.ts b/packages/cli/src/core/initializer.ts index f304cfcec9..089e0fb505 100644 --- a/packages/cli/src/core/initializer.ts +++ b/packages/cli/src/core/initializer.ts @@ -4,7 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { type Config } from '@google/gemini-cli-core'; +import { + IdeClient, + IdeConnectionEvent, + IdeConnectionType, + logIdeConnection, + type Config, +} from '@google/gemini-cli-core'; import { type LoadedSettings } from '../config/settings.js'; import { performInitialAuth } from './auth.js'; import { validateTheme } from './theme.js'; @@ -36,6 +42,12 @@ export async function initializeApp( const shouldOpenAuthDialog = settings.merged.security?.auth?.selectedType === undefined || !!authError; + if (config.getIdeMode()) { + const ideClient = await IdeClient.getInstance(); + await ideClient.connect(); + logIdeConnection(config, new IdeConnectionEvent(IdeConnectionType.START)); + } + return { authError, themeError, diff --git a/packages/core/index.ts b/packages/core/index.ts index c78ddfc4d6..396b3b48f5 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -23,7 +23,6 @@ export { IdeConnectionType, ExtensionInstallEvent, } from './src/telemetry/types.js'; -export { getIdeTrust } from './src/utils/ide-trust.js'; export { makeFakeConfig } from './src/test-utils/config.js'; export * from './src/utils/pathReader.js'; export { ClearcutLogger } from './src/telemetry/clearcut-logger/clearcut-logger.js'; diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index 7321d112a6..ecece914a9 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -48,20 +48,14 @@ import { } from './models.js'; import { shouldAttemptBrowserLaunch } from '../utils/browser.js'; import type { MCPOAuthConfig } from '../mcp/oauth-provider.js'; -import { IdeClient } from '../ide/ide-client.js'; import { ideContextStore } from '../ide/ideContext.js'; import type { FileSystemService } from '../services/fileSystemService.js'; import { StandardFileSystemService } from '../services/fileSystemService.js'; import { logCliConfiguration, - logIdeConnection, logRipgrepFallback, } from '../telemetry/loggers.js'; -import { - IdeConnectionEvent, - IdeConnectionType, - RipgrepFallbackEvent, -} from '../telemetry/types.js'; +import { RipgrepFallbackEvent } from '../telemetry/types.js'; import type { FallbackModelHandler } from '../fallback/types.js'; import { ModelRouterService } from '../routing/modelRouterService.js'; import { OutputFormat } from '../output/types.js'; @@ -439,11 +433,6 @@ export class Config { } this.initialized = true; - if (this.getIdeMode()) { - await (await IdeClient.getInstance()).connect(); - logIdeConnection(this, new IdeConnectionEvent(IdeConnectionType.START)); - } - // Initialize centralized FileDiscoveryService this.getFileService(); if (this.getCheckpointingEnabled()) { diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index d8eaeb070b..21dd4f7d51 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -51,7 +51,6 @@ export * from './utils/errorParsing.js'; export * from './utils/workspaceContext.js'; export * from './utils/ignorePatterns.js'; export * from './utils/partUtils.js'; -export * from './utils/ide-trust.js'; export * from './utils/promptIdContext.js'; // Export services diff --git a/packages/core/src/utils/ide-trust.ts b/packages/core/src/utils/ide-trust.ts deleted file mode 100644 index c1ac801651..0000000000 --- a/packages/core/src/utils/ide-trust.ts +++ /dev/null @@ -1,15 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -import { ideContextStore } from '../ide/ideContext.js'; - -/** - * Gets the workspace trust from the IDE if available. - * @returns A boolean if the IDE provides a trust value, otherwise undefined. - */ -export function getIdeTrust(): boolean | undefined { - return ideContextStore.get()?.workspaceState?.isTrusted; -}