refactor(backend): phase 2 - split commands.rs by domain (100%)
Split monolithic commands.rs (1525 lines) into 7 domain-focused modules
to improve maintainability and readability while preserving the external API.
## Changes
### Module Structure
Created `commands/` directory with domain-based organization:
- **provider.rs** (946 lines, 15 commands)
- Provider CRUD operations (get, add, update, delete, switch)
- Usage query integration
- Endpoint speed testing and custom endpoint management
- Sort order management
- Largest file but highly cohesive (all provider-related)
- **mcp.rs** (235 lines, 13 commands)
- Claude MCP management (~/.claude.json)
- SSOT MCP config management (config.json)
- Sync operations (Claude ↔ Codex)
- Import/export functionality
- **config.rs** (153 lines, 8 commands)
- Config path queries (Claude/Codex)
- Directory operations (open, pick)
- Config status checks
- Parameter compatibility layer (app_type/app/appType)
- **settings.rs** (40 lines, 5 commands)
- App settings management
- App restart functionality
- app_config_dir override (Store integration)
- **plugin.rs** (36 lines, 4 commands)
- Claude plugin management (~/.claude/config.json)
- Plugin status and config operations
- **misc.rs** (45 lines, 3 commands)
- External link handling
- Update checks
- Portable mode detection
- **mod.rs** (15 lines)
- Module exports via `pub use`
- Preserves flat API structure
### API Preservation
- Used `pub use` pattern to maintain external API
- All commands still accessible as `commands::function_name`
- Zero breaking changes for frontend code
- lib.rs invoke_handler unchanged (48 commands registered)
## Statistics
- Files: 1 → 7 (modular organization)
- Lines: 1525 → 1470 (net -55 lines, -3.6%)
- Commands: 48 → 48 (all preserved)
- Average file size: 210 lines (excluding provider.rs)
- Compilation: ✅ Success (6.92s, 0 warnings)
- Tests: ✅ 4/4 passed
## Benefits
- **Maintainability**: Easier to locate and modify domain-specific code
- **Readability**: Smaller files (~200 lines) vs monolithic 1500+ lines
- **Testability**: Can unit test individual modules in isolation
- **Scalability**: Clear pattern for adding new command groups
- **Zero Risk**: No API changes, all tests passing
## Design Decisions
1. **Domain-based split**: Organized by business domain (provider, mcp, config)
rather than technical layers (crud, query, sync)
2. **Preserved provider.rs size**: Kept at 946 lines to maintain high cohesion
(all provider-related operations together). Can be further split in Phase 2.1
if needed.
3. **Parameter compatibility**: Retained multiple parameter names (app_type, app,
appType) for backward compatibility with different frontend call styles
## Phase 2 Status: ✅ 100% Complete
Ready for Phase 3: Adding integration tests.
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 22:18:05 +08:00
|
|
|
|
#![allow(non_snake_case)]
|
|
|
|
|
|
|
|
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
|
|
|
|
use serde::Serialize;
|
|
|
|
|
|
use tauri::State;
|
|
|
|
|
|
|
|
|
|
|
|
use crate::app_config::AppType;
|
|
|
|
|
|
use crate::claude_mcp;
|
refactor(backend): extract MCP service layer with snapshot isolation
Extract all MCP business logic from command layer into `services/mcp.rs`,
implementing snapshot isolation pattern to optimize lock granularity after
RwLock migration in Phase 5.
## Key Changes
### Service Layer (`services/mcp.rs`)
- Add `McpService` with 7 methods: `get_servers`, `upsert_server`,
`delete_server`, `set_enabled`, `sync_enabled`, `import_from_claude`,
`import_from_codex`
- Implement snapshot isolation: acquire write lock only for in-memory
modifications, clone config snapshot, release lock, then perform file I/O
with snapshot
- Use conditional cloning: only clone config when sync is actually needed
(e.g., when `enabled` flag is true or `sync_other_side` is requested)
### Command Layer (`commands/mcp.rs`)
- Reduce to thin wrappers: parse parameters and delegate to `McpService`
- Remove all `*_internal` and `*_test_hook` functions (-94 lines)
- Each command now 5-10 lines (parameter parsing + service call + error mapping)
### Core Logic Refactoring (`mcp.rs`)
- Rename `set_enabled_and_sync_for` → `set_enabled_flag_for`
- Remove file sync logic from low-level function, move sync responsibility
to service layer for better separation of concerns
### Test Adaptation (`tests/mcp_commands.rs`)
- Replace test hooks with direct `McpService` calls
- All 5 MCP integration tests pass
### Additional Fixes
- Add `Default` impl for `AppState` (clippy suggestion)
- Remove unnecessary auto-deref in `commands/provider.rs` and `lib.rs`
- Update Phase 4/5 progress in `BACKEND_REFACTOR_PLAN.md`
## Performance Impact
**Before**: Write lock held during file I/O (~10ms), blocking all readers
**After**: Write lock held only for memory ops (~100μs), file I/O lock-free
Estimated throughput improvement: ~2x in high-concurrency read scenarios
## Testing
- ✅ All tests pass: 5 MCP commands + 7 provider service tests
- ✅ Zero clippy warnings with `-D warnings`
- ✅ No behavioral changes, maintains original save semantics
Part of Phase 4 (Service Layer Abstraction) of backend refactoring roadmap.
2025-10-28 14:59:28 +08:00
|
|
|
|
use crate::services::McpService;
|
refactor(backend): phase 2 - split commands.rs by domain (100%)
Split monolithic commands.rs (1525 lines) into 7 domain-focused modules
to improve maintainability and readability while preserving the external API.
## Changes
### Module Structure
Created `commands/` directory with domain-based organization:
- **provider.rs** (946 lines, 15 commands)
- Provider CRUD operations (get, add, update, delete, switch)
- Usage query integration
- Endpoint speed testing and custom endpoint management
- Sort order management
- Largest file but highly cohesive (all provider-related)
- **mcp.rs** (235 lines, 13 commands)
- Claude MCP management (~/.claude.json)
- SSOT MCP config management (config.json)
- Sync operations (Claude ↔ Codex)
- Import/export functionality
- **config.rs** (153 lines, 8 commands)
- Config path queries (Claude/Codex)
- Directory operations (open, pick)
- Config status checks
- Parameter compatibility layer (app_type/app/appType)
- **settings.rs** (40 lines, 5 commands)
- App settings management
- App restart functionality
- app_config_dir override (Store integration)
- **plugin.rs** (36 lines, 4 commands)
- Claude plugin management (~/.claude/config.json)
- Plugin status and config operations
- **misc.rs** (45 lines, 3 commands)
- External link handling
- Update checks
- Portable mode detection
- **mod.rs** (15 lines)
- Module exports via `pub use`
- Preserves flat API structure
### API Preservation
- Used `pub use` pattern to maintain external API
- All commands still accessible as `commands::function_name`
- Zero breaking changes for frontend code
- lib.rs invoke_handler unchanged (48 commands registered)
## Statistics
- Files: 1 → 7 (modular organization)
- Lines: 1525 → 1470 (net -55 lines, -3.6%)
- Commands: 48 → 48 (all preserved)
- Average file size: 210 lines (excluding provider.rs)
- Compilation: ✅ Success (6.92s, 0 warnings)
- Tests: ✅ 4/4 passed
## Benefits
- **Maintainability**: Easier to locate and modify domain-specific code
- **Readability**: Smaller files (~200 lines) vs monolithic 1500+ lines
- **Testability**: Can unit test individual modules in isolation
- **Scalability**: Clear pattern for adding new command groups
- **Zero Risk**: No API changes, all tests passing
## Design Decisions
1. **Domain-based split**: Organized by business domain (provider, mcp, config)
rather than technical layers (crud, query, sync)
2. **Preserved provider.rs size**: Kept at 946 lines to maintain high cohesion
(all provider-related operations together). Can be further split in Phase 2.1
if needed.
3. **Parameter compatibility**: Retained multiple parameter names (app_type, app,
appType) for backward compatibility with different frontend call styles
## Phase 2 Status: ✅ 100% Complete
Ready for Phase 3: Adding integration tests.
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 22:18:05 +08:00
|
|
|
|
use crate::store::AppState;
|
|
|
|
|
|
|
|
|
|
|
|
/// 获取 Claude MCP 状态
|
|
|
|
|
|
#[tauri::command]
|
|
|
|
|
|
pub async fn get_claude_mcp_status() -> Result<claude_mcp::McpStatus, String> {
|
|
|
|
|
|
claude_mcp::get_mcp_status().map_err(|e| e.to_string())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 读取 mcp.json 文本内容
|
|
|
|
|
|
#[tauri::command]
|
|
|
|
|
|
pub async fn read_claude_mcp_config() -> Result<Option<String>, String> {
|
|
|
|
|
|
claude_mcp::read_mcp_json().map_err(|e| e.to_string())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 新增或更新一个 MCP 服务器条目
|
|
|
|
|
|
#[tauri::command]
|
|
|
|
|
|
pub async fn upsert_claude_mcp_server(id: String, spec: serde_json::Value) -> Result<bool, String> {
|
|
|
|
|
|
claude_mcp::upsert_mcp_server(&id, spec).map_err(|e| e.to_string())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 删除一个 MCP 服务器条目
|
|
|
|
|
|
#[tauri::command]
|
|
|
|
|
|
pub async fn delete_claude_mcp_server(id: String) -> Result<bool, String> {
|
|
|
|
|
|
claude_mcp::delete_mcp_server(&id).map_err(|e| e.to_string())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 校验命令是否在 PATH 中可用(不执行)
|
|
|
|
|
|
#[tauri::command]
|
|
|
|
|
|
pub async fn validate_mcp_command(cmd: String) -> Result<bool, String> {
|
|
|
|
|
|
claude_mcp::validate_command_in_path(&cmd).map_err(|e| e.to_string())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize)]
|
|
|
|
|
|
pub struct McpConfigResponse {
|
|
|
|
|
|
pub config_path: String,
|
|
|
|
|
|
pub servers: HashMap<String, serde_json::Value>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 获取 MCP 配置(来自 ~/.cc-switch/config.json)
|
2025-10-30 12:33:35 +08:00
|
|
|
|
use std::str::FromStr;
|
2025-10-30 11:35:14 +08:00
|
|
|
|
|
refactor(backend): phase 2 - split commands.rs by domain (100%)
Split monolithic commands.rs (1525 lines) into 7 domain-focused modules
to improve maintainability and readability while preserving the external API.
## Changes
### Module Structure
Created `commands/` directory with domain-based organization:
- **provider.rs** (946 lines, 15 commands)
- Provider CRUD operations (get, add, update, delete, switch)
- Usage query integration
- Endpoint speed testing and custom endpoint management
- Sort order management
- Largest file but highly cohesive (all provider-related)
- **mcp.rs** (235 lines, 13 commands)
- Claude MCP management (~/.claude.json)
- SSOT MCP config management (config.json)
- Sync operations (Claude ↔ Codex)
- Import/export functionality
- **config.rs** (153 lines, 8 commands)
- Config path queries (Claude/Codex)
- Directory operations (open, pick)
- Config status checks
- Parameter compatibility layer (app_type/app/appType)
- **settings.rs** (40 lines, 5 commands)
- App settings management
- App restart functionality
- app_config_dir override (Store integration)
- **plugin.rs** (36 lines, 4 commands)
- Claude plugin management (~/.claude/config.json)
- Plugin status and config operations
- **misc.rs** (45 lines, 3 commands)
- External link handling
- Update checks
- Portable mode detection
- **mod.rs** (15 lines)
- Module exports via `pub use`
- Preserves flat API structure
### API Preservation
- Used `pub use` pattern to maintain external API
- All commands still accessible as `commands::function_name`
- Zero breaking changes for frontend code
- lib.rs invoke_handler unchanged (48 commands registered)
## Statistics
- Files: 1 → 7 (modular organization)
- Lines: 1525 → 1470 (net -55 lines, -3.6%)
- Commands: 48 → 48 (all preserved)
- Average file size: 210 lines (excluding provider.rs)
- Compilation: ✅ Success (6.92s, 0 warnings)
- Tests: ✅ 4/4 passed
## Benefits
- **Maintainability**: Easier to locate and modify domain-specific code
- **Readability**: Smaller files (~200 lines) vs monolithic 1500+ lines
- **Testability**: Can unit test individual modules in isolation
- **Scalability**: Clear pattern for adding new command groups
- **Zero Risk**: No API changes, all tests passing
## Design Decisions
1. **Domain-based split**: Organized by business domain (provider, mcp, config)
rather than technical layers (crud, query, sync)
2. **Preserved provider.rs size**: Kept at 946 lines to maintain high cohesion
(all provider-related operations together). Can be further split in Phase 2.1
if needed.
3. **Parameter compatibility**: Retained multiple parameter names (app_type, app,
appType) for backward compatibility with different frontend call styles
## Phase 2 Status: ✅ 100% Complete
Ready for Phase 3: Adding integration tests.
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 22:18:05 +08:00
|
|
|
|
#[tauri::command]
|
|
|
|
|
|
pub async fn get_mcp_config(
|
|
|
|
|
|
state: State<'_, AppState>,
|
2025-10-30 11:35:14 +08:00
|
|
|
|
app: String,
|
refactor(backend): phase 2 - split commands.rs by domain (100%)
Split monolithic commands.rs (1525 lines) into 7 domain-focused modules
to improve maintainability and readability while preserving the external API.
## Changes
### Module Structure
Created `commands/` directory with domain-based organization:
- **provider.rs** (946 lines, 15 commands)
- Provider CRUD operations (get, add, update, delete, switch)
- Usage query integration
- Endpoint speed testing and custom endpoint management
- Sort order management
- Largest file but highly cohesive (all provider-related)
- **mcp.rs** (235 lines, 13 commands)
- Claude MCP management (~/.claude.json)
- SSOT MCP config management (config.json)
- Sync operations (Claude ↔ Codex)
- Import/export functionality
- **config.rs** (153 lines, 8 commands)
- Config path queries (Claude/Codex)
- Directory operations (open, pick)
- Config status checks
- Parameter compatibility layer (app_type/app/appType)
- **settings.rs** (40 lines, 5 commands)
- App settings management
- App restart functionality
- app_config_dir override (Store integration)
- **plugin.rs** (36 lines, 4 commands)
- Claude plugin management (~/.claude/config.json)
- Plugin status and config operations
- **misc.rs** (45 lines, 3 commands)
- External link handling
- Update checks
- Portable mode detection
- **mod.rs** (15 lines)
- Module exports via `pub use`
- Preserves flat API structure
### API Preservation
- Used `pub use` pattern to maintain external API
- All commands still accessible as `commands::function_name`
- Zero breaking changes for frontend code
- lib.rs invoke_handler unchanged (48 commands registered)
## Statistics
- Files: 1 → 7 (modular organization)
- Lines: 1525 → 1470 (net -55 lines, -3.6%)
- Commands: 48 → 48 (all preserved)
- Average file size: 210 lines (excluding provider.rs)
- Compilation: ✅ Success (6.92s, 0 warnings)
- Tests: ✅ 4/4 passed
## Benefits
- **Maintainability**: Easier to locate and modify domain-specific code
- **Readability**: Smaller files (~200 lines) vs monolithic 1500+ lines
- **Testability**: Can unit test individual modules in isolation
- **Scalability**: Clear pattern for adding new command groups
- **Zero Risk**: No API changes, all tests passing
## Design Decisions
1. **Domain-based split**: Organized by business domain (provider, mcp, config)
rather than technical layers (crud, query, sync)
2. **Preserved provider.rs size**: Kept at 946 lines to maintain high cohesion
(all provider-related operations together). Can be further split in Phase 2.1
if needed.
3. **Parameter compatibility**: Retained multiple parameter names (app_type, app,
appType) for backward compatibility with different frontend call styles
## Phase 2 Status: ✅ 100% Complete
Ready for Phase 3: Adding integration tests.
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 22:18:05 +08:00
|
|
|
|
) -> Result<McpConfigResponse, String> {
|
|
|
|
|
|
let config_path = crate::config::get_app_config_path()
|
|
|
|
|
|
.to_string_lossy()
|
|
|
|
|
|
.to_string();
|
2025-10-30 12:33:35 +08:00
|
|
|
|
let app_ty = AppType::from_str(&app).map_err(|e| e.to_string())?;
|
refactor(backend): extract MCP service layer with snapshot isolation
Extract all MCP business logic from command layer into `services/mcp.rs`,
implementing snapshot isolation pattern to optimize lock granularity after
RwLock migration in Phase 5.
## Key Changes
### Service Layer (`services/mcp.rs`)
- Add `McpService` with 7 methods: `get_servers`, `upsert_server`,
`delete_server`, `set_enabled`, `sync_enabled`, `import_from_claude`,
`import_from_codex`
- Implement snapshot isolation: acquire write lock only for in-memory
modifications, clone config snapshot, release lock, then perform file I/O
with snapshot
- Use conditional cloning: only clone config when sync is actually needed
(e.g., when `enabled` flag is true or `sync_other_side` is requested)
### Command Layer (`commands/mcp.rs`)
- Reduce to thin wrappers: parse parameters and delegate to `McpService`
- Remove all `*_internal` and `*_test_hook` functions (-94 lines)
- Each command now 5-10 lines (parameter parsing + service call + error mapping)
### Core Logic Refactoring (`mcp.rs`)
- Rename `set_enabled_and_sync_for` → `set_enabled_flag_for`
- Remove file sync logic from low-level function, move sync responsibility
to service layer for better separation of concerns
### Test Adaptation (`tests/mcp_commands.rs`)
- Replace test hooks with direct `McpService` calls
- All 5 MCP integration tests pass
### Additional Fixes
- Add `Default` impl for `AppState` (clippy suggestion)
- Remove unnecessary auto-deref in `commands/provider.rs` and `lib.rs`
- Update Phase 4/5 progress in `BACKEND_REFACTOR_PLAN.md`
## Performance Impact
**Before**: Write lock held during file I/O (~10ms), blocking all readers
**After**: Write lock held only for memory ops (~100μs), file I/O lock-free
Estimated throughput improvement: ~2x in high-concurrency read scenarios
## Testing
- ✅ All tests pass: 5 MCP commands + 7 provider service tests
- ✅ Zero clippy warnings with `-D warnings`
- ✅ No behavioral changes, maintains original save semantics
Part of Phase 4 (Service Layer Abstraction) of backend refactoring roadmap.
2025-10-28 14:59:28 +08:00
|
|
|
|
let servers = McpService::get_servers(&state, app_ty).map_err(|e| e.to_string())?;
|
refactor(backend): phase 2 - split commands.rs by domain (100%)
Split monolithic commands.rs (1525 lines) into 7 domain-focused modules
to improve maintainability and readability while preserving the external API.
## Changes
### Module Structure
Created `commands/` directory with domain-based organization:
- **provider.rs** (946 lines, 15 commands)
- Provider CRUD operations (get, add, update, delete, switch)
- Usage query integration
- Endpoint speed testing and custom endpoint management
- Sort order management
- Largest file but highly cohesive (all provider-related)
- **mcp.rs** (235 lines, 13 commands)
- Claude MCP management (~/.claude.json)
- SSOT MCP config management (config.json)
- Sync operations (Claude ↔ Codex)
- Import/export functionality
- **config.rs** (153 lines, 8 commands)
- Config path queries (Claude/Codex)
- Directory operations (open, pick)
- Config status checks
- Parameter compatibility layer (app_type/app/appType)
- **settings.rs** (40 lines, 5 commands)
- App settings management
- App restart functionality
- app_config_dir override (Store integration)
- **plugin.rs** (36 lines, 4 commands)
- Claude plugin management (~/.claude/config.json)
- Plugin status and config operations
- **misc.rs** (45 lines, 3 commands)
- External link handling
- Update checks
- Portable mode detection
- **mod.rs** (15 lines)
- Module exports via `pub use`
- Preserves flat API structure
### API Preservation
- Used `pub use` pattern to maintain external API
- All commands still accessible as `commands::function_name`
- Zero breaking changes for frontend code
- lib.rs invoke_handler unchanged (48 commands registered)
## Statistics
- Files: 1 → 7 (modular organization)
- Lines: 1525 → 1470 (net -55 lines, -3.6%)
- Commands: 48 → 48 (all preserved)
- Average file size: 210 lines (excluding provider.rs)
- Compilation: ✅ Success (6.92s, 0 warnings)
- Tests: ✅ 4/4 passed
## Benefits
- **Maintainability**: Easier to locate and modify domain-specific code
- **Readability**: Smaller files (~200 lines) vs monolithic 1500+ lines
- **Testability**: Can unit test individual modules in isolation
- **Scalability**: Clear pattern for adding new command groups
- **Zero Risk**: No API changes, all tests passing
## Design Decisions
1. **Domain-based split**: Organized by business domain (provider, mcp, config)
rather than technical layers (crud, query, sync)
2. **Preserved provider.rs size**: Kept at 946 lines to maintain high cohesion
(all provider-related operations together). Can be further split in Phase 2.1
if needed.
3. **Parameter compatibility**: Retained multiple parameter names (app_type, app,
appType) for backward compatibility with different frontend call styles
## Phase 2 Status: ✅ 100% Complete
Ready for Phase 3: Adding integration tests.
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 22:18:05 +08:00
|
|
|
|
Ok(McpConfigResponse {
|
|
|
|
|
|
config_path,
|
|
|
|
|
|
servers,
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 在 config.json 中新增或更新一个 MCP 服务器定义
|
|
|
|
|
|
#[tauri::command]
|
|
|
|
|
|
pub async fn upsert_mcp_server_in_config(
|
|
|
|
|
|
state: State<'_, AppState>,
|
2025-10-30 11:35:14 +08:00
|
|
|
|
app: String,
|
refactor(backend): phase 2 - split commands.rs by domain (100%)
Split monolithic commands.rs (1525 lines) into 7 domain-focused modules
to improve maintainability and readability while preserving the external API.
## Changes
### Module Structure
Created `commands/` directory with domain-based organization:
- **provider.rs** (946 lines, 15 commands)
- Provider CRUD operations (get, add, update, delete, switch)
- Usage query integration
- Endpoint speed testing and custom endpoint management
- Sort order management
- Largest file but highly cohesive (all provider-related)
- **mcp.rs** (235 lines, 13 commands)
- Claude MCP management (~/.claude.json)
- SSOT MCP config management (config.json)
- Sync operations (Claude ↔ Codex)
- Import/export functionality
- **config.rs** (153 lines, 8 commands)
- Config path queries (Claude/Codex)
- Directory operations (open, pick)
- Config status checks
- Parameter compatibility layer (app_type/app/appType)
- **settings.rs** (40 lines, 5 commands)
- App settings management
- App restart functionality
- app_config_dir override (Store integration)
- **plugin.rs** (36 lines, 4 commands)
- Claude plugin management (~/.claude/config.json)
- Plugin status and config operations
- **misc.rs** (45 lines, 3 commands)
- External link handling
- Update checks
- Portable mode detection
- **mod.rs** (15 lines)
- Module exports via `pub use`
- Preserves flat API structure
### API Preservation
- Used `pub use` pattern to maintain external API
- All commands still accessible as `commands::function_name`
- Zero breaking changes for frontend code
- lib.rs invoke_handler unchanged (48 commands registered)
## Statistics
- Files: 1 → 7 (modular organization)
- Lines: 1525 → 1470 (net -55 lines, -3.6%)
- Commands: 48 → 48 (all preserved)
- Average file size: 210 lines (excluding provider.rs)
- Compilation: ✅ Success (6.92s, 0 warnings)
- Tests: ✅ 4/4 passed
## Benefits
- **Maintainability**: Easier to locate and modify domain-specific code
- **Readability**: Smaller files (~200 lines) vs monolithic 1500+ lines
- **Testability**: Can unit test individual modules in isolation
- **Scalability**: Clear pattern for adding new command groups
- **Zero Risk**: No API changes, all tests passing
## Design Decisions
1. **Domain-based split**: Organized by business domain (provider, mcp, config)
rather than technical layers (crud, query, sync)
2. **Preserved provider.rs size**: Kept at 946 lines to maintain high cohesion
(all provider-related operations together). Can be further split in Phase 2.1
if needed.
3. **Parameter compatibility**: Retained multiple parameter names (app_type, app,
appType) for backward compatibility with different frontend call styles
## Phase 2 Status: ✅ 100% Complete
Ready for Phase 3: Adding integration tests.
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 22:18:05 +08:00
|
|
|
|
id: String,
|
|
|
|
|
|
spec: serde_json::Value,
|
|
|
|
|
|
sync_other_side: Option<bool>,
|
|
|
|
|
|
) -> Result<bool, String> {
|
2025-10-30 12:33:35 +08:00
|
|
|
|
let app_ty = AppType::from_str(&app).map_err(|e| e.to_string())?;
|
refactor(backend): extract MCP service layer with snapshot isolation
Extract all MCP business logic from command layer into `services/mcp.rs`,
implementing snapshot isolation pattern to optimize lock granularity after
RwLock migration in Phase 5.
## Key Changes
### Service Layer (`services/mcp.rs`)
- Add `McpService` with 7 methods: `get_servers`, `upsert_server`,
`delete_server`, `set_enabled`, `sync_enabled`, `import_from_claude`,
`import_from_codex`
- Implement snapshot isolation: acquire write lock only for in-memory
modifications, clone config snapshot, release lock, then perform file I/O
with snapshot
- Use conditional cloning: only clone config when sync is actually needed
(e.g., when `enabled` flag is true or `sync_other_side` is requested)
### Command Layer (`commands/mcp.rs`)
- Reduce to thin wrappers: parse parameters and delegate to `McpService`
- Remove all `*_internal` and `*_test_hook` functions (-94 lines)
- Each command now 5-10 lines (parameter parsing + service call + error mapping)
### Core Logic Refactoring (`mcp.rs`)
- Rename `set_enabled_and_sync_for` → `set_enabled_flag_for`
- Remove file sync logic from low-level function, move sync responsibility
to service layer for better separation of concerns
### Test Adaptation (`tests/mcp_commands.rs`)
- Replace test hooks with direct `McpService` calls
- All 5 MCP integration tests pass
### Additional Fixes
- Add `Default` impl for `AppState` (clippy suggestion)
- Remove unnecessary auto-deref in `commands/provider.rs` and `lib.rs`
- Update Phase 4/5 progress in `BACKEND_REFACTOR_PLAN.md`
## Performance Impact
**Before**: Write lock held during file I/O (~10ms), blocking all readers
**After**: Write lock held only for memory ops (~100μs), file I/O lock-free
Estimated throughput improvement: ~2x in high-concurrency read scenarios
## Testing
- ✅ All tests pass: 5 MCP commands + 7 provider service tests
- ✅ Zero clippy warnings with `-D warnings`
- ✅ No behavioral changes, maintains original save semantics
Part of Phase 4 (Service Layer Abstraction) of backend refactoring roadmap.
2025-10-28 14:59:28 +08:00
|
|
|
|
McpService::upsert_server(&state, app_ty, &id, spec, sync_other_side.unwrap_or(false))
|
|
|
|
|
|
.map_err(|e| e.to_string())
|
refactor(backend): phase 2 - split commands.rs by domain (100%)
Split monolithic commands.rs (1525 lines) into 7 domain-focused modules
to improve maintainability and readability while preserving the external API.
## Changes
### Module Structure
Created `commands/` directory with domain-based organization:
- **provider.rs** (946 lines, 15 commands)
- Provider CRUD operations (get, add, update, delete, switch)
- Usage query integration
- Endpoint speed testing and custom endpoint management
- Sort order management
- Largest file but highly cohesive (all provider-related)
- **mcp.rs** (235 lines, 13 commands)
- Claude MCP management (~/.claude.json)
- SSOT MCP config management (config.json)
- Sync operations (Claude ↔ Codex)
- Import/export functionality
- **config.rs** (153 lines, 8 commands)
- Config path queries (Claude/Codex)
- Directory operations (open, pick)
- Config status checks
- Parameter compatibility layer (app_type/app/appType)
- **settings.rs** (40 lines, 5 commands)
- App settings management
- App restart functionality
- app_config_dir override (Store integration)
- **plugin.rs** (36 lines, 4 commands)
- Claude plugin management (~/.claude/config.json)
- Plugin status and config operations
- **misc.rs** (45 lines, 3 commands)
- External link handling
- Update checks
- Portable mode detection
- **mod.rs** (15 lines)
- Module exports via `pub use`
- Preserves flat API structure
### API Preservation
- Used `pub use` pattern to maintain external API
- All commands still accessible as `commands::function_name`
- Zero breaking changes for frontend code
- lib.rs invoke_handler unchanged (48 commands registered)
## Statistics
- Files: 1 → 7 (modular organization)
- Lines: 1525 → 1470 (net -55 lines, -3.6%)
- Commands: 48 → 48 (all preserved)
- Average file size: 210 lines (excluding provider.rs)
- Compilation: ✅ Success (6.92s, 0 warnings)
- Tests: ✅ 4/4 passed
## Benefits
- **Maintainability**: Easier to locate and modify domain-specific code
- **Readability**: Smaller files (~200 lines) vs monolithic 1500+ lines
- **Testability**: Can unit test individual modules in isolation
- **Scalability**: Clear pattern for adding new command groups
- **Zero Risk**: No API changes, all tests passing
## Design Decisions
1. **Domain-based split**: Organized by business domain (provider, mcp, config)
rather than technical layers (crud, query, sync)
2. **Preserved provider.rs size**: Kept at 946 lines to maintain high cohesion
(all provider-related operations together). Can be further split in Phase 2.1
if needed.
3. **Parameter compatibility**: Retained multiple parameter names (app_type, app,
appType) for backward compatibility with different frontend call styles
## Phase 2 Status: ✅ 100% Complete
Ready for Phase 3: Adding integration tests.
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 22:18:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 在 config.json 中删除一个 MCP 服务器定义
|
|
|
|
|
|
#[tauri::command]
|
|
|
|
|
|
pub async fn delete_mcp_server_in_config(
|
|
|
|
|
|
state: State<'_, AppState>,
|
2025-10-30 11:35:14 +08:00
|
|
|
|
app: String,
|
refactor(backend): phase 2 - split commands.rs by domain (100%)
Split monolithic commands.rs (1525 lines) into 7 domain-focused modules
to improve maintainability and readability while preserving the external API.
## Changes
### Module Structure
Created `commands/` directory with domain-based organization:
- **provider.rs** (946 lines, 15 commands)
- Provider CRUD operations (get, add, update, delete, switch)
- Usage query integration
- Endpoint speed testing and custom endpoint management
- Sort order management
- Largest file but highly cohesive (all provider-related)
- **mcp.rs** (235 lines, 13 commands)
- Claude MCP management (~/.claude.json)
- SSOT MCP config management (config.json)
- Sync operations (Claude ↔ Codex)
- Import/export functionality
- **config.rs** (153 lines, 8 commands)
- Config path queries (Claude/Codex)
- Directory operations (open, pick)
- Config status checks
- Parameter compatibility layer (app_type/app/appType)
- **settings.rs** (40 lines, 5 commands)
- App settings management
- App restart functionality
- app_config_dir override (Store integration)
- **plugin.rs** (36 lines, 4 commands)
- Claude plugin management (~/.claude/config.json)
- Plugin status and config operations
- **misc.rs** (45 lines, 3 commands)
- External link handling
- Update checks
- Portable mode detection
- **mod.rs** (15 lines)
- Module exports via `pub use`
- Preserves flat API structure
### API Preservation
- Used `pub use` pattern to maintain external API
- All commands still accessible as `commands::function_name`
- Zero breaking changes for frontend code
- lib.rs invoke_handler unchanged (48 commands registered)
## Statistics
- Files: 1 → 7 (modular organization)
- Lines: 1525 → 1470 (net -55 lines, -3.6%)
- Commands: 48 → 48 (all preserved)
- Average file size: 210 lines (excluding provider.rs)
- Compilation: ✅ Success (6.92s, 0 warnings)
- Tests: ✅ 4/4 passed
## Benefits
- **Maintainability**: Easier to locate and modify domain-specific code
- **Readability**: Smaller files (~200 lines) vs monolithic 1500+ lines
- **Testability**: Can unit test individual modules in isolation
- **Scalability**: Clear pattern for adding new command groups
- **Zero Risk**: No API changes, all tests passing
## Design Decisions
1. **Domain-based split**: Organized by business domain (provider, mcp, config)
rather than technical layers (crud, query, sync)
2. **Preserved provider.rs size**: Kept at 946 lines to maintain high cohesion
(all provider-related operations together). Can be further split in Phase 2.1
if needed.
3. **Parameter compatibility**: Retained multiple parameter names (app_type, app,
appType) for backward compatibility with different frontend call styles
## Phase 2 Status: ✅ 100% Complete
Ready for Phase 3: Adding integration tests.
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 22:18:05 +08:00
|
|
|
|
id: String,
|
|
|
|
|
|
) -> Result<bool, String> {
|
2025-10-30 12:33:35 +08:00
|
|
|
|
let app_ty = AppType::from_str(&app).map_err(|e| e.to_string())?;
|
refactor(backend): extract MCP service layer with snapshot isolation
Extract all MCP business logic from command layer into `services/mcp.rs`,
implementing snapshot isolation pattern to optimize lock granularity after
RwLock migration in Phase 5.
## Key Changes
### Service Layer (`services/mcp.rs`)
- Add `McpService` with 7 methods: `get_servers`, `upsert_server`,
`delete_server`, `set_enabled`, `sync_enabled`, `import_from_claude`,
`import_from_codex`
- Implement snapshot isolation: acquire write lock only for in-memory
modifications, clone config snapshot, release lock, then perform file I/O
with snapshot
- Use conditional cloning: only clone config when sync is actually needed
(e.g., when `enabled` flag is true or `sync_other_side` is requested)
### Command Layer (`commands/mcp.rs`)
- Reduce to thin wrappers: parse parameters and delegate to `McpService`
- Remove all `*_internal` and `*_test_hook` functions (-94 lines)
- Each command now 5-10 lines (parameter parsing + service call + error mapping)
### Core Logic Refactoring (`mcp.rs`)
- Rename `set_enabled_and_sync_for` → `set_enabled_flag_for`
- Remove file sync logic from low-level function, move sync responsibility
to service layer for better separation of concerns
### Test Adaptation (`tests/mcp_commands.rs`)
- Replace test hooks with direct `McpService` calls
- All 5 MCP integration tests pass
### Additional Fixes
- Add `Default` impl for `AppState` (clippy suggestion)
- Remove unnecessary auto-deref in `commands/provider.rs` and `lib.rs`
- Update Phase 4/5 progress in `BACKEND_REFACTOR_PLAN.md`
## Performance Impact
**Before**: Write lock held during file I/O (~10ms), blocking all readers
**After**: Write lock held only for memory ops (~100μs), file I/O lock-free
Estimated throughput improvement: ~2x in high-concurrency read scenarios
## Testing
- ✅ All tests pass: 5 MCP commands + 7 provider service tests
- ✅ Zero clippy warnings with `-D warnings`
- ✅ No behavioral changes, maintains original save semantics
Part of Phase 4 (Service Layer Abstraction) of backend refactoring roadmap.
2025-10-28 14:59:28 +08:00
|
|
|
|
McpService::delete_server(&state, app_ty, &id).map_err(|e| e.to_string())
|
refactor(backend): phase 2 - split commands.rs by domain (100%)
Split monolithic commands.rs (1525 lines) into 7 domain-focused modules
to improve maintainability and readability while preserving the external API.
## Changes
### Module Structure
Created `commands/` directory with domain-based organization:
- **provider.rs** (946 lines, 15 commands)
- Provider CRUD operations (get, add, update, delete, switch)
- Usage query integration
- Endpoint speed testing and custom endpoint management
- Sort order management
- Largest file but highly cohesive (all provider-related)
- **mcp.rs** (235 lines, 13 commands)
- Claude MCP management (~/.claude.json)
- SSOT MCP config management (config.json)
- Sync operations (Claude ↔ Codex)
- Import/export functionality
- **config.rs** (153 lines, 8 commands)
- Config path queries (Claude/Codex)
- Directory operations (open, pick)
- Config status checks
- Parameter compatibility layer (app_type/app/appType)
- **settings.rs** (40 lines, 5 commands)
- App settings management
- App restart functionality
- app_config_dir override (Store integration)
- **plugin.rs** (36 lines, 4 commands)
- Claude plugin management (~/.claude/config.json)
- Plugin status and config operations
- **misc.rs** (45 lines, 3 commands)
- External link handling
- Update checks
- Portable mode detection
- **mod.rs** (15 lines)
- Module exports via `pub use`
- Preserves flat API structure
### API Preservation
- Used `pub use` pattern to maintain external API
- All commands still accessible as `commands::function_name`
- Zero breaking changes for frontend code
- lib.rs invoke_handler unchanged (48 commands registered)
## Statistics
- Files: 1 → 7 (modular organization)
- Lines: 1525 → 1470 (net -55 lines, -3.6%)
- Commands: 48 → 48 (all preserved)
- Average file size: 210 lines (excluding provider.rs)
- Compilation: ✅ Success (6.92s, 0 warnings)
- Tests: ✅ 4/4 passed
## Benefits
- **Maintainability**: Easier to locate and modify domain-specific code
- **Readability**: Smaller files (~200 lines) vs monolithic 1500+ lines
- **Testability**: Can unit test individual modules in isolation
- **Scalability**: Clear pattern for adding new command groups
- **Zero Risk**: No API changes, all tests passing
## Design Decisions
1. **Domain-based split**: Organized by business domain (provider, mcp, config)
rather than technical layers (crud, query, sync)
2. **Preserved provider.rs size**: Kept at 946 lines to maintain high cohesion
(all provider-related operations together). Can be further split in Phase 2.1
if needed.
3. **Parameter compatibility**: Retained multiple parameter names (app_type, app,
appType) for backward compatibility with different frontend call styles
## Phase 2 Status: ✅ 100% Complete
Ready for Phase 3: Adding integration tests.
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 22:18:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 设置启用状态并同步到客户端配置
|
|
|
|
|
|
#[tauri::command]
|
|
|
|
|
|
pub async fn set_mcp_enabled(
|
|
|
|
|
|
state: State<'_, AppState>,
|
2025-10-30 11:35:14 +08:00
|
|
|
|
app: String,
|
refactor(backend): phase 2 - split commands.rs by domain (100%)
Split monolithic commands.rs (1525 lines) into 7 domain-focused modules
to improve maintainability and readability while preserving the external API.
## Changes
### Module Structure
Created `commands/` directory with domain-based organization:
- **provider.rs** (946 lines, 15 commands)
- Provider CRUD operations (get, add, update, delete, switch)
- Usage query integration
- Endpoint speed testing and custom endpoint management
- Sort order management
- Largest file but highly cohesive (all provider-related)
- **mcp.rs** (235 lines, 13 commands)
- Claude MCP management (~/.claude.json)
- SSOT MCP config management (config.json)
- Sync operations (Claude ↔ Codex)
- Import/export functionality
- **config.rs** (153 lines, 8 commands)
- Config path queries (Claude/Codex)
- Directory operations (open, pick)
- Config status checks
- Parameter compatibility layer (app_type/app/appType)
- **settings.rs** (40 lines, 5 commands)
- App settings management
- App restart functionality
- app_config_dir override (Store integration)
- **plugin.rs** (36 lines, 4 commands)
- Claude plugin management (~/.claude/config.json)
- Plugin status and config operations
- **misc.rs** (45 lines, 3 commands)
- External link handling
- Update checks
- Portable mode detection
- **mod.rs** (15 lines)
- Module exports via `pub use`
- Preserves flat API structure
### API Preservation
- Used `pub use` pattern to maintain external API
- All commands still accessible as `commands::function_name`
- Zero breaking changes for frontend code
- lib.rs invoke_handler unchanged (48 commands registered)
## Statistics
- Files: 1 → 7 (modular organization)
- Lines: 1525 → 1470 (net -55 lines, -3.6%)
- Commands: 48 → 48 (all preserved)
- Average file size: 210 lines (excluding provider.rs)
- Compilation: ✅ Success (6.92s, 0 warnings)
- Tests: ✅ 4/4 passed
## Benefits
- **Maintainability**: Easier to locate and modify domain-specific code
- **Readability**: Smaller files (~200 lines) vs monolithic 1500+ lines
- **Testability**: Can unit test individual modules in isolation
- **Scalability**: Clear pattern for adding new command groups
- **Zero Risk**: No API changes, all tests passing
## Design Decisions
1. **Domain-based split**: Organized by business domain (provider, mcp, config)
rather than technical layers (crud, query, sync)
2. **Preserved provider.rs size**: Kept at 946 lines to maintain high cohesion
(all provider-related operations together). Can be further split in Phase 2.1
if needed.
3. **Parameter compatibility**: Retained multiple parameter names (app_type, app,
appType) for backward compatibility with different frontend call styles
## Phase 2 Status: ✅ 100% Complete
Ready for Phase 3: Adding integration tests.
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 22:18:05 +08:00
|
|
|
|
id: String,
|
|
|
|
|
|
enabled: bool,
|
|
|
|
|
|
) -> Result<bool, String> {
|
2025-10-30 12:33:35 +08:00
|
|
|
|
let app_ty = AppType::from_str(&app).map_err(|e| e.to_string())?;
|
refactor(backend): extract MCP service layer with snapshot isolation
Extract all MCP business logic from command layer into `services/mcp.rs`,
implementing snapshot isolation pattern to optimize lock granularity after
RwLock migration in Phase 5.
## Key Changes
### Service Layer (`services/mcp.rs`)
- Add `McpService` with 7 methods: `get_servers`, `upsert_server`,
`delete_server`, `set_enabled`, `sync_enabled`, `import_from_claude`,
`import_from_codex`
- Implement snapshot isolation: acquire write lock only for in-memory
modifications, clone config snapshot, release lock, then perform file I/O
with snapshot
- Use conditional cloning: only clone config when sync is actually needed
(e.g., when `enabled` flag is true or `sync_other_side` is requested)
### Command Layer (`commands/mcp.rs`)
- Reduce to thin wrappers: parse parameters and delegate to `McpService`
- Remove all `*_internal` and `*_test_hook` functions (-94 lines)
- Each command now 5-10 lines (parameter parsing + service call + error mapping)
### Core Logic Refactoring (`mcp.rs`)
- Rename `set_enabled_and_sync_for` → `set_enabled_flag_for`
- Remove file sync logic from low-level function, move sync responsibility
to service layer for better separation of concerns
### Test Adaptation (`tests/mcp_commands.rs`)
- Replace test hooks with direct `McpService` calls
- All 5 MCP integration tests pass
### Additional Fixes
- Add `Default` impl for `AppState` (clippy suggestion)
- Remove unnecessary auto-deref in `commands/provider.rs` and `lib.rs`
- Update Phase 4/5 progress in `BACKEND_REFACTOR_PLAN.md`
## Performance Impact
**Before**: Write lock held during file I/O (~10ms), blocking all readers
**After**: Write lock held only for memory ops (~100μs), file I/O lock-free
Estimated throughput improvement: ~2x in high-concurrency read scenarios
## Testing
- ✅ All tests pass: 5 MCP commands + 7 provider service tests
- ✅ Zero clippy warnings with `-D warnings`
- ✅ No behavioral changes, maintains original save semantics
Part of Phase 4 (Service Layer Abstraction) of backend refactoring roadmap.
2025-10-28 14:59:28 +08:00
|
|
|
|
McpService::set_enabled(&state, app_ty, &id, enabled).map_err(|e| e.to_string())
|
refactor(backend): phase 2 - split commands.rs by domain (100%)
Split monolithic commands.rs (1525 lines) into 7 domain-focused modules
to improve maintainability and readability while preserving the external API.
## Changes
### Module Structure
Created `commands/` directory with domain-based organization:
- **provider.rs** (946 lines, 15 commands)
- Provider CRUD operations (get, add, update, delete, switch)
- Usage query integration
- Endpoint speed testing and custom endpoint management
- Sort order management
- Largest file but highly cohesive (all provider-related)
- **mcp.rs** (235 lines, 13 commands)
- Claude MCP management (~/.claude.json)
- SSOT MCP config management (config.json)
- Sync operations (Claude ↔ Codex)
- Import/export functionality
- **config.rs** (153 lines, 8 commands)
- Config path queries (Claude/Codex)
- Directory operations (open, pick)
- Config status checks
- Parameter compatibility layer (app_type/app/appType)
- **settings.rs** (40 lines, 5 commands)
- App settings management
- App restart functionality
- app_config_dir override (Store integration)
- **plugin.rs** (36 lines, 4 commands)
- Claude plugin management (~/.claude/config.json)
- Plugin status and config operations
- **misc.rs** (45 lines, 3 commands)
- External link handling
- Update checks
- Portable mode detection
- **mod.rs** (15 lines)
- Module exports via `pub use`
- Preserves flat API structure
### API Preservation
- Used `pub use` pattern to maintain external API
- All commands still accessible as `commands::function_name`
- Zero breaking changes for frontend code
- lib.rs invoke_handler unchanged (48 commands registered)
## Statistics
- Files: 1 → 7 (modular organization)
- Lines: 1525 → 1470 (net -55 lines, -3.6%)
- Commands: 48 → 48 (all preserved)
- Average file size: 210 lines (excluding provider.rs)
- Compilation: ✅ Success (6.92s, 0 warnings)
- Tests: ✅ 4/4 passed
## Benefits
- **Maintainability**: Easier to locate and modify domain-specific code
- **Readability**: Smaller files (~200 lines) vs monolithic 1500+ lines
- **Testability**: Can unit test individual modules in isolation
- **Scalability**: Clear pattern for adding new command groups
- **Zero Risk**: No API changes, all tests passing
## Design Decisions
1. **Domain-based split**: Organized by business domain (provider, mcp, config)
rather than technical layers (crud, query, sync)
2. **Preserved provider.rs size**: Kept at 946 lines to maintain high cohesion
(all provider-related operations together). Can be further split in Phase 2.1
if needed.
3. **Parameter compatibility**: Retained multiple parameter names (app_type, app,
appType) for backward compatibility with different frontend call styles
## Phase 2 Status: ✅ 100% Complete
Ready for Phase 3: Adding integration tests.
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 22:18:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 手动同步:将启用的 MCP 投影到 ~/.claude.json
|
|
|
|
|
|
#[tauri::command]
|
|
|
|
|
|
pub async fn sync_enabled_mcp_to_claude(state: State<'_, AppState>) -> Result<bool, String> {
|
refactor(backend): extract MCP service layer with snapshot isolation
Extract all MCP business logic from command layer into `services/mcp.rs`,
implementing snapshot isolation pattern to optimize lock granularity after
RwLock migration in Phase 5.
## Key Changes
### Service Layer (`services/mcp.rs`)
- Add `McpService` with 7 methods: `get_servers`, `upsert_server`,
`delete_server`, `set_enabled`, `sync_enabled`, `import_from_claude`,
`import_from_codex`
- Implement snapshot isolation: acquire write lock only for in-memory
modifications, clone config snapshot, release lock, then perform file I/O
with snapshot
- Use conditional cloning: only clone config when sync is actually needed
(e.g., when `enabled` flag is true or `sync_other_side` is requested)
### Command Layer (`commands/mcp.rs`)
- Reduce to thin wrappers: parse parameters and delegate to `McpService`
- Remove all `*_internal` and `*_test_hook` functions (-94 lines)
- Each command now 5-10 lines (parameter parsing + service call + error mapping)
### Core Logic Refactoring (`mcp.rs`)
- Rename `set_enabled_and_sync_for` → `set_enabled_flag_for`
- Remove file sync logic from low-level function, move sync responsibility
to service layer for better separation of concerns
### Test Adaptation (`tests/mcp_commands.rs`)
- Replace test hooks with direct `McpService` calls
- All 5 MCP integration tests pass
### Additional Fixes
- Add `Default` impl for `AppState` (clippy suggestion)
- Remove unnecessary auto-deref in `commands/provider.rs` and `lib.rs`
- Update Phase 4/5 progress in `BACKEND_REFACTOR_PLAN.md`
## Performance Impact
**Before**: Write lock held during file I/O (~10ms), blocking all readers
**After**: Write lock held only for memory ops (~100μs), file I/O lock-free
Estimated throughput improvement: ~2x in high-concurrency read scenarios
## Testing
- ✅ All tests pass: 5 MCP commands + 7 provider service tests
- ✅ Zero clippy warnings with `-D warnings`
- ✅ No behavioral changes, maintains original save semantics
Part of Phase 4 (Service Layer Abstraction) of backend refactoring roadmap.
2025-10-28 14:59:28 +08:00
|
|
|
|
McpService::sync_enabled(&state, AppType::Claude)
|
|
|
|
|
|
.map(|_| true)
|
|
|
|
|
|
.map_err(|e| e.to_string())
|
refactor(backend): phase 2 - split commands.rs by domain (100%)
Split monolithic commands.rs (1525 lines) into 7 domain-focused modules
to improve maintainability and readability while preserving the external API.
## Changes
### Module Structure
Created `commands/` directory with domain-based organization:
- **provider.rs** (946 lines, 15 commands)
- Provider CRUD operations (get, add, update, delete, switch)
- Usage query integration
- Endpoint speed testing and custom endpoint management
- Sort order management
- Largest file but highly cohesive (all provider-related)
- **mcp.rs** (235 lines, 13 commands)
- Claude MCP management (~/.claude.json)
- SSOT MCP config management (config.json)
- Sync operations (Claude ↔ Codex)
- Import/export functionality
- **config.rs** (153 lines, 8 commands)
- Config path queries (Claude/Codex)
- Directory operations (open, pick)
- Config status checks
- Parameter compatibility layer (app_type/app/appType)
- **settings.rs** (40 lines, 5 commands)
- App settings management
- App restart functionality
- app_config_dir override (Store integration)
- **plugin.rs** (36 lines, 4 commands)
- Claude plugin management (~/.claude/config.json)
- Plugin status and config operations
- **misc.rs** (45 lines, 3 commands)
- External link handling
- Update checks
- Portable mode detection
- **mod.rs** (15 lines)
- Module exports via `pub use`
- Preserves flat API structure
### API Preservation
- Used `pub use` pattern to maintain external API
- All commands still accessible as `commands::function_name`
- Zero breaking changes for frontend code
- lib.rs invoke_handler unchanged (48 commands registered)
## Statistics
- Files: 1 → 7 (modular organization)
- Lines: 1525 → 1470 (net -55 lines, -3.6%)
- Commands: 48 → 48 (all preserved)
- Average file size: 210 lines (excluding provider.rs)
- Compilation: ✅ Success (6.92s, 0 warnings)
- Tests: ✅ 4/4 passed
## Benefits
- **Maintainability**: Easier to locate and modify domain-specific code
- **Readability**: Smaller files (~200 lines) vs monolithic 1500+ lines
- **Testability**: Can unit test individual modules in isolation
- **Scalability**: Clear pattern for adding new command groups
- **Zero Risk**: No API changes, all tests passing
## Design Decisions
1. **Domain-based split**: Organized by business domain (provider, mcp, config)
rather than technical layers (crud, query, sync)
2. **Preserved provider.rs size**: Kept at 946 lines to maintain high cohesion
(all provider-related operations together). Can be further split in Phase 2.1
if needed.
3. **Parameter compatibility**: Retained multiple parameter names (app_type, app,
appType) for backward compatibility with different frontend call styles
## Phase 2 Status: ✅ 100% Complete
Ready for Phase 3: Adding integration tests.
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 22:18:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 手动同步:将启用的 MCP 投影到 ~/.codex/config.toml
|
|
|
|
|
|
#[tauri::command]
|
|
|
|
|
|
pub async fn sync_enabled_mcp_to_codex(state: State<'_, AppState>) -> Result<bool, String> {
|
refactor(backend): extract MCP service layer with snapshot isolation
Extract all MCP business logic from command layer into `services/mcp.rs`,
implementing snapshot isolation pattern to optimize lock granularity after
RwLock migration in Phase 5.
## Key Changes
### Service Layer (`services/mcp.rs`)
- Add `McpService` with 7 methods: `get_servers`, `upsert_server`,
`delete_server`, `set_enabled`, `sync_enabled`, `import_from_claude`,
`import_from_codex`
- Implement snapshot isolation: acquire write lock only for in-memory
modifications, clone config snapshot, release lock, then perform file I/O
with snapshot
- Use conditional cloning: only clone config when sync is actually needed
(e.g., when `enabled` flag is true or `sync_other_side` is requested)
### Command Layer (`commands/mcp.rs`)
- Reduce to thin wrappers: parse parameters and delegate to `McpService`
- Remove all `*_internal` and `*_test_hook` functions (-94 lines)
- Each command now 5-10 lines (parameter parsing + service call + error mapping)
### Core Logic Refactoring (`mcp.rs`)
- Rename `set_enabled_and_sync_for` → `set_enabled_flag_for`
- Remove file sync logic from low-level function, move sync responsibility
to service layer for better separation of concerns
### Test Adaptation (`tests/mcp_commands.rs`)
- Replace test hooks with direct `McpService` calls
- All 5 MCP integration tests pass
### Additional Fixes
- Add `Default` impl for `AppState` (clippy suggestion)
- Remove unnecessary auto-deref in `commands/provider.rs` and `lib.rs`
- Update Phase 4/5 progress in `BACKEND_REFACTOR_PLAN.md`
## Performance Impact
**Before**: Write lock held during file I/O (~10ms), blocking all readers
**After**: Write lock held only for memory ops (~100μs), file I/O lock-free
Estimated throughput improvement: ~2x in high-concurrency read scenarios
## Testing
- ✅ All tests pass: 5 MCP commands + 7 provider service tests
- ✅ Zero clippy warnings with `-D warnings`
- ✅ No behavioral changes, maintains original save semantics
Part of Phase 4 (Service Layer Abstraction) of backend refactoring roadmap.
2025-10-28 14:59:28 +08:00
|
|
|
|
McpService::sync_enabled(&state, AppType::Codex)
|
|
|
|
|
|
.map(|_| true)
|
|
|
|
|
|
.map_err(|e| e.to_string())
|
refactor(backend): phase 2 - split commands.rs by domain (100%)
Split monolithic commands.rs (1525 lines) into 7 domain-focused modules
to improve maintainability and readability while preserving the external API.
## Changes
### Module Structure
Created `commands/` directory with domain-based organization:
- **provider.rs** (946 lines, 15 commands)
- Provider CRUD operations (get, add, update, delete, switch)
- Usage query integration
- Endpoint speed testing and custom endpoint management
- Sort order management
- Largest file but highly cohesive (all provider-related)
- **mcp.rs** (235 lines, 13 commands)
- Claude MCP management (~/.claude.json)
- SSOT MCP config management (config.json)
- Sync operations (Claude ↔ Codex)
- Import/export functionality
- **config.rs** (153 lines, 8 commands)
- Config path queries (Claude/Codex)
- Directory operations (open, pick)
- Config status checks
- Parameter compatibility layer (app_type/app/appType)
- **settings.rs** (40 lines, 5 commands)
- App settings management
- App restart functionality
- app_config_dir override (Store integration)
- **plugin.rs** (36 lines, 4 commands)
- Claude plugin management (~/.claude/config.json)
- Plugin status and config operations
- **misc.rs** (45 lines, 3 commands)
- External link handling
- Update checks
- Portable mode detection
- **mod.rs** (15 lines)
- Module exports via `pub use`
- Preserves flat API structure
### API Preservation
- Used `pub use` pattern to maintain external API
- All commands still accessible as `commands::function_name`
- Zero breaking changes for frontend code
- lib.rs invoke_handler unchanged (48 commands registered)
## Statistics
- Files: 1 → 7 (modular organization)
- Lines: 1525 → 1470 (net -55 lines, -3.6%)
- Commands: 48 → 48 (all preserved)
- Average file size: 210 lines (excluding provider.rs)
- Compilation: ✅ Success (6.92s, 0 warnings)
- Tests: ✅ 4/4 passed
## Benefits
- **Maintainability**: Easier to locate and modify domain-specific code
- **Readability**: Smaller files (~200 lines) vs monolithic 1500+ lines
- **Testability**: Can unit test individual modules in isolation
- **Scalability**: Clear pattern for adding new command groups
- **Zero Risk**: No API changes, all tests passing
## Design Decisions
1. **Domain-based split**: Organized by business domain (provider, mcp, config)
rather than technical layers (crud, query, sync)
2. **Preserved provider.rs size**: Kept at 946 lines to maintain high cohesion
(all provider-related operations together). Can be further split in Phase 2.1
if needed.
3. **Parameter compatibility**: Retained multiple parameter names (app_type, app,
appType) for backward compatibility with different frontend call styles
## Phase 2 Status: ✅ 100% Complete
Ready for Phase 3: Adding integration tests.
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-27 22:18:05 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 从 ~/.claude.json 导入 MCP 定义到 config.json
|
|
|
|
|
|
#[tauri::command]
|
|
|
|
|
|
pub async fn import_mcp_from_claude(state: State<'_, AppState>) -> Result<usize, String> {
|
refactor(backend): extract MCP service layer with snapshot isolation
Extract all MCP business logic from command layer into `services/mcp.rs`,
implementing snapshot isolation pattern to optimize lock granularity after
RwLock migration in Phase 5.
## Key Changes
### Service Layer (`services/mcp.rs`)
- Add `McpService` with 7 methods: `get_servers`, `upsert_server`,
`delete_server`, `set_enabled`, `sync_enabled`, `import_from_claude`,
`import_from_codex`
- Implement snapshot isolation: acquire write lock only for in-memory
modifications, clone config snapshot, release lock, then perform file I/O
with snapshot
- Use conditional cloning: only clone config when sync is actually needed
(e.g., when `enabled` flag is true or `sync_other_side` is requested)
### Command Layer (`commands/mcp.rs`)
- Reduce to thin wrappers: parse parameters and delegate to `McpService`
- Remove all `*_internal` and `*_test_hook` functions (-94 lines)
- Each command now 5-10 lines (parameter parsing + service call + error mapping)
### Core Logic Refactoring (`mcp.rs`)
- Rename `set_enabled_and_sync_for` → `set_enabled_flag_for`
- Remove file sync logic from low-level function, move sync responsibility
to service layer for better separation of concerns
### Test Adaptation (`tests/mcp_commands.rs`)
- Replace test hooks with direct `McpService` calls
- All 5 MCP integration tests pass
### Additional Fixes
- Add `Default` impl for `AppState` (clippy suggestion)
- Remove unnecessary auto-deref in `commands/provider.rs` and `lib.rs`
- Update Phase 4/5 progress in `BACKEND_REFACTOR_PLAN.md`
## Performance Impact
**Before**: Write lock held during file I/O (~10ms), blocking all readers
**After**: Write lock held only for memory ops (~100μs), file I/O lock-free
Estimated throughput improvement: ~2x in high-concurrency read scenarios
## Testing
- ✅ All tests pass: 5 MCP commands + 7 provider service tests
- ✅ Zero clippy warnings with `-D warnings`
- ✅ No behavioral changes, maintains original save semantics
Part of Phase 4 (Service Layer Abstraction) of backend refactoring roadmap.
2025-10-28 14:59:28 +08:00
|
|
|
|
McpService::import_from_claude(&state).map_err(|e| e.to_string())
|
2025-10-28 11:58:57 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 从 ~/.codex/config.toml 导入 MCP 定义到 config.json
|
|
|
|
|
|
#[tauri::command]
|
|
|
|
|
|
pub async fn import_mcp_from_codex(state: State<'_, AppState>) -> Result<usize, String> {
|
refactor(backend): extract MCP service layer with snapshot isolation
Extract all MCP business logic from command layer into `services/mcp.rs`,
implementing snapshot isolation pattern to optimize lock granularity after
RwLock migration in Phase 5.
## Key Changes
### Service Layer (`services/mcp.rs`)
- Add `McpService` with 7 methods: `get_servers`, `upsert_server`,
`delete_server`, `set_enabled`, `sync_enabled`, `import_from_claude`,
`import_from_codex`
- Implement snapshot isolation: acquire write lock only for in-memory
modifications, clone config snapshot, release lock, then perform file I/O
with snapshot
- Use conditional cloning: only clone config when sync is actually needed
(e.g., when `enabled` flag is true or `sync_other_side` is requested)
### Command Layer (`commands/mcp.rs`)
- Reduce to thin wrappers: parse parameters and delegate to `McpService`
- Remove all `*_internal` and `*_test_hook` functions (-94 lines)
- Each command now 5-10 lines (parameter parsing + service call + error mapping)
### Core Logic Refactoring (`mcp.rs`)
- Rename `set_enabled_and_sync_for` → `set_enabled_flag_for`
- Remove file sync logic from low-level function, move sync responsibility
to service layer for better separation of concerns
### Test Adaptation (`tests/mcp_commands.rs`)
- Replace test hooks with direct `McpService` calls
- All 5 MCP integration tests pass
### Additional Fixes
- Add `Default` impl for `AppState` (clippy suggestion)
- Remove unnecessary auto-deref in `commands/provider.rs` and `lib.rs`
- Update Phase 4/5 progress in `BACKEND_REFACTOR_PLAN.md`
## Performance Impact
**Before**: Write lock held during file I/O (~10ms), blocking all readers
**After**: Write lock held only for memory ops (~100μs), file I/O lock-free
Estimated throughput improvement: ~2x in high-concurrency read scenarios
## Testing
- ✅ All tests pass: 5 MCP commands + 7 provider service tests
- ✅ Zero clippy warnings with `-D warnings`
- ✅ No behavioral changes, maintains original save semantics
Part of Phase 4 (Service Layer Abstraction) of backend refactoring roadmap.
2025-10-28 14:59:28 +08:00
|
|
|
|
McpService::import_from_codex(&state).map_err(|e| e.to_string())
|
2025-10-28 11:58:57 +08:00
|
|
|
|
}
|