import figures from 'figures' import * as React from 'react' import { Box, color, Text, useTheme } from '../../ink.js' import { plural } from '../../utils/stringUtils.js' import type { UnifiedInstalledItem } from './unifiedTypes.js' type Props = { item: UnifiedInstalledItem isSelected: boolean } export function UnifiedInstalledCell({ item, isSelected, }: Props): React.ReactNode { const [theme] = useTheme() if (item.type === 'plugin') { // Status icon and text let statusIcon: string let statusText: string // Show pending toggle status if set, otherwise show current status if (item.pendingToggle) { statusIcon = color('suggestion', theme)(figures.arrowRight) statusText = item.pendingToggle === 'will-enable' ? 'will enable' : 'will disable' } else if (item.errorCount > 0) { statusIcon = color('error', theme)(figures.cross) statusText = `${item.errorCount} ${plural(item.errorCount, 'error')}` } else if (!item.isEnabled) { statusIcon = color('inactive', theme)(figures.radioOff) statusText = 'disabled' } else { statusIcon = color('success', theme)(figures.tick) statusText = 'enabled' } return ( {isSelected ? `${figures.pointer} ` : ' '} {item.name} {' '} Plugin · {item.marketplace} · {statusIcon} {statusText} ) } if (item.type === 'flagged-plugin') { const statusIcon = color('warning', theme)(figures.warning) return ( {isSelected ? `${figures.pointer} ` : ' '} {item.name} {' '} Plugin · {item.marketplace} · {statusIcon} removed ) } if (item.type === 'failed-plugin') { const statusIcon = color('error', theme)(figures.cross) const statusText = `failed to load · ${item.errorCount} ${plural(item.errorCount, 'error')}` return ( {isSelected ? `${figures.pointer} ` : ' '} {item.name} {' '} Plugin · {item.marketplace} · {statusIcon} {statusText} ) } // MCP server let statusIcon: string let statusText: string if (item.status === 'connected') { statusIcon = color('success', theme)(figures.tick) statusText = 'connected' } else if (item.status === 'disabled') { statusIcon = color('inactive', theme)(figures.radioOff) statusText = 'disabled' } else if (item.status === 'pending') { statusIcon = color('inactive', theme)(figures.radioOff) statusText = 'connecting…' } else if (item.status === 'needs-auth') { statusIcon = color('warning', theme)(figures.triangleUpOutline) statusText = 'Enter to auth' } else { statusIcon = color('error', theme)(figures.cross) statusText = 'failed' } // Indented MCPs (child of a plugin) if (item.indented) { return ( {isSelected ? `${figures.pointer} ` : ' '} {item.name} {' '} MCP · {statusIcon} {statusText} ) } return ( {isSelected ? `${figures.pointer} ` : ' '} {item.name} {' '} MCP · {statusIcon} {statusText} ) }