()
| 111 | |
| 112 | // Load chats from localStorage with migration support |
| 113 | function loadChatsFromStorage() { |
| 114 | try { |
| 115 | const stored = localStorage.getItem(CHATS_STORAGE_KEY); |
| 116 | if (stored) { |
| 117 | const data = JSON.parse(stored); |
| 118 | |
| 119 | // Validate structure |
| 120 | if (data && Array.isArray(data.chats)) { |
| 121 | return { |
| 122 | chats: data.chats, |
| 123 | activeChatId: data.activeChatId || null, |
| 124 | lastSaved: data.lastSaved || null |
| 125 | }; |
| 126 | } |
| 127 | } |
| 128 | |
| 129 | // Migration: Check for old format |
| 130 | const oldSystemPrompt = localStorage.getItem(SYSTEM_PROMPT_STORAGE_KEY); |
| 131 | if (oldSystemPrompt) { |
| 132 | // Migrate old single-chat format to new multi-chat format |
| 133 | const chatStore = Alpine.store("chat"); |
| 134 | if (chatStore) { |
| 135 | const migratedChat = chatStore.createChat( |
| 136 | document.getElementById("chat-model")?.value || "", |
| 137 | oldSystemPrompt, |
| 138 | false |
| 139 | ); |
| 140 | // Try to preserve any existing history if available |
| 141 | if (chatStore.activeChat()) { |
| 142 | chatStore.activeChat().name = "Migrated Chat"; |
| 143 | } |
| 144 | // Save migrated data |
| 145 | saveChatsToStorage(); |
| 146 | // Remove old key |
| 147 | localStorage.removeItem(SYSTEM_PROMPT_STORAGE_KEY); |
| 148 | return { |
| 149 | chats: chatStore.chats, |
| 150 | activeChatId: chatStore.activeChatId, |
| 151 | lastSaved: Date.now() |
| 152 | }; |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | return null; |
| 157 | } catch (error) { |
| 158 | console.error('Error loading chats from localStorage:', error); |
| 159 | // Try to recover by clearing corrupted data |
| 160 | try { |
| 161 | localStorage.removeItem(CHATS_STORAGE_KEY); |
| 162 | } catch (e) { |
| 163 | console.error('Failed to clear corrupted data:', e); |
| 164 | } |
| 165 | return null; |
| 166 | } |
| 167 | } |
| 168 | |
| 169 | // Auto-save with debouncing |
| 170 | function autoSaveChats() { |
no test coverage detected