mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-02-01 22:48:03 +00:00
feat(admin): provide actionable error messages for disabled features (#17815)
This commit is contained in:
@@ -1255,7 +1255,7 @@ describe('Approval mode tool exclusion logic', () => {
|
||||
});
|
||||
|
||||
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow(
|
||||
'Cannot start in YOLO mode since it is disabled by your admin',
|
||||
'YOLO mode is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -2928,7 +2928,7 @@ describe('loadCliConfig disableYoloMode', () => {
|
||||
security: { disableYoloMode: true },
|
||||
});
|
||||
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow(
|
||||
'Cannot start in YOLO mode since it is disabled by your admin',
|
||||
'YOLO mode is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli',
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -2960,7 +2960,7 @@ describe('loadCliConfig secureModeEnabled', () => {
|
||||
});
|
||||
|
||||
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow(
|
||||
'Cannot start in YOLO mode since it is disabled by your admin',
|
||||
'YOLO mode is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli',
|
||||
);
|
||||
});
|
||||
|
||||
@@ -2974,7 +2974,7 @@ describe('loadCliConfig secureModeEnabled', () => {
|
||||
});
|
||||
|
||||
await expect(loadCliConfig(settings, 'test-session', argv)).rejects.toThrow(
|
||||
'Cannot start in YOLO mode since it is disabled by your admin',
|
||||
'YOLO mode is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli',
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import {
|
||||
type OutputFormat,
|
||||
coreEvents,
|
||||
GEMINI_MODEL_ALIAS_AUTO,
|
||||
getAdminErrorMessage,
|
||||
} from '@google/gemini-cli-core';
|
||||
import {
|
||||
type Settings,
|
||||
@@ -550,7 +551,7 @@ export async function loadCliConfig(
|
||||
);
|
||||
}
|
||||
throw new FatalConfigError(
|
||||
'Cannot start in YOLO mode since it is disabled by your admin',
|
||||
getAdminErrorMessage('YOLO mode', undefined /* config */),
|
||||
);
|
||||
}
|
||||
} else if (approvalMode === ApprovalMode.YOLO) {
|
||||
|
||||
@@ -16,11 +16,10 @@ import type { ArgumentsCamelCase, CommandModule } from 'yargs';
|
||||
import type { MergedSettings } from './config/settings.js';
|
||||
import type { MockInstance } from 'vitest';
|
||||
|
||||
const { mockRunExitCleanup, mockDebugLogger } = vi.hoisted(() => ({
|
||||
const { mockRunExitCleanup, mockCoreEvents } = vi.hoisted(() => ({
|
||||
mockRunExitCleanup: vi.fn(),
|
||||
mockDebugLogger: {
|
||||
log: vi.fn(),
|
||||
error: vi.fn(),
|
||||
mockCoreEvents: {
|
||||
emitFeedback: vi.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -28,7 +27,7 @@ vi.mock('@google/gemini-cli-core', async () => {
|
||||
const actual = await vi.importActual('@google/gemini-cli-core');
|
||||
return {
|
||||
...actual,
|
||||
debugLogger: mockDebugLogger,
|
||||
coreEvents: mockCoreEvents,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -55,8 +54,7 @@ describe('deferred', () => {
|
||||
describe('runDeferredCommand', () => {
|
||||
it('should do nothing if no deferred command is set', async () => {
|
||||
await runDeferredCommand(createMockSettings());
|
||||
expect(mockDebugLogger.log).not.toHaveBeenCalled();
|
||||
expect(mockDebugLogger.error).not.toHaveBeenCalled();
|
||||
expect(mockCoreEvents.emitFeedback).not.toHaveBeenCalled();
|
||||
expect(mockExit).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -85,8 +83,9 @@ describe('deferred', () => {
|
||||
const settings = createMockSettings({ mcp: { enabled: false } });
|
||||
await runDeferredCommand(settings);
|
||||
|
||||
expect(mockDebugLogger.error).toHaveBeenCalledWith(
|
||||
'Error: MCP is disabled by your admin.',
|
||||
expect(mockCoreEvents.emitFeedback).toHaveBeenCalledWith(
|
||||
'error',
|
||||
'MCP is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli',
|
||||
);
|
||||
expect(mockRunExitCleanup).toHaveBeenCalled();
|
||||
expect(mockExit).toHaveBeenCalledWith(ExitCodes.FATAL_CONFIG_ERROR);
|
||||
@@ -102,8 +101,9 @@ describe('deferred', () => {
|
||||
const settings = createMockSettings({ extensions: { enabled: false } });
|
||||
await runDeferredCommand(settings);
|
||||
|
||||
expect(mockDebugLogger.error).toHaveBeenCalledWith(
|
||||
'Error: Extensions are disabled by your admin.',
|
||||
expect(mockCoreEvents.emitFeedback).toHaveBeenCalledWith(
|
||||
'error',
|
||||
'Extensions is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli',
|
||||
);
|
||||
expect(mockRunExitCleanup).toHaveBeenCalled();
|
||||
expect(mockExit).toHaveBeenCalledWith(ExitCodes.FATAL_CONFIG_ERROR);
|
||||
@@ -119,8 +119,9 @@ describe('deferred', () => {
|
||||
const settings = createMockSettings({ skills: { enabled: false } });
|
||||
await runDeferredCommand(settings);
|
||||
|
||||
expect(mockDebugLogger.error).toHaveBeenCalledWith(
|
||||
'Error: Agent skills are disabled by your admin.',
|
||||
expect(mockCoreEvents.emitFeedback).toHaveBeenCalledWith(
|
||||
'error',
|
||||
'Agent skills is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli',
|
||||
);
|
||||
expect(mockRunExitCleanup).toHaveBeenCalled();
|
||||
expect(mockExit).toHaveBeenCalledWith(ExitCodes.FATAL_CONFIG_ERROR);
|
||||
@@ -183,8 +184,9 @@ describe('deferred', () => {
|
||||
const mcpSettings = createMockSettings({ mcp: { enabled: false } });
|
||||
await runDeferredCommand(mcpSettings);
|
||||
|
||||
expect(mockDebugLogger.error).toHaveBeenCalledWith(
|
||||
'Error: MCP is disabled by your admin.',
|
||||
expect(mockCoreEvents.emitFeedback).toHaveBeenCalledWith(
|
||||
'error',
|
||||
'MCP is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli',
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -4,7 +4,11 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
import type { ArgumentsCamelCase, CommandModule } from 'yargs';
|
||||
import { debugLogger, ExitCodes } from '@google/gemini-cli-core';
|
||||
import {
|
||||
coreEvents,
|
||||
ExitCodes,
|
||||
getAdminErrorMessage,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { runExitCleanup } from './utils/cleanup.js';
|
||||
import type { MergedSettings } from './config/settings.js';
|
||||
import process from 'node:process';
|
||||
@@ -30,7 +34,10 @@ export async function runDeferredCommand(settings: MergedSettings) {
|
||||
const commandName = deferredCommand.commandName;
|
||||
|
||||
if (commandName === 'mcp' && adminSettings?.mcp?.enabled === false) {
|
||||
debugLogger.error('Error: MCP is disabled by your admin.');
|
||||
coreEvents.emitFeedback(
|
||||
'error',
|
||||
getAdminErrorMessage('MCP', undefined /* config */),
|
||||
);
|
||||
await runExitCleanup();
|
||||
process.exit(ExitCodes.FATAL_CONFIG_ERROR);
|
||||
}
|
||||
@@ -39,13 +46,19 @@ export async function runDeferredCommand(settings: MergedSettings) {
|
||||
commandName === 'extensions' &&
|
||||
adminSettings?.extensions?.enabled === false
|
||||
) {
|
||||
debugLogger.error('Error: Extensions are disabled by your admin.');
|
||||
coreEvents.emitFeedback(
|
||||
'error',
|
||||
getAdminErrorMessage('Extensions', undefined /* config */),
|
||||
);
|
||||
await runExitCleanup();
|
||||
process.exit(ExitCodes.FATAL_CONFIG_ERROR);
|
||||
}
|
||||
|
||||
if (commandName === 'skills' && adminSettings?.skills?.enabled === false) {
|
||||
debugLogger.error('Error: Agent skills are disabled by your admin.');
|
||||
coreEvents.emitFeedback(
|
||||
'error',
|
||||
getAdminErrorMessage('Agent skills', undefined /* config */),
|
||||
);
|
||||
await runExitCleanup();
|
||||
process.exit(ExitCodes.FATAL_CONFIG_ERROR);
|
||||
}
|
||||
|
||||
@@ -12,7 +12,11 @@ import {
|
||||
type CommandContext,
|
||||
} from '../ui/commands/types.js';
|
||||
import type { MessageActionReturn, Config } from '@google/gemini-cli-core';
|
||||
import { isNightly, startupProfiler } from '@google/gemini-cli-core';
|
||||
import {
|
||||
isNightly,
|
||||
startupProfiler,
|
||||
getAdminErrorMessage,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { aboutCommand } from '../ui/commands/aboutCommand.js';
|
||||
import { agentsCommand } from '../ui/commands/agentsCommand.js';
|
||||
import { authCommand } from '../ui/commands/authCommand.js';
|
||||
@@ -102,7 +106,10 @@ export class BuiltinCommandLoader implements ICommandLoader {
|
||||
): Promise<MessageActionReturn> => ({
|
||||
type: 'message',
|
||||
messageType: 'error',
|
||||
content: 'Extensions are disabled by your admin.',
|
||||
content: getAdminErrorMessage(
|
||||
'Extensions',
|
||||
this.config ?? undefined,
|
||||
),
|
||||
}),
|
||||
},
|
||||
]
|
||||
@@ -127,7 +134,7 @@ export class BuiltinCommandLoader implements ICommandLoader {
|
||||
): Promise<MessageActionReturn> => ({
|
||||
type: 'message',
|
||||
messageType: 'error',
|
||||
content: 'MCP is disabled by your admin.',
|
||||
content: getAdminErrorMessage('MCP', this.config ?? undefined),
|
||||
}),
|
||||
},
|
||||
]
|
||||
@@ -158,7 +165,10 @@ export class BuiltinCommandLoader implements ICommandLoader {
|
||||
): Promise<MessageActionReturn> => ({
|
||||
type: 'message',
|
||||
messageType: 'error',
|
||||
content: 'Agent skills are disabled by your admin.',
|
||||
content: getAdminErrorMessage(
|
||||
'Agent skills',
|
||||
this.config ?? undefined,
|
||||
),
|
||||
}),
|
||||
},
|
||||
]
|
||||
|
||||
@@ -58,6 +58,7 @@ describe('skillsCommand', () => {
|
||||
(name: string) => skills.find((s) => s.name === name) ?? null,
|
||||
),
|
||||
}),
|
||||
getContentGenerator: vi.fn(),
|
||||
} as unknown as Config,
|
||||
settings: {
|
||||
merged: createTestMergedSettings({ skills: { disabled: [] } }),
|
||||
@@ -367,7 +368,7 @@ describe('skillsCommand', () => {
|
||||
expect(context.ui.addItem).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
type: MessageType.ERROR,
|
||||
text: 'Agent skills are disabled by your admin.',
|
||||
text: 'Agent skills is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli',
|
||||
}),
|
||||
expect.any(Number),
|
||||
);
|
||||
@@ -385,7 +386,7 @@ describe('skillsCommand', () => {
|
||||
expect(context.ui.addItem).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
type: MessageType.ERROR,
|
||||
text: 'Agent skills are disabled by your admin.',
|
||||
text: 'Agent skills is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli',
|
||||
}),
|
||||
expect.any(Number),
|
||||
);
|
||||
|
||||
@@ -11,13 +11,15 @@ import {
|
||||
CommandKind,
|
||||
} from './types.js';
|
||||
import {
|
||||
MessageType,
|
||||
type HistoryItemSkillsList,
|
||||
type HistoryItemInfo,
|
||||
type HistoryItemSkillsList,
|
||||
MessageType,
|
||||
} from '../types.js';
|
||||
import { SettingScope } from '../../config/settings.js';
|
||||
import { enableSkill, disableSkill } from '../../utils/skillSettings.js';
|
||||
import { disableSkill, enableSkill } from '../../utils/skillSettings.js';
|
||||
|
||||
import { getAdminErrorMessage } from '@google/gemini-cli-core';
|
||||
import { renderSkillActionFeedback } from '../../utils/skillUtils.js';
|
||||
import { SettingScope } from '../../config/settings.js';
|
||||
|
||||
async function listAction(
|
||||
context: CommandContext,
|
||||
@@ -83,7 +85,10 @@ async function disableAction(
|
||||
context.ui.addItem(
|
||||
{
|
||||
type: MessageType.ERROR,
|
||||
text: 'Agent skills are disabled by your admin.',
|
||||
text: getAdminErrorMessage(
|
||||
'Agent skills',
|
||||
context.services.config ?? undefined,
|
||||
),
|
||||
},
|
||||
Date.now(),
|
||||
);
|
||||
@@ -141,7 +146,10 @@ async function enableAction(
|
||||
context.ui.addItem(
|
||||
{
|
||||
type: MessageType.ERROR,
|
||||
text: 'Agent skills are disabled by your admin.',
|
||||
text: getAdminErrorMessage(
|
||||
'Agent skills',
|
||||
context.services.config ?? undefined,
|
||||
),
|
||||
},
|
||||
Date.now(),
|
||||
);
|
||||
|
||||
@@ -30,6 +30,9 @@ vi.mock('@google/gemini-cli-core', async () => {
|
||||
return {
|
||||
...actualServerModule,
|
||||
Config: vi.fn(),
|
||||
getAdminErrorMessage: vi.fn(
|
||||
(featureName: string) => `[Mock] ${featureName} is disabled`,
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -52,6 +55,9 @@ interface MockConfigInstanceShape {
|
||||
getUserMemory: Mock<() => string>;
|
||||
getGeminiMdFileCount: Mock<() => number>;
|
||||
getToolRegistry: Mock<() => { discoverTools: Mock<() => void> }>;
|
||||
getRemoteAdminSettings: Mock<
|
||||
() => { strictModeDisabled?: boolean; mcpEnabled?: boolean } | undefined
|
||||
>;
|
||||
}
|
||||
|
||||
type UseKeypressHandler = (key: Key) => void;
|
||||
@@ -109,6 +115,9 @@ describe('useApprovalModeIndicator', () => {
|
||||
.mockReturnValue({ discoverTools: vi.fn() }) as Mock<
|
||||
() => { discoverTools: Mock<() => void> }
|
||||
>,
|
||||
getRemoteAdminSettings: vi.fn().mockReturnValue(undefined) as Mock<
|
||||
() => { strictModeDisabled?: boolean } | undefined
|
||||
>,
|
||||
};
|
||||
instanceSetApprovalModeMock.mockImplementation((value: ApprovalMode) => {
|
||||
instanceGetApprovalModeMock.mockReturnValue(value);
|
||||
@@ -517,6 +526,9 @@ describe('useApprovalModeIndicator', () => {
|
||||
|
||||
it('should not enable YOLO mode when Ctrl+Y is pressed and add an info message', () => {
|
||||
mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);
|
||||
mockConfigInstance.getRemoteAdminSettings.mockReturnValue({
|
||||
strictModeDisabled: true,
|
||||
});
|
||||
const mockAddItem = vi.fn();
|
||||
const { result } = renderHook(() =>
|
||||
useApprovalModeIndicator({
|
||||
@@ -544,6 +556,58 @@ describe('useApprovalModeIndicator', () => {
|
||||
// The mode should not change
|
||||
expect(result.current).toBe(ApprovalMode.DEFAULT);
|
||||
});
|
||||
|
||||
it('should show admin error message when YOLO mode is disabled by admin', () => {
|
||||
mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);
|
||||
mockConfigInstance.getRemoteAdminSettings.mockReturnValue({
|
||||
mcpEnabled: true,
|
||||
});
|
||||
|
||||
const mockAddItem = vi.fn();
|
||||
renderHook(() =>
|
||||
useApprovalModeIndicator({
|
||||
config: mockConfigInstance as unknown as ActualConfigType,
|
||||
addItem: mockAddItem,
|
||||
}),
|
||||
);
|
||||
|
||||
act(() => {
|
||||
capturedUseKeypressHandler({ name: 'y', ctrl: true } as Key);
|
||||
});
|
||||
|
||||
expect(mockAddItem).toHaveBeenCalledWith(
|
||||
{
|
||||
type: MessageType.WARNING,
|
||||
text: '[Mock] YOLO mode is disabled',
|
||||
},
|
||||
expect.any(Number),
|
||||
);
|
||||
});
|
||||
|
||||
it('should show default error message when admin settings are empty', () => {
|
||||
mockConfigInstance.getApprovalMode.mockReturnValue(ApprovalMode.DEFAULT);
|
||||
mockConfigInstance.getRemoteAdminSettings.mockReturnValue({});
|
||||
|
||||
const mockAddItem = vi.fn();
|
||||
renderHook(() =>
|
||||
useApprovalModeIndicator({
|
||||
config: mockConfigInstance as unknown as ActualConfigType,
|
||||
addItem: mockAddItem,
|
||||
}),
|
||||
);
|
||||
|
||||
act(() => {
|
||||
capturedUseKeypressHandler({ name: 'y', ctrl: true } as Key);
|
||||
});
|
||||
|
||||
expect(mockAddItem).toHaveBeenCalledWith(
|
||||
{
|
||||
type: MessageType.WARNING,
|
||||
text: 'You cannot enter YOLO mode since it is disabled in your settings.',
|
||||
},
|
||||
expect.any(Number),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should call onApprovalModeChange when switching to YOLO mode', () => {
|
||||
|
||||
@@ -5,7 +5,11 @@
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { ApprovalMode, type Config } from '@google/gemini-cli-core';
|
||||
import {
|
||||
ApprovalMode,
|
||||
type Config,
|
||||
getAdminErrorMessage,
|
||||
} from '@google/gemini-cli-core';
|
||||
import { useKeypress } from './useKeypress.js';
|
||||
import { keyMatchers, Command } from '../keyMatchers.js';
|
||||
import type { HistoryItemWithoutId } from '../types.js';
|
||||
@@ -41,10 +45,19 @@ export function useApprovalModeIndicator({
|
||||
config.getApprovalMode() !== ApprovalMode.YOLO
|
||||
) {
|
||||
if (addItem) {
|
||||
let text =
|
||||
'You cannot enter YOLO mode since it is disabled in your settings.';
|
||||
const adminSettings = config.getRemoteAdminSettings();
|
||||
const hasSettings =
|
||||
adminSettings && Object.keys(adminSettings).length > 0;
|
||||
if (hasSettings && !adminSettings.strictModeDisabled) {
|
||||
text = getAdminErrorMessage('YOLO mode', config);
|
||||
}
|
||||
|
||||
addItem(
|
||||
{
|
||||
type: MessageType.WARNING,
|
||||
text: 'You cannot enter YOLO mode since it is disabled in your settings.',
|
||||
text,
|
||||
},
|
||||
Date.now(),
|
||||
);
|
||||
|
||||
@@ -17,8 +17,15 @@ import {
|
||||
fetchAdminControls,
|
||||
sanitizeAdminSettings,
|
||||
stopAdminControlsPolling,
|
||||
getAdminErrorMessage,
|
||||
} from './admin_controls.js';
|
||||
import type { CodeAssistServer } from '../server.js';
|
||||
import type { Config } from '../../config/config.js';
|
||||
import { getCodeAssistServer } from '../codeAssist.js';
|
||||
|
||||
vi.mock('../codeAssist.js', () => ({
|
||||
getCodeAssistServer: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('Admin Controls', () => {
|
||||
let mockServer: CodeAssistServer;
|
||||
@@ -370,6 +377,57 @@ describe('Admin Controls', () => {
|
||||
|
||||
// The poll should not have fired again
|
||||
expect(mockServer.fetchAdminControls).toHaveBeenCalledTimes(1);
|
||||
expect(mockServer.fetchAdminControls).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getAdminErrorMessage', () => {
|
||||
let mockConfig: Config;
|
||||
|
||||
beforeEach(() => {
|
||||
mockConfig = {} as Config;
|
||||
});
|
||||
|
||||
it('should include feature name and project ID when present', () => {
|
||||
vi.mocked(getCodeAssistServer).mockReturnValue({
|
||||
projectId: 'test-project-123',
|
||||
} as CodeAssistServer);
|
||||
|
||||
const message = getAdminErrorMessage('Code Completion', mockConfig);
|
||||
|
||||
expect(message).toBe(
|
||||
'Code Completion is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli?project=test-project-123',
|
||||
);
|
||||
});
|
||||
|
||||
it('should include feature name but OMIT project ID when missing', () => {
|
||||
vi.mocked(getCodeAssistServer).mockReturnValue({
|
||||
projectId: undefined,
|
||||
} as CodeAssistServer);
|
||||
|
||||
const message = getAdminErrorMessage('Chat', mockConfig);
|
||||
|
||||
expect(message).toBe(
|
||||
'Chat is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli',
|
||||
);
|
||||
});
|
||||
|
||||
it('should include feature name but OMIT project ID when server is undefined', () => {
|
||||
vi.mocked(getCodeAssistServer).mockReturnValue(undefined);
|
||||
|
||||
const message = getAdminErrorMessage('Chat', mockConfig);
|
||||
|
||||
expect(message).toBe(
|
||||
'Chat is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli',
|
||||
);
|
||||
});
|
||||
|
||||
it('should include feature name but OMIT project ID when config is undefined', () => {
|
||||
const message = getAdminErrorMessage('Chat', undefined);
|
||||
|
||||
expect(message).toBe(
|
||||
'Chat is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,6 +11,8 @@ import {
|
||||
type FetchAdminControlsResponse,
|
||||
FetchAdminControlsResponseSchema,
|
||||
} from '../types.js';
|
||||
import { getCodeAssistServer } from '../codeAssist.js';
|
||||
import type { Config } from '../../config/config.js';
|
||||
|
||||
let pollingInterval: NodeJS.Timeout | undefined;
|
||||
let currentSettings: FetchAdminControlsResponse | undefined;
|
||||
@@ -132,3 +134,20 @@ export function stopAdminControlsPolling() {
|
||||
pollingInterval = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a standardized error message for features disabled by admin settings.
|
||||
*
|
||||
* @param featureName The name of the disabled feature
|
||||
* @param config The application config
|
||||
* @returns The formatted error message
|
||||
*/
|
||||
export function getAdminErrorMessage(
|
||||
featureName: string,
|
||||
config: Config | undefined,
|
||||
): string {
|
||||
const server = config ? getCodeAssistServer(config) : undefined;
|
||||
const projectId = server?.projectId;
|
||||
const projectParam = projectId ? `?project=${projectId}` : '';
|
||||
return `${featureName} is disabled by your administrator. To enable it, please request an update to the settings at: https://goo.gle/manage-gemini-cli${projectParam}`;
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ export * from './code_assist/server.js';
|
||||
export * from './code_assist/setup.js';
|
||||
export * from './code_assist/types.js';
|
||||
export * from './code_assist/telemetry.js';
|
||||
export * from './code_assist/admin/admin_controls.js';
|
||||
export * from './core/apiKeyCredentialStorage.js';
|
||||
|
||||
// Export utilities
|
||||
|
||||
Reference in New Issue
Block a user