Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions crates/daemon/assets/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2759,7 +2759,7 @@
} else {
rememberActiveTerminalState();
enterChatMode();
await loadTranscript(id);
await loadTranscript(id, { force: true });
}
setComposerEnabled(!!(state.ws && state.ws.readyState === 1 && state.currentId));
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down
Loading