import { Show, createMemo, createSignal, onCleanup, onMount, type Component } from "solid-js" import type { Accessor } from "solid-js" import type { Instance } from "../../types/instance" import type { Command } from "../../lib/commands" import { activeParentSessionId, activeSessionId as activeSessionMap, getSessionFamily, setActiveSession } from "../../stores/sessions" import { keyboardRegistry, type KeyboardShortcut } from "../../lib/keyboard-registry" import { buildCustomCommandEntries } from "../../lib/command-utils" import { getCommands as getInstanceCommands } from "../../stores/commands" import { isOpen as isCommandPaletteOpen, hideCommandPalette } from "../../stores/command-palette" import SessionList from "../session-list" import KeyboardHint from "../keyboard-hint" import InstanceWelcomeView from "../instance-welcome-view" import InfoView from "../info-view" import AgentSelector from "../agent-selector" import ModelSelector from "../model-selector" import CommandPalette from "../command-palette" import Kbd from "../kbd" import ContextUsagePanel from "../session/context-usage-panel" import SessionView from "../session/session-view" import { getLogger } from "../../lib/logger" const log = getLogger("session") interface InstanceShellProps { instance: Instance escapeInDebounce: boolean paletteCommands: Accessor onCloseSession: (sessionId: string) => Promise | void onNewSession: () => Promise | void handleSidebarAgentChange: (sessionId: string, agent: string) => Promise handleSidebarModelChange: (sessionId: string, model: { providerId: string; modelId: string }) => Promise onExecuteCommand: (command: Command) => void } const DEFAULT_SESSION_SIDEBAR_WIDTH = 350 const MOBILE_SIDEBAR_BREAKPOINT = 1024 const InstanceShell: Component = (props) => { const [sessionSidebarWidth, setSessionSidebarWidth] = createSignal(DEFAULT_SESSION_SIDEBAR_WIDTH) const [isCompactLayout, setIsCompactLayout] = createSignal(false) const [isSidebarOpen, setIsSidebarOpen] = createSignal(true) const sidebarId = `session-sidebar-${props.instance.id}` let previousIsCompact = false const shouldShowSidebarToggle = () => isCompactLayout() && !isSidebarOpen() onMount(() => { if (typeof window === "undefined") return const handleResize = () => { const compact = window.innerWidth < MOBILE_SIDEBAR_BREAKPOINT setIsCompactLayout(compact) if (!compact) { setIsSidebarOpen(true) } else if (!previousIsCompact && compact) { setIsSidebarOpen(false) } previousIsCompact = compact } handleResize() window.addEventListener("resize", handleResize) onCleanup(() => { window.removeEventListener("resize", handleResize) }) }) const activeSessions = createMemo(() => { const parentId = activeParentSessionId().get(props.instance.id) if (!parentId) return new Map[number]>() const sessionFamily = getSessionFamily(props.instance.id, parentId) return new Map(sessionFamily.map((s) => [s.id, s])) }) const activeSessionIdForInstance = createMemo(() => { return activeSessionMap().get(props.instance.id) || null }) const activeSessionForInstance = createMemo(() => { const sessionId = activeSessionIdForInstance() if (!sessionId || sessionId === "info") return null return activeSessions().get(sessionId) ?? null }) const customCommands = createMemo(() => buildCustomCommandEntries(props.instance.id, getInstanceCommands(props.instance.id))) const instancePaletteCommands = createMemo(() => [...props.paletteCommands(), ...customCommands()]) const paletteOpen = createMemo(() => isCommandPaletteOpen(props.instance.id)) const keyboardShortcuts = createMemo(() => [keyboardRegistry.get("session-prev"), keyboardRegistry.get("session-next")].filter( (shortcut): shortcut is KeyboardShortcut => Boolean(shortcut), ), ) const handleSessionSelect = (sessionId: string) => { setActiveSession(props.instance.id, sessionId) } return ( <> 0} fallback={}>
{ const result = props.onCloseSession(id) if (result instanceof Promise) { void result.catch((error) => log.error("Failed to close session:", error)) } }} onNew={() => { const result = props.onNewSession() if (result instanceof Promise) { void result.catch((error) => log.error("Failed to create session:", error)) } }} showHeader showFooter={false} headerContent={
Sessions
{keyboardShortcuts().length ? ( ) : null}
} onWidthChange={setSessionSidebarWidth} />
{(activeSession) => ( <>
props.handleSidebarAgentChange(activeSession().id, agent)} /> props.handleSidebarModelChange(activeSession().id, model)} />
)}

No session selected

Select a session to view messages

} > {(sessionId) => ( setIsSidebarOpen(true)} forceCompactStatusLayout={shouldShowSidebarToggle()} /> )} } >
hideCommandPalette(props.instance.id)} commands={instancePaletteCommands()} onExecute={props.onExecuteCommand} /> ) } export default InstanceShell