From 6bc2f89ee94bc661c493edfd1c173d64017c45f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mois=C3=A9s=20Gana=20Obreg=C3=B3n?= Date: Thu, 19 Mar 2026 23:58:44 +0000 Subject: [PATCH] fix(cli): deduplicate startup extension warnings in terminal UI This change introduces a module-level Set to deduplicate warning messages emitted by the ExtensionManager. This prevents identical warnings (like missing settings or built-in replacements) from being displayed twice due to loadCliConfig being invoked multiple times during startup. Fixes #23175 See also #23171 for the planned long-term refactor. --- packages/cli/src/config/extension-manager.ts | 23 +++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/cli/src/config/extension-manager.ts b/packages/cli/src/config/extension-manager.ts index f6cb28e6a0..df397f394e 100644 --- a/packages/cli/src/config/extension-manager.ts +++ b/packages/cli/src/config/extension-manager.ts @@ -85,6 +85,8 @@ import type { EventEmitter } from 'node:stream'; import { themeManager } from '../ui/themes/theme-manager.js'; import { getFormattedSettingValue } from '../commands/extensions/utils.js'; +const emittedWarnings = new Set(); + interface ExtensionManagerParams { enabledExtensionOverrides?: string[]; settings: MergedSettings; @@ -421,8 +423,11 @@ Would you like to attempt to install via "git clone" instead?`, .join( ', ', )}. Please run "gemini extensions config ${newExtensionConfig.name} [setting-name]" to configure them.`; - debugLogger.warn(message); - coreEvents.emitFeedback('warning', message); + if (!emittedWarnings.has(message)) { + debugLogger.warn(message); + coreEvents.emitFeedback('warning', message); + emittedWarnings.add(message); + } } if ( @@ -682,8 +687,11 @@ Would you like to attempt to install via "git clone" instead?`, if (existingIdx !== -1) { // If the user has a manually installed version of the builtin extension, we warn them. const message = `Extension "${builtinExt.name}" is now built-in. Your manual installation at "${builtExtensions[existingIdx].path}" is being ignored. Please run "gemini extensions uninstall ${builtinExt.name}" to clean up.`; - debugLogger.warn(message); - coreEvents.emitFeedback('warning', message); + if (!emittedWarnings.has(message)) { + debugLogger.warn(message); + coreEvents.emitFeedback('warning', message); + emittedWarnings.add(message); + } builtExtensions[existingIdx] = builtinExt; } else { // Check if this is the new 'sdd' extension and if 'conductor' is installed. @@ -693,8 +701,11 @@ Would you like to attempt to install via "git clone" instead?`, ); if (conductorIdx !== -1) { const message = `The "conductor" extension has been replaced by built-in Spec-Driven Development. Your project files in "/conductor" are preserved. Run "/spec:setup" to get started.`; - debugLogger.warn(message); - coreEvents.emitFeedback('warning', message); + if (!emittedWarnings.has(message)) { + debugLogger.warn(message); + coreEvents.emitFeedback('warning', message); + emittedWarnings.add(message); + } } } builtExtensions.push(builtinExt);