mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-03 16:34:31 -07:00
Add extensionRegistryURI setting to change where the registry is read from (#20463)
This commit is contained in:
@@ -4,7 +4,12 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { fetchWithTimeout } from '@google/gemini-cli-core';
|
||||
import * as fs from 'node:fs/promises';
|
||||
import {
|
||||
fetchWithTimeout,
|
||||
resolveToRealPath,
|
||||
isPrivateIp,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { AsyncFzf } from 'fzf';
|
||||
|
||||
export interface RegistryExtension {
|
||||
@@ -29,12 +34,19 @@ export interface RegistryExtension {
|
||||
}
|
||||
|
||||
export class ExtensionRegistryClient {
|
||||
private static readonly REGISTRY_URL =
|
||||
static readonly DEFAULT_REGISTRY_URL =
|
||||
'https://geminicli.com/extensions.json';
|
||||
private static readonly FETCH_TIMEOUT_MS = 10000; // 10 seconds
|
||||
|
||||
private static fetchPromise: Promise<RegistryExtension[]> | null = null;
|
||||
|
||||
private readonly registryURI: string;
|
||||
|
||||
constructor(registryURI?: string) {
|
||||
this.registryURI =
|
||||
registryURI || ExtensionRegistryClient.DEFAULT_REGISTRY_URL;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
static resetCache() {
|
||||
ExtensionRegistryClient.fetchPromise = null;
|
||||
@@ -97,18 +109,34 @@ export class ExtensionRegistryClient {
|
||||
return ExtensionRegistryClient.fetchPromise;
|
||||
}
|
||||
|
||||
const uri = this.registryURI;
|
||||
ExtensionRegistryClient.fetchPromise = (async () => {
|
||||
try {
|
||||
const response = await fetchWithTimeout(
|
||||
ExtensionRegistryClient.REGISTRY_URL,
|
||||
ExtensionRegistryClient.FETCH_TIMEOUT_MS,
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch extensions: ${response.statusText}`);
|
||||
}
|
||||
if (uri.startsWith('http')) {
|
||||
if (isPrivateIp(uri)) {
|
||||
throw new Error(
|
||||
'Private IP addresses are not allowed for the extension registry.',
|
||||
);
|
||||
}
|
||||
const response = await fetchWithTimeout(
|
||||
uri,
|
||||
ExtensionRegistryClient.FETCH_TIMEOUT_MS,
|
||||
);
|
||||
if (!response.ok) {
|
||||
throw new Error(
|
||||
`Failed to fetch extensions: ${response.statusText}`,
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
return (await response.json()) as RegistryExtension[];
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
return (await response.json()) as RegistryExtension[];
|
||||
} else {
|
||||
// Handle local file path
|
||||
const filePath = resolveToRealPath(uri);
|
||||
const content = await fs.readFile(filePath, 'utf-8');
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
|
||||
return JSON.parse(content) as RegistryExtension[];
|
||||
}
|
||||
} catch (error) {
|
||||
ExtensionRegistryClient.fetchPromise = null;
|
||||
throw error;
|
||||
|
||||
Reference in New Issue
Block a user