mirror of
https://github.com/stablyai/orca.git
synced 2026-10-17 00:03:08 +00:00
Clear pending input when attaching a different remote terminal handle
When switching between different remote terminal handles, debounced input meant for the previous terminal could get incorrectly flushed and sent to the newly attached terminal. Fix this by clearing the batcher's pending state (text and byte counts) and invoking `inputBatcher.clear()` if the attached terminal handle changes.
This commit is contained in:
@@ -50,6 +50,8 @@ export function createRemoteRuntimePtyTextBatcher(
|
||||
|
||||
const clear = (): void => {
|
||||
clearTimer()
|
||||
pending = ''
|
||||
pendingBytes = 0
|
||||
validationVersion += 1
|
||||
validationTail = null
|
||||
}
|
||||
|
||||
@@ -342,6 +342,50 @@ describe('createRemoteRuntimePtyTransport', () => {
|
||||
expect(transport.isConnected()).toBe(false)
|
||||
})
|
||||
|
||||
it('drops pending input when attaching a different remote terminal handle', async () => {
|
||||
vi.useFakeTimers()
|
||||
runtimeSubscribe.mockImplementation(
|
||||
async (_args: unknown, callbacks: typeof subscriptionCallbacks) => {
|
||||
subscriptionCallbacks = callbacks
|
||||
return { unsubscribe: vi.fn(), sendBinary: subscriptionSendBinary }
|
||||
}
|
||||
)
|
||||
try {
|
||||
const { createRemoteRuntimePtyTransport } = await import('./remote-runtime-pty-transport')
|
||||
const transport = createRemoteRuntimePtyTransport('env-1', {
|
||||
worktreeId: 'wt-1',
|
||||
tabId: 'tab-1',
|
||||
leafId: 'pane:1'
|
||||
})
|
||||
|
||||
transport.attach({
|
||||
existingPtyId: 'remote:env-1@@terminal-old',
|
||||
cols: 80,
|
||||
rows: 24,
|
||||
callbacks: {}
|
||||
})
|
||||
expect(transport.sendInput('queued-for-old')).toBe(true)
|
||||
|
||||
transport.attach({
|
||||
existingPtyId: 'remote:env-1@@terminal-new',
|
||||
cols: 80,
|
||||
rows: 24,
|
||||
callbacks: {}
|
||||
})
|
||||
runtimeCall.mockClear()
|
||||
|
||||
await vi.advanceTimersByTimeAsync(10)
|
||||
|
||||
expect(runtimeCall).not.toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
method: 'terminal.send'
|
||||
})
|
||||
)
|
||||
} finally {
|
||||
vi.useRealTimers()
|
||||
}
|
||||
})
|
||||
|
||||
it('ignores stale attach subscription rejection after reattaching a newer remote terminal', async () => {
|
||||
let rejectOldSubscription: ((error: Error) => void) | null = null
|
||||
const newStream = {
|
||||
|
||||
@@ -507,7 +507,13 @@ export function createRemoteRuntimePtyTransport(
|
||||
storedCallbacks = options.callbacks
|
||||
currentRuntimeEnvironmentId =
|
||||
getRemoteRuntimePtyEnvironmentId(options.existingPtyId) ?? runtimeEnvironmentId
|
||||
handle = getRemoteRuntimeTerminalHandle(options.existingPtyId)
|
||||
const previousHandle = handle
|
||||
const nextHandle = getRemoteRuntimeTerminalHandle(options.existingPtyId)
|
||||
if (previousHandle && previousHandle !== nextHandle) {
|
||||
// Why: debounced input is scoped by the current terminal handle at flush time.
|
||||
inputBatcher.clear()
|
||||
}
|
||||
handle = nextHandle
|
||||
if (!handle) {
|
||||
connected = false
|
||||
remotePtyId = null
|
||||
|
||||
Reference in New Issue
Block a user