From 4060c4f60b62c9eba4037e120ca4812a14ab53b5 Mon Sep 17 00:00:00 2001 From: Shantur Rathore Date: Tue, 23 Dec 2025 18:24:09 +0000 Subject: [PATCH] Show configured plugins in status panels --- .../components/instance-service-status.tsx | 34 +++++++++++++++- .../components/instance/instance-shell2.tsx | 40 ++++++++++++------- .../ui/src/lib/hooks/use-instance-metadata.ts | 12 +++++- packages/ui/src/types/instance.ts | 1 + 4 files changed, 69 insertions(+), 18 deletions(-) diff --git a/packages/ui/src/components/instance-service-status.tsx b/packages/ui/src/components/instance-service-status.tsx index dc610416..9cc1a639 100644 --- a/packages/ui/src/components/instance-service-status.tsx +++ b/packages/ui/src/components/instance-service-status.tsx @@ -6,7 +6,7 @@ import { getLogger } from "../lib/logger" const log = getLogger("session") -type ServiceSection = "lsp" | "mcp" +type ServiceSection = "lsp" | "mcp" | "plugins" interface InstanceServiceStatusProps { sections?: ServiceSection[] @@ -51,20 +51,25 @@ const InstanceServiceStatus: Component = (props) => }) const isLoading = metadataContext?.isLoading ?? (() => false) const refreshMetadata = metadataContext?.refreshMetadata ?? (async () => Promise.resolve()) - const sections = createMemo(() => props.sections ?? ["lsp", "mcp"]) + const sections = createMemo(() => props.sections ?? ["lsp", "mcp", "plugins"]) const includeLsp = createMemo(() => sections().includes("lsp")) const includeMcp = createMemo(() => sections().includes("mcp")) + const includePlugins = createMemo(() => sections().includes("plugins")) const showHeadings = () => props.showSectionHeadings !== false const metadataAccessor = metadataContext?.metadata ?? (() => instance().metadata) const metadata = createMemo(() => metadataAccessor()) const hasLspMetadata = () => metadata()?.lspStatus !== undefined const hasMcpMetadata = () => metadata()?.mcpStatus !== undefined + const hasPluginsMetadata = () => metadata()?.plugins !== undefined + const lspServers = createMemo(() => metadata()?.lspStatus ?? []) const mcpServers = createMemo(() => parseMcpStatus(metadata()?.mcpStatus ?? undefined)) + const plugins = createMemo(() => metadata()?.plugins ?? []) const isLspLoading = () => isLoading() || !hasLspMetadata() const isMcpLoading = () => isLoading() || !hasMcpMetadata() + const isPluginsLoading = () => isLoading() || !hasPluginsMetadata() const [pendingMcpActions, setPendingMcpActions] = createSignal>({}) @@ -213,10 +218,35 @@ const InstanceServiceStatus: Component = (props) => ) + const renderPluginsSection = () => ( +
+ +
+ Plugins +
+
+ 0} + fallback={renderEmptyState(isPluginsLoading() ? "Loading plugins..." : "No plugins configured.")} + > +
+ + {(plugin) => ( +
+
{plugin}
+
+ )} +
+
+
+
+ ) + return (
{renderLspSection()} {renderMcpSection()} + {renderPluginsSection()}
) } diff --git a/packages/ui/src/components/instance/instance-shell2.tsx b/packages/ui/src/components/instance/instance-shell2.tsx index 7f345f8a..a5af55e5 100644 --- a/packages/ui/src/components/instance/instance-shell2.tsx +++ b/packages/ui/src/components/instance/instance-shell2.tsx @@ -128,7 +128,7 @@ const InstanceShell2: Component = (props) => { const [activeResizeSide, setActiveResizeSide] = createSignal<"left" | "right" | null>(null) const [resizeStartX, setResizeStartX] = createSignal(0) const [resizeStartWidth, setResizeStartWidth] = createSignal(0) - const [rightPanelExpandedItems, setRightPanelExpandedItems] = createSignal(["lsp", "mcp"]) + const [rightPanelExpandedItems, setRightPanelExpandedItems] = createSignal(["plan", "mcp", "lsp", "plugins"]) const messageStore = createMemo(() => messageStoreBus.getOrCreate(props.instance.id)) @@ -855,16 +855,9 @@ const InstanceShell2: Component = (props) => { const sections = [ { - id: "lsp", - label: "LSP Servers", - render: () => ( - - ), + id: "plan", + label: "Plan", + render: renderPlanSectionContent, }, { id: "mcp", @@ -879,9 +872,28 @@ const InstanceShell2: Component = (props) => { ), }, { - id: "plan", - label: "Plan", - render: renderPlanSectionContent, + id: "lsp", + label: "LSP Servers", + render: () => ( + + ), + }, + { + id: "plugins", + label: "Plugins", + render: () => ( + + ), }, ] diff --git a/packages/ui/src/lib/hooks/use-instance-metadata.ts b/packages/ui/src/lib/hooks/use-instance-metadata.ts index d132c980..9f6e6c74 100644 --- a/packages/ui/src/lib/hooks/use-instance-metadata.ts +++ b/packages/ui/src/lib/hooks/use-instance-metadata.ts @@ -8,7 +8,7 @@ const pendingMetadataRequests = new Set() function hasMetadataLoaded(metadata?: Instance["metadata"]): boolean { if (!metadata) return false - return "project" in metadata && "mcpStatus" in metadata && "lspStatus" in metadata + return "project" in metadata && "mcpStatus" in metadata && "lspStatus" in metadata && "plugins" in metadata } export async function loadInstanceMetadata(instance: Instance, options?: { force?: boolean }): Promise { @@ -30,15 +30,18 @@ export async function loadInstanceMetadata(instance: Instance, options?: { force pendingMetadataRequests.add(instance.id) try { - const [projectResult, mcpResult, lspResult] = await Promise.allSettled([ + const [projectResult, mcpResult, lspResult, configResult] = await Promise.allSettled([ client.project.current(), client.mcp.status(), fetchLspStatus(instance.id), + client.config.get(), ]) const project = projectResult.status === "fulfilled" ? projectResult.value.data : undefined const mcpStatus = mcpResult.status === "fulfilled" ? (mcpResult.value.data as RawMcpStatus) : undefined const lspStatus = lspResult.status === "fulfilled" ? lspResult.value ?? [] : undefined + const config = configResult.status === "fulfilled" ? (configResult.value.data as { plugin?: unknown } | undefined) : undefined + const plugins = Array.isArray(config?.plugin) ? (config?.plugin as string[]) : undefined const updates: Instance["metadata"] = { ...(currentMetadata ?? {}) } @@ -54,10 +57,15 @@ export async function loadInstanceMetadata(instance: Instance, options?: { force updates.lspStatus = lspStatus ?? [] } + if (configResult.status === "fulfilled") { + updates.plugins = plugins ?? [] + } + if (!updates?.version && instance.binaryVersion) { updates.version = instance.binaryVersion } + mergeInstanceMetadata(instance.id, updates) } catch (error) { log.error("Failed to load instance metadata", error) diff --git a/packages/ui/src/types/instance.ts b/packages/ui/src/types/instance.ts index 34e8ff1f..b2ba792f 100644 --- a/packages/ui/src/types/instance.ts +++ b/packages/ui/src/types/instance.ts @@ -25,6 +25,7 @@ export interface InstanceMetadata { project?: ProjectInfo | null mcpStatus?: RawMcpStatus | null lspStatus?: LspStatus[] | null + plugins?: string[] | null version?: string }