feat: add lock toggle to pin API config across all modes in workspace#11295
Merged
hannesrudolph merged 2 commits intomainfrom Feb 8, 2026
Merged
feat: add lock toggle to pin API config across all modes in workspace#11295hannesrudolph merged 2 commits intomainfrom
hannesrudolph merged 2 commits intomainfrom
Conversation
Add a lock/unlock toggle inside the API config selector popover (next to the settings gear) that, when enabled, applies the selected API configuration to all modes in the current workspace. - Add lockApiConfigAcrossModes to ExtensionState and WebviewMessage types - Store setting in workspaceState (per-workspace, not global) - When locked, activateProviderProfile sets config for all modes - Lock icon in ApiConfigSelector popover bottom bar next to gear - Full i18n: English + 17 locale translations (all mention workspace scope) - 9 new tests: 2 ClineProvider, 2 handler, 5 UI (77 total pass)
7f74f5f to
fc49ed0
Compare
Contributor
No issues found. The latest commit refactors from write-fan-out to read-time override, which resolves the previous redundant
Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues. |
…config The original lock implementation used setModeConfig() fan-out to write the locked config to ALL modes globally. Since the lock flag lives in workspace- scoped workspaceState but modeApiConfigs are in global secrets, this caused cross-workspace data destruction. Replaced with read-time guards: - handleModeSwitch: early return when lock is on (skip per-mode config load) - createTaskWithHistoryItem: skip mode-based config restoration under lock - activateProviderProfile: removed fan-out block - lockApiConfigAcrossModes handler: simplified to flag + state post only - Fixed pre-existing workspaceState mock gap in ClineProvider.spec.ts and ClineProvider.sticky-profile.spec.ts
daniel-lxs
approved these changes
Feb 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Add a lock/unlock toggle inside the API config selector popover (next to the settings gear icon) that, when enabled, pins the currently selected API configuration across all mode switches in the current workspace.
When unlocked (default), switching modes loads each mode's saved API configuration (existing behavior). When locked, mode switches skip per-mode config loading entirely — the current API config stays active regardless of mode. Per-mode config mappings are not modified; they are simply bypassed at read time. Disabling the lock restores normal per-mode sticky behavior with all original mappings intact.
The setting is stored in
workspaceState(per-workspace), so locking in one workspace does not affect other workspaces.How It Works
The lock is implemented as a read-time override, not a write-time fan-out:
handleModeSwitch()checks the lock flag before loading per-mode config. If locked, it early-returns keeping the current API config active.createTaskWithHistoryItem()checks the lock flag before restoring mode-based API config from task history. If locked, the restoration is skipped.activateProviderProfile()has no lock-related logic — it writes to the current mode's config as normal, regardless of lock state.workspaceStateand posts state to the webview. No fan-out, no global side effects.This design ensures the workspace-scoped lock never mutates the global per-mode config mappings, preventing cross-workspace data destruction.
Changes
Core Implementation
packages/types/src/vscode-extension-host.ts— AddedlockApiConfigAcrossModestoExtensionStateandWebviewMessagetypessrc/core/webview/ClineProvider.ts— Reads lock state fromworkspaceState;handleModeSwitch()andcreateTaskWithHistoryItem()skip per-mode config loading when locked;getState()exposes lock flagsrc/core/webview/webviewMessageHandler.ts— Handler writes lock state toworkspaceStateand posts state to webviewwebview-ui/src/components/chat/ApiConfigSelector.tsx— Lock/unlock icon button in popover bottom bar next to settings gearwebview-ui/src/components/chat/ChatTextArea.tsx— Passes lock state + callback props to ApiConfigSelectorwebview-ui/src/context/ExtensionStateContext.tsx— DefaultlockApiConfigAcrossModes: falsei18n (18 locales)
chat.jsonlocale files updated with proper native translations for lock/unlock tooltip stringsTests
src/core/webview/__tests__/ClineProvider.lockApiConfig.spec.ts— Tests read-time override behavior (lock skips per-mode config, unlock preserves normal behavior)src/core/webview/__tests__/webviewMessageHandler.lockApiConfig.spec.ts— Tests handler sets flag without fan-outwebview-ui/src/components/chat/__tests__/ChatTextArea.lockApiConfig.spec.tsx— UI component testsworkspaceStatemock gaps in 4 existing test files