diff options
Diffstat (limited to 'packages/cli/src')
| -rw-r--r-- | packages/cli/src/config/config.test.ts | 41 | ||||
| -rw-r--r-- | packages/cli/src/config/config.ts | 12 | ||||
| -rw-r--r-- | packages/cli/src/config/extension.test.ts | 55 | ||||
| -rw-r--r-- | packages/cli/src/config/extension.ts | 16 |
4 files changed, 99 insertions, 25 deletions
diff --git a/packages/cli/src/config/config.test.ts b/packages/cli/src/config/config.test.ts index 269b4c81..b8c617bb 100644 --- a/packages/cli/src/config/config.test.ts +++ b/packages/cli/src/config/config.test.ts @@ -58,8 +58,11 @@ vi.mock('@gemini-cli/core', async () => { setUserMemory: vi.fn(), setGeminiMdFileCount: vi.fn(), })), - loadServerHierarchicalMemory: vi.fn(() => - Promise.resolve({ memoryContent: '', fileCount: 0 }), + loadServerHierarchicalMemory: vi.fn((cwd, debug, extensionPaths) => + Promise.resolve({ + memoryContent: extensionPaths?.join(',') || '', + fileCount: extensionPaths?.length || 0, + }), ), }; }); @@ -228,15 +231,31 @@ describe('Hierarchical Memory Loading (config.ts) - Placeholder Suite', () => { vi.restoreAllMocks(); }); - it('should have a placeholder test to ensure test file validity', () => { - // This test suite is currently a placeholder. - // Tests for loadHierarchicalGeminiMemory were removed due to persistent - // and complex mocking issues with Node.js built-in modules (like 'os') - // in the Vitest environment. These issues prevented consistent and reliable - // testing of file system interactions dependent on os.homedir(). - // The core logic was implemented as per specification, but the tests - // could not be stabilized. - expect(true).toBe(true); + it('should pass extension context file paths to loadServerHierarchicalMemory', async () => { + process.argv = ['node', 'script.js']; + const settings: Settings = {}; + const extensions = [ + { + name: 'ext1', + version: '1.0.0', + contextFileName: '/path/to/ext1/gemini.md', + }, + { + name: 'ext2', + version: '1.0.0', + }, + { + name: 'ext3', + version: '1.0.0', + contextFileName: '/path/to/ext3/gemini.md', + }, + ]; + await loadCliConfig(settings, extensions, [], 'session-id'); + expect(ServerConfig.loadServerHierarchicalMemory).toHaveBeenCalledWith( + expect.any(String), + false, + ['/path/to/ext1/gemini.md', '/path/to/ext3/gemini.md'], + ); }); // NOTE TO FUTURE DEVELOPERS: diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index 1c8ef625..3a602ef8 100644 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -112,6 +112,7 @@ async function parseArguments(): Promise<CliArgs> { export async function loadHierarchicalGeminiMemory( currentWorkingDirectory: string, debugMode: boolean, + extensionContextFilePaths: string[] = [], ): Promise<{ memoryContent: string; fileCount: number }> { if (debugMode) { logger.debug( @@ -120,7 +121,11 @@ export async function loadHierarchicalGeminiMemory( } // Directly call the server function. // The server function will use its own homedir() for the global path. - return loadServerHierarchicalMemory(currentWorkingDirectory, debugMode); + return loadServerHierarchicalMemory( + currentWorkingDirectory, + debugMode, + extensionContextFilePaths, + ); } export async function loadCliConfig( @@ -145,10 +150,15 @@ export async function loadCliConfig( setServerGeminiMdFilename(getCurrentGeminiMdFilename()); } + const extensionContextFilePaths = extensions + .map((e) => e.contextFileName) + .filter((p): p is string => !!p); + // Call the (now wrapper) loadHierarchicalGeminiMemory which calls the server's version const { memoryContent, fileCount } = await loadHierarchicalGeminiMemory( process.cwd(), debugMode, + extensionContextFilePaths, ); const contentGeneratorConfig = await createContentGeneratorConfig(argv); diff --git a/packages/cli/src/config/extension.test.ts b/packages/cli/src/config/extension.test.ts index 462024bf..6e0d1658 100644 --- a/packages/cli/src/config/extension.test.ts +++ b/packages/cli/src/config/extension.test.ts @@ -41,28 +41,47 @@ describe('loadExtensions', () => { fs.rmSync(tempHomeDir, { recursive: true, force: true }); }); - it('should deduplicate extensions, prioritizing the workspace directory', () => { - // Create extensions in the workspace + it('should load context file path when gemini.md is present', () => { const workspaceExtensionsDir = path.join( tempWorkspaceDir, EXTENSIONS_DIRECTORY_NAME, ); fs.mkdirSync(workspaceExtensionsDir, { recursive: true }); - createExtension(workspaceExtensionsDir, 'ext1', '1.0.0'); + createExtension(workspaceExtensionsDir, 'ext1', '1.0.0', true); createExtension(workspaceExtensionsDir, 'ext2', '2.0.0'); - // Create extensions in the home directory - const homeExtensionsDir = path.join(tempHomeDir, EXTENSIONS_DIRECTORY_NAME); - fs.mkdirSync(homeExtensionsDir, { recursive: true }); - createExtension(homeExtensionsDir, 'ext1', '1.1.0'); // Duplicate that should be ignored - createExtension(homeExtensionsDir, 'ext3', '3.0.0'); + const extensions = loadExtensions(tempWorkspaceDir); + + expect(extensions).toHaveLength(2); + const ext1 = extensions.find((e) => e.name === 'ext1'); + const ext2 = extensions.find((e) => e.name === 'ext2'); + expect(ext1?.contextFileName).toBe( + path.join(workspaceExtensionsDir, 'ext1', 'gemini.md'), + ); + expect(ext2?.contextFileName).toBeUndefined(); + }); + + it('should load context file path from the extension config', () => { + const workspaceExtensionsDir = path.join( + tempWorkspaceDir, + EXTENSIONS_DIRECTORY_NAME, + ); + fs.mkdirSync(workspaceExtensionsDir, { recursive: true }); + createExtension( + workspaceExtensionsDir, + 'ext1', + '1.0.0', + false, + 'my-context.md', + ); const extensions = loadExtensions(tempWorkspaceDir); - expect(extensions).toHaveLength(3); - expect(extensions.find((e) => e.name === 'ext1')?.version).toBe('1.0.0'); // Workspace version should be kept - expect(extensions.find((e) => e.name === 'ext2')?.version).toBe('2.0.0'); - expect(extensions.find((e) => e.name === 'ext3')?.version).toBe('3.0.0'); + expect(extensions).toHaveLength(1); + const ext1 = extensions.find((e) => e.name === 'ext1'); + expect(ext1?.contextFileName).toBe( + path.join(workspaceExtensionsDir, 'ext1', 'my-context.md'), + ); }); }); @@ -70,11 +89,21 @@ function createExtension( extensionsDir: string, name: string, version: string, + addContextFile = false, + contextFileName?: string, ): void { const extDir = path.join(extensionsDir, name); fs.mkdirSync(extDir); fs.writeFileSync( path.join(extDir, EXTENSIONS_CONFIG_FILENAME), - JSON.stringify({ name, version }), + JSON.stringify({ name, version, contextFileName }), ); + + if (addContextFile) { + fs.writeFileSync(path.join(extDir, 'gemini.md'), 'context'); + } + + if (contextFileName) { + fs.writeFileSync(path.join(extDir, contextFileName), 'context'); + } } diff --git a/packages/cli/src/config/extension.ts b/packages/cli/src/config/extension.ts index 641cfcb5..9dd33e1b 100644 --- a/packages/cli/src/config/extension.ts +++ b/packages/cli/src/config/extension.ts @@ -74,6 +74,22 @@ function loadExtensionsFromDir(dir: string): ExtensionConfig[] { ); continue; } + + if (extensionConfig.contextFileName) { + const contextFilePath = path.join( + extensionDir, + extensionConfig.contextFileName, + ); + if (fs.existsSync(contextFilePath)) { + extensionConfig.contextFileName = contextFilePath; + } + } else { + const contextFilePath = path.join(extensionDir, 'gemini.md'); + if (fs.existsSync(contextFilePath)) { + extensionConfig.contextFileName = contextFilePath; + } + } + extensions.push(extensionConfig); } catch (e) { console.error( |
