Revert "fix: improve VS Code config synchronization and code formatting"
This reverts commit 463e430a3d.
This commit is contained in:
@@ -62,7 +62,7 @@ const JsonEditor: React.FC<JsonEditorProps> = ({
|
||||
|
||||
return diagnostics;
|
||||
}),
|
||||
[showValidation],
|
||||
[showValidation]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -131,8 +131,7 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
|
||||
|
||||
// Codex 通用配置状态
|
||||
const [useCodexCommonConfig, setUseCodexCommonConfig] = useState(false);
|
||||
const [codexCommonConfigSnippet, setCodexCommonConfigSnippetState] =
|
||||
useState<string>(() => {
|
||||
const [codexCommonConfigSnippet, setCodexCommonConfigSnippetState] = useState<string>(() => {
|
||||
if (typeof window === "undefined") {
|
||||
return DEFAULT_CODEX_COMMON_CONFIG_SNIPPET;
|
||||
}
|
||||
@@ -218,11 +217,7 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
|
||||
useEffect(() => {
|
||||
if (initialData) {
|
||||
if (!isCodex) {
|
||||
const configString = JSON.stringify(
|
||||
initialData.settingsConfig,
|
||||
null,
|
||||
2,
|
||||
);
|
||||
const configString = JSON.stringify(initialData.settingsConfig, null, 2);
|
||||
const hasCommon = hasCommonConfigSnippet(
|
||||
configString,
|
||||
commonConfigSnippet,
|
||||
@@ -240,9 +235,7 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
|
||||
};
|
||||
if (config.env) {
|
||||
setClaudeModel(config.env.ANTHROPIC_MODEL || "");
|
||||
setClaudeSmallFastModel(
|
||||
config.env.ANTHROPIC_SMALL_FAST_MODEL || "",
|
||||
);
|
||||
setClaudeSmallFastModel(config.env.ANTHROPIC_SMALL_FAST_MODEL || "");
|
||||
setBaseUrl(config.env.ANTHROPIC_BASE_URL || ""); // 初始化基础 URL
|
||||
|
||||
// 初始化 Kimi 模型选择
|
||||
@@ -261,13 +254,7 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
|
||||
setUseCodexCommonConfig(hasCommon);
|
||||
}
|
||||
}
|
||||
}, [
|
||||
initialData,
|
||||
commonConfigSnippet,
|
||||
codexCommonConfigSnippet,
|
||||
isCodex,
|
||||
codexConfig,
|
||||
]);
|
||||
}, [initialData, commonConfigSnippet, codexCommonConfigSnippet, isCodex, codexConfig]);
|
||||
|
||||
// 当选择预设变化时,同步类别
|
||||
useEffect(() => {
|
||||
@@ -542,7 +529,10 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
|
||||
setBaseUrl(""); // 清空基础 URL
|
||||
|
||||
// 同步通用配置状态
|
||||
const hasCommon = hasCommonConfigSnippet(configString, commonConfigSnippet);
|
||||
const hasCommon = hasCommonConfigSnippet(
|
||||
configString,
|
||||
commonConfigSnippet,
|
||||
);
|
||||
setUseCommonConfig(hasCommon);
|
||||
setCommonConfigError("");
|
||||
|
||||
@@ -653,7 +643,10 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
|
||||
updateSettingsConfigValue(configString);
|
||||
|
||||
// 同步通用配置开关
|
||||
const hasCommon = hasCommonConfigSnippet(configString, commonConfigSnippet);
|
||||
const hasCommon = hasCommonConfigSnippet(
|
||||
configString,
|
||||
commonConfigSnippet,
|
||||
);
|
||||
setUseCommonConfig(hasCommon);
|
||||
};
|
||||
|
||||
@@ -688,8 +681,7 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
|
||||
|
||||
// Codex: 处理通用配置开关
|
||||
const handleCodexCommonConfigToggle = (checked: boolean) => {
|
||||
const { updatedConfig, error: snippetError } =
|
||||
updateTomlCommonConfigSnippet(
|
||||
const { updatedConfig, error: snippetError } = updateTomlCommonConfigSnippet(
|
||||
codexConfig,
|
||||
codexCommonConfigSnippet,
|
||||
checked,
|
||||
@@ -761,7 +753,10 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
|
||||
// 保存 Codex 通用配置到 localStorage
|
||||
if (typeof window !== "undefined") {
|
||||
try {
|
||||
window.localStorage.setItem(CODEX_COMMON_CONFIG_STORAGE_KEY, value);
|
||||
window.localStorage.setItem(
|
||||
CODEX_COMMON_CONFIG_STORAGE_KEY,
|
||||
value,
|
||||
);
|
||||
} catch {
|
||||
// ignore localStorage 写入失败
|
||||
}
|
||||
@@ -1182,9 +1177,7 @@ const ProviderForm: React.FC<ProviderFormProps> = ({
|
||||
useCommonConfig={useCodexCommonConfig}
|
||||
onCommonConfigToggle={handleCodexCommonConfigToggle}
|
||||
commonConfigSnippet={codexCommonConfigSnippet}
|
||||
onCommonConfigSnippetChange={
|
||||
handleCodexCommonConfigSnippetChange
|
||||
}
|
||||
onCommonConfigSnippetChange={handleCodexCommonConfigSnippetChange}
|
||||
commonConfigError={codexCommonConfigError}
|
||||
authError={codexAuthError}
|
||||
/>
|
||||
|
||||
@@ -120,7 +120,9 @@ const ClaudeConfigEditor: React.FC<ClaudeConfigEditorProps> = ({
|
||||
rows={12}
|
||||
/>
|
||||
{configError && (
|
||||
<p className="text-xs text-red-500 dark:text-red-400">{configError}</p>
|
||||
<p className="text-xs text-red-500 dark:text-red-400">
|
||||
{configError}
|
||||
</p>
|
||||
)}
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
完整的 Claude Code settings.json 配置内容
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useState, useEffect, useRef } from "react";
|
||||
import React, { useState, useEffect } from "react";
|
||||
import { X, Save } from "lucide-react";
|
||||
import { extractBaseUrlFromToml } from "../../utils/providerConfigUtils";
|
||||
|
||||
@@ -34,7 +34,6 @@ const CodexConfigEditor: React.FC<CodexConfigEditorProps> = ({
|
||||
const [vscodeError, setVscodeError] = useState("");
|
||||
const [vscodeSuccess, setVscodeSuccess] = useState("");
|
||||
const [isWritingVscode, setIsWritingVscode] = useState(false);
|
||||
const lastAppliedBaseUrlRef = useRef<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (commonConfigError && !isCommonConfigModalOpen) {
|
||||
@@ -50,61 +49,6 @@ const CodexConfigEditor: React.FC<CodexConfigEditorProps> = ({
|
||||
return () => window.clearTimeout(timer);
|
||||
}, [vscodeSuccess]);
|
||||
|
||||
const ensureVscodeApiAvailable = () => {
|
||||
if (typeof window === "undefined" || !window.api?.writeVscodeSettings) {
|
||||
setVscodeError("当前环境暂不支持写入 VS Code 配置");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
const applyVscodeConfig = async (
|
||||
baseUrl: string,
|
||||
successMessage = "已写入 VS Code 配置",
|
||||
) => {
|
||||
if (!ensureVscodeApiAvailable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setIsWritingVscode(true);
|
||||
try {
|
||||
const success = await window.api.writeVscodeSettings(baseUrl);
|
||||
if (success) {
|
||||
setVscodeSuccess(successMessage);
|
||||
lastAppliedBaseUrlRef.current = baseUrl;
|
||||
return true;
|
||||
}
|
||||
setVscodeError("写入 VS Code 配置失败,请稍后重试");
|
||||
} catch (error) {
|
||||
setVscodeError(`写入 VS Code 配置失败: ${String(error)}`);
|
||||
} finally {
|
||||
setIsWritingVscode(false);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const removeVscodeConfig = async () => {
|
||||
if (!ensureVscodeApiAvailable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
setIsWritingVscode(true);
|
||||
try {
|
||||
const success = await window.api.writeVscodeSettings();
|
||||
if (success) {
|
||||
setVscodeSuccess("已移除 VS Code 配置");
|
||||
lastAppliedBaseUrlRef.current = null;
|
||||
return true;
|
||||
}
|
||||
setVscodeError("移除 VS Code 配置失败,请稍后重试");
|
||||
} catch (error) {
|
||||
setVscodeError(`移除 VS Code 配置失败: ${String(error)}`);
|
||||
} finally {
|
||||
setIsWritingVscode(false);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const handleVscodeConfigToggle = async (checked: boolean) => {
|
||||
if (isWritingVscode) return;
|
||||
|
||||
@@ -112,6 +56,12 @@ const CodexConfigEditor: React.FC<CodexConfigEditorProps> = ({
|
||||
setVscodeError("");
|
||||
setVscodeSuccess("");
|
||||
|
||||
if (typeof window === "undefined" || !window.api?.writeVscodeSettings) {
|
||||
setVscodeError("当前环境暂不支持写入 VS Code 配置");
|
||||
setWriteVscodeConfig(!checked);
|
||||
return;
|
||||
}
|
||||
|
||||
if (checked) {
|
||||
const trimmed = configValue.trim();
|
||||
if (!trimmed) {
|
||||
@@ -127,66 +77,42 @@ const CodexConfigEditor: React.FC<CodexConfigEditorProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
const success = await applyVscodeConfig(baseUrl);
|
||||
if (!success) {
|
||||
setIsWritingVscode(true);
|
||||
try {
|
||||
const success = await window.api.writeVscodeSettings(baseUrl);
|
||||
if (success) {
|
||||
setVscodeSuccess("已写入 VS Code 配置");
|
||||
} else {
|
||||
setVscodeError("写入 VS Code 配置失败,请稍后重试");
|
||||
setWriteVscodeConfig(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const success = await removeVscodeConfig();
|
||||
if (!success) {
|
||||
setWriteVscodeConfig(true);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (!writeVscodeConfig || isWritingVscode) {
|
||||
return;
|
||||
}
|
||||
|
||||
const trimmed = configValue.trim();
|
||||
if (!trimmed) {
|
||||
return;
|
||||
}
|
||||
|
||||
const baseUrl = extractBaseUrlFromToml(trimmed);
|
||||
if (!baseUrl) {
|
||||
setVscodeError("未在 config.toml 中找到 base_url 字段");
|
||||
} catch (error) {
|
||||
setVscodeError(`写入 VS Code 配置失败: ${String(error)}`);
|
||||
setWriteVscodeConfig(false);
|
||||
return;
|
||||
} finally {
|
||||
setIsWritingVscode(false);
|
||||
}
|
||||
|
||||
if (lastAppliedBaseUrlRef.current === baseUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
const sync = async () => {
|
||||
// 直接调用 API 而不依赖 applyVscodeConfig 函数,避免闭包问题
|
||||
if (typeof window === "undefined" || !window.api?.writeVscodeSettings) {
|
||||
setVscodeError("当前环境暂不支持写入 VS Code 配置");
|
||||
return;
|
||||
}
|
||||
|
||||
setIsWritingVscode(true);
|
||||
try {
|
||||
const success = await window.api.writeVscodeSettings(baseUrl);
|
||||
const success = await window.api.writeVscodeSettings();
|
||||
if (success) {
|
||||
setVscodeSuccess("已更新 VS Code 配置");
|
||||
lastAppliedBaseUrlRef.current = baseUrl;
|
||||
setVscodeSuccess("已移除 VS Code 配置");
|
||||
} else {
|
||||
setVscodeError("写入 VS Code 配置失败,请稍后重试");
|
||||
setVscodeError("移除 VS Code 配置失败,请稍后重试");
|
||||
setWriteVscodeConfig(true);
|
||||
}
|
||||
} catch (error) {
|
||||
setVscodeError(`写入 VS Code 配置失败: ${String(error)}`);
|
||||
setVscodeError(`移除 VS Code 配置失败: ${String(error)}`);
|
||||
setWriteVscodeConfig(true);
|
||||
} finally {
|
||||
setIsWritingVscode(false);
|
||||
}
|
||||
};
|
||||
|
||||
sync();
|
||||
}, [configValue, writeVscodeConfig, isWritingVscode]);
|
||||
|
||||
// 支持按下 ESC 关闭弹窗
|
||||
useEffect(() => {
|
||||
if (!isCommonConfigModalOpen) return;
|
||||
@@ -236,7 +162,9 @@ const CodexConfigEditor: React.FC<CodexConfigEditorProps> = ({
|
||||
data-enable-grammarly="false"
|
||||
/>
|
||||
{authError && (
|
||||
<p className="text-xs text-red-500 dark:text-red-400">{authError}</p>
|
||||
<p className="text-xs text-red-500 dark:text-red-400">
|
||||
{authError}
|
||||
</p>
|
||||
)}
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
Codex auth.json 配置内容
|
||||
@@ -273,10 +201,7 @@ const CodexConfigEditor: React.FC<CodexConfigEditorProps> = ({
|
||||
</p>
|
||||
)}
|
||||
{vscodeError && (
|
||||
<p
|
||||
className="text-xs text-red-500 dark:text-red-400 text-right truncate"
|
||||
title={vscodeError}
|
||||
>
|
||||
<p className="text-xs text-red-500 dark:text-red-400 text-right truncate" title={vscodeError}>
|
||||
{vscodeError}
|
||||
</p>
|
||||
)}
|
||||
@@ -302,10 +227,7 @@ const CodexConfigEditor: React.FC<CodexConfigEditorProps> = ({
|
||||
编辑通用配置
|
||||
</button>
|
||||
{commonConfigError && !isCommonConfigModalOpen && (
|
||||
<p
|
||||
className="text-xs text-red-500 dark:text-red-400 mt-1 max-w-[120px] truncate"
|
||||
title={commonConfigError}
|
||||
>
|
||||
<p className="text-xs text-red-500 dark:text-red-400 mt-1 max-w-[120px] truncate" title={commonConfigError}>
|
||||
{commonConfigError}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -22,10 +22,7 @@ const deepMerge = (
|
||||
return target;
|
||||
};
|
||||
|
||||
const deepRemove = (
|
||||
target: Record<string, any>,
|
||||
source: Record<string, any>,
|
||||
) => {
|
||||
const deepRemove = (target: Record<string, any>, source: Record<string, any>) => {
|
||||
Object.entries(source).forEach(([key, value]) => {
|
||||
if (!(key in target)) return;
|
||||
|
||||
@@ -62,7 +59,7 @@ const isSubset = (target: any, source: any): boolean => {
|
||||
const deepClone = <T>(obj: T): T => {
|
||||
if (obj === null || typeof obj !== "object") return obj;
|
||||
if (obj instanceof Date) return new Date(obj.getTime()) as T;
|
||||
if (obj instanceof Array) return obj.map((item) => deepClone(item)) as T;
|
||||
if (obj instanceof Array) return obj.map(item => deepClone(item)) as T;
|
||||
if (obj instanceof Object) {
|
||||
const clonedObj = {} as T;
|
||||
for (const key in obj) {
|
||||
@@ -81,10 +78,7 @@ export interface UpdateCommonConfigResult {
|
||||
}
|
||||
|
||||
// 验证JSON配置格式
|
||||
export const validateJsonConfig = (
|
||||
value: string,
|
||||
fieldName: string = "配置",
|
||||
): string => {
|
||||
export const validateJsonConfig = (value: string, fieldName: string = "配置"): string => {
|
||||
if (!value.trim()) {
|
||||
return "";
|
||||
}
|
||||
@@ -260,13 +254,13 @@ const removeTomlCommonConfig = (tomlString: string): string => {
|
||||
|
||||
// 找到标记前的换行符(如果有)
|
||||
let realStartIdx = startIdx;
|
||||
if (startIdx > 0 && tomlString[startIdx - 1] === "\n") {
|
||||
if (startIdx > 0 && tomlString[startIdx - 1] === '\n') {
|
||||
realStartIdx = startIdx - 1;
|
||||
}
|
||||
|
||||
// 找到标记后的换行符(如果有)
|
||||
let realEndIdx = endIdx + COMMON_CONFIG_MARKER_END.length;
|
||||
if (realEndIdx < tomlString.length && tomlString[realEndIdx] === "\n") {
|
||||
if (realEndIdx < tomlString.length && tomlString[realEndIdx] === '\n') {
|
||||
realEndIdx = realEndIdx + 1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user