Files
orca/src/main/ipc/pty/runtime/controller.ts
T
OrcaWinandm4air 2779dfeb2b refactor(pty): drop SSH spawn, liveness and kill branches (#27529)
* refactor(pty): drop SSH spawn, liveness and kill branches

* test(pty): drive the commit-durability tests through local PTYs only

* test(pty): drop the SSH host arm from the exit-durability fixture

---------

Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-11 12:05:22 -07:00

97 lines
5.2 KiB
TypeScript

import { localProvider } from '../provider/registry'
import {
getLocalAutomaticWorkStatus,
resumeLocalAutomaticWork
} from '../../../daemon/daemon-automatic-work-resume'
import { makePaneKey } from '../../../../shared/stable-pane-id'
import { claimRuntimePaneCreate, makePaneSpawnReservationKey } from '../pane/spawn-reservation'
import type { PtyRuntimeControllerDeps } from './controller-deps'
import { spawnPtyFromRuntimeController } from './spawn'
import {
killPtyFromRuntimeController,
retireRejectedPtyFromRuntimeController,
stopAndWaitPtyFromRuntimeController
} from './kill'
import {
attachPtyFromRuntimeController,
clearBufferFromRuntimeController,
resetInputModesFromRuntimeController,
confirmForegroundProcessFromRuntimeController,
confirmShellForegroundFromRuntimeController,
getCwdFromRuntimeController,
getForegroundProcessFromRuntimeController,
getRendererSerializerGenerationFromRuntimeController,
getSizeFromRuntimeController,
hasChildProcessesFromRuntimeController,
hasPtyFromRuntimeController,
hasRendererSerializerFromRuntimeController,
inspectProcessFromRuntimeController,
probePtyLivenessFromRuntimeController,
resizePtyFromRuntimeController,
serializeProviderBufferFromRuntimeController,
waitForRendererSerializerFromRuntimeController,
writePtyFromRuntimeController
} from './operations'
import { supportsForegroundProcessEvidenceFromRuntimeController } from './foreground-process-evidence-capability'
import {
listProcessesFromRuntimeController,
listProcessesWithHostScopeFromRuntimeController
} from './inventory-operations'
export function installPtyRuntimeController(deps: PtyRuntimeControllerDeps): void {
const { runtime, adoptStablePane, requestSerializedBuffer } = deps
runtime?.setPtyController({
claimStablePaneCreate: (args) => {
const paneKey = makePaneKey(args.tabId, args.leafId)
const ownerKey = makePaneSpawnReservationKey(args.worktreeId, args.connectionId, paneKey)
return ownerKey ? claimRuntimePaneCreate(ownerKey) : () => {}
},
adoptStablePane,
spawn: async (args) => spawnPtyFromRuntimeController(deps, args),
// Why the local owner only: an SSH host's gate belongs to that host's own runtime.
getAutomaticWorkStatus: () => getLocalAutomaticWorkStatus(localProvider),
resumeAutomaticWork: () => resumeLocalAutomaticWork(localProvider),
write: (ptyId, data, inputKind) => writePtyFromRuntimeController(deps, ptyId, data, inputKind),
writeWithSettlement: (ptyId, data, inputKind) =>
writePtyFromRuntimeController(deps, ptyId, data, inputKind, { waitForSettlement: true }),
probePtyLiveness: (ptyId) => probePtyLivenessFromRuntimeController(deps, ptyId),
// Why: subscriber-driven ingestion for daemon sessions no renderer pane
// ever attached. Local daemon sessions only — SSH panes have their own
// lease machinery, and the in-process local provider streams without
// attach. Attach-only and false-on-doubt: never creates or resizes.
attach: (ptyId) => attachPtyFromRuntimeController(deps, ptyId),
kill: (ptyId) => killPtyFromRuntimeController(deps, ptyId),
retireRejectedPty: (ptyId, stopConfirmed) =>
retireRejectedPtyFromRuntimeController(deps, ptyId, stopConfirmed),
stopAndWait: (ptyId, opts) => stopAndWaitPtyFromRuntimeController(deps, ptyId, opts),
getForegroundProcess: (ptyId) => getForegroundProcessFromRuntimeController(ptyId),
inspectProcess: (ptyId, options) => inspectProcessFromRuntimeController(ptyId, options),
confirmForegroundProcess: (ptyId) => confirmForegroundProcessFromRuntimeController(ptyId),
confirmShellForeground: (ptyId) => confirmShellForegroundFromRuntimeController(ptyId),
getCwd: (ptyId) => getCwdFromRuntimeController(ptyId),
hasChildProcesses: (ptyId) => hasChildProcessesFromRuntimeController(ptyId),
clearBuffer: (ptyId) => clearBufferFromRuntimeController(deps, ptyId),
resetInputModes: (ptyId) => resetInputModesFromRuntimeController(deps, ptyId),
hasPty: (ptyId) => hasPtyFromRuntimeController(deps, ptyId),
listProcesses: (hostId, opts) => listProcessesFromRuntimeController(deps, hostId, opts),
listProcessesWithHostScope: (opts) =>
listProcessesWithHostScopeFromRuntimeController(deps, opts),
supportsForegroundProcessEvidence: (hostId) =>
supportsForegroundProcessEvidenceFromRuntimeController(hostId),
serializeBuffer: (ptyId, opts) => {
// Why: mobile xterm must start from the desktop's exact screen state/dimensions before live TUI chunks render correctly.
return requestSerializedBuffer(ptyId, opts)
},
serializeProviderBuffer: (ptyId, opts) =>
serializeProviderBufferFromRuntimeController(ptyId, opts),
hasRendererSerializer: (ptyId) => hasRendererSerializerFromRuntimeController(ptyId),
getRendererSerializerGeneration: (ptyId) =>
getRendererSerializerGenerationFromRuntimeController(ptyId),
waitForRendererSerializer: (ptyId, afterGeneration, timeoutMs, signal) =>
waitForRendererSerializerFromRuntimeController(ptyId, afterGeneration, timeoutMs, signal),
getSize: (ptyId) => getSizeFromRuntimeController(ptyId),
resize: (ptyId, cols, rows) => resizePtyFromRuntimeController(ptyId, cols, rows)
})
}