fix: send only stdout delta in Bash terminal output to prevent replay#15
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors the terminal output streaming and deduplication logic in dispatchTerminalUpdate to prevent duplicate lines in the Zed terminal. It splits terminal updates into separate terminal_output and terminal_exit notifications, and avoids sending rawOutput inside terminal_exit. Additionally, it skips terminal_output on result events if progress has already streamed data, unless no progress events were fired. The review feedback points out a correctness bug where skipping terminal_output entirely on result events when progress has already streamed can cause final output truncation. Any output appended after the last progress event but before completion would be lost. The reviewer suggests removing the !(isResult && alreadyStreamed) guard and relying on the existing delta-deduplication logic to handle sending only the new suffix.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| const isResult = ev.status === "completed" || ev.status === "failed"; | ||
| const alreadyStreamed = server.terminalSentData.has(ev.callId); | ||
| if (full && !(isResult && alreadyStreamed)) { | ||
| const delta = lastSent && full.startsWith(lastSent) ? full.slice(lastSent.length) : full; | ||
| if (delta) { | ||
| server.terminalSentData.set(ev.callId, full); | ||
| await sendSessionUpdate(cx, acpSid, { | ||
| sessionUpdate: "tool_call_update", | ||
| toolCallId: ev.callId, | ||
| _meta: { terminal_output: { terminal_id: ev.callId, data: delta } }, | ||
| }); | ||
| } | ||
| } |
There was a problem hiding this comment.
Correctness Bug: Final Output Truncation / Loss
By skipping the terminal_output notification entirely when isResult && alreadyStreamed is true, any new output appended to the stdout tail after the last progress event but before the command completed/failed will be completely lost.
Since terminal_exit no longer carries rawOutput (which is correct to prevent duplication in Zed), there is no other way for this final output delta to reach the client.
Solution
We do not need to skip terminal_output entirely. The existing delta/deduplication logic (const delta = lastSent && full.startsWith(lastSent) ? full.slice(lastSent.length) : full;) already perfectly handles deduplication:
- If there is no new output,
deltawill be empty ("") and nothing will be sent. - If there is new output, only the new suffix will be sent.
We should remove the !(isResult && alreadyStreamed) guard and simply process the delta normally.
const isResult = ev.status === "completed" || ev.status === "failed";
if (full) {
const delta = lastSent && full.startsWith(lastSent) ? full.slice(lastSent.length) : full;
if (delta) {
server.terminalSentData.set(ev.callId, full);
await sendSessionUpdate(cx, acpSid, {
sessionUpdate: "tool_call_update",
toolCallId: ev.callId,
_meta: { terminal_output: { terminal_id: ev.callId, data: delta } },
});
}
}
No description provided.