mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-16 08:10:46 -07:00
Use IdeClient directly instead of config.ideClient (#7627)
This commit is contained in:
committed by
GitHub
parent
45d494a8d8
commit
cb43bb9ca4
@@ -260,7 +260,7 @@ export class Config {
|
||||
private readonly folderTrustFeature: boolean;
|
||||
private readonly folderTrust: boolean;
|
||||
private ideMode: boolean;
|
||||
private ideClient!: IdeClient;
|
||||
|
||||
private inFallbackMode = false;
|
||||
private readonly maxSessionTurns: number;
|
||||
private readonly listExtensions: boolean;
|
||||
@@ -383,7 +383,12 @@ export class Config {
|
||||
throw Error('Config was already initialized');
|
||||
}
|
||||
this.initialized = true;
|
||||
this.ideClient = await IdeClient.getInstance();
|
||||
|
||||
if (this.getIdeMode()) {
|
||||
await (await IdeClient.getInstance()).connect();
|
||||
logIdeConnection(this, new IdeConnectionEvent(IdeConnectionType.START));
|
||||
}
|
||||
|
||||
// Initialize centralized FileDiscoveryService
|
||||
this.getFileService();
|
||||
if (this.getCheckpointingEnabled()) {
|
||||
@@ -762,20 +767,6 @@ export class Config {
|
||||
this.ideMode = value;
|
||||
}
|
||||
|
||||
async setIdeModeAndSyncConnection(value: boolean): Promise<void> {
|
||||
this.ideMode = value;
|
||||
if (value) {
|
||||
await this.ideClient.connect();
|
||||
logIdeConnection(this, new IdeConnectionEvent(IdeConnectionType.SESSION));
|
||||
} else {
|
||||
await this.ideClient.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
getIdeClient(): IdeClient {
|
||||
return this.ideClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current FileSystemService
|
||||
*/
|
||||
|
||||
@@ -65,7 +65,7 @@ function getRealPath(path: string): string {
|
||||
* Manages the connection to and interaction with the IDE server.
|
||||
*/
|
||||
export class IdeClient {
|
||||
private static instance: IdeClient;
|
||||
private static instancePromise: Promise<IdeClient> | null = null;
|
||||
private client: Client | undefined = undefined;
|
||||
private state: IDEConnectionState = {
|
||||
status: IDEConnectionStatus.Disconnected,
|
||||
@@ -81,19 +81,21 @@ export class IdeClient {
|
||||
|
||||
private constructor() {}
|
||||
|
||||
static async getInstance(): Promise<IdeClient> {
|
||||
if (!IdeClient.instance) {
|
||||
const client = new IdeClient();
|
||||
client.ideProcessInfo = await getIdeProcessInfo();
|
||||
client.currentIde = detectIde(client.ideProcessInfo);
|
||||
if (client.currentIde) {
|
||||
client.currentIdeDisplayName = getIdeInfo(
|
||||
client.currentIde,
|
||||
).displayName;
|
||||
}
|
||||
IdeClient.instance = client;
|
||||
static getInstance(): Promise<IdeClient> {
|
||||
if (!IdeClient.instancePromise) {
|
||||
IdeClient.instancePromise = (async () => {
|
||||
const client = new IdeClient();
|
||||
client.ideProcessInfo = await getIdeProcessInfo();
|
||||
client.currentIde = detectIde(client.ideProcessInfo);
|
||||
if (client.currentIde) {
|
||||
client.currentIdeDisplayName = getIdeInfo(
|
||||
client.currentIde,
|
||||
).displayName;
|
||||
}
|
||||
return client;
|
||||
})();
|
||||
}
|
||||
return IdeClient.instance;
|
||||
return IdeClient.instancePromise;
|
||||
}
|
||||
|
||||
addStatusChangeListener(listener: (state: IDEConnectionState) => void) {
|
||||
|
||||
@@ -10,7 +10,17 @@ const mockEnsureCorrectEdit = vi.hoisted(() => vi.fn());
|
||||
const mockGenerateJson = vi.hoisted(() => vi.fn());
|
||||
const mockOpenDiff = vi.hoisted(() => vi.fn());
|
||||
|
||||
import { IDEConnectionStatus } from '../ide/ide-client.js';
|
||||
import { IdeClient, IDEConnectionStatus } from '../ide/ide-client.js';
|
||||
|
||||
vi.mock('../ide/ide-client.js', () => ({
|
||||
IdeClient: {
|
||||
getInstance: vi.fn(),
|
||||
},
|
||||
IDEConnectionStatus: {
|
||||
Connected: 'connected',
|
||||
Disconnected: 'disconnected',
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('../utils/editCorrector.js', () => ({
|
||||
ensureCorrectEdit: mockEnsureCorrectEdit,
|
||||
@@ -70,7 +80,6 @@ describe('EditTool', () => {
|
||||
setApprovalMode: vi.fn(),
|
||||
getWorkspaceContext: () => createMockWorkspaceContext(rootDir),
|
||||
getFileSystemService: () => new StandardFileSystemService(),
|
||||
getIdeClient: () => undefined,
|
||||
getIdeMode: () => false,
|
||||
// getGeminiConfig: () => ({ apiKey: 'test-api-key' }), // This was not a real Config method
|
||||
// Add other properties/methods of Config if EditTool uses them
|
||||
@@ -878,8 +887,8 @@ describe('EditTool', () => {
|
||||
status: IDEConnectionStatus.Connected,
|
||||
}),
|
||||
};
|
||||
vi.mocked(IdeClient.getInstance).mockResolvedValue(ideClient);
|
||||
(mockConfig as any).getIdeMode = () => true;
|
||||
(mockConfig as any).getIdeClient = () => ideClient;
|
||||
});
|
||||
|
||||
it('should call ideClient.openDiff and update params on confirmation', async () => {
|
||||
|
||||
@@ -33,7 +33,7 @@ import type {
|
||||
ModifiableDeclarativeTool,
|
||||
ModifyContext,
|
||||
} from './modifiable-tool.js';
|
||||
import { IDEConnectionStatus } from '../ide/ide-client.js';
|
||||
import { IdeClient, IDEConnectionStatus } from '../ide/ide-client.js';
|
||||
|
||||
export function applyReplacement(
|
||||
currentContent: string | null,
|
||||
@@ -267,7 +267,7 @@ class EditToolInvocation implements ToolInvocation<EditToolParams, ToolResult> {
|
||||
'Proposed',
|
||||
DEFAULT_DIFF_OPTIONS,
|
||||
);
|
||||
const ideClient = this.config.getIdeClient();
|
||||
const ideClient = await IdeClient.getInstance();
|
||||
const ideConfirmation =
|
||||
this.config.getIdeMode() &&
|
||||
ideClient?.getConnectionStatus().status === IDEConnectionStatus.Connected
|
||||
|
||||
@@ -10,7 +10,17 @@ const mockFixLLMEditWithInstruction = vi.hoisted(() => vi.fn());
|
||||
const mockGenerateJson = vi.hoisted(() => vi.fn());
|
||||
const mockOpenDiff = vi.hoisted(() => vi.fn());
|
||||
|
||||
import { IDEConnectionStatus } from '../ide/ide-client.js';
|
||||
import { IdeClient, IDEConnectionStatus } from '../ide/ide-client.js';
|
||||
|
||||
vi.mock('../ide/ide-client.js', () => ({
|
||||
IdeClient: {
|
||||
getInstance: vi.fn(),
|
||||
},
|
||||
IDEConnectionStatus: {
|
||||
Connected: 'connected',
|
||||
Disconnected: 'disconnected',
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock('../utils/llm-edit-fixer.js', () => ({
|
||||
FixLLMEditWithInstruction: mockFixLLMEditWithInstruction,
|
||||
@@ -75,7 +85,6 @@ describe('SmartEditTool', () => {
|
||||
setApprovalMode: vi.fn(),
|
||||
getWorkspaceContext: () => createMockWorkspaceContext(rootDir),
|
||||
getFileSystemService: () => new StandardFileSystemService(),
|
||||
getIdeClient: () => undefined,
|
||||
getIdeMode: () => false,
|
||||
getApiKey: () => 'test-api-key',
|
||||
getModel: () => 'test-model',
|
||||
@@ -449,8 +458,8 @@ describe('SmartEditTool', () => {
|
||||
status: IDEConnectionStatus.Connected,
|
||||
}),
|
||||
};
|
||||
vi.mocked(IdeClient.getInstance).mockResolvedValue(ideClient);
|
||||
(mockConfig as any).getIdeMode = () => true;
|
||||
(mockConfig as any).getIdeClient = () => ideClient;
|
||||
});
|
||||
|
||||
it('should call ideClient.openDiff and update params on confirmation', async () => {
|
||||
|
||||
@@ -28,7 +28,7 @@ import {
|
||||
type ModifiableDeclarativeTool,
|
||||
type ModifyContext,
|
||||
} from './modifiable-tool.js';
|
||||
import { IDEConnectionStatus } from '../ide/ide-client.js';
|
||||
import { IdeClient, IDEConnectionStatus } from '../ide/ide-client.js';
|
||||
import { FixLLMEditWithInstruction } from '../utils/llm-edit-fixer.js';
|
||||
|
||||
export function applyReplacement(
|
||||
@@ -526,7 +526,7 @@ class EditToolInvocation implements ToolInvocation<EditToolParams, ToolResult> {
|
||||
'Proposed',
|
||||
DEFAULT_DIFF_OPTIONS,
|
||||
);
|
||||
const ideClient = this.config.getIdeClient();
|
||||
const ideClient = await IdeClient.getInstance();
|
||||
const ideConfirmation =
|
||||
this.config.getIdeMode() &&
|
||||
ideClient?.getConnectionStatus().status === IDEConnectionStatus.Connected
|
||||
|
||||
@@ -39,7 +39,11 @@ const rootDir = path.resolve(os.tmpdir(), 'gemini-cli-test-root');
|
||||
// --- MOCKS ---
|
||||
vi.mock('../core/client.js');
|
||||
vi.mock('../utils/editCorrector.js');
|
||||
|
||||
vi.mock('../ide/ide-client.js', () => ({
|
||||
IdeClient: {
|
||||
getInstance: vi.fn(),
|
||||
},
|
||||
}));
|
||||
let mockGeminiClientInstance: Mocked<GeminiClient>;
|
||||
const mockEnsureCorrectEdit = vi.fn<typeof ensureCorrectEdit>();
|
||||
const mockEnsureCorrectFileContent = vi.fn<typeof ensureCorrectFileContent>();
|
||||
@@ -58,7 +62,6 @@ const mockConfigInternal = {
|
||||
setApprovalMode: vi.fn(),
|
||||
getGeminiClient: vi.fn(), // Initialize as a plain mock function
|
||||
getFileSystemService: () => fsService,
|
||||
getIdeClient: vi.fn(),
|
||||
getIdeMode: vi.fn(() => false),
|
||||
getWorkspaceContext: () => createMockWorkspaceContext(rootDir),
|
||||
getApiKey: () => 'test-key',
|
||||
@@ -120,14 +123,6 @@ describe('WriteFileTool', () => {
|
||||
mockConfigInternal.getGeminiClient.mockReturnValue(
|
||||
mockGeminiClientInstance,
|
||||
);
|
||||
mockConfigInternal.getIdeClient.mockReturnValue({
|
||||
openDiff: vi.fn(),
|
||||
closeDiff: vi.fn(),
|
||||
getIdeContext: vi.fn(),
|
||||
subscribeToIdeContext: vi.fn(),
|
||||
isCodeTrackerEnabled: vi.fn(),
|
||||
getTrackedCode: vi.fn(),
|
||||
});
|
||||
|
||||
tool = new WriteFileTool(mockConfig);
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ import type {
|
||||
ModifiableDeclarativeTool,
|
||||
ModifyContext,
|
||||
} from './modifiable-tool.js';
|
||||
import { IDEConnectionStatus } from '../ide/ide-client.js';
|
||||
import { IdeClient, IDEConnectionStatus } from '../ide/ide-client.js';
|
||||
import { logFileOperation } from '../telemetry/loggers.js';
|
||||
import { FileOperationEvent } from '../telemetry/types.js';
|
||||
import { FileOperation } from '../telemetry/metrics.js';
|
||||
@@ -193,7 +193,7 @@ class WriteFileToolInvocation extends BaseToolInvocation<
|
||||
DEFAULT_DIFF_OPTIONS,
|
||||
);
|
||||
|
||||
const ideClient = this.config.getIdeClient();
|
||||
const ideClient = await IdeClient.getInstance();
|
||||
const ideConfirmation =
|
||||
this.config.getIdeMode() &&
|
||||
ideClient.getConnectionStatus().status === IDEConnectionStatus.Connected
|
||||
|
||||
Reference in New Issue
Block a user