mirror of
https://github.com/stablyai/orca.git
synced 2026-11-15 02:17:31 +00:00
fix(windows): skip the ConPTY input-reader check on WinPTY panes (#36490)
node-pty falls back to WinPTY below Windows build 18309. WinPTY never sends ConPTY's DA1 announcement, so every plain terminal was classified as having no input reader and the healthy shell was killed and respawned. On v1.4.244 that discard killed the WinPTY agent twice, and winpty's native kill throws 'Pty seems to have been killed already', failing every plain terminal spawn. Fixes #36317
This commit is contained in:
@@ -163,6 +163,14 @@ export function _resetConptyStartupTrustForTest(): void {
|
||||
respawnCount = 0
|
||||
}
|
||||
|
||||
type NodePtyWindowsPane = pty.IPty & { _agent?: { _useConpty?: boolean } }
|
||||
|
||||
// node-pty falls back to WinPTY below Windows build 18309, which never announces an input reader.
|
||||
function runsOnWinpty(proc: pty.IPty): boolean {
|
||||
const pane: NodePtyWindowsPane = proc
|
||||
return pane._agent?._useConpty === false
|
||||
}
|
||||
|
||||
function withNotice(claim: () => ConptyStartupEvents): () => ConptyStartupEvents {
|
||||
return () => {
|
||||
const events = claim()
|
||||
@@ -186,7 +194,7 @@ export async function spawnConptyWithInputReader(
|
||||
}> {
|
||||
const firstSpawn = await spawn()
|
||||
const { proc: first, physicalOwner: firstOwner } = firstSpawn
|
||||
if (announcementUntrusted) {
|
||||
if (announcementUntrusted || runsOnWinpty(first)) {
|
||||
return { ...firstSpawn, claimStartupEvents: () => ({ data: [], exit: null }) }
|
||||
}
|
||||
const firstStartup = await decideConptyStartup(first, opts.signal, firstOwner)
|
||||
|
||||
@@ -367,6 +367,19 @@ describe('Windows shell fallback over node-pty ConPTY', () => {
|
||||
expect(nodePty.spawn).toHaveBeenCalledTimes(3)
|
||||
})
|
||||
|
||||
it('hands out a WinPTY pane unchecked, since only ConPTY announces an input reader', async () => {
|
||||
// Windows builds below 18309 get WinPTY, whose native kill throws when repeated (#36317).
|
||||
const winpty = Object.assign(deadPane(990001), { _agent: { _useConpty: false } })
|
||||
nodePty.spawn.mockReturnValueOnce(winpty)
|
||||
|
||||
const result = await spawnNativeDaemonPty(args)
|
||||
|
||||
expect(nodePty.spawn).toHaveBeenCalledOnce()
|
||||
expect(winpty.kill).not.toHaveBeenCalled()
|
||||
expect(ptyJob.killConptyNow).not.toHaveBeenCalled()
|
||||
expect(result.process).toBe(winpty)
|
||||
})
|
||||
|
||||
it('does not respawn a shell that exited before ConPTY announced anything', async () => {
|
||||
const exited = fakePane(990001, [], 3)
|
||||
nodePty.spawn.mockReturnValueOnce(exited)
|
||||
|
||||
Reference in New Issue
Block a user