feat: Electron auto-starts gateway + always loads web app
- createWindow() no longer loads static onboarding HTML on missing gateway - Auto-starts 'openclaw gateway start' if not running + OpenClaw installed - Always loads the React web app (wizard handles gateway state) - Added gateway:restart IPC handler for renderer to restart gateway - Preload exposes gateway.restart() via contextBridge - before-quit kills spawned gateway process
This commit is contained in:
@@ -220,23 +220,33 @@ async function createWindow() {
|
||||
});
|
||||
|
||||
const gatewayUrl = getGatewayUrl();
|
||||
if (gatewayUrl) {
|
||||
// Gateway found — start local server to serve UI + proxy API
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
try {
|
||||
await startLocalServer(gatewayUrl);
|
||||
} catch (err) {
|
||||
console.error('[ClawSuite] Failed to start local server:', err);
|
||||
}
|
||||
if (!gatewayUrl && isOpenClawInstalled()) {
|
||||
console.log('[ClawSuite] Gateway not running, auto-starting...');
|
||||
try {
|
||||
gatewayProcess = (0, child_process_1.spawn)('openclaw', ['gateway', 'start'], {
|
||||
shell: true,
|
||||
stdio: 'ignore',
|
||||
detached: true,
|
||||
});
|
||||
gatewayProcess.unref();
|
||||
await new Promise((resolve) => setTimeout(resolve, 3000));
|
||||
} catch (err) {
|
||||
console.error('[ClawSuite] Failed to auto-start gateway:', err);
|
||||
}
|
||||
const appUrl = getAppUrl();
|
||||
console.log(`[ClawSuite] Loading: ${appUrl}`);
|
||||
mainWindow.loadURL(appUrl);
|
||||
} else {
|
||||
// No gateway — show onboarding wizard
|
||||
mainWindow.loadFile((0, path_1.join)(__dirname, '..', 'electron', 'onboarding', 'index.html'));
|
||||
}
|
||||
|
||||
if (process.env.NODE_ENV !== 'development') {
|
||||
try {
|
||||
await startLocalServer(getGatewayUrl());
|
||||
} catch (err) {
|
||||
console.error('[ClawSuite] Failed to start local server:', err);
|
||||
}
|
||||
}
|
||||
|
||||
const appUrl = getAppUrl();
|
||||
console.log(`[ClawSuite] Loading: ${appUrl}`);
|
||||
mainWindow.loadURL(appUrl);
|
||||
|
||||
mainWindow.webContents.setWindowOpenHandler(({ url }) => {
|
||||
if (url.startsWith('http')) {
|
||||
electron_1.shell.openExternal(url);
|
||||
@@ -356,6 +366,26 @@ electron_1.ipcMain.handle('gateway:start', async () => {
|
||||
stdio: 'pipe',
|
||||
detached: true,
|
||||
});
|
||||
gatewayProcess.unref();
|
||||
setTimeout(() => {
|
||||
const url = getGatewayUrl();
|
||||
resolve({ success: !!url, url });
|
||||
}, 5000);
|
||||
});
|
||||
});
|
||||
|
||||
electron_1.ipcMain.handle('gateway:restart', async () => {
|
||||
try {
|
||||
(0, child_process_1.execSync)('openclaw gateway stop', { timeout: 5000 });
|
||||
} catch { /* may not be running */ }
|
||||
|
||||
return new Promise((resolve) => {
|
||||
gatewayProcess = (0, child_process_1.spawn)('openclaw', ['gateway', 'start'], {
|
||||
shell: true,
|
||||
stdio: 'pipe',
|
||||
detached: true,
|
||||
});
|
||||
gatewayProcess.unref();
|
||||
setTimeout(() => {
|
||||
const url = getGatewayUrl();
|
||||
resolve({ success: !!url, url });
|
||||
@@ -413,6 +443,10 @@ electron_1.app.on('before-quit', () => {
|
||||
appProcess.kill();
|
||||
appProcess = null;
|
||||
}
|
||||
if (gatewayProcess) {
|
||||
gatewayProcess.kill();
|
||||
gatewayProcess = null;
|
||||
}
|
||||
});
|
||||
|
||||
electron_1.app.setName('ClawSuite');
|
||||
|
||||
@@ -11,6 +11,7 @@ electron_1.contextBridge.exposeInMainWorld('clawsuite', {
|
||||
check: () => electron_1.ipcRenderer.invoke('gateway:check'),
|
||||
install: () => electron_1.ipcRenderer.invoke('gateway:install'),
|
||||
start: () => electron_1.ipcRenderer.invoke('gateway:start'),
|
||||
restart: () => electron_1.ipcRenderer.invoke('gateway:restart'),
|
||||
connect: (url) => electron_1.ipcRenderer.invoke('gateway:connect', url),
|
||||
},
|
||||
// Onboarding
|
||||
|
||||
Reference in New Issue
Block a user