diff options
| author | Ramón Medrano Llamas <[email protected]> | 2025-07-28 17:46:43 +0200 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-07-28 15:46:43 +0000 |
| commit | 0170791800183b81e2afc98f8fb2368219bfb3e3 (patch) | |
| tree | aa413e1c0c608403b2ac0053169ab98dd896e415 /packages/cli/src | |
| parent | e2754416516edb8c27e63cee5b249f41c3e0fffc (diff) | |
feat: Add /config refresh command (#4993)
Co-authored-by: Bryan Morgan <[email protected]>
Diffstat (limited to 'packages/cli/src')
| -rw-r--r-- | packages/cli/src/services/BuiltinCommandLoader.ts | 2 | ||||
| -rw-r--r-- | packages/cli/src/ui/App.tsx | 39 | ||||
| -rw-r--r-- | packages/cli/src/ui/commands/configCommand.ts | 33 | ||||
| -rw-r--r-- | packages/cli/src/ui/commands/types.ts | 1 | ||||
| -rw-r--r-- | packages/cli/src/ui/hooks/slashCommandProcessor.ts | 3 |
5 files changed, 71 insertions, 7 deletions
diff --git a/packages/cli/src/services/BuiltinCommandLoader.ts b/packages/cli/src/services/BuiltinCommandLoader.ts index 7ba0d6bb..b0c85d2a 100644 --- a/packages/cli/src/services/BuiltinCommandLoader.ts +++ b/packages/cli/src/services/BuiltinCommandLoader.ts @@ -29,6 +29,7 @@ import { statsCommand } from '../ui/commands/statsCommand.js'; import { themeCommand } from '../ui/commands/themeCommand.js'; import { toolsCommand } from '../ui/commands/toolsCommand.js'; import { vimCommand } from '../ui/commands/vimCommand.js'; +import { configCommand } from '../ui/commands/configCommand.js'; /** * Loads the core, hard-coded slash commands that are an integral part @@ -54,6 +55,7 @@ export class BuiltinCommandLoader implements ICommandLoader { compressCommand, copyCommand, corgiCommand, + configCommand, docsCommand, editorCommand, extensionsCommand, diff --git a/packages/cli/src/ui/App.tsx b/packages/cli/src/ui/App.tsx index aacf45d7..43060fdb 100644 --- a/packages/cli/src/ui/App.tsx +++ b/packages/cli/src/ui/App.tsx @@ -39,8 +39,12 @@ import { EditorSettingsDialog } from './components/EditorSettingsDialog.js'; import { ShellConfirmationDialog } from './components/ShellConfirmationDialog.js'; import { Colors } from './colors.js'; import { Help } from './components/Help.js'; -import { loadHierarchicalGeminiMemory } from '../config/config.js'; -import { LoadedSettings } from '../config/settings.js'; +import { + loadHierarchicalGeminiMemory, + loadCliConfig, + parseArguments, +} from '../config/config.js'; +import { LoadedSettings, loadSettings } from '../config/settings.js'; import { Tips } from './components/Tips.js'; import { ConsolePatcher } from './utils/ConsolePatcher.js'; import { registerCleanup } from '../utils/cleanup.js'; @@ -62,6 +66,7 @@ import { AuthType, type IdeContext, ideContext, + sessionId, } from '@google/gemini-cli-core'; import { validateAuthMethod } from '../config/auth.js'; import { useLogger } from './hooks/useLogger.js'; @@ -89,6 +94,7 @@ import { OverflowProvider } from './contexts/OverflowContext.js'; import { ShowMoreLines } from './components/ShowMoreLines.js'; import { PrivacyNotice } from './privacy/PrivacyNotice.js'; import { appEvents, AppEvent } from '../utils/events.js'; +import { loadExtensions } from '../config/extension.js'; const CTRL_EXIT_PROMPT_DURATION_MS = 1000; @@ -107,12 +113,14 @@ export const AppWrapper = (props: AppProps) => ( </SessionStatsProvider> ); -const App = ({ config, settings, startupWarnings = [], version }: AppProps) => { +const App = (props: AppProps) => { + const [config, setConfig] = useState<Config>(props.config); + const [settings, setSettings] = useState<LoadedSettings>(props.settings); const isFocused = useFocus(); useBracketedPaste(); const [updateMessage, setUpdateMessage] = useState<string | null>(null); const { stdout } = useStdout(); - const nightly = version.includes('nightly'); + const nightly = props.version.includes('nightly'); useEffect(() => { checkForUpdates().then(setUpdateMessage); @@ -307,6 +315,22 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => { } }, [config, addItem, settings.merged]); + const refreshConfig = useCallback(async () => { + const newSettings = loadSettings(process.cwd()); + const newExtensions = loadExtensions(process.cwd()); + const argv = await parseArguments(); + const newConfig = await loadCliConfig( + newSettings.merged, + newExtensions, + sessionId, + argv, + ); + await newConfig.initialize(); + setConfig(newConfig); + setSettings(newSettings); + setGeminiMdFileCount(newConfig.getGeminiMdFileCount()); + }, []); + // Watch for model changes (e.g., from Flash fallback) useEffect(() => { const checkModelChange = () => { @@ -474,6 +498,7 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => { openPrivacyNotice, toggleVimEnabled, setIsProcessing, + refreshConfig, ); const { @@ -777,7 +802,7 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => { {!settings.merged.hideBanner && ( <Header terminalWidth={terminalWidth} - version={version} + version={props.version} nightly={nightly} /> )} @@ -821,7 +846,7 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => { {showHelp && <Help commands={slashCommands} />} <Box flexDirection="column" ref={mainControlsRef}> - {startupWarnings.length > 0 && ( + {props.startupWarnings && props.startupWarnings.length > 0 && ( <Box borderStyle="round" borderColor={Colors.AccentYellow} @@ -829,7 +854,7 @@ const App = ({ config, settings, startupWarnings = [], version }: AppProps) => { marginY={1} flexDirection="column" > - {startupWarnings.map((warning, index) => ( + {props.startupWarnings.map((warning, index) => ( <Text key={index} color={Colors.AccentYellow}> {warning} </Text> diff --git a/packages/cli/src/ui/commands/configCommand.ts b/packages/cli/src/ui/commands/configCommand.ts new file mode 100644 index 00000000..3651b221 --- /dev/null +++ b/packages/cli/src/ui/commands/configCommand.ts @@ -0,0 +1,33 @@ +/** + * @license + * Copyright 2025 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import { + CommandKind, + SlashCommand, + SlashCommandActionReturn, +} from './types.js'; + +export const configCommand: SlashCommand = { + name: 'config', + description: 'Commands for interacting with the CLI configuration.', + kind: CommandKind.BUILT_IN, + subCommands: [ + { + name: 'refresh', + description: 'Reload settings and extensions from the filesystem.', + kind: CommandKind.BUILT_IN, + action: async (context): Promise<SlashCommandActionReturn> => { + await context.ui.refreshConfig(); + return { + type: 'message', + messageType: 'info', + content: + 'Configuration, extensions, memory, and tools have been refreshed.', + }; + }, + }, + ], +}; diff --git a/packages/cli/src/ui/commands/types.ts b/packages/cli/src/ui/commands/types.ts index 2844177f..6665da4b 100644 --- a/packages/cli/src/ui/commands/types.ts +++ b/packages/cli/src/ui/commands/types.ts @@ -59,6 +59,7 @@ export interface CommandContext { /** Toggles a special display mode. */ toggleCorgiMode: () => void; toggleVimEnabled: () => Promise<boolean>; + refreshConfig: () => Promise<void>; }; // Session-specific data session: { diff --git a/packages/cli/src/ui/hooks/slashCommandProcessor.ts b/packages/cli/src/ui/hooks/slashCommandProcessor.ts index be32de11..67e49c21 100644 --- a/packages/cli/src/ui/hooks/slashCommandProcessor.ts +++ b/packages/cli/src/ui/hooks/slashCommandProcessor.ts @@ -50,6 +50,7 @@ export const useSlashCommandProcessor = ( openPrivacyNotice: () => void, toggleVimEnabled: () => Promise<boolean>, setIsProcessing: (isProcessing: boolean) => void, + refreshConfig: () => Promise<void>, ) => { const session = useSessionStats(); const [commands, setCommands] = useState<readonly SlashCommand[]>([]); @@ -158,6 +159,7 @@ export const useSlashCommandProcessor = ( setPendingItem: setPendingCompressionItem, toggleCorgiMode, toggleVimEnabled, + refreshConfig, }, session: { stats: session.stats, @@ -180,6 +182,7 @@ export const useSlashCommandProcessor = ( toggleCorgiMode, toggleVimEnabled, sessionShellAllowlist, + refreshConfig, ], ); |
