diff --git a/docs/cli/settings.md b/docs/cli/settings.md index 85471807ca..2e46dd1fbb 100644 --- a/docs/cli/settings.md +++ b/docs/cli/settings.md @@ -26,7 +26,7 @@ they appear in the UI. | ------------------------------- | ---------------------------------- | ------------------------------------------------------------- | ------- | | Preview Features (e.g., models) | `general.previewFeatures` | Enable preview features (e.g., preview models). | `false` | | Vim Mode | `general.vimMode` | Enable Vim keybindings | `false` | -| Disable Auto Update | `general.disableAutoUpdate` | Disable automatic updates | `false` | +| Enable Auto Update | `general.enableAutoUpdate` | Enable automatic updates. | `true` | | Enable Prompt Completion | `general.enablePromptCompletion` | Enable AI-powered prompt completion suggestions while typing. | `false` | | Debug Keystroke Logging | `general.debugKeystrokeLogging` | Enable debug logging of keystrokes to the console. | `false` | | Enable Session Cleanup | `general.sessionRetention.enabled` | Enable automatic session cleanup | `false` | @@ -39,29 +39,29 @@ they appear in the UI. ### UI -| UI Label | Setting | Description | Default | -| ------------------------------ | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| Hide Window Title | `ui.hideWindowTitle` | Hide the window title bar | `false` | -| Show Thoughts in Title | `ui.showStatusInTitle` | Show Gemini CLI model thoughts in the terminal window title during the working phase | `false` | -| Dynamic Window Title | `ui.dynamicWindowTitle` | Update the terminal window title with current status icons (Ready: ◇, Action Required: ✋, Working: ✦) | `true` | -| Show Home Directory Warning | `ui.showHomeDirectoryWarning` | Show a warning when running Gemini CLI in the home directory. | `true` | -| Hide Tips | `ui.hideTips` | Hide helpful tips in the UI | `false` | -| Hide Banner | `ui.hideBanner` | Hide the application banner | `false` | -| Hide Context Summary | `ui.hideContextSummary` | Hide the context summary (GEMINI.md, MCP servers) above the input. | `false` | -| Hide CWD | `ui.footer.hideCWD` | Hide the current working directory path in the footer. | `false` | -| Hide Sandbox Status | `ui.footer.hideSandboxStatus` | Hide the sandbox status indicator in the footer. | `false` | -| Hide Model Info | `ui.footer.hideModelInfo` | Hide the model name and context usage in the footer. | `false` | -| Hide Context Window Percentage | `ui.footer.hideContextPercentage` | Hides the context window remaining percentage. | `true` | -| Hide Footer | `ui.hideFooter` | Hide the footer from the UI | `false` | -| Show Memory Usage | `ui.showMemoryUsage` | Display memory usage information in the UI | `false` | -| Show Line Numbers | `ui.showLineNumbers` | Show line numbers in the chat. | `true` | -| Show Citations | `ui.showCitations` | Show citations for generated text in the chat. | `false` | -| Show Model Info In Chat | `ui.showModelInfoInChat` | Show the model name in the chat for each model turn. | `false` | -| Use Full Width | `ui.useFullWidth` | Use the entire width of the terminal for output. | `true` | -| Use Alternate Screen Buffer | `ui.useAlternateBuffer` | Use an alternate screen buffer for the UI, preserving shell history. | `false` | -| Incremental Rendering | `ui.incrementalRendering` | Enable incremental rendering for the UI. This option will reduce flickering but may cause rendering artifacts. Only supported when useAlternateBuffer is enabled. | `true` | -| Disable Loading Phrases | `ui.accessibility.disableLoadingPhrases` | Disable loading phrases for accessibility | `false` | -| Screen Reader Mode | `ui.accessibility.screenReader` | Render output in plain-text to be more screen reader accessible | `false` | +| UI Label | Setting | Description | Default | +| ------------------------------ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| Hide Window Title | `ui.hideWindowTitle` | Hide the window title bar | `false` | +| Show Thoughts in Title | `ui.showStatusInTitle` | Show Gemini CLI model thoughts in the terminal window title during the working phase | `false` | +| Dynamic Window Title | `ui.dynamicWindowTitle` | Update the terminal window title with current status icons (Ready: ◇, Action Required: ✋, Working: ✦) | `true` | +| Show Home Directory Warning | `ui.showHomeDirectoryWarning` | Show a warning when running Gemini CLI in the home directory. | `true` | +| Hide Tips | `ui.hideTips` | Hide helpful tips in the UI | `false` | +| Hide Banner | `ui.hideBanner` | Hide the application banner | `false` | +| Hide Context Summary | `ui.hideContextSummary` | Hide the context summary (GEMINI.md, MCP servers) above the input. | `false` | +| Hide CWD | `ui.footer.hideCWD` | Hide the current working directory path in the footer. | `false` | +| Hide Sandbox Status | `ui.footer.hideSandboxStatus` | Hide the sandbox status indicator in the footer. | `false` | +| Hide Model Info | `ui.footer.hideModelInfo` | Hide the model name and context usage in the footer. | `false` | +| Hide Context Window Percentage | `ui.footer.hideContextPercentage` | Hides the context window remaining percentage. | `true` | +| Hide Footer | `ui.hideFooter` | Hide the footer from the UI | `false` | +| Show Memory Usage | `ui.showMemoryUsage` | Display memory usage information in the UI | `false` | +| Show Line Numbers | `ui.showLineNumbers` | Show line numbers in the chat. | `true` | +| Show Citations | `ui.showCitations` | Show citations for generated text in the chat. | `false` | +| Show Model Info In Chat | `ui.showModelInfoInChat` | Show the model name in the chat for each model turn. | `false` | +| Use Full Width | `ui.useFullWidth` | Use the entire width of the terminal for output. | `true` | +| Use Alternate Screen Buffer | `ui.useAlternateBuffer` | Use an alternate screen buffer for the UI, preserving shell history. | `false` | +| Incremental Rendering | `ui.incrementalRendering` | Enable incremental rendering for the UI. This option will reduce flickering but may cause rendering artifacts. Only supported when useAlternateBuffer is enabled. | `true` | +| Enable Loading Phrases | `ui.accessibility.enableLoadingPhrases` | Enable loading phrases during operations. | `true` | +| Screen Reader Mode | `ui.accessibility.screenReader` | Render output in plain-text to be more screen reader accessible | `false` | ### IDE @@ -86,7 +86,7 @@ they appear in the UI. | Respect .gitignore | `context.fileFiltering.respectGitIgnore` | Respect .gitignore files when searching. | `true` | | Respect .geminiignore | `context.fileFiltering.respectGeminiIgnore` | Respect .geminiignore files when searching. | `true` | | Enable Recursive File Search | `context.fileFiltering.enableRecursiveFileSearch` | Enable recursive file search functionality when completing @ references in the prompt. | `true` | -| Disable Fuzzy Search | `context.fileFiltering.disableFuzzySearch` | Disable fuzzy search when searching for files. | `false` | +| Enable Fuzzy Search | `context.fileFiltering.enableFuzzySearch` | Enable fuzzy search when searching for files. | `true` | ### Tools diff --git a/docs/get-started/configuration.md b/docs/get-started/configuration.md index de9c6db5e7..6f24467c5e 100644 --- a/docs/get-started/configuration.md +++ b/docs/get-started/configuration.md @@ -110,13 +110,13 @@ their corresponding top-level category object in your `settings.json` file. - **Description:** Enable Vim keybindings - **Default:** `false` -- **`general.disableAutoUpdate`** (boolean): - - **Description:** Disable automatic updates - - **Default:** `false` +- **`general.enableAutoUpdate`** (boolean): + - **Description:** Enable automatic updates. + - **Default:** `true` -- **`general.disableUpdateNag`** (boolean): - - **Description:** Disable update notification prompts. - - **Default:** `false` +- **`general.enableAutoUpdateNotification`** (boolean): + - **Description:** Enable update notification prompts. + - **Default:** `true` - **`general.checkpointing.enabled`** (boolean): - **Description:** Enable session checkpointing for recovery @@ -266,9 +266,9 @@ their corresponding top-level category object in your `settings.json` file. provided, the CLI cycles through these instead of the defaults. - **Default:** `[]` -- **`ui.accessibility.disableLoadingPhrases`** (boolean): - - **Description:** Disable loading phrases for accessibility - - **Default:** `false` +- **`ui.accessibility.enableLoadingPhrases`** (boolean): + - **Description:** Enable loading phrases during operations. + - **Default:** `true` - **Requires restart:** Yes - **`ui.accessibility.screenReader`** (boolean): @@ -607,9 +607,9 @@ their corresponding top-level category object in your `settings.json` file. - **Default:** `true` - **Requires restart:** Yes -- **`context.fileFiltering.disableFuzzySearch`** (boolean): - - **Description:** Disable fuzzy search when searching for files. - - **Default:** `false` +- **`context.fileFiltering.enableFuzzySearch`** (boolean): + - **Description:** Enable fuzzy search when searching for files. + - **Default:** `true` - **Requires restart:** Yes #### `tools` diff --git a/packages/cli/src/config/config.test.ts b/packages/cli/src/config/config.test.ts index 59d1f4d906..a1ffeb0c36 100644 --- a/packages/cli/src/config/config.test.ts +++ b/packages/cli/src/config/config.test.ts @@ -2193,13 +2193,13 @@ describe('loadCliConfig fileFiltering', () => { value: boolean; }> = [ { - property: 'disableFuzzySearch', - getter: (c) => c.getFileFilteringDisableFuzzySearch(), + property: 'enableFuzzySearch', + getter: (c) => c.getFileFilteringEnableFuzzySearch(), value: true, }, { - property: 'disableFuzzySearch', - getter: (c) => c.getFileFilteringDisableFuzzySearch(), + property: 'enableFuzzySearch', + getter: (c) => c.getFileFilteringEnableFuzzySearch(), value: false, }, { diff --git a/packages/cli/src/config/settings.test.ts b/packages/cli/src/config/settings.test.ts index 004b60ea28..d3ca45ab08 100644 --- a/packages/cli/src/config/settings.test.ts +++ b/packages/cli/src/config/settings.test.ts @@ -44,7 +44,7 @@ vi.mock('./settingsSchema.js', async (importOriginal) => { }); // NOW import everything else, including the (now effectively re-exported) settings.js -import * as pathActual from 'node:path'; // Restored for MOCK_WORKSPACE_SETTINGS_PATH +import * as path from 'node:path'; // Restored for MOCK_WORKSPACE_SETTINGS_PATH import { describe, it, @@ -69,6 +69,10 @@ import { saveSettings, type SettingsFile, getDefaultsFromSchema, + loadEnvironment, + migrateDeprecatedSettings, + SettingScope, + LoadedSettings, } from './settings.js'; import { FatalConfigError, GEMINI_DIR } from '@google/gemini-cli-core'; import { updateSettingsFilePreservingFormat } from '../utils/commentJson.js'; @@ -80,7 +84,7 @@ import { const MOCK_WORKSPACE_DIR = '/mock/workspace'; // Use the (mocked) GEMINI_DIR for consistency -const MOCK_WORKSPACE_SETTINGS_PATH = pathActual.join( +const MOCK_WORKSPACE_SETTINGS_PATH = path.join( MOCK_WORKSPACE_DIR, GEMINI_DIR, 'settings.json', @@ -1602,6 +1606,363 @@ describe('Settings Loading and Merging', () => { }); }); + describe('with workspace trust', () => { + it('should merge workspace settings when workspace is trusted', () => { + (mockFsExistsSync as Mock).mockReturnValue(true); + const userSettingsContent = { + ui: { theme: 'dark' }, + tools: { sandbox: false }, + }; + const workspaceSettingsContent = { + tools: { sandbox: true }, + context: { fileName: 'WORKSPACE.md' }, + }; + + (fs.readFileSync as Mock).mockImplementation( + (p: fs.PathOrFileDescriptor) => { + 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.tools?.sandbox).toBe(true); + expect(settings.merged.context?.fileName).toBe('WORKSPACE.md'); + expect(settings.merged.ui?.theme).toBe('dark'); + }); + + it('should NOT merge workspace settings when workspace is not trusted', () => { + vi.mocked(isWorkspaceTrusted).mockReturnValue({ + isTrusted: false, + source: 'file', + }); + (mockFsExistsSync as Mock).mockReturnValue(true); + const userSettingsContent = { + ui: { theme: 'dark' }, + tools: { sandbox: false }, + context: { fileName: 'USER.md' }, + }; + const workspaceSettingsContent = { + tools: { sandbox: true }, + context: { fileName: 'WORKSPACE.md' }, + }; + + (fs.readFileSync as Mock).mockImplementation( + (p: fs.PathOrFileDescriptor) => { + 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.tools?.sandbox).toBe(false); // User setting + expect(settings.merged.context?.fileName).toBe('USER.md'); // User setting + expect(settings.merged.ui?.theme).toBe('dark'); // User setting + }); + }); + + describe('loadEnvironment', () => { + function setup({ + isFolderTrustEnabled = true, + isWorkspaceTrustedValue = true, + }) { + delete process.env['TESTTEST']; // reset + const geminiEnvPath = path.resolve(path.join(GEMINI_DIR, '.env')); + + vi.mocked(isWorkspaceTrusted).mockReturnValue({ + isTrusted: isWorkspaceTrustedValue, + source: 'file', + }); + (mockFsExistsSync as Mock).mockImplementation((p: fs.PathLike) => + [USER_SETTINGS_PATH, geminiEnvPath].includes(p.toString()), + ); + const userSettingsContent: Settings = { + ui: { + theme: 'dark', + }, + security: { + folderTrust: { + enabled: isFolderTrustEnabled, + }, + }, + context: { + fileName: 'USER_CONTEXT.md', + }, + }; + (fs.readFileSync as Mock).mockImplementation( + (p: fs.PathOrFileDescriptor) => { + if (p === USER_SETTINGS_PATH) + return JSON.stringify(userSettingsContent); + if (p === geminiEnvPath) return 'TESTTEST=1234'; + return '{}'; + }, + ); + } + + it('sets environment variables from .env files', () => { + setup({ isFolderTrustEnabled: false, isWorkspaceTrustedValue: true }); + loadEnvironment(loadSettings(MOCK_WORKSPACE_DIR).merged); + + expect(process.env['TESTTEST']).toEqual('1234'); + }); + + it('does not load env files from untrusted spaces', () => { + setup({ isFolderTrustEnabled: true, isWorkspaceTrustedValue: false }); + loadEnvironment(loadSettings(MOCK_WORKSPACE_DIR).merged); + + expect(process.env['TESTTEST']).not.toEqual('1234'); + }); + }); + + describe('migrateDeprecatedSettings', () => { + let mockFsExistsSync: Mock; + let mockFsReadFileSync: Mock; + + beforeEach(() => { + vi.resetAllMocks(); + mockFsExistsSync = vi.mocked(fs.existsSync); + mockFsExistsSync.mockReturnValue(true); + mockFsReadFileSync = vi.mocked(fs.readFileSync); + mockFsReadFileSync.mockReturnValue('{}'); + vi.mocked(isWorkspaceTrusted).mockReturnValue({ + isTrusted: true, + source: undefined, + }); + }); + + afterEach(() => { + vi.restoreAllMocks(); + }); + + it('should not do anything if there are no deprecated settings', () => { + const userSettingsContent = { + extensions: { + enabled: ['user-ext-1'], + }, + }; + const workspaceSettingsContent = { + someOtherSetting: 'value', + }; + + (fs.readFileSync as Mock).mockImplementation( + (p: fs.PathOrFileDescriptor) => { + if (p === USER_SETTINGS_PATH) + return JSON.stringify(userSettingsContent); + if (p === MOCK_WORKSPACE_SETTINGS_PATH) + return JSON.stringify(workspaceSettingsContent); + return '{}'; + }, + ); + + const setValueSpy = vi.spyOn(LoadedSettings.prototype, 'setValue'); + const loadedSettings = loadSettings(MOCK_WORKSPACE_DIR); + setValueSpy.mockClear(); + + migrateDeprecatedSettings(loadedSettings, true); + + expect(setValueSpy).not.toHaveBeenCalled(); + }); + + it('should migrate general.disableAutoUpdate to general.enableAutoUpdate with inverted value', () => { + const userSettingsContent = { + general: { + disableAutoUpdate: true, + }, + }; + + (fs.readFileSync as Mock).mockImplementation( + (p: fs.PathOrFileDescriptor) => { + if (p === USER_SETTINGS_PATH) + return JSON.stringify(userSettingsContent); + return '{}'; + }, + ); + + const setValueSpy = vi.spyOn(LoadedSettings.prototype, 'setValue'); + const loadedSettings = loadSettings(MOCK_WORKSPACE_DIR); + + migrateDeprecatedSettings(loadedSettings, true); + + // Should set new value to false (inverted from true) + expect(setValueSpy).toHaveBeenCalledWith( + SettingScope.User, + 'general', + expect.objectContaining({ enableAutoUpdate: false }), + ); + }); + + it('should migrate all 4 inverted boolean settings', () => { + const userSettingsContent = { + general: { + disableAutoUpdate: false, + disableUpdateNag: true, + }, + context: { + fileFiltering: { + disableFuzzySearch: false, + }, + }, + ui: { + accessibility: { + disableLoadingPhrases: true, + }, + }, + }; + + (fs.readFileSync as Mock).mockImplementation( + (p: fs.PathOrFileDescriptor) => { + if (p === USER_SETTINGS_PATH) + return JSON.stringify(userSettingsContent); + return '{}'; + }, + ); + + const setValueSpy = vi.spyOn(LoadedSettings.prototype, 'setValue'); + const loadedSettings = loadSettings(MOCK_WORKSPACE_DIR); + + migrateDeprecatedSettings(loadedSettings, true); + + // Check that general settings were migrated with inverted values + expect(setValueSpy).toHaveBeenCalledWith( + SettingScope.User, + 'general', + expect.objectContaining({ enableAutoUpdate: true }), + ); + expect(setValueSpy).toHaveBeenCalledWith( + SettingScope.User, + 'general', + expect.objectContaining({ enableAutoUpdateNotification: false }), + ); + + // Check context.fileFiltering was migrated + expect(setValueSpy).toHaveBeenCalledWith( + SettingScope.User, + 'context', + expect.objectContaining({ + fileFiltering: expect.objectContaining({ enableFuzzySearch: true }), + }), + ); + + // Check ui.accessibility was migrated + expect(setValueSpy).toHaveBeenCalledWith( + SettingScope.User, + 'ui', + expect.objectContaining({ + accessibility: expect.objectContaining({ + enableLoadingPhrases: false, + }), + }), + ); + }); + + it('should prioritize new settings over deprecated ones and respect removeDeprecated flag', () => { + const userSettingsContent = { + general: { + disableAutoUpdate: true, + enableAutoUpdate: true, // Trust this (true) over disableAutoUpdate (true -> false) + }, + context: { + fileFiltering: { + disableFuzzySearch: false, + enableFuzzySearch: false, // Trust this (false) over disableFuzzySearch (false -> true) + }, + }, + }; + + const loadedSettings = new LoadedSettings( + { + path: getSystemSettingsPath(), + settings: {}, + originalSettings: {}, + }, + { + path: getSystemDefaultsPath(), + settings: {}, + originalSettings: {}, + }, + { + path: USER_SETTINGS_PATH, + settings: userSettingsContent as unknown as Settings, + originalSettings: userSettingsContent as unknown as Settings, + }, + { + path: MOCK_WORKSPACE_SETTINGS_PATH, + settings: {}, + originalSettings: {}, + }, + true, + ); + + const setValueSpy = vi.spyOn(loadedSettings, 'setValue'); + + // 1. removeDeprecated = false (default) + migrateDeprecatedSettings(loadedSettings); + + // Should still have old settings + expect( + loadedSettings.forScope(SettingScope.User).settings.general, + ).toHaveProperty('disableAutoUpdate'); + expect( + ( + loadedSettings.forScope(SettingScope.User).settings.context as { + fileFiltering: { disableFuzzySearch: boolean }; + } + ).fileFiltering, + ).toHaveProperty('disableFuzzySearch'); + + // 2. removeDeprecated = true + migrateDeprecatedSettings(loadedSettings, true); + + // Should remove disableAutoUpdate and trust enableAutoUpdate: true + expect(setValueSpy).toHaveBeenCalledWith(SettingScope.User, 'general', { + enableAutoUpdate: true, + }); + + // Should remove disableFuzzySearch and trust enableFuzzySearch: false + expect(setValueSpy).toHaveBeenCalledWith(SettingScope.User, 'context', { + fileFiltering: { enableFuzzySearch: false }, + }); + }); + + it('should trigger migration automatically during loadSettings', () => { + mockFsExistsSync.mockImplementation( + (p: fs.PathLike) => p === USER_SETTINGS_PATH, + ); + const userSettingsContent = { + general: { + disableAutoUpdate: true, + }, + }; + (fs.readFileSync as Mock).mockImplementation( + (p: fs.PathOrFileDescriptor) => { + if (p === USER_SETTINGS_PATH) + return JSON.stringify(userSettingsContent); + return '{}'; + }, + ); + + const settings = loadSettings(MOCK_WORKSPACE_DIR); + + // Verify it was migrated in the merged settings + expect(settings.merged.general?.enableAutoUpdate).toBe(false); + + // Verify it was saved back to disk (via setValue calling updateSettingsFilePreservingFormat) + expect(updateSettingsFilePreservingFormat).toHaveBeenCalledWith( + USER_SETTINGS_PATH, + expect.objectContaining({ + general: expect.objectContaining({ enableAutoUpdate: false }), + }), + ); + }); + }); + describe('saveSettings', () => { it('should save settings using updateSettingsFilePreservingFormat', () => { const mockUpdateSettings = vi.mocked(updateSettingsFilePreservingFormat); diff --git a/packages/cli/src/config/settings.ts b/packages/cli/src/config/settings.ts index 0ad4dabe1e..545866cddf 100644 --- a/packages/cli/src/config/settings.ts +++ b/packages/cli/src/config/settings.ts @@ -148,7 +148,7 @@ export interface SummarizeToolOutputSettings { } export interface AccessibilitySettings { - disableLoadingPhrases?: boolean; + enableLoadingPhrases?: boolean; screenReader?: boolean; } @@ -613,7 +613,7 @@ export function loadSettings( ); } - return new LoadedSettings( + const loadedSettings = new LoadedSettings( { path: systemSettingsPath, settings: systemSettings, @@ -641,6 +641,171 @@ export function loadSettings( isTrusted, settingsErrors, ); + + // Automatically migrate deprecated settings when loading. + migrateDeprecatedSettings(loadedSettings); + + return loadedSettings; +} + +/** + * Migrates deprecated settings to their new counterparts. + * + * TODO: After a couple of weeks (around early Feb 2026), we should start removing + * the deprecated settings from the settings files by default. + * + * @returns true if any changes were made and need to be saved. + */ +export function migrateDeprecatedSettings( + loadedSettings: LoadedSettings, + removeDeprecated = false, +): boolean { + let anyModified = false; + const processScope = (scope: LoadableSettingScope) => { + const settings = loadedSettings.forScope(scope).settings; + + // Migrate inverted boolean settings (disableX -> enableX) + // These settings were renamed and their boolean logic inverted + const generalSettings = settings.general as + | Record + | undefined; + const uiSettings = settings.ui as Record | undefined; + const contextSettings = settings.context as + | Record + | undefined; + + // Migrate general settings (disableAutoUpdate, disableUpdateNag) + if (generalSettings) { + const newGeneral: Record = { ...generalSettings }; + let modified = false; + + if (typeof newGeneral['disableAutoUpdate'] === 'boolean') { + if (typeof newGeneral['enableAutoUpdate'] === 'boolean') { + // Both exist, trust the new one + if (removeDeprecated) { + delete newGeneral['disableAutoUpdate']; + modified = true; + } + } else { + const oldValue = newGeneral['disableAutoUpdate']; + newGeneral['enableAutoUpdate'] = !oldValue; + if (removeDeprecated) { + delete newGeneral['disableAutoUpdate']; + } + modified = true; + } + } + + if (typeof newGeneral['disableUpdateNag'] === 'boolean') { + if (typeof newGeneral['enableAutoUpdateNotification'] === 'boolean') { + // Both exist, trust the new one + if (removeDeprecated) { + delete newGeneral['disableUpdateNag']; + modified = true; + } + } else { + const oldValue = newGeneral['disableUpdateNag']; + newGeneral['enableAutoUpdateNotification'] = !oldValue; + if (removeDeprecated) { + delete newGeneral['disableUpdateNag']; + } + modified = true; + } + } + + if (modified) { + loadedSettings.setValue(scope, 'general', newGeneral); + anyModified = true; + } + } + + // Migrate ui settings + if (uiSettings) { + const newUi: Record = { ...uiSettings }; + let modified = false; + + // Migrate ui.accessibility.disableLoadingPhrases -> ui.accessibility.enableLoadingPhrases + const accessibilitySettings = newUi['accessibility'] as + | Record + | undefined; + if ( + accessibilitySettings && + typeof accessibilitySettings['disableLoadingPhrases'] === 'boolean' + ) { + const newAccessibility: Record = { + ...accessibilitySettings, + }; + if ( + typeof accessibilitySettings['enableLoadingPhrases'] === 'boolean' + ) { + // Both exist, trust the new one + if (removeDeprecated) { + delete newAccessibility['disableLoadingPhrases']; + newUi['accessibility'] = newAccessibility; + modified = true; + } + } else { + const oldValue = accessibilitySettings['disableLoadingPhrases']; + newAccessibility['enableLoadingPhrases'] = !oldValue; + if (removeDeprecated) { + delete newAccessibility['disableLoadingPhrases']; + } + newUi['accessibility'] = newAccessibility; + modified = true; + } + } + + if (modified) { + loadedSettings.setValue(scope, 'ui', newUi); + anyModified = true; + } + } + + // Migrate context settings + if (contextSettings) { + const newContext: Record = { ...contextSettings }; + let modified = false; + + // Migrate context.fileFiltering.disableFuzzySearch -> context.fileFiltering.enableFuzzySearch + const fileFilteringSettings = newContext['fileFiltering'] as + | Record + | undefined; + if ( + fileFilteringSettings && + typeof fileFilteringSettings['disableFuzzySearch'] === 'boolean' + ) { + const newFileFiltering: Record = { + ...fileFilteringSettings, + }; + if (typeof fileFilteringSettings['enableFuzzySearch'] === 'boolean') { + // Both exist, trust the new one + if (removeDeprecated) { + delete newFileFiltering['disableFuzzySearch']; + newContext['fileFiltering'] = newFileFiltering; + modified = true; + } + } else { + const oldValue = fileFilteringSettings['disableFuzzySearch']; + newFileFiltering['enableFuzzySearch'] = !oldValue; + if (removeDeprecated) { + delete newFileFiltering['disableFuzzySearch']; + } + newContext['fileFiltering'] = newFileFiltering; + modified = true; + } + } + + if (modified) { + loadedSettings.setValue(scope, 'context', newContext); + anyModified = true; + } + } + }; + + processScope(SettingScope.User); + processScope(SettingScope.Workspace); + + return anyModified; } export function saveSettings(settingsFile: SettingsFile): void { diff --git a/packages/cli/src/config/settingsSchema.test.ts b/packages/cli/src/config/settingsSchema.test.ts index 03f7a6e313..1daba61176 100644 --- a/packages/cli/src/config/settingsSchema.test.ts +++ b/packages/cli/src/config/settingsSchema.test.ts @@ -79,7 +79,7 @@ describe('SettingsSchema', () => { ).toBeDefined(); expect( getSettingsSchema().ui?.properties?.accessibility.properties - ?.disableLoadingPhrases.type, + ?.enableLoadingPhrases.type, ).toBe('boolean'); }); @@ -170,7 +170,7 @@ describe('SettingsSchema', () => { true, ); expect( - getSettingsSchema().general.properties.disableAutoUpdate.showInDialog, + getSettingsSchema().general.properties.enableAutoUpdate.showInDialog, ).toBe(true); expect( getSettingsSchema().ui.properties.hideWindowTitle.showInDialog, diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts index a9c49ce581..ba850051a9 100644 --- a/packages/cli/src/config/settingsSchema.ts +++ b/packages/cli/src/config/settingsSchema.ts @@ -191,22 +191,22 @@ const SETTINGS_SCHEMA = { description: 'Enable Vim keybindings', showInDialog: true, }, - disableAutoUpdate: { + enableAutoUpdate: { type: 'boolean', - label: 'Disable Auto Update', + label: 'Enable Auto Update', category: 'General', requiresRestart: false, - default: false, - description: 'Disable automatic updates', + default: true, + description: 'Enable automatic updates.', showInDialog: true, }, - disableUpdateNag: { + enableAutoUpdateNotification: { type: 'boolean', - label: 'Disable Update Nag', + label: 'Enable Auto Update Notification', category: 'General', requiresRestart: false, - default: false, - description: 'Disable update notification prompts.', + default: true, + description: 'Enable update notification prompts.', showInDialog: false, }, checkpointing: { @@ -577,13 +577,13 @@ const SETTINGS_SCHEMA = { description: 'Accessibility settings.', showInDialog: false, properties: { - disableLoadingPhrases: { + enableLoadingPhrases: { type: 'boolean', - label: 'Disable Loading Phrases', + label: 'Enable Loading Phrases', category: 'UI', requiresRestart: true, - default: false, - description: 'Disable loading phrases for accessibility', + default: true, + description: 'Enable loading phrases during operations.', showInDialog: true, }, screenReader: { @@ -914,13 +914,13 @@ const SETTINGS_SCHEMA = { `, showInDialog: true, }, - disableFuzzySearch: { + enableFuzzySearch: { type: 'boolean', - label: 'Disable Fuzzy Search', + label: 'Enable Fuzzy Search', category: 'Context', requiresRestart: true, - default: false, - description: 'Disable fuzzy search when searching for files.', + default: true, + description: 'Enable fuzzy search when searching for files.', showInDialog: true, }, }, diff --git a/packages/cli/src/ui/components/Composer.test.tsx b/packages/cli/src/ui/components/Composer.test.tsx index 73e68684a5..8368109a8e 100644 --- a/packages/cli/src/ui/components/Composer.test.tsx +++ b/packages/cli/src/ui/components/Composer.test.tsx @@ -283,7 +283,7 @@ describe('Composer', () => { thought: { subject: 'Hidden', description: 'Should not show' }, }); const config = createMockConfig({ - getAccessibility: vi.fn(() => ({ disableLoadingPhrases: true })), + getAccessibility: vi.fn(() => ({ enableLoadingPhrases: false })), }); const { lastFrame } = renderComposer(uiState, undefined, config); diff --git a/packages/cli/src/ui/components/Composer.tsx b/packages/cli/src/ui/components/Composer.tsx index b7db494409..da1747c114 100644 --- a/packages/cli/src/ui/components/Composer.tsx +++ b/packages/cli/src/ui/components/Composer.tsx @@ -58,12 +58,12 @@ export const Composer = () => { { // 'general.vimMode' has description 'Enable Vim keybindings' in settingsSchema.ts expect(output).toContain('Vim Mode'); expect(output).toContain('Enable Vim keybindings'); - // 'general.disableAutoUpdate' has description 'Disable automatic updates' - expect(output).toContain('Disable Auto Update'); - expect(output).toContain('Disable automatic updates'); + // 'general.enableAutoUpdate' has description 'Enable automatic updates.' + expect(output).toContain('Enable Auto Update'); + expect(output).toContain('Enable automatic updates.'); }); }); @@ -353,7 +353,7 @@ describe('SettingsDialog', () => { }); await waitFor(() => { - expect(lastFrame()).toContain('Disable Auto Update'); + expect(lastFrame()).toContain('Enable Auto Update'); }); // Navigate up @@ -1236,7 +1236,7 @@ describe('SettingsDialog', () => { expect(lastFrame()).toContain('nonexistentsetting'); expect(lastFrame()).toContain(''); expect(lastFrame()).not.toContain('Vim Mode'); // Should not contain any settings - expect(lastFrame()).not.toContain('Disable Auto Update'); // Should not contain any settings + expect(lastFrame()).not.toContain('Enable Auto Update'); // Should not contain any settings }); unmount(); @@ -1263,7 +1263,7 @@ describe('SettingsDialog', () => { userSettings: { general: { vimMode: true, - disableAutoUpdate: true, + enableAutoUpdate: false, debugKeystrokeLogging: true, enablePromptCompletion: true, }, @@ -1274,7 +1274,7 @@ describe('SettingsDialog', () => { showLineNumbers: true, showCitations: true, accessibility: { - disableLoadingPhrases: true, + enableLoadingPhrases: false, screenReader: true, }, }, @@ -1287,7 +1287,7 @@ describe('SettingsDialog', () => { respectGitIgnore: true, respectGeminiIgnore: true, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }, }, tools: { @@ -1310,7 +1310,7 @@ describe('SettingsDialog', () => { userSettings: { general: { vimMode: false, - disableAutoUpdate: true, + enableAutoUpdate: false, }, ui: { showMemoryUsage: true, @@ -1348,7 +1348,7 @@ describe('SettingsDialog', () => { userSettings: { ui: { accessibility: { - disableLoadingPhrases: true, + enableLoadingPhrases: false, screenReader: true, }, showMemoryUsage: true, @@ -1370,7 +1370,7 @@ describe('SettingsDialog', () => { respectGitIgnore: false, respectGeminiIgnore: true, enableRecursiveFileSearch: false, - disableFuzzySearch: true, + enableFuzzySearch: false, }, loadMemoryFromIncludeDirectories: true, discoveryMaxDirs: 100, @@ -1409,7 +1409,7 @@ describe('SettingsDialog', () => { userSettings: { general: { vimMode: false, - disableAutoUpdate: false, + enableAutoUpdate: true, debugKeystrokeLogging: false, enablePromptCompletion: false, }, @@ -1420,7 +1420,7 @@ describe('SettingsDialog', () => { showLineNumbers: false, showCitations: false, accessibility: { - disableLoadingPhrases: false, + enableLoadingPhrases: true, screenReader: false, }, }, @@ -1433,7 +1433,7 @@ describe('SettingsDialog', () => { respectGitIgnore: false, respectGeminiIgnore: false, enableRecursiveFileSearch: false, - disableFuzzySearch: false, + enableFuzzySearch: true, }, }, tools: { diff --git a/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap index 144b936ab6..238ba8b5eb 100644 --- a/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap @@ -16,8 +16,8 @@ exports[`SettingsDialog > Initial Rendering > should render settings list with v │ Vim Mode false │ │ Enable Vim keybindings │ │ │ -│ Disable Auto Update false │ -│ Disable automatic updates │ +│ Enable Auto Update true │ +│ Enable automatic updates. │ │ │ │ Enable Prompt Completion false │ │ Enable AI-powered prompt completion suggestions while typing. │ @@ -62,8 +62,8 @@ exports[`SettingsDialog > Snapshot Tests > should render 'accessibility settings │ Vim Mode true* │ │ Enable Vim keybindings │ │ │ -│ Disable Auto Update false │ -│ Disable automatic updates │ +│ Enable Auto Update true │ +│ Enable automatic updates. │ │ │ │ Enable Prompt Completion false │ │ Enable AI-powered prompt completion suggestions while typing. │ @@ -108,8 +108,8 @@ exports[`SettingsDialog > Snapshot Tests > should render 'all boolean settings d │ Vim Mode false* │ │ Enable Vim keybindings │ │ │ -│ Disable Auto Update false* │ -│ Disable automatic updates │ +│ Enable Auto Update true* │ +│ Enable automatic updates. │ │ │ │ Enable Prompt Completion false* │ │ Enable AI-powered prompt completion suggestions while typing. │ @@ -154,8 +154,8 @@ exports[`SettingsDialog > Snapshot Tests > should render 'default state' correct │ Vim Mode false │ │ Enable Vim keybindings │ │ │ -│ Disable Auto Update false │ -│ Disable automatic updates │ +│ Enable Auto Update true │ +│ Enable automatic updates. │ │ │ │ Enable Prompt Completion false │ │ Enable AI-powered prompt completion suggestions while typing. │ @@ -200,8 +200,8 @@ exports[`SettingsDialog > Snapshot Tests > should render 'file filtering setting │ Vim Mode false │ │ Enable Vim keybindings │ │ │ -│ Disable Auto Update false │ -│ Disable automatic updates │ +│ Enable Auto Update true │ +│ Enable automatic updates. │ │ │ │ Enable Prompt Completion false │ │ Enable AI-powered prompt completion suggestions while typing. │ @@ -246,8 +246,8 @@ exports[`SettingsDialog > Snapshot Tests > should render 'focused on scope selec │ Vim Mode false │ │ Enable Vim keybindings │ │ │ -│ Disable Auto Update false │ -│ Disable automatic updates │ +│ Enable Auto Update true │ +│ Enable automatic updates. │ │ │ │ Enable Prompt Completion false │ │ Enable AI-powered prompt completion suggestions while typing. │ @@ -292,8 +292,8 @@ exports[`SettingsDialog > Snapshot Tests > should render 'mixed boolean and numb │ Vim Mode false* │ │ Enable Vim keybindings │ │ │ -│ Disable Auto Update true* │ -│ Disable automatic updates │ +│ Enable Auto Update false* │ +│ Enable automatic updates. │ │ │ │ Enable Prompt Completion false │ │ Enable AI-powered prompt completion suggestions while typing. │ @@ -338,8 +338,8 @@ exports[`SettingsDialog > Snapshot Tests > should render 'tools and security set │ Vim Mode false │ │ Enable Vim keybindings │ │ │ -│ Disable Auto Update false │ -│ Disable automatic updates │ +│ Enable Auto Update true │ +│ Enable automatic updates. │ │ │ │ Enable Prompt Completion false │ │ Enable AI-powered prompt completion suggestions while typing. │ @@ -384,8 +384,8 @@ exports[`SettingsDialog > Snapshot Tests > should render 'various boolean settin │ Vim Mode true* │ │ Enable Vim keybindings │ │ │ -│ Disable Auto Update true* │ -│ Disable automatic updates │ +│ Enable Auto Update false* │ +│ Enable automatic updates. │ │ │ │ Enable Prompt Completion true* │ │ Enable AI-powered prompt completion suggestions while typing. │ diff --git a/packages/cli/src/ui/hooks/useAtCompletion.test.ts b/packages/cli/src/ui/hooks/useAtCompletion.test.ts index c4e7c98d19..b05e9ff63b 100644 --- a/packages/cli/src/ui/hooks/useAtCompletion.test.ts +++ b/packages/cli/src/ui/hooks/useAtCompletion.test.ts @@ -48,7 +48,7 @@ describe('useAtCompletion', () => { respectGeminiIgnore: true, })), getEnableRecursiveFileSearch: () => true, - getFileFilteringDisableFuzzySearch: () => false, + getFileFilteringEnableFuzzySearch: () => true, getResourceRegistry: vi.fn().mockReturnValue({ getAllResources: () => [], }), @@ -153,7 +153,7 @@ describe('useAtCompletion', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -276,7 +276,7 @@ describe('useAtCompletion', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await realFileSearch.initialize(); @@ -558,7 +558,7 @@ describe('useAtCompletion', () => { respectGitIgnore: true, respectGeminiIgnore: true, })), - getFileFilteringDisableFuzzySearch: () => false, + getFileFilteringEnableFuzzySearch: () => true, } as unknown as Config; const { result } = renderHook(() => diff --git a/packages/cli/src/ui/hooks/useAtCompletion.ts b/packages/cli/src/ui/hooks/useAtCompletion.ts index c5f9ddb888..bea591d261 100644 --- a/packages/cli/src/ui/hooks/useAtCompletion.ts +++ b/packages/cli/src/ui/hooks/useAtCompletion.ts @@ -258,8 +258,8 @@ export function useAtCompletion(props: UseAtCompletionProps): void { cacheTtl: 30, // 30 seconds enableRecursiveFileSearch: config?.getEnableRecursiveFileSearch() ?? true, - disableFuzzySearch: - config?.getFileFilteringDisableFuzzySearch() ?? false, + enableFuzzySearch: + config?.getFileFilteringEnableFuzzySearch() ?? true, maxFiles: config?.getFileFilteringOptions()?.maxFileCount, }); await searcher.initialize(); diff --git a/packages/cli/src/ui/hooks/useAtCompletion_agents.test.ts b/packages/cli/src/ui/hooks/useAtCompletion_agents.test.ts index 53b416ce6a..054abb47ca 100644 --- a/packages/cli/src/ui/hooks/useAtCompletion_agents.test.ts +++ b/packages/cli/src/ui/hooks/useAtCompletion_agents.test.ts @@ -63,6 +63,8 @@ describe('useAtCompletion with Agents', () => { })), getEnableRecursiveFileSearch: () => true, getFileFilteringDisableFuzzySearch: () => false, + getFileFilteringEnableFuzzySearch: () => true, + getAgentsSettings: () => ({}), getResourceRegistry: vi.fn().mockReturnValue({ getAllResources: () => [], }), diff --git a/packages/cli/src/ui/utils/updateCheck.test.ts b/packages/cli/src/ui/utils/updateCheck.test.ts index 5cf4d532a3..17b6c62121 100644 --- a/packages/cli/src/ui/utils/updateCheck.test.ts +++ b/packages/cli/src/ui/utils/updateCheck.test.ts @@ -34,7 +34,7 @@ describe('checkForUpdates', () => { mockSettings = { merged: { general: { - disableUpdateNag: false, + enableAutoUpdateNotification: true, }, }, } as LoadedSettings; @@ -45,8 +45,8 @@ describe('checkForUpdates', () => { vi.restoreAllMocks(); }); - it('should return null if disableUpdateNag is true', async () => { - mockSettings.merged.general.disableUpdateNag = true; + it('should return null if enableAutoUpdateNotification is false', async () => { + mockSettings.merged.general.enableAutoUpdateNotification = false; const result = await checkForUpdates(mockSettings); expect(result).toBeNull(); expect(getPackageJson).not.toHaveBeenCalled(); diff --git a/packages/cli/src/ui/utils/updateCheck.ts b/packages/cli/src/ui/utils/updateCheck.ts index d5f609bf01..21dc0f836e 100644 --- a/packages/cli/src/ui/utils/updateCheck.ts +++ b/packages/cli/src/ui/utils/updateCheck.ts @@ -51,7 +51,7 @@ export async function checkForUpdates( settings: LoadedSettings, ): Promise { try { - if (settings.merged.general.disableUpdateNag) { + if (!settings.merged.general.enableAutoUpdateNotification) { return null; } // Skip update check when running from source (development mode) diff --git a/packages/cli/src/utils/handleAutoUpdate.test.ts b/packages/cli/src/utils/handleAutoUpdate.test.ts index 0a29cf3229..5a2ab9704f 100644 --- a/packages/cli/src/utils/handleAutoUpdate.test.ts +++ b/packages/cli/src/utils/handleAutoUpdate.test.ts @@ -14,7 +14,6 @@ import EventEmitter from 'node:events'; import type { ChildProcess } from 'node:child_process'; import { handleAutoUpdate, setUpdateHandler } from './handleAutoUpdate.js'; import { MessageType } from '../ui/types.js'; -import { mergeSettings } from '../config/settings.js'; vi.mock('./installationInfo.js', async () => { const actual = await vi.importActual('./installationInfo.js'); @@ -50,9 +49,16 @@ describe('handleAutoUpdate', () => { message: 'An update is available!', }; - const defaultMergedSettings = mergeSettings({}, {}, {}, {}, true); mockSettings = { - merged: defaultMergedSettings, + merged: { + general: { + enableAutoUpdate: true, + enableAutoUpdateNotification: true, + }, + tools: { + sandbox: false, + }, + }, } as LoadedSettings; mockChildProcess = Object.assign(new EventEmitter(), { @@ -79,8 +85,8 @@ describe('handleAutoUpdate', () => { expect(mockSpawn).not.toHaveBeenCalled(); }); - it('should do nothing if update nag is disabled', () => { - mockSettings.merged.general.disableUpdateNag = true; + it('should do nothing if update prompts are disabled', () => { + mockSettings.merged.general.enableAutoUpdateNotification = false; handleAutoUpdate(mockUpdateInfo, mockSettings, '/root', mockSpawn); expect(mockGetInstallationInfo).not.toHaveBeenCalled(); expect(updateEventEmitter.emit).not.toHaveBeenCalled(); @@ -88,7 +94,7 @@ describe('handleAutoUpdate', () => { }); it('should emit "update-received" but not update if auto-updates are disabled', () => { - mockSettings.merged.general.disableAutoUpdate = true; + mockSettings.merged.general.enableAutoUpdate = false; mockGetInstallationInfo.mockReturnValue({ updateCommand: 'npm i -g @google/gemini-cli@latest', updateMessage: 'Please update manually.', diff --git a/packages/cli/src/utils/handleAutoUpdate.ts b/packages/cli/src/utils/handleAutoUpdate.ts index 9cadc0bd59..a6d0cdc574 100644 --- a/packages/cli/src/utils/handleAutoUpdate.ts +++ b/packages/cli/src/utils/handleAutoUpdate.ts @@ -30,13 +30,13 @@ export function handleAutoUpdate( return; } - if (settings.merged.general.disableUpdateNag) { + if (!settings.merged.general.enableAutoUpdateNotification) { return; } const installationInfo = getInstallationInfo( projectRoot, - settings.merged.general.disableAutoUpdate, + settings.merged.general.enableAutoUpdate, ); if ( @@ -58,7 +58,7 @@ export function handleAutoUpdate( if ( !installationInfo.updateCommand || - settings.merged.general.disableAutoUpdate + !settings.merged.general.enableAutoUpdate ) { return; } diff --git a/packages/cli/src/utils/installationInfo.test.ts b/packages/cli/src/utils/installationInfo.test.ts index 9d91ea90fb..92323909f1 100644 --- a/packages/cli/src/utils/installationInfo.test.ts +++ b/packages/cli/src/utils/installationInfo.test.ts @@ -60,7 +60,7 @@ describe('getInstallationInfo', () => { it('should return UNKNOWN when cliPath is not available', () => { process.argv[1] = ''; - const info = getInstallationInfo(projectRoot, false); + const info = getInstallationInfo(projectRoot, true); expect(info.packageManager).toBe(PackageManager.UNKNOWN); }); @@ -71,7 +71,7 @@ describe('getInstallationInfo', () => { throw error; }); - const info = getInstallationInfo(projectRoot, false); + const info = getInstallationInfo(projectRoot, true); expect(info.packageManager).toBe(PackageManager.UNKNOWN); expect(debugLogger.log).toHaveBeenCalledWith(error); @@ -84,7 +84,7 @@ describe('getInstallationInfo', () => { ); mockedIsGitRepository.mockReturnValue(true); - const info = getInstallationInfo(projectRoot, false); + const info = getInstallationInfo(projectRoot, true); expect(info.packageManager).toBe(PackageManager.UNKNOWN); expect(info.isGlobal).toBe(false); @@ -98,7 +98,7 @@ describe('getInstallationInfo', () => { process.argv[1] = npxPath; mockedRealPathSync.mockReturnValue(npxPath); - const info = getInstallationInfo(projectRoot, false); + const info = getInstallationInfo(projectRoot, true); expect(info.packageManager).toBe(PackageManager.NPX); expect(info.isGlobal).toBe(false); @@ -110,7 +110,7 @@ describe('getInstallationInfo', () => { process.argv[1] = pnpxPath; mockedRealPathSync.mockReturnValue(pnpxPath); - const info = getInstallationInfo(projectRoot, false); + const info = getInstallationInfo(projectRoot, true); expect(info.packageManager).toBe(PackageManager.PNPX); expect(info.isGlobal).toBe(false); @@ -125,7 +125,7 @@ describe('getInstallationInfo', () => { throw new Error('Command failed'); }); - const info = getInstallationInfo(projectRoot, false); + const info = getInstallationInfo(projectRoot, true); expect(info.packageManager).toBe(PackageManager.BUNX); expect(info.isGlobal).toBe(false); @@ -141,7 +141,7 @@ describe('getInstallationInfo', () => { mockedRealPathSync.mockReturnValue(cliPath); mockedExecSync.mockReturnValue(Buffer.from('gemini-cli')); // Simulate successful command - const info = getInstallationInfo(projectRoot, false); + const info = getInstallationInfo(projectRoot, true); expect(mockedExecSync).toHaveBeenCalledWith( 'brew list -1 | grep -q "^gemini-cli$"', @@ -165,7 +165,7 @@ describe('getInstallationInfo', () => { throw new Error('Command failed'); }); - const info = getInstallationInfo(projectRoot, false); + const info = getInstallationInfo(projectRoot, true); expect(mockedExecSync).toHaveBeenCalledWith( 'brew list -1 | grep -q "^gemini-cli$"', @@ -184,13 +184,15 @@ describe('getInstallationInfo', () => { throw new Error('Command failed'); }); - const info = getInstallationInfo(projectRoot, false); + // isAutoUpdateEnabled = true -> "Attempting to automatically update" + const info = getInstallationInfo(projectRoot, true); expect(info.packageManager).toBe(PackageManager.PNPM); expect(info.isGlobal).toBe(true); expect(info.updateCommand).toBe('pnpm add -g @google/gemini-cli@latest'); expect(info.updateMessage).toContain('Attempting to automatically update'); - const infoDisabled = getInstallationInfo(projectRoot, true); + // isAutoUpdateEnabled = false -> "Please run..." + const infoDisabled = getInstallationInfo(projectRoot, false); expect(infoDisabled.updateMessage).toContain('Please run pnpm add'); }); @@ -202,7 +204,8 @@ describe('getInstallationInfo', () => { throw new Error('Command failed'); }); - const info = getInstallationInfo(projectRoot, false); + // isAutoUpdateEnabled = true -> "Attempting to automatically update" + const info = getInstallationInfo(projectRoot, true); expect(info.packageManager).toBe(PackageManager.YARN); expect(info.isGlobal).toBe(true); expect(info.updateCommand).toBe( @@ -210,7 +213,8 @@ describe('getInstallationInfo', () => { ); expect(info.updateMessage).toContain('Attempting to automatically update'); - const infoDisabled = getInstallationInfo(projectRoot, true); + // isAutoUpdateEnabled = false -> "Please run..." + const infoDisabled = getInstallationInfo(projectRoot, false); expect(infoDisabled.updateMessage).toContain('Please run yarn global add'); }); @@ -222,13 +226,15 @@ describe('getInstallationInfo', () => { throw new Error('Command failed'); }); - const info = getInstallationInfo(projectRoot, false); + // isAutoUpdateEnabled = true -> "Attempting to automatically update" + const info = getInstallationInfo(projectRoot, true); expect(info.packageManager).toBe(PackageManager.BUN); expect(info.isGlobal).toBe(true); expect(info.updateCommand).toBe('bun add -g @google/gemini-cli@latest'); expect(info.updateMessage).toContain('Attempting to automatically update'); - const infoDisabled = getInstallationInfo(projectRoot, true); + // isAutoUpdateEnabled = false -> "Please run..." + const infoDisabled = getInstallationInfo(projectRoot, false); expect(infoDisabled.updateMessage).toContain('Please run bun add'); }); @@ -243,7 +249,7 @@ describe('getInstallationInfo', () => { (p) => p === path.join(projectRoot, 'yarn.lock'), ); - const info = getInstallationInfo(projectRoot, false); + const info = getInstallationInfo(projectRoot, true); expect(info.packageManager).toBe(PackageManager.YARN); expect(info.isGlobal).toBe(false); @@ -261,7 +267,7 @@ describe('getInstallationInfo', () => { (p) => p === path.join(projectRoot, 'pnpm-lock.yaml'), ); - const info = getInstallationInfo(projectRoot, false); + const info = getInstallationInfo(projectRoot, true); expect(info.packageManager).toBe(PackageManager.PNPM); expect(info.isGlobal).toBe(false); @@ -278,7 +284,7 @@ describe('getInstallationInfo', () => { (p) => p === path.join(projectRoot, 'bun.lockb'), ); - const info = getInstallationInfo(projectRoot, false); + const info = getInstallationInfo(projectRoot, true); expect(info.packageManager).toBe(PackageManager.BUN); expect(info.isGlobal).toBe(false); @@ -293,7 +299,7 @@ describe('getInstallationInfo', () => { }); mockedExistsSync.mockReturnValue(false); // No lockfiles - const info = getInstallationInfo(projectRoot, false); + const info = getInstallationInfo(projectRoot, true); expect(info.packageManager).toBe(PackageManager.NPM); expect(info.isGlobal).toBe(false); @@ -307,13 +313,15 @@ describe('getInstallationInfo', () => { throw new Error('Command failed'); }); - const info = getInstallationInfo(projectRoot, false); + // isAutoUpdateEnabled = true -> "Attempting to automatically update" + const info = getInstallationInfo(projectRoot, true); expect(info.packageManager).toBe(PackageManager.NPM); expect(info.isGlobal).toBe(true); expect(info.updateCommand).toBe('npm install -g @google/gemini-cli@latest'); expect(info.updateMessage).toContain('Attempting to automatically update'); - const infoDisabled = getInstallationInfo(projectRoot, true); + // isAutoUpdateEnabled = false -> "Please run..." + const infoDisabled = getInstallationInfo(projectRoot, false); expect(infoDisabled.updateMessage).toContain('Please run npm install'); }); }); diff --git a/packages/cli/src/utils/installationInfo.ts b/packages/cli/src/utils/installationInfo.ts index 625f3fdf37..4c25fa6c59 100644 --- a/packages/cli/src/utils/installationInfo.ts +++ b/packages/cli/src/utils/installationInfo.ts @@ -33,7 +33,7 @@ export interface InstallationInfo { export function getInstallationInfo( projectRoot: string, - isAutoUpdateDisabled: boolean, + isAutoUpdateEnabled: boolean, ): InstallationInfo { const cliPath = process.argv[1]; if (!cliPath) { @@ -103,9 +103,9 @@ export function getInstallationInfo( packageManager: PackageManager.PNPM, isGlobal: true, updateCommand, - updateMessage: isAutoUpdateDisabled - ? `Please run ${updateCommand} to update` - : 'Installed with pnpm. Attempting to automatically update now...', + updateMessage: isAutoUpdateEnabled + ? 'Installed with pnpm. Attempting to automatically update now...' + : `Please run ${updateCommand} to update`, }; } @@ -116,9 +116,9 @@ export function getInstallationInfo( packageManager: PackageManager.YARN, isGlobal: true, updateCommand, - updateMessage: isAutoUpdateDisabled - ? `Please run ${updateCommand} to update` - : 'Installed with yarn. Attempting to automatically update now...', + updateMessage: isAutoUpdateEnabled + ? 'Installed with yarn. Attempting to automatically update now...' + : `Please run ${updateCommand} to update`, }; } @@ -136,9 +136,9 @@ export function getInstallationInfo( packageManager: PackageManager.BUN, isGlobal: true, updateCommand, - updateMessage: isAutoUpdateDisabled - ? `Please run ${updateCommand} to update` - : 'Installed with bun. Attempting to automatically update now...', + updateMessage: isAutoUpdateEnabled + ? 'Installed with bun. Attempting to automatically update now...' + : `Please run ${updateCommand} to update`, }; } @@ -169,9 +169,9 @@ export function getInstallationInfo( packageManager: PackageManager.NPM, isGlobal: true, updateCommand, - updateMessage: isAutoUpdateDisabled - ? `Please run ${updateCommand} to update` - : 'Installed with npm. Attempting to automatically update now...', + updateMessage: isAutoUpdateEnabled + ? 'Installed with npm. Attempting to automatically update now...' + : `Please run ${updateCommand} to update`, }; } catch (error) { debugLogger.log(error); diff --git a/packages/cli/src/utils/settingsUtils.test.ts b/packages/cli/src/utils/settingsUtils.test.ts index ca1dc802c9..51b1566968 100644 --- a/packages/cli/src/utils/settingsUtils.test.ts +++ b/packages/cli/src/utils/settingsUtils.test.ts @@ -120,13 +120,13 @@ describe('SettingsUtils', () => { description: 'Accessibility settings.', showInDialog: false, properties: { - disableLoadingPhrases: { + enableLoadingPhrases: { type: 'boolean', - label: 'Disable Loading Phrases', + label: 'Enable Loading Phrases', category: 'UI', requiresRestart: true, - default: false, - description: 'Disable loading phrases for accessibility', + default: true, + description: 'Enable loading phrases during operations.', showInDialog: true, }, }, @@ -284,18 +284,18 @@ describe('SettingsUtils', () => { it('should handle nested settings correctly', () => { const settings = makeMockSettings({ - ui: { accessibility: { disableLoadingPhrases: true } }, + ui: { accessibility: { enableLoadingPhrases: false } }, }); const mergedSettings = makeMockSettings({ - ui: { accessibility: { disableLoadingPhrases: false } }, + ui: { accessibility: { enableLoadingPhrases: true } }, }); const value = getEffectiveValue( - 'ui.accessibility.disableLoadingPhrases', + 'ui.accessibility.enableLoadingPhrases', settings, mergedSettings, ); - expect(value).toBe(true); + expect(value).toBe(false); }); it('should return undefined for invalid settings', () => { @@ -315,7 +315,7 @@ describe('SettingsUtils', () => { it('should return all setting keys', () => { const keys = getAllSettingKeys(); expect(keys).toContain('test'); - expect(keys).toContain('ui.accessibility.disableLoadingPhrases'); + expect(keys).toContain('ui.accessibility.enableLoadingPhrases'); }); }); @@ -342,9 +342,9 @@ describe('SettingsUtils', () => { describe('isValidSettingKey', () => { it('should return true for valid setting keys', () => { expect(isValidSettingKey('ui.requiresRestart')).toBe(true); - expect( - isValidSettingKey('ui.accessibility.disableLoadingPhrases'), - ).toBe(true); + expect(isValidSettingKey('ui.accessibility.enableLoadingPhrases')).toBe( + true, + ); }); it('should return false for invalid setting keys', () => { @@ -357,7 +357,7 @@ describe('SettingsUtils', () => { it('should return correct category for valid settings', () => { expect(getSettingCategory('ui.requiresRestart')).toBe('UI'); expect( - getSettingCategory('ui.accessibility.disableLoadingPhrases'), + getSettingCategory('ui.accessibility.enableLoadingPhrases'), ).toBe('UI'); }); @@ -391,7 +391,7 @@ describe('SettingsUtils', () => { const uiSettings = categories['UI']; const uiKeys = uiSettings.map((s) => s.key); expect(uiKeys).toContain('ui.requiresRestart'); - expect(uiKeys).toContain('ui.accessibility.disableLoadingPhrases'); + expect(uiKeys).toContain('ui.accessibility.enableLoadingPhrases'); expect(uiKeys).not.toContain('ui.theme'); // This is now marked false }); @@ -421,7 +421,7 @@ describe('SettingsUtils', () => { const keys = booleanSettings.map((s) => s.key); expect(keys).toContain('ui.requiresRestart'); - expect(keys).toContain('ui.accessibility.disableLoadingPhrases'); + expect(keys).toContain('ui.accessibility.enableLoadingPhrases'); expect(keys).not.toContain('privacy.usageStatisticsEnabled'); expect(keys).not.toContain('security.auth.selectedType'); // Advanced setting expect(keys).not.toContain('security.auth.useExternal'); // Advanced setting @@ -454,7 +454,7 @@ describe('SettingsUtils', () => { expect(dialogKeys).toContain('ui.requiresRestart'); // Should include nested settings marked for dialog - expect(dialogKeys).toContain('ui.accessibility.disableLoadingPhrases'); + expect(dialogKeys).toContain('ui.accessibility.enableLoadingPhrases'); // Should NOT include settings marked as hidden expect(dialogKeys).not.toContain('ui.theme'); // Hidden @@ -601,14 +601,14 @@ describe('SettingsUtils', () => { it('should return true when value differs from default', () => { expect(isSettingModified('ui.requiresRestart', true)).toBe(true); expect( - isSettingModified('ui.accessibility.disableLoadingPhrases', true), + isSettingModified('ui.accessibility.enableLoadingPhrases', false), ).toBe(true); }); it('should return false when value matches default', () => { expect(isSettingModified('ui.requiresRestart', false)).toBe(false); expect( - isSettingModified('ui.accessibility.disableLoadingPhrases', false), + isSettingModified('ui.accessibility.enableLoadingPhrases', true), ).toBe(false); }); }); @@ -628,11 +628,11 @@ describe('SettingsUtils', () => { it('should return true for nested settings that exist', () => { const settings = makeMockSettings({ - ui: { accessibility: { disableLoadingPhrases: true } }, + ui: { accessibility: { enableLoadingPhrases: true } }, }); expect( settingExistsInScope( - 'ui.accessibility.disableLoadingPhrases', + 'ui.accessibility.enableLoadingPhrases', settings, ), ).toBe(true); @@ -642,7 +642,7 @@ describe('SettingsUtils', () => { const settings = makeMockSettings({}); expect( settingExistsInScope( - 'ui.accessibility.disableLoadingPhrases', + 'ui.accessibility.enableLoadingPhrases', settings, ), ).toBe(false); @@ -652,7 +652,7 @@ describe('SettingsUtils', () => { const settings = makeMockSettings({ ui: { accessibility: {} } }); expect( settingExistsInScope( - 'ui.accessibility.disableLoadingPhrases', + 'ui.accessibility.enableLoadingPhrases', settings, ), ).toBe(false); @@ -674,25 +674,25 @@ describe('SettingsUtils', () => { it('should set nested setting value', () => { const pendingSettings = makeMockSettings({}); const result = setPendingSettingValue( - 'ui.accessibility.disableLoadingPhrases', + 'ui.accessibility.enableLoadingPhrases', true, pendingSettings, ); - expect(result.ui?.accessibility?.disableLoadingPhrases).toBe(true); + expect(result.ui?.accessibility?.enableLoadingPhrases).toBe(true); }); it('should preserve existing nested settings', () => { const pendingSettings = makeMockSettings({ - ui: { accessibility: { disableLoadingPhrases: false } }, + ui: { accessibility: { enableLoadingPhrases: false } }, }); const result = setPendingSettingValue( - 'ui.accessibility.disableLoadingPhrases', + 'ui.accessibility.enableLoadingPhrases', true, pendingSettings, ); - expect(result.ui?.accessibility?.disableLoadingPhrases).toBe(true); + expect(result.ui?.accessibility?.enableLoadingPhrases).toBe(true); }); it('should not mutate original settings', () => { @@ -1029,7 +1029,7 @@ describe('SettingsUtils', () => { const settings = makeMockSettings({}); // nested setting doesn't exist const result = isDefaultValue( - 'ui.accessibility.disableLoadingPhrases', + 'ui.accessibility.enableLoadingPhrases', settings, ); expect(result).toBe(true); @@ -1037,11 +1037,11 @@ describe('SettingsUtils', () => { it('should return false when nested setting exists in scope', () => { const settings = makeMockSettings({ - ui: { accessibility: { disableLoadingPhrases: true } }, + ui: { accessibility: { enableLoadingPhrases: true } }, }); // nested setting exists const result = isDefaultValue( - 'ui.accessibility.disableLoadingPhrases', + 'ui.accessibility.enableLoadingPhrases', settings, ); expect(result).toBe(false); @@ -1079,14 +1079,14 @@ describe('SettingsUtils', () => { it('should return false for nested settings that exist in scope', () => { const settings = makeMockSettings({ - ui: { accessibility: { disableLoadingPhrases: true } }, + ui: { accessibility: { enableLoadingPhrases: true } }, }); const mergedSettings = makeMockSettings({ - ui: { accessibility: { disableLoadingPhrases: true } }, + ui: { accessibility: { enableLoadingPhrases: true } }, }); const result = isValueInherited( - 'ui.accessibility.disableLoadingPhrases', + 'ui.accessibility.enableLoadingPhrases', settings, mergedSettings, ); @@ -1096,11 +1096,11 @@ describe('SettingsUtils', () => { it('should return true for nested settings that do not exist in scope', () => { const settings = makeMockSettings({}); const mergedSettings = makeMockSettings({ - ui: { accessibility: { disableLoadingPhrases: true } }, + ui: { accessibility: { enableLoadingPhrases: true } }, }); const result = isValueInherited( - 'ui.accessibility.disableLoadingPhrases', + 'ui.accessibility.enableLoadingPhrases', settings, mergedSettings, ); diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts index ed6343ea35..12158fb5d4 100644 --- a/packages/core/src/config/config.ts +++ b/packages/core/src/config/config.ts @@ -108,7 +108,7 @@ import type { AgentDefinition } from '../agents/types.js'; import { fetchAdminControls } from '../code_assist/admin/admin_controls.js'; export interface AccessibilitySettings { - disableLoadingPhrases?: boolean; + enableLoadingPhrases?: boolean; screenReader?: boolean; } @@ -311,7 +311,7 @@ export interface ConfigParameters { respectGitIgnore?: boolean; respectGeminiIgnore?: boolean; enableRecursiveFileSearch?: boolean; - disableFuzzySearch?: boolean; + enableFuzzySearch?: boolean; maxFileCount?: number; searchTimeout?: number; }; @@ -444,7 +444,7 @@ export class Config { respectGitIgnore: boolean; respectGeminiIgnore: boolean; enableRecursiveFileSearch: boolean; - disableFuzzySearch: boolean; + enableFuzzySearch: boolean; maxFileCount: number; searchTimeout: number; }; @@ -598,7 +598,7 @@ export class Config { DEFAULT_FILE_FILTERING_OPTIONS.respectGeminiIgnore, enableRecursiveFileSearch: params.fileFiltering?.enableRecursiveFileSearch ?? true, - disableFuzzySearch: params.fileFiltering?.disableFuzzySearch ?? false, + enableFuzzySearch: params.fileFiltering?.enableFuzzySearch ?? true, maxFileCount: params.fileFiltering?.maxFileCount ?? DEFAULT_FILE_FILTERING_OPTIONS.maxFileCount ?? @@ -1402,8 +1402,8 @@ export class Config { return this.fileFiltering.enableRecursiveFileSearch; } - getFileFilteringDisableFuzzySearch(): boolean { - return this.fileFiltering.disableFuzzySearch; + getFileFilteringEnableFuzzySearch(): boolean { + return this.fileFiltering.enableFuzzySearch; } getFileFilteringRespectGitIgnore(): boolean { diff --git a/packages/core/src/utils/filesearch/fileSearch.test.ts b/packages/core/src/utils/filesearch/fileSearch.test.ts index ee1af9761f..6566b8394d 100644 --- a/packages/core/src/utils/filesearch/fileSearch.test.ts +++ b/packages/core/src/utils/filesearch/fileSearch.test.ts @@ -33,7 +33,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -59,7 +59,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -87,7 +87,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -116,7 +116,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -149,7 +149,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -173,7 +173,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -208,7 +208,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -238,7 +238,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -268,7 +268,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); // Expect no errors to be thrown during initialization @@ -295,7 +295,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -321,7 +321,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -330,7 +330,7 @@ describe('FileSearch', () => { expect(results).toEqual(['src/style.css']); }); - it('should not use fzf for fuzzy matching when disableFuzzySearch is true', async () => { + it('should not use fzf for fuzzy matching when enableFuzzySearch is false', async () => { tmpDir = await createTmpDir({ src: { 'file1.js': '', @@ -347,7 +347,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: true, + enableFuzzySearch: false, }); await fileSearch.initialize(); @@ -356,7 +356,7 @@ describe('FileSearch', () => { expect(results).toEqual(['src/flexible.js']); }); - it('should use fzf for fuzzy matching when disableFuzzySearch is false', async () => { + it('should use fzf for fuzzy matching when enableFuzzySearch is true', async () => { tmpDir = await createTmpDir({ src: { 'file1.js': '', @@ -373,7 +373,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -397,7 +397,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -428,7 +428,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await expect(fileSearch.search('')).rejects.toThrow( @@ -450,7 +450,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -473,7 +473,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -497,7 +497,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -524,7 +524,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -561,7 +561,7 @@ describe('FileSearch', () => { cache: true, // Enable caching for this test cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -601,7 +601,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -645,7 +645,7 @@ describe('FileSearch', () => { cache: true, // Ensure caching is enabled cacheTtl: 10000, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -683,7 +683,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: true, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -713,7 +713,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: false, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -738,7 +738,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: false, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -763,7 +763,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: false, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); @@ -786,7 +786,7 @@ describe('FileSearch', () => { cache: false, cacheTtl: 0, enableRecursiveFileSearch: false, - disableFuzzySearch: false, + enableFuzzySearch: true, }); await fileSearch.initialize(); diff --git a/packages/core/src/utils/filesearch/fileSearch.ts b/packages/core/src/utils/filesearch/fileSearch.ts index e18fdf3111..3c829d6846 100644 --- a/packages/core/src/utils/filesearch/fileSearch.ts +++ b/packages/core/src/utils/filesearch/fileSearch.ts @@ -22,7 +22,7 @@ export interface FileSearchOptions { cache: boolean; cacheTtl: number; enableRecursiveFileSearch: boolean; - disableFuzzySearch: boolean; + enableFuzzySearch: boolean; maxDepth?: number; maxFiles?: number; } @@ -122,7 +122,7 @@ class RecursiveFileSearch implements FileSearch { ): Promise { if ( !this.resultCache || - (!this.fzf && !this.options.disableFuzzySearch) || + (!this.fzf && this.options.enableFuzzySearch) || !this.ignore ) { throw new Error('Engine not initialized. Call initialize() first.'); @@ -183,7 +183,7 @@ class RecursiveFileSearch implements FileSearch { private buildResultCache(): void { this.resultCache = new ResultCache(this.allFiles); - if (!this.options.disableFuzzySearch) { + if (this.options.enableFuzzySearch) { // The v1 algorithm is much faster since it only looks at the first // occurrence of the pattern. We use it for search spaces that have >20k // files, because the v2 algorithm is just too slow in those cases. diff --git a/schemas/settings.schema.json b/schemas/settings.schema.json index 7c36fdf589..79f5a012c0 100644 --- a/schemas/settings.schema.json +++ b/schemas/settings.schema.json @@ -49,18 +49,18 @@ "default": false, "type": "boolean" }, - "disableAutoUpdate": { - "title": "Disable Auto Update", - "description": "Disable automatic updates", - "markdownDescription": "Disable automatic updates\n\n- Category: `General`\n- Requires restart: `no`\n- Default: `false`", - "default": false, + "enableAutoUpdate": { + "title": "Enable Auto Update", + "description": "Enable automatic updates.", + "markdownDescription": "Enable automatic updates.\n\n- Category: `General`\n- Requires restart: `no`\n- Default: `true`", + "default": true, "type": "boolean" }, - "disableUpdateNag": { - "title": "Disable Update Nag", - "description": "Disable update notification prompts.", - "markdownDescription": "Disable update notification prompts.\n\n- Category: `General`\n- Requires restart: `no`\n- Default: `false`", - "default": false, + "enableAutoUpdateNotification": { + "title": "Enable Auto Update Notification", + "description": "Enable update notification prompts.", + "markdownDescription": "Enable update notification prompts.\n\n- Category: `General`\n- Requires restart: `no`\n- Default: `true`", + "default": true, "type": "boolean" }, "checkpointing": { @@ -340,11 +340,11 @@ "default": {}, "type": "object", "properties": { - "disableLoadingPhrases": { - "title": "Disable Loading Phrases", - "description": "Disable loading phrases for accessibility", - "markdownDescription": "Disable loading phrases for accessibility\n\n- Category: `UI`\n- Requires restart: `yes`\n- Default: `false`", - "default": false, + "enableLoadingPhrases": { + "title": "Enable Loading Phrases", + "description": "Enable loading phrases during operations.", + "markdownDescription": "Enable loading phrases during operations.\n\n- Category: `UI`\n- Requires restart: `yes`\n- Default: `true`", + "default": true, "type": "boolean" }, "screenReader": { @@ -1017,11 +1017,11 @@ "default": true, "type": "boolean" }, - "disableFuzzySearch": { - "title": "Disable Fuzzy Search", - "description": "Disable fuzzy search when searching for files.", - "markdownDescription": "Disable fuzzy search when searching for files.\n\n- Category: `Context`\n- Requires restart: `yes`\n- Default: `false`", - "default": false, + "enableFuzzySearch": { + "title": "Enable Fuzzy Search", + "description": "Enable fuzzy search when searching for files.", + "markdownDescription": "Enable fuzzy search when searching for files.\n\n- Category: `Context`\n- Requires restart: `yes`\n- Default: `true`", + "default": true, "type": "boolean" } },