diff --git a/packages/kbot/dist-in/commands/images.js b/packages/kbot/dist-in/commands/images.js index 52be9a0f..06116fcc 100644 --- a/packages/kbot/dist-in/commands/images.js +++ b/packages/kbot/dist-in/commands/images.js @@ -3,12 +3,12 @@ import * as path from 'node:path'; import { sync as write } from '@polymech/fs/write'; import { sync as exists } from '@polymech/fs/exists'; import { readFileSync, statSync, unlinkSync } from 'node:fs'; +import { Logger } from 'tslog'; import { variables } from '../variables.js'; import { resolve } from '@polymech/commons'; import { isArray, isString } from '@polymech/core/primitives'; import { OptionsSchema } from '../zod_schema.js'; import { createImage, editImage } from '../lib/images-google.js'; -import { getLogger } from '../index.js'; import { prompt as resolvePrompt } from '../prompt.js'; import { spawn } from 'node:child_process'; import { loadConfig } from '../config.js'; @@ -103,10 +103,14 @@ export const ImageOptionsSchema = () => { }); }; async function launchGuiAndGetPrompt(argv) { - const logger = getLogger(argv); + const logger = new Logger({ + minLevel: 0, // Show all logs for debugging + prettyLogTemplate: "{{yyyy}}-{{mm}}-{{dd}} {{hh}}:{{MM}}:{{ss}}.{{ms}}\t{{logLevelName}}\t" + }); return new Promise((_resolve, reject) => { + logger.info('🚀 Starting GUI application with improved logging'); const guiAppPath = getGuiAppPath(); - console.log('guiAppPath', guiAppPath); + logger.info('📁 GUI app path:', guiAppPath); if (!exists(guiAppPath)) { return reject(new Error(`GUI application not found at: ${guiAppPath}. Please build it first by running 'npm run tauri build' in 'gui/tauri-app'.`)); } @@ -149,7 +153,6 @@ async function launchGuiAndGetPrompt(argv) { const apiKey = argv.api_key || config?.google?.key; const includes = argv.include ? (Array.isArray(argv.include) ? argv.include : [argv.include]) : []; const absoluteIncludes = includes.map(p => path.resolve(p)); - // Send config via stdin (Tauri will call forward_config_to_frontend) const configResponse = { cmd: 'forward_config_to_frontend', prompt: argv.prompt || null, @@ -167,13 +170,6 @@ async function launchGuiAndGetPrompt(argv) { const base64 = imageBuffer.toString('base64'); const mimeType = path.extname(imagePath).toLowerCase() === '.png' ? 'image/png' : 'image/jpeg'; const filename = path.basename(imagePath); - // Verify base64 encoding - logger.info(`📸 Image encoding check: ${filename}`, { - bufferSize: imageBuffer.length, - base64Size: base64.length, - base64Sample: base64.substring(0, 50), - isValidBase64: /^[A-Za-z0-9+/]*={0,2}$/.test(base64) - }); const imageResponse = { cmd: 'forward_image_to_frontend', base64, @@ -298,23 +294,93 @@ async function launchGuiAndGetPrompt(argv) { } catch (e) { // Not a JSON message, add to regular output - console.log('GUI stdout chunk:', JSON.stringify(line)); + logger.info('GUI stdout chunk:', JSON.stringify(line)); output += line + '\n'; } } }); tauriProcess.stderr.on('data', (data) => { const chunk = data.toString(); - console.log('GUI stderr chunk:', JSON.stringify(chunk)); + const lines = chunk.split('\n').filter(line => line.trim()); + for (const line of lines) { + try { + const logMessage = JSON.parse(line); + if (logMessage.level && logMessage.message) { + // This is a structured log from Rust + // Suppress noisy debug messages + if (logMessage.message === 'add_debug_message command called.' || + logMessage.message.includes('Debug message added. Total messages:')) { + return; // Skip these noisy logs + } + // Parse and prettify stdin command logs + if (logMessage.message === 'Received stdin command' && logMessage.data?.content) { + try { + const command = JSON.parse(logMessage.data.content); + if (command.cmd) { + logger.info(`🦀 📨 Stdin: ${command.cmd}`, { + prompt: command.prompt ? `"${command.prompt.substring(0, 50)}${command.prompt.length > 50 ? '...' : ''}"` : undefined, + dst: command.dst, + files: command.files?.length ? `${command.files.length} files` : undefined, + hasApiKey: !!command.apiKey + }); + return; + } + } + catch (e) { + // Fall through to regular logging + } + } + switch (logMessage.level.toLowerCase()) { + case 'debug': + logger.debug(`🦀 ${logMessage.message}`, logMessage.data); + break; + case 'info': + logger.info(`🦀 ${logMessage.message}`, logMessage.data); + break; + case 'warn': + logger.warn(`🦀 ${logMessage.message}`, logMessage.data); + break; + case 'error': + logger.error(`🦀 ${logMessage.message}`, logMessage.data); + break; + default: + logger.info(`🦀 ${logMessage.message}`, logMessage.data); + } + } + else { + // Fallback for non-JSON logs - show all non-JSON content + logger.info('🦀', line); + } + } + catch (e) { + // Not JSON, show it unless it's the old verbose [RUST LOG] format + if (line.includes('[RUST LOG]')) { + // Suppress add_debug_message noise + if (line.includes('add_debug_message command called') || + line.includes('Debug message added. Total messages:')) { + return; // Skip these + } + // Skip the old verbose format, but keep important parts + if (line.includes('command called') || line.includes('emitted successfully') || line.includes('Failed to')) { + const cleanedLine = line.replace(/^\[RUST LOG\]:\s*/, '').replace(/^\s*-\s*/, ''); + logger.info('🦀', cleanedLine); + } + } + else if (line.trim()) { + // Show all other stderr content + logger.info('🦀', line); + } + } + } errorOutput += chunk; }); tauriProcess.on('close', (code) => { - console.log('GUI process closed with code:', code); - console.log('Final stdout:', JSON.stringify(output)); - console.log('Final stderr:', JSON.stringify(errorOutput)); + logger.info('GUI process closed with code:', code); + logger.info('Final stdout:', JSON.stringify(output)); + logger.info('Final stderr:', JSON.stringify(errorOutput)); if (code === 0) { const trimmedOutput = output.trim(); - console.log('Attempting to parse JSON:', JSON.stringify(trimmedOutput)); + logger.info('Attempting to parse JSON:', JSON.stringify(trimmedOutput)); _resolve(trimmedOutput || null); } else { @@ -327,7 +393,7 @@ async function launchGuiAndGetPrompt(argv) { }); } export const imageCommand = async (argv) => { - const logger = getLogger(argv); + const logger = new Logger({ minLevel: argv.logLevel || 2 }); if (argv.gui) { try { const guiOutput = await launchGuiAndGetPrompt(argv); @@ -402,4 +468,4 @@ export const imageCommand = async (argv) => { logger.error('Failed to parse options or generate image:', error.message, error.issues, error.stack); } }; -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2VzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL2ltYWdlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBQ3hCLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxJQUFJLElBQUksS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQ0gsWUFBWSxFQUNaLFFBQVEsRUFDUixVQUFVLEVBQ2IsTUFBTSxTQUFTLENBQUM7QUFDakIsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUU1QyxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRTlELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDeEMsT0FBTyxFQUFFLE1BQU0sSUFBSSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDdkQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFMUMsU0FBUyxzQkFBc0IsQ0FBQyxHQUF1QixFQUFFLFFBQWtCO0lBQ3ZFLElBQUksTUFBYyxDQUFDO0lBRW5CLElBQUksR0FBRyxFQUFFLENBQUM7UUFDTixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcs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 \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2VzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbW1hbmRzL2ltYWdlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBQ3hCLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxJQUFJLElBQUksS0FBSyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbkQsT0FBTyxFQUFFLElBQUksSUFBSSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNyRCxPQUFPLEVBQ0gsWUFBWSxFQUNaLFFBQVEsRUFDUixVQUFVLEVBQ2IsTUFBTSxTQUFTLENBQUM7QUFDakIsT0FBTyxFQUFXLE1BQU0sRUFBRSxNQUFNLE9BQU8sQ0FBQztBQUN4QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDNUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRTVDLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFOUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDakUsT0FBTyxFQUFFLE1BQU0sSUFBSSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDdkQsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFMUMsU0FBUyxzQkFBc0IsQ0FBQyxHQUF1QixFQUFFLFFBQWtCO0lBQ3ZFLElBQUksTUFBYyxDQUFDO0lBRW5CLElBQUksR0FBRyxFQUFFLENBQUM7UUFDTixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcs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 \ No newline at end of file diff --git a/packages/kbot/dist/win-64/tauri-app.exe b/packages/kbot/dist/win-64/tauri-app.exe index 9ea88ed5..e7a00768 100644 Binary files a/packages/kbot/dist/win-64/tauri-app.exe and b/packages/kbot/dist/win-64/tauri-app.exe differ diff --git a/packages/kbot/gui/tauri-app/src-tauri/capabilities/base.json b/packages/kbot/gui/tauri-app/src-tauri/capabilities/base.json index 61927391..6192d872 100644 --- a/packages/kbot/gui/tauri-app/src-tauri/capabilities/base.json +++ b/packages/kbot/gui/tauri-app/src-tauri/capabilities/base.json @@ -6,7 +6,11 @@ "permissions": [ { "identifier": "fs:scope", - "allow": [{ "path": "$HOME/**" }, { "path": "$EXE/**" }] + "allow": [ + { "path": "$HOME/**" }, + { "path": "$EXE/**" }, + { "path": "$APPDATA/**" } + ] }, "core:default", "fs:default", diff --git a/packages/kbot/gui/tauri-app/src-tauri/src/lib.rs b/packages/kbot/gui/tauri-app/src-tauri/src/lib.rs index 85e245fd..bbe1fa2e 100644 --- a/packages/kbot/gui/tauri-app/src-tauri/src/lib.rs +++ b/packages/kbot/gui/tauri-app/src-tauri/src/lib.rs @@ -2,6 +2,28 @@ use tauri::{Manager, Emitter}; use serde::{Serialize, Deserialize}; use dirs; +#[derive(Serialize)] +struct LogMessage { + level: String, + message: String, + #[serde(skip_serializing_if = "Option::is_none")] + data: Option, + timestamp: u64, +} + +fn log_json(level: &str, message: &str, data: Option) { + let log_msg = LogMessage { + level: level.to_string(), + message: message.to_string(), + data, + timestamp: std::time::SystemTime::now() + .duration_since(std::time::UNIX_EPOCH) + .unwrap() + .as_millis() as u64, + }; + eprintln!("{}", serde_json::to_string(&log_msg).unwrap_or_else(|_| format!("{{\"level\":\"error\",\"message\":\"Failed to serialize log message\"}}"))); +} + struct Counter(std::sync::Mutex); struct DebugMessages(std::sync::Mutex>); @@ -45,11 +67,11 @@ struct ImagePayload { // Learn more about Tauri commands at https://tauri.app/develop/calling-rust/ #[tauri::command] fn submit_prompt(prompt: &str, files: Vec, dst: &str, window: tauri::Window) { - // Use eprintln! for debug logs so they go to stderr, not stdout - eprintln!("[RUST LOG]: submit_prompt command called."); - eprintln!("[RUST LOG]: - Prompt: {}", prompt); - eprintln!("[RUST LOG]: - Files: {:?}", files); - eprintln!("[RUST LOG]: - Dst: {}", dst); + log_json("info", "submit_prompt command called", Some(serde_json::json!({ + "prompt": prompt, + "files": files, + "dst": dst + }))); let payload = Payload { prompt: prompt.to_string(), @@ -58,7 +80,9 @@ fn submit_prompt(prompt: &str, files: Vec, dst: &str, window: tauri::Win }; let json_payload = serde_json::to_string(&payload).unwrap(); - eprintln!("[RUST LOG]: - Sending JSON payload to stdout: {}", json_payload); + log_json("info", "Sending JSON payload to stdout", Some(serde_json::json!({ + "payload_length": json_payload.len() + }))); println!("{}", json_payload); // The actual payload - ONLY this should go to stdout let _ = window.app_handle().exit(0); } @@ -115,9 +139,8 @@ fn reset_counter(state: tauri::State<'_, Counter>) -> Result { #[tauri::command] fn add_debug_message(message: String, level: String, data: Option, state: tauri::State<'_, DebugMessages>) -> Result<(), String> { - eprintln!("[RUST LOG]: add_debug_message command called."); - eprintln!("[RUST LOG]: - Level: {}", level); - eprintln!("[RUST LOG]: - Message: {}", message); + // Forward frontend debug messages to CLI via structured logging + log_json(&level, &format!("Frontend: {}", message), data.clone()); let debug_payload = DebugPayload { level, @@ -134,7 +157,6 @@ fn add_debug_message(message: String, level: String, data: Option Result<(), String> { - eprintln!("[RUST LOG]: request_file_deletion command called."); - eprintln!("[RUST LOG]: - Path: {}", path); + log_json("info", "request_file_deletion command called", Some(serde_json::json!({ + "path": path + }))); let request = serde_json::json!({ "type": "delete_request", @@ -289,7 +312,7 @@ fn request_file_deletion(path: String) -> Result<(), String> { }); println!("{}", serde_json::to_string(&request).unwrap()); - eprintln!("[RUST LOG]: Deletion request sent to images.ts"); + log_json("info", "Deletion request sent to images.ts", None); Ok(()) } @@ -330,13 +353,19 @@ pub fn run() { let app_handle = app.handle().clone(); + // Test our new JSON logging + log_json("info", "Tauri app starting with improved logging", Some(serde_json::json!({ + "test": true, + "message": "This is a test of the new structured logging system" + }))); + // Listen for stdin commands from images.ts std::thread::spawn(move || { use std::io::{self, BufRead, BufReader}; let stdin = io::stdin(); let reader = BufReader::new(stdin); - eprintln!("[RUST LOG]: Stdin listener thread started"); + log_json("info", "Stdin listener thread started", None); for line in reader.lines() { if let Ok(line_content) = line { @@ -345,25 +374,31 @@ pub fn run() { } // Log stdin command but hide binary data - let log_content = if line_content.contains("\"base64\"") { - format!("[COMMAND WITH BASE64 DATA - {} chars]", line_content.len()) + if line_content.contains("\"base64\"") { + log_json("debug", "Received stdin command with base64 data", Some(serde_json::json!({ + "content_length": line_content.len() + }))); } else { - line_content.clone() - }; - eprintln!("[RUST LOG]: Received stdin command: {}", log_content); + log_json("debug", "Received stdin command", Some(serde_json::json!({ + "content": line_content + }))); + } // Parse command from images.ts if let Ok(command) = serde_json::from_str::(&line_content) { if let Some(cmd) = command.get("cmd").and_then(|v| v.as_str()) { - eprintln!("[RUST LOG]: Processing command: {}", cmd); + log_json("info", "Processing command", Some(serde_json::json!({ + "command": cmd + }))); match cmd { "forward_config_to_frontend" => { - eprintln!("[RUST LOG]: Forwarding config to frontend"); - eprintln!("[RUST LOG]: - prompt: {:?}", command.get("prompt")); - eprintln!("[RUST LOG]: - dst: {:?}", command.get("dst")); - eprintln!("[RUST LOG]: - apiKey: {:?}", command.get("apiKey").map(|_| "[REDACTED]")); - eprintln!("[RUST LOG]: - files: {:?}", command.get("files")); + log_json("info", "Forwarding config to frontend", Some(serde_json::json!({ + "has_prompt": command.get("prompt").is_some(), + "has_dst": command.get("dst").is_some(), + "has_api_key": command.get("apiKey").is_some(), + "file_count": command.get("files").and_then(|f| f.as_array()).map(|a| a.len()).unwrap_or(0) + }))); let config_data = serde_json::json!({ "prompt": command.get("prompt"), @@ -373,9 +408,11 @@ pub fn run() { }); if let Err(e) = app_handle.emit("config-received", &config_data) { - eprintln!("[RUST LOG]: Failed to emit config-received: {}", e); + log_json("error", "Failed to emit config-received", Some(serde_json::json!({ + "error": e.to_string() + }))); } else { - eprintln!("[RUST LOG]: Config emitted successfully to frontend"); + log_json("info", "Config emitted successfully to frontend", None); } } "forward_image_to_frontend" => { @@ -384,7 +421,11 @@ pub fn run() { command.get("base64").and_then(|v| v.as_str()), command.get("mimeType").and_then(|v| v.as_str()) ) { - eprintln!("[RUST LOG]: Forwarding image to frontend: {}", filename); + log_json("info", "Forwarding image to frontend", Some(serde_json::json!({ + "filename": filename, + "mime_type": mime_type, + "base64_size": base64.len() + }))); let image_data = serde_json::json!({ "base64": base64, "mimeType": mime_type, @@ -392,9 +433,14 @@ pub fn run() { }); if let Err(e) = app_handle.emit("image-received", &image_data) { - eprintln!("[RUST LOG]: Failed to emit image-received: {}", e); + log_json("error", "Failed to emit image-received", Some(serde_json::json!({ + "error": e.to_string(), + "filename": filename + }))); } else { - eprintln!("[RUST LOG]: Image emitted successfully: {}", filename); + log_json("info", "Image emitted successfully", Some(serde_json::json!({ + "filename": filename + }))); } } } diff --git a/packages/kbot/gui/tauri-app/src/App.tsx b/packages/kbot/gui/tauri-app/src/App.tsx index 5cc45651..1e8a08d7 100644 --- a/packages/kbot/gui/tauri-app/src/App.tsx +++ b/packages/kbot/gui/tauri-app/src/App.tsx @@ -1,5 +1,5 @@ import { useState, useEffect } from "react"; -import { ImageFile } from "./types"; +import { ImageFile, PromptTemplate } from "./types"; import { useTauriListeners } from "./hooks/useTauriListeners"; import { tauriApi } from "./lib/tauriApi"; import Header from "./components/Header"; @@ -29,6 +29,95 @@ function App() { const [messageToSend, setMessageToSend] = useState(""); const [generationTimeoutId, setGenerationTimeoutId] = useState(null); const [currentIndex, setCurrentIndex] = useState(0); + const [prompts, setPrompts] = useState([]); + + const STORE_FILE_NAME = '.kbot-gui.json'; + + useEffect(() => { + const loadPrompts = async () => { + addDebugMessage('debug', '🔄 Store loading useEffect triggered'); + try { + if (tauriApi.isTauri()) { + addDebugMessage('info', '📂 Attempting to load prompts from store...'); + const configDir = await tauriApi.path.appDataDir(); + addDebugMessage('debug', `📁 Data directory: ${configDir}`); + const storePath = await tauriApi.path.join(configDir, STORE_FILE_NAME); + addDebugMessage('debug', `📄 Store path resolved to: ${storePath}`); + + const content = await tauriApi.fs.readTextFile(storePath); + addDebugMessage('debug', `📖 File content length: ${content?.length || 0}`); + + if (content) { + const data = JSON.parse(content); + addDebugMessage('debug', `📋 Parsed store data:`, data); + if (data.prompts) { + setPrompts(data.prompts); + addDebugMessage('info', `✅ Loaded ${data.prompts.length} prompts from store`); + } else { + addDebugMessage('warn', '⚠️ Store file exists but has no prompts array'); + } + } else { + addDebugMessage('info', '📭 Store file is empty'); + } + } else { + addDebugMessage('warn', '🌐 Not in Tauri environment, skipping store load'); + } + } catch (e) { + const error = e as Error; + addDebugMessage('info', `📂 Prompt store not found or failed to load. A new one will be created on save.`, { + error: error.message, + errorName: error.name, + storePath: STORE_FILE_NAME + }); + } + }; + loadPrompts(); + }, []); + + const importPrompts = async () => { + try { + const selected = await tauriApi.dialog.open({ + multiple: false, + filters: [{ name: 'JSON', extensions: ['json'] }] + }); + if (typeof selected === 'string') { + const contents = await tauriApi.fs.readTextFile(selected); + const newPrompts = JSON.parse(contents); + if (newPrompts.prompts && Array.isArray(newPrompts.prompts)) { + setPrompts(newPrompts.prompts); + savePrompts(newPrompts.prompts); + addDebugMessage('info', `✅ Prompts imported successfully from: ${selected}`); + } else { + addDebugMessage('error', 'Invalid prompts file format.'); + } + } + } catch (error) { + addDebugMessage('error', 'Failed to import prompts', { error: (error as Error).message }); + } + }; + + const exportPrompts = async () => { + addDebugMessage('info', 'Attempting to export prompts...'); + try { + const path = await tauriApi.dialog.save({ + defaultPath: 'kbot-prompts.json', + filters: [{ name: 'JSON', extensions: ['json'] }] + }); + + if (path) { + addDebugMessage('debug', `📂 Export path selected: ${path}`); + const dataToWrite = JSON.stringify({ prompts }, null, 2); + addDebugMessage('debug', '📋 Data to be exported:', { promptCount: prompts.length, dataLength: dataToWrite.length }); + addDebugMessage('debug', '💾 About to call writeTextFile...'); + await tauriApi.fs.writeTextFile(path, dataToWrite); + addDebugMessage('info', `✅ Prompts exported successfully to: ${path}`); + } else { + addDebugMessage('info', 'Export dialog was cancelled.'); + } + } catch (error) { + addDebugMessage('error', 'Failed to export prompts', { error: (error as Error).message }); + } + }; const deleteFilePermanently = async (pathToDelete: string) => { addDebugMessage('info', `Requesting deletion of file: ${pathToDelete}`); @@ -123,7 +212,7 @@ function App() { generationTimeoutId, setGenerationTimeoutId, setIsGenerating, - prompt + prompt, }); const addFiles = async (newPaths: string[]) => { @@ -400,6 +489,31 @@ function App() { setMessageToSend(''); }; + const savePrompts = async (promptsToSave: PromptTemplate[]) => { + if (tauriApi.isTauri()) { + try { + addDebugMessage('debug', '💾 Starting save prompts process...'); + const dataDir = await tauriApi.path.appDataDir(); + addDebugMessage('debug', `📁 Got data dir: ${dataDir}`); + const storePath = await tauriApi.path.join(dataDir, STORE_FILE_NAME); + addDebugMessage('debug', `📄 Store path: ${storePath}`); + const dataToSave = JSON.stringify({ prompts: promptsToSave }, null, 2); + addDebugMessage('debug', `💾 Data to save:`, { promptCount: promptsToSave.length, dataLength: dataToSave.length }); + + await tauriApi.fs.writeTextFile(storePath, dataToSave); + addDebugMessage('info', `✅ Prompts saved to ${storePath}`); + } catch (error) { + addDebugMessage('error', 'Failed to save prompts', { + error: (error as Error).message, + errorName: (error as Error).name, + errorStack: (error as Error).stack + }); + } + } else { + addDebugMessage('warn', '🌐 Not in Tauri, cannot save prompts'); + } + }; + async function openFilePicker() { if (!tauriApi.isTauri()) { // Browser fallback: create file input @@ -517,6 +631,11 @@ function App() { addFiles={addFiles} currentIndex={currentIndex} setCurrentIndex={setCurrentIndex} + prompts={prompts} + setPrompts={setPrompts} + savePrompts={savePrompts} + importPrompts={importPrompts} + exportPrompts={exportPrompts} /> {/* Debug Panel */} diff --git a/packages/kbot/gui/tauri-app/src/components/DebugPanel.tsx b/packages/kbot/gui/tauri-app/src/components/DebugPanel.tsx index 1510a683..cc0901c7 100644 --- a/packages/kbot/gui/tauri-app/src/components/DebugPanel.tsx +++ b/packages/kbot/gui/tauri-app/src/components/DebugPanel.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import { tauriApi } from '../lib/tauriApi'; interface DebugPanelProps { debugMessages: any[]; @@ -28,7 +29,30 @@ const DebugPanel: React.FC = ({

Debug Panel

+ { + const newPrompts = [...prompts, { name, text }]; + setPrompts(newPrompts); + savePrompts(newPrompts); + }} + onImportPrompts={importPrompts} + onExportPrompts={exportPrompts} + /> +