import { For, Show, type Accessor, type Component } from "solid-js" import type { ToolState } from "@opencode-ai/sdk" import { Accordion } from "@kobalte/core" import { ChevronDown, TerminalSquare, Trash2, XOctagon } from "lucide-solid" import type { Instance } from "../../../../../types/instance" import type { BackgroundProcess } from "../../../../../../../server/src/api-types" import type { Session } from "../../../../../types/session" import ContextUsagePanel from "../../../../session/context-usage-panel" import { TodoListView } from "../../../../tool-call/renderers/todo" import InstanceServiceStatus from "../../../../instance-service-status" interface StatusTabProps { t: (key: string, vars?: Record) => string instanceId: string instance: Instance activeSessionId: Accessor activeSession: Accessor activeSessionDiffs: Accessor latestTodoState: Accessor backgroundProcessList: Accessor onOpenBackgroundOutput: (process: BackgroundProcess) => void onStopBackgroundProcess: (processId: string) => Promise | void onTerminateBackgroundProcess: (processId: string) => Promise | void expandedItems: Accessor onExpandedItemsChange: (values: string[]) => void onOpenChangesTab: (file?: string) => void } const StatusTab: Component = (props) => { const isSectionExpanded = (id: string) => props.expandedItems().includes(id) const renderStatusSessionChanges = () => { const sessionId = props.activeSessionId() if (!sessionId || sessionId === "info") { return (
{props.t("instanceShell.sessionChanges.noSessionSelected")}
) } const diffs = props.activeSessionDiffs() if (diffs === undefined) { return (
{props.t("instanceShell.sessionChanges.loading")}
) } if (!Array.isArray(diffs) || diffs.length === 0) { return (
{props.t("instanceShell.sessionChanges.empty")}
) } const sorted = [...diffs].sort((a, b) => String(a.file || "").localeCompare(String(b.file || ""))) const totals = sorted.reduce( (acc, item) => { acc.additions += typeof item.additions === "number" ? item.additions : 0 acc.deletions += typeof item.deletions === "number" ? item.deletions : 0 return acc }, { additions: 0, deletions: 0 }, ) return (
{props.t("instanceShell.sessionChanges.filesChanged", { count: sorted.length })} {`+${totals.additions}`} {`-${totals.deletions}`}
{(item) => ( )}
) } const renderPlanSectionContent = () => { const sessionId = props.activeSessionId() if (!sessionId || sessionId === "info") { return (
{props.t("instanceShell.plan.noSessionSelected")}
) } const todoState = props.latestTodoState() if (!todoState) { return (
{props.t("instanceShell.plan.empty")}
) } return } const renderBackgroundProcesses = () => { const processes = props.backgroundProcessList() if (processes.length === 0) { return (
{props.t("instanceShell.backgroundProcesses.empty")}
) } return (
{(process) => (
{process.title}
{props.t("instanceShell.backgroundProcesses.status", { status: process.status })} {props.t("instanceShell.backgroundProcesses.output", { sizeKb: Math.round((process.outputSizeBytes ?? 0) / 1024), })}
)}
) } const statusSections = [ { id: "session-changes", labelKey: "instanceShell.rightPanel.sections.sessionChanges", render: renderStatusSessionChanges, }, { id: "plan", labelKey: "instanceShell.rightPanel.sections.plan", render: renderPlanSectionContent, }, { id: "background-processes", labelKey: "instanceShell.rightPanel.sections.backgroundProcesses", render: renderBackgroundProcesses, }, { id: "mcp", labelKey: "instanceShell.rightPanel.sections.mcp", render: () => ( ), }, { id: "lsp", labelKey: "instanceShell.rightPanel.sections.lsp", render: () => ( ), }, { id: "plugins", labelKey: "instanceShell.rightPanel.sections.plugins", render: () => ( ), }, ] return (
{(activeSession) => ( )} {(section) => ( {props.t(section.labelKey)} {section.render()} )}
) } export default StatusTab