@agent-relay/dashboard-server 2.0.75 → 2.0.77

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 (68) hide show
  1. package/dist/server.js +37 -12
  2. package/dist/server.js.map +1 -1
  3. package/out/404.html +1 -1
  4. package/out/_next/static/chunks/259-83b77fa1b91ba5aa.js +1 -0
  5. package/out/_next/static/chunks/285-7e0f6b4d00cf57de.js +1 -0
  6. package/out/_next/static/chunks/app/app/[[...slug]]/page-e46f6a1ae5a4de44.js +1 -0
  7. package/out/_next/static/chunks/app/{page-5c60a00d938ac40a.js → page-2fc9cd9797ece830.js} +1 -1
  8. package/out/_next/static/chunks/app/providers/page-ad44a77ebe9d01c5.js +1 -0
  9. package/out/about.html +1 -1
  10. package/out/about.txt +1 -1
  11. package/out/app/onboarding.html +1 -1
  12. package/out/app/onboarding.txt +1 -1
  13. package/out/app.html +1 -1
  14. package/out/app.txt +2 -2
  15. package/out/blog/go-to-bed-wake-up-to-a-finished-product.html +1 -1
  16. package/out/blog/go-to-bed-wake-up-to-a-finished-product.txt +1 -1
  17. package/out/blog/let-them-cook-multi-agent-orchestration.html +1 -1
  18. package/out/blog/let-them-cook-multi-agent-orchestration.txt +1 -1
  19. package/out/blog.html +1 -1
  20. package/out/blog.txt +1 -1
  21. package/out/careers.html +1 -1
  22. package/out/careers.txt +1 -1
  23. package/out/changelog.html +1 -1
  24. package/out/changelog.txt +1 -1
  25. package/out/cloud/link.html +1 -1
  26. package/out/cloud/link.txt +1 -1
  27. package/out/complete-profile.html +1 -1
  28. package/out/complete-profile.txt +1 -1
  29. package/out/connect-repos.html +1 -1
  30. package/out/connect-repos.txt +1 -1
  31. package/out/contact.html +1 -1
  32. package/out/contact.txt +1 -1
  33. package/out/docs.html +1 -1
  34. package/out/docs.txt +1 -1
  35. package/out/history.html +1 -1
  36. package/out/history.txt +1 -1
  37. package/out/index.html +1 -1
  38. package/out/index.txt +2 -2
  39. package/out/login.html +1 -1
  40. package/out/login.txt +1 -1
  41. package/out/metrics.html +1 -1
  42. package/out/metrics.txt +1 -1
  43. package/out/pricing.html +1 -1
  44. package/out/pricing.txt +1 -1
  45. package/out/privacy.html +1 -1
  46. package/out/privacy.txt +1 -1
  47. package/out/providers/setup/claude.html +1 -1
  48. package/out/providers/setup/claude.txt +1 -1
  49. package/out/providers/setup/codex.html +1 -1
  50. package/out/providers/setup/codex.txt +1 -1
  51. package/out/providers/setup/cursor.html +1 -1
  52. package/out/providers/setup/cursor.txt +1 -1
  53. package/out/providers.html +1 -1
  54. package/out/providers.txt +2 -2
  55. package/out/security.html +1 -1
  56. package/out/security.txt +1 -1
  57. package/out/signup.html +1 -1
  58. package/out/signup.txt +1 -1
  59. package/out/terms.html +1 -1
  60. package/out/terms.txt +1 -1
  61. package/package.json +10 -10
  62. package/out/_next/static/chunks/259-b560f20df53128e5.js +0 -1
  63. package/out/_next/static/chunks/285-d90511ea4690c27f.js +0 -1
  64. package/out/_next/static/chunks/722-85011b58b9caf88b.js +0 -1
  65. package/out/_next/static/chunks/app/app/[[...slug]]/page-589620c567f85400.js +0 -1
  66. package/out/_next/static/chunks/app/providers/page-394875a22b5ba7ce.js +0 -1
  67. /package/out/_next/static/{4kMPp3uMfICqAWT7vypt4 → yONrkGEJcAsR9DmXHskk0}/_buildManifest.js +0 -0
  68. /package/out/_next/static/{4kMPp3uMfICqAWT7vypt4 → yONrkGEJcAsR9DmXHskk0}/_ssgManifest.js +0 -0
package/dist/server.js CHANGED
@@ -2114,16 +2114,14 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
2114
2114
  initializingClients.add(ws);
2115
2115
  try {
2116
2116
  const data = await getAllData();
2117
- // If team data is temporarily unavailable, send empty-but-valid structure
2118
- // so the client at least renders (better than sending nothing on first connect)
2119
- const safeData = data ?? { agents: [], users: [], messages: [], activity: [], sessions: [], summaries: [] };
2120
- const payload = JSON.stringify(safeData);
2121
- // Guard against empty/invalid payloads
2122
- if (!payload || payload.length === 0) {
2123
- console.warn('[dashboard] Skipping initial send - empty payload');
2124
- return;
2117
+ if (!data) {
2118
+ // Team data temporarily unavailable skip the initial send.
2119
+ // Reconnecting clients keep their previous data (no empty-screen flash).
2120
+ // New clients wait for the first successful broadcastData() cycle.
2121
+ debug('[dashboard] Team data unavailable on connect - deferring initial send to next broadcast');
2125
2122
  }
2126
- if (ws.readyState === WebSocket.OPEN) {
2123
+ else if (ws.readyState === WebSocket.OPEN) {
2124
+ const payload = JSON.stringify(data);
2127
2125
  debug(`[dashboard] Sending initial data, size: ${payload.length}, first 200 chars: ${payload.substring(0, 200)}`);
2128
2126
  ws.send(payload);
2129
2127
  debug('[dashboard] Initial data sent successfully');
@@ -3844,16 +3842,16 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
3844
3842
  app.use('/auth/cli', validateWorkspaceToken);
3845
3843
  /**
3846
3844
  * POST /auth/cli/:provider/start - Start CLI auth flow
3847
- * Body: { useDeviceFlow?: boolean, userId?: string }
3845
+ * Body: { userId?: string }
3848
3846
  *
3849
3847
  * When userId is provided, credentials are stored per-user at /data/users/{userId}/.{provider}/
3850
3848
  * This allows multiple users to share a workspace with their own CLI credentials.
3851
3849
  */
3852
3850
  app.post('/auth/cli/:provider/start', async (req, res) => {
3853
3851
  const { provider } = req.params;
3854
- const { useDeviceFlow, userId } = req.body || {};
3852
+ const { userId } = req.body || {};
3855
3853
  try {
3856
- const session = await startCLIAuth(provider, { useDeviceFlow, userId });
3854
+ const session = await startCLIAuth(provider, { userId });
3857
3855
  res.json({
3858
3856
  sessionId: session.id,
3859
3857
  status: session.status,
@@ -4081,6 +4079,33 @@ export async function startDashboard(portOrOptions, dataDirArg, teamDirArg, dbPa
4081
4079
  res.status(500).json({ error: 'Failed to write credential file' });
4082
4080
  }
4083
4081
  });
4082
+ /**
4083
+ * DELETE /api/credentials/apikey - Delete credential files for a provider from user's home directory
4084
+ * Used by cloud API when disconnecting a provider to clean up CLI credential files
4085
+ */
4086
+ app.delete('/api/credentials/apikey', express.json(), async (req, res) => {
4087
+ const { userId, provider } = req.body;
4088
+ if (!userId || typeof userId !== 'string') {
4089
+ return res.status(400).json({ error: 'userId is required' });
4090
+ }
4091
+ if (!provider || typeof provider !== 'string') {
4092
+ return res.status(400).json({ error: 'provider is required' });
4093
+ }
4094
+ try {
4095
+ const { getUserDirectoryService } = await import('@agent-relay/user-directory');
4096
+ const userDirService = getUserDirectoryService();
4097
+ const deletedPaths = userDirService.deleteProviderCredentials(userId, provider);
4098
+ console.log(`[credentials] Deleted ${provider} credentials for user ${userId}:`, deletedPaths);
4099
+ res.json({
4100
+ success: true,
4101
+ deletedPaths,
4102
+ });
4103
+ }
4104
+ catch (err) {
4105
+ console.error(`[credentials] Failed to delete ${provider} credentials for user ${userId}:`, err);
4106
+ res.status(500).json({ error: 'Failed to delete credential files' });
4107
+ }
4108
+ });
4084
4109
  // ===== Metrics API =====
4085
4110
  /**
4086
4111
  * GET /api/metrics - JSON format metrics for dashboard