refactor: improve code quality and fix linting issues

- Derive Default trait instead of manual implementation for McpRoot and ProviderManager
- Remove redundant closures in codex_config.rs and config.rs
- Simplify match statements to if let patterns in migration.rs and lib.rs
- Remove unnecessary type conversions and borrows in lib.rs
- Fix i18n key inconsistency: sequentialThinking → sequential-thinking
- Format TypeScript files to match Prettier style

All clippy warnings resolved, code passes all quality checks.
This commit is contained in:
Jason
2025-10-12 16:52:32 +08:00
parent 2ec0a10a2c
commit 6e2c80531d
9 changed files with 30 additions and 54 deletions

View File

@@ -10,7 +10,7 @@ pub struct McpConfig {
} }
/// MCP 根:按客户端分开维护(无历史兼容压力,直接以 v2 结构落地) /// MCP 根:按客户端分开维护(无历史兼容压力,直接以 v2 结构落地)
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct McpRoot { pub struct McpRoot {
#[serde(default)] #[serde(default)]
pub claude: McpConfig, pub claude: McpConfig,
@@ -18,15 +18,6 @@ pub struct McpRoot {
pub codex: McpConfig, pub codex: McpConfig,
} }
impl Default for McpRoot {
fn default() -> Self {
Self {
claude: McpConfig::default(),
codex: McpConfig::default(),
}
}
}
use crate::config::{copy_file, get_app_config_dir, get_app_config_path, write_json_file}; use crate::config::{copy_file, get_app_config_dir, get_app_config_path, write_json_file};
use crate::provider::ProviderManager; use crate::provider::ProviderManager;

View File

@@ -33,7 +33,7 @@ pub fn get_codex_provider_paths(
provider_name: Option<&str>, provider_name: Option<&str>,
) -> (PathBuf, PathBuf) { ) -> (PathBuf, PathBuf) {
let base_name = provider_name let base_name = provider_name
.map(|name| sanitize_provider_name(name)) .map(sanitize_provider_name)
.unwrap_or_else(|| sanitize_provider_name(provider_id)); .unwrap_or_else(|| sanitize_provider_name(provider_id));
let auth_path = get_codex_config_dir().join(format!("auth-{}.json", base_name)); let auth_path = get_codex_config_dir().join(format!("auth-{}.json", base_name));

View File

@@ -106,7 +106,7 @@ pub fn sanitize_provider_name(name: &str) -> String {
/// 获取供应商配置文件路径 /// 获取供应商配置文件路径
pub fn get_provider_config_path(provider_id: &str, provider_name: Option<&str>) -> PathBuf { pub fn get_provider_config_path(provider_id: &str, provider_name: Option<&str>) -> PathBuf {
let base_name = provider_name let base_name = provider_name
.map(|name| sanitize_provider_name(name)) .map(sanitize_provider_name)
.unwrap_or_else(|| sanitize_provider_name(provider_id)); .unwrap_or_else(|| sanitize_provider_name(provider_id));
get_claude_config_dir().join(format!("settings-{}.json", base_name)) get_claude_config_dir().join(format!("settings-{}.json", base_name))

View File

@@ -219,7 +219,7 @@ async fn switch_provider_internal(
let provider_id_clone = provider_id.clone(); let provider_id_clone = provider_id.clone();
crate::commands::switch_provider( crate::commands::switch_provider(
app_state.clone().into(), app_state.clone(),
Some(app_type), Some(app_type),
None, None,
None, None,
@@ -281,8 +281,8 @@ pub fn run() {
let builder = builder let builder = builder
// 拦截窗口关闭:根据设置决定是否最小化到托盘 // 拦截窗口关闭:根据设置决定是否最小化到托盘
.on_window_event(|window, event| match event { .on_window_event(|window, event| {
tauri::WindowEvent::CloseRequested { api, .. } => { if let tauri::WindowEvent::CloseRequested { api, .. } = event {
let settings = crate::settings::get_settings(); let settings = crate::settings::get_settings();
if settings.minimize_to_tray_on_close { if settings.minimize_to_tray_on_close {
@@ -294,13 +294,12 @@ pub fn run() {
} }
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
{ {
apply_tray_policy(&window.app_handle(), false); apply_tray_policy(window.app_handle(), false);
} }
} else { } else {
window.app_handle().exit(0); window.app_handle().exit(0);
} }
} }
_ => {}
}) })
.plugin(tauri_plugin_process::init()) .plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_dialog::init())
@@ -362,7 +361,7 @@ pub fn run() {
// 首次启动迁移:扫描副本文件,合并到 config.json并归档副本旧 config.json 先归档 // 首次启动迁移:扫描副本文件,合并到 config.json并归档副本旧 config.json 先归档
{ {
let mut config_guard = app_state.config.lock().unwrap(); let mut config_guard = app_state.config.lock().unwrap();
let migrated = migration::migrate_copies_into_config(&mut *config_guard)?; let migrated = migration::migrate_copies_into_config(&mut config_guard)?;
if migrated { if migrated {
log::info!("已将副本文件导入到 config.json并完成归档"); log::info!("已将副本文件导入到 config.json并完成归档");
} }
@@ -375,7 +374,7 @@ pub fn run() {
let _ = app_state.save(); let _ = app_state.save();
// 创建动态托盘菜单 // 创建动态托盘菜单
let menu = create_tray_menu(&app.handle(), &app_state)?; let menu = create_tray_menu(app.handle(), &app_state)?;
// 构建托盘 // 构建托盘
let mut tray_builder = TrayIconBuilder::with_id("main") let mut tray_builder = TrayIconBuilder::with_id("main")
@@ -460,20 +459,17 @@ pub fn run() {
app.run(|app_handle, event| { app.run(|app_handle, event| {
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
// macOS 在 Dock 图标被点击并重新激活应用时会触发 Reopen 事件,这里手动恢复主窗口 // macOS 在 Dock 图标被点击并重新激活应用时会触发 Reopen 事件,这里手动恢复主窗口
match event { if let RunEvent::Reopen { .. } = event {
RunEvent::Reopen { .. } => { if let Some(window) = app_handle.get_webview_window("main") {
if let Some(window) = app_handle.get_webview_window("main") { #[cfg(target_os = "windows")]
#[cfg(target_os = "windows")] {
{ let _ = window.set_skip_taskbar(false);
let _ = window.set_skip_taskbar(false);
}
let _ = window.unminimize();
let _ = window.show();
let _ = window.set_focus();
apply_tray_policy(app_handle, true);
} }
let _ = window.unminimize();
let _ = window.show();
let _ = window.set_focus();
apply_tray_policy(app_handle, true);
} }
_ => {}
} }
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]

View File

@@ -363,19 +363,13 @@ pub fn migrate_copies_into_config(config: &mut MultiAppConfig) -> Result<bool, S
} }
for (_, ap, cp, _) in codex_items.into_iter() { for (_, ap, cp, _) in codex_items.into_iter() {
if let Some(ap) = ap { if let Some(ap) = ap {
match archive_file(ts, "codex", &ap) { if let Ok(Some(_)) = archive_file(ts, "codex", &ap) {
Ok(Some(_)) => { let _ = delete_file(&ap);
let _ = delete_file(&ap);
}
_ => {}
} }
} }
if let Some(cp) = cp { if let Some(cp) = cp {
match archive_file(ts, "codex", &cp) { if let Ok(Some(_)) = archive_file(ts, "codex", &cp) {
Ok(Some(_)) => { let _ = delete_file(&cp);
let _ = delete_file(&cp);
}
_ => {}
} }
} }
} }

View File

@@ -45,21 +45,12 @@ impl Provider {
} }
/// 供应商管理器 /// 供应商管理器
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ProviderManager { pub struct ProviderManager {
pub providers: HashMap<String, Provider>, pub providers: HashMap<String, Provider>,
pub current: String, pub current: String,
} }
impl Default for ProviderManager {
fn default() -> Self {
Self {
providers: HashMap::new(),
current: String::new(),
}
}
}
/// 供应商元数据 /// 供应商元数据
#[derive(Debug, Clone, Serialize, Deserialize, Default)] #[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct ProviderMeta { pub struct ProviderMeta {

View File

@@ -2,7 +2,10 @@ import React, { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { X, Save, AlertCircle, ChevronDown, ChevronUp } from "lucide-react"; import { X, Save, AlertCircle, ChevronDown, ChevronUp } from "lucide-react";
import { McpServer, McpServerSpec } from "../../types"; import { McpServer, McpServerSpec } from "../../types";
import { mcpPresets, getMcpPresetWithDescription } from "../../config/mcpPresets"; import {
mcpPresets,
getMcpPresetWithDescription,
} from "../../config/mcpPresets";
import { buttonStyles, inputStyles } from "../../lib/styles"; import { buttonStyles, inputStyles } from "../../lib/styles";
import McpWizardModal from "./McpWizardModal"; import McpWizardModal from "./McpWizardModal";
import { import {

View File

@@ -210,7 +210,8 @@ const McpPanel: React.FC<McpPanelProps> = ({ onClose, onNotify, appType }) => {
{/* Info Section */} {/* Info Section */}
<div className="flex-shrink-0 px-6 pt-4 pb-2"> <div className="flex-shrink-0 px-6 pt-4 pb-2">
<div className="text-sm text-gray-500 dark:text-gray-400"> <div className="text-sm text-gray-500 dark:text-gray-400">
{t("mcp.serverCount", { count: Object.keys(servers).length })} · {t("mcp.enabledCount", { count: enabledCount })} {t("mcp.serverCount", { count: Object.keys(servers).length })} ·{" "}
{t("mcp.enabledCount", { count: enabledCount })}
</div> </div>
</div> </div>

View File

@@ -375,7 +375,7 @@
"name": "@modelcontextprotocol/server-memory", "name": "@modelcontextprotocol/server-memory",
"description": "知识图谱记忆系统,支持存储实体、关系和观察,让 AI 记住对话中的重要信息" "description": "知识图谱记忆系统,支持存储实体、关系和观察,让 AI 记住对话中的重要信息"
}, },
"sequentialThinking": { "sequential-thinking": {
"name": "@modelcontextprotocol/server-sequential-thinking", "name": "@modelcontextprotocol/server-sequential-thinking",
"description": "顺序思考工具,帮助 AI 将复杂问题分解为多个步骤,逐步深入思考" "description": "顺序思考工具,帮助 AI 将复杂问题分解为多个步骤,逐步深入思考"
}, },