refactor(mcp): complete v3.7.0 cleanup - remove legacy code and warnings

This commit finalizes the v3.7.0 unified MCP architecture migration by
removing all deprecated code paths and eliminating compiler warnings.

Frontend Changes (~950 lines removed):
- Remove deprecated components: McpPanel, McpListItem, McpToggle
- Remove deprecated hook: useMcpActions
- Remove unused API methods: importFrom*, syncEnabledTo*, syncAllServers
- Simplify McpFormModal by removing dual-mode logic (unified/legacy)
- Remove syncOtherSide checkbox and conflict detection
- Clean up unused imports and state variables
- Delete associated test files

Backend Changes (~400 lines cleaned):
- Remove unused Tauri commands: import_mcp_from_*, sync_enabled_mcp_to_*
- Delete unused Gemini MCP functions: get_mcp_status, upsert/delete_mcp_server
- Add #[allow(deprecated)] to compatibility layer commands
- Add #[allow(dead_code)] to legacy helper functions for future migration
- Simplify boolean expression in mcp.rs per Clippy suggestion

API Deprecation:
- Mark legacy APIs with @deprecated JSDoc (getConfig, upsertServerInConfig, etc.)
- Preserve backward compatibility for v3.x, planned removal in v4.0

Verification:
-  Zero TypeScript errors (pnpm typecheck)
-  Zero Clippy warnings (cargo clippy)
-  All code formatted (prettier + cargo fmt)
-  Builds successfully

Total cleanup: ~1,350 lines of code removed/marked
Breaking changes: None (all legacy APIs still functional)
This commit is contained in:
Jason
2025-11-14 22:43:25 +08:00
parent fafca841cb
commit 2f18d6ec00
19 changed files with 100 additions and 1420 deletions

View File

@@ -1,14 +1,14 @@
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { mcpApi } from '@/lib/api/mcp';
import type { McpServer } from '@/types';
import type { AppId } from '@/lib/api/types';
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import { mcpApi } from "@/lib/api/mcp";
import type { McpServer } from "@/types";
import type { AppId } from "@/lib/api/types";
/**
* 查询所有 MCP 服务器(统一管理)
*/
export function useAllMcpServers() {
return useQuery({
queryKey: ['mcp', 'all'],
queryKey: ["mcp", "all"],
queryFn: () => mcpApi.getAllServers(),
});
}
@@ -21,7 +21,7 @@ export function useUpsertMcpServer() {
return useMutation({
mutationFn: (server: McpServer) => mcpApi.upsertUnifiedServer(server),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['mcp', 'all'] });
queryClient.invalidateQueries({ queryKey: ["mcp", "all"] });
},
});
}
@@ -42,7 +42,7 @@ export function useToggleMcpApp() {
enabled: boolean;
}) => mcpApi.toggleApp(serverId, app, enabled),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['mcp', 'all'] });
queryClient.invalidateQueries({ queryKey: ["mcp", "all"] });
},
});
}
@@ -55,7 +55,7 @@ export function useDeleteMcpServer() {
return useMutation({
mutationFn: (id: string) => mcpApi.deleteUnifiedServer(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['mcp', 'all'] });
queryClient.invalidateQueries({ queryKey: ["mcp", "all"] });
},
});
}

View File

@@ -1,136 +0,0 @@
import { useCallback, useState } from "react";
import { useTranslation } from "react-i18next";
import { toast } from "sonner";
import { mcpApi, type AppId } from "@/lib/api";
import type { McpServer } from "@/types";
import {
extractErrorMessage,
translateMcpBackendError,
} from "@/utils/errorUtils";
export interface UseMcpActionsResult {
servers: Record<string, McpServer>;
loading: boolean;
reload: () => Promise<void>;
toggleEnabled: (id: string, enabled: boolean) => Promise<void>;
saveServer: (
id: string,
server: McpServer,
options?: { syncOtherSide?: boolean },
) => Promise<void>;
deleteServer: (id: string) => Promise<void>;
}
/**
* useMcpActions - MCP management business logic
* Responsibilities:
* - Load MCP servers
* - Toggle enable/disable status
* - Save server configuration
* - Delete server
* - Error handling and toast notifications
*/
export function useMcpActions(appId: AppId): UseMcpActionsResult {
const { t } = useTranslation();
const [servers, setServers] = useState<Record<string, McpServer>>({});
const [loading, setLoading] = useState(false);
const reload = useCallback(async () => {
setLoading(true);
try {
const cfg = await mcpApi.getConfig(appId);
setServers(cfg.servers || {});
} catch (error) {
console.error("[useMcpActions] Failed to load MCP config", error);
const detail = extractErrorMessage(error);
const mapped = translateMcpBackendError(detail, t);
toast.error(mapped || detail || t("mcp.error.loadFailed"), {
duration: mapped || detail ? 6000 : 5000,
});
} finally {
setLoading(false);
}
}, [appId, t]);
const toggleEnabled = useCallback(
async (id: string, enabled: boolean) => {
// Optimistic update
const previousServers = servers;
setServers((prev) => ({
...prev,
[id]: {
...prev[id],
enabled,
},
}));
try {
await mcpApi.setEnabled(appId, id, enabled);
toast.success(enabled ? t("mcp.msg.enabled") : t("mcp.msg.disabled"), {
duration: 1500,
});
} catch (error) {
// Rollback on failure
setServers(previousServers);
const detail = extractErrorMessage(error);
const mapped = translateMcpBackendError(detail, t);
toast.error(mapped || detail || t("mcp.error.saveFailed"), {
duration: mapped || detail ? 6000 : 5000,
});
}
},
[appId, servers, t],
);
const saveServer = useCallback(
async (
id: string,
server: McpServer,
options?: { syncOtherSide?: boolean },
) => {
try {
const payload: McpServer = { ...server, id };
await mcpApi.upsertServerInConfig(appId, id, payload, {
syncOtherSide: options?.syncOtherSide,
});
await reload();
toast.success(t("mcp.msg.saved"), { duration: 1500 });
} catch (error) {
const detail = extractErrorMessage(error);
const mapped = translateMcpBackendError(detail, t);
const msg = mapped || detail || t("mcp.error.saveFailed");
toast.error(msg, { duration: mapped || detail ? 6000 : 5000 });
// Re-throw to allow form-level error handling
throw error;
}
},
[appId, reload, t],
);
const deleteServer = useCallback(
async (id: string) => {
try {
await mcpApi.deleteServerInConfig(appId, id);
await reload();
toast.success(t("mcp.msg.deleted"), { duration: 1500 });
} catch (error) {
const detail = extractErrorMessage(error);
const mapped = translateMcpBackendError(detail, t);
toast.error(mapped || detail || t("mcp.error.deleteFailed"), {
duration: mapped || detail ? 6000 : 5000,
});
throw error;
}
},
[appId, reload, t],
);
return {
servers,
loading,
reload,
toggleEnabled,
saveServer,
deleteServer,
};
}