|
6 | 6 | GLOBAL_SETTINGS_KEYS, |
7 | 7 | SECRET_STATE_KEYS, |
8 | 8 | GLOBAL_STATE_KEYS, |
| 9 | + GLOBAL_SECRET_KEYS, |
9 | 10 | type ProviderSettings, |
10 | 11 | type GlobalSettings, |
11 | 12 | type SecretState, |
@@ -61,19 +62,77 @@ export class ContextProxy { |
61 | 62 | } |
62 | 63 | } |
63 | 64 |
|
64 | | - const promises = SECRET_STATE_KEYS.map(async (key) => { |
65 | | - try { |
66 | | - this.secretCache[key] = await this.originalContext.secrets.get(key) |
67 | | - } catch (error) { |
68 | | - logger.error(`Error loading secret ${key}: ${error instanceof Error ? error.message : String(error)}`) |
69 | | - } |
70 | | - }) |
| 65 | + const promises = [ |
| 66 | + ...SECRET_STATE_KEYS.map(async (key) => { |
| 67 | + try { |
| 68 | + this.secretCache[key] = await this.originalContext.secrets.get(key) |
| 69 | + } catch (error) { |
| 70 | + logger.error( |
| 71 | + `Error loading secret ${key}: ${error instanceof Error ? error.message : String(error)}`, |
| 72 | + ) |
| 73 | + } |
| 74 | + }), |
| 75 | + ...GLOBAL_SECRET_KEYS.map(async (key) => { |
| 76 | + try { |
| 77 | + this.secretCache[key] = await this.originalContext.secrets.get(key) |
| 78 | + } catch (error) { |
| 79 | + logger.error( |
| 80 | + `Error loading global secret ${key}: ${error instanceof Error ? error.message : String(error)}`, |
| 81 | + ) |
| 82 | + } |
| 83 | + }), |
| 84 | + ] |
71 | 85 |
|
72 | 86 | await Promise.all(promises) |
73 | 87 |
|
| 88 | + // Migration: Check for old nested image generation settings and migrate them |
| 89 | + await this.migrateImageGenerationSettings() |
| 90 | + |
74 | 91 | this._isInitialized = true |
75 | 92 | } |
76 | 93 |
|
| 94 | + /** |
| 95 | + * Migrates old nested openRouterImageGenerationSettings to the new flattened structure |
| 96 | + */ |
| 97 | + private async migrateImageGenerationSettings() { |
| 98 | + try { |
| 99 | + // Check if there's an old nested structure |
| 100 | + const oldNestedSettings = this.originalContext.globalState.get<any>("openRouterImageGenerationSettings") |
| 101 | + |
| 102 | + if (oldNestedSettings && typeof oldNestedSettings === "object") { |
| 103 | + logger.info("Migrating old nested image generation settings to flattened structure") |
| 104 | + |
| 105 | + // Migrate the API key if it exists and we don't already have one |
| 106 | + if (oldNestedSettings.openRouterApiKey && !this.secretCache.openRouterImageApiKey) { |
| 107 | + await this.originalContext.secrets.store( |
| 108 | + "openRouterImageApiKey", |
| 109 | + oldNestedSettings.openRouterApiKey, |
| 110 | + ) |
| 111 | + this.secretCache.openRouterImageApiKey = oldNestedSettings.openRouterApiKey |
| 112 | + logger.info("Migrated openRouterImageApiKey to secrets") |
| 113 | + } |
| 114 | + |
| 115 | + // Migrate the selected model if it exists and we don't already have one |
| 116 | + if (oldNestedSettings.selectedModel && !this.stateCache.openRouterImageGenerationSelectedModel) { |
| 117 | + await this.originalContext.globalState.update( |
| 118 | + "openRouterImageGenerationSelectedModel", |
| 119 | + oldNestedSettings.selectedModel, |
| 120 | + ) |
| 121 | + this.stateCache.openRouterImageGenerationSelectedModel = oldNestedSettings.selectedModel |
| 122 | + logger.info("Migrated openRouterImageGenerationSelectedModel to global state") |
| 123 | + } |
| 124 | + |
| 125 | + // Clean up the old nested structure |
| 126 | + await this.originalContext.globalState.update("openRouterImageGenerationSettings", undefined) |
| 127 | + logger.info("Removed old nested openRouterImageGenerationSettings") |
| 128 | + } |
| 129 | + } catch (error) { |
| 130 | + logger.error( |
| 131 | + `Error during image generation settings migration: ${error instanceof Error ? error.message : String(error)}`, |
| 132 | + ) |
| 133 | + } |
| 134 | + } |
| 135 | + |
77 | 136 | public get extensionUri() { |
78 | 137 | return this.originalContext.extensionUri |
79 | 138 | } |
@@ -152,20 +211,34 @@ export class ContextProxy { |
152 | 211 | * This is useful when you need to ensure the cache has the latest values |
153 | 212 | */ |
154 | 213 | async refreshSecrets(): Promise<void> { |
155 | | - const promises = SECRET_STATE_KEYS.map(async (key) => { |
156 | | - try { |
157 | | - this.secretCache[key] = await this.originalContext.secrets.get(key) |
158 | | - } catch (error) { |
159 | | - logger.error( |
160 | | - `Error refreshing secret ${key}: ${error instanceof Error ? error.message : String(error)}`, |
161 | | - ) |
162 | | - } |
163 | | - }) |
| 214 | + const promises = [ |
| 215 | + ...SECRET_STATE_KEYS.map(async (key) => { |
| 216 | + try { |
| 217 | + this.secretCache[key] = await this.originalContext.secrets.get(key) |
| 218 | + } catch (error) { |
| 219 | + logger.error( |
| 220 | + `Error refreshing secret ${key}: ${error instanceof Error ? error.message : String(error)}`, |
| 221 | + ) |
| 222 | + } |
| 223 | + }), |
| 224 | + ...GLOBAL_SECRET_KEYS.map(async (key) => { |
| 225 | + try { |
| 226 | + this.secretCache[key] = await this.originalContext.secrets.get(key) |
| 227 | + } catch (error) { |
| 228 | + logger.error( |
| 229 | + `Error refreshing global secret ${key}: ${error instanceof Error ? error.message : String(error)}`, |
| 230 | + ) |
| 231 | + } |
| 232 | + }), |
| 233 | + ] |
164 | 234 | await Promise.all(promises) |
165 | 235 | } |
166 | 236 |
|
167 | 237 | private getAllSecretState(): SecretState { |
168 | | - return Object.fromEntries(SECRET_STATE_KEYS.map((key) => [key, this.getSecret(key)])) |
| 238 | + return Object.fromEntries([ |
| 239 | + ...SECRET_STATE_KEYS.map((key) => [key, this.getSecret(key as SecretStateKey)]), |
| 240 | + ...GLOBAL_SECRET_KEYS.map((key) => [key, this.getSecret(key as SecretStateKey)]), |
| 241 | + ]) |
169 | 242 | } |
170 | 243 |
|
171 | 244 | /** |
@@ -232,18 +305,24 @@ export class ContextProxy { |
232 | 305 | * RooCodeSettings |
233 | 306 | */ |
234 | 307 |
|
235 | | - public setValue<K extends RooCodeSettingsKey>(key: K, value: RooCodeSettings[K]) { |
236 | | - return isSecretStateKey(key) ? this.storeSecret(key, value as string) : this.updateGlobalState(key, value) |
| 308 | + public async setValue<K extends RooCodeSettingsKey>(key: K, value: RooCodeSettings[K]) { |
| 309 | + return isSecretStateKey(key) |
| 310 | + ? this.storeSecret(key as SecretStateKey, value as string) |
| 311 | + : this.updateGlobalState(key as GlobalStateKey, value) |
237 | 312 | } |
238 | 313 |
|
239 | 314 | public getValue<K extends RooCodeSettingsKey>(key: K): RooCodeSettings[K] { |
240 | 315 | return isSecretStateKey(key) |
241 | | - ? (this.getSecret(key) as RooCodeSettings[K]) |
242 | | - : (this.getGlobalState(key) as RooCodeSettings[K]) |
| 316 | + ? (this.getSecret(key as SecretStateKey) as RooCodeSettings[K]) |
| 317 | + : (this.getGlobalState(key as GlobalStateKey) as RooCodeSettings[K]) |
243 | 318 | } |
244 | 319 |
|
245 | 320 | public getValues(): RooCodeSettings { |
246 | | - return { ...this.getAllGlobalState(), ...this.getAllSecretState() } |
| 321 | + const globalState = this.getAllGlobalState() |
| 322 | + const secretState = this.getAllSecretState() |
| 323 | + |
| 324 | + // Simply merge all states - no nested secrets to handle |
| 325 | + return { ...globalState, ...secretState } |
247 | 326 | } |
248 | 327 |
|
249 | 328 | public async setValues(values: RooCodeSettings) { |
@@ -285,6 +364,7 @@ export class ContextProxy { |
285 | 364 | await Promise.all([ |
286 | 365 | ...GLOBAL_STATE_KEYS.map((key) => this.originalContext.globalState.update(key, undefined)), |
287 | 366 | ...SECRET_STATE_KEYS.map((key) => this.originalContext.secrets.delete(key)), |
| 367 | + ...GLOBAL_SECRET_KEYS.map((key) => this.originalContext.secrets.delete(key)), |
288 | 368 | ]) |
289 | 369 |
|
290 | 370 | await this.initialize() |
|
0 commit comments