Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
b857ad6
Fix code index secret persistence with async VSCode storage
daniel-lxs Jun 26, 2025
2558594
Fix code index secret persistence and test failures
daniel-lxs Jun 26, 2025
d883732
feat: improve code index settings secret handling in UI
daniel-lxs Jun 26, 2025
eee698c
refactor: disconnect code index from unified settings system
daniel-lxs Jun 26, 2025
5488f28
feat: separate code index enable/disable from indexing settings
daniel-lxs Jun 26, 2025
5c0f7e8
refactor: remove ContextProxy.getVSCodeContext() and pass ExtensionCo…
daniel-lxs Jun 27, 2025
56bab24
refactor: streamline secret handling by removing async methods and ut…
daniel-lxs Jul 2, 2025
0a16ef6
feat: translations and popover component
daniel-lxs Jul 2, 2025
e206059
refactor: simplify test mocks and improve checkbox handling in CodeIn…
daniel-lxs Jul 3, 2025
3f91d0a
refactor: remove debug logging from CodeIndexConfigManager, CodeIndex…
daniel-lxs Jul 3, 2025
56ce820
fix: merge missing translation keys from main after rebase
daniel-lxs Jul 3, 2025
da6e8c8
Revert "fix: merge missing translation keys from main after rebase"
daniel-lxs Jul 3, 2025
7bd6724
fix: add missing translation keys from main branch after rebase
daniel-lxs Jul 3, 2025
54568c2
fix: remove clickIndicatorMessage, fix toggle message type, and clean…
daniel-lxs Jul 3, 2025
ccef3d9
refactor: streamline settings management in CodeIndexPopover and impr…
daniel-lxs Jul 3, 2025
a4f9ba9
refactor: remove debug logging from configuration checks in CodeIndex…
daniel-lxs Jul 3, 2025
5bf9e9b
fix: translations
daniel-lxs Jul 3, 2025
e6df6a3
refactor: remove CodeIndexSettings component and associated tests
daniel-lxs Jul 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/core/config/ContextProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,23 @@ export class ContextProxy {
: this.originalContext.secrets.store(key, value)
}

/**
* Refresh secrets from storage and update cache
* This is useful when you need to ensure the cache has the latest values
*/
async refreshSecrets(): Promise<void> {
const promises = SECRET_STATE_KEYS.map(async (key) => {
try {
this.secretCache[key] = await this.originalContext.secrets.get(key)
} catch (error) {
logger.error(
`Error refreshing secret ${key}: ${error instanceof Error ? error.message : String(error)}`,
)
}
})
await Promise.all(promises)
}

private getAllSecretState(): SecretState {
return Object.fromEntries(SECRET_STATE_KEYS.map((key) => [key, this.getSecret(key)]))
}
Expand Down
5 changes: 0 additions & 5 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -884,11 +884,6 @@ export class ClineProvider
this.contextProxy.setProviderSettings(providerSettings),
])

// Notify CodeIndexManager about the settings change
if (this.codeIndexManager) {
await this.codeIndexManager.handleExternalSettingsChange()
}

// Change the provider for the current task.
// TODO: We should rename `buildApiHandler` for clarity (e.g. `getProviderClient`).
const task = this.getCurrentCline()
Expand Down
115 changes: 99 additions & 16 deletions src/core/webview/webviewMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1113,6 +1113,21 @@ export const webviewMessageHandler = async (
break
case "browserToolEnabled":
await updateGlobalState("browserToolEnabled", message.bool ?? true)
await provider.postStateToWebview()
break
case "codebaseIndexEnabled":
// Update the codebaseIndexConfig with the new enabled state
const currentCodebaseConfig = getGlobalState("codebaseIndexConfig") || {}
await updateGlobalState("codebaseIndexConfig", {
...currentCodebaseConfig,
codebaseIndexEnabled: message.bool ?? false,
})

// Notify the code index manager about the change
if (provider.codeIndexManager) {
await provider.codeIndexManager.handleSettingsChange()
}

await provider.postStateToWebview()
break
case "language":
Expand Down Expand Up @@ -1806,38 +1821,86 @@ export const webviewMessageHandler = async (

break
}
case "codebaseIndexConfig": {
const codebaseIndexConfig = message.values ?? {
codebaseIndexEnabled: false,
codebaseIndexQdrantUrl: "http://localhost:6333",
codebaseIndexEmbedderProvider: "openai",
codebaseIndexEmbedderBaseUrl: "",
codebaseIndexEmbedderModelId: "",

case "saveCodeIndexSettingsAtomic": {
if (!message.codeIndexSettings) {
break
}
await updateGlobalState("codebaseIndexConfig", codebaseIndexConfig)

const settings = message.codeIndexSettings

try {
// Save global state settings atomically (without codebaseIndexEnabled which is now in global settings)
const currentConfig = getGlobalState("codebaseIndexConfig") || {}
const globalStateConfig = {
...currentConfig,
codebaseIndexQdrantUrl: settings.codebaseIndexQdrantUrl,
codebaseIndexEmbedderProvider: settings.codebaseIndexEmbedderProvider,
codebaseIndexEmbedderBaseUrl: settings.codebaseIndexEmbedderBaseUrl,
codebaseIndexEmbedderModelId: settings.codebaseIndexEmbedderModelId,
codebaseIndexOpenAiCompatibleBaseUrl: settings.codebaseIndexOpenAiCompatibleBaseUrl,
codebaseIndexOpenAiCompatibleModelDimension: settings.codebaseIndexOpenAiCompatibleModelDimension,
}

// Save global state first
await updateGlobalState("codebaseIndexConfig", globalStateConfig)

// Save secrets directly using context proxy
if (settings.codeIndexOpenAiKey !== undefined) {
await provider.contextProxy.storeSecret("codeIndexOpenAiKey", settings.codeIndexOpenAiKey)
}
if (settings.codeIndexQdrantApiKey !== undefined) {
await provider.contextProxy.storeSecret("codeIndexQdrantApiKey", settings.codeIndexQdrantApiKey)
}
if (settings.codebaseIndexOpenAiCompatibleApiKey !== undefined) {
await provider.contextProxy.storeSecret(
"codebaseIndexOpenAiCompatibleApiKey",
settings.codebaseIndexOpenAiCompatibleApiKey,
)
}
if (settings.codebaseIndexGeminiApiKey !== undefined) {
await provider.contextProxy.storeSecret(
"codebaseIndexGeminiApiKey",
settings.codebaseIndexGeminiApiKey,
)
}

// Verify secrets are actually stored
const storedOpenAiKey = provider.contextProxy.getSecret("codeIndexOpenAiKey")

// Notify code index manager of changes
if (provider.codeIndexManager) {
await provider.codeIndexManager.handleExternalSettingsChange()
await provider.codeIndexManager.handleSettingsChange()

// If now configured and enabled, start indexing automatically
// Auto-start indexing if now enabled and configured
if (provider.codeIndexManager.isFeatureEnabled && provider.codeIndexManager.isFeatureConfigured) {
if (!provider.codeIndexManager.isInitialized) {
await provider.codeIndexManager.initialize(provider.contextProxy)
}
// Start indexing in background (no await)
provider.codeIndexManager.startIndexing()
}
}

// Send success response
await provider.postMessageToWebview({
type: "codeIndexSettingsSaved",
success: true,
settings: globalStateConfig,
})

// Update webview state
await provider.postStateToWebview()
} catch (error) {
provider.log(
`[CodeIndexManager] Error during background CodeIndexManager configuration/indexing: ${error.message || error}`,
)
provider.log(`Error saving code index settings: ${error.message || error}`)
await provider.postMessageToWebview({
type: "codeIndexSettingsSaved",
success: false,
error: error.message || "Failed to save settings",
})
}

await provider.postStateToWebview()
break
}

case "requestIndexingStatus": {
const status = provider.codeIndexManager!.getCurrentStatus()
provider.postMessageToWebview({
Expand All @@ -1846,6 +1909,26 @@ export const webviewMessageHandler = async (
})
break
}
case "requestCodeIndexSecretStatus": {
// Check if secrets are set using the VSCode context directly for async access
const hasOpenAiKey = !!(await provider.context.secrets.get("codeIndexOpenAiKey"))
const hasQdrantApiKey = !!(await provider.context.secrets.get("codeIndexQdrantApiKey"))
const hasOpenAiCompatibleApiKey = !!(await provider.context.secrets.get(
"codebaseIndexOpenAiCompatibleApiKey",
))
const hasGeminiApiKey = !!(await provider.context.secrets.get("codebaseIndexGeminiApiKey"))

provider.postMessageToWebview({
type: "codeIndexSecretStatus",
values: {
hasOpenAiKey,
hasQdrantApiKey,
hasOpenAiCompatibleApiKey,
hasGeminiApiKey,
},
})
break
}
case "startIndexing": {
try {
const manager = provider.codeIndexManager!
Expand Down
Loading