feat(ide): Read IDE info from discovery file (#8760)

This commit is contained in:
Shreya Keshive
2025-09-21 20:54:18 -04:00
committed by GitHub
parent b4455af306
commit 8fdb61aabf
5 changed files with 89 additions and 69 deletions
+27 -18
View File
@@ -60,8 +60,8 @@ type StdioConfig = {
type ConnectionConfig = {
port?: string;
stdio?: StdioConfig;
authToken?: string;
stdio?: StdioConfig;
};
function getRealPath(path: string): string {
@@ -87,6 +87,9 @@ export class IdeClient {
};
private currentIde: IdeInfo | undefined;
private ideProcessInfo: { pid: number; command: string } | undefined;
private connectionConfig:
| (ConnectionConfig & { workspacePath?: string; ideInfo?: IdeInfo })
| undefined;
private authToken: string | undefined;
private diffResponses = new Map<string, (result: DiffUpdateResult) => void>();
private statusListeners = new Set<(state: IDEConnectionState) => void>();
@@ -106,7 +109,11 @@ export class IdeClient {
IdeClient.instancePromise = (async () => {
const client = new IdeClient();
client.ideProcessInfo = await getIdeProcessInfo();
client.currentIde = detectIde(client.ideProcessInfo);
client.connectionConfig = await client.getConnectionConfigFromFile();
client.currentIde = detectIde(
client.ideProcessInfo,
client.connectionConfig?.ideInfo,
);
return client;
})();
}
@@ -141,17 +148,16 @@ export class IdeClient {
this.setState(IDEConnectionStatus.Connecting);
const configFromFile = await this.getConnectionConfigFromFile();
if (configFromFile?.authToken) {
this.authToken = configFromFile.authToken;
this.connectionConfig = await this.getConnectionConfigFromFile();
if (this.connectionConfig?.authToken) {
this.authToken = this.connectionConfig.authToken;
}
const workspacePath =
configFromFile?.workspacePath ??
this.connectionConfig?.workspacePath ??
process.env['GEMINI_CLI_IDE_WORKSPACE_PATH'];
const { isValid, error } = IdeClient.validateWorkspacePath(
workspacePath,
this.currentIde.displayName,
process.cwd(),
);
@@ -160,18 +166,18 @@ export class IdeClient {
return;
}
if (configFromFile) {
if (configFromFile.port) {
if (this.connectionConfig) {
if (this.connectionConfig.port) {
const connected = await this.establishHttpConnection(
configFromFile.port,
this.connectionConfig.port,
);
if (connected) {
return;
}
}
if (configFromFile.stdio) {
if (this.connectionConfig.stdio) {
const connected = await this.establishStdioConnection(
configFromFile.stdio,
this.connectionConfig.stdio,
);
if (connected) {
return;
@@ -494,20 +500,19 @@ export class IdeClient {
static validateWorkspacePath(
ideWorkspacePath: string | undefined,
currentIdeDisplayName: string | undefined,
cwd: string,
): { isValid: boolean; error?: string } {
if (ideWorkspacePath === undefined) {
return {
isValid: false,
error: `Failed to connect to IDE companion extension in ${currentIdeDisplayName}. Please ensure the extension is running. To install the extension, run /ide install.`,
error: `Failed to connect to IDE companion extension. Please ensure the extension is running. To install the extension, run /ide install.`,
};
}
if (ideWorkspacePath === '') {
return {
isValid: false,
error: `To use this feature, please open a workspace folder in ${currentIdeDisplayName} and try again.`,
error: `To use this feature, please open a workspace folder in your IDE and try again.`,
};
}
@@ -521,7 +526,7 @@ export class IdeClient {
if (!isWithinWorkspace) {
return {
isValid: false,
error: `Directory mismatch. Gemini CLI is running in a different location than the open workspace in ${currentIdeDisplayName}. Please run the CLI from one of the following directories: ${ideWorkspacePaths.join(
error: `Directory mismatch. Gemini CLI is running in a different location than the open workspace in the IDE. Please run the CLI from one of the following directories: ${ideWorkspacePaths.join(
', ',
)}`,
};
@@ -564,7 +569,8 @@ export class IdeClient {
}
private async getConnectionConfigFromFile(): Promise<
(ConnectionConfig & { workspacePath?: string }) | undefined
| (ConnectionConfig & { workspacePath?: string; ideInfo?: IdeInfo })
| undefined
> {
if (!this.ideProcessInfo) {
return undefined;
@@ -594,6 +600,10 @@ export class IdeClient {
return undefined;
}
if (!portFiles) {
return undefined;
}
const fileRegex = new RegExp(
`^gemini-ide-server-${this.ideProcessInfo.pid}-\\d+\\.json$`,
);
@@ -630,7 +640,6 @@ export class IdeClient {
}
const { isValid } = IdeClient.validateWorkspacePath(
content.workspacePath,
this.currentIde?.displayName,
process.cwd(),
);
return isValid;