fix(cli) : fixed bug #8310 where /memory refresh will create discrepancies with initial memory load ignoring settings/config for trusted folder and file filters (#10611)

Co-authored-by: Bryan Morgan <bryanmorgan@google.com>
This commit is contained in:
sgnagnarella
2025-10-10 12:04:15 -04:00
committed by GitHub
parent 65b9e367f0
commit 971eb64e98
7 changed files with 84 additions and 37 deletions

View File

@@ -13,10 +13,10 @@ import { MessageType } from '../types.js';
import type { LoadedSettings } from '../../config/settings.js';
import {
getErrorMessage,
loadServerHierarchicalMemory,
type FileDiscoveryService,
} from '@google/gemini-cli-core';
import type { LoadServerHierarchicalMemoryResponse } from '@google/gemini-cli-core/index.js';
import { loadHierarchicalGeminiMemory } from '../../config/config.js';
vi.mock('@google/gemini-cli-core', async (importOriginal) => {
const original =
@@ -27,11 +27,19 @@ vi.mock('@google/gemini-cli-core', async (importOriginal) => {
if (error instanceof Error) return error.message;
return String(error);
}),
loadServerHierarchicalMemory: vi.fn(),
};
});
const mockLoadServerHierarchicalMemory = loadServerHierarchicalMemory as Mock;
vi.mock('../../config/config.js', async (importOriginal) => {
const original =
await importOriginal<typeof import('../../config/config.js')>();
return {
...original,
loadHierarchicalGeminiMemory: vi.fn(),
};
});
const mockLoadHierarchicalGeminiMemory = loadHierarchicalGeminiMemory as Mock;
describe('memoryCommand', () => {
let mockContext: CommandContext;
@@ -177,7 +185,7 @@ describe('memoryCommand', () => {
ignore: [],
include: [],
}),
getFolderTrust: () => false,
isTrustedFolder: () => false,
};
mockContext = createMockCommandContext({
@@ -186,11 +194,17 @@ describe('memoryCommand', () => {
settings: {
merged: {
memoryDiscoveryMaxDirs: 1000,
context: {
importFormat: 'tree',
},
},
} as LoadedSettings,
},
ui: {
setGeminiMdFileCount: vi.fn(),
},
});
mockLoadServerHierarchicalMemory.mockClear();
mockLoadHierarchicalGeminiMemory.mockClear();
});
it('should display success message when memory is refreshed with content', async () => {
@@ -201,7 +215,7 @@ describe('memoryCommand', () => {
fileCount: 2,
filePaths: ['/path/one/GEMINI.md', '/path/two/GEMINI.md'],
};
mockLoadServerHierarchicalMemory.mockResolvedValue(refreshResult);
mockLoadHierarchicalGeminiMemory.mockResolvedValue(refreshResult);
await refreshCommand.action(mockContext, '');
@@ -213,7 +227,7 @@ describe('memoryCommand', () => {
expect.any(Number),
);
expect(loadServerHierarchicalMemory).toHaveBeenCalledOnce();
expect(mockLoadHierarchicalGeminiMemory).toHaveBeenCalledOnce();
expect(mockSetUserMemory).toHaveBeenCalledWith(
refreshResult.memoryContent,
);
@@ -223,6 +237,9 @@ describe('memoryCommand', () => {
expect(mockSetGeminiMdFilePaths).toHaveBeenCalledWith(
refreshResult.filePaths,
);
expect(mockContext.ui.setGeminiMdFileCount).toHaveBeenCalledWith(
refreshResult.fileCount,
);
expect(mockContext.ui.addItem).toHaveBeenCalledWith(
{
@@ -237,11 +254,11 @@ describe('memoryCommand', () => {
if (!refreshCommand.action) throw new Error('Command has no action');
const refreshResult = { memoryContent: '', fileCount: 0, filePaths: [] };
mockLoadServerHierarchicalMemory.mockResolvedValue(refreshResult);
mockLoadHierarchicalGeminiMemory.mockResolvedValue(refreshResult);
await refreshCommand.action(mockContext, '');
expect(loadServerHierarchicalMemory).toHaveBeenCalledOnce();
expect(mockLoadHierarchicalGeminiMemory).toHaveBeenCalledOnce();
expect(mockSetUserMemory).toHaveBeenCalledWith('');
expect(mockSetGeminiMdFileCount).toHaveBeenCalledWith(0);
expect(mockSetGeminiMdFilePaths).toHaveBeenCalledWith([]);
@@ -259,11 +276,11 @@ describe('memoryCommand', () => {
if (!refreshCommand.action) throw new Error('Command has no action');
const error = new Error('Failed to read memory files.');
mockLoadServerHierarchicalMemory.mockRejectedValue(error);
mockLoadHierarchicalGeminiMemory.mockRejectedValue(error);
await refreshCommand.action(mockContext, '');
expect(loadServerHierarchicalMemory).toHaveBeenCalledOnce();
expect(mockLoadHierarchicalGeminiMemory).toHaveBeenCalledOnce();
expect(mockSetUserMemory).not.toHaveBeenCalled();
expect(mockSetGeminiMdFileCount).not.toHaveBeenCalled();
expect(mockSetGeminiMdFilePaths).not.toHaveBeenCalled();
@@ -298,7 +315,7 @@ describe('memoryCommand', () => {
expect.any(Number),
);
expect(loadServerHierarchicalMemory).not.toHaveBeenCalled();
expect(mockLoadHierarchicalGeminiMemory).not.toHaveBeenCalled();
});
});

View File

@@ -4,11 +4,9 @@
* SPDX-License-Identifier: Apache-2.0
*/
import {
getErrorMessage,
loadServerHierarchicalMemory,
} from '@google/gemini-cli-core';
import { getErrorMessage } from '@google/gemini-cli-core';
import { MessageType } from '../types.js';
import { loadHierarchicalGeminiMemory } from '../../config/config.js';
import type { SlashCommand, SlashCommandActionReturn } from './types.js';
import { CommandKind } from './types.js';
@@ -82,25 +80,26 @@ export const memoryCommand: SlashCommand = {
try {
const config = await context.services.config;
const settings = context.services.settings;
if (config) {
const { memoryContent, fileCount, filePaths } =
await loadServerHierarchicalMemory(
await loadHierarchicalGeminiMemory(
config.getWorkingDir(),
config.shouldLoadMemoryFromIncludeDirectories()
? config.getWorkspaceContext().getDirectories()
: [],
config.getDebugMode(),
config.getFileService(),
settings.merged,
config.getExtensionContextFilePaths(),
config.getFolderTrust(),
context.services.settings.merged.context?.importFormat ||
'tree', // Use setting or default to 'tree'
config.isTrustedFolder(),
settings.merged.context?.importFormat || 'tree',
config.getFileFilteringOptions(),
context.services.settings.merged.context?.discoveryMaxDirs,
);
config.setUserMemory(memoryContent);
config.setGeminiMdFileCount(fileCount);
config.setGeminiMdFilePaths(filePaths);
context.ui.setGeminiMdFileCount(fileCount);
const successMessage =
memoryContent.length > 0