Move IdeClient.connect() to initializeApp(). (#8282)

This commit is contained in:
Tommaso Sciortino
2025-09-11 13:07:57 -07:00
committed by GitHub
parent 5237c37c81
commit ea2d551dd2
7 changed files with 32 additions and 58 deletions
+16 -26
View File
@@ -4,17 +4,8 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
// Mock 'os' first.
import * as osActual from 'node:os'; import * as osActual from 'node:os';
vi.mock('os', async (importOriginal) => { import { ideContextStore } from '@google/gemini-cli-core';
const actualOs = await importOriginal<typeof osActual>();
return {
...actualOs,
homedir: vi.fn(() => '/mock/home/user'),
platform: vi.fn(() => 'linux'),
};
});
import { import {
describe, describe,
it, it,
@@ -28,7 +19,6 @@ import {
import * as fs from 'node:fs'; import * as fs from 'node:fs';
import stripJsonComments from 'strip-json-comments'; import stripJsonComments from 'strip-json-comments';
import * as path from 'node:path'; import * as path from 'node:path';
import { import {
loadTrustedFolders, loadTrustedFolders,
USER_TRUSTED_FOLDERS_PATH, USER_TRUSTED_FOLDERS_PATH,
@@ -37,6 +27,14 @@ import {
} from './trustedFolders.js'; } from './trustedFolders.js';
import type { Settings } from './settings.js'; import type { Settings } from './settings.js';
vi.mock('os', async (importOriginal) => {
const actualOs = await importOriginal<typeof osActual>();
return {
...actualOs,
homedir: vi.fn(() => '/mock/home/user'),
platform: vi.fn(() => 'linux'),
};
});
vi.mock('fs', async (importOriginal) => { vi.mock('fs', async (importOriginal) => {
const actualFs = await importOriginal<typeof fs>(); const actualFs = await importOriginal<typeof fs>();
return { return {
@@ -47,7 +45,6 @@ vi.mock('fs', async (importOriginal) => {
mkdirSync: vi.fn(), mkdirSync: vi.fn(),
}; };
}); });
vi.mock('strip-json-comments', () => ({ vi.mock('strip-json-comments', () => ({
default: vi.fn((content) => content), 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<Record<string, unknown>>();
return {
...actual,
getIdeTrust: vi.fn(),
};
});
describe('isWorkspaceTrusted with IDE override', () => { describe('isWorkspaceTrusted with IDE override', () => {
afterEach(() => {
ideContextStore.clear();
});
const mockSettings: Settings = { const mockSettings: Settings = {
security: { security: {
folderTrust: { folderTrust: {
@@ -276,7 +267,7 @@ describe('isWorkspaceTrusted with IDE override', () => {
}; };
it('should return true when ideTrust is true, ignoring config', () => { 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. // Even if config says don't trust, ideTrust should win.
vi.spyOn(fs, 'readFileSync').mockReturnValue( vi.spyOn(fs, 'readFileSync').mockReturnValue(
JSON.stringify({ [process.cwd()]: TrustLevel.DO_NOT_TRUST }), 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', () => { 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. // Even if config says trust, ideTrust should win.
vi.spyOn(fs, 'readFileSync').mockReturnValue( vi.spyOn(fs, 'readFileSync').mockReturnValue(
JSON.stringify({ [process.cwd()]: TrustLevel.TRUST_FOLDER }), 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', () => { it('should fall back to config when ideTrust is undefined', () => {
vi.mocked(getIdeTrust).mockReturnValue(undefined);
vi.spyOn(fs, 'existsSync').mockReturnValue(true); vi.spyOn(fs, 'existsSync').mockReturnValue(true);
vi.spyOn(fs, 'readFileSync').mockReturnValue( vi.spyOn(fs, 'readFileSync').mockReturnValue(
JSON.stringify({ [process.cwd()]: TrustLevel.TRUST_FOLDER }), 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); expect(isWorkspaceTrusted(settings)).toBe(true);
}); });
}); });
+2 -2
View File
@@ -10,7 +10,7 @@ import { homedir } from 'node:os';
import { import {
getErrorMessage, getErrorMessage,
isWithinRoot, isWithinRoot,
getIdeTrust, ideContextStore,
} from '@google/gemini-cli-core'; } from '@google/gemini-cli-core';
import type { Settings } from './settings.js'; import type { Settings } from './settings.js';
import stripJsonComments from 'strip-json-comments'; import stripJsonComments from 'strip-json-comments';
@@ -182,7 +182,7 @@ export function isWorkspaceTrusted(settings: Settings): boolean | undefined {
return true; return true;
} }
const ideTrust = getIdeTrust(); const ideTrust = ideContextStore.get()?.workspaceState?.isTrusted;
if (ideTrust !== undefined) { if (ideTrust !== undefined) {
return ideTrust; return ideTrust;
} }
+13 -1
View File
@@ -4,7 +4,13 @@
* SPDX-License-Identifier: Apache-2.0 * 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 { type LoadedSettings } from '../config/settings.js';
import { performInitialAuth } from './auth.js'; import { performInitialAuth } from './auth.js';
import { validateTheme } from './theme.js'; import { validateTheme } from './theme.js';
@@ -36,6 +42,12 @@ export async function initializeApp(
const shouldOpenAuthDialog = const shouldOpenAuthDialog =
settings.merged.security?.auth?.selectedType === undefined || !!authError; 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 { return {
authError, authError,
themeError, themeError,
-1
View File
@@ -23,7 +23,6 @@ export {
IdeConnectionType, IdeConnectionType,
ExtensionInstallEvent, ExtensionInstallEvent,
} from './src/telemetry/types.js'; } from './src/telemetry/types.js';
export { getIdeTrust } from './src/utils/ide-trust.js';
export { makeFakeConfig } from './src/test-utils/config.js'; export { makeFakeConfig } from './src/test-utils/config.js';
export * from './src/utils/pathReader.js'; export * from './src/utils/pathReader.js';
export { ClearcutLogger } from './src/telemetry/clearcut-logger/clearcut-logger.js'; export { ClearcutLogger } from './src/telemetry/clearcut-logger/clearcut-logger.js';
+1 -12
View File
@@ -48,20 +48,14 @@ import {
} from './models.js'; } from './models.js';
import { shouldAttemptBrowserLaunch } from '../utils/browser.js'; import { shouldAttemptBrowserLaunch } from '../utils/browser.js';
import type { MCPOAuthConfig } from '../mcp/oauth-provider.js'; import type { MCPOAuthConfig } from '../mcp/oauth-provider.js';
import { IdeClient } from '../ide/ide-client.js';
import { ideContextStore } from '../ide/ideContext.js'; import { ideContextStore } from '../ide/ideContext.js';
import type { FileSystemService } from '../services/fileSystemService.js'; import type { FileSystemService } from '../services/fileSystemService.js';
import { StandardFileSystemService } from '../services/fileSystemService.js'; import { StandardFileSystemService } from '../services/fileSystemService.js';
import { import {
logCliConfiguration, logCliConfiguration,
logIdeConnection,
logRipgrepFallback, logRipgrepFallback,
} from '../telemetry/loggers.js'; } from '../telemetry/loggers.js';
import { import { RipgrepFallbackEvent } from '../telemetry/types.js';
IdeConnectionEvent,
IdeConnectionType,
RipgrepFallbackEvent,
} from '../telemetry/types.js';
import type { FallbackModelHandler } from '../fallback/types.js'; import type { FallbackModelHandler } from '../fallback/types.js';
import { ModelRouterService } from '../routing/modelRouterService.js'; import { ModelRouterService } from '../routing/modelRouterService.js';
import { OutputFormat } from '../output/types.js'; import { OutputFormat } from '../output/types.js';
@@ -439,11 +433,6 @@ export class Config {
} }
this.initialized = true; this.initialized = true;
if (this.getIdeMode()) {
await (await IdeClient.getInstance()).connect();
logIdeConnection(this, new IdeConnectionEvent(IdeConnectionType.START));
}
// Initialize centralized FileDiscoveryService // Initialize centralized FileDiscoveryService
this.getFileService(); this.getFileService();
if (this.getCheckpointingEnabled()) { if (this.getCheckpointingEnabled()) {
-1
View File
@@ -51,7 +51,6 @@ export * from './utils/errorParsing.js';
export * from './utils/workspaceContext.js'; export * from './utils/workspaceContext.js';
export * from './utils/ignorePatterns.js'; export * from './utils/ignorePatterns.js';
export * from './utils/partUtils.js'; export * from './utils/partUtils.js';
export * from './utils/ide-trust.js';
export * from './utils/promptIdContext.js'; export * from './utils/promptIdContext.js';
// Export services // Export services
-15
View File
@@ -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;
}