Skip to content

Commit 55d0758

Browse files
committed
feat(server-clone): Phase 1 — Core clone API + storage
Autonomous decisions: - Made normalize_server_id/normalize_alias public — clone_server must reuse the same ID rules as user-space imports - Registered server_clone in commands/mod.rs — required for lib.rs command wiring - Added suggest_clone_suffix/is_clone_id_available on ServerAppService — straightforward helpers for Phase 2 UI collision checks Signed-off-by: crimsonsunset <jsangio1@gmail.com>
1 parent 7d762a8 commit 55d0758

9 files changed

Lines changed: 551 additions & 6 deletions

File tree

apps/desktop/src-tauri/src/commands/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub mod logs;
1414
pub mod meta_tool_approval;
1515
pub mod oauth;
1616
pub mod server;
17+
pub mod server_clone;
1718
pub mod server_discovery;
1819
pub mod server_feature;
1920
pub mod server_manager;
@@ -33,6 +34,7 @@ pub use logs::*;
3334
pub use meta_tool_approval::*;
3435
pub use oauth::*;
3536
pub use server::*;
37+
pub use server_clone::*;
3638
pub use server_discovery::*;
3739
pub use server_feature::*;
3840
pub use server_manager::*;
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
//! Server clone commands
2+
3+
use mcpmux_core::application::ServerAppService;
4+
use mcpmux_core::domain::InstalledServer;
5+
use std::sync::Arc;
6+
use tauri::State;
7+
use tokio::sync::RwLock;
8+
9+
/// Clone an installed server into a new suffixed manual-entry install in the same space.
10+
#[tauri::command]
11+
pub async fn clone_server(
12+
app_service: State<'_, Arc<RwLock<Option<ServerAppService>>>>,
13+
space_id: String,
14+
source_server_id: String,
15+
suffix: String,
16+
alias: Option<String>,
17+
) -> Result<InstalledServer, String> {
18+
let service_lock = app_service.read().await;
19+
let service = service_lock
20+
.as_ref()
21+
.ok_or("ServerAppService not initialized")?;
22+
23+
let space_uuid = uuid::Uuid::parse_str(&space_id).map_err(|e| e.to_string())?;
24+
25+
service
26+
.clone_server(
27+
space_uuid,
28+
&source_server_id,
29+
&suffix,
30+
alias.as_deref(),
31+
)
32+
.await
33+
.map_err(|e| e.to_string())
34+
}
35+
36+
/// Return whether a suffixed clone ID is available in the given space.
37+
#[tauri::command]
38+
pub async fn is_clone_id_available(
39+
app_service: State<'_, Arc<RwLock<Option<ServerAppService>>>>,
40+
space_id: String,
41+
source_server_id: String,
42+
suffix: String,
43+
) -> Result<bool, String> {
44+
let service_lock = app_service.read().await;
45+
let service = service_lock
46+
.as_ref()
47+
.ok_or("ServerAppService not initialized")?;
48+
49+
let space_uuid = uuid::Uuid::parse_str(&space_id).map_err(|e| e.to_string())?;
50+
51+
service
52+
.is_clone_id_available(space_uuid, &source_server_id, &suffix)
53+
.await
54+
.map_err(|e| e.to_string())
55+
}
56+
57+
/// Suggest the first available default suffix for cloning a server.
58+
#[tauri::command]
59+
pub async fn suggest_clone_suffix(
60+
app_service: State<'_, Arc<RwLock<Option<ServerAppService>>>>,
61+
space_id: String,
62+
source_server_id: String,
63+
) -> Result<String, String> {
64+
let service_lock = app_service.read().await;
65+
let service = service_lock
66+
.as_ref()
67+
.ok_or("ServerAppService not initialized")?;
68+
69+
let space_uuid = uuid::Uuid::parse_str(&space_id).map_err(|e| e.to_string())?;
70+
71+
service
72+
.suggest_clone_suffix(space_uuid, &source_server_id)
73+
.await
74+
.map_err(|e| e.to_string())
75+
}

apps/desktop/src-tauri/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -870,6 +870,9 @@ pub fn run() {
870870
commands::set_server_enabled,
871871
commands::set_server_oauth_connected,
872872
commands::save_server_inputs,
873+
commands::clone_server,
874+
commands::is_clone_id_available,
875+
commands::suggest_clone_suffix,
873876
// FeatureSet commands
874877
commands::list_feature_sets,
875878
commands::list_feature_sets_by_space,

0 commit comments

Comments
 (0)