From 15b066cc9c75e273fab787c0617bf6e73ed2d773 Mon Sep 17 00:00:00 2001 From: Roo Code Date: Thu, 30 Apr 2026 13:15:40 +0000 Subject: [PATCH] feat: add lock API config checkbox to Settings Providers tab Adds a discoverable "Use the same configuration for all modes" checkbox to the Providers section in Settings. This mirrors the existing lock icon hidden inside the API Configuration popover, making it much easier to find. - Checkbox in Providers tab reads from cachedState and persists on save - i18n strings added for all 18 locales - Tests added for render and toggle+save behavior Addresses #12237 --- .../src/components/settings/SettingsView.tsx | 16 ++++++ .../settings/__tests__/SettingsView.spec.tsx | 50 +++++++++++++++++++ webview-ui/src/i18n/locales/ca/settings.json | 2 + webview-ui/src/i18n/locales/de/settings.json | 2 + webview-ui/src/i18n/locales/en/settings.json | 2 + webview-ui/src/i18n/locales/es/settings.json | 2 + webview-ui/src/i18n/locales/fr/settings.json | 2 + webview-ui/src/i18n/locales/hi/settings.json | 2 + webview-ui/src/i18n/locales/id/settings.json | 2 + webview-ui/src/i18n/locales/it/settings.json | 2 + webview-ui/src/i18n/locales/ja/settings.json | 2 + webview-ui/src/i18n/locales/ko/settings.json | 2 + webview-ui/src/i18n/locales/nl/settings.json | 2 + webview-ui/src/i18n/locales/pl/settings.json | 2 + .../src/i18n/locales/pt-BR/settings.json | 2 + webview-ui/src/i18n/locales/ru/settings.json | 2 + webview-ui/src/i18n/locales/tr/settings.json | 2 + webview-ui/src/i18n/locales/vi/settings.json | 2 + .../src/i18n/locales/zh-CN/settings.json | 2 + .../src/i18n/locales/zh-TW/settings.json | 2 + 20 files changed, 102 insertions(+) diff --git a/webview-ui/src/components/settings/SettingsView.tsx b/webview-ui/src/components/settings/SettingsView.tsx index 47e087615e3..04a010d8d99 100644 --- a/webview-ui/src/components/settings/SettingsView.tsx +++ b/webview-ui/src/components/settings/SettingsView.tsx @@ -60,6 +60,7 @@ import { StandardTooltip, } from "@src/components/ui" +import { Checkbox } from "vscrui" import { Tab, TabContent, TabHeader, TabList, TabTrigger } from "../common/Tab" import { SetCachedStateField, SetExperimentEnabled } from "./types" import { SectionHeader } from "./SectionHeader" @@ -203,6 +204,7 @@ const SettingsView = forwardRef(({ onDone, t includeCurrentTime, includeCurrentCost, maxGitStatusFiles, + lockApiConfigAcrossModes, } = cachedState const apiConfiguration = useMemo(() => cachedState.apiConfiguration ?? {}, [cachedState.apiConfiguration]) @@ -430,6 +432,7 @@ const SettingsView = forwardRef(({ onDone, t vscode.postMessage({ type: "upsertApiConfiguration", text: currentApiConfigName, apiConfiguration }) vscode.postMessage({ type: "telemetrySetting", text: telemetrySetting }) vscode.postMessage({ type: "debugSetting", bool: cachedState.debug }) + vscode.postMessage({ type: "lockApiConfigAcrossModes", bool: !!lockApiConfigAcrossModes }) setChangeDetected(false) } @@ -766,6 +769,19 @@ const SettingsView = forwardRef(({ onDone, t }) } /> +
+ + setCachedStateField("lockApiConfigAcrossModes", checked) + } + data-testid="lock-api-config-checkbox"> + {t("settings:providers.lockApiConfigAcrossModes")} + +
+ {t("settings:providers.lockApiConfigAcrossModesDescription")} +
+
({ vscode: { postMessage: vi.fn() } })) +vi.mock("vscrui", () => ({ + Checkbox: ({ children, checked, onChange, "data-testid": dataTestId }: any) => ( + + ), +})) + vi.mock("../ApiConfigManager", () => ({ __esModule: true, default: ({ currentApiConfigName }: any) => ( @@ -714,3 +728,39 @@ describe("SettingsView - Duplicate Commands", () => { ) }) }) + +describe("SettingsView - Lock API Config Across Modes", () => { + beforeEach(() => { + vi.clearAllMocks() + }) + + it("renders lock API config checkbox unchecked by default on the providers tab", () => { + const { getSettingsContent } = renderSettingsView() + + const content = getSettingsContent() + const lockCheckbox = within(content).getByTestId("lock-api-config-checkbox") + expect(lockCheckbox).not.toBeChecked() + }) + + it("toggles lock API config and sends lockApiConfigAcrossModes message on save", () => { + const { getSettingsContent } = renderSettingsView() + + const content = getSettingsContent() + const lockCheckbox = within(content).getByTestId("lock-api-config-checkbox") + + // Enable the lock + fireEvent.click(lockCheckbox) + expect(lockCheckbox).toBeChecked() + + // Click Save + const saveButton = screen.getByTestId("save-button") + fireEvent.click(saveButton) + + expect(vscode.postMessage).toHaveBeenCalledWith( + expect.objectContaining({ + type: "lockApiConfigAcrossModes", + bool: true, + }), + ) + }) +}) diff --git a/webview-ui/src/i18n/locales/ca/settings.json b/webview-ui/src/i18n/locales/ca/settings.json index 9d4be59b285..62530934e57 100644 --- a/webview-ui/src/i18n/locales/ca/settings.json +++ b/webview-ui/src/i18n/locales/ca/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "Documentació de {{provider}}", "configProfile": "Perfil de configuració", "description": "Deseu diferents configuracions d'API per canviar ràpidament entre proveïdors i configuracions.", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "Proveïdor d'API", "apiProviderDocs": "Documentació del proveïdor", "model": "Model", diff --git a/webview-ui/src/i18n/locales/de/settings.json b/webview-ui/src/i18n/locales/de/settings.json index 6cb1ebc3773..663978ec72a 100644 --- a/webview-ui/src/i18n/locales/de/settings.json +++ b/webview-ui/src/i18n/locales/de/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "{{provider}}-Dokumentation", "configProfile": "Konfigurationsprofil", "description": "Speichern Sie verschiedene API-Konfigurationen, um schnell zwischen Anbietern und Einstellungen zu wechseln.", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "API-Anbieter", "apiProviderDocs": "Anbieter-Dokumentation", "model": "Modell", diff --git a/webview-ui/src/i18n/locales/en/settings.json b/webview-ui/src/i18n/locales/en/settings.json index 8ec42367f14..30f1bafafae 100644 --- a/webview-ui/src/i18n/locales/en/settings.json +++ b/webview-ui/src/i18n/locales/en/settings.json @@ -351,6 +351,8 @@ "providerDocumentation": "{{provider}} documentation", "configProfile": "Configuration Profile", "description": "Save different API configurations to quickly switch between providers and settings.", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "API Provider", "apiProviderDocs": "Provider Docs", "model": "Model", diff --git a/webview-ui/src/i18n/locales/es/settings.json b/webview-ui/src/i18n/locales/es/settings.json index a26b789de4f..38419564fb6 100644 --- a/webview-ui/src/i18n/locales/es/settings.json +++ b/webview-ui/src/i18n/locales/es/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "Documentación de {{provider}}", "configProfile": "Perfil de configuración", "description": "Guarde diferentes configuraciones de API para cambiar rápidamente entre proveedores y ajustes.", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "Proveedor de API", "apiProviderDocs": "Documentación del Proveedor", "model": "Modelo", diff --git a/webview-ui/src/i18n/locales/fr/settings.json b/webview-ui/src/i18n/locales/fr/settings.json index b8e4da391fe..5db43715a34 100644 --- a/webview-ui/src/i18n/locales/fr/settings.json +++ b/webview-ui/src/i18n/locales/fr/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "Documentation {{provider}}", "configProfile": "Profil de configuration", "description": "Enregistrez différentes configurations d'API pour basculer rapidement entre les fournisseurs et les paramètres.", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "Fournisseur d'API", "apiProviderDocs": "Documentation du Fournisseur", "model": "Modèle", diff --git a/webview-ui/src/i18n/locales/hi/settings.json b/webview-ui/src/i18n/locales/hi/settings.json index 6c602e6441a..edfe3aee847 100644 --- a/webview-ui/src/i18n/locales/hi/settings.json +++ b/webview-ui/src/i18n/locales/hi/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "{{provider}} दस्तावेज़ीकरण", "configProfile": "कॉन्फिगरेशन प्रोफाइल", "description": "विभिन्न API कॉन्फ़िगरेशन सहेजें ताकि प्रदाताओं और सेटिंग्स के बीच त्वरित रूप से स्विच कर सकें।", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "API प्रदाता", "apiProviderDocs": "प्रदाता डॉक्स", "model": "मॉडल", diff --git a/webview-ui/src/i18n/locales/id/settings.json b/webview-ui/src/i18n/locales/id/settings.json index bc12a0da481..38e641f1ef1 100644 --- a/webview-ui/src/i18n/locales/id/settings.json +++ b/webview-ui/src/i18n/locales/id/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "Dokumentasi {{provider}}", "configProfile": "Profil Konfigurasi", "description": "Simpan konfigurasi API yang berbeda untuk beralih dengan cepat antara provider dan pengaturan.", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "Provider API", "apiProviderDocs": "Dokumentasi Penyedia", "model": "Model", diff --git a/webview-ui/src/i18n/locales/it/settings.json b/webview-ui/src/i18n/locales/it/settings.json index 877032cda90..0d6f69a263c 100644 --- a/webview-ui/src/i18n/locales/it/settings.json +++ b/webview-ui/src/i18n/locales/it/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "Documentazione {{provider}}", "configProfile": "Profilo di configurazione", "description": "Salva diverse configurazioni API per passare rapidamente tra fornitori e impostazioni.", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "Fornitore API", "apiProviderDocs": "Documentazione del Provider", "model": "Modello", diff --git a/webview-ui/src/i18n/locales/ja/settings.json b/webview-ui/src/i18n/locales/ja/settings.json index 7f31d349393..d880a99d521 100644 --- a/webview-ui/src/i18n/locales/ja/settings.json +++ b/webview-ui/src/i18n/locales/ja/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "{{provider}}のドキュメント", "configProfile": "設定プロファイル", "description": "異なるAPI設定を保存して、プロバイダーと設定をすばやく切り替えることができます。", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "APIプロバイダー", "apiProviderDocs": "プロバイダードキュメント", "model": "モデル", diff --git a/webview-ui/src/i18n/locales/ko/settings.json b/webview-ui/src/i18n/locales/ko/settings.json index 707719609c4..c375bf9f3a0 100644 --- a/webview-ui/src/i18n/locales/ko/settings.json +++ b/webview-ui/src/i18n/locales/ko/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "{{provider}} 문서", "configProfile": "구성 프로필", "description": "다양한 API 구성을 저장하여 제공자와 설정 간에 빠르게 전환할 수 있습니다.", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "API 제공자", "apiProviderDocs": "공급자 문서", "model": "모델", diff --git a/webview-ui/src/i18n/locales/nl/settings.json b/webview-ui/src/i18n/locales/nl/settings.json index e54277ade4e..0060e439391 100644 --- a/webview-ui/src/i18n/locales/nl/settings.json +++ b/webview-ui/src/i18n/locales/nl/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "{{provider}} documentatie", "configProfile": "Configuratieprofiel", "description": "Sla verschillende API-configuraties op om snel te wisselen tussen providers en instellingen.", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "API-provider", "apiProviderDocs": "Providerdocumentatie", "model": "Model", diff --git a/webview-ui/src/i18n/locales/pl/settings.json b/webview-ui/src/i18n/locales/pl/settings.json index 92d2604acb7..430a143c315 100644 --- a/webview-ui/src/i18n/locales/pl/settings.json +++ b/webview-ui/src/i18n/locales/pl/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "Dokumentacja {{provider}}", "configProfile": "Profil konfiguracji", "description": "Zapisz różne konfiguracje API, aby szybko przełączać się między dostawcami i ustawieniami.", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "Dostawca API", "apiProviderDocs": "Dokumentacja dostawcy", "model": "Model", diff --git a/webview-ui/src/i18n/locales/pt-BR/settings.json b/webview-ui/src/i18n/locales/pt-BR/settings.json index cba3599d3cb..b295a4b310b 100644 --- a/webview-ui/src/i18n/locales/pt-BR/settings.json +++ b/webview-ui/src/i18n/locales/pt-BR/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "Documentação do {{provider}}", "configProfile": "Perfil de configuração", "description": "Salve diferentes configurações de API para alternar rapidamente entre provedores e configurações.", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "Provedor de API", "apiProviderDocs": "Documentação do Provedor", "model": "Modelo", diff --git a/webview-ui/src/i18n/locales/ru/settings.json b/webview-ui/src/i18n/locales/ru/settings.json index 524b8a25281..3fbee0630df 100644 --- a/webview-ui/src/i18n/locales/ru/settings.json +++ b/webview-ui/src/i18n/locales/ru/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "Документация {{provider}}", "configProfile": "Профиль конфигурации", "description": "Сохраняйте различные конфигурации API для быстрого переключения между провайдерами и настройками.", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "Провайдер API", "apiProviderDocs": "Документация провайдера", "model": "Модель", diff --git a/webview-ui/src/i18n/locales/tr/settings.json b/webview-ui/src/i18n/locales/tr/settings.json index 42ba46f85e1..54784f0f99c 100644 --- a/webview-ui/src/i18n/locales/tr/settings.json +++ b/webview-ui/src/i18n/locales/tr/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "{{provider}} Dokümantasyonu", "configProfile": "Yapılandırma Profili", "description": "Sağlayıcılar ve ayarlar arasında hızlıca geçiş yapmak için farklı API yapılandırmalarını kaydedin.", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "API Sağlayıcı", "apiProviderDocs": "Sağlayıcı Belgeleri", "model": "Model", diff --git a/webview-ui/src/i18n/locales/vi/settings.json b/webview-ui/src/i18n/locales/vi/settings.json index 11259a45e35..7aef3f37da3 100644 --- a/webview-ui/src/i18n/locales/vi/settings.json +++ b/webview-ui/src/i18n/locales/vi/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "Tài liệu {{provider}}", "configProfile": "Hồ sơ cấu hình", "description": "Lưu các cấu hình API khác nhau để nhanh chóng chuyển đổi giữa các nhà cung cấp và cài đặt.", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "Nhà cung cấp API", "apiProviderDocs": "Tài liệu Nhà cung cấp", "model": "Mẫu", diff --git a/webview-ui/src/i18n/locales/zh-CN/settings.json b/webview-ui/src/i18n/locales/zh-CN/settings.json index 80ca437ce77..123c8f07e9b 100644 --- a/webview-ui/src/i18n/locales/zh-CN/settings.json +++ b/webview-ui/src/i18n/locales/zh-CN/settings.json @@ -288,6 +288,8 @@ "providerDocumentation": "{{provider}} 文档", "configProfile": "配置文件", "description": "保存多组API配置便于快速切换", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "API提供商", "apiProviderDocs": "提供商文档", "model": "模型", diff --git a/webview-ui/src/i18n/locales/zh-TW/settings.json b/webview-ui/src/i18n/locales/zh-TW/settings.json index 37c14c8e1bb..e7f944e5108 100644 --- a/webview-ui/src/i18n/locales/zh-TW/settings.json +++ b/webview-ui/src/i18n/locales/zh-TW/settings.json @@ -298,6 +298,8 @@ "providerDocumentation": "{{provider}} 說明文件", "configProfile": "設定檔", "description": "儲存不同的 API 設定以快速切換供應商和設定。", + "lockApiConfigAcrossModes": "Use the same configuration for all modes", + "lockApiConfigAcrossModesDescription": "When enabled, switching modes (e.g. Code, Architect, Ask) will keep the current API configuration instead of switching to a mode-specific one.", "apiProvider": "API 供應商", "apiProviderDocs": "供應商說明文件", "model": "模型",