@@ -549,7 +549,7 @@ describe("ClineProvider", () => {
549549 profileThresholds : { } ,
550550 hasOpenedModeSelector : false ,
551551 diagnosticsEnabled : true ,
552- openRouterImageApiKey : undefined ,
552+ openRouterImageApiKeyConfigured : false ,
553553 openRouterImageGenerationSelectedModel : undefined ,
554554 taskSyncEnabled : false ,
555555 checkpointTimeout : DEFAULT_CHECKPOINT_TIMEOUT_SECONDS ,
@@ -564,6 +564,27 @@ describe("ClineProvider", () => {
564564 expect ( mockPostMessage ) . toHaveBeenCalledWith ( message )
565565 } )
566566
567+ describe ( "getStateToPostToWebview secrets redaction" , ( ) => {
568+ test ( "omits raw openRouterImageApiKey from broadcast payload when key is set" , async ( ) => {
569+ // Use contextProxy.setValue rather than mocking secrets.get because ContextProxy only
570+ // reads secrets.get during initialize() (which ran during provider construction). Any
571+ // mock changes after construction are too late — they never reach secretCache.
572+ await provider . contextProxy . setValue ( "openRouterImageApiKey" , "sk-or-v1-supersecret" )
573+
574+ const state = await provider . getStateToPostToWebview ( )
575+
576+ expect ( "openRouterImageApiKey" in state ) . toBe ( false )
577+ expect ( state . openRouterImageApiKeyConfigured ) . toBe ( true )
578+ } )
579+
580+ test ( "sets openRouterImageApiKeyConfigured to false when no key is stored" , async ( ) => {
581+ const state = await provider . getStateToPostToWebview ( )
582+
583+ expect ( "openRouterImageApiKey" in state ) . toBe ( false )
584+ expect ( state . openRouterImageApiKeyConfigured ) . toBe ( false )
585+ } )
586+ } )
587+
567588 test ( "postMessageToWebview does not throw when webview is disposed" , async ( ) => {
568589 await provider . resolveWebviewView ( mockWebviewView )
569590
0 commit comments