diff options
Diffstat (limited to 'packages/cli/src/ui/commands')
| -rw-r--r-- | packages/cli/src/ui/commands/ideCommand.test.ts | 52 | ||||
| -rw-r--r-- | packages/cli/src/ui/commands/ideCommand.ts | 183 |
2 files changed, 148 insertions, 87 deletions
diff --git a/packages/cli/src/ui/commands/ideCommand.test.ts b/packages/cli/src/ui/commands/ideCommand.test.ts index 3c73f52c..3c73549c 100644 --- a/packages/cli/src/ui/commands/ideCommand.test.ts +++ b/packages/cli/src/ui/commands/ideCommand.test.ts @@ -32,11 +32,19 @@ describe('ideCommand', () => { ui: { addItem: vi.fn(), }, + services: { + settings: { + setValue: vi.fn(), + }, + }, } as unknown as CommandContext; mockConfig = { + getIdeModeFeature: vi.fn(), getIdeMode: vi.fn(), getIdeClient: vi.fn(), + setIdeMode: vi.fn(), + setIdeClientDisconnected: vi.fn(), } as unknown as Config; platformSpy = vi.spyOn(process, 'platform', 'get'); @@ -46,13 +54,14 @@ describe('ideCommand', () => { vi.restoreAllMocks(); }); - it('should return null if ideMode is not enabled', () => { - vi.mocked(mockConfig.getIdeMode).mockReturnValue(false); + it('should return null if ideModeFeature is not enabled', () => { + vi.mocked(mockConfig.getIdeModeFeature).mockReturnValue(false); const command = ideCommand(mockConfig); expect(command).toBeNull(); }); - it('should return the ide command if ideMode is enabled', () => { + it('should return the ide command if ideModeFeature is enabled', () => { + vi.mocked(mockConfig.getIdeModeFeature).mockReturnValue(true); vi.mocked(mockConfig.getIdeMode).mockReturnValue(true); vi.mocked(mockConfig.getIdeClient).mockReturnValue({ getCurrentIde: () => DetectedIde.VSCode, @@ -60,19 +69,20 @@ describe('ideCommand', () => { const command = ideCommand(mockConfig); expect(command).not.toBeNull(); expect(command?.name).toBe('ide'); - expect(command?.subCommands).toHaveLength(2); - expect(command?.subCommands?.[0].name).toBe('status'); - expect(command?.subCommands?.[1].name).toBe('install'); + expect(command?.subCommands).toHaveLength(3); + expect(command?.subCommands?.[0].name).toBe('disable'); + expect(command?.subCommands?.[1].name).toBe('status'); + expect(command?.subCommands?.[2].name).toBe('install'); }); describe('status subcommand', () => { const mockGetConnectionStatus = vi.fn(); beforeEach(() => { - vi.mocked(mockConfig.getIdeMode).mockReturnValue(true); + vi.mocked(mockConfig.getIdeModeFeature).mockReturnValue(true); vi.mocked(mockConfig.getIdeClient).mockReturnValue({ getConnectionStatus: mockGetConnectionStatus, getCurrentIde: () => DetectedIde.VSCode, - } as ReturnType<Config['getIdeClient']>); + } as unknown as ReturnType<Config['getIdeClient']>); }); it('should show connected status', () => { @@ -80,7 +90,8 @@ describe('ideCommand', () => { status: core.IDEConnectionStatus.Connected, }); const command = ideCommand(mockConfig); - const result = command!.subCommands![0].action!(mockContext, ''); + const result = command!.subCommands!.find((c) => c.name === 'status')! + .action!(mockContext, ''); expect(mockGetConnectionStatus).toHaveBeenCalled(); expect(result).toEqual({ type: 'message', @@ -94,7 +105,8 @@ describe('ideCommand', () => { status: core.IDEConnectionStatus.Connecting, }); const command = ideCommand(mockConfig); - const result = command!.subCommands![0].action!(mockContext, ''); + const result = command!.subCommands!.find((c) => c.name === 'status')! + .action!(mockContext, ''); expect(mockGetConnectionStatus).toHaveBeenCalled(); expect(result).toEqual({ type: 'message', @@ -107,7 +119,8 @@ describe('ideCommand', () => { status: core.IDEConnectionStatus.Disconnected, }); const command = ideCommand(mockConfig); - const result = command!.subCommands![0].action!(mockContext, ''); + const result = command!.subCommands!.find((c) => c.name === 'status')! + .action!(mockContext, ''); expect(mockGetConnectionStatus).toHaveBeenCalled(); expect(result).toEqual({ type: 'message', @@ -123,7 +136,8 @@ describe('ideCommand', () => { details, }); const command = ideCommand(mockConfig); - const result = command!.subCommands![0].action!(mockContext, ''); + const result = command!.subCommands!.find((c) => c.name === 'status')! + .action!(mockContext, ''); expect(mockGetConnectionStatus).toHaveBeenCalled(); expect(result).toEqual({ type: 'message', @@ -136,10 +150,12 @@ describe('ideCommand', () => { describe('install subcommand', () => { const mockInstall = vi.fn(); beforeEach(() => { + vi.mocked(mockConfig.getIdeModeFeature).mockReturnValue(true); vi.mocked(mockConfig.getIdeMode).mockReturnValue(true); vi.mocked(mockConfig.getIdeClient).mockReturnValue({ getCurrentIde: () => DetectedIde.VSCode, - } as ReturnType<Config['getIdeClient']>); + getConnectionStatus: vi.fn(), + } as unknown as ReturnType<Config['getIdeClient']>); vi.mocked(core.getIdeInstaller).mockReturnValue({ install: mockInstall, isInstalled: vi.fn(), @@ -154,7 +170,10 @@ describe('ideCommand', () => { }); const command = ideCommand(mockConfig); - await command!.subCommands![1].action!(mockContext, ''); + await command!.subCommands!.find((c) => c.name === 'install')!.action!( + mockContext, + '', + ); expect(core.getIdeInstaller).toHaveBeenCalledWith('vscode'); expect(mockInstall).toHaveBeenCalled(); @@ -181,7 +200,10 @@ describe('ideCommand', () => { }); const command = ideCommand(mockConfig); - await command!.subCommands![1].action!(mockContext, ''); + await command!.subCommands!.find((c) => c.name === 'install')!.action!( + mockContext, + '', + ); expect(core.getIdeInstaller).toHaveBeenCalledWith('vscode'); expect(mockInstall).toHaveBeenCalled(); diff --git a/packages/cli/src/ui/commands/ideCommand.ts b/packages/cli/src/ui/commands/ideCommand.ts index 26b0f57d..1da7d6b0 100644 --- a/packages/cli/src/ui/commands/ideCommand.ts +++ b/packages/cli/src/ui/commands/ideCommand.ts @@ -6,9 +6,9 @@ import { Config, + IDEConnectionStatus, getIdeDisplayName, getIdeInstaller, - IDEConnectionStatus, } from '@google/gemini-cli-core'; import { CommandContext, @@ -16,91 +16,130 @@ import { SlashCommandActionReturn, CommandKind, } from './types.js'; +import { SettingScope } from '../../config/settings.js'; export const ideCommand = (config: Config | null): SlashCommand | null => { - if (!config?.getIdeMode()) { + if (!config?.getIdeModeFeature()) { return null; } const currentIDE = config.getIdeClient().getCurrentIde(); if (!currentIDE) { - throw new Error( - 'IDE slash command should not be available if not running in an IDE', - ); + return null; } - return { + const ideSlashCommand: SlashCommand = { name: 'ide', description: 'manage IDE integration', kind: CommandKind.BUILT_IN, - subCommands: [ - { - name: 'status', - description: 'check status of IDE integration', - kind: CommandKind.BUILT_IN, - action: (_context: CommandContext): SlashCommandActionReturn => { - const connection = config.getIdeClient().getConnectionStatus(); - switch (connection?.status) { - case IDEConnectionStatus.Connected: - return { - type: 'message', - messageType: 'info', - content: `🟢 Connected`, - } as const; - case IDEConnectionStatus.Connecting: - return { - type: 'message', - messageType: 'info', - content: `🟡 Connecting...`, - } as const; - default: { - let content = `🔴 Disconnected`; - if (connection?.details) { - content += `: ${connection.details}`; - } - return { - type: 'message', - messageType: 'error', - content, - } as const; - } - } - }, - }, - { - name: 'install', - description: `install required IDE companion ${getIdeDisplayName(currentIDE)} extension `, - kind: CommandKind.BUILT_IN, - action: async (context) => { - const installer = getIdeInstaller(currentIDE); - if (!installer) { - context.ui.addItem( - { - type: 'error', - text: 'No installer available for your configured IDE.', - }, - Date.now(), - ); - return; + subCommands: [], + }; + + const statusCommand: SlashCommand = { + name: 'status', + description: 'check status of IDE integration', + kind: CommandKind.BUILT_IN, + action: (_context: CommandContext): SlashCommandActionReturn => { + const connection = config.getIdeClient().getConnectionStatus(); + switch (connection?.status) { + case IDEConnectionStatus.Connected: + return { + type: 'message', + messageType: 'info', + content: `🟢 Connected`, + } as const; + case IDEConnectionStatus.Connecting: + return { + type: 'message', + messageType: 'info', + content: `🟡 Connecting...`, + } as const; + default: { + let content = `🔴 Disconnected`; + if (connection?.details) { + content += `: ${connection.details}`; } + return { + type: 'message', + messageType: 'error', + content, + } as const; + } + } + }, + }; - context.ui.addItem( - { - type: 'info', - text: `Installing IDE companion extension...`, - }, - Date.now(), - ); + const installCommand: SlashCommand = { + name: 'install', + description: `install required IDE companion ${getIdeDisplayName(currentIDE)} extension `, + kind: CommandKind.BUILT_IN, + action: async (context) => { + const installer = getIdeInstaller(currentIDE); + if (!installer) { + context.ui.addItem( + { + type: 'error', + text: 'No installer available for your configured IDE.', + }, + Date.now(), + ); + return; + } - const result = await installer.install(); - context.ui.addItem( - { - type: result.success ? 'info' : 'error', - text: result.message, - }, - Date.now(), - ); + context.ui.addItem( + { + type: 'info', + text: `Installing IDE companion extension...`, }, - }, - ], + Date.now(), + ); + + const result = await installer.install(); + context.ui.addItem( + { + type: result.success ? 'info' : 'error', + text: result.message, + }, + Date.now(), + ); + }, + }; + + const enableCommand: SlashCommand = { + name: 'enable', + description: 'enable IDE integration', + kind: CommandKind.BUILT_IN, + action: async (context: CommandContext) => { + context.services.settings.setValue(SettingScope.User, 'ideMode', true); + config.setIdeMode(true); + config.setIdeClientConnected(); + }, + }; + + const disableCommand: SlashCommand = { + name: 'disable', + description: 'disable IDE integration', + kind: CommandKind.BUILT_IN, + action: async (context: CommandContext) => { + context.services.settings.setValue(SettingScope.User, 'ideMode', false); + config.setIdeMode(false); + config.setIdeClientDisconnected(); + }, }; + + const ideModeEnabled = config.getIdeMode(); + if (ideModeEnabled) { + ideSlashCommand.subCommands = [ + disableCommand, + statusCommand, + installCommand, + ]; + } else { + ideSlashCommand.subCommands = [ + enableCommand, + statusCommand, + installCommand, + ]; + } + + return ideSlashCommand; }; |
