test(terminal): model resume record clear at PTY spawn

This commit is contained in:
Brennan Benson
2026-08-24 10:51:51 -07:00
parent 51f94a9a51
commit daf61ea013
3 changed files with 33 additions and 5 deletions
@@ -3,6 +3,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest'
import { useAppStore, type AppState } from '@/store'
import { activateAndRevealWorktree } from './worktree-activation'
import { makeCreatedAgentWorktree as makeWorktree } from '@/lib/worktree-activation-created-agent-test-state'
import { consumeQueuedStartupAndClearSleepingRecord } from '@/components/terminal-pane/use-terminal-pane-lifecycle'
const initialAppStoreState = useAppStore.getState()
@@ -89,12 +90,26 @@ describe('STA-1111 worktree reopen does not fork-bomb tabs', () => {
expect(state.automaticAgentResumeClaimsByTabId[tabs[0]!.id]?.providerSession).toEqual(
providerSession
)
expect(state.sleepingAgentSessionsByPaneKey[paneKey]).toBeUndefined()
// Activation queues the replacement; the record is cleared only after
// its first PTY spawn consumes that startup command.
if (reopen === 0) {
expect(state.consumeTabStartupCommand(tabs[0]!.id)?.resumeProviderSession).toEqual(
providerSession
expect(state.sleepingAgentSessionsByPaneKey[paneKey]).toBeDefined()
const consumed = state.consumeTabStartupCommand(tabs[0]!.id)
expect(consumed?.resumeProviderSession).toEqual(providerSession)
// The real pane lifecycle invokes this on the fresh PTY boundary.
consumeQueuedStartupAndClearSleepingRecord(
tabs[0]!.id,
() => consumed,
(identityPaneKey) =>
useAppStore.getState().sleepingAgentSessionsByPaneKey[identityPaneKey],
useAppStore.getState().clearSleepingAgentSession
)
expect(useAppStore.getState().sleepingAgentSessionsByPaneKey[paneKey]).toBeUndefined()
} else {
// Later captures are stale replays of the already claimed session and
// are discarded without forking another replacement tab.
expect(state.sleepingAgentSessionsByPaneKey[paneKey]).toBeUndefined()
}
}
})
@@ -3,6 +3,7 @@ import { afterEach, beforeEach, expect, vi } from 'vitest'
import type { PublicKnownRuntimeEnvironment } from '../../../shared/runtime-environments'
import { makePaneKey } from '../../../shared/stable-pane-id'
import { resetStaleDocumentVisibilityForTesting } from '@/components/terminal-pane/stale-document-visibility'
import { consumeQueuedStartupAndClearSleepingRecord } from '@/components/terminal-pane/use-terminal-pane-lifecycle'
import { useAppStore, type AppState } from '@/store'
import {
BG_MIRROR_TAB_ID,
@@ -155,7 +156,6 @@ export function tabIds(worktreeId: string): string[] {
* consumed the record launched nothing. */
export function expectReplayedResume(paneKey: string, worktreeId: string, sessionId: string): void {
const state = useAppStore.getState()
expect(state.sleepingAgentSessionsByPaneKey[paneKey]).toBeUndefined()
const claimedTabIds = Object.keys(state.automaticAgentResumeClaimsByTabId)
expect(claimedTabIds).toHaveLength(1)
const replacementTabId = claimedTabIds[0]!
@@ -165,6 +165,18 @@ export function expectReplayedResume(paneKey: string, worktreeId: string, sessio
launchAgent: 'codex',
providerSession: { key: 'session_id', id: sessionId }
})
// The mirror verdict only justifies the replacement launch. The sleeping
// record remains retryable until the replacement's first PTY spawn consumes
// its queued startup; model that concrete execution-host boundary here.
expect(state.sleepingAgentSessionsByPaneKey[paneKey]).toBeDefined()
consumeQueuedStartupAndClearSleepingRecord(
replacementTabId,
state.consumeTabStartupCommand,
(identityPaneKey) => useAppStore.getState().sleepingAgentSessionsByPaneKey[identityPaneKey],
useAppStore.getState().clearSleepingAgentSession
)
expect(useAppStore.getState().sleepingAgentSessionsByPaneKey[paneKey]).toBeUndefined()
}
/** Registers the shared harness reset for the receipt-era describe blocks. */
@@ -138,7 +138,6 @@ describe('mirrored-pane resume deferral against real stream frames', () => {
// claims the session. Asserting only the record would pass for a replay
// that cleared it and launched nothing.
const replayed = useAppStore.getState()
expect(replayed.sleepingAgentSessionsByPaneKey[backgroundPaneKey]).toBeUndefined()
const backgroundTabIds = tabIds(BG_WT)
expect(backgroundTabIds).toHaveLength(1)
expect(backgroundTabIds[0]).not.toBe(BG_MIRROR_TAB_ID)
@@ -146,6 +145,8 @@ describe('mirrored-pane resume deferral against real stream frames', () => {
launchAgent: 'codex',
providerSession: { key: 'session_id', id: 'codex-session-bg-1' }
})
expect(replayed.sleepingAgentSessionsByPaneKey[backgroundPaneKey]).toBeDefined()
expectReplayedResume(backgroundPaneKey, BG_WT, 'codex-session-bg-1')
})
// The three tests below pin the remaining release sites one frame at a time: