diff --git a/src-tauri/src/config.rs b/src-tauri/src/config.rs index 00cd3bd..e8923b6 100644 --- a/src-tauri/src/config.rs +++ b/src-tauri/src/config.rs @@ -21,7 +21,7 @@ pub struct ClaudeStartOptions { pub allowed_tools: Vec, } -#[derive(Debug, Clone, Serialize, Deserialize, Default)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct HikariConfig { #[serde(default)] pub model: Option, @@ -48,6 +48,21 @@ pub struct HikariConfig { pub greeting_custom_prompt: Option, } +impl Default for HikariConfig { + fn default() -> Self { + Self { + model: None, + api_key: None, + custom_instructions: None, + mcp_servers_json: None, + auto_granted_tools: Vec::new(), + theme: Theme::default(), + greeting_enabled: true, + greeting_custom_prompt: None, + } + } +} + fn default_greeting_enabled() -> bool { true } @@ -73,7 +88,7 @@ mod tests { assert!(config.mcp_servers_json.is_none()); assert!(config.auto_granted_tools.is_empty()); assert_eq!(config.theme, Theme::Dark); - assert!(!config.greeting_enabled); + assert!(config.greeting_enabled); assert!(config.greeting_custom_prompt.is_none()); } diff --git a/src/lib/tauri.ts b/src/lib/tauri.ts index 5688590..a747089 100644 --- a/src/lib/tauri.ts +++ b/src/lib/tauri.ts @@ -11,20 +11,25 @@ interface StateChangePayload { tool_name: string | null; } -function generateTimeBasedGreeting(): string { +function getTimeOfDay(): string { const hour = new Date().getHours(); if (hour >= 5 && hour < 12) { - return "Good morning! How can I help you today?"; + return "morning"; } else if (hour >= 12 && hour < 17) { - return "Good afternoon! What are we working on?"; + return "afternoon"; } else if (hour >= 17 && hour < 21) { - return "Good evening! Ready to get some work done?"; + return "evening"; } else { - return "Working late? I'm here to help!"; + return "late night"; } } +function generateGreetingPrompt(): string { + const timeOfDay = getTimeOfDay(); + return `[System: A new session has started. It's currently ${timeOfDay}. Please greet the user warmly and briefly. Keep it short - just 1-2 sentences.]`; +} + async function sendGreeting() { const config = configStore.getConfig(); @@ -32,12 +37,17 @@ async function sendGreeting() { return; } - const greetingPrompt = config.greeting_custom_prompt?.trim() || generateTimeBasedGreeting(); + const greetingPrompt = config.greeting_custom_prompt?.trim() || generateGreetingPrompt(); + + // Don't show the system prompt in the UI - just trigger Claude to respond + characterState.setState("thinking"); try { await invoke("send_prompt", { message: greetingPrompt }); } catch (error) { console.error("Failed to send greeting:", error); + claudeStore.addLine("error", `Failed to send greeting: ${error}`); + characterState.setTemporaryState("error", 3000); } } @@ -48,13 +58,15 @@ interface OutputPayload { } export async function initializeTauriListeners() { - await listen("claude:connection", (event) => { + await listen("claude:connection", async (event) => { const status = event.payload as ConnectionStatus; claudeStore.setConnectionStatus(status); if (status === "connected") { claudeStore.addLine("system", "Connected to Claude Code"); characterState.setState("idle"); + // Send greeting when connection is established + await sendGreeting(); } else if (status === "disconnected") { claudeStore.addLine("system", "Disconnected from Claude Code"); characterState.setState("idle"); @@ -101,11 +113,9 @@ export async function initializeTauriListeners() { // no-op }); - await listen("claude:session", async (event) => { + await listen("claude:session", (event) => { claudeStore.setSessionId(event.payload); claudeStore.addLine("system", `Session: ${event.payload.substring(0, 8)}...`); - - await sendGreeting(); }); await listen("claude:cwd", (event) => {