agent-relay 2.0.21 → 2.0.23
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/bin/relay-pty-linux-arm64 +0 -0
- package/dist/src/cli/index.d.ts +3 -3
- package/dist/src/cli/index.js +31 -100
- package/package.json +22 -29
- package/packages/api-types/package.json +1 -1
- package/packages/bridge/package.json +8 -8
- package/packages/cli-tester/package.json +1 -1
- package/packages/cloud/dist/server.js +25 -4
- package/packages/cloud/package.json +6 -6
- package/packages/config/package.json +2 -2
- package/packages/continuity/package.json +1 -1
- package/packages/daemon/dist/orchestrator.js +21 -1
- package/packages/daemon/dist/router.d.ts +5 -0
- package/packages/daemon/dist/router.js +31 -0
- package/packages/daemon/dist/server.d.ts +5 -0
- package/packages/daemon/dist/server.js +131 -1
- package/packages/daemon/package.json +12 -12
- package/packages/hooks/package.json +4 -4
- package/packages/mcp/dist/client.d.ts +15 -0
- package/packages/mcp/dist/client.js +9 -0
- package/packages/mcp/dist/server.js +13 -1
- package/packages/mcp/dist/tools/index.d.ts +2 -0
- package/packages/mcp/dist/tools/index.js +2 -0
- package/packages/mcp/dist/tools/relay-connected.d.ts +17 -0
- package/packages/mcp/dist/tools/relay-connected.js +40 -0
- package/packages/mcp/dist/tools/relay-remove-agent.d.ts +20 -0
- package/packages/mcp/dist/tools/relay-remove-agent.js +50 -0
- package/packages/mcp/package.json +2 -2
- package/packages/memory/package.json +2 -2
- package/packages/policy/package.json +2 -2
- package/packages/protocol/dist/types.d.ts +46 -1
- package/packages/protocol/package.json +1 -1
- package/packages/resiliency/package.json +1 -1
- package/packages/sdk/dist/client.d.ts +22 -1
- package/packages/sdk/dist/client.js +31 -0
- package/packages/sdk/dist/protocol/index.d.ts +1 -1
- package/packages/sdk/dist/protocol/types.d.ts +35 -1
- package/packages/sdk/package.json +2 -2
- package/packages/spawner/package.json +1 -1
- package/packages/state/package.json +1 -1
- package/packages/storage/dist/adapter.d.ts +4 -0
- package/packages/storage/dist/sqlite-adapter.d.ts +10 -0
- package/packages/storage/dist/sqlite-adapter.js +26 -0
- package/packages/storage/package.json +2 -2
- package/packages/telemetry/package.json +1 -1
- package/packages/trajectory/package.json +2 -2
- package/packages/user-directory/package.json +2 -2
- package/packages/utils/dist/update-checker.js +4 -0
- package/packages/utils/package.json +1 -1
- package/packages/wrapper/package.json +6 -6
- package/deploy/workspace/codex.config.toml +0 -20
- package/deploy/workspace/entrypoint-browser.sh +0 -118
- package/deploy/workspace/entrypoint.sh +0 -612
- package/deploy/workspace/gh-credential-relay +0 -90
- package/deploy/workspace/gh-relay +0 -156
- package/deploy/workspace/git-credential-relay +0 -330
- package/deploy/workspace/git-credential-relay.test.sh +0 -230
- package/dist/dashboard/out/404.html +0 -1
- package/dist/dashboard/out/_next/static/7MZPqYkVGw3EGzVBkVmY9/_buildManifest.js +0 -1
- package/dist/dashboard/out/_next/static/7MZPqYkVGw3EGzVBkVmY9/_ssgManifest.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/116-a883fca163f3a5bc.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/117-c8afed19e821a35d.js +0 -2
- package/dist/dashboard/out/_next/static/chunks/282-980c2eb8fff20123.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/320-a6304232cd0ee2ce.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/532-bace199897eeab37.js +0 -9
- package/dist/dashboard/out/_next/static/chunks/631-16b905e5920f9b59.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/648-acb2ff9f77cbfbd3.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/766-2aea80818f7eb0d8.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/83-26d2bde54616ee90.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/847-f1f467060f32afff.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/891-5cb1513eeb97a891.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/_not-found/page-60501fddbafba9dc.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-9914652442f7e4fb.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/app/page-366fb7c078d4e9e0.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/cloud/link/page-fa1d5842aa90e8a6.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/complete-profile/page-dd64bbdf66b639cd.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-113060009ef35bc2.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/history/page-9965d2483011b846.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/layout-6b91e33784c20610.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/login/page-435eceb0073be027.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/metrics/page-1e37ef8e73940b40.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/page-8119d4246743574e.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/pricing/page-9db3ebdfa567a7c9.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/providers/page-ecb16ffd3b36262b.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/providers/setup/[provider]/page-4dbe33f0f7691b7c.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/app/signup/page-c7a0a28341365ae0.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/e868780c-48e5f147c90a3a41.js +0 -18
- package/dist/dashboard/out/_next/static/chunks/fd9d1056-609918ca7b6280bb.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/framework-f66176bb897dc684.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/main-311c3db74dcfadb7.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/main-app-fdbeb09028f57c9f.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/pages/_app-72b849fbd24ac258.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/pages/_error-7ba65e1336b92748.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
- package/dist/dashboard/out/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +0 -1
- package/dist/dashboard/out/_next/static/css/4034f236dd1a3178.css +0 -1
- package/dist/dashboard/out/_next/static/css/6892f8422896ef7a.css +0 -1
- package/dist/dashboard/out/alt-logos/agent-relay-logo-128.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-256.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-32.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-512.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo-64.png +0 -0
- package/dist/dashboard/out/alt-logos/agent-relay-logo.svg +0 -45
- package/dist/dashboard/out/alt-logos/logo.svg +0 -38
- package/dist/dashboard/out/alt-logos/monogram-logo-128.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-256.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-32.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-512.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo-64.png +0 -0
- package/dist/dashboard/out/alt-logos/monogram-logo.svg +0 -38
- package/dist/dashboard/out/app/onboarding.html +0 -1
- package/dist/dashboard/out/app/onboarding.txt +0 -7
- package/dist/dashboard/out/app.html +0 -1
- package/dist/dashboard/out/app.txt +0 -7
- package/dist/dashboard/out/apple-icon.png +0 -0
- package/dist/dashboard/out/cloud/link.html +0 -1
- package/dist/dashboard/out/cloud/link.txt +0 -7
- package/dist/dashboard/out/complete-profile.html +0 -5
- package/dist/dashboard/out/complete-profile.txt +0 -7
- package/dist/dashboard/out/connect-repos.html +0 -1
- package/dist/dashboard/out/connect-repos.txt +0 -7
- package/dist/dashboard/out/history.html +0 -1
- package/dist/dashboard/out/history.txt +0 -7
- package/dist/dashboard/out/index.html +0 -1
- package/dist/dashboard/out/index.txt +0 -7
- package/dist/dashboard/out/login.html +0 -5
- package/dist/dashboard/out/login.txt +0 -7
- package/dist/dashboard/out/metrics.html +0 -1
- package/dist/dashboard/out/metrics.txt +0 -7
- package/dist/dashboard/out/pricing.html +0 -13
- package/dist/dashboard/out/pricing.txt +0 -7
- package/dist/dashboard/out/providers/setup/claude.html +0 -1
- package/dist/dashboard/out/providers/setup/claude.txt +0 -8
- package/dist/dashboard/out/providers/setup/codex.html +0 -1
- package/dist/dashboard/out/providers/setup/codex.txt +0 -8
- package/dist/dashboard/out/providers/setup/cursor.html +0 -1
- package/dist/dashboard/out/providers/setup/cursor.txt +0 -8
- package/dist/dashboard/out/providers.html +0 -1
- package/dist/dashboard/out/providers.txt +0 -7
- package/dist/dashboard/out/signup.html +0 -6
- package/dist/dashboard/out/signup.txt +0 -7
- package/dist/src/dashboard-server/index.d.ts +0 -8
- package/dist/src/dashboard-server/index.js +0 -8
- package/packages/dashboard/README.md +0 -48
- package/packages/dashboard/dist/health-worker-manager.d.ts +0 -62
- package/packages/dashboard/dist/health-worker-manager.js +0 -144
- package/packages/dashboard/dist/health-worker.d.ts +0 -9
- package/packages/dashboard/dist/health-worker.js +0 -79
- package/packages/dashboard/dist/index.d.ts +0 -20
- package/packages/dashboard/dist/index.js +0 -19
- package/packages/dashboard/dist/metrics.d.ts +0 -105
- package/packages/dashboard/dist/metrics.js +0 -193
- package/packages/dashboard/dist/needs-attention.d.ts +0 -24
- package/packages/dashboard/dist/needs-attention.js +0 -78
- package/packages/dashboard/dist/server.d.ts +0 -25
- package/packages/dashboard/dist/server.js +0 -5270
- package/packages/dashboard/dist/start.d.ts +0 -6
- package/packages/dashboard/dist/start.js +0 -13
- package/packages/dashboard/dist/types/threading.d.ts +0 -8
- package/packages/dashboard/dist/types/threading.js +0 -2
- package/packages/dashboard/dist/user-bridge.d.ts +0 -154
- package/packages/dashboard/dist/user-bridge.js +0 -372
- package/packages/dashboard/package.json +0 -65
- package/packages/dashboard/ui/app/app/onboarding/page.tsx +0 -394
- package/packages/dashboard/ui/app/app/page.tsx +0 -667
- package/packages/dashboard/ui/app/apple-icon.png +0 -0
- package/packages/dashboard/ui/app/cloud/link/page.tsx +0 -464
- package/packages/dashboard/ui/app/complete-profile/page.tsx +0 -204
- package/packages/dashboard/ui/app/connect-repos/page.tsx +0 -410
- package/packages/dashboard/ui/app/favicon.png +0 -0
- package/packages/dashboard/ui/app/globals.css +0 -59
- package/packages/dashboard/ui/app/history/page.tsx +0 -658
- package/packages/dashboard/ui/app/layout.tsx +0 -25
- package/packages/dashboard/ui/app/login/page.tsx +0 -424
- package/packages/dashboard/ui/app/metrics/page.tsx +0 -751
- package/packages/dashboard/ui/app/page.tsx +0 -59
- package/packages/dashboard/ui/app/pricing/page.tsx +0 -7
- package/packages/dashboard/ui/app/providers/page.tsx +0 -193
- package/packages/dashboard/ui/app/providers/setup/[provider]/ProviderSetupClient.tsx +0 -148
- package/packages/dashboard/ui/app/providers/setup/[provider]/constants.ts +0 -35
- package/packages/dashboard/ui/app/providers/setup/[provider]/page.tsx +0 -42
- package/packages/dashboard/ui/app/signup/page.tsx +0 -533
- package/packages/dashboard/ui/index.ts +0 -49
- package/packages/dashboard/ui/landing/LandingPage.tsx +0 -713
- package/packages/dashboard/ui/landing/PricingPage.tsx +0 -559
- package/packages/dashboard/ui/landing/index.ts +0 -6
- package/packages/dashboard/ui/landing/styles.css +0 -2850
- package/packages/dashboard/ui/lib/agent-merge.ts +0 -35
- package/packages/dashboard/ui/lib/api.ts +0 -1155
- package/packages/dashboard/ui/lib/cloudApi.ts +0 -877
- package/packages/dashboard/ui/lib/colors.ts +0 -218
- package/packages/dashboard/ui/lib/hierarchy.ts +0 -242
- package/packages/dashboard/ui/lib/stuckDetection.ts +0 -142
- package/packages/dashboard/ui/next-env.d.ts +0 -5
- package/packages/dashboard/ui/next.config.js +0 -41
- package/packages/dashboard/ui/package-lock.json +0 -2882
- package/packages/dashboard/ui/package.json +0 -33
- package/packages/dashboard/ui/postcss.config.js +0 -5
- package/packages/dashboard/ui/react-components/ActivityFeed.tsx +0 -216
- package/packages/dashboard/ui/react-components/AddWorkspaceModal.tsx +0 -170
- package/packages/dashboard/ui/react-components/AgentCard.tsx +0 -587
- package/packages/dashboard/ui/react-components/AgentList.tsx +0 -411
- package/packages/dashboard/ui/react-components/AgentProfilePanel.tsx +0 -564
- package/packages/dashboard/ui/react-components/App.tsx +0 -3033
- package/packages/dashboard/ui/react-components/BillingPanel.tsx +0 -922
- package/packages/dashboard/ui/react-components/BillingResult.tsx +0 -447
- package/packages/dashboard/ui/react-components/BroadcastComposer.tsx +0 -690
- package/packages/dashboard/ui/react-components/ChannelAdminPanel.tsx +0 -773
- package/packages/dashboard/ui/react-components/ChannelBrowser.tsx +0 -385
- package/packages/dashboard/ui/react-components/ChannelChat.tsx +0 -261
- package/packages/dashboard/ui/react-components/ChannelSidebar.tsx +0 -399
- package/packages/dashboard/ui/react-components/CloudSessionProvider.tsx +0 -130
- package/packages/dashboard/ui/react-components/CommandPalette.tsx +0 -815
- package/packages/dashboard/ui/react-components/ConfirmationDialog.tsx +0 -133
- package/packages/dashboard/ui/react-components/ConversationHistory.tsx +0 -518
- package/packages/dashboard/ui/react-components/CoordinatorPanel.tsx +0 -944
- package/packages/dashboard/ui/react-components/DecisionQueue.tsx +0 -717
- package/packages/dashboard/ui/react-components/DirectMessageView.tsx +0 -164
- package/packages/dashboard/ui/react-components/FileAutocomplete.tsx +0 -368
- package/packages/dashboard/ui/react-components/FleetOverview.tsx +0 -278
- package/packages/dashboard/ui/react-components/LogViewer.tsx +0 -310
- package/packages/dashboard/ui/react-components/LogViewerPanel.tsx +0 -482
- package/packages/dashboard/ui/react-components/Logo.tsx +0 -284
- package/packages/dashboard/ui/react-components/MentionAutocomplete.tsx +0 -384
- package/packages/dashboard/ui/react-components/MessageComposer.tsx +0 -457
- package/packages/dashboard/ui/react-components/MessageList.tsx +0 -649
- package/packages/dashboard/ui/react-components/MessageSenderName.tsx +0 -91
- package/packages/dashboard/ui/react-components/MessageStatusIndicator.tsx +0 -142
- package/packages/dashboard/ui/react-components/NewConversationModal.tsx +0 -400
- package/packages/dashboard/ui/react-components/NotificationToast.tsx +0 -488
- package/packages/dashboard/ui/react-components/OnlineUsersIndicator.tsx +0 -164
- package/packages/dashboard/ui/react-components/Pagination.tsx +0 -124
- package/packages/dashboard/ui/react-components/PricingPlans.tsx +0 -386
- package/packages/dashboard/ui/react-components/ProjectList.tsx +0 -625
- package/packages/dashboard/ui/react-components/ProviderAuthFlow.tsx +0 -853
- package/packages/dashboard/ui/react-components/ProviderConnectionList.tsx +0 -378
- package/packages/dashboard/ui/react-components/ProvisioningProgress.tsx +0 -730
- package/packages/dashboard/ui/react-components/RepoAccessPanel.tsx +0 -549
- package/packages/dashboard/ui/react-components/ServerCard.tsx +0 -202
- package/packages/dashboard/ui/react-components/SessionExpiredModal.tsx +0 -128
- package/packages/dashboard/ui/react-components/SpawnModal.tsx +0 -804
- package/packages/dashboard/ui/react-components/TaskAssignmentUI.tsx +0 -375
- package/packages/dashboard/ui/react-components/TerminalProviderSetup.tsx +0 -608
- package/packages/dashboard/ui/react-components/ThemeProvider.tsx +0 -325
- package/packages/dashboard/ui/react-components/ThinkingIndicator.tsx +0 -231
- package/packages/dashboard/ui/react-components/ThreadList.tsx +0 -198
- package/packages/dashboard/ui/react-components/ThreadPanel.tsx +0 -346
- package/packages/dashboard/ui/react-components/TrajectoryViewer.tsx +0 -698
- package/packages/dashboard/ui/react-components/TypingIndicator.tsx +0 -69
- package/packages/dashboard/ui/react-components/UsageBanner.tsx +0 -231
- package/packages/dashboard/ui/react-components/UserProfilePanel.tsx +0 -233
- package/packages/dashboard/ui/react-components/WorkspaceContext.tsx +0 -107
- package/packages/dashboard/ui/react-components/WorkspaceSelector.tsx +0 -234
- package/packages/dashboard/ui/react-components/WorkspaceStatusIndicator.tsx +0 -370
- package/packages/dashboard/ui/react-components/XTermInteractive.tsx +0 -510
- package/packages/dashboard/ui/react-components/XTermLogViewer.tsx +0 -719
- package/packages/dashboard/ui/react-components/channels/ChannelDialogs.tsx +0 -1411
- package/packages/dashboard/ui/react-components/channels/ChannelHeader.tsx +0 -317
- package/packages/dashboard/ui/react-components/channels/ChannelMessageList.tsx +0 -463
- package/packages/dashboard/ui/react-components/channels/ChannelViewV1.tsx +0 -146
- package/packages/dashboard/ui/react-components/channels/MessageInput.tsx +0 -288
- package/packages/dashboard/ui/react-components/channels/SearchInput.tsx +0 -172
- package/packages/dashboard/ui/react-components/channels/SearchResults.tsx +0 -336
- package/packages/dashboard/ui/react-components/channels/api.ts +0 -697
- package/packages/dashboard/ui/react-components/channels/index.ts +0 -76
- package/packages/dashboard/ui/react-components/channels/mockApi.ts +0 -344
- package/packages/dashboard/ui/react-components/channels/types.ts +0 -566
- package/packages/dashboard/ui/react-components/hooks/index.ts +0 -57
- package/packages/dashboard/ui/react-components/hooks/useAgentLogs.ts +0 -394
- package/packages/dashboard/ui/react-components/hooks/useAgents.ts +0 -127
- package/packages/dashboard/ui/react-components/hooks/useBroadcastDedup.ts +0 -86
- package/packages/dashboard/ui/react-components/hooks/useChannelAdmin.ts +0 -329
- package/packages/dashboard/ui/react-components/hooks/useChannelBrowser.ts +0 -239
- package/packages/dashboard/ui/react-components/hooks/useChannelCommands.ts +0 -138
- package/packages/dashboard/ui/react-components/hooks/useChannels.ts +0 -328
- package/packages/dashboard/ui/react-components/hooks/useDebounce.ts +0 -29
- package/packages/dashboard/ui/react-components/hooks/useDirectMessage.ts +0 -141
- package/packages/dashboard/ui/react-components/hooks/useMessages.ts +0 -309
- package/packages/dashboard/ui/react-components/hooks/useOrchestrator.ts +0 -364
- package/packages/dashboard/ui/react-components/hooks/usePinnedAgents.ts +0 -140
- package/packages/dashboard/ui/react-components/hooks/usePresence.ts +0 -340
- package/packages/dashboard/ui/react-components/hooks/useRecentRepos.ts +0 -130
- package/packages/dashboard/ui/react-components/hooks/useSession.ts +0 -209
- package/packages/dashboard/ui/react-components/hooks/useTrajectory.ts +0 -265
- package/packages/dashboard/ui/react-components/hooks/useWebSocket.ts +0 -169
- package/packages/dashboard/ui/react-components/hooks/useWorkspaceMembers.ts +0 -120
- package/packages/dashboard/ui/react-components/hooks/useWorkspaceRepos.ts +0 -73
- package/packages/dashboard/ui/react-components/hooks/useWorkspaceStatus.ts +0 -237
- package/packages/dashboard/ui/react-components/index.ts +0 -81
- package/packages/dashboard/ui/react-components/layout/Header.tsx +0 -355
- package/packages/dashboard/ui/react-components/layout/RepoContextHeader.tsx +0 -361
- package/packages/dashboard/ui/react-components/layout/Sidebar.archive.test.tsx +0 -126
- package/packages/dashboard/ui/react-components/layout/Sidebar.test.tsx +0 -691
- package/packages/dashboard/ui/react-components/layout/Sidebar.tsx +0 -930
- package/packages/dashboard/ui/react-components/layout/index.ts +0 -7
- package/packages/dashboard/ui/react-components/settings/BillingSettingsPanel.tsx +0 -564
- package/packages/dashboard/ui/react-components/settings/SettingsPage.tsx +0 -544
- package/packages/dashboard/ui/react-components/settings/TeamSettingsPanel.tsx +0 -560
- package/packages/dashboard/ui/react-components/settings/WorkspaceSettingsPanel.tsx +0 -1386
- package/packages/dashboard/ui/react-components/settings/index.ts +0 -11
- package/packages/dashboard/ui/react-components/settings/types.ts +0 -53
- package/packages/dashboard/ui/react-components/utils/messageFormatting.tsx +0 -370
- package/packages/dashboard/ui/tailwind.config.js +0 -148
- package/packages/dashboard/ui/types/index.ts +0 -304
- package/packages/dashboard/ui/types/threading.ts +0 -7
- package/packages/dashboard/ui-dist/404.html +0 -1
- package/packages/dashboard/ui-dist/_next/static/7MZPqYkVGw3EGzVBkVmY9/_buildManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/7MZPqYkVGw3EGzVBkVmY9/_ssgManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/116-a883fca163f3a5bc.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/117-c8afed19e821a35d.js +0 -2
- package/packages/dashboard/ui-dist/_next/static/chunks/282-980c2eb8fff20123.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/320-a6304232cd0ee2ce.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/532-bace199897eeab37.js +0 -9
- package/packages/dashboard/ui-dist/_next/static/chunks/631-16b905e5920f9b59.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/648-acb2ff9f77cbfbd3.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/766-2aea80818f7eb0d8.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/83-26d2bde54616ee90.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/847-f1f467060f32afff.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/891-5cb1513eeb97a891.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/_not-found/page-60501fddbafba9dc.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/app/onboarding/page-9914652442f7e4fb.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/app/page-366fb7c078d4e9e0.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/cloud/link/page-fa1d5842aa90e8a6.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/complete-profile/page-dd64bbdf66b639cd.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/connect-repos/page-113060009ef35bc2.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/history/page-9965d2483011b846.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/layout-6b91e33784c20610.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/login/page-435eceb0073be027.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/metrics/page-1e37ef8e73940b40.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/page-8119d4246743574e.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/pricing/page-9db3ebdfa567a7c9.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/providers/page-ecb16ffd3b36262b.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/providers/setup/[provider]/page-4dbe33f0f7691b7c.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/app/signup/page-c7a0a28341365ae0.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/e868780c-48e5f147c90a3a41.js +0 -18
- package/packages/dashboard/ui-dist/_next/static/chunks/fd9d1056-609918ca7b6280bb.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/framework-f66176bb897dc684.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/main-311c3db74dcfadb7.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/main-app-fdbeb09028f57c9f.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/pages/_app-72b849fbd24ac258.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/pages/_error-7ba65e1336b92748.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/css/4034f236dd1a3178.css +0 -1
- package/packages/dashboard/ui-dist/_next/static/css/6892f8422896ef7a.css +0 -1
- package/packages/dashboard/ui-dist/_next/static/iJ3Uiz3IrqUJL7IxKZHiV/_buildManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/iJ3Uiz3IrqUJL7IxKZHiV/_ssgManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/l-jd878zUJ_IlraqEWMZc/_buildManifest.js +0 -1
- package/packages/dashboard/ui-dist/_next/static/l-jd878zUJ_IlraqEWMZc/_ssgManifest.js +0 -1
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-128.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-256.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-32.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-512.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-64.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo.svg +0 -45
- package/packages/dashboard/ui-dist/alt-logos/logo.svg +0 -38
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-128.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-256.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-32.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-512.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo-64.png +0 -0
- package/packages/dashboard/ui-dist/alt-logos/monogram-logo.svg +0 -38
- package/packages/dashboard/ui-dist/app/onboarding.html +0 -1
- package/packages/dashboard/ui-dist/app/onboarding.txt +0 -7
- package/packages/dashboard/ui-dist/app.html +0 -1
- package/packages/dashboard/ui-dist/app.txt +0 -7
- package/packages/dashboard/ui-dist/apple-icon.png +0 -0
- package/packages/dashboard/ui-dist/cloud/link.html +0 -1
- package/packages/dashboard/ui-dist/cloud/link.txt +0 -7
- package/packages/dashboard/ui-dist/complete-profile.html +0 -5
- package/packages/dashboard/ui-dist/complete-profile.txt +0 -7
- package/packages/dashboard/ui-dist/connect-repos.html +0 -1
- package/packages/dashboard/ui-dist/connect-repos.txt +0 -7
- package/packages/dashboard/ui-dist/history.html +0 -1
- package/packages/dashboard/ui-dist/history.txt +0 -7
- package/packages/dashboard/ui-dist/index.html +0 -1
- package/packages/dashboard/ui-dist/index.txt +0 -7
- package/packages/dashboard/ui-dist/login.html +0 -5
- package/packages/dashboard/ui-dist/login.txt +0 -7
- package/packages/dashboard/ui-dist/metrics.html +0 -1
- package/packages/dashboard/ui-dist/metrics.txt +0 -7
- package/packages/dashboard/ui-dist/pricing.html +0 -13
- package/packages/dashboard/ui-dist/pricing.txt +0 -7
- package/packages/dashboard/ui-dist/providers/setup/claude.html +0 -1
- package/packages/dashboard/ui-dist/providers/setup/claude.txt +0 -8
- package/packages/dashboard/ui-dist/providers/setup/codex.html +0 -1
- package/packages/dashboard/ui-dist/providers/setup/codex.txt +0 -8
- package/packages/dashboard/ui-dist/providers/setup/cursor.html +0 -1
- package/packages/dashboard/ui-dist/providers/setup/cursor.txt +0 -8
- package/packages/dashboard/ui-dist/providers.html +0 -1
- package/packages/dashboard/ui-dist/providers.txt +0 -7
- package/packages/dashboard/ui-dist/signup.html +0 -6
- package/packages/dashboard/ui-dist/signup.txt +0 -7
- package/packages/dashboard-server/dist/health-worker-manager.d.ts +0 -62
- package/packages/dashboard-server/dist/health-worker-manager.js +0 -144
- package/packages/dashboard-server/dist/health-worker.d.ts +0 -9
- package/packages/dashboard-server/dist/health-worker.js +0 -79
- package/packages/dashboard-server/dist/index.d.ts +0 -18
- package/packages/dashboard-server/dist/index.js +0 -17
- package/packages/dashboard-server/dist/metrics.d.ts +0 -105
- package/packages/dashboard-server/dist/metrics.js +0 -193
- package/packages/dashboard-server/dist/needs-attention.d.ts +0 -24
- package/packages/dashboard-server/dist/needs-attention.js +0 -78
- package/packages/dashboard-server/dist/server.d.ts +0 -25
- package/packages/dashboard-server/dist/server.js +0 -5158
- package/packages/dashboard-server/dist/start.d.ts +0 -6
- package/packages/dashboard-server/dist/start.js +0 -13
- package/packages/dashboard-server/dist/types/threading.d.ts +0 -8
- package/packages/dashboard-server/dist/types/threading.js +0 -2
- package/packages/dashboard-server/dist/user-bridge.d.ts +0 -158
- package/packages/dashboard-server/dist/user-bridge.js +0 -390
- package/packages/dashboard-server/package.json +0 -55
|
@@ -1,649 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MessageList Component - Mission Control Theme
|
|
3
|
-
*
|
|
4
|
-
* Displays a list of messages with threading support,
|
|
5
|
-
* provider-colored icons, and From → To format.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import React, { useRef, useEffect, useLayoutEffect, useState, useCallback } from 'react';
|
|
9
|
-
import { ACTIVITY_FEED_ID } from './App';
|
|
10
|
-
import type { Message, Agent, Attachment } from '../types';
|
|
11
|
-
import type { UserPresence } from './hooks/usePresence';
|
|
12
|
-
import { MessageStatusIndicator } from './MessageStatusIndicator';
|
|
13
|
-
import { ThinkingIndicator } from './ThinkingIndicator';
|
|
14
|
-
import { deduplicateBroadcasts } from './hooks/useBroadcastDedup';
|
|
15
|
-
import { MessageSenderName } from './MessageSenderName';
|
|
16
|
-
import { formatMessageBody } from './utils/messageFormatting';
|
|
17
|
-
|
|
18
|
-
// Provider icons and colors matching landing page
|
|
19
|
-
const PROVIDER_CONFIG: Record<string, { icon: string; color: string }> = {
|
|
20
|
-
claude: { icon: '◈', color: '#00d9ff' },
|
|
21
|
-
codex: { icon: '⬡', color: '#ff6b35' },
|
|
22
|
-
gemini: { icon: '◇', color: '#a855f7' },
|
|
23
|
-
openai: { icon: '◆', color: '#10a37f' },
|
|
24
|
-
default: { icon: '●', color: '#00d9ff' },
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
// Get provider config from agent name (heuristic-based)
|
|
28
|
-
function getProviderConfig(agentName: string): { icon: string; color: string } {
|
|
29
|
-
const nameLower = agentName.toLowerCase();
|
|
30
|
-
if (nameLower.includes('claude') || nameLower.includes('anthropic')) {
|
|
31
|
-
return PROVIDER_CONFIG.claude;
|
|
32
|
-
}
|
|
33
|
-
if (nameLower.includes('codex') || nameLower.includes('openai') || nameLower.includes('gpt')) {
|
|
34
|
-
return PROVIDER_CONFIG.codex;
|
|
35
|
-
}
|
|
36
|
-
if (nameLower.includes('gemini') || nameLower.includes('google') || nameLower.includes('bard')) {
|
|
37
|
-
return PROVIDER_CONFIG.gemini;
|
|
38
|
-
}
|
|
39
|
-
// Default: cycle through colors based on name hash
|
|
40
|
-
const hash = agentName.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
|
|
41
|
-
const providers = Object.keys(PROVIDER_CONFIG).filter((k) => k !== 'default');
|
|
42
|
-
const provider = providers[hash % providers.length];
|
|
43
|
-
return PROVIDER_CONFIG[provider];
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** Current user info for displaying avatar/username */
|
|
47
|
-
export interface CurrentUser {
|
|
48
|
-
displayName: string;
|
|
49
|
-
avatarUrl?: string;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export interface MessageListProps {
|
|
53
|
-
messages: Message[];
|
|
54
|
-
currentChannel: string;
|
|
55
|
-
onThreadClick?: (messageId: string) => void;
|
|
56
|
-
highlightedMessageId?: string;
|
|
57
|
-
/** Currently selected thread ID - when set, shows thread-related messages */
|
|
58
|
-
currentThread?: string | null;
|
|
59
|
-
/** Agents list for checking processing state */
|
|
60
|
-
agents?: Agent[];
|
|
61
|
-
/** Current user info (for cloud mode - shows avatar/username instead of "Dashboard") */
|
|
62
|
-
currentUser?: CurrentUser;
|
|
63
|
-
/** Skip channel filtering - messages are already filtered (for DM views) */
|
|
64
|
-
skipChannelFilter?: boolean;
|
|
65
|
-
/** Default auto-scroll preference */
|
|
66
|
-
autoScrollDefault?: boolean;
|
|
67
|
-
/** Show timestamps in message header */
|
|
68
|
-
showTimestamps?: boolean;
|
|
69
|
-
/** Compact spacing for dense layouts */
|
|
70
|
-
compactMode?: boolean;
|
|
71
|
-
/** Callback when an agent name is clicked to open profile */
|
|
72
|
-
onAgentClick?: (agent: Agent) => void;
|
|
73
|
-
/** Callback when a human user name is clicked to open profile */
|
|
74
|
-
onUserClick?: (user: UserPresence) => void;
|
|
75
|
-
/** Online users list for profile lookup */
|
|
76
|
-
onlineUsers?: UserPresence[];
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function MessageList({
|
|
80
|
-
messages,
|
|
81
|
-
currentChannel,
|
|
82
|
-
onThreadClick,
|
|
83
|
-
highlightedMessageId,
|
|
84
|
-
currentThread,
|
|
85
|
-
agents = [],
|
|
86
|
-
currentUser,
|
|
87
|
-
skipChannelFilter = false,
|
|
88
|
-
autoScrollDefault = true,
|
|
89
|
-
showTimestamps = true,
|
|
90
|
-
compactMode = false,
|
|
91
|
-
onAgentClick,
|
|
92
|
-
onUserClick,
|
|
93
|
-
onlineUsers = [],
|
|
94
|
-
}: MessageListProps) {
|
|
95
|
-
// Build a map of agent name -> processing state for quick lookup
|
|
96
|
-
const processingAgents = new Map<string, { isProcessing: boolean; processingStartedAt?: number }>();
|
|
97
|
-
for (const agent of agents) {
|
|
98
|
-
if (agent.isProcessing) {
|
|
99
|
-
processingAgents.set(agent.name, {
|
|
100
|
-
isProcessing: true,
|
|
101
|
-
processingStartedAt: agent.processingStartedAt,
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// Build a map of recipient -> latest message ID from current user
|
|
107
|
-
// This is used to only show the thinking indicator on the most recent message
|
|
108
|
-
const latestMessageToAgent = new Map<string, string>();
|
|
109
|
-
const scrollContainerRef = useRef<HTMLDivElement>(null);
|
|
110
|
-
const [autoScroll, setAutoScroll] = useState(autoScrollDefault);
|
|
111
|
-
const prevFilteredLengthRef = useRef<number>(0);
|
|
112
|
-
const prevChannelRef = useRef<string>(currentChannel);
|
|
113
|
-
// Track if we should scroll on next render (set before DOM updates)
|
|
114
|
-
const shouldScrollRef = useRef(false);
|
|
115
|
-
// Track if a scroll is in progress to prevent race conditions
|
|
116
|
-
const isScrollingRef = useRef(false);
|
|
117
|
-
|
|
118
|
-
useEffect(() => {
|
|
119
|
-
setAutoScroll(autoScrollDefault);
|
|
120
|
-
}, [autoScrollDefault]);
|
|
121
|
-
|
|
122
|
-
// Filter messages for current channel or current thread
|
|
123
|
-
const channelFilteredMessages = messages.filter((msg) => {
|
|
124
|
-
// When a thread is selected, show messages related to that thread
|
|
125
|
-
if (currentThread) {
|
|
126
|
-
// Show the original message (id matches thread) or replies (thread field matches)
|
|
127
|
-
return msg.id === currentThread || msg.thread === currentThread;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Skip channel filtering if messages are already filtered (e.g., DM views)
|
|
131
|
-
if (skipChannelFilter) {
|
|
132
|
-
return true;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// Activity feed shows broadcasts
|
|
136
|
-
if (currentChannel === ACTIVITY_FEED_ID) {
|
|
137
|
-
return msg.to === '*' || msg.isBroadcast;
|
|
138
|
-
}
|
|
139
|
-
// #general channel shows only actual channel messages (not broadcasts)
|
|
140
|
-
if (currentChannel === 'general' || currentChannel === '#general') {
|
|
141
|
-
return msg.channel === 'general' || msg.channel === '#general' ||
|
|
142
|
-
msg.to === '#general' || msg.to === 'general';
|
|
143
|
-
}
|
|
144
|
-
return msg.from === currentChannel || msg.to === currentChannel;
|
|
145
|
-
});
|
|
146
|
-
|
|
147
|
-
// Deduplicate broadcast messages in Activity feed
|
|
148
|
-
// When a broadcast is sent to '*', the backend delivers it to each recipient separately,
|
|
149
|
-
// causing the same message to appear multiple times. Deduplication removes duplicates
|
|
150
|
-
// by grouping broadcasts with the same sender, content, and timestamp.
|
|
151
|
-
const filteredMessages = currentChannel === ACTIVITY_FEED_ID
|
|
152
|
-
? deduplicateBroadcasts(channelFilteredMessages)
|
|
153
|
-
: channelFilteredMessages;
|
|
154
|
-
|
|
155
|
-
// Populate latestMessageToAgent with the latest message from current user to each agent
|
|
156
|
-
// Iterate in order (oldest to newest) so the last one wins
|
|
157
|
-
for (const msg of filteredMessages) {
|
|
158
|
-
const isFromCurrentUser = msg.from === 'Dashboard' ||
|
|
159
|
-
(currentUser && msg.from === currentUser.displayName);
|
|
160
|
-
if (isFromCurrentUser && msg.to !== '*') {
|
|
161
|
-
latestMessageToAgent.set(msg.to, msg.id);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const autoScrollAllowed = autoScrollDefault;
|
|
166
|
-
|
|
167
|
-
// Check if we need to scroll BEFORE the DOM updates
|
|
168
|
-
// This runs during render, before useLayoutEffect
|
|
169
|
-
const currentLength = filteredMessages.length;
|
|
170
|
-
if (currentLength > prevFilteredLengthRef.current) {
|
|
171
|
-
// Check if the latest message is from the current user
|
|
172
|
-
// This includes both "Dashboard" (local mode) and GitHub username (cloud mode)
|
|
173
|
-
// Scroll for user's own messages only when auto-scroll is enabled
|
|
174
|
-
const latestMessage = filteredMessages[filteredMessages.length - 1];
|
|
175
|
-
const latestIsFromUser = latestMessage?.from === 'Dashboard' ||
|
|
176
|
-
(currentUser && latestMessage?.from === currentUser.displayName);
|
|
177
|
-
|
|
178
|
-
if (autoScrollAllowed && (latestIsFromUser || autoScroll)) {
|
|
179
|
-
shouldScrollRef.current = true;
|
|
180
|
-
// Re-enable auto-scroll if we're scrolling for user's message
|
|
181
|
-
// This ensures continued auto-scroll after user sends a message
|
|
182
|
-
if (latestIsFromUser && !autoScroll) {
|
|
183
|
-
setAutoScroll(true);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
prevFilteredLengthRef.current = currentLength;
|
|
188
|
-
|
|
189
|
-
// Handle scroll to detect manual scroll (disable/enable auto-scroll)
|
|
190
|
-
const handleScroll = useCallback(() => {
|
|
191
|
-
if (!scrollContainerRef.current) return;
|
|
192
|
-
// Skip scroll events that happen during programmatic scrolling
|
|
193
|
-
if (isScrollingRef.current) return;
|
|
194
|
-
if (!autoScrollDefault) return;
|
|
195
|
-
|
|
196
|
-
const container = scrollContainerRef.current;
|
|
197
|
-
const distanceFromBottom = container.scrollHeight - container.scrollTop - container.clientHeight;
|
|
198
|
-
const isAtBottom = distanceFromBottom < 50;
|
|
199
|
-
|
|
200
|
-
// Re-enable auto-scroll when user scrolls to bottom
|
|
201
|
-
if (isAtBottom && !autoScroll) {
|
|
202
|
-
setAutoScroll(true);
|
|
203
|
-
}
|
|
204
|
-
// Disable auto-scroll when user scrolls significantly away from bottom
|
|
205
|
-
// Use a larger threshold to avoid false disables from small layout shifts
|
|
206
|
-
else if (distanceFromBottom > 150 && autoScroll) {
|
|
207
|
-
setAutoScroll(false);
|
|
208
|
-
}
|
|
209
|
-
}, [autoScroll]);
|
|
210
|
-
|
|
211
|
-
// Auto-scroll to bottom when new messages arrive - use useLayoutEffect for immediate execution
|
|
212
|
-
useLayoutEffect(() => {
|
|
213
|
-
if (shouldScrollRef.current && scrollContainerRef.current) {
|
|
214
|
-
shouldScrollRef.current = false;
|
|
215
|
-
isScrollingRef.current = true;
|
|
216
|
-
|
|
217
|
-
const container = scrollContainerRef.current;
|
|
218
|
-
container.scrollTop = container.scrollHeight;
|
|
219
|
-
|
|
220
|
-
// Clear the scrolling flag after the scroll event has been processed
|
|
221
|
-
requestAnimationFrame(() => {
|
|
222
|
-
setTimeout(() => {
|
|
223
|
-
isScrollingRef.current = false;
|
|
224
|
-
}, 50);
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
}, [filteredMessages.length]);
|
|
228
|
-
|
|
229
|
-
// Reset scroll position and auto-scroll when channel changes
|
|
230
|
-
useLayoutEffect(() => {
|
|
231
|
-
if (currentChannel !== prevChannelRef.current) {
|
|
232
|
-
prevChannelRef.current = currentChannel;
|
|
233
|
-
prevFilteredLengthRef.current = filteredMessages.length;
|
|
234
|
-
setAutoScroll(true);
|
|
235
|
-
|
|
236
|
-
// Scroll to bottom on channel change
|
|
237
|
-
if (scrollContainerRef.current) {
|
|
238
|
-
isScrollingRef.current = true;
|
|
239
|
-
const container = scrollContainerRef.current;
|
|
240
|
-
container.scrollTop = container.scrollHeight;
|
|
241
|
-
|
|
242
|
-
// Clear the scrolling flag after the scroll event has been processed
|
|
243
|
-
requestAnimationFrame(() => {
|
|
244
|
-
setTimeout(() => {
|
|
245
|
-
isScrollingRef.current = false;
|
|
246
|
-
}, 50);
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
}, [currentChannel, filteredMessages.length]);
|
|
251
|
-
|
|
252
|
-
if (filteredMessages.length === 0) {
|
|
253
|
-
return (
|
|
254
|
-
<div className="flex flex-col items-center justify-center h-full text-text-muted text-center">
|
|
255
|
-
<EmptyIcon />
|
|
256
|
-
<h3 className="m-0 mb-2 text-base font-display text-text-secondary">No messages yet</h3>
|
|
257
|
-
<p className="m-0 text-sm">
|
|
258
|
-
{currentChannel === 'general'
|
|
259
|
-
? 'Broadcast messages will appear here'
|
|
260
|
-
: `Messages with ${currentChannel} will appear here`}
|
|
261
|
-
</p>
|
|
262
|
-
</div>
|
|
263
|
-
);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
return (
|
|
267
|
-
<div
|
|
268
|
-
className={`flex flex-col bg-bg-secondary h-full overflow-y-auto ${
|
|
269
|
-
compactMode ? 'gap-0.5 p-1.5 sm:p-2' : 'gap-1 p-2 sm:p-4'
|
|
270
|
-
}`}
|
|
271
|
-
ref={scrollContainerRef}
|
|
272
|
-
onScroll={handleScroll}
|
|
273
|
-
>
|
|
274
|
-
{filteredMessages.map((message) => {
|
|
275
|
-
// Check if message is from current user (Dashboard or GitHub username)
|
|
276
|
-
const isFromCurrentUser = message.from === 'Dashboard' ||
|
|
277
|
-
(currentUser && message.from === currentUser.displayName);
|
|
278
|
-
|
|
279
|
-
// Check if this is the latest message from current user to this recipient
|
|
280
|
-
// Only the latest message should show the thinking indicator
|
|
281
|
-
const isLatestToRecipient = isFromCurrentUser && message.to !== '*' &&
|
|
282
|
-
latestMessageToAgent.get(message.to) === message.id;
|
|
283
|
-
|
|
284
|
-
// Check if the recipient is currently processing
|
|
285
|
-
// Only show thinking indicator for the LATEST message from current user to an agent
|
|
286
|
-
const recipientProcessing = isLatestToRecipient
|
|
287
|
-
? processingAgents.get(message.to)
|
|
288
|
-
: undefined;
|
|
289
|
-
|
|
290
|
-
return (
|
|
291
|
-
<MessageItem
|
|
292
|
-
key={message.id}
|
|
293
|
-
message={message}
|
|
294
|
-
isHighlighted={message.id === highlightedMessageId}
|
|
295
|
-
onThreadClick={onThreadClick}
|
|
296
|
-
recipientProcessing={recipientProcessing}
|
|
297
|
-
currentUser={currentUser}
|
|
298
|
-
showTimestamps={showTimestamps}
|
|
299
|
-
compactMode={compactMode}
|
|
300
|
-
agents={agents}
|
|
301
|
-
onlineUsers={onlineUsers}
|
|
302
|
-
onAgentClick={onAgentClick}
|
|
303
|
-
onUserClick={onUserClick}
|
|
304
|
-
/>
|
|
305
|
-
);
|
|
306
|
-
})}
|
|
307
|
-
</div>
|
|
308
|
-
);
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
interface MessageItemProps {
|
|
312
|
-
message: Message;
|
|
313
|
-
isHighlighted?: boolean;
|
|
314
|
-
onThreadClick?: (messageId: string) => void;
|
|
315
|
-
/** Processing state of the recipient agent (for showing thinking indicator) */
|
|
316
|
-
recipientProcessing?: { isProcessing: boolean; processingStartedAt?: number };
|
|
317
|
-
/** Current user info for displaying avatar/username */
|
|
318
|
-
currentUser?: CurrentUser;
|
|
319
|
-
showTimestamps?: boolean;
|
|
320
|
-
compactMode?: boolean;
|
|
321
|
-
/** All agents for name lookup */
|
|
322
|
-
agents?: Agent[];
|
|
323
|
-
/** Online users for profile lookup */
|
|
324
|
-
onlineUsers?: UserPresence[];
|
|
325
|
-
/** Callback when an agent name is clicked */
|
|
326
|
-
onAgentClick?: (agent: Agent) => void;
|
|
327
|
-
/** Callback when a user name is clicked */
|
|
328
|
-
onUserClick?: (user: UserPresence) => void;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
function MessageItem({
|
|
332
|
-
message,
|
|
333
|
-
isHighlighted,
|
|
334
|
-
onThreadClick,
|
|
335
|
-
recipientProcessing,
|
|
336
|
-
currentUser,
|
|
337
|
-
showTimestamps = true,
|
|
338
|
-
compactMode = false,
|
|
339
|
-
agents = [],
|
|
340
|
-
onlineUsers = [],
|
|
341
|
-
onAgentClick,
|
|
342
|
-
onUserClick,
|
|
343
|
-
}: MessageItemProps) {
|
|
344
|
-
const timestamp = formatTimestamp(message.timestamp);
|
|
345
|
-
|
|
346
|
-
// Check if this message is from the current user (Dashboard or their GitHub username)
|
|
347
|
-
const isFromCurrentUser = message.from === 'Dashboard' ||
|
|
348
|
-
(currentUser && message.from === currentUser.displayName);
|
|
349
|
-
|
|
350
|
-
// Get provider config for agent messages, or use user styling for current user
|
|
351
|
-
const provider = isFromCurrentUser && currentUser
|
|
352
|
-
? { icon: '', color: '#a855f7' } // Purple for user messages
|
|
353
|
-
: getProviderConfig(message.from);
|
|
354
|
-
|
|
355
|
-
// Display name: use GitHub username if available, otherwise message.from
|
|
356
|
-
const displayName = isFromCurrentUser && currentUser
|
|
357
|
-
? currentUser.displayName
|
|
358
|
-
: message.from;
|
|
359
|
-
const replyCount = message.threadSummary?.replyCount ?? message.replyCount ?? 0;
|
|
360
|
-
const hasReplies = replyCount > 0;
|
|
361
|
-
|
|
362
|
-
// Look up agent or user for sender (for clickable profile)
|
|
363
|
-
const senderAgent = agents.find(a => a.name.toLowerCase() === message.from.toLowerCase() && !a.isHuman);
|
|
364
|
-
const senderUser = onlineUsers.find(u => u.username.toLowerCase() === message.from.toLowerCase());
|
|
365
|
-
|
|
366
|
-
// Look up agent or user for recipient (for clickable profile)
|
|
367
|
-
const recipientAgent = message.to !== '*' ? agents.find(a => a.name.toLowerCase() === message.to.toLowerCase() && !a.isHuman) : undefined;
|
|
368
|
-
const recipientUser = message.to !== '*' ? onlineUsers.find(u => u.username.toLowerCase() === message.to.toLowerCase()) : undefined;
|
|
369
|
-
const recipientProviderConfig = recipientAgent ? getProviderConfig(message.to) : undefined;
|
|
370
|
-
|
|
371
|
-
// Show thinking indicator when:
|
|
372
|
-
// 1. Message is from Dashboard or current user (user sent it)
|
|
373
|
-
// 2. Message has been delivered (acked)
|
|
374
|
-
// 3. Recipient is currently processing
|
|
375
|
-
const showThinking = isFromCurrentUser &&
|
|
376
|
-
(message.status === 'acked' || message.status === 'read') &&
|
|
377
|
-
recipientProcessing?.isProcessing;
|
|
378
|
-
|
|
379
|
-
return (
|
|
380
|
-
<div
|
|
381
|
-
className={`
|
|
382
|
-
group flex rounded-xl transition-all duration-150
|
|
383
|
-
${compactMode ? 'gap-2 py-1.5 px-2' : 'gap-2 sm:gap-3 py-2 sm:py-3 px-2 sm:px-4'}
|
|
384
|
-
hover:bg-bg-card/50
|
|
385
|
-
${isHighlighted ? 'bg-warning-light/20 border-l-2 border-l-warning pl-2 sm:pl-3' : ''}
|
|
386
|
-
`}
|
|
387
|
-
>
|
|
388
|
-
{/* Avatar/Icon */}
|
|
389
|
-
{isFromCurrentUser && currentUser?.avatarUrl ? (
|
|
390
|
-
<img
|
|
391
|
-
src={currentUser.avatarUrl}
|
|
392
|
-
alt={displayName}
|
|
393
|
-
className={`shrink-0 rounded-lg sm:rounded-xl border-2 object-cover ${
|
|
394
|
-
compactMode ? 'w-7 h-7 sm:w-8 sm:h-8' : 'w-8 h-8 sm:w-10 sm:h-10'
|
|
395
|
-
}`}
|
|
396
|
-
style={{
|
|
397
|
-
borderColor: provider.color,
|
|
398
|
-
boxShadow: `0 0 16px ${provider.color}30`,
|
|
399
|
-
}}
|
|
400
|
-
/>
|
|
401
|
-
) : senderUser?.avatarUrl ? (
|
|
402
|
-
<img
|
|
403
|
-
src={senderUser.avatarUrl}
|
|
404
|
-
alt={displayName}
|
|
405
|
-
className={`shrink-0 rounded-lg sm:rounded-xl border-2 object-cover ${
|
|
406
|
-
compactMode ? 'w-7 h-7 sm:w-8 sm:h-8' : 'w-8 h-8 sm:w-10 sm:h-10'
|
|
407
|
-
}`}
|
|
408
|
-
style={{
|
|
409
|
-
borderColor: provider.color,
|
|
410
|
-
boxShadow: `0 0 16px ${provider.color}30`,
|
|
411
|
-
}}
|
|
412
|
-
/>
|
|
413
|
-
) : (
|
|
414
|
-
<div
|
|
415
|
-
className={`shrink-0 rounded-lg sm:rounded-xl flex items-center justify-center font-medium border-2 ${
|
|
416
|
-
compactMode ? 'w-7 h-7 sm:w-8 sm:h-8 text-sm sm:text-base' : 'w-8 h-8 sm:w-10 sm:h-10 text-base sm:text-lg'
|
|
417
|
-
}`}
|
|
418
|
-
style={{
|
|
419
|
-
backgroundColor: `${provider.color}15`,
|
|
420
|
-
borderColor: provider.color,
|
|
421
|
-
color: provider.color,
|
|
422
|
-
boxShadow: `0 0 16px ${provider.color}30`,
|
|
423
|
-
}}
|
|
424
|
-
>
|
|
425
|
-
{provider.icon}
|
|
426
|
-
</div>
|
|
427
|
-
)}
|
|
428
|
-
|
|
429
|
-
<div className="flex-1 min-w-0 overflow-hidden">
|
|
430
|
-
{/* Message Header */}
|
|
431
|
-
<div className={`flex items-center gap-2 flex-wrap ${compactMode ? 'mb-1' : 'mb-1.5'}`}>
|
|
432
|
-
<MessageSenderName
|
|
433
|
-
displayName={displayName}
|
|
434
|
-
color={provider.color}
|
|
435
|
-
isCurrentUser={isFromCurrentUser}
|
|
436
|
-
agent={senderAgent}
|
|
437
|
-
userPresence={senderUser}
|
|
438
|
-
onAgentClick={onAgentClick}
|
|
439
|
-
onUserClick={onUserClick}
|
|
440
|
-
/>
|
|
441
|
-
|
|
442
|
-
{message.to !== '*' && (
|
|
443
|
-
<>
|
|
444
|
-
<span className="text-text-dim text-xs">→</span>
|
|
445
|
-
<MessageSenderName
|
|
446
|
-
displayName={message.to}
|
|
447
|
-
color={recipientProviderConfig?.color || '#00d9ff'}
|
|
448
|
-
agent={recipientAgent}
|
|
449
|
-
userPresence={recipientUser}
|
|
450
|
-
onAgentClick={onAgentClick}
|
|
451
|
-
onUserClick={onUserClick}
|
|
452
|
-
/>
|
|
453
|
-
</>
|
|
454
|
-
)}
|
|
455
|
-
|
|
456
|
-
{message.thread && (
|
|
457
|
-
<span className="text-xs py-0.5 px-2 rounded-full font-mono font-medium bg-accent-purple/20 text-accent-purple">
|
|
458
|
-
{message.thread}
|
|
459
|
-
</span>
|
|
460
|
-
)}
|
|
461
|
-
|
|
462
|
-
{message.to === '*' && (
|
|
463
|
-
<span className="text-xs py-0.5 px-2 rounded-full uppercase font-medium bg-warning/20 text-warning">
|
|
464
|
-
broadcast
|
|
465
|
-
</span>
|
|
466
|
-
)}
|
|
467
|
-
|
|
468
|
-
{showTimestamps && (
|
|
469
|
-
<span className="text-text-dim text-xs ml-auto font-mono">{timestamp}</span>
|
|
470
|
-
)}
|
|
471
|
-
|
|
472
|
-
{/* Message status indicator - show for messages sent by current user */}
|
|
473
|
-
{isFromCurrentUser && (
|
|
474
|
-
<MessageStatusIndicator status={message.status} size="small" />
|
|
475
|
-
)}
|
|
476
|
-
|
|
477
|
-
{/* Thinking indicator - show when recipient is processing */}
|
|
478
|
-
{showThinking && (
|
|
479
|
-
<ThinkingIndicator
|
|
480
|
-
isProcessing={true}
|
|
481
|
-
processingStartedAt={recipientProcessing?.processingStartedAt}
|
|
482
|
-
size="small"
|
|
483
|
-
showLabel={true}
|
|
484
|
-
/>
|
|
485
|
-
)}
|
|
486
|
-
|
|
487
|
-
{/* Thread/Reply button */}
|
|
488
|
-
<button
|
|
489
|
-
className={`
|
|
490
|
-
inline-flex items-center gap-1.5 p-1.5 rounded-lg transition-all duration-150 cursor-pointer border-none
|
|
491
|
-
${hasReplies || message.thread
|
|
492
|
-
? 'text-accent-cyan bg-accent-cyan/10 hover:bg-accent-cyan/20'
|
|
493
|
-
: 'text-text-muted bg-transparent opacity-0 group-hover:opacity-100 hover:text-accent-cyan hover:bg-accent-cyan/10'}
|
|
494
|
-
`}
|
|
495
|
-
onClick={() => onThreadClick?.(message.thread || message.id)}
|
|
496
|
-
title={message.thread ? `View thread: ${message.thread}` : (hasReplies ? `${replyCount} ${replyCount === 1 ? 'reply' : 'replies'}` : 'Reply in thread')}
|
|
497
|
-
>
|
|
498
|
-
<ThreadIcon />
|
|
499
|
-
{hasReplies && (
|
|
500
|
-
<span className="text-xs font-medium">{replyCount}</span>
|
|
501
|
-
)}
|
|
502
|
-
</button>
|
|
503
|
-
</div>
|
|
504
|
-
|
|
505
|
-
{/* Message Content */}
|
|
506
|
-
<div className="text-sm leading-relaxed text-text-primary whitespace-pre-wrap break-words">
|
|
507
|
-
{formatMessageBody(message.content)}
|
|
508
|
-
</div>
|
|
509
|
-
|
|
510
|
-
{/* Attachments */}
|
|
511
|
-
{message.attachments && message.attachments.length > 0 && (
|
|
512
|
-
<MessageAttachments attachments={message.attachments} />
|
|
513
|
-
)}
|
|
514
|
-
</div>
|
|
515
|
-
</div>
|
|
516
|
-
);
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
/**
|
|
520
|
-
* Message Attachments Component
|
|
521
|
-
* Displays image attachments with lightbox functionality
|
|
522
|
-
*/
|
|
523
|
-
interface MessageAttachmentsProps {
|
|
524
|
-
attachments: Attachment[];
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
function MessageAttachments({ attachments }: MessageAttachmentsProps) {
|
|
528
|
-
const [lightboxImage, setLightboxImage] = useState<Attachment | null>(null);
|
|
529
|
-
|
|
530
|
-
const imageAttachments = attachments.filter(a =>
|
|
531
|
-
a.mimeType.startsWith('image/')
|
|
532
|
-
);
|
|
533
|
-
|
|
534
|
-
if (imageAttachments.length === 0) return null;
|
|
535
|
-
|
|
536
|
-
return (
|
|
537
|
-
<>
|
|
538
|
-
<div className="flex flex-wrap gap-2 mt-2">
|
|
539
|
-
{imageAttachments.map((attachment) => (
|
|
540
|
-
<button
|
|
541
|
-
key={attachment.id}
|
|
542
|
-
type="button"
|
|
543
|
-
onClick={() => setLightboxImage(attachment)}
|
|
544
|
-
className="relative group cursor-pointer bg-transparent border-0 p-0"
|
|
545
|
-
title={`View ${attachment.filename}`}
|
|
546
|
-
>
|
|
547
|
-
<img
|
|
548
|
-
src={attachment.data || attachment.url}
|
|
549
|
-
alt={attachment.filename}
|
|
550
|
-
className="max-h-48 max-w-xs rounded-lg border border-border-subtle object-cover transition-all duration-150 group-hover:border-accent-cyan/50 group-hover:shadow-[0_0_8px_rgba(0,217,255,0.2)]"
|
|
551
|
-
loading="lazy"
|
|
552
|
-
/>
|
|
553
|
-
<div className="absolute inset-0 bg-black/0 group-hover:bg-black/10 rounded-lg transition-colors flex items-center justify-center opacity-0 group-hover:opacity-100">
|
|
554
|
-
<svg
|
|
555
|
-
width="24"
|
|
556
|
-
height="24"
|
|
557
|
-
viewBox="0 0 24 24"
|
|
558
|
-
fill="none"
|
|
559
|
-
stroke="white"
|
|
560
|
-
strokeWidth="2"
|
|
561
|
-
className="drop-shadow-lg"
|
|
562
|
-
>
|
|
563
|
-
<circle cx="11" cy="11" r="8" />
|
|
564
|
-
<line x1="21" y1="21" x2="16.65" y2="16.65" />
|
|
565
|
-
<line x1="11" y1="8" x2="11" y2="14" />
|
|
566
|
-
<line x1="8" y1="11" x2="14" y2="11" />
|
|
567
|
-
</svg>
|
|
568
|
-
</div>
|
|
569
|
-
</button>
|
|
570
|
-
))}
|
|
571
|
-
</div>
|
|
572
|
-
|
|
573
|
-
{/* Lightbox Modal */}
|
|
574
|
-
{lightboxImage && (
|
|
575
|
-
<div
|
|
576
|
-
className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/80 backdrop-blur-sm"
|
|
577
|
-
onClick={() => setLightboxImage(null)}
|
|
578
|
-
>
|
|
579
|
-
<div className="relative max-w-[90vw] max-h-[90vh]">
|
|
580
|
-
<img
|
|
581
|
-
src={lightboxImage.data || lightboxImage.url}
|
|
582
|
-
alt={lightboxImage.filename}
|
|
583
|
-
className="max-w-full max-h-[90vh] rounded-lg shadow-2xl"
|
|
584
|
-
onClick={(e) => e.stopPropagation()}
|
|
585
|
-
/>
|
|
586
|
-
<button
|
|
587
|
-
type="button"
|
|
588
|
-
onClick={() => setLightboxImage(null)}
|
|
589
|
-
className="absolute -top-3 -right-3 w-8 h-8 bg-bg-tertiary border border-border-subtle rounded-full flex items-center justify-center text-text-muted hover:text-text-primary hover:bg-bg-card transition-colors shadow-lg"
|
|
590
|
-
title="Close"
|
|
591
|
-
>
|
|
592
|
-
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
593
|
-
<line x1="18" y1="6" x2="6" y2="18" />
|
|
594
|
-
<line x1="6" y1="6" x2="18" y2="18" />
|
|
595
|
-
</svg>
|
|
596
|
-
</button>
|
|
597
|
-
<div className="absolute bottom-0 left-0 right-0 p-3 bg-gradient-to-t from-black/60 to-transparent rounded-b-lg">
|
|
598
|
-
<p className="text-white text-sm truncate">{lightboxImage.filename}</p>
|
|
599
|
-
</div>
|
|
600
|
-
</div>
|
|
601
|
-
</div>
|
|
602
|
-
)}
|
|
603
|
-
</>
|
|
604
|
-
);
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
/**
|
|
608
|
-
* Format timestamp for display
|
|
609
|
-
*/
|
|
610
|
-
function formatTimestamp(timestamp: string | number): string {
|
|
611
|
-
const date = new Date(timestamp);
|
|
612
|
-
const now = new Date();
|
|
613
|
-
const isToday = date.toDateString() === now.toDateString();
|
|
614
|
-
|
|
615
|
-
if (isToday) {
|
|
616
|
-
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
const yesterday = new Date(now);
|
|
620
|
-
yesterday.setDate(yesterday.getDate() - 1);
|
|
621
|
-
const isYesterday = date.toDateString() === yesterday.toDateString();
|
|
622
|
-
|
|
623
|
-
if (isYesterday) {
|
|
624
|
-
return `Yesterday ${date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`;
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
return date.toLocaleDateString([], {
|
|
628
|
-
month: 'short',
|
|
629
|
-
day: 'numeric',
|
|
630
|
-
hour: '2-digit',
|
|
631
|
-
minute: '2-digit',
|
|
632
|
-
});
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
function EmptyIcon() {
|
|
636
|
-
return (
|
|
637
|
-
<svg className="mb-4 opacity-50 text-text-muted" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
|
|
638
|
-
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
|
|
639
|
-
</svg>
|
|
640
|
-
);
|
|
641
|
-
}
|
|
642
|
-
|
|
643
|
-
function ThreadIcon() {
|
|
644
|
-
return (
|
|
645
|
-
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
|
646
|
-
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
|
|
647
|
-
</svg>
|
|
648
|
-
);
|
|
649
|
-
}
|