diff --git a/src/main/ipc/pty/runtime/queried-host-kinds.test.ts b/src/main/ipc/pty/runtime/queried-host-kinds.test.ts index 1f7ce2459d8..6e6e1b33db1 100644 --- a/src/main/ipc/pty/runtime/queried-host-kinds.test.ts +++ b/src/main/ipc/pty/runtime/queried-host-kinds.test.ts @@ -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() }) diff --git a/src/main/ipc/pty/runtime/spawn-preflight.ts b/src/main/ipc/pty/runtime/spawn-preflight.ts index e40f9bc431d..e73379df41c 100644 --- a/src/main/ipc/pty/runtime/spawn-preflight.ts +++ b/src/main/ipc/pty/runtime/spawn-preflight.ts @@ -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) +} diff --git a/src/main/providers/settled-pty-writer-census.test.ts b/src/main/providers/settled-pty-writer-census.test.ts index 1535b1dabe2..1890ae62213 100644 --- a/src/main/providers/settled-pty-writer-census.test.ts +++ b/src/main/providers/settled-pty-writer-census.test.ts @@ -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')