Skip to content

Commit 81c0eea

Browse files
JooHyung Parkclaude
andcommitted
[ai-assisted] fix: IPC start server button had no effect
Remove serverManagerAdapter indirection layer and have IPC handlers call TalkToFigmaService directly, matching the cmd+s code path. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 103e9fc commit 81c0eea

File tree

2 files changed

+47
-118
lines changed

2 files changed

+47
-118
lines changed

src/main.ts

Lines changed: 2 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import path from 'node:path';
99
import inspector from 'node:inspector';
1010
import started from 'electron-squirrel-startup';
1111
import { initialize } from '@aptabase/electron/main';
12-
import { registerIpcHandlers, setServerManager, setAuthManager, emitToRenderer } from './main/ipc-handlers';
12+
import { registerIpcHandlers, setAuthManager, emitToRenderer } from './main/ipc-handlers';
1313
import { createLogger, setMainWindow } from './main/utils/logger';
1414
import { TalkToFigmaService, TalkToFigmaServerManager, TalkToFigmaTray } from './main/server';
15-
import { trackAppStart, trackAppQuit, trackUserEngagement, trackFirstOpenIfNeeded, trackAppException, trackServerAction, trackOAuthAction, APTABASE_APP_KEY } from './main/analytics';
15+
import { trackAppStart, trackAppQuit, trackUserEngagement, trackFirstOpenIfNeeded, trackAppException, trackOAuthAction, APTABASE_APP_KEY } from './main/analytics';
1616
import { FigmaOAuthService } from './main/figma/oauth/FigmaOAuthService';
1717
import { FigmaApiClient } from './main/figma/api/FigmaApiClient';
1818
import { IPC_CHANNELS, STORE_KEYS } from './shared/constants';
@@ -209,95 +209,6 @@ const initializeServers = (window: BrowserWindow) => {
209209
}
210210
});
211211

212-
// Create adapter for IPC handlers to use the new service
213-
const serverManagerAdapter: {
214-
start: () => Promise<void>;
215-
stop: () => Promise<void>;
216-
restart: () => Promise<void>;
217-
getStatus: () => ServerState;
218-
} = {
219-
start: async () => {
220-
const startTime = Date.now();
221-
try {
222-
const result = await service!.startAll();
223-
if (!result.success) {
224-
throw new Error(result.error || 'Failed to start servers');
225-
}
226-
// Track successful server start with startup time
227-
const startupTimeMs = Date.now() - startTime;
228-
trackServerAction('start', 'all', 3055, startupTimeMs, true);
229-
// Note: emitStatusChange is called via TrayUpdateCallback in service.startAll()
230-
// No need to call it explicitly here to avoid duplicate events
231-
} catch (error) {
232-
// Track failed server start
233-
const errorMessage = error instanceof Error ? error.message : String(error);
234-
trackServerAction('start', 'all', 3055, undefined, false, errorMessage);
235-
// Ensure UI reflects error state
236-
emitStatusChange();
237-
throw error;
238-
}
239-
},
240-
stop: async () => {
241-
try {
242-
const result = await service!.stopAll();
243-
if (!result.success) {
244-
throw new Error(result.error || 'Failed to stop servers');
245-
}
246-
// Track successful server stop
247-
trackServerAction('stop', 'all', 3055, undefined, true);
248-
// Note: emitStatusChange is called via TrayUpdateCallback in service.stopAll()
249-
// No need to call it explicitly here to avoid duplicate events
250-
} catch (error) {
251-
// Track failed server stop
252-
const errorMessage = error instanceof Error ? error.message : String(error);
253-
trackServerAction('stop', 'all', 3055, undefined, false, errorMessage);
254-
// Ensure UI reflects error state
255-
emitStatusChange();
256-
throw error;
257-
}
258-
},
259-
restart: async () => {
260-
// Track server restart at the beginning
261-
trackServerAction('restart', 'all', 3055, undefined, true);
262-
// Delegate to stop and start - they handle their own tracking
263-
await serverManagerAdapter.stop();
264-
await new Promise(resolve => setTimeout(resolve, 1000));
265-
await serverManagerAdapter.start();
266-
},
267-
getStatus: () => {
268-
const result = service!.getStatus();
269-
if (result.success && result.status) {
270-
// Convert FigmaServerState to ServerState format
271-
const figmaState = result.status;
272-
return {
273-
websocket: {
274-
status: figmaState.websocket.running ? 'running' : 'stopped',
275-
port: figmaState.websocket.port,
276-
connectedClients: figmaState.websocket.clientCount || 0,
277-
mcpClientCount: figmaState.websocket.mcpClientCount,
278-
figmaClientCount: figmaState.websocket.figmaClientCount,
279-
},
280-
mcp: {
281-
status: 'running', // stdio mode is always available when app is running
282-
transport: 'stdio',
283-
},
284-
operationInProgress: false,
285-
lastError: null,
286-
};
287-
}
288-
// Return default stopped state if getStatus fails
289-
return {
290-
websocket: { status: 'stopped', port: 3055, connectedClients: 0 },
291-
mcp: { status: 'stopped', transport: 'stdio' },
292-
operationInProgress: false,
293-
lastError: result.error || null,
294-
};
295-
},
296-
};
297-
298-
// Set the adapter for IPC handlers
299-
setServerManager(serverManagerAdapter);
300-
301212
// Create auth manager adapter
302213
const authManagerAdapter = {
303214
startOAuth: async () => {

src/main/ipc-handlers.ts

Lines changed: 45 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,19 @@ import { createLogger } from './utils/logger';
1010
import * as storeUtils from './utils/store';
1111
import type { ServerState, FigmaAuthState } from '../shared/types';
1212
import { registerMcpConfigHandlers } from './handlers/mcp-config-handler';
13-
import { trackTutorialAction, trackThemeChange, trackPageView } from './analytics';
13+
import { trackTutorialAction, trackThemeChange, trackPageView, trackServerAction } from './analytics';
1414
import { checkForUpdates } from './utils/updater';
15+
import { TalkToFigmaService } from './server/TalkToFigmaService';
1516

1617
const logger = createLogger('IPC');
1718

18-
// Placeholder for server manager (will be implemented in Phase 2)
19-
let serverManager: {
20-
start: () => Promise<void>;
21-
stop: () => Promise<void>;
22-
restart: () => Promise<void>;
23-
getStatus: () => ServerState;
24-
} | null = null;
25-
26-
// Placeholder for auth manager (will be implemented in Phase 4)
19+
// Auth manager (set by main.ts after initialization)
2720
let authManager: {
2821
startOAuth: () => Promise<void>;
2922
logout: () => Promise<void>;
3023
getStatus: () => FigmaAuthState;
3124
} | null = null;
3225

33-
export function setServerManager(manager: typeof serverManager): void {
34-
serverManager = manager;
35-
}
36-
3726
export function setAuthManager(manager: typeof authManager): void {
3827
authManager = manager;
3928
}
@@ -44,38 +33,67 @@ export function registerIpcHandlers(mainWindow: BrowserWindow): void {
4433
// ===== Server Control =====
4534
ipcMain.handle(IPC_CHANNELS.SERVER_START, async () => {
4635
logger.info('IPC: server:start');
47-
if (!serverManager) {
48-
throw new Error('Server manager not initialized');
36+
const service = TalkToFigmaService.getInstance();
37+
const startTime = Date.now();
38+
const result = await service.startAll({ showNotification: false });
39+
if (!result.success) {
40+
trackServerAction('start', 'all', 3055, undefined, false, result.error);
41+
throw new Error(result.error || 'Failed to start servers');
4942
}
50-
await serverManager.start();
43+
trackServerAction('start', 'all', 3055, Date.now() - startTime, true);
5144
});
5245

5346
ipcMain.handle(IPC_CHANNELS.SERVER_STOP, async () => {
5447
logger.info('IPC: server:stop');
55-
if (!serverManager) {
56-
throw new Error('Server manager not initialized');
48+
const service = TalkToFigmaService.getInstance();
49+
const result = await service.stopAll({ showNotification: false });
50+
if (!result.success) {
51+
trackServerAction('stop', 'all', 3055, undefined, false, result.error);
52+
throw new Error(result.error || 'Failed to stop servers');
5753
}
58-
await serverManager.stop();
54+
trackServerAction('stop', 'all', 3055, undefined, true);
5955
});
6056

6157
ipcMain.handle(IPC_CHANNELS.SERVER_RESTART, async () => {
6258
logger.info('IPC: server:restart');
63-
if (!serverManager) {
64-
throw new Error('Server manager not initialized');
59+
const service = TalkToFigmaService.getInstance();
60+
await service.stopAll({ showNotification: false });
61+
await new Promise(resolve => setTimeout(resolve, 1000));
62+
const result = await service.startAll({ showNotification: false });
63+
if (!result.success) {
64+
trackServerAction('restart', 'all', 3055, undefined, false, result.error);
65+
throw new Error(result.error || 'Failed to restart servers');
6566
}
66-
await serverManager.restart();
67+
trackServerAction('restart', 'all', 3055, undefined, true);
6768
});
6869

6970
ipcMain.handle(IPC_CHANNELS.SERVER_GET_STATUS, async () => {
70-
if (!serverManager) {
71+
const service = TalkToFigmaService.getInstance();
72+
const result = service.getStatus();
73+
if (result.success && result.status) {
74+
const figmaState = result.status;
7175
return {
72-
websocket: { status: 'stopped', port: 3055, connectedClients: 0 },
73-
mcp: { status: 'stopped', port: 3056 },
76+
websocket: {
77+
status: figmaState.websocket.running ? 'running' : 'stopped',
78+
port: figmaState.websocket.port,
79+
connectedClients: figmaState.websocket.clientCount || 0,
80+
mcpClientCount: figmaState.websocket.mcpClientCount,
81+
figmaClientCount: figmaState.websocket.figmaClientCount,
82+
},
83+
mcp: {
84+
status: 'running',
85+
transport: 'stdio',
86+
},
7487
operationInProgress: false,
7588
lastError: null,
7689
} as ServerState;
7790
}
78-
return serverManager.getStatus();
91+
return {
92+
websocket: { status: 'stopped', port: 3055, connectedClients: 0 },
93+
mcp: { status: 'stopped', port: 3056 },
94+
operationInProgress: false,
95+
lastError: result.error || null,
96+
} as ServerState;
7997
});
8098

8199
// ===== Authentication =====

0 commit comments

Comments
 (0)