Skip to content

Commit f3eae5a

Browse files
committed
fix: integrate server directly into Electron main process for production [RELEASE]
1 parent 494560c commit f3eae5a

1 file changed

Lines changed: 23 additions & 27 deletions

File tree

‎gemini-bridge/main.js‎

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,40 @@
11
const { app, BrowserWindow, Tray, Menu, nativeImage } = require('electron');
22
const path = require('path');
33
const http = require('http');
4-
const { spawn } = require('child_process');
4+
5+
// Integrar el servidor directamente en el proceso principal
6+
// Esto asegura que el servidor funcione en producción sin depender de un binario 'node' externo
7+
require('./server.js');
58

69
let mainWindow;
710
let tray;
8-
let serverProcess;
911

1012
function createWindow() {
1113
mainWindow = new BrowserWindow({
1214
width: 1200,
1315
height: 850,
1416
title: "Agent Tunnel",
1517
icon: path.join(__dirname, 'logo.png'),
18+
show: false, // No mostrar hasta que esté listo
1619
webPreferences: {
1720
nodeIntegration: false,
1821
contextIsolation: true
1922
}
2023
});
2124

22-
// En producción cargamos el servidor local
2325
const url = 'http://localhost:3456';
2426

25-
// Pequeña espera para asegurar que el servidor ha arrancado
26-
setTimeout(() => {
27-
mainWindow.loadURL(url).catch(() => {
28-
// Reintentar si falla (el servidor está arrancando)
29-
setTimeout(() => mainWindow.loadURL(url), 1000);
27+
// Reintentar la carga hasta que el servidor interno esté listo
28+
const loadWithRetry = () => {
29+
mainWindow.loadURL(url).then(() => {
30+
mainWindow.show();
31+
}).catch(() => {
32+
console.log("Servidor no listo, reintentando...");
33+
setTimeout(loadWithRetry, 500);
3034
});
31-
}, 1000);
35+
};
36+
37+
loadWithRetry();
3238

3339
mainWindow.on('close', (event) => {
3440
if (!app.isQuitting) {
@@ -41,20 +47,23 @@ function createWindow() {
4147

4248
function createTray() {
4349
const iconPath = path.join(__dirname, 'logo.png');
44-
// Usamos un icono redimensionado para el tray
45-
const icon = nativeImage.createFromPath(iconPath).resize({ width: 18, height: 18 });
46-
tray = new Tray(icon);
50+
const image = nativeImage.createFromPath(iconPath);
51+
52+
// En macOS el tray suele ser de 18x18, en Windows 16x16
53+
const trayIcon = image.resize({ width: 18, height: 18 });
54+
tray = new Tray(trayIcon);
4755
tray.setToolTip('Agent Tunnel');
4856

4957
tray.on('click', () => {
5058
mainWindow.show();
5159
});
5260

5361
updateTrayMenu();
62+
// Actualizar el menú del Tray periódicamente para reflejar cambios en las sesiones
63+
setInterval(updateTrayMenu, 5000);
5464
}
5565

5666
async function updateTrayMenu() {
57-
// Consultar sesiones activas al servidor local
5867
const req = http.get('http://localhost:3456/api/sessions', (res) => {
5968
let data = '';
6069
res.on('data', chunk => data += chunk);
@@ -120,36 +129,23 @@ function stopSession(name) {
120129
'Content-Length': postData.length
121130
}
122131
});
123-
req.on('error', (e) => console.error('Error stopping session via tray:', e));
124132
req.write(postData);
125133
req.end();
126134
}
127135

128136
app.whenReady().then(() => {
129-
// Iniciar el servidor de Agent Tunnel (el mismo que usa la CLI)
130-
serverProcess = spawn('node', ['server.js'], {
131-
cwd: __dirname,
132-
stdio: 'inherit'
133-
});
134-
135137
createWindow();
136138
createTray();
137139

138-
// Actualizar el menú del Tray cada 5 segundos para reflejar cambios
139-
setInterval(updateTrayMenu, 5000);
140-
141140
app.on('activate', () => {
142141
if (BrowserWindow.getAllWindows().length === 0) createWindow();
143142
});
144143
});
145144

146145
app.on('window-all-closed', () => {
147-
if (process.platform !== 'darwin') {
148-
// En Windows/Linux se queda en el tray
149-
}
146+
// Mantener la app viva en el tray
150147
});
151148

152149
app.on('before-quit', () => {
153150
app.isQuitting = true;
154-
if (serverProcess) serverProcess.kill();
155151
});

0 commit comments

Comments
 (0)