fluxy-bot 0.4.17 → 0.4.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fluxy-bot",
3
- "version": "0.4.17",
3
+ "version": "0.4.19",
4
4
  "description": "Self-hosted, self-evolving AI agent with its own dashboard.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -57,9 +57,13 @@ export async function startSupervisor() {
57
57
  const workerPort = getWorkerPort(config.port);
58
58
  const backendPort = getBackendPort(config.port);
59
59
 
60
- // Start Vite dev server for dashboard HMR
60
+ // Create HTTP server first (Vite needs it for HMR WebSocket)
61
+ // The request handler is set up later via server.on('request')
62
+ const server = http.createServer();
63
+
64
+ // Start Vite dev server — pass supervisor server so Vite attaches HMR WebSocket directly
61
65
  console.log('[supervisor] Starting Vite dev server...');
62
- const vitePorts = await startViteDevServers(config.port);
66
+ const vitePorts = await startViteDevServers(config.port, server);
63
67
  console.log(`[supervisor] Vite ready — dashboard :${vitePorts.dashboard}`);
64
68
 
65
69
  // Ensure file storage dirs exist
@@ -152,8 +156,8 @@ export async function startSupervisor() {
152
156
  });
153
157
  }
154
158
 
155
- // HTTP server — proxies to Vite dev servers + worker API
156
- const server = http.createServer(async (req, res) => {
159
+ // HTTP request handler — proxies to Vite dev servers + worker API
160
+ server.on('request', async (req, res) => {
157
161
  // Fluxy widget — served directly (not part of Vite build)
158
162
  if (req.url === '/fluxy/widget.js') {
159
163
  console.log('[supervisor] Serving /fluxy/widget.js directly');
@@ -421,8 +425,7 @@ export async function startSupervisor() {
421
425
  // Intercept bot:done — Vite HMR handles file changes automatically
422
426
  if (type === 'bot:done') {
423
427
  if (eventData.usedFileTools) {
424
- console.log('[supervisor] File tools used — Vite HMR will apply changes automatically');
425
- console.log('[supervisor] Restarting backend...');
428
+ console.log('[supervisor] File tools used — Vite HMR handles frontend, restarting backend');
426
429
  resetBackendRestarts();
427
430
  stopBackend();
428
431
  spawnBackend(backendPort);
@@ -508,41 +511,27 @@ export async function startSupervisor() {
508
511
  });
509
512
  });
510
513
 
514
+ // Fluxy chat WebSocket — Vite HMR is handled automatically (hmr.server = this server)
511
515
  server.on('upgrade', async (req, socket: net.Socket, head) => {
516
+ if (!req.url?.startsWith('/fluxy/ws')) return; // Let Vite handle HMR upgrades
517
+
512
518
  console.log(`[supervisor] WebSocket upgrade: ${req.url}`);
513
519
 
514
- if (req.url?.startsWith('/fluxy/ws')) {
515
- // Auth check for WebSocket
516
- const needsAuth = await isAuthRequired();
517
- if (needsAuth) {
518
- const urlObj = new URL(req.url, `http://${req.headers.host}`);
519
- const token = urlObj.searchParams.get('token');
520
- if (!token || !(await validateToken(token))) {
521
- console.log('[supervisor] WS auth failed — rejecting');
522
- socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
523
- socket.destroy();
524
- return;
525
- }
520
+ // Auth check for WebSocket
521
+ const needsAuth = await isAuthRequired();
522
+ if (needsAuth) {
523
+ const urlObj = new URL(req.url, `http://${req.headers.host}`);
524
+ const token = urlObj.searchParams.get('token');
525
+ if (!token || !(await validateToken(token))) {
526
+ console.log('[supervisor] WS auth failed — rejecting');
527
+ socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
528
+ socket.destroy();
529
+ return;
526
530
  }
527
-
528
- console.log('[supervisor] → Fluxy chat WebSocket');
529
- fluxyWss.handleUpgrade(req, socket, head, (ws) => fluxyWss.emit('connection', ws, req));
530
- return;
531
531
  }
532
532
 
533
- // Route HMR WebSocket to dashboard Vite dev server
534
- const targetPort = vitePorts.dashboard;
535
- console.log(`[supervisor] → Vite HMR (dashboard) :${targetPort}`);
536
-
537
- const proxy = net.connect(targetPort, () => {
538
- const headers = Object.entries(req.headers).map(([k, v]) => `${k}: ${v}`).join('\r\n');
539
- proxy.write(`GET ${req.url} HTTP/1.1\r\n${headers}\r\n\r\n`);
540
- if (head.length > 0) proxy.write(head);
541
- socket.pipe(proxy).pipe(socket);
542
- });
543
-
544
- proxy.on('error', () => { console.error(`[supervisor] WS proxy error → :${targetPort}`); socket.destroy(); });
545
- socket.on('error', () => proxy.destroy());
533
+ console.log('[supervisor] Fluxy chat WebSocket');
534
+ fluxyWss.handleUpgrade(req, socket, head, (ws) => fluxyWss.emit('connection', ws, req));
546
535
  });
547
536
 
548
537
  // Start
@@ -1,17 +1,18 @@
1
1
  import { createServer as createViteServer, type ViteDevServer } from 'vite';
2
+ import type http from 'http';
2
3
  import path from 'path';
3
4
  import { PKG_DIR } from '../shared/paths.js';
4
5
  import { log } from '../shared/logger.js';
5
6
 
6
7
  let dashboardVite: ViteDevServer | null = null;
7
8
 
8
- export async function startViteDevServers(supervisorPort: number): Promise<{ dashboard: number }> {
9
+ export async function startViteDevServers(supervisorPort: number, hmrServer: http.Server): Promise<{ dashboard: number }> {
9
10
  const ports = {
10
11
  dashboard: supervisorPort + 2,
11
12
  };
12
13
 
13
14
  console.log(`[vite-dev] Starting dashboard Vite dev server on :${ports.dashboard}`);
14
- console.log(`[vite-dev] HMR clientPort :${supervisorPort} (browser connects through supervisor proxy)`);
15
+ console.log(`[vite-dev] HMR attached to supervisor server (port ${supervisorPort})`);
15
16
  console.log(`[vite-dev] PKG_DIR = ${PKG_DIR}`);
16
17
 
17
18
  try {
@@ -22,7 +23,7 @@ export async function startViteDevServers(supervisorPort: number): Promise<{ das
22
23
  host: '127.0.0.1',
23
24
  strictPort: true,
24
25
  allowedHosts: true,
25
- hmr: { clientPort: supervisorPort },
26
+ hmr: { server: hmrServer, clientPort: supervisorPort },
26
27
  },
27
28
  logLevel: 'info',
28
29
  });
@@ -51,6 +52,13 @@ export async function startViteDevServers(supervisorPort: number): Promise<{ das
51
52
  return ports;
52
53
  }
53
54
 
55
+ /** Tell connected browsers to full-reload via Vite's HMR WebSocket */
56
+ export function reloadDashboard(): void {
57
+ if (!dashboardVite) return;
58
+ console.log('[vite-dev] Sending full-reload to dashboard clients');
59
+ dashboardVite.hot.send({ type: 'full-reload', path: '*' });
60
+ }
61
+
54
62
  export async function stopViteDevServers(): Promise<void> {
55
63
  console.log('[vite-dev] Stopping Vite dev servers...');
56
64
  if (dashboardVite) {