@@ -296,79 +296,233 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
296296
297297 const handleSubmit = ( ) => {
298298 if ( isSettingValid ) {
299- vscode . postMessage ( { type : "language" , text : language } )
300- vscode . postMessage ( { type : "alwaysAllowReadOnly" , bool : alwaysAllowReadOnly } )
301- vscode . postMessage ( {
302- type : "alwaysAllowReadOnlyOutsideWorkspace" ,
303- bool : alwaysAllowReadOnlyOutsideWorkspace ,
304- } )
305- vscode . postMessage ( { type : "alwaysAllowWrite" , bool : alwaysAllowWrite } )
306- vscode . postMessage ( { type : "alwaysAllowWriteOutsideWorkspace" , bool : alwaysAllowWriteOutsideWorkspace } )
307- vscode . postMessage ( { type : "alwaysAllowWriteProtected" , bool : alwaysAllowWriteProtected } )
308- vscode . postMessage ( { type : "alwaysAllowExecute" , bool : alwaysAllowExecute } )
309- vscode . postMessage ( { type : "alwaysAllowBrowser" , bool : alwaysAllowBrowser } )
310- vscode . postMessage ( { type : "alwaysAllowMcp" , bool : alwaysAllowMcp } )
311- vscode . postMessage ( { type : "allowedCommands" , commands : allowedCommands ?? [ ] } )
312- vscode . postMessage ( { type : "deniedCommands" , commands : deniedCommands ?? [ ] } )
313- vscode . postMessage ( { type : "allowedMaxRequests" , value : allowedMaxRequests ?? undefined } )
314- vscode . postMessage ( { type : "allowedMaxCost" , value : allowedMaxCost ?? undefined } )
315- vscode . postMessage ( { type : "autoCondenseContext" , bool : autoCondenseContext } )
316- vscode . postMessage ( { type : "autoCondenseContextPercent" , value : autoCondenseContextPercent } )
317- vscode . postMessage ( { type : "browserToolEnabled" , bool : browserToolEnabled } )
318- vscode . postMessage ( { type : "soundEnabled" , bool : soundEnabled } )
319- vscode . postMessage ( { type : "ttsEnabled" , bool : ttsEnabled } )
320- vscode . postMessage ( { type : "ttsSpeed" , value : ttsSpeed } )
321- vscode . postMessage ( { type : "soundVolume" , value : soundVolume } )
322- vscode . postMessage ( { type : "diffEnabled" , bool : diffEnabled } )
323- vscode . postMessage ( { type : "enableCheckpoints" , bool : enableCheckpoints } )
324- vscode . postMessage ( { type : "browserViewportSize" , text : browserViewportSize } )
325- vscode . postMessage ( { type : "remoteBrowserHost" , text : remoteBrowserHost } )
326- vscode . postMessage ( { type : "remoteBrowserEnabled" , bool : remoteBrowserEnabled } )
327- vscode . postMessage ( { type : "fuzzyMatchThreshold" , value : fuzzyMatchThreshold ?? 1.0 } )
328- vscode . postMessage ( { type : "writeDelayMs" , value : writeDelayMs } )
329- vscode . postMessage ( { type : "screenshotQuality" , value : screenshotQuality ?? 75 } )
330- vscode . postMessage ( { type : "terminalOutputLineLimit" , value : terminalOutputLineLimit ?? 500 } )
331- vscode . postMessage ( { type : "terminalOutputCharacterLimit" , value : terminalOutputCharacterLimit ?? 50000 } )
332- vscode . postMessage ( { type : "terminalShellIntegrationTimeout" , value : terminalShellIntegrationTimeout } )
333- vscode . postMessage ( { type : "terminalShellIntegrationDisabled" , bool : terminalShellIntegrationDisabled } )
334- vscode . postMessage ( { type : "terminalCommandDelay" , value : terminalCommandDelay } )
335- vscode . postMessage ( { type : "terminalPowershellCounter" , bool : terminalPowershellCounter } )
336- vscode . postMessage ( { type : "terminalZshClearEolMark" , bool : terminalZshClearEolMark } )
337- vscode . postMessage ( { type : "terminalZshOhMy" , bool : terminalZshOhMy } )
338- vscode . postMessage ( { type : "terminalZshP10k" , bool : terminalZshP10k } )
339- vscode . postMessage ( { type : "terminalZdotdir" , bool : terminalZdotdir } )
340- vscode . postMessage ( { type : "terminalCompressProgressBar" , bool : terminalCompressProgressBar } )
341- vscode . postMessage ( { type : "mcpEnabled" , bool : mcpEnabled } )
342- vscode . postMessage ( { type : "alwaysApproveResubmit" , bool : alwaysApproveResubmit } )
343- vscode . postMessage ( { type : "requestDelaySeconds" , value : requestDelaySeconds } )
344- vscode . postMessage ( { type : "maxOpenTabsContext" , value : maxOpenTabsContext } )
345- vscode . postMessage ( { type : "maxWorkspaceFiles" , value : maxWorkspaceFiles ?? 200 } )
346- vscode . postMessage ( { type : "showRooIgnoredFiles" , bool : showRooIgnoredFiles } )
347- vscode . postMessage ( { type : "maxReadFileLine" , value : maxReadFileLine ?? - 1 } )
348- vscode . postMessage ( { type : "maxImageFileSize" , value : maxImageFileSize ?? 5 } )
349- vscode . postMessage ( { type : "maxTotalImageSize" , value : maxTotalImageSize ?? 20 } )
350- vscode . postMessage ( { type : "maxConcurrentFileReads" , value : cachedState . maxConcurrentFileReads ?? 5 } )
351- vscode . postMessage ( { type : "includeDiagnosticMessages" , bool : includeDiagnosticMessages } )
352- vscode . postMessage ( { type : "maxDiagnosticMessages" , value : maxDiagnosticMessages ?? 50 } )
353- vscode . postMessage ( { type : "currentApiConfigName" , text : currentApiConfigName } )
354- vscode . postMessage ( { type : "updateExperimental" , values : experiments } )
355- vscode . postMessage ( { type : "alwaysAllowModeSwitch" , bool : alwaysAllowModeSwitch } )
356- vscode . postMessage ( { type : "alwaysAllowSubtasks" , bool : alwaysAllowSubtasks } )
357- vscode . postMessage ( { type : "alwaysAllowFollowupQuestions" , bool : alwaysAllowFollowupQuestions } )
358- vscode . postMessage ( { type : "alwaysAllowUpdateTodoList" , bool : alwaysAllowUpdateTodoList } )
359- vscode . postMessage ( { type : "followupAutoApproveTimeoutMs" , value : followupAutoApproveTimeoutMs } )
360- vscode . postMessage ( { type : "condensingApiConfigId" , text : condensingApiConfigId || "" } )
361- vscode . postMessage ( { type : "updateCondensingPrompt" , text : customCondensingPrompt || "" } )
362- vscode . postMessage ( { type : "updateSupportPrompt" , values : customSupportPrompts || { } } )
363- vscode . postMessage ( { type : "includeTaskHistoryInEnhance" , bool : includeTaskHistoryInEnhance ?? true } )
364- vscode . postMessage ( { type : "upsertApiConfiguration" , text : currentApiConfigName , apiConfiguration } )
365- vscode . postMessage ( { type : "telemetrySetting" , text : telemetrySetting } )
366- vscode . postMessage ( { type : "profileThresholds" , values : profileThresholds } )
367- vscode . postMessage ( { type : "openRouterImageApiKey" , text : openRouterImageApiKey } )
368- vscode . postMessage ( {
369- type : "openRouterImageGenerationSelectedModel" ,
370- text : openRouterImageGenerationSelectedModel ,
371- } )
299+ // Helper function to check if a value has changed
300+ const hasChanged = ( cachedValue : any , originalValue : any ) : boolean => {
301+ // Handle objects and arrays with deep comparison
302+ if ( typeof cachedValue === "object" && cachedValue !== null ) {
303+ return JSON . stringify ( cachedValue ) !== JSON . stringify ( originalValue )
304+ }
305+ return cachedValue !== originalValue
306+ }
307+
308+ // Only send messages for settings that have actually changed
309+ if ( hasChanged ( language , extensionState . language ) ) {
310+ vscode . postMessage ( { type : "language" , text : language } )
311+ }
312+ if ( hasChanged ( alwaysAllowReadOnly , extensionState . alwaysAllowReadOnly ) ) {
313+ vscode . postMessage ( { type : "alwaysAllowReadOnly" , bool : alwaysAllowReadOnly } )
314+ }
315+ if ( hasChanged ( alwaysAllowReadOnlyOutsideWorkspace , extensionState . alwaysAllowReadOnlyOutsideWorkspace ) ) {
316+ vscode . postMessage ( {
317+ type : "alwaysAllowReadOnlyOutsideWorkspace" ,
318+ bool : alwaysAllowReadOnlyOutsideWorkspace ,
319+ } )
320+ }
321+ if ( hasChanged ( alwaysAllowWrite , extensionState . alwaysAllowWrite ) ) {
322+ vscode . postMessage ( { type : "alwaysAllowWrite" , bool : alwaysAllowWrite } )
323+ }
324+ if ( hasChanged ( alwaysAllowWriteOutsideWorkspace , extensionState . alwaysAllowWriteOutsideWorkspace ) ) {
325+ vscode . postMessage ( { type : "alwaysAllowWriteOutsideWorkspace" , bool : alwaysAllowWriteOutsideWorkspace } )
326+ }
327+ if ( hasChanged ( alwaysAllowWriteProtected , extensionState . alwaysAllowWriteProtected ) ) {
328+ vscode . postMessage ( { type : "alwaysAllowWriteProtected" , bool : alwaysAllowWriteProtected } )
329+ }
330+ if ( hasChanged ( alwaysAllowExecute , extensionState . alwaysAllowExecute ) ) {
331+ vscode . postMessage ( { type : "alwaysAllowExecute" , bool : alwaysAllowExecute } )
332+ }
333+ if ( hasChanged ( alwaysAllowBrowser , extensionState . alwaysAllowBrowser ) ) {
334+ vscode . postMessage ( { type : "alwaysAllowBrowser" , bool : alwaysAllowBrowser } )
335+ }
336+ if ( hasChanged ( alwaysAllowMcp , extensionState . alwaysAllowMcp ) ) {
337+ vscode . postMessage ( { type : "alwaysAllowMcp" , bool : alwaysAllowMcp } )
338+ }
339+ if ( hasChanged ( allowedCommands , extensionState . allowedCommands ) ) {
340+ vscode . postMessage ( { type : "allowedCommands" , commands : allowedCommands ?? [ ] } )
341+ }
342+ if ( hasChanged ( deniedCommands , extensionState . deniedCommands ) ) {
343+ vscode . postMessage ( { type : "deniedCommands" , commands : deniedCommands ?? [ ] } )
344+ }
345+ if ( hasChanged ( allowedMaxRequests , extensionState . allowedMaxRequests ) ) {
346+ vscode . postMessage ( { type : "allowedMaxRequests" , value : allowedMaxRequests ?? undefined } )
347+ }
348+ if ( hasChanged ( allowedMaxCost , extensionState . allowedMaxCost ) ) {
349+ vscode . postMessage ( { type : "allowedMaxCost" , value : allowedMaxCost ?? undefined } )
350+ }
351+ // Only send autoCondenseContext if it has actually changed
352+ if ( hasChanged ( autoCondenseContext , extensionState . autoCondenseContext ) ) {
353+ vscode . postMessage ( { type : "autoCondenseContext" , bool : autoCondenseContext } )
354+ }
355+ // Only send autoCondenseContextPercent if it has actually changed
356+ if ( hasChanged ( autoCondenseContextPercent , extensionState . autoCondenseContextPercent ) ) {
357+ vscode . postMessage ( { type : "autoCondenseContextPercent" , value : autoCondenseContextPercent } )
358+ }
359+ if ( hasChanged ( browserToolEnabled , extensionState . browserToolEnabled ) ) {
360+ vscode . postMessage ( { type : "browserToolEnabled" , bool : browserToolEnabled } )
361+ }
362+ if ( hasChanged ( soundEnabled , extensionState . soundEnabled ) ) {
363+ vscode . postMessage ( { type : "soundEnabled" , bool : soundEnabled } )
364+ }
365+ if ( hasChanged ( ttsEnabled , extensionState . ttsEnabled ) ) {
366+ vscode . postMessage ( { type : "ttsEnabled" , bool : ttsEnabled } )
367+ }
368+ if ( hasChanged ( ttsSpeed , extensionState . ttsSpeed ) ) {
369+ vscode . postMessage ( { type : "ttsSpeed" , value : ttsSpeed } )
370+ }
371+ if ( hasChanged ( soundVolume , extensionState . soundVolume ) ) {
372+ vscode . postMessage ( { type : "soundVolume" , value : soundVolume } )
373+ }
374+ if ( hasChanged ( diffEnabled , extensionState . diffEnabled ) ) {
375+ vscode . postMessage ( { type : "diffEnabled" , bool : diffEnabled } )
376+ }
377+ if ( hasChanged ( enableCheckpoints , extensionState . enableCheckpoints ) ) {
378+ vscode . postMessage ( { type : "enableCheckpoints" , bool : enableCheckpoints } )
379+ }
380+ if ( hasChanged ( browserViewportSize , extensionState . browserViewportSize ) ) {
381+ vscode . postMessage ( { type : "browserViewportSize" , text : browserViewportSize } )
382+ }
383+ if ( hasChanged ( remoteBrowserHost , extensionState . remoteBrowserHost ) ) {
384+ vscode . postMessage ( { type : "remoteBrowserHost" , text : remoteBrowserHost } )
385+ }
386+ if ( hasChanged ( remoteBrowserEnabled , extensionState . remoteBrowserEnabled ) ) {
387+ vscode . postMessage ( { type : "remoteBrowserEnabled" , bool : remoteBrowserEnabled } )
388+ }
389+ if ( hasChanged ( fuzzyMatchThreshold , extensionState . fuzzyMatchThreshold ) ) {
390+ vscode . postMessage ( { type : "fuzzyMatchThreshold" , value : fuzzyMatchThreshold ?? 1.0 } )
391+ }
392+ if ( hasChanged ( writeDelayMs , extensionState . writeDelayMs ) ) {
393+ vscode . postMessage ( { type : "writeDelayMs" , value : writeDelayMs } )
394+ }
395+ if ( hasChanged ( screenshotQuality , extensionState . screenshotQuality ) ) {
396+ vscode . postMessage ( { type : "screenshotQuality" , value : screenshotQuality ?? 75 } )
397+ }
398+ if ( hasChanged ( terminalOutputLineLimit , extensionState . terminalOutputLineLimit ) ) {
399+ vscode . postMessage ( { type : "terminalOutputLineLimit" , value : terminalOutputLineLimit ?? 500 } )
400+ }
401+ if ( hasChanged ( terminalOutputCharacterLimit , extensionState . terminalOutputCharacterLimit ) ) {
402+ vscode . postMessage ( {
403+ type : "terminalOutputCharacterLimit" ,
404+ value : terminalOutputCharacterLimit ?? 50000 ,
405+ } )
406+ }
407+ if ( hasChanged ( terminalShellIntegrationTimeout , extensionState . terminalShellIntegrationTimeout ) ) {
408+ vscode . postMessage ( { type : "terminalShellIntegrationTimeout" , value : terminalShellIntegrationTimeout } )
409+ }
410+ if ( hasChanged ( terminalShellIntegrationDisabled , extensionState . terminalShellIntegrationDisabled ) ) {
411+ vscode . postMessage ( { type : "terminalShellIntegrationDisabled" , bool : terminalShellIntegrationDisabled } )
412+ }
413+ if ( hasChanged ( terminalCommandDelay , extensionState . terminalCommandDelay ) ) {
414+ vscode . postMessage ( { type : "terminalCommandDelay" , value : terminalCommandDelay } )
415+ }
416+ if ( hasChanged ( terminalPowershellCounter , extensionState . terminalPowershellCounter ) ) {
417+ vscode . postMessage ( { type : "terminalPowershellCounter" , bool : terminalPowershellCounter } )
418+ }
419+ if ( hasChanged ( terminalZshClearEolMark , extensionState . terminalZshClearEolMark ) ) {
420+ vscode . postMessage ( { type : "terminalZshClearEolMark" , bool : terminalZshClearEolMark } )
421+ }
422+ if ( hasChanged ( terminalZshOhMy , extensionState . terminalZshOhMy ) ) {
423+ vscode . postMessage ( { type : "terminalZshOhMy" , bool : terminalZshOhMy } )
424+ }
425+ if ( hasChanged ( terminalZshP10k , extensionState . terminalZshP10k ) ) {
426+ vscode . postMessage ( { type : "terminalZshP10k" , bool : terminalZshP10k } )
427+ }
428+ if ( hasChanged ( terminalZdotdir , extensionState . terminalZdotdir ) ) {
429+ vscode . postMessage ( { type : "terminalZdotdir" , bool : terminalZdotdir } )
430+ }
431+ if ( hasChanged ( terminalCompressProgressBar , extensionState . terminalCompressProgressBar ) ) {
432+ vscode . postMessage ( { type : "terminalCompressProgressBar" , bool : terminalCompressProgressBar } )
433+ }
434+ if ( hasChanged ( mcpEnabled , extensionState . mcpEnabled ) ) {
435+ vscode . postMessage ( { type : "mcpEnabled" , bool : mcpEnabled } )
436+ }
437+ if ( hasChanged ( alwaysApproveResubmit , extensionState . alwaysApproveResubmit ) ) {
438+ vscode . postMessage ( { type : "alwaysApproveResubmit" , bool : alwaysApproveResubmit } )
439+ }
440+ if ( hasChanged ( requestDelaySeconds , extensionState . requestDelaySeconds ) ) {
441+ vscode . postMessage ( { type : "requestDelaySeconds" , value : requestDelaySeconds } )
442+ }
443+ if ( hasChanged ( maxOpenTabsContext , extensionState . maxOpenTabsContext ) ) {
444+ vscode . postMessage ( { type : "maxOpenTabsContext" , value : maxOpenTabsContext } )
445+ }
446+ if ( hasChanged ( maxWorkspaceFiles , extensionState . maxWorkspaceFiles ) ) {
447+ vscode . postMessage ( { type : "maxWorkspaceFiles" , value : maxWorkspaceFiles ?? 200 } )
448+ }
449+ if ( hasChanged ( showRooIgnoredFiles , extensionState . showRooIgnoredFiles ) ) {
450+ vscode . postMessage ( { type : "showRooIgnoredFiles" , bool : showRooIgnoredFiles } )
451+ }
452+ if ( hasChanged ( maxReadFileLine , extensionState . maxReadFileLine ) ) {
453+ vscode . postMessage ( { type : "maxReadFileLine" , value : maxReadFileLine ?? - 1 } )
454+ }
455+ if ( hasChanged ( maxImageFileSize , extensionState . maxImageFileSize ) ) {
456+ vscode . postMessage ( { type : "maxImageFileSize" , value : maxImageFileSize ?? 5 } )
457+ }
458+ if ( hasChanged ( maxTotalImageSize , extensionState . maxTotalImageSize ) ) {
459+ vscode . postMessage ( { type : "maxTotalImageSize" , value : maxTotalImageSize ?? 20 } )
460+ }
461+ if ( hasChanged ( maxConcurrentFileReads , extensionState . maxConcurrentFileReads ) ) {
462+ vscode . postMessage ( { type : "maxConcurrentFileReads" , value : cachedState . maxConcurrentFileReads ?? 5 } )
463+ }
464+ if ( hasChanged ( includeDiagnosticMessages , extensionState . includeDiagnosticMessages ) ) {
465+ vscode . postMessage ( { type : "includeDiagnosticMessages" , bool : includeDiagnosticMessages } )
466+ }
467+ if ( hasChanged ( maxDiagnosticMessages , extensionState . maxDiagnosticMessages ) ) {
468+ vscode . postMessage ( { type : "maxDiagnosticMessages" , value : maxDiagnosticMessages ?? 50 } )
469+ }
470+ if ( hasChanged ( currentApiConfigName , extensionState . currentApiConfigName ) ) {
471+ vscode . postMessage ( { type : "currentApiConfigName" , text : currentApiConfigName } )
472+ }
473+ if ( hasChanged ( experiments , extensionState . experiments ) ) {
474+ vscode . postMessage ( { type : "updateExperimental" , values : experiments } )
475+ }
476+ if ( hasChanged ( alwaysAllowModeSwitch , extensionState . alwaysAllowModeSwitch ) ) {
477+ vscode . postMessage ( { type : "alwaysAllowModeSwitch" , bool : alwaysAllowModeSwitch } )
478+ }
479+ if ( hasChanged ( alwaysAllowSubtasks , extensionState . alwaysAllowSubtasks ) ) {
480+ vscode . postMessage ( { type : "alwaysAllowSubtasks" , bool : alwaysAllowSubtasks } )
481+ }
482+ if ( hasChanged ( alwaysAllowFollowupQuestions , extensionState . alwaysAllowFollowupQuestions ) ) {
483+ vscode . postMessage ( { type : "alwaysAllowFollowupQuestions" , bool : alwaysAllowFollowupQuestions } )
484+ }
485+ if ( hasChanged ( alwaysAllowUpdateTodoList , extensionState . alwaysAllowUpdateTodoList ) ) {
486+ vscode . postMessage ( { type : "alwaysAllowUpdateTodoList" , bool : alwaysAllowUpdateTodoList } )
487+ }
488+ if ( hasChanged ( followupAutoApproveTimeoutMs , extensionState . followupAutoApproveTimeoutMs ) ) {
489+ vscode . postMessage ( { type : "followupAutoApproveTimeoutMs" , value : followupAutoApproveTimeoutMs } )
490+ }
491+ if ( hasChanged ( condensingApiConfigId , extensionState . condensingApiConfigId ) ) {
492+ vscode . postMessage ( { type : "condensingApiConfigId" , text : condensingApiConfigId || "" } )
493+ }
494+ if ( hasChanged ( customCondensingPrompt , extensionState . customCondensingPrompt ) ) {
495+ vscode . postMessage ( { type : "updateCondensingPrompt" , text : customCondensingPrompt || "" } )
496+ }
497+ if ( hasChanged ( customSupportPrompts , extensionState . customSupportPrompts ) ) {
498+ vscode . postMessage ( { type : "updateSupportPrompt" , values : customSupportPrompts || { } } )
499+ }
500+ if ( hasChanged ( includeTaskHistoryInEnhance , extensionState . includeTaskHistoryInEnhance ) ) {
501+ vscode . postMessage ( { type : "includeTaskHistoryInEnhance" , bool : includeTaskHistoryInEnhance ?? true } )
502+ }
503+ if ( hasChanged ( apiConfiguration , extensionState . apiConfiguration ) ) {
504+ vscode . postMessage ( { type : "upsertApiConfiguration" , text : currentApiConfigName , apiConfiguration } )
505+ }
506+ if ( hasChanged ( telemetrySetting , extensionState . telemetrySetting ) ) {
507+ vscode . postMessage ( { type : "telemetrySetting" , text : telemetrySetting } )
508+ }
509+ if ( hasChanged ( profileThresholds , extensionState . profileThresholds ) ) {
510+ vscode . postMessage ( { type : "profileThresholds" , values : profileThresholds } )
511+ }
512+ if ( hasChanged ( openRouterImageApiKey , extensionState . openRouterImageApiKey ) ) {
513+ vscode . postMessage ( { type : "openRouterImageApiKey" , text : openRouterImageApiKey } )
514+ }
515+ if (
516+ hasChanged (
517+ openRouterImageGenerationSelectedModel ,
518+ extensionState . openRouterImageGenerationSelectedModel ,
519+ )
520+ ) {
521+ vscode . postMessage ( {
522+ type : "openRouterImageGenerationSelectedModel" ,
523+ text : openRouterImageGenerationSelectedModel ,
524+ } )
525+ }
372526 setChangeDetected ( false )
373527 }
374528 }
0 commit comments