mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-21 09:17:53 +00:00
feat(ui): add /settings command and UI panel (#4738)
Co-authored-by: Jacob Richman <jacob314@gmail.com>
This commit is contained in:
@@ -9,18 +9,15 @@ import * as path from 'path';
|
||||
import { homedir, platform } from 'os';
|
||||
import * as dotenv from 'dotenv';
|
||||
import {
|
||||
MCPServerConfig,
|
||||
GEMINI_CONFIG_DIR as GEMINI_DIR,
|
||||
getErrorMessage,
|
||||
BugCommandSettings,
|
||||
ChatCompressionSettings,
|
||||
TelemetrySettings,
|
||||
AuthType,
|
||||
} from '@google/gemini-cli-core';
|
||||
import stripJsonComments from 'strip-json-comments';
|
||||
import { DefaultLight } from '../ui/themes/default-light.js';
|
||||
import { DefaultDark } from '../ui/themes/default.js';
|
||||
import { CustomTheme } from '../ui/themes/theme.js';
|
||||
import { Settings, MemoryImportFormat } from './settingsSchema.js';
|
||||
|
||||
export type { Settings, MemoryImportFormat };
|
||||
|
||||
export const SETTINGS_DIRECTORY_NAME = '.gemini';
|
||||
export const USER_SETTINGS_DIR = path.join(homedir(), SETTINGS_DIRECTORY_NAME);
|
||||
@@ -44,7 +41,7 @@ export function getWorkspaceSettingsPath(workspaceDir: string): string {
|
||||
return path.join(workspaceDir, SETTINGS_DIRECTORY_NAME, 'settings.json');
|
||||
}
|
||||
|
||||
export type DnsResolutionOrder = 'ipv4first' | 'verbatim';
|
||||
export type { DnsResolutionOrder } from './settingsSchema.js';
|
||||
|
||||
export enum SettingScope {
|
||||
User = 'User',
|
||||
@@ -64,86 +61,6 @@ export interface AccessibilitySettings {
|
||||
disableLoadingPhrases?: boolean;
|
||||
}
|
||||
|
||||
export interface Settings {
|
||||
theme?: string;
|
||||
customThemes?: Record<string, CustomTheme>;
|
||||
selectedAuthType?: AuthType;
|
||||
useExternalAuth?: boolean;
|
||||
sandbox?: boolean | string;
|
||||
coreTools?: string[];
|
||||
excludeTools?: string[];
|
||||
toolDiscoveryCommand?: string;
|
||||
toolCallCommand?: string;
|
||||
mcpServerCommand?: string;
|
||||
mcpServers?: Record<string, MCPServerConfig>;
|
||||
allowMCPServers?: string[];
|
||||
excludeMCPServers?: string[];
|
||||
showMemoryUsage?: boolean;
|
||||
contextFileName?: string | string[];
|
||||
accessibility?: AccessibilitySettings;
|
||||
telemetry?: TelemetrySettings;
|
||||
usageStatisticsEnabled?: boolean;
|
||||
preferredEditor?: string;
|
||||
bugCommand?: BugCommandSettings;
|
||||
checkpointing?: CheckpointingSettings;
|
||||
autoConfigureMaxOldSpaceSize?: boolean;
|
||||
/** The model name to use (e.g 'gemini-9.0-pro') */
|
||||
model?: string;
|
||||
|
||||
// Git-aware file filtering settings
|
||||
fileFiltering?: {
|
||||
respectGitIgnore?: boolean;
|
||||
respectGeminiIgnore?: boolean;
|
||||
enableRecursiveFileSearch?: boolean;
|
||||
};
|
||||
|
||||
hideWindowTitle?: boolean;
|
||||
|
||||
hideTips?: boolean;
|
||||
hideBanner?: boolean;
|
||||
|
||||
// Setting for setting maximum number of user/model/tool turns in a session.
|
||||
maxSessionTurns?: number;
|
||||
|
||||
// A map of tool names to their summarization settings.
|
||||
summarizeToolOutput?: Record<string, SummarizeToolOutputSettings>;
|
||||
|
||||
vimMode?: boolean;
|
||||
memoryImportFormat?: 'tree' | 'flat';
|
||||
|
||||
// Flag to be removed post-launch.
|
||||
ideModeFeature?: 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;
|
||||
|
||||
// Setting for disabling auto-update.
|
||||
disableAutoUpdate?: boolean;
|
||||
|
||||
// Setting for disabling the update nag message.
|
||||
disableUpdateNag?: boolean;
|
||||
|
||||
memoryDiscoveryMaxDirs?: number;
|
||||
|
||||
// Environment variables to exclude from project .env files
|
||||
excludedProjectEnvVars?: string[];
|
||||
dnsResolutionOrder?: DnsResolutionOrder;
|
||||
|
||||
includeDirectories?: string[];
|
||||
|
||||
loadMemoryFromIncludeDirectories?: boolean;
|
||||
|
||||
chatCompression?: ChatCompressionSettings;
|
||||
showLineNumbers?: boolean;
|
||||
}
|
||||
|
||||
export interface SettingsError {
|
||||
message: string;
|
||||
path: string;
|
||||
|
||||
253
packages/cli/src/config/settingsSchema.test.ts
Normal file
253
packages/cli/src/config/settingsSchema.test.ts
Normal file
@@ -0,0 +1,253 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { SETTINGS_SCHEMA, Settings } from './settingsSchema.js';
|
||||
|
||||
describe('SettingsSchema', () => {
|
||||
describe('SETTINGS_SCHEMA', () => {
|
||||
it('should contain all expected top-level settings', () => {
|
||||
const expectedSettings = [
|
||||
'theme',
|
||||
'customThemes',
|
||||
'showMemoryUsage',
|
||||
'usageStatisticsEnabled',
|
||||
'autoConfigureMaxOldSpaceSize',
|
||||
'preferredEditor',
|
||||
'maxSessionTurns',
|
||||
'memoryImportFormat',
|
||||
'memoryDiscoveryMaxDirs',
|
||||
'contextFileName',
|
||||
'vimMode',
|
||||
'ideMode',
|
||||
'accessibility',
|
||||
'checkpointing',
|
||||
'fileFiltering',
|
||||
'disableAutoUpdate',
|
||||
'hideWindowTitle',
|
||||
'hideTips',
|
||||
'hideBanner',
|
||||
'selectedAuthType',
|
||||
'useExternalAuth',
|
||||
'sandbox',
|
||||
'coreTools',
|
||||
'excludeTools',
|
||||
'toolDiscoveryCommand',
|
||||
'toolCallCommand',
|
||||
'mcpServerCommand',
|
||||
'mcpServers',
|
||||
'allowMCPServers',
|
||||
'excludeMCPServers',
|
||||
'telemetry',
|
||||
'bugCommand',
|
||||
'summarizeToolOutput',
|
||||
'ideModeFeature',
|
||||
'dnsResolutionOrder',
|
||||
'excludedProjectEnvVars',
|
||||
'disableUpdateNag',
|
||||
'includeDirectories',
|
||||
'loadMemoryFromIncludeDirectories',
|
||||
'model',
|
||||
'hasSeenIdeIntegrationNudge',
|
||||
'folderTrustFeature',
|
||||
];
|
||||
|
||||
expectedSettings.forEach((setting) => {
|
||||
expect(
|
||||
SETTINGS_SCHEMA[setting as keyof typeof SETTINGS_SCHEMA],
|
||||
).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
it('should have correct structure for each setting', () => {
|
||||
Object.entries(SETTINGS_SCHEMA).forEach(([_key, definition]) => {
|
||||
expect(definition).toHaveProperty('type');
|
||||
expect(definition).toHaveProperty('label');
|
||||
expect(definition).toHaveProperty('category');
|
||||
expect(definition).toHaveProperty('requiresRestart');
|
||||
expect(definition).toHaveProperty('default');
|
||||
expect(typeof definition.type).toBe('string');
|
||||
expect(typeof definition.label).toBe('string');
|
||||
expect(typeof definition.category).toBe('string');
|
||||
expect(typeof definition.requiresRestart).toBe('boolean');
|
||||
});
|
||||
});
|
||||
|
||||
it('should have correct nested setting structure', () => {
|
||||
const nestedSettings = [
|
||||
'accessibility',
|
||||
'checkpointing',
|
||||
'fileFiltering',
|
||||
];
|
||||
|
||||
nestedSettings.forEach((setting) => {
|
||||
const definition = SETTINGS_SCHEMA[
|
||||
setting as keyof typeof SETTINGS_SCHEMA
|
||||
] as (typeof SETTINGS_SCHEMA)[keyof typeof SETTINGS_SCHEMA] & {
|
||||
properties: unknown;
|
||||
};
|
||||
expect(definition.type).toBe('object');
|
||||
expect(definition.properties).toBeDefined();
|
||||
expect(typeof definition.properties).toBe('object');
|
||||
});
|
||||
});
|
||||
|
||||
it('should have accessibility nested properties', () => {
|
||||
expect(
|
||||
SETTINGS_SCHEMA.accessibility.properties?.disableLoadingPhrases,
|
||||
).toBeDefined();
|
||||
expect(
|
||||
SETTINGS_SCHEMA.accessibility.properties?.disableLoadingPhrases.type,
|
||||
).toBe('boolean');
|
||||
});
|
||||
|
||||
it('should have checkpointing nested properties', () => {
|
||||
expect(SETTINGS_SCHEMA.checkpointing.properties?.enabled).toBeDefined();
|
||||
expect(SETTINGS_SCHEMA.checkpointing.properties?.enabled.type).toBe(
|
||||
'boolean',
|
||||
);
|
||||
});
|
||||
|
||||
it('should have fileFiltering nested properties', () => {
|
||||
expect(
|
||||
SETTINGS_SCHEMA.fileFiltering.properties?.respectGitIgnore,
|
||||
).toBeDefined();
|
||||
expect(
|
||||
SETTINGS_SCHEMA.fileFiltering.properties?.respectGeminiIgnore,
|
||||
).toBeDefined();
|
||||
expect(
|
||||
SETTINGS_SCHEMA.fileFiltering.properties?.enableRecursiveFileSearch,
|
||||
).toBeDefined();
|
||||
});
|
||||
|
||||
it('should have unique categories', () => {
|
||||
const categories = new Set();
|
||||
|
||||
// Collect categories from top-level settings
|
||||
Object.values(SETTINGS_SCHEMA).forEach((definition) => {
|
||||
categories.add(definition.category);
|
||||
// Also collect from nested properties
|
||||
const defWithProps = definition as typeof definition & {
|
||||
properties?: Record<string, unknown>;
|
||||
};
|
||||
if (defWithProps.properties) {
|
||||
Object.values(defWithProps.properties).forEach(
|
||||
(nestedDef: unknown) => {
|
||||
const nestedDefTyped = nestedDef as { category?: string };
|
||||
if (nestedDefTyped.category) {
|
||||
categories.add(nestedDefTyped.category);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
expect(categories.size).toBeGreaterThan(0);
|
||||
expect(categories).toContain('General');
|
||||
expect(categories).toContain('UI');
|
||||
expect(categories).toContain('Mode');
|
||||
expect(categories).toContain('Updates');
|
||||
expect(categories).toContain('Accessibility');
|
||||
expect(categories).toContain('Checkpointing');
|
||||
expect(categories).toContain('File Filtering');
|
||||
expect(categories).toContain('Advanced');
|
||||
});
|
||||
|
||||
it('should have consistent default values for boolean settings', () => {
|
||||
const checkBooleanDefaults = (schema: Record<string, unknown>) => {
|
||||
Object.entries(schema).forEach(
|
||||
([_key, definition]: [string, unknown]) => {
|
||||
const def = definition as {
|
||||
type?: string;
|
||||
default?: unknown;
|
||||
properties?: Record<string, unknown>;
|
||||
};
|
||||
if (def.type === 'boolean') {
|
||||
// Boolean settings can have boolean or undefined defaults (for optional settings)
|
||||
expect(['boolean', 'undefined']).toContain(typeof def.default);
|
||||
}
|
||||
if (def.properties) {
|
||||
checkBooleanDefaults(def.properties);
|
||||
}
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
checkBooleanDefaults(SETTINGS_SCHEMA as Record<string, unknown>);
|
||||
});
|
||||
|
||||
it('should have showInDialog property configured', () => {
|
||||
// Check that user-facing settings are marked for dialog display
|
||||
expect(SETTINGS_SCHEMA.showMemoryUsage.showInDialog).toBe(true);
|
||||
expect(SETTINGS_SCHEMA.vimMode.showInDialog).toBe(true);
|
||||
expect(SETTINGS_SCHEMA.ideMode.showInDialog).toBe(true);
|
||||
expect(SETTINGS_SCHEMA.disableAutoUpdate.showInDialog).toBe(true);
|
||||
expect(SETTINGS_SCHEMA.hideWindowTitle.showInDialog).toBe(true);
|
||||
expect(SETTINGS_SCHEMA.hideTips.showInDialog).toBe(true);
|
||||
expect(SETTINGS_SCHEMA.hideBanner.showInDialog).toBe(true);
|
||||
expect(SETTINGS_SCHEMA.usageStatisticsEnabled.showInDialog).toBe(true);
|
||||
|
||||
// Check that advanced settings are hidden from dialog
|
||||
expect(SETTINGS_SCHEMA.selectedAuthType.showInDialog).toBe(false);
|
||||
expect(SETTINGS_SCHEMA.coreTools.showInDialog).toBe(false);
|
||||
expect(SETTINGS_SCHEMA.mcpServers.showInDialog).toBe(false);
|
||||
expect(SETTINGS_SCHEMA.telemetry.showInDialog).toBe(false);
|
||||
|
||||
// Check that some settings are appropriately hidden
|
||||
expect(SETTINGS_SCHEMA.theme.showInDialog).toBe(false); // Changed to false
|
||||
expect(SETTINGS_SCHEMA.customThemes.showInDialog).toBe(false); // Managed via theme editor
|
||||
expect(SETTINGS_SCHEMA.checkpointing.showInDialog).toBe(false); // Experimental feature
|
||||
expect(SETTINGS_SCHEMA.accessibility.showInDialog).toBe(false); // Changed to false
|
||||
expect(SETTINGS_SCHEMA.fileFiltering.showInDialog).toBe(false); // Changed to false
|
||||
expect(SETTINGS_SCHEMA.preferredEditor.showInDialog).toBe(false); // Changed to false
|
||||
expect(SETTINGS_SCHEMA.autoConfigureMaxOldSpaceSize.showInDialog).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it('should infer Settings type correctly', () => {
|
||||
// This test ensures that the Settings type is properly inferred from the schema
|
||||
const settings: Settings = {
|
||||
theme: 'dark',
|
||||
includeDirectories: ['/path/to/dir'],
|
||||
loadMemoryFromIncludeDirectories: true,
|
||||
};
|
||||
|
||||
// TypeScript should not complain about these properties
|
||||
expect(settings.theme).toBe('dark');
|
||||
expect(settings.includeDirectories).toEqual(['/path/to/dir']);
|
||||
expect(settings.loadMemoryFromIncludeDirectories).toBe(true);
|
||||
});
|
||||
|
||||
it('should have includeDirectories setting in schema', () => {
|
||||
expect(SETTINGS_SCHEMA.includeDirectories).toBeDefined();
|
||||
expect(SETTINGS_SCHEMA.includeDirectories.type).toBe('array');
|
||||
expect(SETTINGS_SCHEMA.includeDirectories.category).toBe('General');
|
||||
expect(SETTINGS_SCHEMA.includeDirectories.default).toEqual([]);
|
||||
});
|
||||
|
||||
it('should have loadMemoryFromIncludeDirectories setting in schema', () => {
|
||||
expect(SETTINGS_SCHEMA.loadMemoryFromIncludeDirectories).toBeDefined();
|
||||
expect(SETTINGS_SCHEMA.loadMemoryFromIncludeDirectories.type).toBe(
|
||||
'boolean',
|
||||
);
|
||||
expect(SETTINGS_SCHEMA.loadMemoryFromIncludeDirectories.category).toBe(
|
||||
'General',
|
||||
);
|
||||
expect(SETTINGS_SCHEMA.loadMemoryFromIncludeDirectories.default).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
it('should have folderTrustFeature setting in schema', () => {
|
||||
expect(SETTINGS_SCHEMA.folderTrustFeature).toBeDefined();
|
||||
expect(SETTINGS_SCHEMA.folderTrustFeature.type).toBe('boolean');
|
||||
expect(SETTINGS_SCHEMA.folderTrustFeature.category).toBe('General');
|
||||
expect(SETTINGS_SCHEMA.folderTrustFeature.default).toBe(false);
|
||||
expect(SETTINGS_SCHEMA.folderTrustFeature.showInDialog).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
516
packages/cli/src/config/settingsSchema.ts
Normal file
516
packages/cli/src/config/settingsSchema.ts
Normal file
@@ -0,0 +1,516 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2025 Google LLC
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {
|
||||
MCPServerConfig,
|
||||
BugCommandSettings,
|
||||
TelemetrySettings,
|
||||
AuthType,
|
||||
ChatCompressionSettings,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { CustomTheme } from '../ui/themes/theme.js';
|
||||
|
||||
export interface SettingDefinition {
|
||||
type: 'boolean' | 'string' | 'number' | 'array' | 'object';
|
||||
label: string;
|
||||
category: string;
|
||||
requiresRestart: boolean;
|
||||
default: boolean | string | number | string[] | object | undefined;
|
||||
description?: string;
|
||||
parentKey?: string;
|
||||
childKey?: string;
|
||||
key?: string;
|
||||
properties?: SettingsSchema;
|
||||
showInDialog?: boolean;
|
||||
}
|
||||
|
||||
export interface SettingsSchema {
|
||||
[key: string]: SettingDefinition;
|
||||
}
|
||||
|
||||
export type MemoryImportFormat = 'tree' | 'flat';
|
||||
export type DnsResolutionOrder = 'ipv4first' | 'verbatim';
|
||||
|
||||
/**
|
||||
* The canonical schema for all settings.
|
||||
* The structure of this object defines the structure of the `Settings` type.
|
||||
* `as const` is crucial for TypeScript to infer the most specific types possible.
|
||||
*/
|
||||
export const SETTINGS_SCHEMA = {
|
||||
// UI Settings
|
||||
theme: {
|
||||
type: 'string',
|
||||
label: 'Theme',
|
||||
category: 'UI',
|
||||
requiresRestart: false,
|
||||
default: undefined as string | undefined,
|
||||
description: 'The color theme for the UI.',
|
||||
showInDialog: false,
|
||||
},
|
||||
customThemes: {
|
||||
type: 'object',
|
||||
label: 'Custom Themes',
|
||||
category: 'UI',
|
||||
requiresRestart: false,
|
||||
default: {} as Record<string, CustomTheme>,
|
||||
description: 'Custom theme definitions.',
|
||||
showInDialog: false,
|
||||
},
|
||||
hideWindowTitle: {
|
||||
type: 'boolean',
|
||||
label: 'Hide Window Title',
|
||||
category: 'UI',
|
||||
requiresRestart: true,
|
||||
default: false,
|
||||
description: 'Hide the window title bar',
|
||||
showInDialog: true,
|
||||
},
|
||||
hideTips: {
|
||||
type: 'boolean',
|
||||
label: 'Hide Tips',
|
||||
category: 'UI',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description: 'Hide helpful tips in the UI',
|
||||
showInDialog: true,
|
||||
},
|
||||
hideBanner: {
|
||||
type: 'boolean',
|
||||
label: 'Hide Banner',
|
||||
category: 'UI',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description: 'Hide the application banner',
|
||||
showInDialog: true,
|
||||
},
|
||||
showMemoryUsage: {
|
||||
type: 'boolean',
|
||||
label: 'Show Memory Usage',
|
||||
category: 'UI',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description: 'Display memory usage information in the UI',
|
||||
showInDialog: true,
|
||||
},
|
||||
|
||||
usageStatisticsEnabled: {
|
||||
type: 'boolean',
|
||||
label: 'Enable Usage Statistics',
|
||||
category: 'General',
|
||||
requiresRestart: true,
|
||||
default: false,
|
||||
description: 'Enable collection of usage statistics',
|
||||
showInDialog: true,
|
||||
},
|
||||
autoConfigureMaxOldSpaceSize: {
|
||||
type: 'boolean',
|
||||
label: 'Auto Configure Max Old Space Size',
|
||||
category: 'General',
|
||||
requiresRestart: true,
|
||||
default: false,
|
||||
description: 'Automatically configure Node.js memory limits',
|
||||
showInDialog: true,
|
||||
},
|
||||
preferredEditor: {
|
||||
type: 'string',
|
||||
label: 'Preferred Editor',
|
||||
category: 'General',
|
||||
requiresRestart: false,
|
||||
default: undefined as string | undefined,
|
||||
description: 'The preferred editor to open files in.',
|
||||
showInDialog: false,
|
||||
},
|
||||
maxSessionTurns: {
|
||||
type: 'number',
|
||||
label: 'Max Session Turns',
|
||||
category: 'General',
|
||||
requiresRestart: false,
|
||||
default: undefined as number | undefined,
|
||||
description:
|
||||
'Maximum number of user/model/tool turns to keep in a session.',
|
||||
showInDialog: false,
|
||||
},
|
||||
memoryImportFormat: {
|
||||
type: 'string',
|
||||
label: 'Memory Import Format',
|
||||
category: 'General',
|
||||
requiresRestart: false,
|
||||
default: undefined as MemoryImportFormat | undefined,
|
||||
description: 'The format to use when importing memory.',
|
||||
showInDialog: false,
|
||||
},
|
||||
memoryDiscoveryMaxDirs: {
|
||||
type: 'number',
|
||||
label: 'Memory Discovery Max Dirs',
|
||||
category: 'General',
|
||||
requiresRestart: false,
|
||||
default: undefined as number | undefined,
|
||||
description: 'Maximum number of directories to search for memory.',
|
||||
showInDialog: false,
|
||||
},
|
||||
contextFileName: {
|
||||
type: 'object',
|
||||
label: 'Context File Name',
|
||||
category: 'General',
|
||||
requiresRestart: false,
|
||||
default: undefined as string | string[] | undefined,
|
||||
description: 'The name of the context file.',
|
||||
showInDialog: false,
|
||||
},
|
||||
vimMode: {
|
||||
type: 'boolean',
|
||||
label: 'Vim Mode',
|
||||
category: 'Mode',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description: 'Enable Vim keybindings',
|
||||
showInDialog: true,
|
||||
},
|
||||
ideMode: {
|
||||
type: 'boolean',
|
||||
label: 'IDE Mode',
|
||||
category: 'Mode',
|
||||
requiresRestart: true,
|
||||
default: false,
|
||||
description: 'Enable IDE integration mode',
|
||||
showInDialog: true,
|
||||
},
|
||||
|
||||
accessibility: {
|
||||
type: 'object',
|
||||
label: 'Accessibility',
|
||||
category: 'Accessibility',
|
||||
requiresRestart: true,
|
||||
default: {},
|
||||
description: 'Accessibility settings.',
|
||||
showInDialog: false,
|
||||
properties: {
|
||||
disableLoadingPhrases: {
|
||||
type: 'boolean',
|
||||
label: 'Disable Loading Phrases',
|
||||
category: 'Accessibility',
|
||||
requiresRestart: true,
|
||||
default: false,
|
||||
description: 'Disable loading phrases for accessibility',
|
||||
showInDialog: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
checkpointing: {
|
||||
type: 'object',
|
||||
label: 'Checkpointing',
|
||||
category: 'Checkpointing',
|
||||
requiresRestart: true,
|
||||
default: {},
|
||||
description: 'Session checkpointing settings.',
|
||||
showInDialog: false,
|
||||
properties: {
|
||||
enabled: {
|
||||
type: 'boolean',
|
||||
label: 'Enable Checkpointing',
|
||||
category: 'Checkpointing',
|
||||
requiresRestart: true,
|
||||
default: false,
|
||||
description: 'Enable session checkpointing for recovery',
|
||||
showInDialog: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
fileFiltering: {
|
||||
type: 'object',
|
||||
label: 'File Filtering',
|
||||
category: 'File Filtering',
|
||||
requiresRestart: true,
|
||||
default: {},
|
||||
description: 'Settings for git-aware file filtering.',
|
||||
showInDialog: false,
|
||||
properties: {
|
||||
respectGitIgnore: {
|
||||
type: 'boolean',
|
||||
label: 'Respect .gitignore',
|
||||
category: 'File Filtering',
|
||||
requiresRestart: true,
|
||||
default: true,
|
||||
description: 'Respect .gitignore files when searching',
|
||||
showInDialog: true,
|
||||
},
|
||||
respectGeminiIgnore: {
|
||||
type: 'boolean',
|
||||
label: 'Respect .geminiignore',
|
||||
category: 'File Filtering',
|
||||
requiresRestart: true,
|
||||
default: true,
|
||||
description: 'Respect .geminiignore files when searching',
|
||||
showInDialog: true,
|
||||
},
|
||||
enableRecursiveFileSearch: {
|
||||
type: 'boolean',
|
||||
label: 'Enable Recursive File Search',
|
||||
category: 'File Filtering',
|
||||
requiresRestart: true,
|
||||
default: true,
|
||||
description: 'Enable recursive file search functionality',
|
||||
showInDialog: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
disableAutoUpdate: {
|
||||
type: 'boolean',
|
||||
label: 'Disable Auto Update',
|
||||
category: 'Updates',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description: 'Disable automatic updates',
|
||||
showInDialog: true,
|
||||
},
|
||||
|
||||
selectedAuthType: {
|
||||
type: 'string',
|
||||
label: 'Selected Auth Type',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as AuthType | undefined,
|
||||
description: 'The currently selected authentication type.',
|
||||
showInDialog: false,
|
||||
},
|
||||
useExternalAuth: {
|
||||
type: 'boolean',
|
||||
label: 'Use External Auth',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as boolean | undefined,
|
||||
description: 'Whether to use an external authentication flow.',
|
||||
showInDialog: false,
|
||||
},
|
||||
sandbox: {
|
||||
type: 'object',
|
||||
label: 'Sandbox',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as boolean | string | undefined,
|
||||
description:
|
||||
'Sandbox execution environment (can be a boolean or a path string).',
|
||||
showInDialog: false,
|
||||
},
|
||||
coreTools: {
|
||||
type: 'array',
|
||||
label: 'Core Tools',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as string[] | undefined,
|
||||
description: 'Paths to core tool definitions.',
|
||||
showInDialog: false,
|
||||
},
|
||||
excludeTools: {
|
||||
type: 'array',
|
||||
label: 'Exclude Tools',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as string[] | undefined,
|
||||
description: 'Tool names to exclude from discovery.',
|
||||
showInDialog: false,
|
||||
},
|
||||
toolDiscoveryCommand: {
|
||||
type: 'string',
|
||||
label: 'Tool Discovery Command',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as string | undefined,
|
||||
description: 'Command to run for tool discovery.',
|
||||
showInDialog: false,
|
||||
},
|
||||
toolCallCommand: {
|
||||
type: 'string',
|
||||
label: 'Tool Call Command',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as string | undefined,
|
||||
description: 'Command to run for tool calls.',
|
||||
showInDialog: false,
|
||||
},
|
||||
mcpServerCommand: {
|
||||
type: 'string',
|
||||
label: 'MCP Server Command',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as string | undefined,
|
||||
description: 'Command to start an MCP server.',
|
||||
showInDialog: false,
|
||||
},
|
||||
mcpServers: {
|
||||
type: 'object',
|
||||
label: 'MCP Servers',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: {} as Record<string, MCPServerConfig>,
|
||||
description: 'Configuration for MCP servers.',
|
||||
showInDialog: false,
|
||||
},
|
||||
allowMCPServers: {
|
||||
type: 'array',
|
||||
label: 'Allow MCP Servers',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as string[] | undefined,
|
||||
description: 'A whitelist of MCP servers to allow.',
|
||||
showInDialog: false,
|
||||
},
|
||||
excludeMCPServers: {
|
||||
type: 'array',
|
||||
label: 'Exclude MCP Servers',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as string[] | undefined,
|
||||
description: 'A blacklist of MCP servers to exclude.',
|
||||
showInDialog: false,
|
||||
},
|
||||
telemetry: {
|
||||
type: 'object',
|
||||
label: 'Telemetry',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as TelemetrySettings | undefined,
|
||||
description: 'Telemetry configuration.',
|
||||
showInDialog: false,
|
||||
},
|
||||
bugCommand: {
|
||||
type: 'object',
|
||||
label: 'Bug Command',
|
||||
category: 'Advanced',
|
||||
requiresRestart: false,
|
||||
default: undefined as BugCommandSettings | undefined,
|
||||
description: 'Configuration for the bug report command.',
|
||||
showInDialog: false,
|
||||
},
|
||||
summarizeToolOutput: {
|
||||
type: 'object',
|
||||
label: 'Summarize Tool Output',
|
||||
category: 'Advanced',
|
||||
requiresRestart: false,
|
||||
default: undefined as Record<string, { tokenBudget?: number }> | undefined,
|
||||
description: 'Settings for summarizing tool output.',
|
||||
showInDialog: false,
|
||||
},
|
||||
ideModeFeature: {
|
||||
type: 'boolean',
|
||||
label: 'IDE Mode Feature Flag',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as boolean | undefined,
|
||||
description: 'Internal feature flag for IDE mode.',
|
||||
showInDialog: false,
|
||||
},
|
||||
dnsResolutionOrder: {
|
||||
type: 'string',
|
||||
label: 'DNS Resolution Order',
|
||||
category: 'Advanced',
|
||||
requiresRestart: true,
|
||||
default: undefined as DnsResolutionOrder | undefined,
|
||||
description: 'The DNS resolution order.',
|
||||
showInDialog: false,
|
||||
},
|
||||
excludedProjectEnvVars: {
|
||||
type: 'array',
|
||||
label: 'Excluded Project Environment Variables',
|
||||
category: 'Advanced',
|
||||
requiresRestart: false,
|
||||
default: ['DEBUG', 'DEBUG_MODE'] as string[],
|
||||
description: 'Environment variables to exclude from project context.',
|
||||
showInDialog: false,
|
||||
},
|
||||
disableUpdateNag: {
|
||||
type: 'boolean',
|
||||
label: 'Disable Update Nag',
|
||||
category: 'Updates',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description: 'Disable update notification prompts.',
|
||||
showInDialog: false,
|
||||
},
|
||||
includeDirectories: {
|
||||
type: 'array',
|
||||
label: 'Include Directories',
|
||||
category: 'General',
|
||||
requiresRestart: false,
|
||||
default: [] as string[],
|
||||
description: 'Additional directories to include in the workspace context.',
|
||||
showInDialog: false,
|
||||
},
|
||||
loadMemoryFromIncludeDirectories: {
|
||||
type: 'boolean',
|
||||
label: 'Load Memory From Include Directories',
|
||||
category: 'General',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description: 'Whether to load memory files from include directories.',
|
||||
showInDialog: true,
|
||||
},
|
||||
model: {
|
||||
type: 'string',
|
||||
label: 'Model',
|
||||
category: 'General',
|
||||
requiresRestart: false,
|
||||
default: undefined as string | undefined,
|
||||
description: 'The Gemini model to use for conversations.',
|
||||
showInDialog: false,
|
||||
},
|
||||
hasSeenIdeIntegrationNudge: {
|
||||
type: 'boolean',
|
||||
label: 'Has Seen IDE Integration Nudge',
|
||||
category: 'General',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description: 'Whether the user has seen the IDE integration nudge.',
|
||||
showInDialog: false,
|
||||
},
|
||||
folderTrustFeature: {
|
||||
type: 'boolean',
|
||||
label: 'Folder Trust Feature',
|
||||
category: 'General',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description: 'Enable folder trust feature for enhanced security.',
|
||||
showInDialog: true,
|
||||
},
|
||||
folderTrust: {
|
||||
type: 'boolean',
|
||||
label: 'Folder Trust',
|
||||
category: 'General',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description: 'Setting to track whether Folder trust is enabled.',
|
||||
showInDialog: true,
|
||||
},
|
||||
chatCompression: {
|
||||
type: 'object',
|
||||
label: 'Chat Compression',
|
||||
category: 'General',
|
||||
requiresRestart: false,
|
||||
default: undefined as ChatCompressionSettings | undefined,
|
||||
description: 'Chat compression settings.',
|
||||
showInDialog: false,
|
||||
},
|
||||
showLineNumbers: {
|
||||
type: 'boolean',
|
||||
label: 'Show Line Numbers',
|
||||
category: 'General',
|
||||
requiresRestart: false,
|
||||
default: false,
|
||||
description: 'Show line numbers in the chat.',
|
||||
showInDialog: true,
|
||||
},
|
||||
} as const;
|
||||
|
||||
type InferSettings<T extends SettingsSchema> = {
|
||||
-readonly [K in keyof T]?: T[K] extends { properties: SettingsSchema }
|
||||
? InferSettings<T[K]['properties']>
|
||||
: T[K]['default'] extends boolean
|
||||
? boolean
|
||||
: T[K]['default'];
|
||||
};
|
||||
|
||||
export type Settings = InferSettings<typeof SETTINGS_SCHEMA>;
|
||||
Reference in New Issue
Block a user