MCPcopy
hub / github.com/codeaashu/claude-code / ManagePlugins

Function ManagePlugins

src/commands/plugin/ManagePlugins.tsx:397–2214  ·  view source on GitHub ↗
({
  setViewState: setParentViewState,
  setResult,
  onManageComplete,
  onSearchModeChange,
  targetPlugin,
  targetMarketplace,
  action
}: Props)

Source from the content-addressed store, hash-verified

395 });
396}
397export function ManagePlugins({
398 setViewState: setParentViewState,
399 setResult,
400 onManageComplete,
401 onSearchModeChange,
402 targetPlugin,
403 targetMarketplace,
404 action
405}: Props): React.ReactNode {
406 // App state for MCP access
407 const mcpClients = useAppState(s => s.mcp.clients);
408 const mcpTools = useAppState(s_0 => s_0.mcp.tools);
409 const pluginErrors = useAppState(s_1 => s_1.plugins.errors);
410 const flaggedPlugins = getFlaggedPlugins();
411
412 // Search state
413 const [isSearchMode, setIsSearchModeRaw] = useState(false);
414 const setIsSearchMode = useCallback((active: boolean) => {
415 setIsSearchModeRaw(active);
416 onSearchModeChange?.(active);
417 }, [onSearchModeChange]);
418 const isTerminalFocused = useTerminalFocus();
419 const {
420 columns: terminalWidth
421 } = useTerminalSize();
422
423 // View state
424 const [viewState, setViewState] = useState<ViewState>('plugin-list');
425 const {
426 query: searchQuery,
427 setQuery: setSearchQuery,
428 cursorOffset: searchCursorOffset
429 } = useSearchInput({
430 isActive: viewState === 'plugin-list' && isSearchMode,
431 onExit: () => {
432 setIsSearchMode(false);
433 }
434 });
435 const [selectedPlugin, setSelectedPlugin] = useState<PluginState | null>(null);
436
437 // Data state
438 const [marketplaces, setMarketplaces] = useState<MarketplaceInfo[]>([]);
439 const [pluginStates, setPluginStates] = useState<PluginState[]>([]);
440 const [loading, setLoading] = useState(true);
441 const [pendingToggles, setPendingToggles] = useState<Map<string, 'will-enable' | 'will-disable'>>(new Map());
442
443 // Guard to prevent auto-navigation from re-triggering after the user
444 // navigates away (targetPlugin is never cleared by the parent).
445 const hasAutoNavigated = useRef(false);
446 // Auto-action (enable/disable/uninstall) to fire after auto-navigation lands.
447 // Ref, not state: it's consumed by a one-shot effect that already re-runs on
448 // viewState/selectedPlugin, so a render-triggering state var would be redundant.
449 const pendingAutoActionRef = useRef<'enable' | 'disable' | 'uninstall' | undefined>(undefined);
450
451 // MCP toggle hook
452 const toggleMcpServer = useMcpToggleEnabled();
453
454 // Handle escape to go back - viewState-dependent navigation

Callers

nothing calls this directly

Calls 15

useAppStateFunction · 0.85
getFlaggedPluginsFunction · 0.85
useTerminalFocusFunction · 0.85
useTerminalSizeFunction · 0.85
useSearchInputFunction · 0.85
useMcpToggleEnabledFunction · 0.85
useKeybindingFunction · 0.85
getPluginEditableScopesFunction · 0.85
parsePluginIdentifierFunction · 0.85
getMcpStatusFunction · 0.85
markFlaggedPluginsSeenFunction · 0.85
usePaginationFunction · 0.85

Tested by

no test coverage detected