diff --git a/crates/daemon/assets/index.html b/crates/daemon/assets/index.html index 4174e4de..dba5ca9f 100644 --- a/crates/daemon/assets/index.html +++ b/crates/daemon/assets/index.html @@ -2759,7 +2759,7 @@ } else { rememberActiveTerminalState(); enterChatMode(); - await loadTranscript(id); + await loadTranscript(id, { force: true }); } setComposerEnabled(!!(state.ws && state.ws.readyState === 1 && state.currentId)); } @@ -3955,6 +3955,11 @@ } } +function markTranscriptStale(id) { + const pane = state.transcriptPaneById.get(id); + if (pane) delete pane.dataset.loaded; +} + function transcriptTarget(sessionId = state.currentId) { if (activeTranscriptEl) return activeTranscriptEl; if (sessionId) return transcriptPaneForSession(sessionId); @@ -4003,8 +4008,9 @@ el.textContent = `Loading older history… ${loaded.toLocaleString()} / ${total.toLocaleString()} (${pct}%)`; } -async function loadTranscript(id) { +async function loadTranscript(id, opts = {}) { const pane = showTranscriptPane(id); + if (opts.force) delete pane.dataset.loaded; if (pane.dataset.loaded === "true") return; // already built — instant re-select // Delayed skeleton: only show it if the fetch is slow enough to notice // (avoids a skeleton flash on fast local loads). The pane is otherwise @@ -4149,6 +4155,9 @@ if (event.active) state.agentStatusById.set(session_id, event); else state.agentStatusById.delete(session_id); } + if (eventInvalidatesCachedTranscript(event) && !(session_id === state.currentId && state.mode === "chat")) { + markTranscriptStale(session_id); + } if (session_id !== state.currentId) return; if (state.mode === "chat") showTranscriptPane(session_id); renderEvent(event, params.at); @@ -4325,6 +4334,21 @@ } } +function eventInvalidatesCachedTranscript(event) { + if (!event || !event.type) return false; + switch (event.type) { + case "message": + case "tool_use": + case "tool_result": + case "tool_approval_request": + case "error": + case "reset": + return true; + default: + return false; + } +} + function renderEditorStateForSession(id) { renderEditorState(state.editorById.get(id) || null, state.agentStatusById.get(id) || null); } @@ -5271,10 +5295,13 @@ resetInputHeightPreservingTerminalScroll(); const pty = currentSessionHasPty(); if (pty) { - const payload = enter ? text + "\r" : text; - const data = encodeBase64Utf8(payload); try { - await rpc("session.pty_input", { session_id: sid, data }); + if (text) { + await rpc("session.pty_input", { session_id: sid, data: encodeBase64Utf8(text) }); + } + if (enter) { + await rpc("session.pty_input", { session_id: sid, data: encodeBase64Utf8("\r") }); + } } catch (e) { appendError(`pty_input failed: ${e.message}`); restoreComposerText(text, sid);