diff --git a/src/renderer/src/runtime/remote-runtime-terminal-frame-drop-resync.test.ts b/src/renderer/src/runtime/remote-runtime-terminal-frame-drop-resync.test.ts index 1d851a0e6ef..aff47e81a1d 100644 --- a/src/renderer/src/runtime/remote-runtime-terminal-frame-drop-resync.test.ts +++ b/src/renderer/src/runtime/remote-runtime-terminal-frame-drop-resync.test.ts @@ -209,6 +209,9 @@ describe('remote terminal frame-drop resync', () => { expect(server.droppedFrames).toBe(1) // Instead, a fresh authoritative snapshot recovers the terminal. expect(snapshots).toEqual(['INITIAL', '\x1b[2J\x1b[3J\x1b[HRECOVERED']) + + server.output('ddd') + expect(data).toEqual(['aaa', 'ddd']) }) it('passes contiguous output straight through without resyncing', async () => { @@ -352,5 +355,8 @@ describe('remote terminal frame-drop resync', () => { await expect(manualSnapshot).resolves.toMatchObject({ data: 'MANUAL' }) expect(server.snapshotRequests).toHaveLength(2) expect(snapshots).toEqual(['INITIAL', '\x1b[2J\x1b[3J\x1b[HRECOVERED']) + + server.output('ddd') + expect(data).toEqual(['aaa', 'ddd']) }) }) diff --git a/src/renderer/src/runtime/remote-runtime-terminal-multiplexer.ts b/src/renderer/src/runtime/remote-runtime-terminal-multiplexer.ts index 455261b0f9c..6bc9c4a8a2d 100644 --- a/src/renderer/src/runtime/remote-runtime-terminal-multiplexer.ts +++ b/src/renderer/src/runtime/remote-runtime-terminal-multiplexer.ts @@ -605,15 +605,16 @@ class RemoteRuntimeTerminalMultiplexer { clearPendingSnapshotRequest(stream) } clearSnapshot(stream) - // Why: the snapshot is the new authoritative output high-water; align the - // gap detector to it and re-open the live path (used by both the initial - // snapshot and a frame-drop resync, which reuses the 'initial' target). - if (target === 'initial') { + // Why: initial and recovery snapshots are authoritative output + // high-waters; align the gap detector and re-open the live path. + if (target === 'initial' || target === 'recovery') { stream.expectedSeq = typeof info?.seq === 'number' ? info.seq : undefined stream.resyncInFlight = false stream.resyncPendingSend = false - stream.initialSnapshotReceived = true - stream.callbacks.onSubscribed?.() + if (target === 'initial') { + stream.initialSnapshotReceived = true + stream.callbacks.onSubscribed?.() + } } else { this.sendDeferredResyncSnapshot(stream) }