/** * Project tabs store — per-project tab state. * * Tracks which tab is active and which tabs have been activated (PERSISTED-LAZY * pattern) for each project card. This allows cross-component access — e.g., * StatusBar can show which tab is active, palette commands can switch tabs. */ // ── Types ──────────────────────────────────────────────────────────────── export type ProjectTab = | 'model' | 'docs' | 'context' | 'files' | 'ssh' | 'memory' | 'comms' | 'tasks'; export const ALL_TABS: ProjectTab[] = [ 'model', 'docs', 'context', 'files', 'ssh', 'memory', 'comms', 'tasks', ]; interface TabState { activeTab: ProjectTab; activatedTabs: Set; } // ── State ──────────────────────────────────────────────────────────────── let _tabs = $state>(new Map()); // ── Internal helper ────────────────────────────────────────────────────── function ensureEntry(projectId: string): TabState { let entry = _tabs.get(projectId); if (!entry) { entry = { activeTab: 'model', activatedTabs: new Set(['model']) }; _tabs.set(projectId, entry); // Trigger reactivity by reassigning the map _tabs = new Map(_tabs); } return entry; } // ── Getters ────────────────────────────────────────────────────────────── export function getActiveTab(projectId: string): ProjectTab { return _tabs.get(projectId)?.activeTab ?? 'model'; } export function isTabActivated(projectId: string, tab: ProjectTab): boolean { return _tabs.get(projectId)?.activatedTabs.has(tab) ?? (tab === 'model'); } // ── Actions ────────────────────────────────────────────────────────────── export function setActiveTab(projectId: string, tab: ProjectTab): void { const entry = ensureEntry(projectId); entry.activeTab = tab; entry.activatedTabs = new Set([...entry.activatedTabs, tab]); // Trigger reactivity _tabs = new Map(_tabs); } /** Remove tab state when a project is deleted. */ export function removeProject(projectId: string): void { if (_tabs.has(projectId)) { _tabs.delete(projectId); _tabs = new Map(_tabs); } }