Files
orca/src/main/runtime/terminal-layout-queue-exit.test.ts
T
Kelvin Amoaba 2aa47c91d2 fix(runtime): send a terminal's first screen before closing its stream on exit (#39681)
* fix(runtime): send a terminal's first screen before closing its stream on exit

A PTY exit while terminal.subscribe was still publishing its first snapshot
ended the stream at once: the phone got end with no screen. The exit now
waits for that publication, the exited PTY's model stays readable (off the
live map) until it finishes, and queued layout work settles on exit so it
can't hold the stream open.

* fix(runtime): skip the renderer seed when the PTY exits while its screen is read
2026-11-08 18:34:16 +00:00

35 lines
1.6 KiB
TypeScript

import { describe, expect, it, vi } from 'vitest'
import { OrcaRuntimeService } from './orca-runtime'
const PTY_ID = 'repo-1::/tmp/wt@@7a3c9e01'
type LayoutInternals = {
recordPtyWorktree: (ptyId: string, worktreeId: string, state?: { connected?: boolean }) => unknown
enqueueLayout: (ptyId: string, target: unknown) => Promise<{ ok: boolean; reason?: string }>
applyLayout: (ptyId: string, target: unknown) => Promise<{ ok: boolean; reason?: string }>
freshSubscribeGuard: Set<string>
}
describe('layout queue when its PTY exits', () => {
it('settles layout work queued behind the running slot as pty-exited', async () => {
const runtime = new OrcaRuntimeService()
// oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: test reaches protected members the runtime defines.
const internals = runtime as unknown as LayoutInternals
internals.recordPtyWorktree(PTY_ID, 'repo-1::/tmp/wt', { connected: true })
let finishRunning = (): void => {}
vi.spyOn(internals, 'applyLayout').mockImplementation(
() => new Promise((resolve) => (finishRunning = () => resolve({ ok: true })))
)
internals.freshSubscribeGuard.add(PTY_ID)
const target = { kind: 'phone', cols: 40, rows: 20, ownerClientId: 'phone-1' }
const running = internals.enqueueLayout(PTY_ID, target)
const queued = internals.enqueueLayout(PTY_ID, { ...target, ownerClientId: 'phone-2' })
await runtime.onPtyExit(PTY_ID, 0)
finishRunning()
await expect(running).resolves.toEqual({ ok: true })
await expect(queued).resolves.toEqual({ ok: false, reason: 'pty-exited' })
})
})