From 0c6d429fdbc67a5f5d1d4daec1a1934987e6a750 Mon Sep 17 00:00:00 2001 From: YoVinchen Date: Thu, 12 Feb 2026 12:01:50 +0800 Subject: [PATCH] feat(omo): unify common config enabled via provider meta for OpenCode --- src-tauri/src/commands/misc.rs | 2 +- src-tauri/src/config_merge.rs | 2 +- src-tauri/src/provider.rs | 2 + src-tauri/src/services/omo.rs | 39 +++++++++++++++---- src/App.tsx | 6 ++- .../providers/EditProviderDialog.tsx | 2 +- .../providers/forms/ProviderForm.tsx | 33 ++++++++++------ src/types.ts | 1 + 8 files changed, 65 insertions(+), 22 deletions(-) diff --git a/src-tauri/src/commands/misc.rs b/src-tauri/src/commands/misc.rs index db229776b..e7c21471d 100644 --- a/src-tauri/src/commands/misc.rs +++ b/src-tauri/src/commands/misc.rs @@ -323,7 +323,7 @@ fn scan_cli_version(tool: &str) -> (Option, Option) { let mut search_paths: Vec = vec![ home.join(".local/bin"), // Native install (official recommended) home.join(".npm-global/bin"), - home.join("n/bin"), // n version manager + home.join("n/bin"), // n version manager home.join(".volta/bin"), // Volta package manager ]; diff --git a/src-tauri/src/config_merge.rs b/src-tauri/src/config_merge.rs index 3e1fbcf5c..b123bebb0 100644 --- a/src-tauri/src/config_merge.rs +++ b/src-tauri/src/config_merge.rs @@ -465,7 +465,7 @@ pub fn is_common_config_enabled(meta: Option<&ProviderMeta>, app_type: &AppType) AppType::Claude => by_app.claude, AppType::Codex => by_app.codex, AppType::Gemini => by_app.gemini, - AppType::OpenCode => None, // OpenCode doesn't support common config + AppType::OpenCode => by_app.opencode, }) .or(m.common_config_enabled) }) diff --git a/src-tauri/src/provider.rs b/src-tauri/src/provider.rs index 50854726d..827fd6a0b 100644 --- a/src-tauri/src/provider.rs +++ b/src-tauri/src/provider.rs @@ -200,6 +200,8 @@ pub struct CommonConfigEnabledByApp { pub codex: Option, #[serde(skip_serializing_if = "Option::is_none")] pub gemini: Option, + #[serde(skip_serializing_if = "Option::is_none")] + pub opencode: Option, } /// 供应商元数据 diff --git a/src-tauri/src/services/omo.rs b/src-tauri/src/services/omo.rs index 45ed9479b..8bd690d29 100644 --- a/src-tauri/src/services/omo.rs +++ b/src-tauri/src/services/omo.rs @@ -2,6 +2,7 @@ use crate::config::write_json_file; use crate::database::OmoGlobalConfig; use crate::error::AppError; use crate::opencode_config::get_opencode_dir; +use crate::provider::{CommonConfigEnabledByApp, ProviderMeta}; use crate::store::AppState; use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; @@ -142,6 +143,29 @@ impl OmoService { } } + fn resolve_common_config_enabled(provider: &crate::provider::Provider) -> bool { + // Unified path: use provider meta (same mechanism as other apps). + if let Some(meta) = provider.meta.as_ref() { + if let Some(enabled) = meta + .common_config_enabled_by_app + .as_ref() + .and_then(|by_app| by_app.opencode) + { + return enabled; + } + if let Some(enabled) = meta.common_config_enabled { + return enabled; + } + } + + // Backward compatibility: legacy OMO providers stored this flag in settings_config. + provider + .settings_config + .get("useCommonConfig") + .and_then(|v| v.as_bool()) + .unwrap_or(true) + } + pub fn delete_config_file() -> Result<(), AppError> { let config_path = Self::config_path(); if config_path.exists() { @@ -160,11 +184,7 @@ impl OmoService { let agents = p.settings_config.get("agents").cloned(); let categories = p.settings_config.get("categories").cloned(); let other_fields = p.settings_config.get("otherFields").cloned(); - let use_common_config = p - .settings_config - .get("useCommonConfig") - .and_then(|v| v.as_bool()) - .unwrap_or(true); + let use_common_config = Self::resolve_common_config_enabled(p); (agents, categories, other_fields, use_common_config) }); @@ -237,7 +257,6 @@ impl OmoService { if let Some(categories) = obj.get("categories") { settings.insert("categories".to_string(), categories.clone()); } - settings.insert("useCommonConfig".to_string(), Value::Bool(true)); let other = Self::extract_other_fields(&obj); if !other.is_empty() { @@ -263,7 +282,13 @@ impl OmoService { created_at: Some(chrono::Utc::now().timestamp_millis()), sort_index: None, notes: None, - meta: None, + meta: Some(ProviderMeta { + common_config_enabled_by_app: Some(CommonConfigEnabledByApp { + opencode: Some(true), + ..Default::default() + }), + ..Default::default() + }), icon: None, icon_color: None, in_failover_queue: false, diff --git a/src/App.tsx b/src/App.tsx index 9f758f8ba..4f0d47785 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -141,7 +141,11 @@ function App() { // Fallback from sessions view when switching to an app without session support useEffect(() => { - if (currentView === "sessions" && activeApp !== "claude" && activeApp !== "codex") { + if ( + currentView === "sessions" && + activeApp !== "claude" && + activeApp !== "codex" + ) { setCurrentView("providers"); } }, [activeApp, currentView]); diff --git a/src/components/providers/EditProviderDialog.tsx b/src/components/providers/EditProviderDialog.tsx index 9b8110324..91f475bb3 100644 --- a/src/components/providers/EditProviderDialog.tsx +++ b/src/components/providers/EditProviderDialog.tsx @@ -91,7 +91,7 @@ export function EditProviderDialog({ // 检查是否启用了通用配置 const metaByApp = provider.meta?.commonConfigEnabledByApp; const commonConfigEnabled = - metaByApp?.[appId as "claude" | "codex" | "gemini"] ?? + metaByApp?.[appId] ?? provider.meta?.commonConfigEnabled ?? false; diff --git a/src/components/providers/forms/ProviderForm.tsx b/src/components/providers/forms/ProviderForm.tsx index f2d4c3354..f54e38c8c 100644 --- a/src/components/providers/forms/ProviderForm.tsx +++ b/src/components/providers/forms/ProviderForm.tsx @@ -651,16 +651,6 @@ export function ProviderForm({ markCommonConfigSaved: markGeminiCommonConfigSaved, } = geminiCommonConfig; - const supportsCommonConfig = - appId === "claude" || appId === "codex" || appId === "gemini"; - const commonConfigEnabled = supportsCommonConfig - ? appId === "claude" - ? useCommonConfig - : appId === "codex" - ? useCodexCommonConfigFlag - : useGeminiCommonConfigFlag - : undefined; - const { data: opencodeProvidersData } = useProvidersQuery("opencode"); const existingOpencodeKeys = useMemo(() => { if (!opencodeProvidersData?.providers) return []; @@ -866,6 +856,13 @@ export function ProviderForm({ const [isOmoConfigModalOpen, setIsOmoConfigModalOpen] = useState(false); const [useOmoCommonConfig, setUseOmoCommonConfig] = useState(() => { + const metaByApp = initialData?.meta?.commonConfigEnabledByApp; + const fromMeta = + metaByApp?.opencode ?? initialData?.meta?.commonConfigEnabled; + if (typeof fromMeta === "boolean") { + return fromMeta; + } + // Backward compatibility for old OMO data. const raw = initialOmoSettings?.useCommonConfig; return typeof raw === "boolean" ? raw : true; }); @@ -949,6 +946,21 @@ export function ProviderForm({ setUseOmoCommonConfig(useCommonConfig); }, []); + const supportsCommonConfig = + appId === "claude" || + appId === "codex" || + appId === "gemini" || + isOmoCategory; + const commonConfigEnabled = supportsCommonConfig + ? appId === "claude" + ? useCommonConfig + : appId === "codex" + ? useCodexCommonConfigFlag + : appId === "gemini" + ? useGeminiCommonConfigFlag + : useOmoCommonConfig + : undefined; + const updateOpencodeSettings = useCallback( (updater: (config: Record) => void) => { try { @@ -1277,7 +1289,6 @@ export function ProviderForm({ } } else if (appId === "opencode" && category === "omo") { const omoConfig: Record = {}; - omoConfig.useCommonConfig = useOmoCommonConfig; if (Object.keys(omoAgents).length > 0) { omoConfig.agents = omoAgents; } diff --git a/src/types.ts b/src/types.ts index 9da1e3a15..3bb95f6f8 100644 --- a/src/types.ts +++ b/src/types.ts @@ -124,6 +124,7 @@ export type CommonConfigEnabledByApp = Partial<{ claude: boolean; codex: boolean; gemini: boolean; + opencode: boolean; }>; // 供应商元数据(字段名与后端一致,保持 snake_case)