From d247d6441ba09c23987065631e02c44dd4fba8d6 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Thu, 3 Sep 2026 21:04:04 -0700 Subject: [PATCH] perf(startup): overlap the runtime capability refresh with the session-tabs inventory (#18460) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The startup structured-session restore chained `runtime:getStatus` before `session.tabs.listAll`, but the capability value is discarded at that call site — it only seeds the module cache later launch flows read, and the inventory fetch never reads it. On a profile with 413 worktrees / 801 tabs that serial leg cost a median 109 ms of the did-finish-load -> renderer-startup-hydration-done window. Issue both calls concurrently. `Promise.all` still resolves only after both settle, so the capability cache is populated no later than before. --- ...local-structured-session-tabs-sync.test.ts | 37 +++++++++++++++++++ .../inventory-refresh.ts | 10 +++-- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/renderer/src/runtime/local-structured-session-tabs-sync.test.ts b/src/renderer/src/runtime/local-structured-session-tabs-sync.test.ts index 7a6c713f37f..702c5570c0d 100644 --- a/src/renderer/src/runtime/local-structured-session-tabs-sync.test.ts +++ b/src/renderer/src/runtime/local-structured-session-tabs-sync.test.ts @@ -307,6 +307,43 @@ describe('local structured session tab projection', () => { } }) + it('starts the session-tabs inventory without waiting for the capability refresh', async () => { + const priorApi = window.api + let releaseStatus = (): void => undefined + const statusGate = new Promise((resolve) => { + releaseStatus = resolve + }) + const getStatus = vi.fn(async () => { + await statusGate + return { capabilities: [STRUCTURED_AGENT_SESSION_RUNTIME_CAPABILITY] } + }) + const call = vi.fn().mockResolvedValue({ ok: true, result: { snapshots: [] } }) + Object.defineProperty(window, 'api', { + configurable: true, + value: { runtime: { getStatus, call } } + }) + try { + vi.resetModules() + const { restoreLocalStructuredSessionTabsOnce } = + await import('./local-structured-session-tabs-sync') + let settled = false + const restored = restoreLocalStructuredSessionTabsOnce().finally(() => { + settled = true + }) + expect(getStatus).toHaveBeenCalledOnce() + // The inventory RPC must already be in flight while the capability refresh is pending. + expect(call).toHaveBeenCalledWith({ method: 'session.tabs.listAll', params: {} }) + // ...and overlapping must not let the restore open the gate before capabilities land. + await new Promise((resolve) => setTimeout(resolve, 0)) + expect(settled).toBe(false) + releaseStatus() + await restored + expect(call).toHaveBeenCalledOnce() + } finally { + Object.defineProperty(window, 'api', { configurable: true, value: priorApi }) + } + }) + it('accepts a newer session after merged content returns to the base epoch', () => { const state = createSnapshot() const base = { diff --git a/src/renderer/src/runtime/local-structured-session-tabs-sync/inventory-refresh.ts b/src/renderer/src/runtime/local-structured-session-tabs-sync/inventory-refresh.ts index d0f29ec0cf8..af756458707 100644 --- a/src/renderer/src/runtime/local-structured-session-tabs-sync/inventory-refresh.ts +++ b/src/renderer/src/runtime/local-structured-session-tabs-sync/inventory-refresh.ts @@ -10,10 +10,14 @@ import { applyStructuredSessionTabSnapshots } from './snapshot-apply' export function restoreLocalStructuredSessionTabsOnce( expectedGeneration = localStructuredSessionGeneration() ): Promise { + // Why concurrent: the capability refresh only seeds the module cache that later launch + // flows read; the inventory fetch never reads it, so chaining them only paid a second + // serial IPC round-trip on the startup gate. return latchLocalStructuredSessionRestore(() => - refreshLocalRuntimeCapabilities() - .then(() => refreshLocalStructuredSessionTabs(expectedGeneration)) - .then(() => undefined) + Promise.all([ + refreshLocalRuntimeCapabilities(), + refreshLocalStructuredSessionTabs(expectedGeneration) + ]).then(() => undefined) ) }