From 4a8a1d564a696db9ddc8ece00b3455b7abc73493 Mon Sep 17 00:00:00 2001 From: Naomi Carrigan Date: Sun, 25 Jan 2026 15:00:52 -0800 Subject: [PATCH] feat: add session import/export functionality - Add JSON export with full session metadata for backup/restore - Add Markdown export with formatted conversation history - Add import capability for previously exported sessions - Add tauri-plugin-fs for file system operations - Add export dropdown menu and import button to session history panel --- package.json | 1 + pnpm-lock.yaml | 10 ++ src-tauri/Cargo.lock | 1 + src-tauri/Cargo.toml | 1 + src-tauri/capabilities/default.json | 5 +- src-tauri/src/lib.rs | 1 + src/lib/components/SessionHistoryPanel.svelte | 112 ++++++++++++++-- src/lib/stores/sessions.ts | 121 ++++++++++++++++++ 8 files changed, 237 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 42fca6d..5025a4b 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "@tauri-apps/api": "^2", "@tauri-apps/plugin-clipboard-manager": "^2.3.2", "@tauri-apps/plugin-dialog": "^2", + "@tauri-apps/plugin-fs": "^2.4.5", "@tauri-apps/plugin-notification": "^2", "@tauri-apps/plugin-opener": "^2", "@tauri-apps/plugin-os": "^2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2bc5ddd..78797db 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,9 @@ importers: '@tauri-apps/plugin-dialog': specifier: ^2 version: 2.6.0 + '@tauri-apps/plugin-fs': + specifier: ^2.4.5 + version: 2.4.5 '@tauri-apps/plugin-notification': specifier: ^2 version: 2.3.3 @@ -744,6 +747,9 @@ packages: '@tauri-apps/plugin-dialog@2.6.0': resolution: {integrity: sha512-q4Uq3eY87TdcYzXACiYSPhmpBA76shgmQswGkSVio4C82Sz2W4iehe9TnKYwbq7weHiL88Yw19XZm7v28+Micg==} + '@tauri-apps/plugin-fs@2.4.5': + resolution: {integrity: sha512-dVxWWGE6VrOxC7/jlhyE+ON/Cc2REJlM35R3PJX3UvFw2XwYhLGQVAIyrehenDdKjotipjYEVc4YjOl3qq90fA==} + '@tauri-apps/plugin-notification@2.3.3': resolution: {integrity: sha512-Zw+ZH18RJb41G4NrfHgIuofJiymusqN+q8fGUIIV7vyCH+5sSn5coqRv/MWB9qETsUs97vmU045q7OyseCV3Qg==} @@ -2300,6 +2306,10 @@ snapshots: dependencies: '@tauri-apps/api': 2.9.1 + '@tauri-apps/plugin-fs@2.4.5': + dependencies: + '@tauri-apps/api': 2.9.1 + '@tauri-apps/plugin-notification@2.3.3': dependencies: '@tauri-apps/api': 2.9.1 diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 8f4fc69..ff78693 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -1613,6 +1613,7 @@ dependencies = [ "tauri-build", "tauri-plugin-clipboard-manager", "tauri-plugin-dialog", + "tauri-plugin-fs", "tauri-plugin-http", "tauri-plugin-notification", "tauri-plugin-opener", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index ede8d32..10243c0 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -27,6 +27,7 @@ tauri-plugin-notification = "2" tauri-plugin-os = "2" tauri-plugin-http = "2" tauri-plugin-clipboard-manager = "2" +tauri-plugin-fs = "2" tempfile = "3" semver = "1" chrono = { version = "0.4.43", features = ["serde"] } diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json index 2bf139b..5caf529 100644 --- a/src-tauri/capabilities/default.json +++ b/src-tauri/capabilities/default.json @@ -16,6 +16,9 @@ "notification:allow-notify", "clipboard-manager:default", "clipboard-manager:allow-read-image", - "core:tray:default" + "core:tray:default", + "fs:default", + "fs:allow-read-text-file", + "fs:allow-write-text-file" ] } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index ef86871..cf97d8b 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -39,6 +39,7 @@ pub fn run() { .plugin(tauri_plugin_os::init()) .plugin(tauri_plugin_http::init()) .plugin(tauri_plugin_clipboard_manager::init()) + .plugin(tauri_plugin_fs::init()) .manage(bridge_manager.clone()) .manage(temp_manager.clone()) .setup(move |app| { diff --git a/src/lib/components/SessionHistoryPanel.svelte b/src/lib/components/SessionHistoryPanel.svelte index 130be84..f22995c 100644 --- a/src/lib/components/SessionHistoryPanel.svelte +++ b/src/lib/components/SessionHistoryPanel.svelte @@ -13,6 +13,8 @@ let searchInput = $state(""); let selectedSession = $state(null); let showDeleteConfirm = $state(null); + let showExportMenu = $state(null); + let isImporting = $state(false); const sessions = $derived(sessionsStore.sessions); const isLoading = $derived(sessionsStore.isLoading); @@ -89,6 +91,34 @@ function handleBackToList(): void { selectedSession = null; } + + async function handleExportJson(sessionId: string): Promise { + showExportMenu = null; + await sessionsStore.exportSessionAsJson(sessionId); + } + + async function handleExportMarkdown(sessionId: string): Promise { + showExportMenu = null; + await sessionsStore.exportSessionAsMarkdown(sessionId); + } + + async function handleImport(): Promise { + isImporting = true; + try { + await sessionsStore.importSession(); + } finally { + isImporting = false; + } + } + + function toggleExportMenu(sessionId: string): void { + if (showExportMenu === sessionId) { + showExportMenu = null; + } else { + showExportMenu = sessionId; + showDeleteConfirm = null; + } + }
- +
+ {#if !selectedSession} + + {/if} + +
{#if selectedSession} @@ -280,6 +330,40 @@ > Resume +
+ + {#if showExportMenu === session.id} +
+ + +
+ {/if} +
{#if showDeleteConfirm === session.id}