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);