2025-07-16 18:36:14 -04:00
/ * *
* @license
* Copyright 2025 Google LLC
* SPDX - License - Identifier : Apache - 2.0
* /
2025-07-30 21:26:31 +00:00
import {
Config ,
2025-08-04 17:06:17 -04:00
DetectedIde ,
2025-07-30 22:36:24 +00:00
IDEConnectionStatus ,
2025-07-30 21:26:31 +00:00
getIdeDisplayName ,
getIdeInstaller ,
2025-08-05 18:52:58 -04:00
IdeClient ,
2025-07-30 21:26:31 +00:00
} from '@google/gemini-cli-core' ;
2025-07-16 18:36:14 -04:00
import {
CommandContext ,
SlashCommand ,
SlashCommandActionReturn ,
2025-07-20 16:57:34 -04:00
CommandKind ,
2025-07-16 18:36:14 -04:00
} from './types.js' ;
2025-07-30 22:36:24 +00:00
import { SettingScope } from '../../config/settings.js' ;
2025-07-16 18:36:14 -04:00
2025-08-05 18:52:58 -04:00
function getIdeStatusMessage ( ideClient : IdeClient ) : {
messageType : 'info' | 'error' ;
content : string ;
} {
const connection = ideClient . getConnectionStatus ( ) ;
switch ( connection . status ) {
case IDEConnectionStatus . Connected :
return {
messageType : 'info' ,
content : ` 🟢 Connected to ${ ideClient . getDetectedIdeDisplayName ( ) } ` ,
} ;
case IDEConnectionStatus . Connecting :
return {
messageType : 'info' ,
content : ` 🟡 Connecting... ` ,
} ;
default : {
let content = ` 🔴 Disconnected ` ;
if ( connection ? . details ) {
content += ` : ${ connection . details } ` ;
}
return {
messageType : 'error' ,
content ,
} ;
}
}
}
2025-07-16 18:36:14 -04:00
export const ideCommand = ( config : Config | null ) : SlashCommand | null = > {
2025-08-04 17:06:17 -04:00
if ( ! config || ! config . getIdeModeFeature ( ) ) {
2025-07-16 18:36:14 -04:00
return null ;
}
2025-08-04 17:06:17 -04:00
const ideClient = config . getIdeClient ( ) ;
const currentIDE = ideClient . getCurrentIde ( ) ;
if ( ! currentIDE || ! ideClient . getDetectedIdeDisplayName ( ) ) {
return {
name : 'ide' ,
description : 'manage IDE integration' ,
kind : CommandKind.BUILT_IN ,
action : ( ) : SlashCommandActionReturn = >
( {
type : 'message' ,
messageType : 'error' ,
content : ` IDE integration is not supported in your current environment. To use this feature, run Gemini CLI in one of these supported IDEs: ${ Object . values (
DetectedIde ,
)
. map ( ( ide ) = > getIdeDisplayName ( ide ) )
. join ( ', ' ) } ` ,
} ) as const ,
} ;
2025-07-30 21:26:31 +00:00
}
2025-07-16 18:36:14 -04:00
2025-07-30 22:36:24 +00:00
const ideSlashCommand : SlashCommand = {
2025-07-16 18:36:14 -04:00
name : 'ide' ,
description : 'manage IDE integration' ,
2025-07-20 16:57:34 -04:00
kind : CommandKind.BUILT_IN ,
2025-07-30 22:36:24 +00:00
subCommands : [ ] ,
} ;
const statusCommand : SlashCommand = {
name : 'status' ,
description : 'check status of IDE integration' ,
kind : CommandKind.BUILT_IN ,
2025-08-05 18:52:58 -04:00
action : ( ) : SlashCommandActionReturn = > {
const { messageType , content } = getIdeStatusMessage ( ideClient ) ;
return {
type : 'message' ,
messageType ,
content ,
} as const ;
2025-07-30 22:36:24 +00:00
} ,
} ;
2025-07-16 18:36:14 -04:00
2025-07-30 22:36:24 +00:00
const installCommand : SlashCommand = {
name : 'install' ,
2025-08-04 17:06:17 -04:00
description : ` install required IDE companion for ${ ideClient . getDetectedIdeDisplayName ( ) } ` ,
2025-07-30 22:36:24 +00:00
kind : CommandKind.BUILT_IN ,
action : async ( context ) = > {
const installer = getIdeInstaller ( currentIDE ) ;
if ( ! installer ) {
context . ui . addItem (
{
type : 'error' ,
2025-08-04 17:06:17 -04:00
text : ` No installer is available for ${ ideClient . getDetectedIdeDisplayName ( ) } . Please install the IDE companion manually from its marketplace. ` ,
2025-07-30 22:36:24 +00:00
} ,
Date . now ( ) ,
) ;
return ;
}
2025-07-30 21:26:31 +00:00
2025-07-30 22:36:24 +00:00
context . ui . addItem (
{
type : 'info' ,
2025-08-04 17:06:17 -04:00
text : ` Installing IDE companion... ` ,
2025-07-16 18:36:14 -04:00
} ,
2025-07-30 22:36:24 +00:00
Date . now ( ) ,
) ;
const result = await installer . install ( ) ;
2025-08-05 18:52:58 -04:00
if ( result . success ) {
config . setIdeMode ( true ) ;
context . services . settings . setValue ( SettingScope . User , 'ideMode' , true ) ;
}
2025-07-30 22:36:24 +00:00
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 ) ;
2025-08-05 18:52:58 -04:00
await config . setIdeModeAndSyncConnection ( true ) ;
const { messageType , content } = getIdeStatusMessage ( ideClient ) ;
context . ui . addItem (
{
type : messageType ,
text : content ,
} ,
Date . now ( ) ,
) ;
2025-07-30 22:36:24 +00:00
} ,
} ;
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 ) ;
2025-08-05 18:52:58 -04:00
await config . setIdeModeAndSyncConnection ( false ) ;
const { messageType , content } = getIdeStatusMessage ( ideClient ) ;
context . ui . addItem (
{
type : messageType ,
text : content ,
} ,
Date . now ( ) ,
) ;
2025-07-30 22:36:24 +00:00
} ,
2025-07-16 18:36:14 -04:00
} ;
2025-07-30 22:36:24 +00:00
const ideModeEnabled = config . getIdeMode ( ) ;
if ( ideModeEnabled ) {
ideSlashCommand . subCommands = [
disableCommand ,
statusCommand ,
installCommand ,
] ;
} else {
ideSlashCommand . subCommands = [
enableCommand ,
statusCommand ,
installCommand ,
] ;
}
return ideSlashCommand ;
2025-07-16 18:36:14 -04:00
} ;