Skip to content

Commit 78fda0f

Browse files
authored
Merge pull request #92 from levante-hub/fix/runtime-implementation
fix: runtime installation improvements and auto-install for MCP servers
2 parents fab4bbf + 930f20a commit 78fda0f

26 files changed

+409
-445
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
"update-electron-app": "^3.1.1",
111111
"use-stick-to-bottom": "^1.1.1",
112112
"vaul": "^1.1.2",
113+
"winston": "^3.18.3",
113114
"zod": "^4.1.12",
114115
"zustand": "^5.0.8"
115116
},

pnpm-lock.yaml

Lines changed: 8 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/ipc/mcpHandlers/configuration.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,16 @@ export function registerConfigurationHandlers(
4343
results[serverId] = { success: true };
4444
logger.mcp.info("Successfully reconnected MCP server", { serverId });
4545
} catch (error: any) {
46-
results[serverId] = { success: false, error: error.message };
46+
// Handle runtime errors gracefully during batch refresh
47+
if (error.message === 'RUNTIME_NOT_FOUND') {
48+
results[serverId] = {
49+
success: false,
50+
error: "Runtime not available. Please check your connection and try again."
51+
};
52+
} else {
53+
results[serverId] = { success: false, error: error.message };
54+
}
55+
4756
logger.mcp.error("Failed to reconnect MCP server", {
4857
serverId,
4958
error: error.message,

src/main/ipc/mcpHandlers/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ let mcpService: IMCPService;
2121
const configManager = new MCPConfigurationManager();
2222
const logger = getLogger();
2323

24-
export function registerMCPHandlers() {
24+
export async function registerMCPHandlers() {
2525
try {
2626
// Create MCP service based on user preferences
2727
const uiPreferences = preferencesService.getAll();
28-
mcpService = MCPServiceFactory.createFromUIPreferences(uiPreferences);
28+
mcpService = await MCPServiceFactory.createFromUIPreferences(uiPreferences);
2929

3030
logger.mcp.info("MCP service created via factory", {
3131
sdk: uiPreferences.mcp?.sdk || "mcp-use",

src/main/ipc/mcpHandlers/registry.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,6 @@ import { getLogger } from "../../services/logging";
44
const logger = getLogger();
55

66
export function registerRegistryHandlers(mcpService: any, configManager: any) {
7-
// Diagnose system for MCP compatibility
8-
ipcMain.handle("levante/mcp/diagnose-system", async () => {
9-
try {
10-
const diagnosis = await mcpService.diagnoseSystem();
11-
return { success: true, data: diagnosis };
12-
} catch (error: any) {
13-
return { success: false, error: error.message };
14-
}
15-
});
16-
177
// Get MCP registry information
188
ipcMain.handle("levante/mcp/get-registry", async () => {
199
try {

src/main/lifecycle/initialization.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ export async function initializeServices(): Promise<void> {
109109
* Should be called after service initialization
110110
* @param getMainWindow - Function to get current main window reference
111111
*/
112-
export function registerIPCHandlers(getMainWindow: () => BrowserWindow | null): void {
112+
export async function registerIPCHandlers(getMainWindow: () => BrowserWindow | null): Promise<void> {
113113
// Service-specific handlers
114114
setupDatabaseHandlers();
115115
setupPreferencesHandlers();
@@ -119,7 +119,7 @@ export function registerIPCHandlers(getMainWindow: () => BrowserWindow | null):
119119
setupLoggerHandlers();
120120
setupWizardHandlers();
121121
setupProfileHandlers();
122-
registerMCPHandlers();
122+
await registerMCPHandlers();
123123
registerDebugHandlers();
124124
registerAnalyticsHandlers();
125125

src/main/main.ts

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -46,28 +46,39 @@ let mainWindow: BrowserWindow | null = null;
4646

4747
// App ready event
4848
app.whenReady().then(async () => {
49-
// Initialize all services
50-
await initializeServices();
49+
try {
50+
// Initialize all services
51+
await initializeServices();
5152

52-
// Register all IPC handlers
53-
registerIPCHandlers(() => mainWindow);
53+
// Register all IPC handlers
54+
await registerIPCHandlers(() => mainWindow);
5455

55-
// Create main window
56-
mainWindow = createMainWindow();
56+
// Create main window
57+
mainWindow = createMainWindow();
5758

58-
// Track app open (fire and forget, don't block UI)
59-
analyticsService.trackAppOpen().catch(() => { });
59+
// Track app open (fire and forget, don't block UI)
60+
analyticsService.trackAppOpen().catch(() => { });
6061

61-
// Create application menu
62-
createApplicationMenu(mainWindow);
62+
// Create application menu
63+
createApplicationMenu(mainWindow);
6364

64-
// Register main window with services
65-
deepLinkService.setMainWindow(mainWindow);
66-
oauthCallbackServer.setMainWindow(mainWindow);
65+
// Register main window with services
66+
deepLinkService.setMainWindow(mainWindow);
67+
oauthCallbackServer.setMainWindow(mainWindow);
6768

68-
// Register app event handlers
69-
registerAppEvents(() => mainWindow);
69+
// Register app event handlers
70+
registerAppEvents(() => mainWindow);
7071

71-
// Setup deep link handling (Windows/Linux)
72-
setupDeepLinkHandling();
72+
// Setup deep link handling (Windows/Linux)
73+
setupDeepLinkHandling();
74+
} catch (error) {
75+
console.error('Fatal error during app initialization:', error);
76+
// Show error dialog and quit
77+
const { dialog } = await import('electron');
78+
dialog.showErrorBox(
79+
'Initialization Error',
80+
`Failed to start the application:\n\n${error instanceof Error ? error.message : String(error)}`
81+
);
82+
app.quit();
83+
}
7384
});

src/main/services/mcp/IMCPService.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ import type { MCPRegistry } from "./types.js";
1717
* must implement, allowing them to be used interchangeably via the factory pattern.
1818
*/
1919
export interface IMCPService {
20+
/**
21+
* Initialize the MCP service. Must be called before using other methods.
22+
* This allows for async initialization like configuring loggers.
23+
*/
24+
initialize(): Promise<void>;
25+
2026
/**
2127
* Connect to an MCP server with the given configuration.
2228
* @param config - Server configuration including transport details
@@ -98,16 +104,6 @@ export interface IMCPService {
98104
alternative?: string;
99105
}>;
100106

101-
/**
102-
* Run system diagnostics for MCP compatibility.
103-
* @returns Diagnostic results with issues and recommendations
104-
*/
105-
diagnoseSystem(): Promise<{
106-
success: boolean;
107-
issues: string[];
108-
recommendations: string[];
109-
}>;
110-
111107
// ==========================================
112108
// MCP Resources methods
113109
// ==========================================

src/main/services/mcp/diagnostics.ts

Lines changed: 0 additions & 101 deletions
This file was deleted.

src/main/services/mcp/index.ts

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import type {
77
} from "../../types/mcp.js";
88
import { getLogger } from "../logging";
99
import { createTransport, handleConnectionError } from "./transports.js";
10-
import { diagnoseSystem } from "./diagnostics.js";
1110
import { loadMCPRegistry } from "./registry.js";
1211
import type { MCPRegistry } from "./types";
1312
import { RuntimeManager } from "../runtime/runtimeManager";
@@ -367,13 +366,4 @@ export class MCPService {
367366
};
368367
}
369368
}
370-
371-
// Diagnose system for MCP compatibility
372-
async diagnoseSystem(): Promise<{
373-
success: boolean;
374-
issues: string[];
375-
recommendations: string[];
376-
}> {
377-
return await diagnoseSystem();
378-
}
379369
}

0 commit comments

Comments
 (0)