diff --git a/src/lib/stores/claude.ts b/src/lib/stores/claude.ts index d8c802e..a5a9dc7 100644 --- a/src/lib/stores/claude.ts +++ b/src/lib/stores/claude.ts @@ -33,6 +33,7 @@ export const claudeStore = { // Methods setConnectionStatus: conversationsStore.setConnectionStatus, setConnectionStatusForConversation: conversationsStore.setConnectionStatusForConversation, + setCharacterStateForConversation: conversationsStore.setCharacterStateForConversation, setSessionId: conversationsStore.setSessionId, setSessionIdForConversation: conversationsStore.setSessionIdForConversation, setWorkingDirectory: conversationsStore.setWorkingDirectory, diff --git a/src/lib/stores/conversations.ts b/src/lib/stores/conversations.ts index feb8706..72fe89e 100644 --- a/src/lib/stores/conversations.ts +++ b/src/lib/stores/conversations.ts @@ -1,6 +1,8 @@ import { writable, derived, get } from "svelte/store"; import type { TerminalLine, ConnectionStatus, PermissionRequest } from "$lib/types/messages"; +import type { CharacterState } from "$lib/types/states"; import { cleanupConversationTracking } from "$lib/tauri"; +import { characterState } from "$lib/stores/character"; export interface Conversation { id: string; @@ -9,6 +11,7 @@ export interface Conversation { sessionId: string | null; connectionStatus: ConnectionStatus; workingDirectory: string; + characterState: CharacterState; isProcessing: boolean; grantedTools: Set; createdAt: Date; @@ -41,6 +44,7 @@ function createConversationsStore() { sessionId: null, connectionStatus: "disconnected", workingDirectory: "", + characterState: "idle", isProcessing: false, grantedTools: new Set(), createdAt: new Date(), @@ -122,6 +126,19 @@ function createConversationsStore() { return convs; }); }, + setCharacterStateForConversation: (conversationId: string, state: CharacterState) => { + conversations.update((convs) => { + const conv = convs.get(conversationId); + if (conv) { + conv.characterState = state; + // If this is the active conversation, update the global character state + if (conversationId === get(activeConversationId)) { + characterState.setState(state); + } + } + return convs; + }); + }, requestPermission: (request: PermissionRequest) => pendingPermission.set(request), clearPermission: () => pendingPermission.set(null), setPendingRetryMessage: (message: string | null) => pendingRetryMessage.set(message), @@ -177,6 +194,11 @@ function createConversationsStore() { if (currentId !== id) { activeConversationId.set(id); + // Update the global character state to match the conversation's state + if (targetConv) { + characterState.setState(targetConv.characterState); + } + // Auto-reconnect logic if (targetConv && targetConv.connectionStatus === "disconnected") { // Check if another conversation is connected diff --git a/src/lib/tauri.ts b/src/lib/tauri.ts index 35e00b7..97f55b3 100644 --- a/src/lib/tauri.ts +++ b/src/lib/tauri.ts @@ -142,7 +142,8 @@ export async function initializeTauriListeners() { // Add system message to the correct conversation claudeStore.addLineToConversation(targetConversationId, "system", "Connected to Claude Code"); - characterState.setState("idle"); + // Update character state for this conversation + claudeStore.setCharacterStateForConversation(targetConversationId, "idle"); // Check if this specific conversation has connected before if (!connectedConversations.has(targetConversationId)) { @@ -164,7 +165,10 @@ export async function initializeTauriListeners() { claudeStore.addLineToConversation(targetConversationId, "system", "Disconnected from Claude Code"); } - characterState.setState("idle"); + // Update character state for this conversation + if (targetConversationId) { + claudeStore.setCharacterStateForConversation(targetConversationId, "idle"); + } } else if (status === "error") { const targetConversationId = conversation_id || get(claudeStore.activeConversationId); @@ -181,12 +185,6 @@ export async function initializeTauriListeners() { const stateUnlisten = await listen("claude:state", (event) => { const { state, conversation_id } = event.payload; - // Only process events for the active conversation - const activeConversationId = get(claudeStore.activeConversationId); - if (conversation_id && activeConversationId && conversation_id !== activeConversationId) { - return; - } - const stateMap: Record = { idle: "idle", thinking: "thinking", @@ -201,10 +199,25 @@ export async function initializeTauriListeners() { const mappedState = stateMap[state.toLowerCase()] || "idle"; - if (mappedState === "success" || mappedState === "error") { - characterState.setTemporaryState(mappedState, 3000); + // Always update the conversation's state + if (conversation_id) { + claudeStore.setCharacterStateForConversation(conversation_id, mappedState); } else { - characterState.setState(mappedState); + // Fallback to active conversation if no conversation_id + const activeConversationId = get(claudeStore.activeConversationId); + if (activeConversationId) { + claudeStore.setCharacterStateForConversation(activeConversationId, mappedState); + } + } + + // Only update global character state for active conversation + const activeConversationId = get(claudeStore.activeConversationId); + if (!conversation_id || conversation_id === activeConversationId) { + if (mappedState === "success" || mappedState === "error") { + characterState.setTemporaryState(mappedState, 3000); + } else { + characterState.setState(mappedState); + } } }); unlisteners.push(stateUnlisten);