diff --git a/packages/app/src/components/chat/ChatHeader.vue b/packages/app/src/components/chat/ChatHeader.vue
index 91324649..a3c211ef 100644
--- a/packages/app/src/components/chat/ChatHeader.vue
+++ b/packages/app/src/components/chat/ChatHeader.vue
@@ -191,6 +191,12 @@
Plain text (.txt)
@@ -210,6 +233,7 @@ import { useChatStore } from '@/stores/chat'
import { useAI } from '@/composables/useAI'
import { useContentPanel } from '@/composables/useContentPanel'
import { downloadConversation, type ExportFormat } from '@/utils/conversation-export'
+import { parseImportFile } from '@/utils/conversation-import'
defineProps<{
title: string
@@ -330,6 +354,44 @@ function handleDelete() {
chatStore.deleteConversation(id)
showMenu.value = false
}
+
+const importInputRef = ref(null)
+const importStatus = ref(null)
+
+function triggerImport() {
+ showMenu.value = false
+ importInputRef.value?.click()
+}
+
+async function handleImportFile(e: Event) {
+ const input = e.target as HTMLInputElement
+ const file = input.files?.[0]
+ if (!file) return
+
+ try {
+ const text = await file.text()
+ const result = parseImportFile(text)
+
+ if (result.error || result.conversations.length === 0) {
+ importStatus.value = `Error: ${result.error ?? 'No conversations found'}`
+ } else {
+ for (const conv of result.conversations) {
+ chatStore.conversations.set(conv.id, conv)
+ }
+ const count = result.conversations.length
+ importStatus.value = `Imported ${count} conversation${count > 1 ? 's' : ''} (${result.format})`
+ // Switch to first imported conversation
+ chatStore.setActiveConversation(result.conversations[0].id)
+ }
+ } catch {
+ importStatus.value = 'Error: Failed to read file'
+ }
+
+ // Clear file input for re-use
+ input.value = ''
+ // Auto-hide status after 3 seconds
+ setTimeout(() => { importStatus.value = null }, 3000)
+}