import React, { useState, useEffect, useMemo } from 'react' import { Package, Search, Download, Power, PowerOff, Trash2, RefreshCw, CheckCircle, Loader2, Info, Grid3x3, List, Sparkles, Puzzle, AlertCircle, X, Wrench } from 'lucide-react' import Typography from '../components/ui/Typography' import { Button } from '../components/ui/Button' import { Card, CardContent } from '../components/ui/Card' import { Input } from '../components/ui/input' import { usePluginStore } from '../stores/pluginStore' import type { PluginConfig, PluginSearchResult } from '../../shared/types/plugin' import { cn } from '../lib/utils' type ViewMode = 'installed' | 'catalog' interface PluginsPageProps {} interface PluginCardProps { plugin: PluginConfig; updateAvailable: boolean; progress?: any; isInstalling: boolean; onToggle: (pluginId: string, enabled: boolean) => void; onUpdate: (pluginId: string) => void; onUninstall: (pluginId: string) => void; } const PluginCard: React.FC = ({ plugin, updateAvailable, progress, isInstalling, onToggle, onUpdate, onUninstall }) => { return (
{plugin.name}
v{plugin.version} {updateAvailable && ( Update available )}
{plugin.metadata.description} {progress && (
{progress.phase} {progress.progress ? {progress.progress}% : null}
)}
{updateAvailable && ( )}
); }; interface SearchResultCardProps { result: PluginSearchResult; installed: boolean; installing: boolean; isInstalling: boolean; onInstall: (name: string) => void; } const SearchResultCard: React.FC = ({ result, installed, installing, isInstalling, onInstall }) => { return (
{result.name} v{result.version}
{installed && (
Installed
)}
{result.description} {result.score && (
Quality
Popular
)} {!installed && ( )} ); }; /** * Main page for plugin management with discovery, installation, and configuration */ const PluginsPage: React.FC = () => { const [viewMode, setViewMode] = useState('installed') const [searchQuery, setSearchQuery] = useState('') const [installingPlugins, setInstallingPlugins] = useState>(new Set()) const { plugins, searchResults, isSearching, isInstalling, isLoading, error, searchError, installError, installProgress, updateInfo, searchPlugins, installPlugin, uninstallPlugin, updatePlugin, enablePlugin, disablePlugin, loadInstalledPlugins, checkForUpdates, clearError, getEnabledPlugins } = usePluginStore() useEffect(() => { loadInstalledPlugins() }, [loadInstalledPlugins]) useEffect(() => { const checkUpdates = () => checkForUpdates().catch(() => {}) checkUpdates() const interval = setInterval(checkUpdates, 5 * 60 * 1000) return () => clearInterval(interval) }, [checkForUpdates]) useEffect(() => { if (viewMode === 'catalog' && searchQuery) { const debounceTimer = setTimeout(() => { searchPlugins(searchQuery).catch(() => {}) }, 500) return () => clearTimeout(debounceTimer) } }, [searchQuery, viewMode, searchPlugins]) const installedPluginsList = useMemo(() => { const pluginsList = Object.values(plugins) if (!searchQuery) return pluginsList const query = searchQuery.toLowerCase() return pluginsList.filter(plugin => plugin.name.toLowerCase().includes(query) || plugin.metadata.description?.toLowerCase().includes(query) || plugin.metadata.keywords?.some(k => k.toLowerCase().includes(query)) ) }, [plugins, searchQuery]) const isPluginInstalled = (name: string) => { return Object.values(plugins).some(p => p.name === name) } const handleInstallPlugin = async (name: string) => { setInstallingPlugins(prev => new Set(prev).add(name)) try { await installPlugin(name) } catch (error) { } finally { setInstallingPlugins(prev => { const next = new Set(prev) next.delete(name) return next }) } } const handleUninstallPlugin = async (pluginId: string) => { const plugin = plugins[pluginId] if (!plugin) return if (window.confirm(`Are you sure you want to uninstall "${plugin.name}"? This action cannot be undone.`)) { try { await uninstallPlugin(pluginId) } catch (error) { } } } const handleTogglePlugin = async (pluginId: string, enabled: boolean) => { try { if (enabled) { await enablePlugin(pluginId) } else { await disablePlugin(pluginId) } } catch (error) { } } const handleUpdatePlugin = async (pluginId: string) => { try { await updatePlugin(pluginId) } catch (error) { } } return (
Plugins
COMING SOON
The plugin system will allow you to extend your agent with additional capabilities {/* Coming Soon Notice - Made more prominent */}
Plugin System Under Development The plugin system is currently being developed and is not yet functional. Soon you'll be able to:
  • Install plugins from the NPM registry
  • Extend your agent with custom tools and integrations
  • Manage plugin configurations and permissions
{(error || searchError || installError) && (
Error {error || searchError || installError}
)} {/* Coming Soon Message - Moved up */}
Plugin System Coming Soon We're working hard to bring you an amazing plugin ecosystem. Check back soon!
In Development
{/* Search Bar - Disabled */}
{/* Main Content - With overlay */}
{/* Overlay to show content is not functional */}
Preview of upcoming plugin interface
{/* Original content - now behind overlay */}
{viewMode === 'installed' ? ( <> {isLoading ? (
Loading plugins...
) : installedPluginsList.length === 0 ? (
No Plugins Installed Browse the catalog to discover and install plugins.
) : (
{installedPluginsList.map(plugin => ( ))}
)} ) : ( <> {isSearching ? (
Searching plugins...
) : searchResults.length === 0 && searchQuery ? ( No Results Found Try searching with different keywords ) : searchResults.length > 0 ? (
{searchResults.map(result => ( ))}
) : (
Enter a search term to discover plugins
)} )}
Statistics
Installed {Object.keys(plugins).length}
Enabled {getEnabledPlugins().length}
Updates {Object.keys(updateInfo).length}
Quick Actions
Coming Soon
Local development
Custom registries
Permissions
Advanced config
) } export default PluginsPage