@agent-relay/dashboard-server 2.0.57 → 2.0.59

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.
Files changed (60) hide show
  1. package/dist/server.js +28 -16
  2. package/dist/server.js.map +1 -1
  3. package/dist/start.js +1 -0
  4. package/dist/start.js.map +1 -1
  5. package/dist/types/index.d.ts +2 -0
  6. package/dist/types/index.d.ts.map +1 -1
  7. package/out/404.html +1 -1
  8. package/out/about.html +1 -1
  9. package/out/about.txt +1 -1
  10. package/out/app/onboarding.html +1 -1
  11. package/out/app/onboarding.txt +1 -1
  12. package/out/app.html +1 -1
  13. package/out/app.txt +1 -1
  14. package/out/blog/go-to-bed-wake-up-to-a-finished-product.html +1 -1
  15. package/out/blog/go-to-bed-wake-up-to-a-finished-product.txt +1 -1
  16. package/out/blog.html +1 -1
  17. package/out/blog.txt +1 -1
  18. package/out/careers.html +1 -1
  19. package/out/careers.txt +1 -1
  20. package/out/changelog.html +1 -1
  21. package/out/changelog.txt +1 -1
  22. package/out/cloud/link.html +1 -1
  23. package/out/cloud/link.txt +1 -1
  24. package/out/complete-profile.html +1 -1
  25. package/out/complete-profile.txt +1 -1
  26. package/out/connect-repos.html +1 -1
  27. package/out/connect-repos.txt +1 -1
  28. package/out/contact.html +1 -1
  29. package/out/contact.txt +1 -1
  30. package/out/docs.html +1 -1
  31. package/out/docs.txt +1 -1
  32. package/out/history.html +1 -1
  33. package/out/history.txt +1 -1
  34. package/out/index.html +1 -1
  35. package/out/index.txt +1 -1
  36. package/out/login.html +1 -1
  37. package/out/login.txt +1 -1
  38. package/out/metrics.html +1 -1
  39. package/out/metrics.txt +1 -1
  40. package/out/pricing.html +1 -1
  41. package/out/pricing.txt +1 -1
  42. package/out/privacy.html +1 -1
  43. package/out/privacy.txt +1 -1
  44. package/out/providers/setup/claude.html +1 -1
  45. package/out/providers/setup/claude.txt +1 -1
  46. package/out/providers/setup/codex.html +1 -1
  47. package/out/providers/setup/codex.txt +1 -1
  48. package/out/providers/setup/cursor.html +1 -1
  49. package/out/providers/setup/cursor.txt +1 -1
  50. package/out/providers.html +1 -1
  51. package/out/providers.txt +1 -1
  52. package/out/security.html +1 -1
  53. package/out/security.txt +1 -1
  54. package/out/signup.html +1 -1
  55. package/out/signup.txt +1 -1
  56. package/out/terms.html +1 -1
  57. package/out/terms.txt +1 -1
  58. package/package.json +10 -10
  59. /package/out/_next/static/{QS-NFfJUw1w3081kmWJg9 → vqqAzuICuRIakU1wIp0AV}/_buildManifest.js +0 -0
  60. /package/out/_next/static/{QS-NFfJUw1w3081kmWJg9 → vqqAzuICuRIakU1wIp0AV}/_ssgManifest.js +0 -0
package/dist/server.js CHANGED
@@ -318,8 +318,15 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
318
318
  const options = typeof portOrOptions === 'number'
319
319
  ? { port: portOrOptions, dataDir: dataDirArg, teamDir: teamDirArg, dbPath: dbPathArg }
320
320
  : portOrOptions;
321
- const { port, dataDir, teamDir, dbPath, enableSpawner, projectRoot, tmuxSession, onMarkSpawning, onClearSpawning } = options;
322
- console.log('Starting dashboard...');
321
+ const { port, dataDir, teamDir, dbPath, enableSpawner, projectRoot, tmuxSession, onMarkSpawning, onClearSpawning, verbose } = options;
322
+ // Debug logging helper - only logs when verbose is true or VERBOSE env var is set
323
+ const isVerbose = verbose || process.env.VERBOSE === 'true';
324
+ const debug = (message) => {
325
+ if (isVerbose) {
326
+ console.log(message);
327
+ }
328
+ };
329
+ console.log('[dashboard] Starting dashboard...');
323
330
  const disableStorage = process.env.RELAY_DISABLE_STORAGE === 'true';
324
331
  // Use createStorageAdapter to match daemon's storage type (JSONL by default)
325
332
  // This ensures dashboard reads from the same storage as daemon writes to
@@ -576,7 +583,7 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
576
583
  wss.clients.forEach((ws) => {
577
584
  if (mainClientAlive.get(ws) === false) {
578
585
  // Client didn't respond to last ping - close gracefully
579
- console.log('[dashboard] Main WebSocket client unresponsive, closing gracefully');
586
+ debug('[dashboard] Main WebSocket client unresponsive, closing gracefully');
580
587
  ws.close(1000, 'unresponsive');
581
588
  return;
582
589
  }
@@ -590,7 +597,7 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
590
597
  const bridgePingInterval = setInterval(() => {
591
598
  wssBridge.clients.forEach((ws) => {
592
599
  if (bridgeClientAlive.get(ws) === false) {
593
- console.log('[dashboard] Bridge WebSocket client unresponsive, closing gracefully');
600
+ debug('[dashboard] Bridge WebSocket client unresponsive, closing gracefully');
594
601
  ws.close(1000, 'unresponsive');
595
602
  return;
596
603
  }
@@ -780,6 +787,11 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
780
787
  app.get('/app', (req, res) => {
781
788
  res.sendFile(path.join(dashboardDir, 'app.html'));
782
789
  });
790
+ // Catch-all for /app/* routes - serve app.html and let client-side routing handle it
791
+ // Express 5 requires named parameter for wildcards
792
+ app.get('/app/{*path}', (req, res) => {
793
+ res.sendFile(path.join(dashboardDir, 'app.html'));
794
+ });
783
795
  }
784
796
  else {
785
797
  // Serve a fallback page when dashboard UI files aren't available
@@ -1971,7 +1983,7 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
1971
1983
  };
1972
1984
  // Handle new WebSocket connections - send initial data immediately
1973
1985
  wss.on('connection', async (ws, req) => {
1974
- console.log('[dashboard] WebSocket client connected from:', req.socket.remoteAddress);
1986
+ debug(`[dashboard] WebSocket client connected from: ${req.socket.remoteAddress}`);
1975
1987
  // Mark client as alive initially for ping/pong keepalive
1976
1988
  mainClientAlive.set(ws, true);
1977
1989
  // Handle pong responses (keep connection alive)
@@ -1989,9 +2001,9 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
1989
2001
  return;
1990
2002
  }
1991
2003
  if (ws.readyState === WebSocket.OPEN) {
1992
- console.log('[dashboard] Sending initial data, size:', payload.length, 'first 200 chars:', payload.substring(0, 200));
2004
+ debug(`[dashboard] Sending initial data, size: ${payload.length}, first 200 chars: ${payload.substring(0, 200)}`);
1993
2005
  ws.send(payload);
1994
- console.log('[dashboard] Initial data sent successfully');
2006
+ debug('[dashboard] Initial data sent successfully');
1995
2007
  }
1996
2008
  else {
1997
2009
  console.warn('[dashboard] WebSocket not open, state:', ws.readyState);
@@ -2008,12 +2020,12 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
2008
2020
  console.error('[dashboard] WebSocket client error:', err);
2009
2021
  });
2010
2022
  ws.on('close', (code, reason) => {
2011
- console.log('[dashboard] WebSocket client disconnected, code:', code, 'reason:', reason?.toString() || 'none');
2023
+ debug(`[dashboard] WebSocket client disconnected, code: ${code}, reason: ${reason?.toString() || 'none'}`);
2012
2024
  });
2013
2025
  });
2014
2026
  // Handle bridge WebSocket connections
2015
2027
  wssBridge.on('connection', async (ws) => {
2016
- console.log('[dashboard] Bridge WebSocket client connected');
2028
+ debug('[dashboard] Bridge WebSocket client connected');
2017
2029
  // Mark client as alive initially for ping/pong keepalive
2018
2030
  bridgeClientAlive.set(ws, true);
2019
2031
  // Handle pong responses (keep connection alive)
@@ -2034,7 +2046,7 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
2034
2046
  console.error('[dashboard] Bridge WebSocket client error:', err);
2035
2047
  });
2036
2048
  ws.on('close', (code, reason) => {
2037
- console.log('[dashboard] Bridge WebSocket client disconnected, code:', code, 'reason:', reason?.toString() || 'none');
2049
+ debug(`[dashboard] Bridge WebSocket client disconnected, code: ${code}, reason: ${reason?.toString() || 'none'}`);
2038
2050
  });
2039
2051
  });
2040
2052
  // Track alive status for ping/pong keepalive on log connections
@@ -2046,7 +2058,7 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
2046
2058
  wssLogs.clients.forEach((ws) => {
2047
2059
  if (logClientAlive.get(ws) === false) {
2048
2060
  // Client didn't respond to last ping - close gracefully
2049
- console.log('[dashboard] Logs WebSocket client unresponsive, closing gracefully');
2061
+ debug('[dashboard] Logs WebSocket client unresponsive, closing gracefully');
2050
2062
  ws.close(1000, 'unresponsive');
2051
2063
  return;
2052
2064
  }
@@ -2061,7 +2073,7 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
2061
2073
  });
2062
2074
  // Handle logs WebSocket connections for live log streaming
2063
2075
  wssLogs.on('connection', (ws, req) => {
2064
- console.log('[dashboard] Logs WebSocket client connected');
2076
+ debug('[dashboard] Logs WebSocket client connected');
2065
2077
  const clientSubscriptions = new Set();
2066
2078
  // Mark client as alive initially
2067
2079
  logClientAlive.set(ws, true);
@@ -2208,7 +2220,7 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
2208
2220
  logSubscriptions.set(agentName, new Set());
2209
2221
  }
2210
2222
  logSubscriptions.get(agentName).add(ws);
2211
- console.log(`[dashboard] Client subscribed to logs for: ${agentName} (spawned: ${isSpawned}, daemon: ${isDaemon})`);
2223
+ debug(`[dashboard] Client subscribed to logs for: ${agentName} (spawned: ${isSpawned}, daemon: ${isDaemon})`);
2212
2224
  if (isSpawned && spawner) {
2213
2225
  // Send initial log history for spawned agents (5000 lines to match xterm scrollback capacity)
2214
2226
  const lines = spawner.getWorkerOutput(agentName, 5000);
@@ -2289,7 +2301,7 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
2289
2301
  fileLastSize.delete(agentName);
2290
2302
  }
2291
2303
  }
2292
- console.log(`[dashboard] Client unsubscribed from logs for: ${agentName}`);
2304
+ debug(`[dashboard] Client unsubscribed from logs for: ${agentName}`);
2293
2305
  ws.send(JSON.stringify({
2294
2306
  type: 'unsubscribed',
2295
2307
  agent: agentName,
@@ -2436,7 +2448,7 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
2436
2448
  const payload = JSON.stringify(message);
2437
2449
  // Broadcast to main WebSocket clients (local mode)
2438
2450
  const mainClients = Array.from(wss.clients).filter(c => c.readyState === WebSocket.OPEN);
2439
- console.log(`[dashboard] Broadcasting direct_message to ${mainClients.length} main clients`);
2451
+ debug(`[dashboard] Broadcasting direct_message to ${mainClients.length} main clients`);
2440
2452
  wss.clients.forEach((client) => {
2441
2453
  if (client.readyState === WebSocket.OPEN) {
2442
2454
  client.send(payload);
@@ -2445,7 +2457,7 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
2445
2457
  // Also broadcast to presence WebSocket clients (cloud mode)
2446
2458
  const presenceClients = Array.from(wssPresence.clients).filter(c => c.readyState === WebSocket.OPEN);
2447
2459
  if (presenceClients.length > 0) {
2448
- console.log(`[dashboard] Broadcasting direct_message to ${presenceClients.length} presence clients`);
2460
+ debug(`[dashboard] Broadcasting direct_message to ${presenceClients.length} presence clients`);
2449
2461
  wssPresence.clients.forEach((client) => {
2450
2462
  if (client.readyState === WebSocket.OPEN) {
2451
2463
  client.send(payload);