mirror of
https://github.com/stablyai/orca.git
synced 2026-09-24 00:02:24 +00:00
* fix(runtime): reject provider inventory across PTY lifecycle changes * fix(runtime): canonicalize SSH inventory generation keys --------- Co-authored-by: m4air <m4air@Mac.localdomain> Co-authored-by: Neil <neil@stably.ai>
89 lines
4.8 KiB
Diff
89 lines
4.8 KiB
Diff
diff --git a/src/main/runtime/orca-runtime-invalidate-all-handles-for-pty.ts b/src/main/runtime/orca-runtime-invalidate-all-handles-for-pty.ts
|
|
index 448fb2a00fb..9d6e5d56ca4 100644
|
|
--- a/src/main/runtime/orca-runtime-invalidate-all-handles-for-pty.ts
|
|
+++ b/src/main/runtime/orca-runtime-invalidate-all-handles-for-pty.ts
|
|
@@ -1,6 +1,12 @@
|
|
// @ts-nocheck -- mechanically split from OrcaRuntimeService; behavior is covered by AST equivalence and characterization tests.
|
|
import { OrcaRuntimeWithResolveKnownWorkspaceFileTarget } from './orca-runtime-resolve-known-workspace-file-target'
|
|
import type { PtyIncarnationId } from '../../shared/pty-incarnation'
|
|
+import { getPtyExecutionHost } from '../../shared/terminal-execution-host'
|
|
+import {
|
|
+ LOCAL_EXECUTION_HOST_ID,
|
|
+ parseExecutionHostId,
|
|
+ toSshExecutionHostId
|
|
+} from '../../shared/execution-host'
|
|
|
|
export class OrcaRuntimeWithInvalidateAllHandlesForPty extends OrcaRuntimeWithResolveKnownWorkspaceFileTarget {
|
|
protected invalidateAllHandlesForPty(ptyId: string, preserveHandle?: string): Set<string> {
|
|
@@ -110,11 +116,30 @@ export class OrcaRuntimeWithInvalidateAllHandlesForPty extends OrcaRuntimeWithRe
|
|
return false
|
|
}
|
|
|
|
+ protected invalidatePtyControllerInventoryForLifecycle(
|
|
+ ptyId: string,
|
|
+ connectionId?: string | null
|
|
+ ): void {
|
|
+ const generation = ++this.ptyControllerInventorySequence
|
|
+ const hostId = getPtyExecutionHost(ptyId)
|
|
+ if (hostId === 'foreign' || (hostId && parseExecutionHostId(hostId)?.kind === 'runtime')) {
|
|
+ this.ptyControllerAggregateInventoryGeneration = generation
|
|
+ return
|
|
+ }
|
|
+ const connection =
|
|
+ connectionId === undefined ? this.ptysById.get(ptyId)?.connectionId : connectionId
|
|
+ const providerKey =
|
|
+ hostId ?? (connection ? toSshExecutionHostId(connection) : LOCAL_EXECUTION_HOST_ID)
|
|
+ // A pending census predates this admission or exit, including legacy IDs without an incarnation.
|
|
+ this.ptyControllerInventoryGenerationByProvider.set(providerKey, generation)
|
|
+ }
|
|
+
|
|
onPtySpawned(
|
|
ptyId: string,
|
|
incarnationId?: PtyIncarnationId,
|
|
options: { awaitsRegistration?: boolean } = {}
|
|
): void {
|
|
+ this.invalidatePtyControllerInventoryForLifecycle(ptyId)
|
|
const existingPty = this.ptysById.get(ptyId)
|
|
if (
|
|
existingPty &&
|
|
diff --git a/src/main/runtime/orca-runtime-on-pty-exit.ts b/src/main/runtime/orca-runtime-on-pty-exit.ts
|
|
index 6ddf877f87c..ce24ed65d98 100644
|
|
--- a/src/main/runtime/orca-runtime-on-pty-exit.ts
|
|
+++ b/src/main/runtime/orca-runtime-on-pty-exit.ts
|
|
@@ -30,6 +30,7 @@ export class OrcaRuntimeWithOnPtyExit extends OrcaRuntimeWithOnClientDisconnecte
|
|
if (exitIncarnationId && pty?.incarnationId && exitIncarnationId !== pty.incarnationId) {
|
|
return
|
|
}
|
|
+ this.invalidatePtyControllerInventoryForLifecycle(ptyId, pty?.connectionId)
|
|
// A bare exit code is not enough to establish why a process ended: older
|
|
// daemons and SSH relays can report 0 for crashes and wrapper exits.
|
|
const observedCause = options.cause ?? resolveUnreportedExitCause(exitCode)
|
|
diff --git a/src/main/runtime/orca-runtime-refresh-pty-worktree-records-with-controller-inventory.ts b/src/main/runtime/orca-runtime-refresh-pty-worktree-records-with-controller-inventory.ts
|
|
index aca67f67ba2..930907da120 100644
|
|
--- a/src/main/runtime/orca-runtime-refresh-pty-worktree-records-with-controller-inventory.ts
|
|
+++ b/src/main/runtime/orca-runtime-refresh-pty-worktree-records-with-controller-inventory.ts
|
|
@@ -55,7 +55,10 @@ export class OrcaRuntimeWithRefreshPtyWorktreeRecordsWithControllerInventory ext
|
|
}
|
|
const inventoryGeneration = this.ptyControllerInventorySequence + 1
|
|
this.ptyControllerInventorySequence = inventoryGeneration
|
|
- const providerKey = typeof connectionId === 'string' ? `ssh:${connectionId}` : 'local'
|
|
+ const providerKey =
|
|
+ typeof connectionId === 'string'
|
|
+ ? toSshExecutionHostId(connectionId)
|
|
+ : LOCAL_EXECUTION_HOST_ID
|
|
const livenessObservationAtStart = this.ptyLivenessObservationSequence
|
|
if (connectionId === undefined) {
|
|
this.ptyControllerAggregateInventoryGeneration = inventoryGeneration
|
|
diff --git a/src/main/runtime/orca-runtime-register-pty.ts b/src/main/runtime/orca-runtime-register-pty.ts
|
|
index dae2519ca9f..2d36a18a1e0 100644
|
|
--- a/src/main/runtime/orca-runtime-register-pty.ts
|
|
+++ b/src/main/runtime/orca-runtime-register-pty.ts
|
|
@@ -26,6 +26,7 @@ export class OrcaRuntimeWithRegisterPty extends OrcaRuntimeWithInvalidateAllHand
|
|
isWsl?: boolean
|
|
): void {
|
|
this.assertPtyDidNotExitBeforeRegistration(ptyId, binding?.incarnationId)
|
|
+ this.invalidatePtyControllerInventoryForLifecycle(ptyId, connectionId)
|
|
const existingPty = this.ptysById.get(ptyId)
|
|
const replacementHandle = binding?.terminalHandle?.trim()
|
|
const pendingReplacement = this.pendingPtyHandleReplacementFences.get(ptyId)
|