feat(settings): add 'Apply to Claude Code extension' toggle

- Apply immediately on save (write or remove primaryApiKey)
- Honor setting on provider switch (enabled: write for non-official, remove for official; disabled: no auto writes)
- Remove per-provider Claude plugin buttons from ProviderList
- Upsert primaryApiKey=any preserving other fields; respect override dir
- Add zh/en i18n for the new setting
This commit is contained in:
Jason
2025-10-10 16:35:21 +08:00
parent 70d8d2cc43
commit c350e64687
8 changed files with 87 additions and 87 deletions

View File

@@ -50,6 +50,7 @@ export default function SettingsModal({
const [settings, setSettings] = useState<Settings>({
showInTray: true,
minimizeToTrayOnClose: true,
enableClaudePluginIntegration: false,
claudeConfigDir: undefined,
codexConfigDir: undefined,
language: persistedLanguage,
@@ -116,6 +117,11 @@ export default function SettingsModal({
setSettings({
showInTray,
minimizeToTrayOnClose,
enableClaudePluginIntegration:
typeof (loadedSettings as any)?.enableClaudePluginIntegration ===
"boolean"
? (loadedSettings as any).enableClaudePluginIntegration
: false,
claudeConfigDir:
typeof (loadedSettings as any)?.claudeConfigDir === "string"
? (loadedSettings as any).claudeConfigDir
@@ -184,6 +190,16 @@ export default function SettingsModal({
language: selectedLanguage,
};
await window.api.saveSettings(payload);
// 立即生效:根据开关无条件写入/移除 ~/.claude/config.json
try {
if (payload.enableClaudePluginIntegration) {
await window.api.applyClaudePluginConfig({ official: false });
} else {
await window.api.applyClaudePluginConfig({ official: true });
}
} catch (e) {
console.warn("[Settings] Apply Claude plugin config on save failed", e);
}
setSettings(payload);
try {
window.localStorage.setItem("language", selectedLanguage);
@@ -506,6 +522,28 @@ export default function SettingsModal({
className="w-4 h-4 text-blue-500 rounded focus:ring-blue-500/20"
/>
</label>
{/* Claude 插件联动开关 */}
<label className="flex items-center justify-between">
<div>
<span className="text-sm text-gray-900 dark:text-gray-100">
{t("settings.enableClaudePluginIntegration")}
</span>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1 max-w-[34rem]">
{t("settings.enableClaudePluginIntegrationDescription")}
</p>
</div>
<input
type="checkbox"
checked={!!settings.enableClaudePluginIntegration}
onChange={(e) =>
setSettings((prev) => ({
...prev,
enableClaudePluginIntegration: e.target.checked,
}))
}
className="w-4 h-4 text-blue-500 rounded focus:ring-blue-500/20"
/>
</label>
</div>
</div>