From f32298743d6152e7fe0a842460aa002ac6666779 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Sat, 20 Jun 2026 23:58:38 +0800 Subject: [PATCH] fix(driver): keep custom store paths consistent --- .../components/config/DriverStoreDialog.vue | 7 ++ apps/desktop/src/lib/http.ts | 2 + apps/desktop/src/lib/tauri.ts | 2 + src-tauri/src/commands/app_settings.rs | 117 +++++++++++++++++- src-tauri/src/lib.rs | 19 +-- 5 files changed, 131 insertions(+), 16 deletions(-) diff --git a/apps/desktop/src/components/config/DriverStoreDialog.vue b/apps/desktop/src/components/config/DriverStoreDialog.vue index 4a2d35fc38..c35f79e350 100644 --- a/apps/desktop/src/components/config/DriverStoreDialog.vue +++ b/apps/desktop/src/components/config/DriverStoreDialog.vue @@ -130,6 +130,13 @@ async function applyDriverStoreDir(kind: DriverStoreDirKind, newDir: string | nu settingsStore.desktopSettings.driver_store_dir = result.driver_store_dir; settingsStore.desktopSettings.plugin_store_dir = result.plugin_store_dir; settingsStore.desktopSettings.agent_store_dir = result.agent_store_dir; + currentDriverStorePath.value = { + driver_store_dir: result.driver_store_dir, + plugin_store_dir: result.plugin_store_dir, + agent_store_dir: result.agent_store_dir, + plugins_dir: result.plugins_dir, + agents_dir: result.agents_dir, + }; toast(t("driverStore.driverStoreDirSuccess", { target })); // Restart the app to use the new paths const { relaunch } = await import("@tauri-apps/plugin-process"); diff --git a/apps/desktop/src/lib/http.ts b/apps/desktop/src/lib/http.ts index 564e4d9d26..42067f84db 100644 --- a/apps/desktop/src/lib/http.ts +++ b/apps/desktop/src/lib/http.ts @@ -913,6 +913,8 @@ export interface DriverStoreMigrationResult { driver_store_dir: string | null; plugin_store_dir: string | null; agent_store_dir: string | null; + plugins_dir: string; + agents_dir: string; migrated_plugins: boolean; migrated_agents: boolean; } diff --git a/apps/desktop/src/lib/tauri.ts b/apps/desktop/src/lib/tauri.ts index 78fe028fa8..5e861b767d 100644 --- a/apps/desktop/src/lib/tauri.ts +++ b/apps/desktop/src/lib/tauri.ts @@ -342,6 +342,8 @@ export interface DriverStoreMigrationResult { driver_store_dir: string | null; plugin_store_dir: string | null; agent_store_dir: string | null; + plugins_dir: string; + agents_dir: string; migrated_plugins: boolean; migrated_agents: boolean; } diff --git a/src-tauri/src/commands/app_settings.rs b/src-tauri/src/commands/app_settings.rs index 77adb70c98..be5297b65f 100644 --- a/src-tauri/src/commands/app_settings.rs +++ b/src-tauri/src/commands/app_settings.rs @@ -14,6 +14,8 @@ pub struct DriverStoreMigrationResult { pub driver_store_dir: Option, pub plugin_store_dir: Option, pub agent_store_dir: Option, + pub plugins_dir: String, + pub agents_dir: String, pub migrated_plugins: bool, pub migrated_agents: bool, } @@ -103,7 +105,13 @@ pub async fn set_driver_store_dir( settings.agent_store_dir = None; state.storage.save_desktop_settings(&settings).await?; - Ok(driver_store_migration_result(settings, migrated_plugins, migrated_agents)) + Ok(driver_store_migration_result( + settings, + &target_plugins_dir, + &target_agents_dir, + migrated_plugins, + migrated_agents, + )) } #[tauri::command] @@ -127,7 +135,7 @@ pub async fn set_plugin_store_dir( settings.plugin_store_dir = new_dir; state.storage.save_desktop_settings(&settings).await?; - Ok(driver_store_migration_result(settings, migrated_plugins, false)) + Ok(driver_store_migration_result(settings, &target_plugins_dir, ¤t_agents_dir, migrated_plugins, false)) } #[tauri::command] @@ -152,7 +160,7 @@ pub async fn set_agent_store_dir( settings.agent_store_dir = new_dir; state.storage.save_desktop_settings(&settings).await?; - Ok(driver_store_migration_result(settings, false, migrated_agents)) + Ok(driver_store_migration_result(settings, ¤t_plugins_dir, &target_agents_dir, false, migrated_agents)) } fn normalize_store_dir(dir: Option) -> Option { @@ -181,6 +189,31 @@ fn default_agent_store_dir(app: &AppHandle) -> Result { }) } +pub(crate) fn resolve_driver_store_dirs_from_settings( + settings: &DesktopSettings, + data_dir: &Path, + default_agent_dir: Option, +) -> (PathBuf, Option) { + let legacy_driver_base = + settings.driver_store_dir.as_ref().filter(|value| !value.trim().is_empty()).map(PathBuf::from); + let plugin_dir = settings + .plugin_store_dir + .as_ref() + .filter(|value| !value.trim().is_empty()) + .map(PathBuf::from) + .or_else(|| legacy_driver_base.as_ref().map(|base| base.join("plugins"))) + .unwrap_or_else(|| data_dir.join("plugins")); + let agent_dir = settings + .agent_store_dir + .as_ref() + .filter(|value| !value.trim().is_empty()) + .map(PathBuf::from) + .or_else(|| legacy_driver_base.as_ref().map(|base| base.join("agents"))) + .or(default_agent_dir); + + (plugin_dir, agent_dir) +} + fn convert_legacy_driver_store(settings: &mut DesktopSettings, current_plugins_dir: &Path, current_agents_dir: &Path) { if settings.driver_store_dir.is_none() { return; @@ -196,6 +229,8 @@ fn convert_legacy_driver_store(settings: &mut DesktopSettings, current_plugins_d fn driver_store_migration_result( settings: DesktopSettings, + plugins_dir: &Path, + agents_dir: &Path, migrated_plugins: bool, migrated_agents: bool, ) -> DriverStoreMigrationResult { @@ -203,6 +238,8 @@ fn driver_store_migration_result( driver_store_dir: settings.driver_store_dir, plugin_store_dir: settings.plugin_store_dir, agent_store_dir: settings.agent_store_dir, + plugins_dir: plugins_dir.to_string_lossy().to_string(), + agents_dir: agents_dir.to_string_lossy().to_string(), migrated_plugins, migrated_agents, } @@ -352,3 +389,77 @@ fn load_native_debug_logs_from_dir(log_dir: PathBuf) -> Result { } Ok(output) } + +#[cfg(test)] +mod tests { + use super::{driver_store_migration_result, resolve_driver_store_dirs_from_settings, DesktopSettings}; + use std::path::PathBuf; + + #[test] + fn plugin_store_result_uses_selected_directory_without_agent_prefix() { + let settings = DesktopSettings { + plugin_store_dir: Some(path("D:/develop/DBX")), + agent_store_dir: Some(path("D:/develop/DBX/agents")), + ..Default::default() + }; + let plugins_dir = PathBuf::from(path("D:/develop/DBX")); + let agents_dir = PathBuf::from(path("D:/develop/DBX/agents")); + + let result = driver_store_migration_result(settings, &plugins_dir, &agents_dir, true, false); + + assert_eq!(result.plugin_store_dir.as_deref(), Some(path("D:/develop/DBX").as_str())); + assert_eq!(result.plugins_dir, path("D:/develop/DBX")); + assert_eq!(result.agents_dir, path("D:/develop/DBX/agents")); + assert!(!result.plugins_dir.contains(&path("agents/com.dbx.app/plugins"))); + } + + #[test] + fn legacy_driver_store_result_keeps_plugins_and_agents_as_siblings() { + let settings = DesktopSettings { driver_store_dir: Some(path("D:/develop/DBX")), ..Default::default() }; + let plugins_dir = PathBuf::from(path("D:/develop/DBX/plugins")); + let agents_dir = PathBuf::from(path("D:/develop/DBX/agents")); + + let result = driver_store_migration_result(settings, &plugins_dir, &agents_dir, true, true); + + assert_eq!(result.driver_store_dir.as_deref(), Some(path("D:/develop/DBX").as_str())); + assert_eq!(result.plugins_dir, path("D:/develop/DBX/plugins")); + assert_eq!(result.agents_dir, path("D:/develop/DBX/agents")); + } + + #[test] + fn resolves_separate_plugin_store_dir_as_exact_selected_dir() { + let settings = DesktopSettings { + driver_store_dir: Some(path("D:/legacy-base")), + plugin_store_dir: Some(path("D:/develop/DBX")), + agent_store_dir: Some(path("D:/develop/DBX/agents")), + ..Default::default() + }; + + let (plugins_dir, agents_dir) = resolve_driver_store_dirs_from_settings( + &settings, + &PathBuf::from(path("C:/Users/lenovo/AppData/Roaming/com.dbx.app")), + Some(PathBuf::from(path("C:/Users/lenovo/.dbx/agents"))), + ); + + assert_eq!(plugins_dir, PathBuf::from(path("D:/develop/DBX"))); + assert_eq!(agents_dir, Some(PathBuf::from(path("D:/develop/DBX/agents")))); + } + + #[test] + fn resolves_legacy_driver_store_dir_to_sibling_plugins_and_agents() { + let settings = DesktopSettings { driver_store_dir: Some(path("D:/develop/DBX")), ..Default::default() }; + + let (plugins_dir, agents_dir) = resolve_driver_store_dirs_from_settings( + &settings, + &PathBuf::from(path("C:/Users/lenovo/AppData/Roaming/com.dbx.app")), + Some(PathBuf::from(path("C:/Users/lenovo/.dbx/agents"))), + ); + + assert_eq!(plugins_dir, PathBuf::from(path("D:/develop/DBX/plugins"))); + assert_eq!(agents_dir, Some(PathBuf::from(path("D:/develop/DBX/agents")))); + } + + fn path(value: &str) -> String { + value.replace('/', std::path::MAIN_SEPARATOR_STR) + } +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index cd3c767bb6..3fb547196e 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -286,19 +286,12 @@ pub fn run() { apply_debug_log_level(desktop_settings.debug_logging_enabled); eprintln!("[STARTUP] storage ready in {:?}", t.elapsed()); - let legacy_driver_base = desktop_settings.driver_store_dir.as_ref().map(std::path::PathBuf::from); - let plugin_dir = desktop_settings - .plugin_store_dir - .as_ref() - .map(std::path::PathBuf::from) - .or_else(|| legacy_driver_base.as_ref().map(|base| base.join("plugins"))) - .unwrap_or_else(|| data_dir.join("plugins")); - let agent_dir = desktop_settings - .agent_store_dir - .as_ref() - .map(std::path::PathBuf::from) - .or_else(|| legacy_driver_base.as_ref().map(|base| base.join("agents"))) - .or_else(|| data_dir::uses_custom_data_dir().then(|| data_dir.join("agents"))); + let default_agent_dir = data_dir::uses_custom_data_dir().then(|| data_dir.join("agents")); + let (plugin_dir, agent_dir) = commands::app_settings::resolve_driver_store_dirs_from_settings( + &desktop_settings, + &data_dir, + default_agent_dir, + ); let state = if let Some(agent_dir) = agent_dir { Arc::new(AppState::new_with_plugin_and_agent_dir_and_app_version(