Preserve daemon spawn identity after routing recovery

This commit is contained in:
m4air
2026-09-28 05:55:30 -07:00
parent 6e3e09c6ca
commit 403fec69de
3 changed files with 46 additions and 25 deletions
@@ -1,7 +1,8 @@
import { afterEach, describe, expect, it, vi } from 'vitest'
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import { parseExecutionHostId } from '../../../../shared/execution-host'
import { sshProviders } from '../provider/registry'
import { localProvider, setLocalPtyProvider, sshProviders } from '../provider/registry'
import { listProcessesWithHostScopeFromRuntimeController } from './inventory-operations'
import { createUnavailablePtyProvider } from '../../../providers/unavailable-pty-provider'
import type { PtyRuntimeControllerDeps } from './controller-deps'
/**
@@ -21,7 +22,12 @@ import type { PtyRuntimeControllerDeps } from './controller-deps'
* `kind === 'ssh'` in `orca-runtime-refresh-pty-worktree-records-with-controller-inventory.ts`.
*/
describe('the hosts a PTY inventory can report having queried', () => {
const originalProvider = localProvider
beforeEach(() => {
setLocalPtyProvider({ ...createUnavailablePtyProvider(), listProcesses: async () => [] })
})
afterEach(() => {
setLocalPtyProvider(originalProvider)
sshProviders.clear()
})
+24 -18
View File
@@ -71,24 +71,7 @@ export async function prepareRuntimePtySpawn(
terminalWindowsWslDistro: null
}
ctx.daemonShellOverride = ctx.terminalRuntimeOptions.shellOverride
ctx.isDaemonHostSpawn = !args.connectionId && !routesFreshSpawnsToLocalProvider(ctx.provider)
ctx.callerRequestedSessionId = args.sessionId?.trim()
ctx.requestedSessionId =
ctx.callerRequestedSessionId ??
(ctx.isDaemonHostSpawn && args.agentSessionCreateOperationId
? ptySessionIdForAgentCreateOperation(args.worktreeId, args.agentSessionCreateOperationId)
: undefined)
ctx.sessionId =
ctx.requestedSessionId ??
(ctx.isDaemonHostSpawn ? mintPtySessionId(args.worktreeId) : undefined)
ctx.effectiveSessionRelayId =
ctx.sessionId !== undefined ? getRelayPtyId(args.connectionId, ctx.sessionId) : undefined
ctx.effectiveSessionAppId =
ctx.sessionId !== undefined ? getAppPtyId(args.connectionId, ctx.sessionId) : undefined
ctx.isNewDaemonSession =
!ctx.preAdoptedStablePane &&
ctx.isDaemonHostSpawn &&
(ctx.callerRequestedSessionId === undefined || args.isNewSession === true)
prepareRuntimeSessionIdentity(ctx)
ctx.expectedWslDistro = !args.connectionId
? (resolveWslSessionContext({
cwd: ctx.cwd,
@@ -135,6 +118,7 @@ export async function prepareRuntimePtySpawn(
)
if (freshSpawnRecovery) {
await freshSpawnRecovery
prepareRuntimeSessionIdentity(ctx)
}
}
ctx.codexSelectionTarget = getCodexSelectionTargetForPty(
@@ -278,3 +262,25 @@ export async function prepareRuntimePtySpawn(
return null
}
function prepareRuntimeSessionIdentity(ctx: RuntimePtySpawnState): void {
const args = ctx.args
ctx.isDaemonHostSpawn = !args.connectionId && !routesFreshSpawnsToLocalProvider(ctx.provider)
ctx.callerRequestedSessionId = args.sessionId?.trim()
ctx.requestedSessionId =
ctx.callerRequestedSessionId ??
(ctx.isDaemonHostSpawn && args.agentSessionCreateOperationId
? ptySessionIdForAgentCreateOperation(args.worktreeId, args.agentSessionCreateOperationId)
: undefined)
ctx.sessionId =
ctx.requestedSessionId ??
(ctx.isDaemonHostSpawn ? mintPtySessionId(args.worktreeId) : undefined)
ctx.effectiveSessionRelayId =
ctx.sessionId !== undefined ? getRelayPtyId(args.connectionId, ctx.sessionId) : undefined
ctx.effectiveSessionAppId =
ctx.sessionId !== undefined ? getAppPtyId(args.connectionId, ctx.sessionId) : undefined
ctx.isNewDaemonSession =
!ctx.preAdoptedStablePane &&
ctx.isDaemonHostSpawn &&
(ctx.callerRequestedSessionId === undefined || args.isNewSession === true)
}
@@ -4,6 +4,8 @@ import { describe, expect, it, vi } from 'vitest'
import { SshPtyProvider } from './ssh-pty-provider'
import { createMockMux } from './ssh-pty-provider-mock-multiplexer'
import { DaemonPtyRouter } from '../daemon/daemon-pty-router'
import { WslDaemonPtyProvider } from '../wsl/wsl-daemon-pty-provider'
import { createUnavailablePtyProvider } from './unavailable-pty-provider'
import { DaemonPtyAdapter } from '../daemon/daemon-pty-adapter'
vi.mock('electron', () => ({
@@ -24,7 +26,8 @@ const REPO_ROOT = join(__dirname, '..', '..', '..')
const SETTLED_PTY_WRITER_FILES = [
'src/main/providers/relay-pty-provider.ts',
'src/main/daemon/daemon-pty-router.ts',
'src/main/daemon/daemon-pty-adapter.ts'
'src/main/daemon/daemon-pty-adapter.ts',
'src/main/wsl/wsl-daemon-pty-provider.ts'
]
/** Where the provider-side settlement is actually decided; the adapter inherits its own. */
@@ -32,7 +35,9 @@ const SETTLED_WRITER_DECLARATIONS = [
'src/main/providers/relay-pty-provider.ts',
'src/main/providers/ssh-pty-provider-rpc-operations.ts',
'src/main/daemon/daemon-pty-router.ts',
'src/main/daemon/daemon-pty-session-input.ts'
'src/main/daemon/daemon-pty-session-input.ts',
'src/main/wsl/wsl-daemon-pty-provider.ts',
'src/main/providers/unavailable-pty-provider.ts'
]
function declaredProviderFiles(directory = join(REPO_ROOT, 'src/main')): string[] {
@@ -64,12 +69,16 @@ describe('settled PTY writer census', () => {
})
it('exposes a settled writer on every production provider instance', () => {
const daemonClient = { isConnected: () => false, onEvent: vi.fn(() => vi.fn()) }
const adapter = new DaemonPtyAdapter(daemonClient as never)
const adapter = new DaemonPtyAdapter({
socketPath: join(__dirname, 'census.sock'),
tokenPath: join(__dirname, 'census.token')
})
const instances = [
new SshPtyProvider('conn-census', createMockMux() as never),
new DaemonPtyRouter({ current: adapter, legacy: [] }),
adapter
adapter,
new WslDaemonPtyProvider({ distro: 'Ubuntu', relayBuildId: 'census-build' }, adapter),
createUnavailablePtyProvider()
]
for (const provider of instances) {
expect(typeof provider.writeWithSettlement, provider.constructor.name).toBe('function')