refactor(pty): arm the swap-window settle watcher once per startup promise

This commit is contained in:
Brennan Benson
2026-08-27 19:57:01 -07:00
parent 21672439b5
commit b3008b6319
2 changed files with 32 additions and 22 deletions
@@ -151,15 +151,18 @@ describe('registerPtyHandlers daemon-swap-window presence', () => {
// authoritatively answer for a remote host's PTY, so remote-scoped ids
// stay unknown, never absent.
let controller: { hasPty: (ptyId: string) => boolean | null } | undefined
registerPtyHandlers(mainWindow as never, {
setPtyController: vi.fn((next) => {
controller = next
}),
registerPty: vi.fn(),
onPtySpawned: vi.fn(),
onPtyExit: vi.fn(),
onPtyData: vi.fn()
} as never)
registerPtyHandlers(
mainWindow as never,
{
setPtyController: vi.fn((next) => {
controller = next
}),
registerPty: vi.fn(),
onPtySpawned: vi.fn(),
onPtyExit: vi.fn(),
onPtyData: vi.fn()
} as never
)
expect(controller?.hasPty('remote:environment@@pty-1')).toBe(null)
})
@@ -184,15 +187,18 @@ describe('registerPtyHandlers daemon-swap-window presence', () => {
// no barrier; the installed provider is then the sole owner (#12393) and
// its false stays an observed absence.
let controller: { hasPty: (ptyId: string) => boolean | null } | undefined
registerPtyHandlers(mainWindow as never, {
setPtyController: vi.fn((next) => {
controller = next
}),
registerPty: vi.fn(),
onPtySpawned: vi.fn(),
onPtyExit: vi.fn(),
onPtyData: vi.fn()
} as never)
registerPtyHandlers(
mainWindow as never,
{
setPtyController: vi.fn((next) => {
controller = next
}),
registerPty: vi.fn(),
onPtySpawned: vi.fn(),
onPtyExit: vi.fn(),
onPtyData: vi.fn()
} as never
)
expect(controller?.hasPty('never-spawned-pty')).toBe(false)
await expect(handlers.get('pty:hasPty')!(null, { id: 'never-spawned-pty' })).resolves.toBe(
+8 -4
View File
@@ -153,6 +153,7 @@ export async function clearBufferFromRuntimeController(
}
const settledLocalPtyProviderStartups = new WeakSet<Promise<void>>()
const watchedLocalPtyProviderStartups = new WeakSet<Promise<void>>()
export function hasPtyFromRuntimeController(
deps: PtyRuntimeControllerDeps,
@@ -171,10 +172,13 @@ export function hasPtyFromRuntimeController(
// probePtyLiveness does, and the pre-swap provider's "no PTY" for a
// daemon-restored id is fabricated — answer unverifiable until the swap
// settles (docs/reference/ssh-execution-boundary.md rule 2).
startupPromise.then(
() => settledLocalPtyProviderStartups.add(startupPromise),
() => settledLocalPtyProviderStartups.add(startupPromise)
)
if (!watchedLocalPtyProviderStartups.has(startupPromise)) {
watchedLocalPtyProviderStartups.add(startupPromise)
const markSettled = (): void => {
settledLocalPtyProviderStartups.add(startupPromise)
}
startupPromise.then(markSettled, markSettled)
}
return null
}
return getProviderForPty(ptyId).hasPty?.(ptyId) ?? null