mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-21 02:24:09 -07:00
Add ExtensionLoader interface, use that on Config object (#12116)
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { EventEmitter } from 'node:events';
|
||||
import type { GeminiCLIExtension } from '../config/config.js';
|
||||
|
||||
export interface ExtensionLoader {
|
||||
getExtensions(): GeminiCLIExtension[];
|
||||
|
||||
extensionEvents(): EventEmitter<ExtensionEvents>;
|
||||
}
|
||||
|
||||
export interface ExtensionEvents {
|
||||
extensionEnabled: ExtensionEnableEvent[];
|
||||
extensionDisabled: ExtensionDisableEvent[];
|
||||
extensionLoaded: ExtensionLoadEvent[];
|
||||
extensionUnloaded: ExtensionUnloadEvent[];
|
||||
extensionInstalled: ExtensionInstallEvent[];
|
||||
extensionUninstalled: ExtensionUninstallEvent[];
|
||||
extensionUpdated: ExtensionUpdateEvent[];
|
||||
}
|
||||
|
||||
interface BaseExtensionEvent {
|
||||
extension: GeminiCLIExtension;
|
||||
}
|
||||
export type ExtensionDisableEvent = BaseExtensionEvent;
|
||||
export type ExtensionEnableEvent = BaseExtensionEvent;
|
||||
export type ExtensionInstallEvent = BaseExtensionEvent;
|
||||
export type ExtensionLoadEvent = BaseExtensionEvent;
|
||||
export type ExtensionUnloadEvent = BaseExtensionEvent;
|
||||
export type ExtensionUninstallEvent = BaseExtensionEvent;
|
||||
export type ExtensionUpdateEvent = BaseExtensionEvent;
|
||||
|
||||
export class SimpleExtensionLoader implements ExtensionLoader {
|
||||
private _eventEmitter = new EventEmitter<ExtensionEvents>();
|
||||
constructor(private readonly extensions: GeminiCLIExtension[]) {}
|
||||
|
||||
extensionEvents(): EventEmitter<ExtensionEvents> {
|
||||
return this._eventEmitter;
|
||||
}
|
||||
|
||||
getExtensions(): GeminiCLIExtension[] {
|
||||
return this.extensions;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
import { FileDiscoveryService } from '../services/fileDiscoveryService.js';
|
||||
import { GEMINI_DIR } from './paths.js';
|
||||
import type { GeminiCLIExtension } from '../config/config.js';
|
||||
import { SimpleExtensionLoader } from './extensionLoader.js';
|
||||
|
||||
vi.mock('os', async (importOriginal) => {
|
||||
const actualOs = await importOriginal<typeof os>();
|
||||
@@ -88,7 +89,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||
[],
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
false, // untrusted
|
||||
);
|
||||
|
||||
@@ -117,7 +118,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||
[],
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
false, // untrusted
|
||||
);
|
||||
|
||||
@@ -133,7 +134,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||
[],
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
);
|
||||
|
||||
@@ -155,7 +156,7 @@ describe('loadServerHierarchicalMemory', () => {
|
||||
[],
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
);
|
||||
|
||||
@@ -182,7 +183,7 @@ default context content
|
||||
[],
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
);
|
||||
|
||||
@@ -213,7 +214,7 @@ custom context content
|
||||
[],
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
);
|
||||
|
||||
@@ -248,7 +249,7 @@ cwd context content
|
||||
[],
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
);
|
||||
|
||||
@@ -280,7 +281,7 @@ Subdir custom memory
|
||||
[],
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
);
|
||||
|
||||
@@ -312,7 +313,7 @@ Src directory memory
|
||||
[],
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
);
|
||||
|
||||
@@ -356,7 +357,7 @@ Subdir memory
|
||||
[],
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
);
|
||||
|
||||
@@ -409,7 +410,7 @@ Subdir memory
|
||||
[],
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
'tree',
|
||||
{
|
||||
@@ -445,7 +446,7 @@ My code memory
|
||||
[],
|
||||
true,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
'tree', // importFormat
|
||||
{
|
||||
@@ -467,7 +468,7 @@ My code memory
|
||||
[],
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
);
|
||||
|
||||
@@ -489,12 +490,12 @@ My code memory
|
||||
[],
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[
|
||||
new SimpleExtensionLoader([
|
||||
{
|
||||
contextFiles: [extensionFilePath],
|
||||
isActive: true,
|
||||
} as GeminiCLIExtension,
|
||||
], // extensions
|
||||
]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
);
|
||||
|
||||
@@ -521,7 +522,7 @@ Extension memory content
|
||||
[includedDir],
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
);
|
||||
|
||||
@@ -556,7 +557,7 @@ included directory memory
|
||||
createdFiles.map((f) => path.dirname(f)),
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
);
|
||||
|
||||
@@ -591,7 +592,7 @@ included directory memory
|
||||
[childDir, parentDir], // Deliberately include duplicates
|
||||
false,
|
||||
new FileDiscoveryService(projectRoot),
|
||||
[], // extensions
|
||||
new SimpleExtensionLoader([]),
|
||||
DEFAULT_FOLDER_TRUST,
|
||||
);
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import { processImports } from './memoryImportProcessor.js';
|
||||
import type { FileFilteringOptions } from '../config/constants.js';
|
||||
import { DEFAULT_MEMORY_FILE_FILTERING_OPTIONS } from '../config/constants.js';
|
||||
import { GEMINI_DIR } from './paths.js';
|
||||
import type { GeminiCLIExtension } from '../config/config.js';
|
||||
import type { ExtensionLoader } from './extensionLoader.js';
|
||||
import { debugLogger } from './debugLogger.js';
|
||||
|
||||
// Simple console logger, similar to the one previously in CLI's config.ts
|
||||
@@ -338,7 +338,7 @@ export async function loadServerHierarchicalMemory(
|
||||
includeDirectoriesToReadGemini: readonly string[],
|
||||
debugMode: boolean,
|
||||
fileService: FileDiscoveryService,
|
||||
extensions: GeminiCLIExtension[],
|
||||
extensionLoader: ExtensionLoader,
|
||||
folderTrust: boolean,
|
||||
importFormat: 'flat' | 'tree' = 'tree',
|
||||
fileFilteringOptions?: FileFilteringOptions,
|
||||
@@ -365,7 +365,8 @@ export async function loadServerHierarchicalMemory(
|
||||
|
||||
// Add extension file paths separately since they may be conditionally enabled.
|
||||
filePaths.push(
|
||||
...extensions
|
||||
...extensionLoader
|
||||
.getExtensions()
|
||||
.filter((ext) => ext.isActive)
|
||||
.flatMap((ext) => ext.contextFiles),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user