@@ -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
@@ -428,51 +429,63 @@ export class ClineProvider
428429 }
429430 }
430431
431- private getPersistedViewStates ( ) : Record < string , PersistedViewState > {
432- const viewStates = this . contextProxy . getValue ( "viewStates" )
432+ private getPersistedViewStates ( options : { fresh ?: boolean } = { } ) : Record < string , PersistedViewState > {
433+ const viewStates = options . fresh
434+ ? this . context . globalState . get < GlobalState [ "viewStates" ] > ( "viewStates" )
435+ : this . contextProxy . getValue ( "viewStates" )
433436
434437 if ( ! viewStates || typeof viewStates !== "object" || Array . isArray ( viewStates ) ) {
435438 return { }
436439 }
437440
438- return viewStates
441+ return { ... viewStates }
439442 }
440443
441444 private async savePersistedViewState ( values : Partial < PersistedViewState > ) : Promise < void > {
442- const states = this . getPersistedViewStates ( )
443- const current = states [ this . viewStateId ] ?? { }
444- const next : PersistedViewState = { ...current }
445+ const write = ClineProvider . persistedViewStateWriteQueue . then ( async ( ) => {
446+ const states = this . getPersistedViewStates ( { fresh : true } )
447+ const current = states [ this . viewStateId ] ?? { }
448+ const next : PersistedViewState = { ...current }
449+
450+ if ( "mode" in values ) {
451+ if ( values . mode === undefined || values . mode === null ) {
452+ delete next . mode
453+ } else {
454+ next . mode = values . mode
455+ }
456+ }
445457
446- if ( "mode" in values ) {
447- if ( values . mode === undefined || values . mode === null ) {
448- delete next . mode
449- } else {
450- next . mode = values . mode
458+ if ( "currentApiConfigName" in values ) {
459+ if ( values . currentApiConfigName === undefined || values . currentApiConfigName === null ) {
460+ delete next . currentApiConfigName
461+ } else {
462+ next . currentApiConfigName = values . currentApiConfigName
463+ }
451464 }
452- }
453465
454- if ( "currentApiConfigName" in values ) {
455- if ( values . currentApiConfigName === undefined || values . currentApiConfigName === null ) {
456- delete next . currentApiConfigName
466+ if ( ! next . mode && ! next . currentApiConfigName ) {
467+ delete states [ this . viewStateId ]
457468 } else {
458- next . currentApiConfigName = values . currentApiConfigName
469+ next . updatedAt = values . updatedAt ?? Date . now ( )
470+ states [ this . viewStateId ] = next
459471 }
460- }
461472
462- if ( ! next . mode && ! next . currentApiConfigName ) {
463- delete states [ this . viewStateId ]
464- } else {
465- next . updatedAt = values . updatedAt ?? Date . now ( )
466- states [ this . viewStateId ] = next
467- }
473+ await this . contextProxy . setValue ( "viewStates" , this . prunePersistedViewStates ( states ) )
474+ } )
468475
469- await this . contextProxy . setValue ( "viewStates" , this . prunePersistedViewStates ( states ) )
476+ ClineProvider . persistedViewStateWriteQueue = write . catch ( ( ) => { } )
477+ await write
470478 }
471479
472480 private async clearPersistedViewState ( viewStateId = this . viewStateId ) : Promise < void > {
473- const states = this . getPersistedViewStates ( )
474- delete states [ viewStateId ]
475- await this . contextProxy . setValue ( "viewStates" , states )
481+ const write = ClineProvider . persistedViewStateWriteQueue . then ( async ( ) => {
482+ const states = this . getPersistedViewStates ( { fresh : true } )
483+ delete states [ viewStateId ]
484+ await this . contextProxy . setValue ( "viewStates" , states )
485+ } )
486+
487+ ClineProvider . persistedViewStateWriteQueue = write . catch ( ( ) => { } )
488+ await write
476489 }
477490
478491 private prunePersistedViewStates ( states : Record < string , PersistedViewState > ) : Record < string , PersistedViewState > {
@@ -3008,6 +3021,7 @@ export class ClineProvider
30083021 public async setValue < K extends keyof RooCodeSettings > ( key : K , value : RooCodeSettings [ K ] ) {
30093022 await this . contextProxy . setValue ( key , value )
30103023 this . _updateViewLocalStateFromMutation ( { [ key ] : value } )
3024+ await this . _persistViewLocalStateFromMutation ( { [ key ] : value } )
30113025 }
30123026
30133027 public getValue < K extends keyof RooCodeSettings > ( key : K ) {
@@ -3021,6 +3035,7 @@ export class ClineProvider
30213035 public async setValues ( values : RooCodeSettings ) {
30223036 await this . contextProxy . setValues ( values )
30233037 this . _updateViewLocalStateFromMutation ( values )
3038+ await this . _persistViewLocalStateFromMutation ( values )
30243039 }
30253040
30263041 /**
@@ -3070,6 +3085,24 @@ export class ClineProvider
30703085 }
30713086 }
30723087
3088+ private async _persistViewLocalStateFromMutation (
3089+ values : Partial < RooCodeSettings > & Partial < ExtensionState > ,
3090+ ) : Promise < void > {
3091+ const persistedValues : Partial < PersistedViewState > = { }
3092+
3093+ if ( "mode" in values ) {
3094+ persistedValues . mode = values . mode as PersistedViewState [ "mode" ]
3095+ }
3096+
3097+ if ( "currentApiConfigName" in values ) {
3098+ persistedValues . currentApiConfigName = values . currentApiConfigName
3099+ }
3100+
3101+ if ( "mode" in persistedValues || "currentApiConfigName" in persistedValues ) {
3102+ await this . savePersistedViewState ( persistedValues )
3103+ }
3104+ }
3105+
30733106 /**
30743107 * Clear view-local state cache so that getState() falls back to ContextProxy defaults.
30753108 */
0 commit comments