From 2667ed13f15fc10f8a99473e54b7743027aeb9fe Mon Sep 17 00:00:00 2001
From: GyDi <zzzgydi@gmail.com>
Date: Fri, 18 Nov 2022 18:18:41 +0800
Subject: [PATCH] refactor: done

---
 src-tauri/src/cmds.rs                         | 93 ++++++-------------
 src-tauri/src/config/clash.rs                 | 12 +--
 src-tauri/src/config/config.rs                | 81 +++++++++++++++-
 src-tauri/src/config/draft.rs                 |  7 +-
 src-tauri/src/config/mod.rs                   |  2 +
 src-tauri/src/config/prfitem.rs               |  4 +-
 src-tauri/src/config/profiles.rs              | 57 +++++++-----
 src-tauri/src/config/runtime.rs               | 18 ++++
 src-tauri/src/config/verge.rs                 | 12 +--
 src-tauri/src/core/clash_api.rs               | 10 +-
 src-tauri/src/core/core.rs                    | 79 ++++++----------
 src-tauri/src/core/timer.rs                   |  3 -
 src-tauri/src/feat.rs                         | 56 ++++++-----
 src-tauri/src/main.rs                         | 15 +--
 src-tauri/src/utils/config.rs                 | 48 ----------
 src-tauri/src/utils/dirs.rs                   | 10 +-
 src-tauri/src/utils/help.rs                   | 62 ++++++++++---
 src-tauri/src/utils/init.rs                   | 41 ++++----
 src-tauri/src/utils/mod.rs                    |  1 -
 src-tauri/src/utils/resolve.rs                |  3 +-
 src/components/profile/enhanced.tsx           | 10 +-
 .../setting/mods/clash-field-viewer.tsx       |  4 +-
 src/pages/profiles.tsx                        | 14 +--
 src/services/cmds.ts                          | 20 +---
 24 files changed, 332 insertions(+), 330 deletions(-)
 create mode 100644 src-tauri/src/config/runtime.rs
 delete mode 100644 src-tauri/src/utils/config.rs

diff --git a/src-tauri/src/cmds.rs b/src-tauri/src/cmds.rs
index c96e90e..fb05e43 100644
--- a/src-tauri/src/cmds.rs
+++ b/src-tauri/src/cmds.rs
@@ -5,7 +5,7 @@ use crate::{
     utils::{dirs, help},
 };
 use crate::{ret_err, wrap_err};
-use anyhow::Result;
+use anyhow::{Context, Result};
 use serde_yaml::Mapping;
 use std::collections::{HashMap, VecDeque};
 use sysproxy::Sysproxy;
@@ -19,7 +19,9 @@ pub fn get_profiles() -> CmdResult<IProfiles> {
 
 #[tauri::command]
 pub async fn enhance_profiles() -> CmdResult {
-    wrap_err!(feat::handle_activate().await)
+    wrap_err!(CoreManager::global().update_config().await)?;
+    handle::Handle::refresh_clash();
+    Ok(())
 }
 
 #[deprecated]
@@ -41,48 +43,24 @@ pub async fn update_profile(index: String, option: Option<PrfOption>) -> CmdResu
 }
 
 #[tauri::command]
-pub async fn select_profile(index: String) -> CmdResult {
-    wrap_err!({ Config::profiles().draft().put_current(index) })?;
-
-    match feat::handle_activate().await {
-        Ok(_) => {
-            Config::profiles().apply();
-            wrap_err!(Config::profiles().data().save_file())?;
-            Ok(())
-        }
-        Err(err) => {
-            Config::profiles().discard();
-            log::error!(target: "app", "{err}");
-            Err(format!("{err}"))
-        }
+pub async fn delete_profile(index: String) -> CmdResult {
+    let should_update = wrap_err!({ Config::profiles().data().delete_item(index) })?;
+    if should_update {
+        wrap_err!(CoreManager::global().update_config().await)?;
+        handle::Handle::refresh_clash();
     }
-}
-
-/// change the profile chain
-#[tauri::command]
-pub async fn change_profile_chain(chain: Option<Vec<String>>) -> CmdResult {
-    wrap_err!({ Config::profiles().draft().put_chain(chain) })?;
 
-    match feat::handle_activate().await {
-        Ok(_) => {
-            Config::profiles().apply();
-            wrap_err!(Config::profiles().data().save_file())?;
-            Ok(())
-        }
-        Err(err) => {
-            Config::profiles().discard();
-            log::error!(target: "app", "{err}");
-            Err(format!("{err}"))
-        }
-    }
+    Ok(())
 }
 
+/// 修改profiles的
 #[tauri::command]
-pub async fn change_profile_valid(valid: Option<Vec<String>>) -> CmdResult {
-    wrap_err!({ Config::profiles().draft().put_valid(valid) })?;
+pub async fn patch_profiles_config(profiles: IProfiles) -> CmdResult {
+    wrap_err!({ Config::profiles().draft().patch_config(profiles) })?;
 
-    match feat::handle_activate().await {
+    match CoreManager::global().update_config().await {
         Ok(_) => {
+            handle::Handle::refresh_clash();
             Config::profiles().apply();
             wrap_err!(Config::profiles().data().save_file())?;
             Ok(())
@@ -95,20 +73,10 @@ pub async fn change_profile_valid(valid: Option<Vec<String>>) -> CmdResult {
     }
 }
 
-#[tauri::command]
-pub async fn delete_profile(index: String) -> CmdResult {
-    let should_update = wrap_err!({ Config::profiles().data().delete_item(index) })?;
-    if should_update {
-        wrap_err!(feat::handle_activate().await)?;
-    }
-
-    Ok(())
-}
-
+/// 修改某个profile item的
 #[tauri::command]
 pub fn patch_profile(index: String, profile: PrfItem) -> CmdResult {
     wrap_err!(Config::profiles().data().patch_item(index, profile))?;
-
     wrap_err!(timer::Timer::global().refresh())
 }
 
@@ -157,34 +125,29 @@ pub fn get_clash_info() -> CmdResult<ClashInfoN> {
 
 #[tauri::command]
 pub fn get_runtime_config() -> CmdResult<Option<Mapping>> {
-    Ok(CoreManager::global().runtime_config.lock().config.clone())
+    Ok(Config::runtime().latest().config.clone())
 }
 
 #[tauri::command]
-pub fn get_runtime_yaml() -> CmdResult<Option<String>> {
-    Ok(CoreManager::global()
-        .runtime_config
-        .lock()
-        .config_yaml
-        .clone())
+pub fn get_runtime_yaml() -> CmdResult<String> {
+    let runtime = Config::runtime();
+    let runtime = runtime.latest();
+    let config = runtime.config.as_ref();
+    wrap_err!(config
+        .ok_or(anyhow::anyhow!("failed to parse config to yaml file"))
+        .and_then(
+            |config| serde_yaml::to_string(config).context("failed to convert config to yaml")
+        ))
 }
 
 #[tauri::command]
 pub fn get_runtime_exists() -> CmdResult<Vec<String>> {
-    Ok(CoreManager::global()
-        .runtime_config
-        .lock()
-        .exists_keys
-        .clone())
+    Ok(Config::runtime().latest().exists_keys.clone())
 }
 
 #[tauri::command]
 pub fn get_runtime_logs() -> CmdResult<HashMap<String, Vec<(String, String)>>> {
-    Ok(CoreManager::global()
-        .runtime_config
-        .lock()
-        .chain_logs
-        .clone())
+    Ok(Config::runtime().latest().chain_logs.clone())
 }
 
 #[tauri::command]
diff --git a/src-tauri/src/config/clash.rs b/src-tauri/src/config/clash.rs
index e864d48..549ccfc 100644
--- a/src-tauri/src/config/clash.rs
+++ b/src-tauri/src/config/clash.rs
@@ -1,4 +1,4 @@
-use crate::utils::{config, dirs};
+use crate::utils::{dirs, help};
 use anyhow::Result;
 use serde::{Deserialize, Serialize};
 use serde_yaml::{Mapping, Value};
@@ -8,7 +8,7 @@ pub struct IClashTemp(pub Mapping);
 
 impl IClashTemp {
     pub fn new() -> Self {
-        match dirs::clash_path().and_then(|path| config::read_merge_mapping(&path)) {
+        match dirs::clash_path().and_then(|path| help::read_merge_mapping(&path)) {
             Ok(map) => Self(map),
             Err(err) => {
                 log::error!(target: "app", "{err}");
@@ -20,7 +20,7 @@ impl IClashTemp {
     pub fn template() -> Self {
         let mut map = Mapping::new();
 
-        map.insert("mixed-port".into(), 7892.into());
+        map.insert("mixed-port".into(), 7890.into());
         map.insert("log-level".into(), "info".into());
         map.insert("allow-lan".into(), false.into());
         map.insert("mode".into(), "rule".into());
@@ -37,10 +37,10 @@ impl IClashTemp {
     }
 
     pub fn save_config(&self) -> Result<()> {
-        config::save_yaml(
-            dirs::clash_path()?,
+        help::save_yaml(
+            &dirs::clash_path()?,
             &self.0,
-            Some("# Default Config For ClashN Core\n\n"),
+            Some("# Generated by Clash Verge"),
         )
     }
 
diff --git a/src-tauri/src/config/config.rs b/src-tauri/src/config/config.rs
index 56b7149..1ba7a1e 100644
--- a/src-tauri/src/config/config.rs
+++ b/src-tauri/src/config/config.rs
@@ -1,10 +1,20 @@
-use super::{Draft, IClashTemp, IProfiles, IVerge};
+use super::{Draft, IClashTemp, IProfiles, IRuntime, IVerge};
+use crate::{
+    enhance,
+    utils::{dirs, help},
+};
+use anyhow::{anyhow, Result};
 use once_cell::sync::OnceCell;
+use std::{env::temp_dir, path::PathBuf};
+
+pub const RUNTIME_CONFIG: &str = "clash-verge.yaml";
+pub const CHECK_CONFIG: &str = "clash-verge-check.yaml";
 
 pub struct Config {
     clash_config: Draft<IClashTemp>,
     verge_config: Draft<IVerge>,
     profiles_config: Draft<IProfiles>,
+    runtime_config: Draft<IRuntime>,
 }
 
 impl Config {
@@ -15,6 +25,7 @@ impl Config {
             clash_config: Draft::from(IClashTemp::new()),
             verge_config: Draft::from(IVerge::new()),
             profiles_config: Draft::from(IProfiles::new()),
+            runtime_config: Draft::from(IRuntime::new()),
         })
     }
 
@@ -29,4 +40,72 @@ impl Config {
     pub fn profiles() -> Draft<IProfiles> {
         Self::global().profiles_config.clone()
     }
+
+    pub fn runtime() -> Draft<IRuntime> {
+        Self::global().runtime_config.clone()
+    }
+
+    /// 初始化配置
+    pub fn init_config() -> Result<()> {
+        crate::log_err!(Self::generate());
+        if let Err(err) = Self::generate_file(ConfigType::Run) {
+            log::error!(target: "app", "{err}");
+
+            let runtime_path = dirs::app_home_dir()?.join(RUNTIME_CONFIG);
+            // 如果不存在就将默认的clash文件拿过来
+            if !runtime_path.exists() {
+                help::save_yaml(
+                    &runtime_path,
+                    &Config::clash().latest().0,
+                    Some("# Clash Verge Runtime"),
+                )?;
+            }
+        }
+        Ok(())
+    }
+
+    /// 将配置丢到对应的文件中
+    pub fn generate_file(typ: ConfigType) -> Result<PathBuf> {
+        let path = match typ {
+            ConfigType::Run => dirs::app_home_dir()?.join(RUNTIME_CONFIG),
+            ConfigType::Check => temp_dir().join(CHECK_CONFIG),
+        };
+
+        let runtime = Config::runtime();
+        let runtime = runtime.latest();
+        let config = runtime
+            .config
+            .as_ref()
+            .ok_or(anyhow!("failed to get runtime config"))?;
+
+        help::save_yaml(&path, &config, Some("# Generated by Clash Verge"))?;
+        Ok(path)
+    }
+
+    /// 生成配置存好
+    pub fn generate() -> Result<()> {
+        let clash_config = { Config::clash().latest().clone() };
+
+        let tun_mode = { Config::verge().latest().enable_tun_mode.clone() };
+        let tun_mode = tun_mode.unwrap_or(false);
+
+        let pa = { Config::profiles().latest().gen_activate()? };
+
+        let (config, exists_keys, logs) =
+            enhance::enhance_config(clash_config.0, pa.current, pa.chain, pa.valid, tun_mode);
+
+        *Config::runtime().draft() = IRuntime {
+            config: Some(config),
+            exists_keys,
+            chain_logs: logs,
+        };
+
+        Ok(())
+    }
+}
+
+#[derive(Debug)]
+pub enum ConfigType {
+    Run,
+    Check,
 }
diff --git a/src-tauri/src/config/draft.rs b/src-tauri/src/config/draft.rs
index 2f70b28..f1edf67 100644
--- a/src-tauri/src/config/draft.rs
+++ b/src-tauri/src/config/draft.rs
@@ -1,4 +1,4 @@
-use super::{IClashTemp, IProfiles, IVerge};
+use super::{IClashTemp, IProfiles, IRuntime, IVerge};
 use parking_lot::{MappedMutexGuard, Mutex, MutexGuard};
 use std::sync::Arc;
 
@@ -10,6 +10,7 @@ pub struct Draft<T: Clone + ToOwned> {
 macro_rules! draft_define {
     ($id: ident) => {
         impl Draft<$id> {
+            #[allow(unused)]
             pub fn data(&self) -> MappedMutexGuard<$id> {
                 MutexGuard::map(self.inner.lock(), |guard| &mut guard.0)
             }
@@ -65,9 +66,9 @@ macro_rules! draft_define {
 
 // draft_define!(IClash);
 draft_define!(IClashTemp);
-draft_define!(IVerge);
-// draft_define!(Mapping);
 draft_define!(IProfiles);
+draft_define!(IRuntime);
+draft_define!(IVerge);
 
 #[test]
 fn test_draft() {
diff --git a/src-tauri/src/config/mod.rs b/src-tauri/src/config/mod.rs
index 554a4d4..b246a76 100644
--- a/src-tauri/src/config/mod.rs
+++ b/src-tauri/src/config/mod.rs
@@ -3,6 +3,7 @@ mod config;
 mod draft;
 mod prfitem;
 mod profiles;
+mod runtime;
 mod verge;
 
 pub use self::clash::*;
@@ -10,4 +11,5 @@ pub use self::config::*;
 pub use self::draft::*;
 pub use self::prfitem::*;
 pub use self::profiles::*;
+pub use self::runtime::*;
 pub use self::verge::*;
diff --git a/src-tauri/src/config/prfitem.rs b/src-tauri/src/config/prfitem.rs
index b2e6444..664ad05 100644
--- a/src-tauri/src/config/prfitem.rs
+++ b/src-tauri/src/config/prfitem.rs
@@ -1,4 +1,4 @@
-use crate::utils::{config, dirs, help, tmpl};
+use crate::utils::{dirs, help, tmpl};
 use anyhow::{bail, Context, Result};
 use reqwest::StatusCode;
 use serde::{Deserialize, Serialize};
@@ -388,7 +388,7 @@ impl PrfItem {
             }),
             "merge" => Some(ChainItem {
                 uid,
-                data: ChainType::Merge(config::read_merge_mapping(&path).ok()?),
+                data: ChainType::Merge(help::read_merge_mapping(&path).ok()?),
             }),
             _ => None,
         }
diff --git a/src-tauri/src/config/profiles.rs b/src-tauri/src/config/profiles.rs
index 847e233..302b055 100644
--- a/src-tauri/src/config/profiles.rs
+++ b/src-tauri/src/config/profiles.rs
@@ -1,9 +1,8 @@
 use super::{prfitem::PrfItem, ChainItem};
-use crate::utils::{config, dirs, help};
+use crate::utils::{dirs, help};
 use anyhow::{bail, Context, Result};
 use serde::{Deserialize, Serialize};
 use serde_yaml::Mapping;
-use std::collections::HashMap;
 use std::{fs, io::Write};
 
 /// Define the `profiles.yaml` schema
@@ -32,7 +31,7 @@ macro_rules! patch {
 
 impl IProfiles {
     pub fn new() -> Self {
-        match dirs::profiles_path().and_then(|path| config::read_yaml::<Self>(&path)) {
+        match dirs::profiles_path().and_then(|path| help::read_yaml::<Self>(&path)) {
             Ok(mut profiles) => {
                 if profiles.items.is_none() {
                     profiles.items = Some(vec![]);
@@ -62,21 +61,45 @@ impl IProfiles {
         }
     }
 
-    /// save the config to the file
     pub fn save_file(&self) -> Result<()> {
-        config::save_yaml(
-            dirs::profiles_path()?,
+        help::save_yaml(
+            &dirs::profiles_path()?,
             self,
-            Some("# Profiles Config for Clash Verge\n\n"),
+            Some("# Profiles Config for Clash Verge"),
         )
     }
 
-    /// get the current uid
+    /// 只修改current,valid和chain
+    pub fn patch_config(&mut self, patch: IProfiles) -> Result<()> {
+        if self.items.is_none() {
+            self.items = Some(vec![]);
+        }
+
+        if let Some(current) = patch.current {
+            let items = self.items.as_ref().unwrap();
+            let some_uid = Some(current);
+
+            if items.iter().any(|e| e.uid == some_uid) {
+                self.current = some_uid;
+            }
+        }
+
+        if let Some(chain) = patch.chain {
+            self.chain = Some(chain);
+        }
+
+        if let Some(valid) = patch.valid {
+            self.valid = Some(valid);
+        }
+
+        Ok(())
+    }
+
     pub fn get_current(&self) -> Option<String> {
         self.current.clone()
     }
 
-    /// only change the main to the target id
+    #[deprecated]
     pub fn put_current(&mut self, uid: String) -> Result<()> {
         if self.items.is_none() {
             self.items = Some(vec![]);
@@ -93,13 +116,13 @@ impl IProfiles {
         bail!("invalid uid \"{uid}\"");
     }
 
-    /// just change the `chain`
+    #[deprecated]
     pub fn put_chain(&mut self, chain: Option<Vec<String>>) -> Result<()> {
         self.chain = chain;
         self.save_file()
     }
 
-    /// just change the `field`
+    #[deprecated]
     pub fn put_valid(&mut self, valid: Option<Vec<String>>) -> Result<()> {
         self.valid = valid;
         self.save_file()
@@ -283,7 +306,7 @@ impl IProfiles {
                     None => bail!("failed to get the file field"),
                 };
 
-                return Ok(config::read_merge_mapping(&file_path)?);
+                return Ok(help::read_merge_mapping(&file_path)?);
             }
         }
         bail!("failed to find the current profile \"uid:{current}\"");
@@ -316,13 +339,3 @@ pub struct PrfActivate {
     pub chain: Vec<ChainItem>,
     pub valid: Vec<String>,
 }
-
-#[derive(Default, Debug, Clone, Deserialize, Serialize)]
-pub struct RuntimeResult {
-    pub config: Option<Mapping>,
-    pub config_yaml: Option<String>,
-    // 记录在配置中(包括merge和script生成的)出现过的keys
-    // 这些keys不一定都生效
-    pub exists_keys: Vec<String>,
-    pub chain_logs: HashMap<String, Vec<(String, String)>>,
-}
diff --git a/src-tauri/src/config/runtime.rs b/src-tauri/src/config/runtime.rs
new file mode 100644
index 0000000..3b67b06
--- /dev/null
+++ b/src-tauri/src/config/runtime.rs
@@ -0,0 +1,18 @@
+use serde::{Deserialize, Serialize};
+use serde_yaml::Mapping;
+use std::collections::HashMap;
+
+#[derive(Default, Debug, Clone, Deserialize, Serialize)]
+pub struct IRuntime {
+    pub config: Option<Mapping>,
+    // 记录在配置中(包括merge和script生成的)出现过的keys
+    // 这些keys不一定都生效
+    pub exists_keys: Vec<String>,
+    pub chain_logs: HashMap<String, Vec<(String, String)>>,
+}
+
+impl IRuntime {
+    pub fn new() -> Self {
+        Self::default()
+    }
+}
diff --git a/src-tauri/src/config/verge.rs b/src-tauri/src/config/verge.rs
index 8c21cfe..60143ee 100644
--- a/src-tauri/src/config/verge.rs
+++ b/src-tauri/src/config/verge.rs
@@ -1,4 +1,4 @@
-use crate::utils::{config, dirs};
+use crate::utils::{dirs, help};
 use anyhow::Result;
 use serde::{Deserialize, Serialize};
 
@@ -85,7 +85,7 @@ pub struct IVergeTheme {
 
 impl IVerge {
     pub fn new() -> Self {
-        match dirs::verge_path().and_then(|path| config::read_yaml::<IVerge>(&path)) {
+        match dirs::verge_path().and_then(|path| help::read_yaml::<IVerge>(&path)) {
             Ok(config) => config,
             Err(err) => {
                 log::error!(target: "app", "{err}");
@@ -113,11 +113,7 @@ impl IVerge {
 
     /// Save IVerge App Config
     pub fn save_file(&self) -> Result<()> {
-        config::save_yaml(
-            dirs::verge_path()?,
-            &self,
-            Some("# The Config for Clash IVerge App\n\n"),
-        )
+        help::save_yaml(&dirs::verge_path()?, &self, Some("# Clash Verge Config"))
     }
 
     /// patch verge config
@@ -161,7 +157,7 @@ impl IVerge {
         #[cfg(feature = "verge-dev")]
         const SERVER_PORT: u16 = 11233;
 
-        match dirs::verge_path().and_then(|path| config::read_yaml::<IVerge>(&path)) {
+        match dirs::verge_path().and_then(|path| help::read_yaml::<IVerge>(&path)) {
             Ok(config) => config.app_singleton_port.unwrap_or(SERVER_PORT),
             Err(_) => SERVER_PORT, // 这里就不log错误了
         }
diff --git a/src-tauri/src/core/clash_api.rs b/src-tauri/src/core/clash_api.rs
index 35e55d2..cb00db8 100644
--- a/src-tauri/src/core/clash_api.rs
+++ b/src-tauri/src/core/clash_api.rs
@@ -1,19 +1,17 @@
-use crate::{config::Config, utils::dirs};
+use crate::config::Config;
 use anyhow::{bail, Result};
 use reqwest::header::HeaderMap;
 use serde_yaml::Mapping;
 use std::collections::HashMap;
 
 /// PUT /configs
-pub async fn put_configs() -> Result<()> {
+/// path 是绝对路径
+pub async fn put_configs(path: &str) -> Result<()> {
     let (url, headers) = clash_client_info()?;
     let url = format!("{url}/configs");
 
-    let runtime_yaml = dirs::clash_runtime_yaml()?;
-    let runtime_yaml = dirs::path_to_str(&runtime_yaml)?;
-
     let mut data = HashMap::new();
-    data.insert("path", runtime_yaml);
+    data.insert("path", path);
 
     let client = reqwest::ClientBuilder::new().no_proxy().build()?;
     let builder = client.put(&url).headers(headers).json(&data);
diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs
index 4011902..b45ddf3 100644
--- a/src-tauri/src/core/core.rs
+++ b/src-tauri/src/core/core.rs
@@ -1,9 +1,6 @@
 use super::{clash_api, logger::Logger};
-use crate::{
-    config::*,
-    enhance, log_err,
-    utils::{self, dirs},
-};
+use crate::log_err;
+use crate::{config::*, utils::dirs};
 use anyhow::{bail, Context, Result};
 use once_cell::sync::OnceCell;
 use parking_lot::Mutex;
@@ -18,8 +15,6 @@ pub struct CoreManager {
 
     #[allow(unused)]
     use_service_mode: Arc<Mutex<bool>>,
-
-    pub runtime_config: Arc<Mutex<RuntimeResult>>,
 }
 
 impl CoreManager {
@@ -28,7 +23,6 @@ impl CoreManager {
 
         CORE_MANAGER.get_or_init(|| CoreManager {
             sidecar: Arc::new(Mutex::new(None)),
-            runtime_config: Arc::new(Mutex::new(RuntimeResult::default())),
             use_service_mode: Arc::new(Mutex::new(false)),
         })
     }
@@ -50,11 +44,7 @@ impl CoreManager {
 
         tauri::async_runtime::spawn(async {
             // 启动clash
-            if Self::global().run_core().await.is_ok() {
-                // 更新配置
-                sleep(Duration::from_millis(100)).await;
-                crate::log_err!(Self::global().activate_config().await);
-            }
+            log_err!(Self::global().run_core().await);
         });
 
         Ok(())
@@ -62,7 +52,7 @@ impl CoreManager {
 
     /// 检查配置是否正确
     pub fn check_config(&self) -> Result<()> {
-        let config_path = dirs::clash_runtime_yaml()?;
+        let config_path = Config::generate_file(ConfigType::Check)?;
         let config_path = dirs::path_to_str(&config_path)?;
 
         let clash_core = { Config::verge().latest().clash_core.clone() };
@@ -82,6 +72,8 @@ impl CoreManager {
 
     /// 启动核心
     pub async fn run_core(&self) -> Result<()> {
+        let config_path = Config::generate_file(ConfigType::Run)?;
+
         #[cfg(target_os = "windows")]
         {
             use super::win_service;
@@ -123,10 +115,12 @@ impl CoreManager {
         let clash_core = { Config::verge().latest().clash_core.clone() };
         let clash_core = clash_core.unwrap_or("clash".into());
 
+        let config_path = dirs::path_to_str(&config_path)?;
+
         // fix #212
         let args = match clash_core.as_str() {
-            "clash-meta" => vec!["-m", "-d", app_dir],
-            _ => vec!["-d", app_dir],
+            "clash-meta" => vec!["-m", "-d", app_dir, "-f", config_path],
+            _ => vec!["-d", app_dir, "-f", config_path],
         };
 
         let cmd = Command::new_sidecar(clash_core)?;
@@ -199,53 +193,42 @@ impl CoreManager {
             bail!("invalid clash core name \"{clash_core}\"");
         }
 
+        Config::verge().draft().clash_core = Some(clash_core);
+
         // 清掉旧日志
         Logger::global().clear_log();
 
-        {
-            Config::verge().draft().clash_core = Some(clash_core);
-        }
-
         match self.run_core().await {
             Ok(_) => {
-                log_err!({
-                    Config::verge().apply();
-                    Config::verge().latest().save_file()
-                });
-
-                sleep(Duration::from_millis(100)).await; // 等一会儿再更新配置
-                self.activate_config().await?;
+                Config::verge().apply();
+                Config::runtime().apply();
+                log_err!(Config::verge().latest().save_file());
                 Ok(())
             }
             Err(err) => {
                 Config::verge().discard();
+                Config::runtime().discard();
                 Err(err)
             }
         }
     }
 
-    /// 激活一个配置
-    pub async fn activate_config(&self) -> Result<()> {
-        let clash_config = { Config::clash().latest().clone() };
-
-        let tun_mode = { Config::verge().latest().enable_tun_mode.clone() };
-        let tun_mode = tun_mode.unwrap_or(false);
-
-        let pa = { Config::profiles().latest().gen_activate()? };
-
-        let (config, exists_keys, logs) =
-            enhance::enhance_config(clash_config.0, pa.current, pa.chain, pa.valid, tun_mode);
-
-        // 保存到文件中
-        let runtime_path = dirs::clash_runtime_yaml()?;
-        utils::config::save_yaml(runtime_path, &config, Some("# Clash Verge Runtime Config"))?;
+    /// 更新proxies那些
+    /// 如果涉及端口和外部控制则需要重启
+    pub async fn update_config(&self) -> Result<()> {
+        // 更新配置
+        Config::generate()?;
 
         // 检查配置是否正常
         self.check_config()?;
 
+        // 更新运行时配置
+        let path = Config::generate_file(ConfigType::Run)?;
+        let path = dirs::path_to_str(&path)?;
+
         // 发送请求 发送5次
         for i in 0..5 {
-            match clash_api::put_configs().await {
+            match clash_api::put_configs(path).await {
                 Ok(_) => break,
                 Err(err) => {
                     if i < 4 {
@@ -258,16 +241,6 @@ impl CoreManager {
             sleep(Duration::from_millis(250)).await;
         }
 
-        // 保存结果
-        let mut runtime = self.runtime_config.lock();
-        let config_yaml = Some(serde_yaml::to_string(&config).unwrap_or("".into()));
-        *runtime = RuntimeResult {
-            config: Some(config),
-            config_yaml,
-            exists_keys,
-            chain_logs: logs,
-        };
-
         Ok(())
     }
 }
diff --git a/src-tauri/src/core/timer.rs b/src-tauri/src/core/timer.rs
index 8537367..1b40f0f 100644
--- a/src-tauri/src/core/timer.rs
+++ b/src-tauri/src/core/timer.rs
@@ -43,9 +43,6 @@ impl Timer {
         Config::profiles().latest().get_items().map(|items| {
             items
                 .iter()
-                // .filter_map(|item| {
-                //     item.uid.is_some() && item.updated.is_some() && item.option.is_some()
-                // })
                 .filter_map(|item| {
                     // mins to seconds
                     let interval = ((item.option.as_ref()?.update_interval?) as i64) * 60;
diff --git a/src-tauri/src/feat.rs b/src-tauri/src/feat.rs
index 834c1bd..7c73631 100644
--- a/src-tauri/src/feat.rs
+++ b/src-tauri/src/feat.rs
@@ -1,3 +1,9 @@
+//!
+//! feat mod 里的函数主要用于
+//! - hotkey 快捷键
+//! - timer 定时器
+//! - cmds 页面调用
+//!
 use crate::config::*;
 use crate::core::*;
 use crate::log_err;
@@ -8,8 +14,14 @@ use serde_yaml::{Mapping, Value};
 pub fn restart_clash_core() {
     tauri::async_runtime::spawn(async {
         match CoreManager::global().run_core().await {
-            Ok(_) => log_err!(handle_activate().await),
-            Err(err) => log::error!(target: "app", "{err}"),
+            Ok(_) => {
+                handle::Handle::refresh_clash();
+                handle::Handle::notice_message("set_config::ok", "ok");
+            }
+            Err(err) => {
+                handle::Handle::notice_message("set_config::error", format!("{err}"));
+                log::error!(target:"app", "{err}");
+            }
         }
     });
 }
@@ -157,7 +169,7 @@ pub async fn patch_clash(patch: Mapping) -> Result<()> {
             || patch.get("secret").is_some()
             || patch.get("external-controller").is_some()
         {
-            handle_activate().await?;
+            CoreManager::global().run_core().await?;
         }
 
         // 更新系统代理
@@ -196,10 +208,12 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> {
 
     match {
         #[cfg(target_os = "windows")]
-        {}
+        {
+            todo!()
+        }
 
         if tun_mode.is_some() {
-            handle_activate().await?;
+            update_core_config().await?;
         }
 
         if auto_launch.is_some() {
@@ -238,21 +252,6 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> {
     }
 }
 
-/// 激活配置
-pub async fn handle_activate() -> Result<()> {
-    match CoreManager::global().activate_config().await {
-        Ok(_) => {
-            handle::Handle::refresh_clash();
-            handle::Handle::notice_message("set_config::ok", "ok");
-            Ok(())
-        }
-        Err(err) => {
-            handle::Handle::notice_message("set_config::error", format!("{err}"));
-            Err(err)
-        }
-    }
-}
-
 /// 更新某个profile
 /// 如果更新当前配置就激活配置
 pub async fn update_profile(uid: String, option: Option<PrfOption>) -> Result<()> {
@@ -286,8 +285,23 @@ pub async fn update_profile(uid: String, option: Option<PrfOption>) -> Result<()
     };
 
     if should_update {
-        handle_activate().await?;
+        update_core_config().await?;
     }
 
     Ok(())
 }
+
+/// 更新配置
+async fn update_core_config() -> Result<()> {
+    match CoreManager::global().update_config().await {
+        Ok(_) => {
+            handle::Handle::refresh_clash();
+            handle::Handle::notice_message("set_config::ok", "ok");
+            Ok(())
+        }
+        Err(err) => {
+            handle::Handle::notice_message("set_config::error", format!("{err}"));
+            Err(err)
+        }
+    }
+}
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index f78c4e8..abe0e7d 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -49,17 +49,15 @@ fn main() -> std::io::Result<()> {
             cmds::patch_verge_config,
             // cmds::update_hotkeys,
             // profile
+            cmds::get_profiles,
+            cmds::enhance_profiles,
+            cmds::patch_profiles_config,
             cmds::view_profile,
             cmds::patch_profile,
             cmds::create_profile,
             cmds::import_profile,
             cmds::update_profile,
             cmds::delete_profile,
-            cmds::select_profile,
-            cmds::get_profiles,
-            cmds::enhance_profiles,
-            cmds::change_profile_chain,
-            cmds::change_profile_valid,
             cmds::read_profile_file,
             cmds::save_profile_file,
             // service mode
@@ -92,13 +90,6 @@ fn main() -> std::io::Result<()> {
         .build(tauri::generate_context!())
         .expect("error while running tauri application");
 
-    // let app_handle = app.app_handle();
-    // ctrlc::set_handler(move || {
-    //     resolve::resolve_reset();
-    //     app_handle.exit(0);
-    // })
-    // .expect("error while exiting.");
-
     app.run(|app_handle, e| match e {
         tauri::RunEvent::ExitRequested { api, .. } => {
             api.prevent_exit();
diff --git a/src-tauri/src/utils/config.rs b/src-tauri/src/utils/config.rs
deleted file mode 100644
index c1c563a..0000000
--- a/src-tauri/src/utils/config.rs
+++ /dev/null
@@ -1,48 +0,0 @@
-use anyhow::{anyhow, bail, Context, Result};
-use serde::{de::DeserializeOwned, Serialize};
-use serde_yaml::{Mapping, Value};
-use std::{fs, path::PathBuf};
-
-/// read data from yaml as struct T
-pub fn read_yaml<T: DeserializeOwned>(path: &PathBuf) -> Result<T> {
-    if !path.exists() {
-        bail!("file not found \"{}\"", path.display());
-    }
-
-    let yaml_str = fs::read_to_string(&path)
-        .context(format!("failed to read the file \"{}\"", path.display()))?;
-
-    serde_yaml::from_str::<T>(&yaml_str).context(format!(
-        "failed to read the file with yaml format \"{}\"",
-        path.display()
-    ))
-}
-
-/// read mapping from yaml fix #165
-pub fn read_merge_mapping(path: &PathBuf) -> Result<Mapping> {
-    let mut val: Value = read_yaml(path)?;
-    val.apply_merge()
-        .context(format!("failed to apply merge \"{}\"", path.display()))?;
-
-    Ok(val
-        .as_mapping()
-        .ok_or(anyhow!(
-            "failed to transform to yaml mapping \"{}\"",
-            path.display()
-        ))?
-        .to_owned())
-}
-
-/// save the data to the file
-/// can set `prefix` string to add some comments
-pub fn save_yaml<T: Serialize>(path: PathBuf, data: &T, prefix: Option<&str>) -> Result<()> {
-    let data_str = serde_yaml::to_string(data)?;
-
-    let yaml_str = match prefix {
-        Some(prefix) => format!("{prefix}\n{data_str}"),
-        None => data_str,
-    };
-
-    let path_str = path.as_os_str().to_string_lossy().to_string();
-    fs::write(path, yaml_str.as_bytes()).context(format!("failed to save file \"{path_str}\""))
-}
diff --git a/src-tauri/src/utils/dirs.rs b/src-tauri/src/utils/dirs.rs
index 8c32125..553408a 100644
--- a/src-tauri/src/utils/dirs.rs
+++ b/src-tauri/src/utils/dirs.rs
@@ -1,5 +1,5 @@
 use anyhow::Result;
-use std::{env::temp_dir, path::PathBuf};
+use std::path::PathBuf;
 use tauri::{
     api::path::{home_dir, resource_dir},
     Env, PackageInfo,
@@ -107,14 +107,6 @@ pub fn profiles_path() -> Result<PathBuf> {
     Ok(app_home_dir()?.join(PROFILE_YAML))
 }
 
-pub fn clash_runtime_yaml() -> Result<PathBuf> {
-    Ok(app_home_dir()?.join("clash-verge-runtime.yaml"))
-}
-
-pub fn clash_check_yaml() -> Result<PathBuf> {
-    Ok(temp_dir().join("clash-verge-check.yaml"))
-}
-
 pub fn app_res_dir() -> Result<PathBuf> {
     unsafe {
         Ok(RESOURCE_DIR
diff --git a/src-tauri/src/utils/help.rs b/src-tauri/src/utils/help.rs
index 8ad5925..2d4a32f 100644
--- a/src-tauri/src/utils/help.rs
+++ b/src-tauri/src/utils/help.rs
@@ -1,8 +1,52 @@
-use anyhow::Result;
+use anyhow::{anyhow, bail, Context, Result};
 use nanoid::nanoid;
-use std::path::PathBuf;
-use std::process::Command;
-use std::str::FromStr;
+use serde::{de::DeserializeOwned, Serialize};
+use serde_yaml::{Mapping, Value};
+use std::{fs, path::PathBuf, process::Command, str::FromStr};
+
+/// read data from yaml as struct T
+pub fn read_yaml<T: DeserializeOwned>(path: &PathBuf) -> Result<T> {
+    if !path.exists() {
+        bail!("file not found \"{}\"", path.display());
+    }
+
+    let yaml_str = fs::read_to_string(&path)
+        .context(format!("failed to read the file \"{}\"", path.display()))?;
+
+    serde_yaml::from_str::<T>(&yaml_str).context(format!(
+        "failed to read the file with yaml format \"{}\"",
+        path.display()
+    ))
+}
+
+/// read mapping from yaml fix #165
+pub fn read_merge_mapping(path: &PathBuf) -> Result<Mapping> {
+    let mut val: Value = read_yaml(path)?;
+    val.apply_merge()
+        .context(format!("failed to apply merge \"{}\"", path.display()))?;
+
+    Ok(val
+        .as_mapping()
+        .ok_or(anyhow!(
+            "failed to transform to yaml mapping \"{}\"",
+            path.display()
+        ))?
+        .to_owned())
+}
+
+/// save the data to the file
+/// can set `prefix` string to add some comments
+pub fn save_yaml<T: Serialize>(path: &PathBuf, data: &T, prefix: Option<&str>) -> Result<()> {
+    let data_str = serde_yaml::to_string(data)?;
+
+    let yaml_str = match prefix {
+        Some(prefix) => format!("{prefix}\n\n{data_str}"),
+        None => data_str,
+    };
+
+    let path_str = path.as_os_str().to_string_lossy().to_string();
+    fs::write(path, yaml_str.as_bytes()).context(format!("failed to save file \"{path_str}\""))
+}
 
 const ALPHABET: [char; 62] = [
     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
@@ -68,16 +112,6 @@ macro_rules! error {
     };
 }
 
-#[deprecated]
-#[macro_export]
-macro_rules! log_if_err {
-    ($result: expr) => {
-        if let Err(err) = $result {
-            log::error!(target: "app", "{err}");
-        }
-    };
-}
-
 #[macro_export]
 macro_rules! log_err {
     ($result: expr) => {
diff --git a/src-tauri/src/utils/init.rs b/src-tauri/src/utils/init.rs
index 5f8d2a6..3aeeb6c 100644
--- a/src-tauri/src/utils/init.rs
+++ b/src-tauri/src/utils/init.rs
@@ -1,4 +1,4 @@
-use crate::utils::{dirs, tmpl};
+use crate::utils::dirs;
 use anyhow::Result;
 use chrono::Local;
 use log::LevelFilter;
@@ -7,7 +7,6 @@ use log4rs::append::file::FileAppender;
 use log4rs::config::{Appender, Config, Logger, Root};
 use log4rs::encode::pattern::PatternEncoder;
 use std::fs;
-use std::io::Write;
 use tauri::PackageInfo;
 
 /// initialize this instance's log file
@@ -21,13 +20,20 @@ fn init_log() -> Result<()> {
     let log_file = format!("{}.log", local_time);
     let log_file = log_dir.join(log_file);
 
+    #[cfg(feature = "verge-dev")]
+    let time_format = "{d(%Y-%m-%d %H:%M:%S)} {l} - {M} {m}{n}";
+    #[cfg(not(feature = "verge-dev"))]
     let time_format = "{d(%Y-%m-%d %H:%M:%S)} {l} - {m}{n}";
-    let stdout = ConsoleAppender::builder()
-        .encoder(Box::new(PatternEncoder::new(time_format)))
-        .build();
-    let tofile = FileAppender::builder()
-        .encoder(Box::new(PatternEncoder::new(time_format)))
-        .build(log_file)?;
+
+    let encode = Box::new(PatternEncoder::new(time_format));
+
+    let stdout = ConsoleAppender::builder().encoder(encode.clone()).build();
+    let tofile = FileAppender::builder().encoder(encode).build(log_file)?;
+
+    #[cfg(feature = "verge-dev")]
+    let level = LevelFilter::Debug;
+    #[cfg(not(feature = "verge-dev"))]
+    let level = LevelFilter::Info;
 
     let config = Config::builder()
         .appender(Appender::builder().build("stdout", Box::new(stdout)))
@@ -36,9 +42,9 @@ fn init_log() -> Result<()> {
             Logger::builder()
                 .appenders(["file", "stdout"])
                 .additive(false)
-                .build("app", LevelFilter::Info),
+                .build("app", level),
         )
-        .build(Root::builder().appender("stdout").build(LevelFilter::Info))?;
+        .build(Root::builder().appender("stdout").build(level))?;
 
     log4rs::init_config(config)?;
 
@@ -58,21 +64,6 @@ pub fn init_config() -> Result<()> {
         if !app_dir.exists() {
             let _ = fs::create_dir_all(&app_dir);
         }
-
-        // // target path
-        // let clash_path = app_dir.join("config.yaml");
-        // let verge_path = app_dir.join("verge.yaml");
-        // let profile_path = app_dir.join("profiles.yaml");
-
-        // if !clash_path.exists() {
-        //     fs::File::create(clash_path)?.write(tmpl::CLASH_CONFIG)?;
-        // }
-        // if !verge_path.exists() {
-        //     fs::File::create(verge_path)?.write(tmpl::VERGE_CONFIG)?;
-        // }
-        // if !profile_path.exists() {
-        //     fs::File::create(profile_path)?.write(tmpl::PROFILES_CONFIG)?;
-        // }
     });
 
     let _ = dirs::app_profiles_dir().map(|profiles_dir| {
diff --git a/src-tauri/src/utils/mod.rs b/src-tauri/src/utils/mod.rs
index 8fb66eb..aeb0a60 100644
--- a/src-tauri/src/utils/mod.rs
+++ b/src-tauri/src/utils/mod.rs
@@ -1,4 +1,3 @@
-pub mod config;
 pub mod dirs;
 pub mod help;
 pub mod init;
diff --git a/src-tauri/src/utils/resolve.rs b/src-tauri/src/utils/resolve.rs
index 9e6792e..737042c 100644
--- a/src-tauri/src/utils/resolve.rs
+++ b/src-tauri/src/utils/resolve.rs
@@ -10,9 +10,10 @@ pub fn resolve_setup(app: &mut App) {
 
     handle::Handle::global().init(app.app_handle());
 
-    init::init_resources(app.package_info());
+    log_err!(init::init_resources(app.package_info()));
 
     // 启动核心
+    log_err!(Config::init_config());
     log_err!(CoreManager::global().init());
 
     // setup a simple http server for singleton
diff --git a/src/components/profile/enhanced.tsx b/src/components/profile/enhanced.tsx
index 6c9a5fd..3c38913 100644
--- a/src/components/profile/enhanced.tsx
+++ b/src/components/profile/enhanced.tsx
@@ -7,7 +7,7 @@ import {
   getProfiles,
   deleteProfile,
   enhanceProfiles,
-  changeProfileChain,
+  patchProfilesConfig,
   getRuntimeLogs,
 } from "@/services/cmds";
 import ProfileMore from "./profile-more";
@@ -43,7 +43,7 @@ const EnhancedMode = (props: Props) => {
     if (chain.includes(uid)) return;
 
     const newChain = [...chain, uid];
-    await changeProfileChain(newChain);
+    await patchProfilesConfig({ chain: newChain });
     mutateProfiles((conf = {}) => ({ ...conf, chain: newChain }), true);
     mutateLogs();
   });
@@ -52,7 +52,7 @@ const EnhancedMode = (props: Props) => {
     if (!chain.includes(uid)) return;
 
     const newChain = chain.filter((i) => i !== uid);
-    await changeProfileChain(newChain);
+    await patchProfilesConfig({ chain: newChain });
     mutateProfiles((conf = {}) => ({ ...conf, chain: newChain }), true);
     mutateLogs();
   });
@@ -72,7 +72,7 @@ const EnhancedMode = (props: Props) => {
     if (!chain.includes(uid)) return;
 
     const newChain = [uid].concat(chain.filter((i) => i !== uid));
-    await changeProfileChain(newChain);
+    await patchProfilesConfig({ chain: newChain });
     mutateProfiles((conf = {}) => ({ ...conf, chain: newChain }), true);
     mutateLogs();
   });
@@ -81,7 +81,7 @@ const EnhancedMode = (props: Props) => {
     if (!chain.includes(uid)) return;
 
     const newChain = chain.filter((i) => i !== uid).concat([uid]);
-    await changeProfileChain(newChain);
+    await patchProfilesConfig({ chain: newChain });
     mutateProfiles((conf = {}) => ({ ...conf, chain: newChain }), true);
     mutateLogs();
   });
diff --git a/src/components/setting/mods/clash-field-viewer.tsx b/src/components/setting/mods/clash-field-viewer.tsx
index c365a9b..dbfa51d 100644
--- a/src/components/setting/mods/clash-field-viewer.tsx
+++ b/src/components/setting/mods/clash-field-viewer.tsx
@@ -15,9 +15,9 @@ import {
 } from "@mui/material";
 import { InfoRounded } from "@mui/icons-material";
 import {
-  changeProfileValid,
   getProfiles,
   getRuntimeExists,
+  patchProfilesConfig,
 } from "@/services/cmds";
 import { ModalHandler } from "@/hooks/use-modal-handler";
 import {
@@ -91,7 +91,7 @@ const ClashFieldViewer = ({ handler }: Props) => {
     if (curSet.size === oldSet.size && curSet.size === joinSet.size) return;
 
     try {
-      await changeProfileValid([...curSet]);
+      await patchProfilesConfig({ valid: [...curSet] });
       mutateProfile();
       // Notice.success("Refresh clash config", 1000);
     } catch (err: any) {
diff --git a/src/pages/profiles.tsx b/src/pages/profiles.tsx
index 241a497..a56f275 100644
--- a/src/pages/profiles.tsx
+++ b/src/pages/profiles.tsx
@@ -7,7 +7,7 @@ import { useTranslation } from "react-i18next";
 import {
   getProfiles,
   patchProfile,
-  selectProfile,
+  patchProfilesConfig,
   importProfile,
 } from "@/services/cmds";
 import { getProxies, updateProxy } from "@/services/api";
@@ -113,7 +113,7 @@ const ProfilePage = () => {
 
         if (!newProfiles.current && remoteItem) {
           const current = remoteItem.uid;
-          selectProfile(current);
+          patchProfilesConfig({ current });
           mutate("getProfiles", { ...newProfiles, current }, true);
           mutate("getRuntimeLogs");
         }
@@ -125,13 +125,13 @@ const ProfilePage = () => {
     }
   };
 
-  const onSelect = useLockFn(async (uid: string, force: boolean) => {
-    if (!force && uid === profiles.current) return;
+  const onSelect = useLockFn(async (current: string, force: boolean) => {
+    if (!force && current === profiles.current) return;
 
     try {
-      await selectProfile(uid);
-      setCurrentProfile(uid);
-      mutate("getProfiles", { ...profiles, current: uid }, true);
+      await patchProfilesConfig({ current });
+      setCurrentProfile(current);
+      mutate("getProfiles", { ...profiles, current: current }, true);
       mutate("getRuntimeLogs");
       // if (force) Notice.success("Refresh clash config", 1000);
     } catch (err: any) {
diff --git a/src/services/cmds.ts b/src/services/cmds.ts
index 2203be6..43faf4b 100644
--- a/src/services/cmds.ts
+++ b/src/services/cmds.ts
@@ -32,6 +32,10 @@ export async function enhanceProfiles() {
   return invoke<void>("enhance_profiles");
 }
 
+export async function patchProfilesConfig(profiles: CmdType.ProfilesConfig) {
+  return invoke<void>("patch_profiles_config");
+}
+
 export async function createProfile(
   item: Partial<CmdType.ProfileItem>,
   fileData?: string | null
@@ -76,18 +80,6 @@ export async function patchProfile(
   return invoke<void>("patch_profile", { index, profile });
 }
 
-export async function selectProfile(index: string) {
-  return invoke<void>("select_profile", { index });
-}
-
-export async function changeProfileChain(chain?: string[]) {
-  return invoke<void>("change_profile_chain", { chain });
-}
-
-export async function changeProfileValid(valid?: string[]) {
-  return invoke<void>("change_profile_valid", { valid });
-}
-
 export async function getClashInfo() {
   return invoke<CmdType.ClashInfo | null>("get_clash_info");
 }
@@ -136,10 +128,6 @@ export async function restartSidecar() {
   return invoke<void>("restart_sidecar");
 }
 
-// export async function killSidecar() {
-//   return invoke<any>("kill_sidecar");
-// }
-
 export async function openAppDir() {
   return invoke<void>("open_app_dir").catch((err) =>
     Notice.error(err?.message || err.toString(), 1500)
-- 
GitLab