fix(cli): stop reporting a recovered runtime as unreachable

The open-window poll carried the earlier reason forward with `?? lastReason`, so a
runtime that came back mid-wait still timed out with "its runtime is unreachable"
and a reason naming a socket it no longer uses -- a stale negative reported as the
current diagnosis. Clear the reason whenever the status says reachable.

That leaves two genuinely different timeouts, so give them different words: one
never got an answer; the other answered the whole time and opened no window, where
"may still be running headlessly" understates what the poll already proved.
This commit is contained in:
Brennan Benson
2026-08-29 18:58:06 -07:00
committed by Merge Sim
parent 70dc4e28fd
commit a90ce02e08
2 changed files with 67 additions and 4 deletions
+50
View File
@@ -348,6 +348,56 @@ describe.skipIf(process.platform === 'win32')('RuntimeClient', () => {
})
})
// STA-3969: the poll carried the earlier reason forward with `?? lastReason`, so a runtime
// that RECOVERED mid-wait was still reported unreachable at the timeout -- a stale negative
// presented as the current diagnosis.
it('openOrca stops reporting a runtime unreachable once it answers again', async () => {
const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-client-'))
const endpoint = join(userDataPath, 'runtime.sock')
const server = createServer((socket) => {
sockets.add(socket)
socket.once('close', () => sockets.delete(socket))
socket.once('data', (data) => {
const request = JSON.parse(String(data).trim()) as { id: string }
socket.write(
`${JSON.stringify({
id: request.id,
ok: true,
result: {
runtimeId: 'runtime-1',
rendererGraphEpoch: 0,
graphStatus: 'ready',
authoritativeWindowId: 0,
desktopWindowStatus: 'initializing',
liveTabCount: 0,
liveLeafCount: 0
},
_meta: { runtimeId: 'runtime-1' }
})}\n`
)
})
})
servers.add(server)
await new Promise<void>((resolve) => server.listen(endpoint, resolve))
// Starts pointed at an endpoint nothing serves, then recovers onto the live one.
writeMetadata(userDataPath, join(userDataPath, 'never-listened.sock'), 'token', process.pid)
vi.mocked(launchOrcaApp).mockImplementationOnce(() => {
writeMetadata(userDataPath, endpoint, 'token', process.pid)
})
const client = new RuntimeClient(userDataPath, 100)
const failure = await client.openOrca(1_000).then(
() => null,
(error: unknown) => error as { code: string; message: string; data?: unknown }
)
expect(failure?.code).toBe('runtime_open_timeout')
expect(failure?.message).not.toContain('unreachable')
expect(failure?.data).toBeUndefined()
// The second timeout case: answers all the way through, just no window.
expect(failure?.message).toContain('is responding and still running headlessly')
})
it('openOrca waits for a reachable headless runtime to expose a desktop window', async () => {
const userDataPath = mkdtempSync(join(tmpdir(), 'orca-runtime-client-'))
const endpoint = join(userDataPath, 'runtime.sock')