@@ -166,6 +166,7 @@ export class ClineProvider
166166 private static activeInstances : Set < ClineProvider > = new Set ( )
167167 private static nextViewId = 0
168168 private static readonly MAX_PERSISTED_VIEW_STATES = 50
169+ private static persistedViewStateWriteQueue : Promise < void > = Promise . resolve ( )
169170 private disposables : vscode . Disposable [ ] = [ ]
170171 private webviewDisposables : vscode . Disposable [ ] = [ ]
171172 private view ?: vscode . WebviewView | vscode . WebviewPanel
@@ -435,51 +436,63 @@ export class ClineProvider
435436 }
436437 }
437438
438- private getPersistedViewStates ( ) : Record < string , PersistedViewState > {
439- const viewStates = this . contextProxy . getValue ( "viewStates" )
439+ private getPersistedViewStates ( options : { fresh ?: boolean } = { } ) : Record < string , PersistedViewState > {
440+ const viewStates = options . fresh
441+ ? this . context . globalState . get < GlobalState [ "viewStates" ] > ( "viewStates" )
442+ : this . contextProxy . getValue ( "viewStates" )
440443
441444 if ( ! viewStates || typeof viewStates !== "object" || Array . isArray ( viewStates ) ) {
442445 return { }
443446 }
444447
445- return viewStates
448+ return { ... viewStates }
446449 }
447450
448451 private async savePersistedViewState ( values : Partial < PersistedViewState > ) : Promise < void > {
449- const states = this . getPersistedViewStates ( )
450- const current = states [ this . viewStateId ] ?? { }
451- const next : PersistedViewState = { ...current }
452+ const write = ClineProvider . persistedViewStateWriteQueue . then ( async ( ) => {
453+ const states = this . getPersistedViewStates ( { fresh : true } )
454+ const current = states [ this . viewStateId ] ?? { }
455+ const next : PersistedViewState = { ...current }
456+
457+ if ( "mode" in values ) {
458+ if ( values . mode === undefined || values . mode === null ) {
459+ delete next . mode
460+ } else {
461+ next . mode = values . mode
462+ }
463+ }
452464
453- if ( "mode" in values ) {
454- if ( values . mode === undefined || values . mode === null ) {
455- delete next . mode
456- } else {
457- next . mode = values . mode
465+ if ( "currentApiConfigName" in values ) {
466+ if ( values . currentApiConfigName === undefined || values . currentApiConfigName === null ) {
467+ delete next . currentApiConfigName
468+ } else {
469+ next . currentApiConfigName = values . currentApiConfigName
470+ }
458471 }
459- }
460472
461- if ( "currentApiConfigName" in values ) {
462- if ( values . currentApiConfigName === undefined || values . currentApiConfigName === null ) {
463- delete next . currentApiConfigName
473+ if ( ! next . mode && ! next . currentApiConfigName ) {
474+ delete states [ this . viewStateId ]
464475 } else {
465- next . currentApiConfigName = values . currentApiConfigName
476+ next . updatedAt = values . updatedAt ?? Date . now ( )
477+ states [ this . viewStateId ] = next
466478 }
467- }
468479
469- if ( ! next . mode && ! next . currentApiConfigName ) {
470- delete states [ this . viewStateId ]
471- } else {
472- next . updatedAt = values . updatedAt ?? Date . now ( )
473- states [ this . viewStateId ] = next
474- }
480+ await this . contextProxy . setValue ( "viewStates" , this . prunePersistedViewStates ( states ) )
481+ } )
475482
476- await this . contextProxy . setValue ( "viewStates" , this . prunePersistedViewStates ( states ) )
483+ ClineProvider . persistedViewStateWriteQueue = write . catch ( ( ) => { } )
484+ await write
477485 }
478486
479487 private async clearPersistedViewState ( viewStateId = this . viewStateId ) : Promise < void > {
480- const states = this . getPersistedViewStates ( )
481- delete states [ viewStateId ]
482- await this . contextProxy . setValue ( "viewStates" , states )
488+ const write = ClineProvider . persistedViewStateWriteQueue . then ( async ( ) => {
489+ const states = this . getPersistedViewStates ( { fresh : true } )
490+ delete states [ viewStateId ]
491+ await this . contextProxy . setValue ( "viewStates" , states )
492+ } )
493+
494+ ClineProvider . persistedViewStateWriteQueue = write . catch ( ( ) => { } )
495+ await write
483496 }
484497
485498 private prunePersistedViewStates ( states : Record < string , PersistedViewState > ) : Record < string , PersistedViewState > {
@@ -3041,6 +3054,7 @@ export class ClineProvider
30413054 public async setValue < K extends keyof RooCodeSettings > ( key : K , value : RooCodeSettings [ K ] ) {
30423055 await this . contextProxy . setValue ( key , value )
30433056 this . _updateViewLocalStateFromMutation ( { [ key ] : value } )
3057+ await this . _persistViewLocalStateFromMutation ( { [ key ] : value } )
30443058 }
30453059
30463060 public getValue < K extends keyof RooCodeSettings > ( key : K ) {
@@ -3054,6 +3068,7 @@ export class ClineProvider
30543068 public async setValues ( values : RooCodeSettings ) {
30553069 await this . contextProxy . setValues ( values )
30563070 this . _updateViewLocalStateFromMutation ( values )
3071+ await this . _persistViewLocalStateFromMutation ( values )
30573072 }
30583073
30593074 /**
@@ -3103,6 +3118,24 @@ export class ClineProvider
31033118 }
31043119 }
31053120
3121+ private async _persistViewLocalStateFromMutation (
3122+ values : Partial < RooCodeSettings > & Partial < ExtensionState > ,
3123+ ) : Promise < void > {
3124+ const persistedValues : Partial < PersistedViewState > = { }
3125+
3126+ if ( "mode" in values ) {
3127+ persistedValues . mode = values . mode as PersistedViewState [ "mode" ]
3128+ }
3129+
3130+ if ( "currentApiConfigName" in values ) {
3131+ persistedValues . currentApiConfigName = values . currentApiConfigName
3132+ }
3133+
3134+ if ( "mode" in persistedValues || "currentApiConfigName" in persistedValues ) {
3135+ await this . savePersistedViewState ( persistedValues )
3136+ }
3137+ }
3138+
31063139 /**
31073140 * Clear view-local state cache so that getState() falls back to ContextProxy defaults.
31083141 */
0 commit comments