From b960a36428aa1a44495cacf20d26b6ed9a684dac Mon Sep 17 00:00:00 2001 From: Neil Date: Tue, 6 Oct 2026 14:57:41 -0700 Subject: [PATCH 1/6] Preserve runtime-owned PTYs through first renderer mount --- .../runtime/orca-runtime-sync-window-graph.ts | 51 +++- .../runtime-owned-terminal-projection.ts | 121 +++++++++ .../terminal-list-surface-lost-orphan.test.ts | 229 +++++++++++++++++- tests/e2e/helpers/fake-codex-launch-probes.ts | 4 + ...ackground-terminal-mount-authority.spec.ts | 17 +- 5 files changed, 401 insertions(+), 21 deletions(-) create mode 100644 src/main/runtime/runtime-owned-terminal-projection.ts diff --git a/src/main/runtime/orca-runtime-sync-window-graph.ts b/src/main/runtime/orca-runtime-sync-window-graph.ts index 893c51c68cce..69716b400b80 100644 --- a/src/main/runtime/orca-runtime-sync-window-graph.ts +++ b/src/main/runtime/orca-runtime-sync-window-graph.ts @@ -9,6 +9,13 @@ import type { } from '../../shared/runtime-types' import { HEADLESS_RUNTIME_WINDOW_ID } from '../../shared/runtime-types' import type { RuntimeLeafRecord } from './runtime-terminal-state-records' +import { + collectRendererPublishedEmptyTerminalPanes, + createRuntimeOwnedPtyResolver, + chooseProjectedPtyId, + makeRuntimePaneIdentity, + shouldPreservePublishedRuntimePane +} from './runtime-owned-terminal-projection' /** The runtime indexes graph tabs by bare id, so duplicate ids cannot be routed safely. */ function assertUniqueRuntimeGraphTabIds(tabs: readonly RuntimeSyncedTab[]): void { @@ -98,6 +105,17 @@ export class OrcaRuntimeWithSyncWindowGraph extends OrcaRuntimeWithAttachWindow // Why: renderer reloads can briefly republish the same leaf with no ptyId; // keep live CLI handles usable while the UI graph rebuilds. const preserveLivePtysDuringReload = this.graphStatus === 'reloading' + const incomingPtyIds = new Set(lifecycleLeaves.map((leaf) => leaf.ptyId)) + const published = collectRendererPublishedEmptyTerminalPanes( + graph, + this.mobileSessionTabsByWorktree, + this.acceptedRendererMobileSnapshotByWorktree + ) + const retainedRuntimePtyId = createRuntimeOwnedPtyResolver( + this.ptysById.values(), + (ptyId) => this.getPtyLivenessVerdict(ptyId)?.status === 'exited', + incomingPtyIds + ) for (const leaf of lifecycleLeaves) { if (leaf.ptyId) { if (leaf.parked) { @@ -108,10 +126,13 @@ export class OrcaRuntimeWithSyncWindowGraph extends OrcaRuntimeWithAttachWindow } const leafKey = this.getLeafKey(leaf.tabId, leaf.leafId) const existing = this.leaves.get(leafKey) - const ptyId = - preserveLivePtysDuringReload && leaf.ptyId === null && existing?.ptyId - ? existing.ptyId - : leaf.ptyId + const ptyId = chooseProjectedPtyId( + leaf.ptyId, + existing?.worktreeId === leaf.worktreeId ? existing.ptyId : null, + preserveLivePtysDuringReload, + makeRuntimePaneIdentity(leaf, this.makeRuntimePaneKey(leaf)), + retainedRuntimePtyId + ) const ptyGeneration = existing && existing.ptyId !== ptyId ? existing.ptyGeneration + 1 @@ -190,13 +211,25 @@ export class OrcaRuntimeWithSyncWindowGraph extends OrcaRuntimeWithAttachWindow const retainedIncarnation = oldLeaf?.ptyId ? this.handleByPtyIncarnation.get(oldLeaf.ptyId) : undefined + // Inactive panes may lack transport leaves while the renderer still publishes their exact surface. + const preservePublishedRuntimePane = + oldLeaf?.ptyId !== null && + oldLeaf?.ptyId !== undefined && + shouldPreservePublishedRuntimePane( + makeRuntimePaneIdentity(oldLeaf, this.makeRuntimePaneKey(oldLeaf)), + oldLeaf.ptyId, + published.emptyPaneWorktrees.get(oldLeafKey), + published.boundPtyIds, + retainedRuntimePtyId + ) if ( - preserveLivePtysDuringReload && oldLeaf?.ptyId && - (this.handleByPtyId.has(oldLeaf.ptyId) || - (retainedIncarnation && - retainedIncarnation.incarnationId === - this.ptysById.get(oldLeaf.ptyId)?.incarnationId)) && + (preservePublishedRuntimePane || + (preserveLivePtysDuringReload && + (this.handleByPtyId.has(oldLeaf.ptyId) || + (retainedIncarnation && + retainedIncarnation.incarnationId === + this.ptysById.get(oldLeaf.ptyId)?.incarnationId)))) && !nextPtyIds.has(oldLeaf.ptyId) ) { // Why: a CLI-created agent keeps using its exported handle even if diff --git a/src/main/runtime/runtime-owned-terminal-projection.ts b/src/main/runtime/runtime-owned-terminal-projection.ts new file mode 100644 index 000000000000..27bce561f4ec --- /dev/null +++ b/src/main/runtime/runtime-owned-terminal-projection.ts @@ -0,0 +1,121 @@ +import type { RuntimePtyWorktreeRecord } from './runtime-terminal-state-records' +import type { + RuntimeMobileSessionTabsSnapshot, + RuntimeSyncWindowGraph +} from '../../shared/runtime-types' +import { isTerminalLeafId } from '../../shared/stable-pane-id' + +/** The surface a retention decision is about; all three must match for the host to keep its PTY. */ +export type RuntimePaneIdentity = { + paneKey: string + worktreeId: string + tabId: string +} + +export function makeRuntimePaneIdentity( + leaf: { worktreeId: string; tabId: string }, + paneKey: string +): RuntimePaneIdentity { + return { paneKey, worktreeId: leaf.worktreeId, tabId: leaf.tabId } +} + +/** Resolves the host-owned PTY a pane may keep, or null when nothing may be retained. */ +export type RuntimeOwnedPtyResolver = ( + pane: RuntimePaneIdentity, + currentPtyId: string | null +) => string | null + +export function collectRendererPublishedEmptyTerminalPanes( + graph: Pick, + snapshots: ReadonlyMap, + acceptedSnapshots: ReadonlyMap }> +): { emptyPaneWorktrees: Map; boundPtyIds: Set } { + const worktrees = new Set([ + ...(graph.mobileSessionTabs?.map((snapshot) => snapshot.worktree) ?? []), + ...(graph.unchangedMobileSessionWorktrees ?? []) + ]) + const emptyPaneWorktrees = new Map() + const boundPtyIds = new Set() + for (const worktreeId of worktrees) { + const accepted = acceptedSnapshots.get(worktreeId) + for (const tab of snapshots.get(worktreeId)?.tabs ?? []) { + // Host-preserved tabs cannot stand in for a pane the renderer actually published. + if ( + tab.type !== 'terminal' || + !accepted?.rendererTabIdentityKeys.has(`${tab.parentTabId}::${tab.leafId}`) + ) { + continue + } + if (tab.ptyId) { + boundPtyIds.add(tab.ptyId) + } else if (isTerminalLeafId(tab.leafId)) { + emptyPaneWorktrees.set(`${tab.parentTabId}::${tab.leafId}`, worktreeId) + } + } + } + return { emptyPaneWorktrees, boundPtyIds } +} + +function indexRuntimeOwnedPanePtys( + ptys: Iterable, + isExited: (ptyId: string) => boolean +): Map { + const owners = new Map() + for (const pty of ptys) { + if (!pty.runtimeSessionOwned || !pty.paneKey || isExited(pty.ptyId)) { + continue + } + // Ambiguous host ownership cannot authorize choosing either process. + owners.set(pty.paneKey, owners.has(pty.paneKey) ? null : pty) + } + return owners +} + +export function createRuntimeOwnedPtyResolver( + ptys: Iterable, + isExited: (ptyId: string) => boolean, + incomingPtyIds: ReadonlySet +): RuntimeOwnedPtyResolver { + const hostOwnedPtys = indexRuntimeOwnedPanePtys(ptys, isExited) + return (pane, currentPtyId) => { + const pty = hostOwnedPtys.get(pane.paneKey) + // A pane claimed elsewhere in this graph, or already bound to a different PTY, is not retainable. + return pty?.worktreeId === pane.worktreeId && + pty.tabId === pane.tabId && + (!currentPtyId || currentPtyId === pty.ptyId) && + !incomingPtyIds.has(pty.ptyId) + ? pty.ptyId + : null + } +} + +export function chooseProjectedPtyId( + incomingPtyId: string | null, + existingPtyId: string | null | undefined, + preserveReload: boolean, + pane: RuntimePaneIdentity, + resolver: RuntimeOwnedPtyResolver +): string | null { + if (incomingPtyId) { + return incomingPtyId + } + const owned = resolver(pane, null) + if (owned && (!existingPtyId || existingPtyId === owned)) { + return owned + } + return preserveReload ? (existingPtyId ?? null) : null +} + +export function shouldPreservePublishedRuntimePane( + pane: RuntimePaneIdentity, + ptyId: string, + publishedWorktree: string | undefined, + publishedPtyIds: ReadonlySet, + resolver: RuntimeOwnedPtyResolver +): boolean { + return ( + publishedWorktree === pane.worktreeId && + !publishedPtyIds.has(ptyId) && + resolver(pane, ptyId) !== null + ) +} diff --git a/src/main/runtime/terminal-list-surface-lost-orphan.test.ts b/src/main/runtime/terminal-list-surface-lost-orphan.test.ts index eec898bc08db..dfb9d1fa8560 100644 --- a/src/main/runtime/terminal-list-surface-lost-orphan.test.ts +++ b/src/main/runtime/terminal-list-surface-lost-orphan.test.ts @@ -5,6 +5,7 @@ import type { WorkspaceSessionState } from '../../shared/workspace-session-state import type { TerminalLayoutSnapshot, TerminalTab } from '../../shared/terminal-tab-types' import { makePaneKey } from '../../shared/stable-pane-id' import { spawnSurfaceClaimSequence } from './pty-recorded-surface-topology' +import type { RuntimeMobileSessionTabsSnapshot } from '../../shared/runtime-types' // #18191: a terminal whose pane the graph dropped kept reporting `orphaned: false` with a // `tabId` no tab has — "field-for-field identical to a healthy one", so an operator polling @@ -97,10 +98,27 @@ function tab(tabId: string, activeLeafId: string) { return { tabId, worktreeId: WORKTREE_ID, title: '', activeLeafId, layout: null } } +class RuntimeWithOwnedPty extends OrcaRuntimeService { + markReloading(): void { + this.graphStatus = 'reloading' + } + projectedPty(tabId: string, leafId: string): string | null | undefined { + return this.leaves.get(this.getLeafKey(tabId, leafId))?.ptyId + } + + markRuntimeOwned(ptyId: string): void { + const pty = this.ptysById.get(ptyId) + if (!pty) { + throw new Error('Expected registered PTY') + } + pty.runtimeSessionOwned = true + } +} + /** Both PTYs stay live on the host throughout; only the graph changes. */ -function makeRuntime(session?: WorkspaceSessionState): OrcaRuntimeService { +function makeRuntime(session?: WorkspaceSessionState): RuntimeWithOwnedPty { // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: makeStore returns the repo and session reads this suite drives; the rest of Store is unreached. - const runtime = new OrcaRuntimeService(makeStore(session) as never) + const runtime = new RuntimeWithOwnedPty(makeStore(session) as never) // oxlint-disable-next-line typescript/consistent-type-assertions -- SAFETY: the stub carries the four controller members this suite drives; both PTYs stay live throughout. runtime.setPtyController({ spawn: vi.fn(async () => ({ id: 'never' })), @@ -253,3 +271,210 @@ describe('terminal inventory after a pane is dropped', () => { expect(byPty.get(KEPT_PTY)?.orphaned).toBe(false) }) }) + +describe('runtime-owned terminal projection gaps', () => { + it.each([false, true])( + 'adopts the host binding before a bound graph leaf exists (empty leaf: %s)', + async (emptyLeaf) => { + const runtime = makeRuntime() + runtime.syncWindowGraph(1, { + tabs: [tab('tab-kept', KEPT_LEAF), tab('tab-dropped', DROPPED_LEAF)], + leaves: [ + leaf('tab-kept', KEPT_LEAF, KEPT_PTY), + ...(emptyLeaf ? [{ ...leaf('tab-dropped', DROPPED_LEAF, DROPPED_PTY), ptyId: null }] : []) + ] + }) + runtime.registerPty(DROPPED_PTY, WORKTREE_ID, null, { + tabId: 'tab-dropped', + leafId: DROPPED_LEAF, + incarnationId: DROPPED_INCARNATION + }) + runtime.markRuntimeOwned(DROPPED_PTY) + const before = (await runtime.listTerminals(`id:${WORKTREE_ID}`)).terminals.find( + ({ ptyId }) => ptyId === DROPPED_PTY + ) + runtime.syncWindowGraph(1, { + tabs: [tab('tab-kept', KEPT_LEAF), tab('tab-dropped', DROPPED_LEAF)], + leaves: [ + leaf('tab-kept', KEPT_LEAF, KEPT_PTY), + { ...leaf('tab-dropped', DROPPED_LEAF, DROPPED_PTY), ptyId: null } + ] + }) + const after = (await runtime.listTerminals(`id:${WORKTREE_ID}`)).terminals.find( + ({ ptyId }) => ptyId === DROPPED_PTY + ) + expect(before).toBeDefined() + expect(after).toEqual(before) + expect(runtime.projectedPty('tab-dropped', DROPPED_LEAF)).toBe(DROPPED_PTY) + } + ) + + it('does not choose between two live host owners of the same pane', () => { + const runtime = makeRuntime() + runtime.markRuntimeOwned(DROPPED_PTY) + runtime.registerPty('competing-pty', WORKTREE_ID, null, { + tabId: 'tab-dropped', + leafId: DROPPED_LEAF, + incarnationId: 'competing-incarnation' + }) + runtime.markRuntimeOwned('competing-pty') + runtime.syncWindowGraph(1, { + tabs: [tab('tab-dropped', DROPPED_LEAF)], + leaves: [{ ...leaf('tab-dropped', DROPPED_LEAF, DROPPED_PTY), ptyId: null }] + }) + expect(runtime.projectedPty('tab-dropped', DROPPED_LEAF)).toBeNull() + }) + + it.each(['removed', 'replaced', 'moved'] as const)( + 'retains a published unmounted pane until it is explicitly %s', + async (change) => { + const session = sessionStillHoldingBothPanes() + session.terminalLayoutsByTabId['tab-dropped'].root = { type: 'leaf', leafId: DROPPED_LEAF } + const runtime = makeRuntime(session) + runtime.markRuntimeOwned(DROPPED_PTY) + const before = await runtime.listTerminals(`id:${WORKTREE_ID}`) + const snapshot: RuntimeMobileSessionTabsSnapshot = { + worktree: WORKTREE_ID, + publicationEpoch: 'test', + snapshotVersion: 1, + activeGroupId: null, + activeTabId: null, + activeTabType: null, + tabs: [ + { + type: 'terminal', + id: 'mobile-dropped', + title: 'Setup', + parentTabId: 'tab-dropped', + leafId: DROPPED_LEAF, + ptyId: null, + isActive: false, + parentLayout: { + root: { type: 'leaf', leafId: DROPPED_LEAF }, + activeLeafId: DROPPED_LEAF, + expandedLeafId: null + } + } + ] + } + const graph = { + tabs: [tab('tab-kept', KEPT_LEAF)], + leaves: [leaf('tab-kept', KEPT_LEAF, KEPT_PTY)] + } + runtime.syncWindowGraph(1, { ...graph, mobileSessionTabs: [snapshot] }) + runtime.markRuntimeOwned(DROPPED_PTY) + expect((await runtime.listTerminals(`id:${WORKTREE_ID}`)).terminals).toEqual(before.terminals) + runtime.syncWindowGraph(1, { + ...graph, + mobileSessionTabs: [], + unchangedMobileSessionWorktrees: [WORKTREE_ID] + }) + expect((await runtime.listTerminals(`id:${WORKTREE_ID}`)).terminals).toEqual(before.terminals) + runtime.syncWindowGraph(1, { + ...graph, + mobileSessionTabs: [ + { + ...snapshot, + snapshotVersion: 2, + tabs: + change === 'removed' + ? [] + : snapshot.tabs.map((surface) => ({ + ...surface, + ptyId: change === 'replaced' ? 'replacement-pty' : DROPPED_PTY, + ...(change === 'moved' ? { parentTabId: 'tab-moved', leafId: KEPT_LEAF } : {}) + })) + } + ] + }) + expect(runtime.projectedPty('tab-dropped', DROPPED_LEAF)).toBeUndefined() + if (change === 'removed') { + const result = await runtime.listTerminals(`id:${WORKTREE_ID}`) + expect(result.terminals.find(({ ptyId }) => ptyId === DROPPED_PTY)?.orphaned).toBe(true) + } + } + ) + + it.each(['unverifiable', 'exited', 'different-workspace', 'replacement'] as const)( + 'respects %s evidence while an existing pane publishes null', + async (scenario) => { + const runtime = makeRuntime() + runtime.markRuntimeOwned(DROPPED_PTY) + await runtime.listTerminals(`id:${WORKTREE_ID}`) + if (scenario === 'unverifiable') { + runtime.markPtyLivenessUnverifiable(DROPPED_PTY, 'host disconnected') + } else if (scenario === 'exited') { + await runtime.onPtyExit(DROPPED_PTY, 0, DROPPED_INCARNATION) + } + const worktreeId = scenario === 'different-workspace' ? 'folder:other' : WORKTREE_ID + const incomingPtyId = scenario === 'replacement' ? 'replacement-pty' : null + runtime.syncWindowGraph(1, { + tabs: [{ ...tab('tab-dropped', DROPPED_LEAF), worktreeId }], + leaves: [ + { ...leaf('tab-dropped', DROPPED_LEAF, DROPPED_PTY), worktreeId, ptyId: incomingPtyId } + ] + }) + expect(runtime.projectedPty('tab-dropped', DROPPED_LEAF)).toBe( + scenario === 'unverifiable' ? DROPPED_PTY : incomingPtyId + ) + } + ) + + it('does not reuse a previous workspace binding during renderer reload', () => { + const runtime = makeRuntime() + runtime.markRuntimeOwned(DROPPED_PTY) + runtime.markReloading() + runtime.syncWindowGraph(1, { + tabs: [{ ...tab('tab-dropped', DROPPED_LEAF), worktreeId: 'folder:other' }], + leaves: [ + { + ...leaf('tab-dropped', DROPPED_LEAF, DROPPED_PTY), + worktreeId: 'folder:other', + ptyId: null + } + ] + }) + expect(runtime.projectedPty('tab-dropped', DROPPED_LEAF)).toBeNull() + }) + + it('retains the exact live handle and surface while an existing pane publishes null', async () => { + const runtime = makeRuntime() + runtime.markRuntimeOwned(DROPPED_PTY) + const before = await runtime.listTerminals(`id:${WORKTREE_ID}`) + runtime.syncWindowGraph(1, { + tabs: [tab('tab-kept', KEPT_LEAF), tab('tab-dropped', DROPPED_LEAF)], + leaves: [ + leaf('tab-kept', KEPT_LEAF, KEPT_PTY), + { ...leaf('tab-dropped', DROPPED_LEAF, DROPPED_PTY), ptyId: null } + ] + }) + const after = await runtime.listTerminals(`id:${WORKTREE_ID}`) + expect(after.terminals).toEqual(before.terminals) + }) + + it('still reports a removed runtime-owned pane as orphaned', async () => { + const runtime = makeRuntime() + runtime.markRuntimeOwned(DROPPED_PTY) + await runtime.listTerminals(`id:${WORKTREE_ID}`) + dropOnePane(runtime) + const result = await runtime.listTerminals(`id:${WORKTREE_ID}`) + expect(result.terminals.find(({ ptyId }) => ptyId === DROPPED_PTY)?.orphaned).toBe(true) + }) + + it('does not duplicate a runtime-owned PTY explicitly moved to another pane', async () => { + const runtime = makeRuntime() + runtime.markRuntimeOwned(DROPPED_PTY) + await runtime.listTerminals(`id:${WORKTREE_ID}`) + runtime.syncWindowGraph(1, { + tabs: [tab('tab-kept', KEPT_LEAF), tab('tab-dropped', DROPPED_LEAF)], + leaves: [ + leaf('tab-kept', KEPT_LEAF, DROPPED_PTY), + { ...leaf('tab-dropped', DROPPED_LEAF, DROPPED_PTY), ptyId: null } + ] + }) + const result = await runtime.listTerminals(`id:${WORKTREE_ID}`) + expect(result.terminals.filter(({ ptyId }) => ptyId === DROPPED_PTY)).toEqual([ + expect.objectContaining({ tabId: 'tab-kept', leafId: KEPT_LEAF, orphaned: false }) + ]) + }) +}) diff --git a/tests/e2e/helpers/fake-codex-launch-probes.ts b/tests/e2e/helpers/fake-codex-launch-probes.ts index 45371a05ec95..9017089026e8 100644 --- a/tests/e2e/helpers/fake-codex-launch-probes.ts +++ b/tests/e2e/helpers/fake-codex-launch-probes.ts @@ -4,6 +4,10 @@ * `--no-daemon` support probe (`codex --help`) exits without advertising the flag. */ export const FAKE_CODEX_LAUNCH_PROBES_SOURCE = ` +if (process.argv.length === 3 && process.argv[2] === '--version') { + process.stdout.write('codex-cli 0.0.0\\n') + process.exit(0) +} if (process.argv.slice(2).includes('app-server')) { process.stderr.write("error: unrecognized subcommand 'app-server'\\n") process.exit(2) diff --git a/tests/e2e/live-background-terminal-mount-authority.spec.ts b/tests/e2e/live-background-terminal-mount-authority.spec.ts index 39735b0c1e88..4a9b6574b0a0 100644 --- a/tests/e2e/live-background-terminal-mount-authority.spec.ts +++ b/tests/e2e/live-background-terminal-mount-authority.spec.ts @@ -85,18 +85,12 @@ const test = base.extend({ ORCA_E2E_CANARY_LEDGER: canaryLedgerPath, ORCA_E2E_SIGNAL_LEDGER: signalLedgerPath }, - { option: true } + { scope: 'test' } ] }) function readSpawnLedger(): SpawnEvent[] { - if (!existsSync(spawnLedgerPath)) { - return [] - } - return readFileSync(spawnLedgerPath, 'utf8') - .split(/\r?\n/) - .filter(Boolean) - .map((line) => JSON.parse(line) as SpawnEvent) + return readJsonLines(spawnLedgerPath) } function readJsonLines(filePath: string): T[] { @@ -546,11 +540,14 @@ test('adopts runtime-owned agent and Setup PTYs on first mount', async ({ const state = window.__store?.getState() await state?.fetchRepos() const repo = window.__store?.getState().repos.find((candidate) => candidate.id === repoId) - if (!repo) { + if (!repo?.hookSettings) { return false } await window.__store?.getState().updateRepo(repoId, { - hookSettings: { ...repo.hookSettings, setupAgentStartupPolicy: 'start-immediately' } + hookSettings: { + ...repo.hookSettings, + setupAgentStartupPolicy: 'start-immediately' + } }) await window.__store?.getState().updateSettings({ agentCmdOverrides: { codex: command }, From 2c04ecf82195b6f3cfcede045e220befa9ebdb02 Mon Sep 17 00:00:00 2001 From: Neil Date: Tue, 6 Oct 2026 15:50:49 -0700 Subject: [PATCH 2/6] test: route new orchestration SQLite fixtures through Node --- config/scripts/vitest-sqlite-database-runtime-files.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/scripts/vitest-sqlite-database-runtime-files.mjs b/config/scripts/vitest-sqlite-database-runtime-files.mjs index 9098a6f566db..cec9f43adefd 100644 --- a/config/scripts/vitest-sqlite-database-runtime-files.mjs +++ b/config/scripts/vitest-sqlite-database-runtime-files.mjs @@ -1,5 +1,7 @@ // Database opening and lifecycle fixtures exercise Node SQLite behavior. export const SQLITE_DATABASE_RUNTIME_INCLUDE = [ + 'src/main/runtime/orchestration/orchestration-party-location.test.ts', + 'src/main/runtime/runtime-orchestration-sender-names.test.ts', 'src/main/ai-vault-search/session-search-file-write.test.ts', 'src/main/ai-vault-search/session-search-live-transcript.test.ts', 'src/main/ai-vault/session-scanner-devin-contention.test.ts', From 9d2cf39cb4b6dc872ce8832a39dc241d3aecf3de Mon Sep 17 00:00:00 2001 From: Neil Date: Tue, 6 Oct 2026 17:44:44 -0700 Subject: [PATCH 3/6] Use upstream SQLite runtime registrations without duplicates --- config/scripts/vitest-sqlite-database-runtime-files.mjs | 2 -- 1 file changed, 2 deletions(-) diff --git a/config/scripts/vitest-sqlite-database-runtime-files.mjs b/config/scripts/vitest-sqlite-database-runtime-files.mjs index cec9f43adefd..9098a6f566db 100644 --- a/config/scripts/vitest-sqlite-database-runtime-files.mjs +++ b/config/scripts/vitest-sqlite-database-runtime-files.mjs @@ -1,7 +1,5 @@ // Database opening and lifecycle fixtures exercise Node SQLite behavior. export const SQLITE_DATABASE_RUNTIME_INCLUDE = [ - 'src/main/runtime/orchestration/orchestration-party-location.test.ts', - 'src/main/runtime/runtime-orchestration-sender-names.test.ts', 'src/main/ai-vault-search/session-search-file-write.test.ts', 'src/main/ai-vault-search/session-search-live-transcript.test.ts', 'src/main/ai-vault/session-scanner-devin-contention.test.ts', From 0398f3d400d5c11a528c582cc34c4427fd10bf8e Mon Sep 17 00:00:00 2001 From: Neil Date: Tue, 6 Oct 2026 17:51:49 -0700 Subject: [PATCH 4/6] test: run real shell PTY fixtures in the Node runtime --- config/scripts/vitest-node-runtime-files.mjs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/scripts/vitest-node-runtime-files.mjs b/config/scripts/vitest-node-runtime-files.mjs index 791e38f209f7..7cbb2c8f02da 100644 --- a/config/scripts/vitest-node-runtime-files.mjs +++ b/config/scripts/vitest-node-runtime-files.mjs @@ -25,6 +25,9 @@ export const NODE_RUNTIME_INCLUDE = [ 'src/main/automations/automation-worker-durability.test.ts', 'src/**/*.node-pty.test.ts', 'src/**/node-pty-*.test.ts', + 'src/main/daemon/shell-ready.test.ts', + 'src/main/daemon/repro-13767-shell-ready-marker-lost-to-exec.test.ts', + 'src/main/shell-startup-feature-channel.test.ts', 'src/**/*.live-shell.test.ts', 'src/**/*real-pty*.test.ts', 'src/**/*-native.test.ts', From 9a79f6bbc4f5af8bf203b7eb78fa28dcfc6f0a5f Mon Sep 17 00:00:00 2001 From: Neil Date: Tue, 6 Oct 2026 17:59:50 -0700 Subject: [PATCH 5/6] Keep first-mount viewport probes within narrow terminal rows --- tests/e2e/live-background-terminal-mount-authority.spec.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e/live-background-terminal-mount-authority.spec.ts b/tests/e2e/live-background-terminal-mount-authority.spec.ts index 4a9b6574b0a0..02c449f92eea 100644 --- a/tests/e2e/live-background-terminal-mount-authority.spec.ts +++ b/tests/e2e/live-background-terminal-mount-authority.spec.ts @@ -754,7 +754,7 @@ test('adopts runtime-owned agent and Setup PTYs on first mount', async ({ await expect .poll(() => orcaPage.evaluate(() => window.api.pty.getRendererDeliveryDebugSnapshot())) .toMatchObject(postReloadDelivery) - const remountAgentLiveMarker = `AGENT_LIVE_${randomUUID()}` + const remountAgentLiveMarker = `AGENT_LIVE_${randomUUID().slice(0, 8)}` await client.call('terminal.send', { terminal: agent!.handle, text: remountAgentLiveMarker, @@ -768,7 +768,7 @@ test('adopts runtime-owned agent and Setup PTYs on first mount', async ({ expect( await orcaPage.evaluate(() => window.api.pty.getRendererDeliveryDebugSnapshot()) ).toMatchObject(postReloadDelivery) - const remountAgentAcceptedMarker = `AGENT_ACCEPTED_${randomUUID()}` + const remountAgentAcceptedMarker = `AGENT_ACCEPTED_${randomUUID().slice(0, 8)}` expect( await orcaPage.evaluate( ({ marker, ptyId }) => window.api.pty.writeAccepted(ptyId, `${marker}\r`, 'driving'), @@ -795,7 +795,7 @@ test('adopts runtime-owned agent and Setup PTYs on first mount', async ({ const remountedSetupPtyId = await waitForActivePanePtyId(orcaPage) expect(remountedSetupPtyId).toBe(setup!.ptyId) await enableTerminalAccessibility(orcaPage, setup!.tabId) - const remountSetupLiveMarker = `SETUP_LIVE_${randomUUID()}` + const remountSetupLiveMarker = `SETUP_LIVE_${randomUUID().slice(0, 8)}` await client.call('terminal.send', { terminal: setup!.handle, text: remountSetupLiveMarker, From 573a597645dc5071dbe8dd1f27411a477bd87ef5 Mon Sep 17 00:00:00 2001 From: Neil Date: Tue, 6 Oct 2026 18:20:38 -0700 Subject: [PATCH 6/6] Run the upstream agent launch database fixture in Node --- config/scripts/vitest-sqlite-database-runtime-files.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/config/scripts/vitest-sqlite-database-runtime-files.mjs b/config/scripts/vitest-sqlite-database-runtime-files.mjs index 9098a6f566db..e837c26efb27 100644 --- a/config/scripts/vitest-sqlite-database-runtime-files.mjs +++ b/config/scripts/vitest-sqlite-database-runtime-files.mjs @@ -34,6 +34,7 @@ export const SQLITE_DATABASE_RUNTIME_INCLUDE = [ 'src/main/runtime/claude-structured-session-integration.test.ts', 'src/main/runtime/claude-structured-startup-fault-is-not-an-exit.test.ts', 'src/main/runtime/exit-provenance-audit.test.ts', + 'src/main/runtime/rpc/methods/agent-launch-instant-tab.test.ts', 'src/main/runtime/orchestration-cli-subprocess.test.ts', 'src/main/runtime/orchestration-dispatch-mailbox-delivery.test.ts', 'src/main/runtime/orchestration-mailbox-crash-recovery.test.ts',