/** * @license * Copyright 2025 Google LLC * SPDX-License-Identifier: Apache-2.0 */ import type React from 'react'; import { Box, Text } from 'ink'; import { useUIState } from '../../contexts/UIStateContext.js'; import { ExtensionUpdateState } from '../../state/extensions.js'; import { debugLogger, type GeminiCLIExtension } from '@google/gemini-cli-core'; import { getFormattedSettingValue } from '../../../commands/extensions/utils.js'; interface ExtensionsList { extensions: readonly GeminiCLIExtension[]; } export const ExtensionsList: React.FC = ({ extensions }) => { const { extensionsUpdateState } = useUIState(); if (extensions.length === 0) { return No extensions installed.; } return ( Installed extensions: {extensions.map((ext) => { const state = extensionsUpdateState.get(ext.name); const isActive = ext.isActive; const activeString = isActive ? 'active' : 'disabled'; const activeColor = isActive ? 'green' : 'grey'; let stateColor = 'gray'; const stateText = state || 'unknown state'; switch (state) { case ExtensionUpdateState.CHECKING_FOR_UPDATES: case ExtensionUpdateState.UPDATING: stateColor = 'cyan'; break; case ExtensionUpdateState.UPDATE_AVAILABLE: case ExtensionUpdateState.UPDATED_NEEDS_RESTART: stateColor = 'yellow'; break; case ExtensionUpdateState.ERROR: stateColor = 'red'; break; case ExtensionUpdateState.UP_TO_DATE: case ExtensionUpdateState.NOT_UPDATABLE: case ExtensionUpdateState.UPDATED: stateColor = 'green'; break; case undefined: break; default: debugLogger.warn(`Unhandled ExtensionUpdateState ${state}`); break; } return ( {`${ext.name} (v${ext.version})`} {` - ${activeString}`} {{` (${stateText})`}} {ext.resolvedSettings && ext.resolvedSettings.length > 0 && ( settings: {ext.resolvedSettings.map((setting) => ( - {setting.name}: {getFormattedSettingValue(setting)} {setting.scope && ( {' '} ( {setting.scope.charAt(0).toUpperCase() + setting.scope.slice(1)} {setting.source ? ` - ${setting.source}` : ''}) )} ))} )} ); })} ); };