Skip to content

Commit 09e348e

Browse files
authored
Move codebase indexing out of experimental (#5481)
1 parent cb4652e commit 09e348e

File tree

11 files changed

+68
-155
lines changed

11 files changed

+68
-155
lines changed

src/core/webview/ClineProvider.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1510,7 +1510,7 @@ export class ClineProvider
15101510
customCondensingPrompt,
15111511
codebaseIndexModels: codebaseIndexModels ?? EMBEDDING_MODEL_PROFILES,
15121512
codebaseIndexConfig: codebaseIndexConfig ?? {
1513-
codebaseIndexEnabled: false,
1513+
codebaseIndexEnabled: true,
15141514
codebaseIndexQdrantUrl: "http://localhost:6333",
15151515
codebaseIndexEmbedderProvider: "openai",
15161516
codebaseIndexEmbedderBaseUrl: "",
@@ -1668,7 +1668,7 @@ export class ClineProvider
16681668
customCondensingPrompt: stateValues.customCondensingPrompt,
16691669
codebaseIndexModels: stateValues.codebaseIndexModels ?? EMBEDDING_MODEL_PROFILES,
16701670
codebaseIndexConfig: stateValues.codebaseIndexConfig ?? {
1671-
codebaseIndexEnabled: false,
1671+
codebaseIndexEnabled: true,
16721672
codebaseIndexQdrantUrl: "http://localhost:6333",
16731673
codebaseIndexEmbedderProvider: "openai",
16741674
codebaseIndexEmbedderBaseUrl: "",

src/core/webview/__tests__/ClineProvider.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ describe("ClineProvider", () => {
501501
alwaysAllowReadOnlyOutsideWorkspace: false,
502502
alwaysAllowWrite: false,
503503
codebaseIndexConfig: {
504-
codebaseIndexEnabled: false,
504+
codebaseIndexEnabled: true,
505505
codebaseIndexQdrantUrl: "",
506506
codebaseIndexEmbedderProvider: "openai",
507507
codebaseIndexEmbedderBaseUrl: "",

src/core/webview/webviewMessageHandler.ts

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,21 +1221,6 @@ export const webviewMessageHandler = async (
12211221
break
12221222
case "browserToolEnabled":
12231223
await updateGlobalState("browserToolEnabled", message.bool ?? true)
1224-
await provider.postStateToWebview()
1225-
break
1226-
case "codebaseIndexEnabled":
1227-
// Update the codebaseIndexConfig with the new enabled state
1228-
const currentCodebaseConfig = getGlobalState("codebaseIndexConfig") || {}
1229-
await updateGlobalState("codebaseIndexConfig", {
1230-
...currentCodebaseConfig,
1231-
codebaseIndexEnabled: message.bool ?? false,
1232-
})
1233-
1234-
// Notify the code index manager about the change
1235-
if (provider.codeIndexManager) {
1236-
await provider.codeIndexManager.handleSettingsChange()
1237-
}
1238-
12391224
await provider.postStateToWebview()
12401225
break
12411226
case "language":

src/services/code-index/__tests__/config-manager.spec.ts

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ describe("CodeIndexConfigManager", () => {
3232
describe("constructor", () => {
3333
it("should initialize with ContextProxy", () => {
3434
expect(configManager).toBeDefined()
35-
expect(configManager.isFeatureEnabled).toBe(false)
35+
expect(configManager.isFeatureEnabled).toBe(true)
3636
expect(configManager.currentEmbedderProvider).toBe("openai")
3737
})
3838
})
@@ -45,7 +45,6 @@ describe("CodeIndexConfigManager", () => {
4545
const result = await configManager.loadConfiguration()
4646

4747
expect(result.currentConfig).toEqual({
48-
isEnabled: false,
4948
isConfigured: false,
5049
embedderProvider: "openai",
5150
modelId: undefined,
@@ -77,7 +76,6 @@ describe("CodeIndexConfigManager", () => {
7776
const result = await configManager.loadConfiguration()
7877

7978
expect(result.currentConfig).toEqual({
80-
isEnabled: true,
8179
isConfigured: true,
8280
embedderProvider: "openai",
8381
modelId: "text-embedding-3-large",
@@ -111,7 +109,6 @@ describe("CodeIndexConfigManager", () => {
111109
const result = await configManager.loadConfiguration()
112110

113111
expect(result.currentConfig).toEqual({
114-
isEnabled: true,
115112
isConfigured: true,
116113
embedderProvider: "openai-compatible",
117114
modelId: "text-embedding-3-large",
@@ -149,7 +146,6 @@ describe("CodeIndexConfigManager", () => {
149146
const result = await configManager.loadConfiguration()
150147

151148
expect(result.currentConfig).toEqual({
152-
isEnabled: true,
153149
isConfigured: true,
154150
embedderProvider: "openai-compatible",
155151
modelId: "custom-model",
@@ -188,7 +184,6 @@ describe("CodeIndexConfigManager", () => {
188184
const result = await configManager.loadConfiguration()
189185

190186
expect(result.currentConfig).toEqual({
191-
isEnabled: true,
192187
isConfigured: true,
193188
embedderProvider: "openai-compatible",
194189
modelId: "custom-model",
@@ -227,7 +222,6 @@ describe("CodeIndexConfigManager", () => {
227222
const result = await configManager.loadConfiguration()
228223

229224
expect(result.currentConfig).toEqual({
230-
isEnabled: true,
231225
isConfigured: true,
232226
embedderProvider: "openai-compatible",
233227
modelId: "custom-model",
@@ -326,14 +320,14 @@ describe("CodeIndexConfigManager", () => {
326320
})
327321

328322
it("should detect restart requirement when transitioning to enabled+configured", async () => {
329-
// Initial state - disabled
323+
// Initial state - enabled but not configured
330324
mockContextProxy.getGlobalState.mockReturnValue({
331-
codebaseIndexEnabled: false,
325+
codebaseIndexEnabled: true,
332326
})
333327

334328
await configManager.loadConfiguration()
335329

336-
// Enable and configure
330+
// Configure the feature
337331
mockContextProxy.getGlobalState.mockReturnValue({
338332
codebaseIndexEnabled: true,
339333
codebaseIndexQdrantUrl: "http://qdrant.local",
@@ -689,29 +683,28 @@ describe("CodeIndexConfigManager", () => {
689683
expect(result.requiresRestart).toBe(true)
690684
})
691685

692-
it("should not require restart when disabled remains disabled", async () => {
693-
// Initial state - disabled but configured
686+
it("should require restart when enabled and provider changes even if unconfigured", async () => {
687+
// Initial state - enabled but not configured (missing API key)
694688
mockContextProxy.getGlobalState.mockReturnValue({
695-
codebaseIndexEnabled: false,
689+
codebaseIndexEnabled: true,
696690
codebaseIndexQdrantUrl: "http://qdrant.local",
697691
codebaseIndexEmbedderProvider: "openai",
698692
})
699-
setupSecretMocks({
700-
codeIndexOpenAiKey: "test-key",
701-
})
693+
setupSecretMocks({})
702694

703695
await configManager.loadConfiguration()
704696

705-
// Still disabled but change other settings
697+
// Still enabled but change provider while remaining unconfigured
706698
mockContextProxy.getGlobalState.mockReturnValue({
707-
codebaseIndexEnabled: false,
708-
codebaseIndexQdrantUrl: "http://different-qdrant.local",
699+
codebaseIndexEnabled: true,
700+
codebaseIndexQdrantUrl: "http://qdrant.local",
709701
codebaseIndexEmbedderProvider: "ollama",
710702
codebaseIndexEmbedderBaseUrl: "http://ollama.local",
711703
})
712704

713705
const result = await configManager.loadConfiguration()
714-
expect(result.requiresRestart).toBe(false)
706+
// Should require restart because provider changed while enabled
707+
expect(result.requiresRestart).toBe(true)
715708
})
716709

717710
it("should not require restart when unconfigured remains unconfigured", async () => {
@@ -970,7 +963,7 @@ describe("CodeIndexConfigManager", () => {
970963
it("should not require restart when API keys transition from undefined to empty string", async () => {
971964
// Initial state with undefined API keys
972965
mockContextProxy.getGlobalState.mockReturnValue({
973-
codebaseIndexEnabled: false, // Start disabled to avoid restart due to enable+configure
966+
codebaseIndexEnabled: true, // Always enabled now
974967
codebaseIndexQdrantUrl: "http://qdrant.local",
975968
codebaseIndexEmbedderProvider: "openai",
976969
})
@@ -1208,7 +1201,6 @@ describe("CodeIndexConfigManager", () => {
12081201
it("should return correct configuration via getConfig", () => {
12091202
const config = configManager.getConfig()
12101203
expect(config).toEqual({
1211-
isEnabled: true,
12121204
isConfigured: true,
12131205
embedderProvider: "openai",
12141206
modelId: "text-embedding-3-large",
@@ -1267,7 +1259,7 @@ describe("CodeIndexConfigManager", () => {
12671259
it("should properly initialize with current config to prevent false restarts", async () => {
12681260
// Setup configuration
12691261
mockContextProxy.getGlobalState.mockReturnValue({
1270-
codebaseIndexEnabled: false, // Start disabled to avoid transition restart
1262+
codebaseIndexEnabled: true, // Always enabled now
12711263
codebaseIndexQdrantUrl: "http://qdrant.local",
12721264
codebaseIndexEmbedderProvider: "openai",
12731265
codebaseIndexEmbedderModelId: "text-embedding-3-small",

src/services/code-index/__tests__/manager.spec.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ describe("CodeIndexManager - handleSettingsChange regression", () => {
8181
isFeatureConfigured: true,
8282
isFeatureEnabled: true,
8383
getConfig: vi.fn().mockReturnValue({
84-
isEnabled: true,
8584
isConfigured: true,
8685
embedderProvider: "openai",
8786
modelId: "text-embedding-3-small",
@@ -149,7 +148,6 @@ describe("CodeIndexManager - handleSettingsChange regression", () => {
149148
isFeatureConfigured: true,
150149
isFeatureEnabled: true,
151150
getConfig: vi.fn().mockReturnValue({
152-
isEnabled: true,
153151
isConfigured: true,
154152
embedderProvider: "openai",
155153
modelId: "text-embedding-3-small",
@@ -276,7 +274,6 @@ describe("CodeIndexManager - handleSettingsChange regression", () => {
276274
isFeatureConfigured: true,
277275
isFeatureEnabled: true,
278276
getConfig: vitest.fn().mockReturnValue({
279-
isEnabled: true,
280277
isConfigured: true,
281278
embedderProvider: "openai",
282279
modelId: "text-embedding-3-small",

src/services/code-index/config-manager.ts

Lines changed: 45 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { getDefaultModelId, getModelDimension, getModelScoreThreshold } from "..
1010
* Handles loading, validating, and providing access to configuration values.
1111
*/
1212
export class CodeIndexConfigManager {
13-
private isEnabled: boolean = false
1413
private embedderProvider: EmbedderProvider = "openai"
1514
private modelId?: string
1615
private modelDimension?: number
@@ -42,7 +41,7 @@ export class CodeIndexConfigManager {
4241
private _loadAndSetConfiguration(): void {
4342
// Load configuration from storage
4443
const codebaseIndexConfig = this.contextProxy?.getGlobalState("codebaseIndexConfig") ?? {
45-
codebaseIndexEnabled: false,
44+
codebaseIndexEnabled: true,
4645
codebaseIndexQdrantUrl: "http://localhost:6333",
4746
codebaseIndexEmbedderProvider: "openai",
4847
codebaseIndexEmbedderBaseUrl: "",
@@ -69,7 +68,7 @@ export class CodeIndexConfigManager {
6968
const geminiApiKey = this.contextProxy?.getSecret("codebaseIndexGeminiApiKey") ?? ""
7069

7170
// Update instance variables with configuration
72-
this.isEnabled = codebaseIndexEnabled || false
71+
// Note: codebaseIndexEnabled is no longer used as the feature is always enabled
7372
this.qdrantUrl = codebaseIndexQdrantUrl
7473
this.qdrantApiKey = qdrantApiKey ?? ""
7574
this.searchMinScore = codebaseIndexSearchMinScore
@@ -127,7 +126,6 @@ export class CodeIndexConfigManager {
127126
public async loadConfiguration(): Promise<{
128127
configSnapshot: PreviousConfigSnapshot
129128
currentConfig: {
130-
isEnabled: boolean
131129
isConfigured: boolean
132130
embedderProvider: EmbedderProvider
133131
modelId?: string
@@ -144,7 +142,7 @@ export class CodeIndexConfigManager {
144142
}> {
145143
// Capture the ACTUAL previous state before loading new configuration
146144
const previousConfigSnapshot: PreviousConfigSnapshot = {
147-
enabled: this.isEnabled,
145+
enabled: true, // Feature is always enabled
148146
configured: this.isConfigured(),
149147
embedderProvider: this.embedderProvider,
150148
modelId: this.modelId,
@@ -169,7 +167,6 @@ export class CodeIndexConfigManager {
169167
return {
170168
configSnapshot: previousConfigSnapshot,
171169
currentConfig: {
172-
isEnabled: this.isEnabled,
173170
isConfigured: this.isConfigured(),
174171
embedderProvider: this.embedderProvider,
175172
modelId: this.modelId,
@@ -246,66 +243,62 @@ export class CodeIndexConfigManager {
246243
const prevQdrantUrl = prev?.qdrantUrl ?? ""
247244
const prevQdrantApiKey = prev?.qdrantApiKey ?? ""
248245

249-
// 1. Transition from disabled/unconfigured to enabled+configured
250-
if ((!prevEnabled || !prevConfigured) && this.isEnabled && nowConfigured) {
246+
// 1. Transition from unconfigured to configured
247+
// Since the feature is always enabled, we only check configuration status
248+
if (!prevConfigured && nowConfigured) {
251249
return true
252250
}
253251

254-
// 2. If was disabled and still is, no restart needed
255-
if (!prevEnabled && !this.isEnabled) {
256-
return false
257-
}
258-
259252
// 3. If wasn't ready before and isn't ready now, no restart needed
260253
if (!prevConfigured && !nowConfigured) {
261254
return false
262255
}
263256

264257
// 4. CRITICAL CHANGES - Always restart for these
265-
if (this.isEnabled || prevEnabled) {
266-
// Provider change
267-
if (prevProvider !== this.embedderProvider) {
268-
return true
269-
}
258+
// Since feature is always enabled, we always check for critical changes
270259

271-
// Authentication changes (API keys)
272-
const currentOpenAiKey = this.openAiOptions?.openAiNativeApiKey ?? ""
273-
const currentOllamaBaseUrl = this.ollamaOptions?.ollamaBaseUrl ?? ""
274-
const currentOpenAiCompatibleBaseUrl = this.openAiCompatibleOptions?.baseUrl ?? ""
275-
const currentOpenAiCompatibleApiKey = this.openAiCompatibleOptions?.apiKey ?? ""
276-
const currentModelDimension = this.modelDimension
277-
const currentGeminiApiKey = this.geminiOptions?.apiKey ?? ""
278-
const currentQdrantUrl = this.qdrantUrl ?? ""
279-
const currentQdrantApiKey = this.qdrantApiKey ?? ""
280-
281-
if (prevOpenAiKey !== currentOpenAiKey) {
282-
return true
283-
}
260+
// Provider change
261+
if (prevProvider !== this.embedderProvider) {
262+
return true
263+
}
284264

285-
if (prevOllamaBaseUrl !== currentOllamaBaseUrl) {
286-
return true
287-
}
265+
// Authentication changes (API keys)
266+
const currentOpenAiKey = this.openAiOptions?.openAiNativeApiKey ?? ""
267+
const currentOllamaBaseUrl = this.ollamaOptions?.ollamaBaseUrl ?? ""
268+
const currentOpenAiCompatibleBaseUrl = this.openAiCompatibleOptions?.baseUrl ?? ""
269+
const currentOpenAiCompatibleApiKey = this.openAiCompatibleOptions?.apiKey ?? ""
270+
const currentModelDimension = this.modelDimension
271+
const currentGeminiApiKey = this.geminiOptions?.apiKey ?? ""
272+
const currentQdrantUrl = this.qdrantUrl ?? ""
273+
const currentQdrantApiKey = this.qdrantApiKey ?? ""
274+
275+
if (prevOpenAiKey !== currentOpenAiKey) {
276+
return true
277+
}
288278

289-
if (
290-
prevOpenAiCompatibleBaseUrl !== currentOpenAiCompatibleBaseUrl ||
291-
prevOpenAiCompatibleApiKey !== currentOpenAiCompatibleApiKey
292-
) {
293-
return true
294-
}
279+
if (prevOllamaBaseUrl !== currentOllamaBaseUrl) {
280+
return true
281+
}
295282

296-
// Check for model dimension changes (generic for all providers)
297-
if (prevModelDimension !== currentModelDimension) {
298-
return true
299-
}
283+
if (
284+
prevOpenAiCompatibleBaseUrl !== currentOpenAiCompatibleBaseUrl ||
285+
prevOpenAiCompatibleApiKey !== currentOpenAiCompatibleApiKey
286+
) {
287+
return true
288+
}
300289

301-
if (prevQdrantUrl !== currentQdrantUrl || prevQdrantApiKey !== currentQdrantApiKey) {
302-
return true
303-
}
290+
// Check for model dimension changes (generic for all providers)
291+
if (prevModelDimension !== currentModelDimension) {
292+
return true
293+
}
304294

305-
// Vector dimension changes (still important for compatibility)
306-
if (this._hasVectorDimensionChanged(prevProvider, prev?.modelId)) {
307-
return true
308-
}
295+
if (prevQdrantUrl !== currentQdrantUrl || prevQdrantApiKey !== currentQdrantApiKey) {
296+
return true
297+
}
298+
299+
// Vector dimension changes (still important for compatibility)
300+
if (this._hasVectorDimensionChanged(prevProvider, prev?.modelId)) {
301+
return true
309302
}
310303

311304
return false
@@ -342,7 +335,6 @@ export class CodeIndexConfigManager {
342335
*/
343336
public getConfig(): CodeIndexConfig {
344337
return {
345-
isEnabled: this.isEnabled,
346338
isConfigured: this.isConfigured(),
347339
embedderProvider: this.embedderProvider,
348340
modelId: this.modelId,
@@ -362,7 +354,7 @@ export class CodeIndexConfigManager {
362354
* Gets whether the code indexing feature is enabled
363355
*/
364356
public get isFeatureEnabled(): boolean {
365-
return this.isEnabled
357+
return true
366358
}
367359

368360
/**

src/services/code-index/interfaces/config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import { EmbedderProvider } from "./manager"
55
* Configuration state for the code indexing feature
66
*/
77
export interface CodeIndexConfig {
8-
isEnabled: boolean
98
isConfigured: boolean
109
embedderProvider: EmbedderProvider
1110
modelId?: string

0 commit comments

Comments
 (0)