import { APP_SESSION_ID, APP_SESSION_SCHEMA_VERSION, reconcileAppSessionSnapshot, type AppSessionSnapshot, } from "../core/state/session-persistence"; import type { SessionStore } from "../data/session-store"; import { materializeDetachedPanesAsFloating, type AppConfig, } from "../types/config"; import type { DesktopSharedStateSnapshot, DesktopWindowBridge, } from "../types/desktop-window"; import type { CliLaunchConfigResult, CliLaunchRequest, } from "../types/plugin"; type SessionSnapshotReader = Pick; interface ResolveInitialAppConfigOptions { initialConfig: AppConfig; desktopSnapshot?: DesktopSharedStateSnapshot | null; hasDesktopWindowBridge: boolean; } interface ResolveCliLaunchConfigOptions { cliLaunchRequest?: CliLaunchRequest | null; config: AppConfig; terminalWidth: number; terminalHeight: number; } interface ResolveAppSessionSnapshotOptions { cliLaunchRequest?: CliLaunchRequest | null; cliLaunchState: TLaunchState | undefined; config: AppConfig; desktopSnapshot?: DesktopSharedStateSnapshot | null; desktopWindowKind?: DesktopWindowBridge["kind"]; sessionStore: SessionSnapshotReader; } export function resolveInitialAppConfig({ initialConfig, desktopSnapshot = null, hasDesktopWindowBridge, }: ResolveInitialAppConfigOptions): AppConfig { const baseConfig = desktopSnapshot?.config ?? initialConfig; if (hasDesktopWindowBridge) return baseConfig; return { ...baseConfig, layout: materializeDetachedPanesAsFloating(baseConfig.layout), layouts: baseConfig.layouts.map((entry) => ({ ...entry, layout: materializeDetachedPanesAsFloating(entry.layout), })), }; } export function resolveCliLaunchConfig({ cliLaunchRequest, config, terminalWidth, terminalHeight, }: ResolveCliLaunchConfigOptions): CliLaunchConfigResult { if (!cliLaunchRequest) return { config, launchState: undefined }; return cliLaunchRequest.applyConfig(config, { terminalWidth, terminalHeight, }); } function readPersistedAppSessionSnapshot( sessionStore: SessionSnapshotReader, ): AppSessionSnapshot | null { return sessionStore.get(APP_SESSION_ID, APP_SESSION_SCHEMA_VERSION)?.value ?? null; } function createDetachedSessionSnapshotFallback(): AppSessionSnapshot { return { paneState: {}, focusedPaneId: null, activePanel: "left", statusBarVisible: true, openPaneIds: [], hydrationTargets: [], exchangeCurrencies: [], savedAt: Date.now(), }; } function resolveDetachedAppSessionSnapshot( config: AppConfig, sessionStore: SessionSnapshotReader, desktopSnapshot?: DesktopSharedStateSnapshot | null, ): AppSessionSnapshot | null { const baseSessionSnapshot = reconcileAppSessionSnapshot( config, readPersistedAppSessionSnapshot(sessionStore), ) ?? createDetachedSessionSnapshotFallback(); return desktopSnapshot ? { ...baseSessionSnapshot, paneState: desktopSnapshot.paneState, focusedPaneId: desktopSnapshot.focusedPaneId, activePanel: desktopSnapshot.activePanel, statusBarVisible: desktopSnapshot.statusBarVisible, } : null; } export function resolveAppSessionSnapshot({ cliLaunchRequest, cliLaunchState, config, desktopSnapshot = null, desktopWindowKind, sessionStore, }: ResolveAppSessionSnapshotOptions): AppSessionSnapshot | null { if (desktopWindowKind === "detached") { return resolveDetachedAppSessionSnapshot(config, sessionStore, desktopSnapshot); } const persisted = readPersistedAppSessionSnapshot(sessionStore); const reconciled = reconcileAppSessionSnapshot(config, persisted); if (!cliLaunchRequest?.applySessionSnapshot) return reconciled; return cliLaunchRequest.applySessionSnapshot(config, reconciled, cliLaunchState); }