Add new folderTrust setting that the users can enable or disable (#5798)

This commit is contained in:
shrutip90 2025-08-07 14:06:17 -07:00 committed by GitHub
parent 3a3b138195
commit 53f8617b24
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 130 additions and 4 deletions

View File

@ -1042,6 +1042,58 @@ describe('loadCliConfig folderTrustFeature', () => {
});
});
describe('loadCliConfig folderTrust', () => {
const originalArgv = process.argv;
const originalEnv = { ...process.env };
beforeEach(() => {
vi.resetAllMocks();
vi.mocked(os.homedir).mockReturnValue('/mock/home/user');
process.env.GEMINI_API_KEY = 'test-api-key';
});
afterEach(() => {
process.argv = originalArgv;
process.env = originalEnv;
vi.restoreAllMocks();
});
it('should be false if folderTrustFeature is false and folderTrust is false', async () => {
process.argv = ['node', 'script.js'];
const settings: Settings = {
folderTrustFeature: false,
folderTrust: false,
};
const argv = await parseArguments();
const config = await loadCliConfig(settings, [], 'test-session', argv);
expect(config.getFolderTrust()).toBe(false);
});
it('should be false if folderTrustFeature is true and folderTrust is false', async () => {
process.argv = ['node', 'script.js'];
const argv = await parseArguments();
const settings: Settings = { folderTrustFeature: true, folderTrust: false };
const config = await loadCliConfig(settings, [], 'test-session', argv);
expect(config.getFolderTrust()).toBe(false);
});
it('should be false if folderTrustFeature is false and folderTrust is true', async () => {
process.argv = ['node', 'script.js'];
const argv = await parseArguments();
const settings: Settings = { folderTrustFeature: false, folderTrust: true };
const config = await loadCliConfig(settings, [], 'test-session', argv);
expect(config.getFolderTrust()).toBe(false);
});
it('should be true when folderTrustFeature is true and folderTrust is true', async () => {
process.argv = ['node', 'script.js'];
const argv = await parseArguments();
const settings: Settings = { folderTrustFeature: true, folderTrust: true };
const config = await loadCliConfig(settings, [], 'test-session', argv);
expect(config.getFolderTrust()).toBe(true);
});
});
vi.mock('fs', async () => {
const actualFs = await vi.importActual<typeof fs>('fs');
const MOCK_CWD1 = process.cwd();

View File

@ -314,6 +314,8 @@ export async function loadCliConfig(
argv.ideModeFeature ?? settings.ideModeFeature ?? false;
const folderTrustFeature = settings.folderTrustFeature ?? false;
const folderTrustSetting = settings.folderTrust ?? false;
const folderTrust = folderTrustFeature && folderTrustSetting;
const allExtensions = annotateActiveExtensions(
extensions,
@ -484,6 +486,7 @@ export async function loadCliConfig(
ideModeFeature,
chatCompression: settings.chatCompression,
folderTrustFeature,
folderTrust,
});
}

View File

@ -310,6 +310,62 @@ describe('Settings Loading and Merging', () => {
});
});
it('should ignore folderTrust from workspace settings', () => {
(mockFsExistsSync as Mock).mockReturnValue(true);
const userSettingsContent = {
folderTrust: true,
};
const workspaceSettingsContent = {
folderTrust: false, // This should be ignored
};
const systemSettingsContent = {
// No folderTrust here
};
(fs.readFileSync as Mock).mockImplementation(
(p: fs.PathOrFileDescriptor) => {
if (p === getSystemSettingsPath())
return JSON.stringify(systemSettingsContent);
if (p === USER_SETTINGS_PATH)
return JSON.stringify(userSettingsContent);
if (p === MOCK_WORKSPACE_SETTINGS_PATH)
return JSON.stringify(workspaceSettingsContent);
return '{}';
},
);
const settings = loadSettings(MOCK_WORKSPACE_DIR);
expect(settings.merged.folderTrust).toBe(true); // User setting should be used
});
it('should use system folderTrust over user setting', () => {
(mockFsExistsSync as Mock).mockReturnValue(true);
const userSettingsContent = {
folderTrust: false,
};
const workspaceSettingsContent = {
folderTrust: true, // This should be ignored
};
const systemSettingsContent = {
folderTrust: true,
};
(fs.readFileSync as Mock).mockImplementation(
(p: fs.PathOrFileDescriptor) => {
if (p === getSystemSettingsPath())
return JSON.stringify(systemSettingsContent);
if (p === USER_SETTINGS_PATH)
return JSON.stringify(userSettingsContent);
if (p === MOCK_WORKSPACE_SETTINGS_PATH)
return JSON.stringify(workspaceSettingsContent);
return '{}';
},
);
const settings = loadSettings(MOCK_WORKSPACE_DIR);
expect(settings.merged.folderTrust).toBe(true); // System setting should be used
});
it('should handle contextFileName correctly when only in user settings', () => {
(mockFsExistsSync as Mock).mockImplementation(
(p: fs.PathLike) => p === USER_SETTINGS_PATH,

View File

@ -113,10 +113,14 @@ export interface Settings {
// Flag to be removed post-launch.
ideModeFeature?: boolean;
folderTrustFeature?: boolean;
/// IDE mode setting configured via slash command toggle.
ideMode?: boolean;
// Flag to be removed post-launch.
folderTrustFeature?: boolean;
// Setting to track whether Folder trust is enabled.
folderTrust?: boolean;
// Setting to track if the user has seen the IDE integration nudge.
hasSeenIdeIntegrationNudge?: boolean;
@ -178,9 +182,13 @@ export class LoadedSettings {
const user = this.user.settings;
const workspace = this.workspace.settings;
// folderTrust is not supported at workspace level.
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { folderTrust, ...workspaceWithoutFolderTrust } = workspace;
return {
...user,
...workspace,
...workspaceWithoutFolderTrust,
...system,
customThemes: {
...(user.customThemes || {}),

View File

@ -193,6 +193,7 @@ export interface ConfigParameters {
summarizeToolOutput?: Record<string, SummarizeToolOutputSettings>;
ideModeFeature?: boolean;
folderTrustFeature?: boolean;
folderTrust?: boolean;
ideMode?: boolean;
loadMemoryFromIncludeDirectories?: boolean;
chatCompression?: ChatCompressionSettings;
@ -240,6 +241,7 @@ export class Config {
private readonly noBrowser: boolean;
private readonly ideModeFeature: boolean;
private readonly folderTrustFeature: boolean;
private readonly folderTrust: boolean;
private ideMode: boolean;
private ideClient: IdeClient;
private inFallbackMode = false;
@ -314,6 +316,7 @@ export class Config {
this.summarizeToolOutput = params.summarizeToolOutput;
this.ideModeFeature = params.ideModeFeature ?? false;
this.folderTrustFeature = params.folderTrustFeature ?? false;
this.folderTrust = params.folderTrust ?? false;
this.ideMode = params.ideMode ?? false;
this.ideClient = IdeClient.getInstance();
if (this.ideMode && this.ideModeFeature) {
@ -648,12 +651,16 @@ export class Config {
return this.ideModeFeature;
}
getIdeMode(): boolean {
return this.ideMode;
}
getFolderTrustFeature(): boolean {
return this.folderTrustFeature;
}
getIdeMode(): boolean {
return this.ideMode;
getFolderTrust(): boolean {
return this.folderTrust;
}
setIdeMode(value: boolean): void {