refactor(renderer): remove the web-session-tabs-sync barrel (#27969)

Co-authored-by: m4air <m4air@Mac.localdomain>
This commit is contained in:
OrcaWin
2026-10-12 05:30:29 -07:00
committed by GitHub
co-authored by m4air
parent 41fc9542b3
commit f8daed0d98
63 changed files with 351 additions and 266 deletions
+2 -2
View File
@@ -36,7 +36,7 @@ describe('restart-survival E2E routing', () => {
'src/main/runtime/rpc/methods/browser-client-host.ts',
'src/main/browser/browser-client-host-authority-replacement-wait.ts',
'src/main/browser/paired-runtime-browser-client-host-composition.ts',
'src/renderer/src/runtime/web-session-tabs-sync.ts',
'src/renderer/src/runtime/web-session-tabs-sync/snapshot-api.ts',
'src/renderer/src/runtime/host-session-snapshot-authority.ts',
'src/renderer/src/runtime/restored-client-hosted-browser-host-attach.ts',
'src/renderer/src/store/slices/runtime-status.ts',
@@ -131,7 +131,7 @@ describe('PR E2E gate contract', () => {
'src/renderer/src/components/terminal-pane/terminal-error-accumulation.ts',
'src/renderer/src/runtime/web-runtime-terminal-creation.ts',
'src/renderer/src/runtime/web-runtime-session-tab-lifecycle.ts',
'src/renderer/src/runtime/web-session-tabs-sync.ts',
'src/renderer/src/runtime/web-session-tabs-sync/use-web-session-tabs-sync.ts',
'src/renderer/src/runtime/web-session-terminal-orphan-recovery.ts',
'src/renderer/src/runtime/web-session-terminal-orphan-recovery-adoption.ts',
'src/renderer/src/runtime/web-session-terminal-orphan-recovery-surface.ts',
@@ -35,7 +35,7 @@ const STACK_WRITERS = [
'src/renderer/src/store/slices/terminals.ts',
'src/renderer/src/components/terminal-pane/TerminalPane.tsx',
'src/renderer/src/runtime/sync-runtime-graph.ts',
'src/renderer/src/runtime/web-session-tabs-sync.ts',
'src/renderer/src/runtime/web-session-tabs-sync/store-patch.ts',
'src/main/runtime/orca-runtime-split-terminal.ts',
'src/main/runtime/orca-runtime-sync-window-graph.ts',
'src/main/runtime/mobile-session-layout-projection.ts',
+2 -2
View File
@@ -337,7 +337,7 @@ export const PR_E2E_SOURCE_ROUTES = [
specs: ['tests/e2e/paired-remote-terminal-serve-restart-binding.spec.ts'],
matches: (file) =>
isProductSource(file) &&
/^(?:src\/main\/daemon\/(?:daemon-attach-only-retirement|daemon-pty-applied-size|daemon-pty-session-control|daemon-pty-spawn-result)\.ts|src\/renderer\/src\/components\/terminal-pane\/(?:remote-runtime-pty-transport|terminal-error-accumulation)\.ts|src\/renderer\/src\/runtime\/(?:web-runtime-terminal-creation|web-runtime-session-tab-lifecycle|web-session-tabs-sync|web-session-terminal-orphan-(?:topology|recovery(?:-(?:adoption|surface|inventory|inventory-validation|cache|queue|rpc-lane|pane))?))\.ts)$/.test(
/^(?:src\/main\/daemon\/(?:daemon-attach-only-retirement|daemon-pty-applied-size|daemon-pty-session-control|daemon-pty-spawn-result)\.ts|src\/renderer\/src\/components\/terminal-pane\/(?:remote-runtime-pty-transport|terminal-error-accumulation)\.ts|src\/renderer\/src\/runtime\/(?:web-runtime-terminal-creation|web-runtime-session-tab-lifecycle|web-session-tabs-sync\/use-web-session-tabs-sync|web-session-terminal-orphan-(?:topology|recovery(?:-(?:adoption|surface|inventory|inventory-validation|cache|queue|rpc-lane|pane))?))\.ts)$/.test(
file
)
},
@@ -367,7 +367,7 @@ export const PR_E2E_SOURCE_ROUTES = [
specs: ['tests/e2e/paired-remote-pane-layout-retry.spec.ts'],
matches: (file) =>
isProductSource(file) &&
/^(?:src\/renderer\/src\/components\/terminal-pane\/(?:remote-pane-layout-push|TerminalPane)\.tsx?|src\/renderer\/src\/lib\/terminal-layout-equality\.ts|src\/renderer\/src\/runtime\/web-session-tabs-sync\.ts|src\/renderer\/src\/store\/slices\/terminals\.ts)$/.test(
/^(?:src\/renderer\/src\/components\/terminal-pane\/(?:remote-pane-layout-push|TerminalPane)\.tsx?|src\/renderer\/src\/lib\/terminal-layout-equality\.ts|src\/renderer\/src\/runtime\/web-session-tabs-sync\/use-web-session-tabs-sync\.ts|src\/renderer\/src\/store\/slices\/terminals\.ts)$/.test(
file
)
},
@@ -25,7 +25,7 @@ describe('unit support routing', () => {
(unitHarness) => {
for (const file of [
'src/renderer/src/runtime/web-session-tabs-sync-next-test-harness.ts',
'src/renderer/src/runtime/web-session-tabs-sync.ts',
'src/renderer/src/runtime/web-session-tabs-sync/snapshot-api.ts',
'src/renderer/src/components/native-chat/NativeChatStructuredSession.next-test-harness.tsx',
'src/renderer/src/components/native-chat/NativeChatStructuredSession.tsx',
'src/main/providers/windows-conpty-wide-char-duplication.node-pty.test.ts',
@@ -50,7 +50,7 @@ describe('unit support routing', () => {
const spec = 'tests/e2e/paired-client-hosted-browser-restart-survival.spec.ts'
for (const file of [
'src/renderer/src/runtime/web-session-tabs-sync-next-test-harness.ts',
'src/renderer/src/runtime/web-session-tabs-sync.ts',
'src/renderer/src/runtime/web-session-tabs-sync/snapshot-api.ts',
spec
]) {
expect(selectPrE2eSpecs([harness, file]), file).toContain(spec)
@@ -14,7 +14,7 @@ import {
import { useRadixBodyPointerEventsRecovery } from '../hooks/useRadixBodyPointerEventsRecovery'
import { useGitStatusPolling } from '../components/right-sidebar/useGitStatusPolling'
import { useOsc52ClipboardDefaultOnNotice } from '../components/terminal-pane/osc52-clipboard-default-on-notice'
import { useWebSessionTabsSync } from '../runtime/web-session-tabs-sync'
import { useWebSessionTabsSync } from '../runtime/web-session-tabs-sync/use-web-session-tabs-sync'
import { useLocalStructuredSessionTabsSync } from '../runtime/local-structured-session-tabs-sync'
import { useHostStructuredAgentsSync } from '../runtime/host-structured-agents-sync'
import { useHostModelCatalogSnapshotsSync } from '../runtime/host-model-catalog-snapshots-sync'
@@ -43,8 +43,10 @@ vi.mock('@/runtime/web-terminal-surface-id', () => ({
toHostSessionTabId: vi.fn((tabId: string) => tabId)
}))
vi.mock('@/runtime/web-session-tabs-sync', () => ({
getLatestWebSessionTabsPublicationEpoch: vi.fn(() => 'epoch-1'),
vi.mock('@/runtime/web-session-tabs-sync/tracking-lifecycle', () => ({
getLatestWebSessionTabsPublicationEpoch: vi.fn(() => 'epoch-1')
}))
vi.mock('@/runtime/web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: resolveHostSessionTabIdForWebSessionTabMock
}))
@@ -26,7 +26,7 @@ vi.mock('@/runtime/web-terminal-surface-id', () => ({
toHostSessionTabId: vi.fn((tabId: string) => tabId)
}))
vi.mock('@/runtime/web-session-tabs-sync', () => ({
vi.mock('@/runtime/web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: vi.fn(() => null)
}))
@@ -23,8 +23,10 @@ vi.mock('@/runtime/web-terminal-surface-id', () => ({
toHostSessionTabId: vi.fn((tabId: string) => tabId)
}))
vi.mock('@/runtime/web-session-tabs-sync', () => ({
getLatestWebSessionTabsPublicationEpoch: vi.fn(() => null),
vi.mock('@/runtime/web-session-tabs-sync/tracking-lifecycle', () => ({
getLatestWebSessionTabsPublicationEpoch: vi.fn(() => null)
}))
vi.mock('@/runtime/web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: vi.fn(() => null)
}))
@@ -21,8 +21,10 @@ vi.mock('@/runtime/web-terminal-surface-id', () => ({
toHostSessionTabId: (tabId: string) => tabId
}))
vi.mock('@/runtime/web-session-tabs-sync', () => ({
getLatestWebSessionTabsPublicationEpoch: () => null,
vi.mock('@/runtime/web-session-tabs-sync/tracking-lifecycle', () => ({
getLatestWebSessionTabsPublicationEpoch: () => null
}))
vi.mock('@/runtime/web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: () => null
}))
@@ -43,8 +43,10 @@ vi.mock('@/runtime/web-terminal-surface-id', () => ({
toHostSessionTabId: toHostSessionTabIdMock
}))
vi.mock('@/runtime/web-session-tabs-sync', () => ({
getLatestWebSessionTabsPublicationEpoch: getLatestWebSessionTabsPublicationEpochMock,
vi.mock('@/runtime/web-session-tabs-sync/tracking-lifecycle', () => ({
getLatestWebSessionTabsPublicationEpoch: getLatestWebSessionTabsPublicationEpochMock
}))
vi.mock('@/runtime/web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: resolveHostSessionTabIdForWebSessionTabMock
}))
@@ -2,10 +2,8 @@ import { useAppStore } from '@/store'
import { closeWebRuntimeSessionTab } from '@/runtime/web-runtime-session-tab-lifecycle'
import { isWebRuntimeSessionActive } from '@/runtime/web-runtime-session-environment'
import { toHostSessionTabId } from '@/runtime/web-terminal-surface-id'
import {
getLatestWebSessionTabsPublicationEpoch,
resolveHostSessionTabIdForWebSessionTab
} from '@/runtime/web-session-tabs-sync'
import { getLatestWebSessionTabsPublicationEpoch } from '@/runtime/web-session-tabs-sync/tracking-lifecycle'
import { resolveHostSessionTabIdForWebSessionTab } from '@/runtime/web-session-tabs-sync/tracking-mappings'
import { resolveTerminalCloseRoute } from '@/lib/terminal-close-route'
import {
guardPinnedTabClose,
@@ -39,8 +39,10 @@ vi.mock('@/runtime/web-terminal-surface-id', () => ({
toHostSessionTabId: vi.fn((tabId: string) => tabId)
}))
vi.mock('@/runtime/web-session-tabs-sync', () => ({
getLatestWebSessionTabsPublicationEpoch: vi.fn(() => 'epoch-1'),
vi.mock('@/runtime/web-session-tabs-sync/tracking-lifecycle', () => ({
getLatestWebSessionTabsPublicationEpoch: vi.fn(() => 'epoch-1')
}))
vi.mock('@/runtime/web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: resolveHostSessionTabIdForWebSessionTabMock
}))
@@ -3,7 +3,7 @@ import { tabHasLivePty } from '@/lib/tab-has-live-pty'
import { createWebRuntimeSessionTerminal } from '@/runtime/web-runtime-terminal-creation'
import { isWebRuntimeSessionActive } from '@/runtime/web-runtime-session-environment'
import { isWebTerminalSurfaceTabId } from '@/runtime/web-terminal-surface-id'
import { getLastKnownHostTerminalTabCount } from '@/runtime/web-session-tabs-sync'
import { getLastKnownHostTerminalTabCount } from '@/runtime/web-session-tabs-sync/tracking-lifecycle'
import {
beginWebRuntimeWakeTerminalRespawn,
endWebRuntimeWakeTerminalRespawn
@@ -3,7 +3,7 @@ import { getDefaultSettings } from '../../../shared/constants'
import { useAppStore } from '@/store'
import { activateAndRevealWorktree } from './worktree-activation'
import { ensureWebRuntimeWorktreeTerminalAfterWake } from './web-runtime-worktree-terminal-after-wake'
import { resetWebSessionTabsSnapshotFreshnessForTests } from '@/runtime/web-session-tabs-sync'
import { resetWebSessionTabsSnapshotFreshnessForTests } from '@/runtime/web-session-tabs-sync/tracking-lifecycle'
import { resetWebRuntimeWakeTerminalRespawnForTests } from '@/runtime/web-runtime-wake-terminal-respawn'
import {
makeCreatedAgentWorktree as makeWorktree,
@@ -494,7 +494,8 @@ describe('activateAndRevealWorktree', () => {
}))
})
const { shouldApplyWebSessionTabsSnapshot } = await import('@/runtime/web-session-tabs-sync')
const { shouldApplyWebSessionTabsSnapshot } =
await import('@/runtime/web-session-tabs-sync/tracking-decisions')
shouldApplyWebSessionTabsSnapshot(
{
worktree: worktree.id,
@@ -3,7 +3,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest'
import { getDefaultSettings } from '../../../shared/constants'
import type { Worktree } from '../../../shared/worktree/types'
import { resetWebRuntimeWakeTerminalRespawnForTests } from '@/runtime/web-runtime-wake-terminal-respawn'
import { resetWebSessionTabsSnapshotFreshnessForTests } from '@/runtime/web-session-tabs-sync'
import { resetWebSessionTabsSnapshotFreshnessForTests } from '@/runtime/web-session-tabs-sync/tracking-lifecycle'
import { useAppStore } from '@/store'
import { ensureWebRuntimeWorktreeTerminalAfterWake } from './web-runtime-worktree-terminal-after-wake'
import { toast } from 'sonner'
@@ -117,6 +117,12 @@ describe('empty remote worktree activation', () => {
})
)
expect(toast.error).not.toHaveBeenCalled()
// Why: drain the post-create snapshot refresh so it cannot land on the next test's bridge.
await vi.waitFor(() =>
expect(callRuntimeEnvironment).toHaveBeenCalledWith(
expect.objectContaining({ method: 'session.tabs.list' })
)
)
})
it('surfaces a failed host terminal request without retrying ambiguously', async () => {
@@ -24,7 +24,7 @@ import {
} from './host-session-mirror-frame-fixtures'
import { resetHostSessionMirrorHydrationForTests } from './host-session-mirror-hydration'
import { replaceRuntimeEnvironmentRevisions } from './runtime-environment-revision'
import { resetWebSessionTabsSnapshotFreshnessForTests } from './web-session-tabs-sync'
import { resetWebSessionTabsSnapshotFreshnessForTests } from './web-session-tabs-sync/tracking-lifecycle'
const initialState = useAppStore.getInitialState()
@@ -70,11 +70,9 @@ import {
setDocumentVisibility,
tabIds
} from './host-session-mirror-frame-ordering-harness'
import {
clearWebSessionTabsTrackingForEnvironment,
useWebSessionTabsSync,
WEB_SESSION_TABS_VISIBILITY_RESUME_STAGGER_MS
} from './web-session-tabs-sync'
import { clearWebSessionTabsTrackingForEnvironment } from './web-session-tabs-sync/tracking-lifecycle'
import { useWebSessionTabsSync } from './web-session-tabs-sync/use-web-session-tabs-sync'
import { WEB_SESSION_TABS_VISIBILITY_RESUME_STAGGER_MS } from './web-session-tabs-sync/state'
import { hasHostSessionMirrorHydrated } from './host-session-mirror-hydration'
import { WINDOW_VISIBILITY_SUBSCRIPTION_PARK_DELAY_MS } from './window-visibility-subscription-parking'
@@ -72,11 +72,9 @@ import {
hasHostSessionMirrorHydrated
} from './host-session-mirror-hydration'
import { refreshWebRuntimeSessionTabsSnapshot } from './web-runtime-session-snapshot'
import {
clearWebSessionTabsTrackingForEnvironment,
useWebSessionTabsSync,
WEB_SESSION_TABS_VISIBILITY_RESUME_STAGGER_MS
} from './web-session-tabs-sync'
import { clearWebSessionTabsTrackingForEnvironment } from './web-session-tabs-sync/tracking-lifecycle'
import { useWebSessionTabsSync } from './web-session-tabs-sync/use-web-session-tabs-sync'
import { WEB_SESSION_TABS_VISIBILITY_RESUME_STAGGER_MS } from './web-session-tabs-sync/state'
import { WINDOW_VISIBILITY_SUBSCRIPTION_PARK_DELAY_MS } from './window-visibility-subscription-parking'
/**
@@ -2,7 +2,8 @@ import { afterEach, describe, expect, it } from 'vitest'
import type { RuntimeMobileSessionTabsResult } from '../../../shared/runtime-types'
import type { Tab } from '../../../shared/tab-types'
import { projectLocalStructuredSessionTabs } from './local-structured-session-tabs-sync'
import { applyWebSessionTabsSnapshot, type WebSessionTabsSyncState } from './web-session-tabs-sync'
import { applyWebSessionTabsSnapshot } from './web-session-tabs-sync/snapshot-api'
import type { WebSessionTabsSyncState } from './web-session-tabs-sync/state'
import { collectClientLayoutGroupIds } from './web-session-client-owned-tab-placement'
import { resetWebSessionFocusIntentForTests } from './web-session-focus-intent'
@@ -17,7 +17,7 @@ import {
resetLocalStructuredSessionVersionForTests
} from './local-structured-session-tabs-sync'
import { localStructuredSessionEpochHistoryByWorktree } from './local-structured-session-tabs-sync/inventory-generation-fence'
import type { WebSessionTabsSyncState } from './web-session-tabs-sync'
import type { WebSessionTabsSyncState } from './web-session-tabs-sync/state'
import { resetWebSessionFocusIntentForTests } from './web-session-focus-intent'
const WORKTREE = 'folder:ws-1'
@@ -18,8 +18,8 @@ import {
applyLocalStructuredSessionTabSnapshots,
resetLocalStructuredSessionVersionForTests
} from './local-structured-session-tabs-sync'
import type { WebSessionTabsSyncState } from './web-session-tabs-sync'
import { resetWebSessionTabsSnapshotFreshnessForTests } from './web-session-tabs-sync'
import type { WebSessionTabsSyncState } from './web-session-tabs-sync/state'
import { resetWebSessionTabsSnapshotFreshnessForTests } from './web-session-tabs-sync/tracking-lifecycle'
const WORKTREE = 'repo-1::/tmp/wt-reveal'
const HOST_TAB_ID = 'agent-session:codex-reveal-1'
@@ -1,6 +1,6 @@
import type { WorktreeRuntimeOwnerState } from '../lib/worktree-runtime-owner'
import { folderWorkspaceKey } from '../../../shared/workspace-scope'
import type { WebSessionTabsSyncState } from './web-session-tabs-sync'
import type { WebSessionTabsSyncState } from './web-session-tabs-sync/state'
export type StructuredSessionTabPublicationVersion = {
publicationEpoch: string
@@ -6,7 +6,8 @@ import {
applyLocalStructuredSessionTabSnapshots,
projectLocalStructuredSessionTabs
} from './local-structured-session-tabs-sync'
import { applyWebSessionTabsSnapshot, type WebSessionTabsSyncState } from './web-session-tabs-sync'
import { applyWebSessionTabsSnapshot } from './web-session-tabs-sync/snapshot-api'
import type { WebSessionTabsSyncState } from './web-session-tabs-sync/state'
import {
ENV,
HOST_SURFACE_ID,
@@ -14,11 +14,9 @@ import {
resetLocalStructuredSessionVersionForTests,
startLocalStructuredSessionTabsSync
} from './local-structured-session-tabs-sync'
import {
applyWebSessionTabsSnapshot,
resetWebSessionTabsSnapshotFreshnessForTests,
type WebSessionTabsSyncState
} from './web-session-tabs-sync'
import { applyWebSessionTabsSnapshot } from './web-session-tabs-sync/snapshot-api'
import { resetWebSessionTabsSnapshotFreshnessForTests } from './web-session-tabs-sync/tracking-lifecycle'
import type { WebSessionTabsSyncState } from './web-session-tabs-sync/state'
import {
recordWebSessionFocusIntent,
resetWebSessionFocusIntentForTests
@@ -5,11 +5,9 @@ import type {
import { markStructuredAgentSessionLaunchesPublished } from '../../lib/structured-agent-session-launch-publication'
import type { WorktreeRuntimeOwnerState } from '../../lib/worktree-runtime-owner'
import { getExecutionHostIdForWorktree } from '../../lib/worktree-runtime-owner'
import {
applyWebSessionTabsSnapshot,
applyWebSessionTabsStorePatch
} from '../web-session-tabs-sync'
import type { WebSessionTabsSyncState } from '../web-session-tabs-sync'
import { applyWebSessionTabsSnapshot } from '../web-session-tabs-sync/snapshot-api'
import { applyWebSessionTabsStorePatch } from '../web-session-tabs-sync/store-patch'
import type { WebSessionTabsSyncState } from '../web-session-tabs-sync/state'
import {
admitRetiredValueUnderAuthority,
noteRetiredValue,
@@ -13,11 +13,9 @@ import {
applyLocalStructuredSessionTabSnapshots,
resetLocalStructuredSessionVersionForTests
} from './local-structured-session-tabs-sync'
import {
applyWebSessionTabsSnapshot,
resetWebSessionTabsSnapshotFreshnessForTests,
type WebSessionTabsSyncState
} from './web-session-tabs-sync'
import { applyWebSessionTabsSnapshot } from './web-session-tabs-sync/snapshot-api'
import { resetWebSessionTabsSnapshotFreshnessForTests } from './web-session-tabs-sync/tracking-lifecycle'
import type { WebSessionTabsSyncState } from './web-session-tabs-sync/state'
const WORKTREE_ID = 'repo-1::worktree-1'
const TERMINAL_ID = 'terminal-1'
@@ -24,7 +24,7 @@ import {
selectRuntimeSessionMirrorTargetInputs,
useRuntimeSessionMirrorEnvironmentKeys
} from './use-runtime-session-mirror-environment-key'
import { useWebSessionTabsSync } from './web-session-tabs-sync'
import { useWebSessionTabsSync } from './web-session-tabs-sync/use-web-session-tabs-sync'
const initialState = useAppStore.getInitialState()
@@ -21,12 +21,18 @@ vi.mock('../store', () => ({
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: vi.fn(),
applyWebSessionTabsSnapshot: vi.fn(),
decideWebSessionTabsSnapshot: vi.fn(() => ({ apply: true, settlesHostMirror: true })),
getWebSessionTabsTrackingGeneration: vi.fn(() => 0),
applyWebSessionTabsStorePatch: vi.fn(() => () => {}),
getWebSessionTabsTrackingGeneration: vi.fn(() => 0)
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({ applyWebSessionTabsSnapshot: vi.fn() }))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: vi.fn(() => ({ apply: true, settlesHostMirror: true }))
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: vi.fn(() => () => {})
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: vi.fn()
}))
@@ -5,7 +5,7 @@ import type { Tab, TabGroup } from '../../../shared/tab-types'
import type { ExecutionHostId } from '../../../shared/execution-host'
import { useAppStore } from '../store'
import type { AppState } from '../store/types'
import { applyWebSessionTabsSnapshot } from './web-session-tabs-sync'
import { applyWebSessionTabsSnapshot } from './web-session-tabs-sync/snapshot-api'
import { ENV, NOW, WT, makeSnapshot } from './web-session-tabs-sync-test-harness'
export const HOST: ExecutionHostId = `runtime:${ENV}`
@@ -47,16 +47,24 @@ vi.mock('../store', () => ({
subscribe: mocks.subscribe
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
// The production caller invokes the returned settle receipt.
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
vi.mock('@/lib/feature-education-telemetry', () => ({
@@ -41,16 +41,24 @@ vi.mock('../store', () => ({
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
// The production caller invokes the returned settle receipt.
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
@@ -43,16 +43,24 @@ vi.mock('../store', () => ({
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
// The production caller invokes the returned settle receipt.
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
@@ -44,16 +44,24 @@ vi.mock('../store', () => ({
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
// The production caller invokes the returned settle receipt.
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
@@ -48,16 +48,24 @@ vi.mock('../store', () => ({
subscribe: mocks.subscribe
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
// The production caller invokes the returned settle receipt.
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
vi.mock('@/lib/feature-education-telemetry', () => ({
@@ -48,16 +48,24 @@ vi.mock('../store', () => ({
subscribe: mocks.subscribe
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
// The production caller invokes the returned settle receipt.
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
vi.mock('@/lib/feature-education-telemetry', () => ({
@@ -44,16 +44,24 @@ vi.mock('../store', () => ({
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
// The production caller invokes the returned settle receipt.
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
@@ -47,15 +47,23 @@ vi.mock('../store', () => ({
subscribe: mocks.subscribe
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
vi.mock('@/lib/feature-education-telemetry', () => ({
@@ -13,8 +13,8 @@ import { captureRuntimeEnvironmentCall } from './web-runtime-session-environment
import { throwIfE2eWebRuntimeBrowserReconciliationFails } from './web-runtime-browser-creation-e2e-fault'
import { getSessionTabsRuntimeIdFromResponse } from './web-session-tabs-sync/publisher-identity-fences'
import { WEB_SESSION_TABS_FRAME_OUTRANKED } from './web-session-tabs-sync/tracking-decisions'
// Not through the barrel: receipt ordering is this path's gate, not an optional collaborator a
// caller's module mock may leave out — doing so is what left this path unordered to begin with.
// Imported statically, not lazily: receipt ordering is this path's gate, not an optional
// collaborator a caller's module mock may leave out — doing so is what left this path unordered.
import {
recordReceivedWebSessionTabsSnapshot,
shouldApplyRecoveredWebSessionTabsSnapshot
@@ -39,20 +39,31 @@ export async function refreshWebRuntimeSessionTabsSnapshot(
errorMode?: 'warn' | 'throw'
} = {}
): Promise<void> {
const webSessionTabsSync = await import('./web-session-tabs-sync')
// Why one await up front: the apply below must not yield between the list and its receipt.
const [
{ applyWebSessionTabsSnapshot },
{ applyWebSessionTabsStorePatch },
{ decideWebSessionTabsSnapshot },
{ getWebSessionTabsTrackingGeneration }
] = await Promise.all([
import('./web-session-tabs-sync/snapshot-api'),
import('./web-session-tabs-sync/store-patch'),
import('./web-session-tabs-sync/tracking-decisions'),
import('./web-session-tabs-sync/tracking-lifecycle')
])
const expectedEnvironmentPairingRevision =
options.expectedEnvironmentPairingRevision ?? getRuntimeEnvironmentRevision(environmentId)
const expectedEnvironmentConnectionGeneration =
getRuntimeEnvironmentConnectionGeneration(environmentId)
const expectedTrackingGeneration =
webSessionTabsSync.getWebSessionTabsTrackingGeneration(environmentId)
const expectedTrackingGeneration = getWebSessionTabsTrackingGeneration(environmentId)
const callEnvironment = captureRuntimeEnvironmentCall(
environmentId,
expectedEnvironmentPairingRevision
)
try {
if (options.acceptCurrentSnapshot) {
const { acceptReplayedWebSessionTabsSnapshot } = await import('./web-session-tabs-sync')
const { acceptReplayedWebSessionTabsSnapshot } =
await import('./web-session-tabs-sync/tracking-lifecycle')
// Why: the host snapshot may have arrived before structured create returned;
// re-accept its current version after the exact provisional handoff is known.
acceptReplayedWebSessionTabsSnapshot(environmentId, worktreeId)
@@ -93,11 +104,6 @@ export async function refreshWebRuntimeSessionTabsSnapshot(
...options.confirmAgentSessionHandoff
})
}
const {
applyWebSessionTabsSnapshot,
applyWebSessionTabsStorePatch,
decideWebSessionTabsSnapshot
} = webSessionTabsSync
// A list is evidence about a moment, not about now. Record its place in receipt order before
// ranking it, or a snapshot the host answered before a close lands after the retraction did.
recordReceivedWebSessionTabsSnapshot(
@@ -1,4 +1,5 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import type * as TrackingDecisions from './web-session-tabs-sync/tracking-decisions'
import {
activateWebRuntimeSessionTab,
closeWebRuntimeSessionTab
@@ -47,16 +48,25 @@ vi.mock('../store', () => ({
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', async (importOriginal) => ({
...(await importOriginal<typeof TrackingDecisions>()),
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
// The production caller invokes the returned settle receipt.
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
@@ -113,7 +113,8 @@ async function callWebRuntimeSessionTabMethod(
if (isLifecycleClose && (!args.publicationEpoch || !args.terminalHandle)) {
// Why: missing host-generation or terminal-incarnation evidence means keep;
// a tab id alone can be stale or reused after reconnect.
const { acceptReplayedWebSessionTabsSnapshot } = await import('./web-session-tabs-sync')
const { acceptReplayedWebSessionTabsSnapshot } =
await import('./web-session-tabs-sync/tracking-lifecycle')
acceptReplayedWebSessionTabsSnapshot(environmentId, args.worktreeId)
await refreshWebRuntimeSessionTabsSnapshot(environmentId, args.worktreeId)
console.warn('[web-runtime-session] suppressed lifecycle close without incarnation evidence', {
@@ -130,7 +131,8 @@ async function callWebRuntimeSessionTabMethod(
}
try {
const { resolveHostSessionTabIdForWebSessionTab } = await import('./web-session-tabs-sync')
const { resolveHostSessionTabIdForWebSessionTab } =
await import('./web-session-tabs-sync/tracking-mappings')
const state = useAppStore.getState()
const hostTabId =
resolveHostSessionTabIdForWebSessionTab(state, {
@@ -191,7 +193,8 @@ async function callWebRuntimeSessionTabMethod(
// only when it republished; dead-leaf refusals must stay suppressed.
clearWebSessionCloseIntent(intentOwner, args.worktreeId, immediateHostTabId)
clearWebSessionCloseIntent(intentOwner, args.worktreeId, hostTabId)
const { acceptReplayedWebSessionTabsSnapshot } = await import('./web-session-tabs-sync')
const { acceptReplayedWebSessionTabsSnapshot } =
await import('./web-session-tabs-sync/tracking-lifecycle')
acceptReplayedWebSessionTabsSnapshot(environmentId, args.worktreeId)
}
await refreshWebRuntimeSessionTabsSnapshot(environmentId, args.worktreeId, {
@@ -220,7 +223,8 @@ async function callWebRuntimeSessionTabMethod(
}
}
if (isLifecycleClose) {
const { acceptReplayedWebSessionTabsSnapshot } = await import('./web-session-tabs-sync')
const { acceptReplayedWebSessionTabsSnapshot } =
await import('./web-session-tabs-sync/tracking-lifecycle')
acceptReplayedWebSessionTabsSnapshot(environmentId, args.worktreeId)
await refreshWebRuntimeSessionTabsSnapshot(environmentId, args.worktreeId, {
expectedEnvironmentPairingRevision: intentOwner.pairingRevision
@@ -38,16 +38,24 @@ vi.mock('../store', () => ({
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
// The production caller invokes the returned settle receipt.
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab,
resolveHostSessionGroupIdForWebSessionTab: mocks.resolveHostSessionGroupIdForWebSessionTab
}))
@@ -46,7 +46,7 @@ export async function moveWebRuntimeSessionTab(
try {
const { resolveHostSessionGroupIdForWebSessionTab, resolveHostSessionTabIdForWebSessionTab } =
await import('./web-session-tabs-sync')
await import('./web-session-tabs-sync/tracking-mappings')
const state = useAppStore.getState()
const groups = state.groupsByWorktree?.[args.worktreeId] ?? []
const targetGroup = groups.find((group) => group.id === args.targetGroupId)
@@ -34,16 +34,24 @@ vi.mock('../store', () => ({
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
// The production caller invokes the returned settle receipt.
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
@@ -1,4 +1,5 @@
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
import type * as TrackingDecisions from './web-session-tabs-sync/tracking-decisions'
import {
createWebRuntimeAgentSessionTerminal,
createWebRuntimeAgentSessionTerminalWithLaunchDraft,
@@ -47,16 +48,25 @@ vi.mock('../store', () => ({
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', async (importOriginal) => ({
...(await importOriginal<typeof TrackingDecisions>()),
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
// The production caller invokes the returned settle receipt.
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
@@ -40,16 +40,24 @@ vi.mock('../store', () => ({
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
// The production caller invokes the returned settle receipt.
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
@@ -48,16 +48,24 @@ vi.mock('../lib/activate-tab-and-focus-pane', () => ({
activateTabAndFocusPane: mocks.activateTabAndFocusPane
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
// The production caller invokes the returned settle receipt.
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
@@ -41,14 +41,22 @@ vi.mock('../store', () => ({
}
}))
vi.mock('./web-session-tabs-sync', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
@@ -46,16 +46,24 @@ vi.mock('../store', () => ({
}
}))
vi.mock('./web-session-tabs-sync', () => ({
vi.mock('./web-session-tabs-sync/tracking-lifecycle', () => ({
acceptReplayedWebSessionTabsSnapshot: mocks.acceptReplayedWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot,
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration,
getWebSessionTabsTrackingGeneration: mocks.getWebSessionTabsTrackingGeneration
}))
vi.mock('./web-session-tabs-sync/snapshot-api', () => ({
applyWebSessionTabsSnapshot: mocks.applyWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/tracking-decisions', () => ({
decideWebSessionTabsSnapshot: mocks.decideWebSessionTabsSnapshot
}))
vi.mock('./web-session-tabs-sync/store-patch', () => ({
applyWebSessionTabsStorePatch: (buildPatch: (state: unknown) => unknown) => {
mocks.setState(buildPatch)
// The production caller invokes the returned settle receipt.
return () => {}
},
}
}))
vi.mock('./web-session-tabs-sync/tracking-mappings', () => ({
resolveHostSessionTabIdForWebSessionTab: mocks.resolveHostSessionTabIdForWebSessionTab
}))
@@ -251,7 +251,7 @@ export function setWebRuntimeTabProps(args: {
}
const callEnvironment = captureRuntimeEnvironmentCall(environmentId)
const state = useAppStore.getState()
void import('./web-session-tabs-sync')
void import('./web-session-tabs-sync/tracking-mappings')
.then(({ resolveHostSessionTabIdForWebSessionTab }) => {
const hostTabId =
resolveHostSessionTabIdForWebSessionTab(state, {
@@ -32,10 +32,8 @@ vi.mock('./web-session-terminal-orphan-recovery', () => ({
import { useAppStore } from '@/store'
import { replaceRuntimeEnvironmentRevisions } from './runtime-environment-revision'
import {
resetWebSessionTabsSnapshotFreshnessForTests,
useWebSessionTabsSync
} from './web-session-tabs-sync'
import { resetWebSessionTabsSnapshotFreshnessForTests } from './web-session-tabs-sync/tracking-lifecycle'
import { useWebSessionTabsSync } from './web-session-tabs-sync/use-web-session-tabs-sync'
/**
* #21928: a paired host mints `headless:` epochs for one worktree between renderer frames, so the
@@ -32,10 +32,8 @@ vi.mock('./web-session-terminal-orphan-recovery', () => ({
import { useAppStore } from '@/store'
import { replaceRuntimeEnvironmentRevisions } from './runtime-environment-revision'
import {
resetWebSessionTabsSnapshotFreshnessForTests,
useWebSessionTabsSync
} from './web-session-tabs-sync'
import { resetWebSessionTabsSnapshotFreshnessForTests } from './web-session-tabs-sync/tracking-lifecycle'
import { useWebSessionTabsSync } from './web-session-tabs-sync/use-web-session-tabs-sync'
import { WINDOW_VISIBILITY_SUBSCRIPTION_RETRY_INITIAL_MS } from './window-visibility-subscription-parking'
/**
@@ -5,7 +5,7 @@ import type {
} from '../../../shared/runtime-types'
import type { OpenFile } from '../store/slices/editor'
import { buildOwnedEditorFileId } from '../store/slices/editor/file-ids/editor-file-ids'
import { applyWebSessionTabsSnapshot } from './web-session-tabs-sync'
import { applyWebSessionTabsSnapshot } from './web-session-tabs-sync/snapshot-api'
import {
ENV,
NOW,
@@ -1,9 +1,7 @@
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { toWebTerminalSurfaceTabId } from '../../../shared/terminal-surface-id'
import {
applyWebSessionTabsSnapshot,
resolveHostSessionGroupIdForWebSessionTab
} from './web-session-tabs-sync'
import { applyWebSessionTabsSnapshot } from './web-session-tabs-sync/snapshot-api'
import { resolveHostSessionGroupIdForWebSessionTab } from './web-session-tabs-sync/tracking-mappings'
import {
ENV,
LEAF_ID,
@@ -44,10 +44,8 @@ import { useAppStore } from '@/store'
import type { PublicKnownRuntimeEnvironment } from '../../../shared/runtime-environments'
import type { AppState } from '@/store/types'
import { replaceRuntimeEnvironmentRevisions } from './runtime-environment-revision'
import {
resetWebSessionTabsSnapshotFreshnessForTests,
useWebSessionTabsSync
} from './web-session-tabs-sync'
import { resetWebSessionTabsSnapshotFreshnessForTests } from './web-session-tabs-sync/tracking-lifecycle'
import { useWebSessionTabsSync } from './web-session-tabs-sync/use-web-session-tabs-sync'
import { clearRuntimeEnvironmentConnectionGenerationsForTests } from '@/store/slices/runtime-status'
import { resetWebRuntimeInitialTerminalBootstrapForTests } from './web-runtime-initial-terminal-bootstrap'
@@ -13,7 +13,7 @@ vi.mock('./web-runtime-session-tab-lifecycle', () => ({
import { useAppStore } from '../store'
import { createWorkspaceTabCloseCommands } from '@/components/tab-group/workspace-tab-close-commands'
import { ORCA_EDITOR_REQUEST_FILE_CLOSE_EVENT } from '@/components/editor/editor-autosave'
import { applyWebSessionTabsSnapshot } from './web-session-tabs-sync'
import { applyWebSessionTabsSnapshot } from './web-session-tabs-sync/snapshot-api'
import {
ENV,
NOW,
@@ -30,10 +30,8 @@ vi.mock('@/lib/worktree-runtime-owner', async (importOriginal) => {
import { useAppStore } from '@/store'
import { replaceRuntimeEnvironmentRevisions } from './runtime-environment-revision'
import { clearHostLiveTerminalProbesForTests } from './host-live-terminal-probe'
import {
resetWebSessionTabsSnapshotFreshnessForTests,
useWebSessionTabsSync
} from './web-session-tabs-sync'
import { resetWebSessionTabsSnapshotFreshnessForTests } from './web-session-tabs-sync/tracking-lifecycle'
import { useWebSessionTabsSync } from './web-session-tabs-sync/use-web-session-tabs-sync'
import { clearRuntimeEnvironmentConnectionGenerationsForTests } from '@/store/slices/runtime-status'
import { buildRuntimeSessionMirrorEnvironmentKeys } from './use-runtime-session-mirror-environment-key'
@@ -31,10 +31,8 @@ import { useAppStore } from '@/store'
import type { RuntimeEnvironmentStatus } from '@/store/slices/runtime-status-types'
import { replaceRuntimeEnvironmentRevisions } from './runtime-environment-revision'
import { clearHostLiveTerminalProbesForTests } from './host-live-terminal-probe'
import {
resetWebSessionTabsSnapshotFreshnessForTests,
useWebSessionTabsSync
} from './web-session-tabs-sync'
import { resetWebSessionTabsSnapshotFreshnessForTests } from './web-session-tabs-sync/tracking-lifecycle'
import { useWebSessionTabsSync } from './web-session-tabs-sync/use-web-session-tabs-sync'
import { clearRuntimeEnvironmentConnectionGenerationsForTests } from '@/store/slices/runtime-status'
const ENV_A = 'env-a'
@@ -49,10 +49,10 @@ import { subscribeAcceptedWebSessionTerminalHandle } from './web-session-termina
import {
_getWebSessionTabsReceiptTrackingCountsForTest,
_getWebSessionTabsTrackingCountsForTest,
resetWebSessionTabsSnapshotFreshnessForTests,
useWebSessionTabsSync,
WEB_SESSION_TABS_VISIBILITY_RESUME_STAGGER_MS
} from './web-session-tabs-sync'
resetWebSessionTabsSnapshotFreshnessForTests
} from './web-session-tabs-sync/tracking-lifecycle'
import { useWebSessionTabsSync } from './web-session-tabs-sync/use-web-session-tabs-sync'
import { WEB_SESSION_TABS_VISIBILITY_RESUME_STAGGER_MS } from './web-session-tabs-sync/state'
import { WINDOW_VISIBILITY_SUBSCRIPTION_PARK_DELAY_MS } from './window-visibility-subscription-parking'
const ENV_A = 'env-a'
@@ -47,10 +47,10 @@ import { clearHostLiveTerminalProbesForTests } from './host-live-terminal-probe'
import {
acceptReplayedWebSessionTabsSnapshot,
_getWebSessionTabsTrackingCountsForTest,
resetWebSessionTabsSnapshotFreshnessForTests,
useWebSessionTabsSync,
WEB_SESSION_TABS_VISIBILITY_RESUME_STAGGER_MS
} from './web-session-tabs-sync'
resetWebSessionTabsSnapshotFreshnessForTests
} from './web-session-tabs-sync/tracking-lifecycle'
import { useWebSessionTabsSync } from './web-session-tabs-sync/use-web-session-tabs-sync'
import { WEB_SESSION_TABS_VISIBILITY_RESUME_STAGGER_MS } from './web-session-tabs-sync/state'
import { clearRuntimeEnvironmentConnectionGenerationsForTests } from '@/store/slices/runtime-status'
import {
WINDOW_VISIBILITY_SUBSCRIPTION_PARK_DELAY_BACKOFF_LIMIT,
@@ -13,13 +13,15 @@ import type { Tab } from '../../../shared/tab-types'
import type { TerminalTab } from '../../../shared/terminal-tab-types'
import {
acceptReplayedWebSessionTabsSnapshot,
clearWebSessionTabsTrackingForEnvironment
} from './web-session-tabs-sync/tracking-lifecycle'
import {
applyFreshWebSessionTabsSnapshot,
applyWebSessionTabsSnapshot,
clearWebSessionTabsTrackingForEnvironment,
resolveHostSessionTabIdForWebSessionTab,
shouldApplyWebSessionTabsSnapshot,
type WebSessionTabsSyncState
} from './web-session-tabs-sync'
applyWebSessionTabsSnapshot
} from './web-session-tabs-sync/snapshot-api'
import { resolveHostSessionTabIdForWebSessionTab } from './web-session-tabs-sync/tracking-mappings'
import { shouldApplyWebSessionTabsSnapshot } from './web-session-tabs-sync/tracking-decisions'
import type { WebSessionTabsSyncState } from './web-session-tabs-sync/state'
import {
recordReceivedWebSessionTabsSnapshot,
shouldApplyRecoveredWebSessionTabsSnapshot
@@ -1,58 +0,0 @@
/** Public boundary for the web runtime session-tab mirror. */
export {
applyFreshWebSessionTabsSnapshot,
applyFreshWebSessionTabsSnapshots,
applyWebSessionTabsSnapshot,
applyWebSessionTabsSnapshots,
applyWebSessionTabsSnapshotOperations,
decideWebSessionTabsSnapshotOperations
} from './web-session-tabs-sync/snapshot-api'
export type {
DecidedWebSessionTabsSnapshotOperation,
WebSessionTabsSnapshotOperation
} from './web-session-tabs-sync/snapshot-api'
export {
acceptReplayedWebSessionTabsSnapshot,
clearWebSessionTabsTrackingForEnvironment,
getLastKnownHostTerminalTabCount,
getLatestWebSessionTabsPublicationEpoch,
getWebSessionTabsTrackingGeneration,
resetWebSessionTabsSnapshotFreshnessForTests,
_getWebSessionTabsReceiptTrackingCountsForTest,
_getWebSessionTabsTrackingCountsForTest
} from './web-session-tabs-sync/tracking-lifecycle'
export {
resolveHostSessionGroupIdForWebSessionTab,
resolveHostSessionTabIdForWebSessionTab
} from './web-session-tabs-sync/tracking-mappings'
export {
decideWebSessionTabsSnapshot,
shouldApplyWebSessionTabsSnapshot,
shouldBootstrapInitialWebRuntimeTerminal,
shouldRespawnWebRuntimeTerminalAfterWake,
shouldSyncAllRuntimeSessionTabs,
shouldSyncRuntimeSessionTabs,
WEB_SESSION_TABS_FRAME_OUTRANKED
} from './web-session-tabs-sync/tracking-decisions'
export type { WebSessionTabsSnapshotDecision } from './web-session-tabs-sync/tracking-decisions'
export { applyWebSessionTabsStorePatch } from './web-session-tabs-sync/store-patch'
export type {
HostSessionMirrorPatchFrame,
HostSessionMirrorPatchVerdict,
HostSessionMirrorSettle
} from './web-session-tabs-sync/mirror-settle'
export {
hostSessionMirrorSettleForPatchlessFrame,
createHostSessionMirrorSettle
} from './web-session-tabs-sync/mirror-settle'
export { WEB_SESSION_TABS_VISIBILITY_RESUME_STAGGER_MS } from './web-session-tabs-sync/state'
export type {
WebSessionTabsSnapshotApplyOptions,
WebSessionTabsSyncState,
SessionTabsStreamEvent
} from './web-session-tabs-sync/state'
export { useWebSessionTabsSync } from './web-session-tabs-sync/use-web-session-tabs-sync'
@@ -15,7 +15,7 @@ import { setStructuredAgentSessionHost } from '../../src/main/native-chat/agent-
import { useAppStore } from '../../src/renderer/src/store'
import { applyStructuredSessionTabSnapshots } from '../../src/renderer/src/runtime/local-structured-session-tabs-sync/snapshot-apply'
import { resetLocalStructuredSessionVersionForTests } from '../../src/renderer/src/runtime/local-structured-session-tabs-sync'
import { resetWebSessionTabsSnapshotFreshnessForTests } from '../../src/renderer/src/runtime/web-session-tabs-sync'
import { resetWebSessionTabsSnapshotFreshnessForTests } from '../../src/renderer/src/runtime/web-session-tabs-sync/tracking-lifecycle'
import { registerSessionTabIpcBridge } from '../../src/renderer/src/hooks/ipc-events/session-tab-ipc-bridge'
import { registerTerminalUiRoutingIpcBridge } from '../../src/renderer/src/hooks/ipc-events/terminal-ui-routing-ipc-bridge'
import { resetWebSessionCloseIntentForTests } from '../../src/renderer/src/runtime/web-session-close-intent'
@@ -16,10 +16,8 @@ import { setStructuredAgentSessionHost } from '../../src/main/native-chat/agent-
import { useAppStore } from '../../src/renderer/src/store'
import { applyStructuredSessionTabSnapshots } from '../../src/renderer/src/runtime/local-structured-session-tabs-sync/snapshot-apply'
import { resetLocalStructuredSessionVersionForTests } from '../../src/renderer/src/runtime/local-structured-session-tabs-sync'
import {
applyWebSessionTabsSnapshot,
resetWebSessionTabsSnapshotFreshnessForTests
} from '../../src/renderer/src/runtime/web-session-tabs-sync'
import { applyWebSessionTabsSnapshot } from '../../src/renderer/src/runtime/web-session-tabs-sync/snapshot-api'
import { resetWebSessionTabsSnapshotFreshnessForTests } from '../../src/renderer/src/runtime/web-session-tabs-sync/tracking-lifecycle'
import { acceptPairedHostStructuredSessions } from '../../src/renderer/src/runtime/structured-agent-session-tab-retirement'
import { LOCAL_STRUCTURED_SESSION_OWNER } from '../../src/renderer/src/runtime/local-structured-session-owner'
import { registerSessionTabIpcBridge } from '../../src/renderer/src/hooks/ipc-events/session-tab-ipc-bridge'