mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
fix(cli): automatically add all VSCode workspace folders to Gemini context (#21380)
Co-authored-by: Spencer <spencertang@google.com>
This commit is contained in:
@@ -763,6 +763,48 @@ describe('loadCliConfig', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should add IDE workspace folders from GEMINI_CLI_IDE_WORKSPACE_PATH to include directories', async () => {
|
||||||
|
vi.stubEnv(
|
||||||
|
'GEMINI_CLI_IDE_WORKSPACE_PATH',
|
||||||
|
['/project/folderA', '/project/folderB'].join(path.delimiter),
|
||||||
|
);
|
||||||
|
process.argv = ['node', 'script.js'];
|
||||||
|
const argv = await parseArguments(createTestMergedSettings());
|
||||||
|
const settings = createTestMergedSettings();
|
||||||
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
||||||
|
const dirs = config.getPendingIncludeDirectories();
|
||||||
|
expect(dirs).toContain('/project/folderA');
|
||||||
|
expect(dirs).toContain('/project/folderB');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should skip inaccessible workspace folders from GEMINI_CLI_IDE_WORKSPACE_PATH', async () => {
|
||||||
|
const resolveToRealPathSpy = vi
|
||||||
|
.spyOn(ServerConfig, 'resolveToRealPath')
|
||||||
|
.mockImplementation((p) => {
|
||||||
|
if (p.toString().includes('restricted')) {
|
||||||
|
const err = new Error('EACCES: permission denied');
|
||||||
|
(err as NodeJS.ErrnoException).code = 'EACCES';
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
return p.toString();
|
||||||
|
});
|
||||||
|
vi.stubEnv(
|
||||||
|
'GEMINI_CLI_IDE_WORKSPACE_PATH',
|
||||||
|
['/project/folderA', '/nonexistent/restricted/folder'].join(
|
||||||
|
path.delimiter,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
process.argv = ['node', 'script.js'];
|
||||||
|
const argv = await parseArguments(createTestMergedSettings());
|
||||||
|
const settings = createTestMergedSettings();
|
||||||
|
const config = await loadCliConfig(settings, 'test-session', argv);
|
||||||
|
const dirs = config.getPendingIncludeDirectories();
|
||||||
|
expect(dirs).toContain('/project/folderA');
|
||||||
|
expect(dirs).not.toContain('/nonexistent/restricted/folder');
|
||||||
|
|
||||||
|
resolveToRealPathSpy.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
it('should use default fileFilter options when unconfigured', async () => {
|
it('should use default fileFilter options when unconfigured', async () => {
|
||||||
process.argv = ['node', 'script.js'];
|
process.argv = ['node', 'script.js'];
|
||||||
const argv = await parseArguments(createTestMergedSettings());
|
const argv = await parseArguments(createTestMergedSettings());
|
||||||
@@ -798,6 +840,7 @@ describe('loadCliConfig', () => {
|
|||||||
describe('Hierarchical Memory Loading (config.ts) - Placeholder Suite', () => {
|
describe('Hierarchical Memory Loading (config.ts) - Placeholder Suite', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
vi.resetAllMocks();
|
vi.resetAllMocks();
|
||||||
|
vi.stubEnv('GEMINI_CLI_IDE_WORKSPACE_PATH', '');
|
||||||
// Restore ExtensionManager mocks that were reset
|
// Restore ExtensionManager mocks that were reset
|
||||||
ExtensionManager.prototype.getExtensions = vi.fn().mockReturnValue([]);
|
ExtensionManager.prototype.getExtensions = vi.fn().mockReturnValue([]);
|
||||||
ExtensionManager.prototype.loadExtensions = vi
|
ExtensionManager.prototype.loadExtensions = vi
|
||||||
@@ -809,6 +852,7 @@ describe('Hierarchical Memory Loading (config.ts) - Placeholder Suite', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
vi.unstubAllEnvs();
|
||||||
vi.restoreAllMocks();
|
vi.restoreAllMocks();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -475,10 +475,32 @@ export async function loadCliConfig(
|
|||||||
...settings.context?.fileFiltering,
|
...settings.context?.fileFiltering,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//changes the includeDirectories to be absolute paths based on the cwd, and also include any additional directories specified via CLI args
|
||||||
const includeDirectories = (settings.context?.includeDirectories || [])
|
const includeDirectories = (settings.context?.includeDirectories || [])
|
||||||
.map(resolvePath)
|
.map(resolvePath)
|
||||||
.concat((argv.includeDirectories || []).map(resolvePath));
|
.concat((argv.includeDirectories || []).map(resolvePath));
|
||||||
|
|
||||||
|
// When running inside VSCode with multiple workspace folders,
|
||||||
|
// automatically add the other folders as include directories
|
||||||
|
// so Gemini has context of all open folders, not just the cwd.
|
||||||
|
const ideWorkspacePath = process.env['GEMINI_CLI_IDE_WORKSPACE_PATH'];
|
||||||
|
if (ideWorkspacePath) {
|
||||||
|
const realCwd = resolveToRealPath(cwd);
|
||||||
|
const ideFolders = ideWorkspacePath.split(path.delimiter).filter((p) => {
|
||||||
|
const trimmedPath = p.trim();
|
||||||
|
if (!trimmedPath) return false;
|
||||||
|
try {
|
||||||
|
return resolveToRealPath(trimmedPath) !== realCwd;
|
||||||
|
} catch (e) {
|
||||||
|
debugLogger.debug(
|
||||||
|
`[IDE] Skipping inaccessible workspace folder: ${trimmedPath} (${e instanceof Error ? e.message : String(e)})`,
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
includeDirectories.push(...ideFolders);
|
||||||
|
}
|
||||||
|
|
||||||
const extensionManager = new ExtensionManager({
|
const extensionManager = new ExtensionManager({
|
||||||
settings,
|
settings,
|
||||||
requestConsent: requestConsentNonInteractive,
|
requestConsent: requestConsentNonInteractive,
|
||||||
|
|||||||
Reference in New Issue
Block a user