diff --git a/ui-electrobun/src/mainview/agent-store.svelte.ts b/ui-electrobun/src/mainview/agent-store.svelte.ts index 6d6cdea..9697913 100644 --- a/ui-electrobun/src/mainview/agent-store.svelte.ts +++ b/ui-electrobun/src/mainview/agent-store.svelte.ts @@ -115,6 +115,11 @@ const projectSessionMap = new Map(); // Map sessionId -> reactive session state let sessions = $state>({}); +// Version counter — bump on every mutation to force Svelte re-renders +// (cross-module $state reads don't auto-track in Svelte 5) +let _v = $state(0); +function bump() { _v++; } + // Grace period timers for cleanup after done/error const cleanupTimers = new Map>(); @@ -235,6 +240,7 @@ function ensureListeners() { msg.seqId = nextSeqId(payload.sessionId); } session.messages = [...session.messages, ...converted]; + bump(); // Force re-render persistMessages(session); // Reset stall timer on activity resetStallTimer(payload.sessionId, session.projectId); @@ -262,6 +268,7 @@ function ensureListeners() { session.status = normalizeStatus(payload.status); if (payload.error) session.error = payload.error; + bump(); // Force re-render // Fix #14: Wire health store — update project status setProjectStatus(session.projectId, session.status === 'done' ? 'done' : session.status === 'error' ? 'error' : session.status === 'running' ? 'running' : 'idle'); @@ -306,6 +313,7 @@ function ensureListeners() { session.costUsd = payload.costUsd; session.inputTokens = payload.inputTokens; session.outputTokens = payload.outputTokens; + bump(); // Force re-render // Fix #14: Wire health store — record token/cost snapshot recordTokenSnapshot(session.projectId, payload.inputTokens + payload.outputTokens, payload.costUsd); }); @@ -545,6 +553,7 @@ async function _startAgentInner( }; projectSessionMap.set(projectId, sessionId); + bump(); // Force re-render — new session created resetStallTimer(sessionId, projectId); const result = await appRpc.request['agent.start']({ @@ -609,8 +618,9 @@ export async function sendPrompt(projectId: string, prompt: string): Promise<{ o return appRpc.request['agent.prompt']({ sessionId, prompt }); } -/** Get the current session for a project (reactive). */ +/** Get the current session for a project (reactive via version counter). */ export function getSession(projectId: string): AgentSession | undefined { + void _v; // Read version counter to subscribe Svelte's reactivity const sessionId = projectSessionMap.get(projectId); if (!sessionId) return undefined; return sessions[sessionId];