From 5d2aed9bf46bd09ce111c17e218f60ef76a40362 Mon Sep 17 00:00:00 2001 From: Jinwoo-H Date: Fri, 18 Sep 2026 14:00:09 -0400 Subject: [PATCH] refactor(session-search): move the AI Vault project key to shared The host must spell a project key exactly as the client does, so the two sides share one function instead of two copies that can drift. --- .../right-sidebar/ai-vault-project-key.ts | 13 ++----------- .../right-sidebar/ai-vault-scope-paths.ts | 7 ++----- src/shared/ai-vault-project-key.ts | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 16 deletions(-) create mode 100644 src/shared/ai-vault-project-key.ts diff --git a/src/renderer/src/components/right-sidebar/ai-vault-project-key.ts b/src/renderer/src/components/right-sidebar/ai-vault-project-key.ts index 0ab046a25d3..a5423f3d60e 100644 --- a/src/renderer/src/components/right-sidebar/ai-vault-project-key.ts +++ b/src/renderer/src/components/right-sidebar/ai-vault-project-key.ts @@ -1,18 +1,9 @@ import type { ProjectHostSetup } from '../../../../shared/project-types' import type { Repo } from '../../../../shared/repo-types' import type { Worktree } from '../../../../shared/worktree/types' +import { toAiVaultProjectKey } from '../../../../shared/ai-vault-project-key' -export function toAiVaultProjectKey( - projectId: string | null | undefined, - repoId?: string | null -): string | null { - if (projectId) { - // Why: legacy projections can already use repo-prefixed project ids; wrapping - // them again would split active scope and resolved session keys. - return projectId.startsWith('repo:') ? projectId : `project:${projectId}` - } - return repoId ? `repo:${repoId}` : null -} +export { toAiVaultProjectKey } from '../../../../shared/ai-vault-project-key' export function resolveActiveProjectKey( activeRepo: Repo | null, diff --git a/src/renderer/src/components/right-sidebar/ai-vault-scope-paths.ts b/src/renderer/src/components/right-sidebar/ai-vault-scope-paths.ts index cfdef42f3e0..087808d3c23 100644 --- a/src/renderer/src/components/right-sidebar/ai-vault-scope-paths.ts +++ b/src/renderer/src/components/right-sidebar/ai-vault-scope-paths.ts @@ -6,6 +6,7 @@ import type { ProjectHostSetupProjection } from '../../../../shared/project-host import type { ProjectHostSetup } from '../../../../shared/project-types' import type { Worktree } from '../../../../shared/worktree/types' import { splitWorktreeIdForFilesystem } from '../../../../shared/worktree/id' +import { toAiVaultProjectKey } from '../../../../shared/ai-vault-project-key' export function deriveAiVaultWorkspaceScopePaths( activeWorktree: Pick | null, @@ -103,11 +104,7 @@ function worktreeProjectKey( entry: Pick | { projectId?: string | null; repoId?: string }, setup?: { projectId?: string | null; repoId?: string } ): string | null { - const projectId = entry.projectId ?? setup?.projectId ?? null - if (projectId) { - return projectId.startsWith('repo:') ? projectId : `project:${projectId}` - } - return entry.repoId ? `repo:${entry.repoId}` : null + return toAiVaultProjectKey(entry.projectId ?? setup?.projectId ?? null, entry.repoId) } /** diff --git a/src/shared/ai-vault-project-key.ts b/src/shared/ai-vault-project-key.ts new file mode 100644 index 00000000000..7337f1b4bec --- /dev/null +++ b/src/shared/ai-vault-project-key.ts @@ -0,0 +1,16 @@ +/** + * One spelling of "which project" for the sessions panel and for a host + * resolving a search scope, so a key minted on a client and a key matched on the + * execution host cannot drift apart. + */ +export function toAiVaultProjectKey( + projectId: string | null | undefined, + repoId?: string | null +): string | null { + if (projectId) { + // Why: legacy projections can already use repo-prefixed project ids; wrapping + // them again would split active scope and resolved session keys. + return projectId.startsWith('repo:') ? projectId : `project:${projectId}` + } + return repoId ? `repo:${repoId}` : null +}