diff --git a/packages/cli/src/config/extension-manager.ts b/packages/cli/src/config/extension-manager.ts
index 48cd17b873..adc7743cf1 100644
--- a/packages/cli/src/config/extension-manager.ts
+++ b/packages/cli/src/config/extension-manager.ts
@@ -44,6 +44,7 @@ import {
type GeminiCLIExtension,
type HookDefinition,
type HookEventName,
+ type ResolvedExtensionSetting,
} from '@google/gemini-cli-core';
import { maybeRequestConsentOrFail } from './extensions/consent.js';
import { resolveEnvVarsInObject } from '../utils/envVarResolver.js';
@@ -509,6 +510,24 @@ Would you like to attempt to install via "git clone" instead?`,
);
config = resolveEnvVarsInObject(config, customEnv);
+ const resolvedSettings: ResolvedExtensionSetting[] = [];
+ if (config.settings) {
+ for (const setting of config.settings) {
+ const value = customEnv[setting.envVar];
+ resolvedSettings.push({
+ name: setting.name,
+ envVar: setting.envVar,
+ value:
+ value === undefined
+ ? '[not set]'
+ : setting.sensitive
+ ? '***'
+ : value,
+ sensitive: setting.sensitive ?? false,
+ });
+ }
+ }
+
if (config.mcpServers) {
config.mcpServers = Object.fromEntries(
Object.entries(config.mcpServers).map(([key, value]) => [
@@ -532,7 +551,7 @@ Would you like to attempt to install via "git clone" instead?`,
});
}
- const extension = {
+ const extension: GeminiCLIExtension = {
name: config.name,
version: config.version,
path: effectiveExtensionPath,
@@ -546,6 +565,8 @@ Would you like to attempt to install via "git clone" instead?`,
this.workspaceDir,
),
id: getExtensionId(config, installMetadata),
+ settings: config.settings,
+ resolvedSettings,
};
this.loadedExtensions = [...this.loadedExtensions, extension];
@@ -700,6 +721,13 @@ Would you like to attempt to install via "git clone" instead?`,
output += `\n ${tool}`;
});
}
+ const resolvedSettings = extension.resolvedSettings;
+ if (resolvedSettings && resolvedSettings.length > 0) {
+ output += `\n Settings:`;
+ resolvedSettings.forEach((setting) => {
+ output += `\n ${setting.name}: ${setting.value}`;
+ });
+ }
return output;
}
diff --git a/packages/cli/src/ui/components/views/ExtensionsList.test.tsx b/packages/cli/src/ui/components/views/ExtensionsList.test.tsx
index 8c841991ce..7fb5d2f361 100644
--- a/packages/cli/src/ui/components/views/ExtensionsList.test.tsx
+++ b/packages/cli/src/ui/components/views/ExtensionsList.test.tsx
@@ -125,4 +125,33 @@ describe('', () => {
unmount();
});
}
+
+ it('should render resolved settings for an extension', () => {
+ mockUIState(new Map());
+ const extensionWithSettings = {
+ ...mockExtensions[0],
+ resolvedSettings: [
+ {
+ name: 'sensitiveApiKey',
+ value: '***',
+ envVar: 'API_KEY',
+ sensitive: true,
+ },
+ {
+ name: 'maxTokens',
+ value: '1000',
+ envVar: 'MAX_TOKENS',
+ sensitive: false,
+ },
+ ],
+ };
+ const { lastFrame, unmount } = render(
+ ,
+ );
+ const output = lastFrame();
+ expect(output).toContain('settings:');
+ expect(output).toContain('- sensitiveApiKey: ***');
+ expect(output).toContain('- maxTokens: 1000');
+ unmount();
+ });
});
diff --git a/packages/cli/src/ui/components/views/ExtensionsList.tsx b/packages/cli/src/ui/components/views/ExtensionsList.tsx
index 9297d2496a..2d456625f1 100644
--- a/packages/cli/src/ui/components/views/ExtensionsList.tsx
+++ b/packages/cli/src/ui/components/views/ExtensionsList.tsx
@@ -23,7 +23,7 @@ export const ExtensionsList: React.FC = ({ extensions }) => {
return (
- Installed extensions:
+ Installed extensions:
{extensions.map((ext) => {
const state = extensionsUpdateState.get(ext.name);
@@ -59,12 +59,22 @@ export const ExtensionsList: React.FC = ({ extensions }) => {
}
return (
-
+
{`${ext.name} (v${ext.version})`}
{` - ${activeString}`}
{{` (${stateText})`}}
+ {ext.resolvedSettings && ext.resolvedSettings.length > 0 && (
+
+ settings:
+ {ext.resolvedSettings.map((setting) => (
+
+ - {setting.name}: {setting.value}
+
+ ))}
+
+ )}
);
})}
diff --git a/packages/core/src/config/config.ts b/packages/core/src/config/config.ts
index e07d40d03d..e1aeed6eee 100644
--- a/packages/core/src/config/config.ts
+++ b/packages/core/src/config/config.ts
@@ -134,6 +134,20 @@ export interface CodebaseInvestigatorSettings {
model?: string;
}
+export interface ExtensionSetting {
+ name: string;
+ description: string;
+ envVar: string;
+ sensitive?: boolean;
+}
+
+export interface ResolvedExtensionSetting {
+ name: string;
+ envVar: string;
+ value: string;
+ sensitive: boolean;
+}
+
export interface IntrospectionAgentSettings {
enabled?: boolean;
}
@@ -155,6 +169,8 @@ export interface GeminiCLIExtension {
excludeTools?: string[];
id: string;
hooks?: { [K in HookEventName]?: HookDefinition[] };
+ settings?: ExtensionSetting[];
+ resolvedSettings?: ResolvedExtensionSetting[];
}
export interface ExtensionInstallMetadata {