refactor clawx

This commit is contained in:
paisley
2026-03-07 15:51:44 +08:00
parent b41a8eedd9
commit 3c9cec9fb3
40 changed files with 2567 additions and 638 deletions

View File

@@ -3,6 +3,7 @@
* Manages window creation, system tray, and IPC handlers
*/
import { app, BrowserWindow, nativeImage, session, shell } from 'electron';
import type { Server } from 'node:http';
import { join } from 'path';
import { GatewayManager } from '../gateway/manager';
import { registerIpcHandlers } from './ipc-handlers';
@@ -20,6 +21,10 @@ import { isQuitting, setQuitting } from './app-state';
import { applyProxySettings } from './proxy';
import { getSetting } from '../utils/store';
import { ensureBuiltinSkillsInstalled } from '../utils/skill-config';
import { startHostApiServer } from '../api/server';
import { HostEventBus } from '../api/event-bus';
import { deviceOAuthManager } from '../utils/device-oauth';
import { whatsAppLoginManager } from '../utils/whatsapp-login';
// Disable GPU hardware acceleration globally for maximum stability across
// all GPU configurations (no GPU, integrated, discrete).
@@ -58,6 +63,8 @@ if (!gotTheLock) {
let mainWindow: BrowserWindow | null = null;
const gatewayManager = new GatewayManager();
const clawHubService = new ClawHubService();
const hostEventBus = new HostEventBus();
let hostApiServer: Server | null = null;
/**
* Resolve the icons directory path (works in both dev and packaged mode)
@@ -185,6 +192,13 @@ async function initialize(): Promise<void> {
// Register IPC handlers
registerIpcHandlers(gatewayManager, clawHubService, mainWindow);
hostApiServer = startHostApiServer({
gatewayManager,
clawHubService,
eventBus: hostEventBus,
mainWindow,
});
// Register update handlers
registerUpdateHandlers(appUpdater, mainWindow);
@@ -251,12 +265,61 @@ async function initialize(): Promise<void> {
// Re-apply ClawX context after every gateway restart because the gateway
// may re-seed workspace files with clean templates (losing ClawX markers).
gatewayManager.on('status', (status: { state: string }) => {
hostEventBus.emit('gateway:status', status);
if (status.state === 'running') {
void ensureClawXContext().catch((error) => {
logger.warn('Failed to re-merge ClawX context after gateway reconnect:', error);
});
}
});
gatewayManager.on('error', (error) => {
hostEventBus.emit('gateway:error', { message: error.message });
});
gatewayManager.on('notification', (notification) => {
hostEventBus.emit('gateway:notification', notification);
});
gatewayManager.on('chat:message', (data) => {
hostEventBus.emit('gateway:chat-message', data);
});
gatewayManager.on('channel:status', (data) => {
hostEventBus.emit('gateway:channel-status', data);
});
gatewayManager.on('exit', (code) => {
hostEventBus.emit('gateway:exit', { code });
});
deviceOAuthManager.on('oauth:code', (payload) => {
hostEventBus.emit('oauth:code', payload);
});
deviceOAuthManager.on('oauth:start', (payload) => {
hostEventBus.emit('oauth:start', payload);
});
deviceOAuthManager.on('oauth:success', (provider) => {
hostEventBus.emit('oauth:success', { provider, success: true });
});
deviceOAuthManager.on('oauth:error', (error) => {
hostEventBus.emit('oauth:error', error);
});
whatsAppLoginManager.on('qr', (data) => {
hostEventBus.emit('channel:whatsapp-qr', data);
});
whatsAppLoginManager.on('success', (data) => {
hostEventBus.emit('channel:whatsapp-success', data);
});
whatsAppLoginManager.on('error', (error) => {
hostEventBus.emit('channel:whatsapp-error', error);
});
}
// When a second instance is launched, focus the existing window instead.
@@ -293,6 +356,8 @@ app.on('window-all-closed', () => {
app.on('before-quit', () => {
setQuitting();
hostEventBus.closeAll();
hostApiServer?.close();
// Fire-and-forget: do not await gatewayManager.stop() here.
// Awaiting inside before-quit can stall Electron's quit sequence.
void gatewayManager.stop().catch((err) => {