From f8a20c315439221d496037b11f8114196de9b8e7 Mon Sep 17 00:00:00 2001 From: Hannes Rudolph Date: Fri, 23 Jan 2026 18:58:33 -0700 Subject: [PATCH] fix: remove codebaseIndexModels from globalState storage EMBEDDING_MODEL_PROFILES was being stored in globalState on every ClineProvider initialization, but this is unnecessary - it's static reference data that should be passed directly to the webview. Changes: - Remove line that stored EMBEDDING_MODEL_PROFILES in globalState - The webview still receives the data via the ?? fallback in getState() - Add migration v3 to clean up existing codebaseIndexModels keys - Add tests for migration v3 --- src/core/webview/ClineProvider.ts | 3 +- .../__tests__/settingsMigrations.spec.ts | 48 +++++++++++++++++++ src/utils/settingsMigrations.ts | 15 ++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/src/core/webview/ClineProvider.ts b/src/core/webview/ClineProvider.ts index 39285122c3..d3342ba63b 100644 --- a/src/core/webview/ClineProvider.ts +++ b/src/core/webview/ClineProvider.ts @@ -176,7 +176,8 @@ export class ClineProvider ClineProvider.activeInstances.add(this) this.mdmService = mdmService - this.updateGlobalState("codebaseIndexModels", EMBEDDING_MODEL_PROFILES) + // Note: EMBEDDING_MODEL_PROFILES is passed directly to webview via getStateToPostToWebview() + // without persisting to globalState. The webview receives it via the ?? fallback. // Start configuration loading (which might trigger indexing) in the background. // Don't await, allowing activation to continue immediately. diff --git a/src/utils/__tests__/settingsMigrations.spec.ts b/src/utils/__tests__/settingsMigrations.spec.ts index 8a8dfa38eb..94ef563b49 100644 --- a/src/utils/__tests__/settingsMigrations.spec.ts +++ b/src/utils/__tests__/settingsMigrations.spec.ts @@ -213,6 +213,12 @@ describe("settingsMigrations", () => { expect("customMigration" in migrations[2]).toBe(true) }) + it("should have migration version 3 defined with customMigration", () => { + expect(migrations[3]).toBeDefined() + expect(migrations[3].description).toContain("codebaseIndexModels") + expect("customMigration" in migrations[3]).toBe(true) + }) + it("CURRENT_MIGRATION_VERSION should be the max key in migrations", () => { const maxVersion = Math.max(...Object.keys(migrations).map(Number)) expect(CURRENT_MIGRATION_VERSION).toBe(maxVersion) @@ -304,6 +310,48 @@ describe("settingsMigrations", () => { }) }) + describe("migration v3 - remove codebaseIndexModels from globalState", () => { + it("should remove codebaseIndexModels if it exists", async () => { + const mockModels = { openai: { model: "text-embedding-3-small" } } + + mockContextProxy.getGlobalState.mockImplementation((key: keyof GlobalState) => { + if (key === "settingsMigrationVersion") return 2 // Already completed v1 and v2 + if (key === "codebaseIndexModels") return mockModels + return undefined + }) + + await runSettingsMigrations(mockContextProxy as unknown as ContextProxy) + + // Should have removed codebaseIndexModels + expect(mockContextProxy.updateGlobalState).toHaveBeenCalledWith("codebaseIndexModels", undefined) + + // Migration version should be updated + expect(mockContextProxy.updateGlobalState).toHaveBeenCalledWith( + "settingsMigrationVersion", + CURRENT_MIGRATION_VERSION, + ) + }) + + it("should skip migration if codebaseIndexModels does not exist", async () => { + mockContextProxy.getGlobalState.mockImplementation((key: keyof GlobalState) => { + if (key === "settingsMigrationVersion") return 2 // Already completed v1 and v2 + if (key === "codebaseIndexModels") return undefined + return undefined + }) + + await runSettingsMigrations(mockContextProxy as unknown as ContextProxy) + + // Should NOT have called updateGlobalState for codebaseIndexModels + expect(mockContextProxy.updateGlobalState).not.toHaveBeenCalledWith("codebaseIndexModels", undefined) + + // Should still update migration version + expect(mockContextProxy.updateGlobalState).toHaveBeenCalledWith( + "settingsMigrationVersion", + CURRENT_MIGRATION_VERSION, + ) + }) + }) + describe("clearDefaultSettings", () => { it("should clear settings that match current defaults", async () => { // Setup: user has settings that match current defaults diff --git a/src/utils/settingsMigrations.ts b/src/utils/settingsMigrations.ts index 8ebe6044e6..b65dfec2ab 100644 --- a/src/utils/settingsMigrations.ts +++ b/src/utils/settingsMigrations.ts @@ -127,6 +127,21 @@ export const migrations: Record = { logger.info(" Removed nested codebaseIndexConfig object") }, }, + 3: { + description: "Remove codebaseIndexModels from globalState (now passed directly to webview)", + customMigration: async (contextProxy: ContextProxy) => { + // codebaseIndexModels was previously storing the static EMBEDDING_MODEL_PROFILES + // object in globalState, but this is unnecessary - it's reference data that + // should be passed directly to the webview without persisting. + const stored = contextProxy.getGlobalState("codebaseIndexModels" as keyof GlobalState) + if (stored !== undefined) { + await contextProxy.updateGlobalState("codebaseIndexModels" as keyof GlobalState, undefined) + logger.info(" Removed codebaseIndexModels from globalState") + } else { + logger.info(" codebaseIndexModels not found in globalState, skipping") + } + }, + }, } /**