Revert "feat: add common config snippet management system"

This reverts commit 36b78d1b4b.
This commit is contained in:
Jason
2025-09-17 16:14:43 +08:00
parent 36b78d1b4b
commit 1d1440f52f
14 changed files with 28 additions and 710 deletions

View File

@@ -32,7 +32,6 @@
"@codemirror/view": "^6.38.2",
"@tailwindcss/vite": "^4.1.13",
"@tauri-apps/api": "^2.8.0",
"@tauri-apps/plugin-dialog": "^2.4.0",
"@tauri-apps/plugin-process": "^2.0.0",
"@tauri-apps/plugin-updater": "^2.0.0",
"codemirror": "^6.0.2",

10
pnpm-lock.yaml generated
View File

@@ -26,9 +26,6 @@ importers:
'@tauri-apps/api':
specifier: ^2.8.0
version: 2.8.0
'@tauri-apps/plugin-dialog':
specifier: ^2.4.0
version: 2.4.0
'@tauri-apps/plugin-process':
specifier: ^2.0.0
version: 2.3.0
@@ -635,9 +632,6 @@ packages:
engines: {node: '>= 10'}
hasBin: true
'@tauri-apps/plugin-dialog@2.4.0':
resolution: {integrity: sha512-OvXkrEBfWwtd8tzVCEXIvRfNEX87qs2jv6SqmVPiHcJjBhSF/GUvjqUNIDmKByb5N8nvDqVUM7+g1sXwdC/S9w==}
'@tauri-apps/plugin-process@2.3.0':
resolution: {integrity: sha512-0DNj6u+9csODiV4seSxxRbnLpeGYdojlcctCuLOCgpH9X3+ckVZIEj6H7tRQ7zqWr7kSTEWnrxtAdBb0FbtrmQ==}
@@ -1445,10 +1439,6 @@ snapshots:
'@tauri-apps/cli-win32-ia32-msvc': 2.8.1
'@tauri-apps/cli-win32-x64-msvc': 2.8.1
'@tauri-apps/plugin-dialog@2.4.0':
dependencies:
'@tauri-apps/api': 2.8.0
'@tauri-apps/plugin-process@2.3.0':
dependencies:
'@tauri-apps/api': 2.8.0

334
src-tauri/Cargo.lock generated
View File

@@ -105,27 +105,6 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "ashpd"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df"
dependencies = [
"enumflags2",
"futures-channel",
"futures-util",
"rand 0.9.2",
"raw-window-handle",
"serde",
"serde_repr",
"tokio",
"url",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"zbus 5.11.0",
]
[[package]]
name = "async-broadcast"
version = "0.7.2"
@@ -590,7 +569,6 @@ dependencies = [
"serde_json",
"tauri",
"tauri-build",
"tauri-plugin-dialog",
"tauri-plugin-log",
"tauri-plugin-opener",
"tauri-plugin-process",
@@ -956,8 +934,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
dependencies = [
"bitflags 2.9.3",
"block2 0.6.1",
"libc",
"objc2 0.6.2",
]
@@ -972,15 +948,6 @@ dependencies = [
"syn 2.0.106",
]
[[package]]
name = "dlib"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
dependencies = [
"libloading",
]
[[package]]
name = "dlopen2"
version = "0.8.0"
@@ -1004,12 +971,6 @@ dependencies = [
"syn 2.0.106",
]
[[package]]
name = "downcast-rs"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
[[package]]
name = "dpi"
version = "0.1.2"
@@ -2390,19 +2351,6 @@ dependencies = [
"memoffset",
]
[[package]]
name = "nix"
version = "0.30.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
dependencies = [
"bitflags 2.9.3",
"cfg-if",
"cfg_aliases 0.2.1",
"libc",
"memoffset",
]
[[package]]
name = "nodrop"
version = "0.1.14"
@@ -3038,7 +2986,7 @@ checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1"
dependencies = [
"base64 0.22.1",
"indexmap 2.11.0",
"quick-xml 0.38.2",
"quick-xml",
"serde",
"time",
]
@@ -3120,15 +3068,6 @@ dependencies = [
"toml_edit 0.20.2",
]
[[package]]
name = "proc-macro-crate"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983"
dependencies = [
"toml_edit 0.23.4",
]
[[package]]
name = "proc-macro-error"
version = "1.0.4"
@@ -3188,15 +3127,6 @@ dependencies = [
"syn 1.0.109",
]
[[package]]
name = "quick-xml"
version = "0.37.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb"
dependencies = [
"memchr",
]
[[package]]
name = "quick-xml"
version = "0.38.2"
@@ -3528,31 +3458,6 @@ dependencies = [
"webpki-roots",
]
[[package]]
name = "rfd"
version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef2bee61e6cffa4635c72d7d81a84294e28f0930db0ddcb0f66d10244674ebed"
dependencies = [
"ashpd",
"block2 0.6.1",
"dispatch2",
"glib-sys",
"gobject-sys",
"gtk-sys",
"js-sys",
"log",
"objc2 0.6.2",
"objc2-app-kit 0.3.1",
"objc2-core-foundation",
"objc2-foundation 0.3.1",
"raw-window-handle",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows-sys 0.59.0",
]
[[package]]
name = "ring"
version = "0.17.14"
@@ -3753,12 +3658,6 @@ dependencies = [
"syn 2.0.106",
]
[[package]]
name = "scoped-tls"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
[[package]]
name = "scopeguard"
version = "1.2.0"
@@ -4421,46 +4320,6 @@ dependencies = [
"walkdir",
]
[[package]]
name = "tauri-plugin-dialog"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0beee42a4002bc695550599b011728d9dfabf82f767f134754ed6655e434824e"
dependencies = [
"log",
"raw-window-handle",
"rfd",
"serde",
"serde_json",
"tauri",
"tauri-plugin",
"tauri-plugin-fs",
"thiserror 2.0.16",
"url",
]
[[package]]
name = "tauri-plugin-fs"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "315784ec4be45e90a987687bae7235e6be3d6e9e350d2b75c16b8a4bf22c1db7"
dependencies = [
"anyhow",
"dunce",
"glob",
"percent-encoding",
"schemars 0.8.22",
"serde",
"serde_json",
"serde_repr",
"tauri",
"tauri-plugin",
"tauri-utils",
"thiserror 2.0.16",
"toml 0.9.5",
"url",
]
[[package]]
name = "tauri-plugin-log"
version = "2.6.0"
@@ -4502,7 +4361,7 @@ dependencies = [
"thiserror 2.0.16",
"url",
"windows 0.58.0",
"zbus 4.0.1",
"zbus",
]
[[package]]
@@ -4781,10 +4640,8 @@ dependencies = [
"libc",
"mio",
"pin-project-lite",
"signal-hook-registry",
"slab",
"socket2",
"tracing",
"windows-sys 0.59.0",
]
@@ -4880,18 +4737,6 @@ dependencies = [
"winnow 0.5.40",
]
[[package]]
name = "toml_edit"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7211ff1b8f0d3adae1663b7da9ffe396eabe1ca25f0b0bee42b0da29a9ddce93"
dependencies = [
"indexmap 2.11.0",
"toml_datetime 0.7.0",
"toml_parser",
"winnow 0.7.13",
]
[[package]]
name = "toml_parser"
version = "1.0.2"
@@ -5309,66 +5154,6 @@ dependencies = [
"web-sys",
]
[[package]]
name = "wayland-backend"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35"
dependencies = [
"cc",
"downcast-rs",
"rustix",
"scoped-tls",
"smallvec",
"wayland-sys",
]
[[package]]
name = "wayland-client"
version = "0.31.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d"
dependencies = [
"bitflags 2.9.3",
"rustix",
"wayland-backend",
"wayland-scanner",
]
[[package]]
name = "wayland-protocols"
version = "0.32.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901"
dependencies = [
"bitflags 2.9.3",
"wayland-backend",
"wayland-client",
"wayland-scanner",
]
[[package]]
name = "wayland-scanner"
version = "0.31.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3"
dependencies = [
"proc-macro2",
"quick-xml 0.37.5",
"quote",
]
[[package]]
name = "wayland-sys"
version = "0.31.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142"
dependencies = [
"dlib",
"log",
"pkg-config",
]
[[package]]
name = "web-sys"
version = "0.3.77"
@@ -6010,9 +5795,6 @@ name = "winnow"
version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
dependencies = [
"memchr",
]
[[package]]
name = "winreg"
@@ -6181,7 +5963,7 @@ dependencies = [
"futures-sink",
"futures-util",
"hex",
"nix 0.27.1",
"nix",
"ordered-stream",
"rand 0.8.5",
"serde",
@@ -6192,37 +5974,9 @@ dependencies = [
"uds_windows",
"windows-sys 0.52.0",
"xdg-home",
"zbus_macros 4.0.1",
"zbus_names 3.0.0",
"zvariant 4.0.0",
]
[[package]]
name = "zbus"
version = "5.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d07e46d035fb8e375b2ce63ba4e4ff90a7f73cf2ffb0138b29e1158d2eaadf7"
dependencies = [
"async-broadcast",
"async-recursion",
"async-trait",
"enumflags2",
"event-listener",
"futures-core",
"futures-lite",
"hex",
"nix 0.30.1",
"ordered-stream",
"serde",
"serde_repr",
"tokio",
"tracing",
"uds_windows",
"windows-sys 0.60.2",
"winnow 0.7.13",
"zbus_macros 5.11.0",
"zbus_names 4.2.0",
"zvariant 5.7.0",
"zbus_macros",
"zbus_names",
"zvariant",
]
[[package]]
@@ -6236,22 +5990,7 @@ dependencies = [
"quote",
"regex",
"syn 1.0.109",
"zvariant_utils 1.1.0",
]
[[package]]
name = "zbus_macros"
version = "5.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57e797a9c847ed3ccc5b6254e8bcce056494b375b511b3d6edcec0aeb4defaca"
dependencies = [
"proc-macro-crate 3.4.0",
"proc-macro2",
"quote",
"syn 2.0.106",
"zbus_names 4.2.0",
"zvariant 5.7.0",
"zvariant_utils 3.2.1",
"zvariant_utils",
]
[[package]]
@@ -6262,19 +6001,7 @@ checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c"
dependencies = [
"serde",
"static_assertions",
"zvariant 4.0.0",
]
[[package]]
name = "zbus_names"
version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97"
dependencies = [
"serde",
"static_assertions",
"winnow 0.7.13",
"zvariant 5.7.0",
"zvariant",
]
[[package]]
@@ -6379,22 +6106,7 @@ dependencies = [
"enumflags2",
"serde",
"static_assertions",
"zvariant_derive 4.0.0",
]
[[package]]
name = "zvariant"
version = "5.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "999dd3be73c52b1fccd109a4a81e4fcd20fab1d3599c8121b38d04e1419498db"
dependencies = [
"endi",
"enumflags2",
"serde",
"url",
"winnow 0.7.13",
"zvariant_derive 5.7.0",
"zvariant_utils 3.2.1",
"zvariant_derive",
]
[[package]]
@@ -6407,20 +6119,7 @@ dependencies = [
"proc-macro2",
"quote",
"syn 1.0.109",
"zvariant_utils 1.1.0",
]
[[package]]
name = "zvariant_derive"
version = "5.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6643fd0b26a46d226bd90d3f07c1b5321fe9bb7f04673cb37ac6d6883885b68e"
dependencies = [
"proc-macro-crate 3.4.0",
"proc-macro2",
"quote",
"syn 2.0.106",
"zvariant_utils 3.2.1",
"zvariant_utils",
]
[[package]]
@@ -6433,16 +6132,3 @@ dependencies = [
"quote",
"syn 1.0.109",
]
[[package]]
name = "zvariant_utils"
version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6949d142f89f6916deca2232cf26a8afacf2b9fdc35ce766105e104478be599"
dependencies = [
"proc-macro2",
"quote",
"serde",
"syn 2.0.106",
"winnow 0.7.13",
]

View File

@@ -28,7 +28,6 @@ tauri-plugin-process = "2"
tauri-plugin-updater = "2"
dirs = "5.0"
toml = "0.8"
tauri-plugin-dialog = "2"
[target.'cfg(target_os = "macos")'.dependencies]
objc2 = "0.5"

View File

@@ -8,7 +8,6 @@
"permissions": [
"core:default",
"opener:default",
"dialog:default",
"updater:default",
"process:allow-restart"
]

View File

@@ -10,10 +10,6 @@ use std::path::Path;
/// 获取 Codex 配置目录路径
pub fn get_codex_config_dir() -> PathBuf {
if let Some(custom) = crate::settings::get_codex_override_dir() {
return custom;
}
dirs::home_dir().expect("无法获取用户主目录").join(".codex")
}

View File

@@ -483,26 +483,6 @@ pub async fn get_claude_code_config_path() -> Result<String, String> {
Ok(get_claude_settings_path().to_string_lossy().to_string())
}
/// 获取当前生效的配置目录
#[tauri::command]
pub async fn get_config_dir(
app_type: Option<AppType>,
app: Option<String>,
appType: Option<String>,
) -> Result<String, String> {
let app = app_type
.or_else(|| app.as_deref().map(|s| s.into()))
.or_else(|| appType.as_deref().map(|s| s.into()))
.unwrap_or(AppType::Claude);
let dir = match app {
AppType::Claude => crate::config::get_claude_config_dir(),
AppType::Codex => crate::codex_config::get_codex_config_dir(),
};
Ok(dir.to_string_lossy().to_string())
}
/// 打开配置文件夹
/// 兼容两种参数:`app_type`(推荐)或 `app`(字符串)
#[tauri::command]
@@ -586,15 +566,21 @@ pub async fn open_app_config_folder(handle: tauri::AppHandle) -> Result<bool, St
/// 获取设置
#[tauri::command]
pub async fn get_settings() -> Result<serde_json::Value, String> {
serde_json::to_value(crate::settings::get_settings())
.map_err(|e| format!("序列化设置失败: {}", e))
pub async fn get_settings(_state: State<'_, AppState>) -> Result<serde_json::Value, String> {
// 暂时返回默认设置:系统托盘(菜单栏)显示开关
Ok(serde_json::json!({
"showInTray": true
}))
}
/// 保存设置
#[tauri::command]
pub async fn save_settings(settings: crate::settings::AppSettings) -> Result<bool, String> {
crate::settings::update_settings(settings)?;
pub async fn save_settings(
_state: State<'_, AppState>,
settings: serde_json::Value,
) -> Result<bool, String> {
// TODO: 实现系统托盘显示开关的保存与应用(显示/隐藏菜单栏托盘图标)
log::info!("保存设置: {:?}", settings);
Ok(true)
}

View File

@@ -6,10 +6,6 @@ use std::path::{Path, PathBuf};
/// 获取 Claude Code 配置目录路径
pub fn get_claude_config_dir() -> PathBuf {
if let Some(custom) = crate::settings::get_claude_override_dir() {
return custom;
}
dirs::home_dir()
.expect("无法获取用户主目录")
.join(".claude")

View File

@@ -4,7 +4,6 @@ mod commands;
mod config;
mod migration;
mod provider;
mod settings;
mod store;
use store::AppState;
@@ -243,7 +242,6 @@ pub fn run() {
})
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_dialog::init())
.setup(|app| {
// 注册 Updater 插件(桌面端)
#[cfg(desktop)]
@@ -348,7 +346,6 @@ pub fn run() {
commands::get_claude_config_status,
commands::get_config_status,
commands::get_claude_code_config_path,
commands::get_config_dir,
commands::open_config_folder,
commands::open_external,
commands::get_app_config_path,

View File

@@ -1,147 +0,0 @@
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::PathBuf;
use std::sync::{OnceLock, RwLock};
/// 应用设置结构,允许覆盖默认配置目录
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AppSettings {
#[serde(default = "default_show_in_tray")]
pub show_in_tray: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub claude_config_dir: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub codex_config_dir: Option<String>,
}
fn default_show_in_tray() -> bool {
true
}
impl Default for AppSettings {
fn default() -> Self {
Self {
show_in_tray: true,
claude_config_dir: None,
codex_config_dir: None,
}
}
}
impl AppSettings {
fn settings_path() -> PathBuf {
crate::config::get_app_config_dir().join("settings.json")
}
fn normalize_paths(&mut self) {
self.claude_config_dir = self
.claude_config_dir
.as_ref()
.map(|s| s.trim())
.filter(|s| !s.is_empty())
.map(|s| s.to_string());
self.codex_config_dir = self
.codex_config_dir
.as_ref()
.map(|s| s.trim())
.filter(|s| !s.is_empty())
.map(|s| s.to_string());
}
pub fn load() -> Self {
let path = Self::settings_path();
if let Ok(content) = fs::read_to_string(&path) {
match serde_json::from_str::<AppSettings>(&content) {
Ok(mut settings) => {
settings.normalize_paths();
settings
}
Err(err) => {
log::warn!(
"解析设置文件失败,将使用默认设置。路径: {}, 错误: {}",
path.display(),
err
);
Self::default()
}
}
} else {
Self::default()
}
}
pub fn save(&self) -> Result<(), String> {
let mut normalized = self.clone();
normalized.normalize_paths();
let path = Self::settings_path();
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)
.map_err(|e| format!("创建设置目录失败: {}", e))?;
}
let json = serde_json::to_string_pretty(&normalized)
.map_err(|e| format!("序列化设置失败: {}", e))?;
fs::write(&path, json).map_err(|e| format!("写入设置失败: {}", e))?;
Ok(())
}
}
fn settings_store() -> &'static RwLock<AppSettings> {
static STORE: OnceLock<RwLock<AppSettings>> = OnceLock::new();
STORE.get_or_init(|| RwLock::new(AppSettings::load()))
}
fn resolve_override_path(raw: &str) -> PathBuf {
if raw == "~" {
if let Some(home) = dirs::home_dir() {
return home;
}
} else if let Some(stripped) = raw.strip_prefix("~/") {
if let Some(home) = dirs::home_dir() {
return home.join(stripped);
}
} else if let Some(stripped) = raw.strip_prefix("~\\") {
if let Some(home) = dirs::home_dir() {
return home.join(stripped);
}
}
PathBuf::from(raw)
}
pub fn get_settings() -> AppSettings {
settings_store()
.read()
.expect("读取设置锁失败")
.clone()
}
pub fn update_settings(mut new_settings: AppSettings) -> Result<(), String> {
new_settings.normalize_paths();
new_settings.save()?;
let mut guard = settings_store()
.write()
.expect("写入设置锁失败");
*guard = new_settings;
Ok(())
}
pub fn get_claude_override_dir() -> Option<PathBuf> {
let settings = settings_store().read().ok()?;
settings
.claude_config_dir
.as_ref()
.map(|p| resolve_override_path(p))
}
pub fn get_codex_override_dir() -> Option<PathBuf> {
let settings = settings_store().read().ok()?;
settings
.codex_config_dir
.as_ref()
.map(|p| resolve_override_path(p))
}

View File

@@ -6,16 +6,12 @@ import {
Download,
ExternalLink,
Check,
Undo2,
FolderSearch,
} from "lucide-react";
import { getVersion } from "@tauri-apps/api/app";
import { open } from "@tauri-apps/plugin-dialog";
import "../lib/tauri-api";
import { relaunchApp } from "../lib/updater";
import { useUpdate } from "../contexts/UpdateContext";
import type { Settings } from "../types";
import type { AppType } from "../lib/tauri-api";
interface SettingsModalProps {
onClose: () => void;
@@ -24,16 +20,12 @@ interface SettingsModalProps {
export default function SettingsModal({ onClose }: SettingsModalProps) {
const [settings, setSettings] = useState<Settings>({
showInTray: true,
claudeConfigDir: undefined,
codexConfigDir: undefined,
});
const [configPath, setConfigPath] = useState<string>("");
const [version, setVersion] = useState<string>("");
const [isCheckingUpdate, setIsCheckingUpdate] = useState(false);
const [isDownloading, setIsDownloading] = useState(false);
const [showUpToDate, setShowUpToDate] = useState(false);
const [resolvedClaudeDir, setResolvedClaudeDir] = useState<string>("");
const [resolvedCodexDir, setResolvedCodexDir] = useState<string>("");
const { hasUpdate, updateInfo, updateHandle, checkUpdate, resetDismiss } =
useUpdate();
@@ -41,7 +33,6 @@ export default function SettingsModal({ onClose }: SettingsModalProps) {
loadSettings();
loadConfigPath();
loadVersion();
loadResolvedDirs();
}, []);
const loadVersion = async () => {
@@ -58,21 +49,12 @@ export default function SettingsModal({ onClose }: SettingsModalProps) {
const loadSettings = async () => {
try {
const loadedSettings = await window.api.getSettings();
const showInTray =
(loadedSettings as any)?.showInTray ??
(loadedSettings as any)?.showInDock ??
true;
setSettings({
showInTray,
claudeConfigDir:
typeof (loadedSettings as any)?.claudeConfigDir === "string"
? (loadedSettings as any).claudeConfigDir
: undefined,
codexConfigDir:
typeof (loadedSettings as any)?.codexConfigDir === "string"
? (loadedSettings as any).codexConfigDir
: undefined,
});
if ((loadedSettings as any)?.showInTray !== undefined) {
setSettings({ showInTray: (loadedSettings as any).showInTray });
} else if ((loadedSettings as any)?.showInDock !== undefined) {
// 向后兼容:若历史上有 showInDock则映射为 showInTray
setSettings({ showInTray: (loadedSettings as any).showInDock });
}
} catch (error) {
console.error("加载设置失败:", error);
}
@@ -89,34 +71,9 @@ export default function SettingsModal({ onClose }: SettingsModalProps) {
}
};
const loadResolvedDirs = async () => {
try {
const [claudeDir, codexDir] = await Promise.all([
window.api.getConfigDir("claude"),
window.api.getConfigDir("codex"),
]);
setResolvedClaudeDir(claudeDir || "");
setResolvedCodexDir(codexDir || "");
} catch (error) {
console.error("获取配置目录失败:", error);
}
};
const saveSettings = async () => {
try {
const payload: Settings = {
...settings,
claudeConfigDir:
settings.claudeConfigDir && settings.claudeConfigDir.trim() !== ""
? settings.claudeConfigDir.trim()
: undefined,
codexConfigDir:
settings.codexConfigDir && settings.codexConfigDir.trim() !== ""
? settings.codexConfigDir.trim()
: undefined,
};
await window.api.saveSettings(payload);
setSettings(payload);
await window.api.saveSettings(settings);
onClose();
} catch (error) {
console.error("保存设置失败:", error);
@@ -178,35 +135,6 @@ export default function SettingsModal({ onClose }: SettingsModalProps) {
}
};
const handleBrowseConfigDir = async (app: AppType) => {
try {
const currentResolved =
app === "claude"
? settings.claudeConfigDir ?? resolvedClaudeDir
: settings.codexConfigDir ?? resolvedCodexDir;
const selected = await open({
directory: true,
multiple: false,
defaultPath: currentResolved || undefined,
});
if (!selected || Array.isArray(selected)) {
return;
}
if (app === "claude") {
setSettings((prev) => ({ ...prev, claudeConfigDir: selected }));
setResolvedClaudeDir(selected);
} else {
setSettings((prev) => ({ ...prev, codexConfigDir: selected }));
setResolvedCodexDir(selected);
}
} catch (error) {
console.error("选择配置目录失败:", error);
}
};
const handleOpenReleaseNotes = async () => {
try {
const targetVersion = updateInfo?.availableVersion || version;
@@ -297,102 +225,6 @@ export default function SettingsModal({ onClose }: SettingsModalProps) {
</div>
</div>
{/* 配置目录覆盖 */}
<div>
<h3 className="text-sm font-medium text-gray-900 dark:text-gray-100 mb-2">
</h3>
<p className="text-xs text-gray-500 dark:text-gray-400 mb-3 leading-relaxed">
Windows WSL Claude Code Codex
使macOS/Windows
</p>
<div className="space-y-3">
<div>
<label className="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">
Claude Code
</label>
<div className="flex gap-2">
<input
type="text"
value={
settings.claudeConfigDir ?? resolvedClaudeDir ?? ""
}
onChange={(e) =>
setSettings({
...settings,
claudeConfigDir: e.target.value,
})
}
placeholder="例如:/mnt/c/Users/<你的用户名>/.claude"
className="flex-1 px-3 py-2 text-xs font-mono bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500/40"
/>
<button
type="button"
onClick={() => handleBrowseConfigDir("claude")}
className="px-2 py-2 text-xs text-gray-500 dark:text-gray-400 hover:text-blue-500 dark:hover:text-blue-400 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors"
title="浏览目录"
>
<FolderSearch size={16} />
</button>
<button
type="button"
onClick={() =>
setSettings({
...settings,
claudeConfigDir: undefined,
})
}
className="px-2 py-2 text-xs text-gray-500 dark:text-gray-400 hover:text-blue-500 dark:hover:text-blue-400 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors"
title="恢复默认目录"
>
<Undo2 size={16} />
</button>
</div>
</div>
<div>
<label className="block text-xs font-medium text-gray-500 dark:text-gray-400 mb-1">
Codex
</label>
<div className="flex gap-2">
<input
type="text"
value={settings.codexConfigDir ?? resolvedCodexDir ?? ""}
onChange={(e) =>
setSettings({
...settings,
codexConfigDir: e.target.value,
})
}
placeholder="例如:/mnt/c/Users/<你的用户名>/.codex"
className="flex-1 px-3 py-2 text-xs font-mono bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500/40"
/>
<button
type="button"
onClick={() => handleBrowseConfigDir("codex")}
className="px-2 py-2 text-xs text-gray-500 dark:text-gray-400 hover:text-blue-500 dark:hover:text-blue-400 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors"
title="浏览目录"
>
<FolderSearch size={16} />
</button>
<button
type="button"
onClick={() =>
setSettings({
...settings,
codexConfigDir: undefined,
})
}
className="px-2 py-2 text-xs text-gray-500 dark:text-gray-400 hover:text-blue-500 dark:hover:text-blue-400 hover:bg-gray-100 dark:hover:bg-gray-800 rounded-lg transition-colors"
title="恢复默认目录"
>
<Undo2 size={16} />
</button>
</div>
</div>
</div>
</div>
{/* 关于 */}
<div>
<h3 className="text-sm font-medium text-gray-900 dark:text-gray-100 mb-3">

View File

@@ -122,16 +122,6 @@ export const tauriAPI = {
}
},
// 获取当前生效的配置目录
getConfigDir: async (app?: AppType): Promise<string> => {
try {
return await invoke("get_config_dir", { app_type: app, app });
} catch (error) {
console.error("获取配置目录失败:", error);
return "";
}
},
// 获取 Claude Code 配置状态
getClaudeConfigStatus: async (): Promise<ConfigStatus> => {
try {

View File

@@ -24,8 +24,4 @@ export interface AppConfig {
export interface Settings {
// 是否在系统托盘macOS 菜单栏)显示图标
showInTray: boolean;
// 覆盖 Claude Code 配置目录(可选)
claudeConfigDir?: string;
// 覆盖 Codex 配置目录(可选)
codexConfigDir?: string;
}

1
src/vite-env.d.ts vendored
View File

@@ -28,7 +28,6 @@ declare global {
getClaudeCodeConfigPath: () => Promise<string>;
getClaudeConfigStatus: () => Promise<ConfigStatus>;
getConfigStatus: (app?: AppType) => Promise<ConfigStatus>;
getConfigDir: (app?: AppType) => Promise<string>;
selectConfigFile: () => Promise<string | null>;
openConfigFolder: (app?: AppType) => Promise<void>;
openExternal: (url: string) => Promise<void>;