From b4b3bcdb8463f2936aeab532e46f48e0b5fdfca4 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Wed, 29 Jul 2026 00:20:47 -0700 Subject: [PATCH] perf(vault): look up resume worktrees through the shared index (#11317) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolving a session's resume target scanned every worktree in every repo: two `Object.values(worktreesByRepo).flat().find(...)` calls, which also allocate a fresh 1124-element array each time, plus an equivalent `some()` walk. All three run per visible session row, so a panel render repeated them ~20 times. `getIndexedWorktreeMap` already exists for this and is WeakMap-cached on `worktreesByRepo`, so the index is built once per store snapshot rather than per call. `connection-owner-resolution.ts` already resolves worktrees this way. ~1.6ms -> ~0.002ms per render pass at 1124 worktrees. Net -4 lines. Behavior is unchanged: the map dedupes by id, which only diverges from `find()` when one id appears twice with different objects. Worktree ids are `repoId::path`, so a duplicate id within a repo array — the documented race the index was built for — refers to the same worktree. --- .../components/right-sidebar/ai-vault-session-resume.ts | 5 ++--- src/renderer/src/lib/ai-vault-resume-target.ts | 9 +++------ 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/renderer/src/components/right-sidebar/ai-vault-session-resume.ts b/src/renderer/src/components/right-sidebar/ai-vault-session-resume.ts index a166adf011c..9465144b705 100644 --- a/src/renderer/src/components/right-sidebar/ai-vault-session-resume.ts +++ b/src/renderer/src/components/right-sidebar/ai-vault-session-resume.ts @@ -9,6 +9,7 @@ import { type AiVaultSession } from '../../../../shared/ai-vault-types' import type { AppState } from '@/store/types' +import { getIndexedWorktreeMap } from '@/store/worktree-repo-index' import { translate } from '@/i18n/i18n' import { parseWorkspaceKey } from '../../../../shared/workspace-scope' import { @@ -145,9 +146,7 @@ export function isKnownAiVaultResumeWorkspaceTarget( } const worktreeId = workspaceKey?.type === 'worktree' ? workspaceKey.worktreeId : workspaceId - return Object.values(state.worktreesByRepo).some((worktrees) => - worktrees.some((worktree) => worktree.id === worktreeId) - ) + return getIndexedWorktreeMap(state.worktreesByRepo).has(worktreeId) } function resolveSupportedResumeWorktreeId(args: { diff --git a/src/renderer/src/lib/ai-vault-resume-target.ts b/src/renderer/src/lib/ai-vault-resume-target.ts index f52e26c62e8..3c9206ae372 100644 --- a/src/renderer/src/lib/ai-vault-resume-target.ts +++ b/src/renderer/src/lib/ai-vault-resume-target.ts @@ -11,6 +11,7 @@ import { getRepoIdFromWorktreeId } from '../../../shared/worktree-id' import { parseWorkspaceKey } from '../../../shared/workspace-scope' import { isWslUncPath } from '../../../shared/wsl-paths' import type { AppState } from '@/store/types' +import { getIndexedWorktreeMap } from '@/store/worktree-repo-index' import { getFolderWorkspaceCandidateRepos } from './folder-workspace-connection' export type AiVaultResumeTargetStatus = 'local' | 'ssh' | 'runtime' | 'unknown' @@ -132,9 +133,7 @@ export function getAiVaultResumeWorkspaceExecutionHostId( } const worktreeId = workspaceKey?.type === 'worktree' ? workspaceKey.worktreeId : workspaceId - const worktree = Object.values(state.worktreesByRepo ?? {}) - .flat() - .find((candidate) => candidate.id === worktreeId) + const worktree = getIndexedWorktreeMap(state.worktreesByRepo ?? {}).get(worktreeId) const worktreeHostId = normalizeExecutionHostId(worktree?.hostId) if (worktreeHostId) { return worktreeHostId @@ -158,9 +157,7 @@ export function getAiVaultResumeWorkspaceTargetStatus( } const worktreeId = workspaceKey?.type === 'worktree' ? workspaceKey.worktreeId : workspaceId - const worktree = Object.values(state.worktreesByRepo ?? {}) - .flat() - .find((candidate) => candidate.id === worktreeId) + const worktree = getIndexedWorktreeMap(state.worktreesByRepo ?? {}).get(worktreeId) const worktreeHost = getAiVaultResumeExecutionHostTargetStatus(worktree?.hostId) if (worktreeHost !== 'unknown') { return worktreeHost