import { Show, createMemo, createSignal, 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 ContextUsagePanel from "../session/context-usage-panel" import SessionView from "../session/session-view" 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 = 280 const InstanceShell: Component = (props) => { const [sessionSidebarWidth, setSessionSidebarWidth] = createSignal(DEFAULT_SESSION_SIDEBAR_WIDTH) 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) => console.error("Failed to close session:", error)) } }} onNew={() => { const result = props.onNewSession() if (result instanceof Promise) { void result.catch((error) => console.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) => ( )} } >
hideCommandPalette(props.instance.id)} commands={instancePaletteCommands()} onExecute={props.onExecuteCommand} /> ) } export default InstanceShell