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.
Files changed (412) hide show
  1. package/bin/relay-pty-linux-arm64 +0 -0
  2. package/dist/src/cli/index.d.ts +3 -3
  3. package/dist/src/cli/index.js +31 -100
  4. package/package.json +22 -29
  5. package/packages/api-types/package.json +1 -1
  6. package/packages/bridge/package.json +8 -8
  7. package/packages/cli-tester/package.json +1 -1
  8. package/packages/cloud/dist/server.js +25 -4
  9. package/packages/cloud/package.json +6 -6
  10. package/packages/config/package.json +2 -2
  11. package/packages/continuity/package.json +1 -1
  12. package/packages/daemon/dist/orchestrator.js +21 -1
  13. package/packages/daemon/dist/router.d.ts +5 -0
  14. package/packages/daemon/dist/router.js +31 -0
  15. package/packages/daemon/dist/server.d.ts +5 -0
  16. package/packages/daemon/dist/server.js +131 -1
  17. package/packages/daemon/package.json +12 -12
  18. package/packages/hooks/package.json +4 -4
  19. package/packages/mcp/dist/client.d.ts +15 -0
  20. package/packages/mcp/dist/client.js +9 -0
  21. package/packages/mcp/dist/server.js +13 -1
  22. package/packages/mcp/dist/tools/index.d.ts +2 -0
  23. package/packages/mcp/dist/tools/index.js +2 -0
  24. package/packages/mcp/dist/tools/relay-connected.d.ts +17 -0
  25. package/packages/mcp/dist/tools/relay-connected.js +40 -0
  26. package/packages/mcp/dist/tools/relay-remove-agent.d.ts +20 -0
  27. package/packages/mcp/dist/tools/relay-remove-agent.js +50 -0
  28. package/packages/mcp/package.json +2 -2
  29. package/packages/memory/package.json +2 -2
  30. package/packages/policy/package.json +2 -2
  31. package/packages/protocol/dist/types.d.ts +46 -1
  32. package/packages/protocol/package.json +1 -1
  33. package/packages/resiliency/package.json +1 -1
  34. package/packages/sdk/dist/client.d.ts +22 -1
  35. package/packages/sdk/dist/client.js +31 -0
  36. package/packages/sdk/dist/protocol/index.d.ts +1 -1
  37. package/packages/sdk/dist/protocol/types.d.ts +35 -1
  38. package/packages/sdk/package.json +2 -2
  39. package/packages/spawner/package.json +1 -1
  40. package/packages/state/package.json +1 -1
  41. package/packages/storage/dist/adapter.d.ts +4 -0
  42. package/packages/storage/dist/sqlite-adapter.d.ts +10 -0
  43. package/packages/storage/dist/sqlite-adapter.js +26 -0
  44. package/packages/storage/package.json +2 -2
  45. package/packages/telemetry/package.json +1 -1
  46. package/packages/trajectory/package.json +2 -2
  47. package/packages/user-directory/package.json +2 -2
  48. package/packages/utils/dist/update-checker.js +4 -0
  49. package/packages/utils/package.json +1 -1
  50. package/packages/wrapper/package.json +6 -6
  51. package/deploy/workspace/codex.config.toml +0 -20
  52. package/deploy/workspace/entrypoint-browser.sh +0 -118
  53. package/deploy/workspace/entrypoint.sh +0 -612
  54. package/deploy/workspace/gh-credential-relay +0 -90
  55. package/deploy/workspace/gh-relay +0 -156
  56. package/deploy/workspace/git-credential-relay +0 -330
  57. package/deploy/workspace/git-credential-relay.test.sh +0 -230
  58. package/dist/dashboard/out/404.html +0 -1
  59. package/dist/dashboard/out/_next/static/7MZPqYkVGw3EGzVBkVmY9/_buildManifest.js +0 -1
  60. package/dist/dashboard/out/_next/static/7MZPqYkVGw3EGzVBkVmY9/_ssgManifest.js +0 -1
  61. package/dist/dashboard/out/_next/static/chunks/116-a883fca163f3a5bc.js +0 -1
  62. package/dist/dashboard/out/_next/static/chunks/117-c8afed19e821a35d.js +0 -2
  63. package/dist/dashboard/out/_next/static/chunks/282-980c2eb8fff20123.js +0 -1
  64. package/dist/dashboard/out/_next/static/chunks/320-a6304232cd0ee2ce.js +0 -1
  65. package/dist/dashboard/out/_next/static/chunks/532-bace199897eeab37.js +0 -9
  66. package/dist/dashboard/out/_next/static/chunks/631-16b905e5920f9b59.js +0 -1
  67. package/dist/dashboard/out/_next/static/chunks/648-acb2ff9f77cbfbd3.js +0 -1
  68. package/dist/dashboard/out/_next/static/chunks/766-2aea80818f7eb0d8.js +0 -1
  69. package/dist/dashboard/out/_next/static/chunks/83-26d2bde54616ee90.js +0 -1
  70. package/dist/dashboard/out/_next/static/chunks/847-f1f467060f32afff.js +0 -1
  71. package/dist/dashboard/out/_next/static/chunks/891-5cb1513eeb97a891.js +0 -1
  72. package/dist/dashboard/out/_next/static/chunks/app/_not-found/page-60501fddbafba9dc.js +0 -1
  73. package/dist/dashboard/out/_next/static/chunks/app/app/onboarding/page-9914652442f7e4fb.js +0 -1
  74. package/dist/dashboard/out/_next/static/chunks/app/app/page-366fb7c078d4e9e0.js +0 -1
  75. package/dist/dashboard/out/_next/static/chunks/app/cloud/link/page-fa1d5842aa90e8a6.js +0 -1
  76. package/dist/dashboard/out/_next/static/chunks/app/complete-profile/page-dd64bbdf66b639cd.js +0 -1
  77. package/dist/dashboard/out/_next/static/chunks/app/connect-repos/page-113060009ef35bc2.js +0 -1
  78. package/dist/dashboard/out/_next/static/chunks/app/history/page-9965d2483011b846.js +0 -1
  79. package/dist/dashboard/out/_next/static/chunks/app/layout-6b91e33784c20610.js +0 -1
  80. package/dist/dashboard/out/_next/static/chunks/app/login/page-435eceb0073be027.js +0 -1
  81. package/dist/dashboard/out/_next/static/chunks/app/metrics/page-1e37ef8e73940b40.js +0 -1
  82. package/dist/dashboard/out/_next/static/chunks/app/page-8119d4246743574e.js +0 -1
  83. package/dist/dashboard/out/_next/static/chunks/app/pricing/page-9db3ebdfa567a7c9.js +0 -1
  84. package/dist/dashboard/out/_next/static/chunks/app/providers/page-ecb16ffd3b36262b.js +0 -1
  85. package/dist/dashboard/out/_next/static/chunks/app/providers/setup/[provider]/page-4dbe33f0f7691b7c.js +0 -1
  86. package/dist/dashboard/out/_next/static/chunks/app/signup/page-c7a0a28341365ae0.js +0 -1
  87. package/dist/dashboard/out/_next/static/chunks/e868780c-48e5f147c90a3a41.js +0 -18
  88. package/dist/dashboard/out/_next/static/chunks/fd9d1056-609918ca7b6280bb.js +0 -1
  89. package/dist/dashboard/out/_next/static/chunks/framework-f66176bb897dc684.js +0 -1
  90. package/dist/dashboard/out/_next/static/chunks/main-311c3db74dcfadb7.js +0 -1
  91. package/dist/dashboard/out/_next/static/chunks/main-app-fdbeb09028f57c9f.js +0 -1
  92. package/dist/dashboard/out/_next/static/chunks/pages/_app-72b849fbd24ac258.js +0 -1
  93. package/dist/dashboard/out/_next/static/chunks/pages/_error-7ba65e1336b92748.js +0 -1
  94. package/dist/dashboard/out/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  95. package/dist/dashboard/out/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +0 -1
  96. package/dist/dashboard/out/_next/static/css/4034f236dd1a3178.css +0 -1
  97. package/dist/dashboard/out/_next/static/css/6892f8422896ef7a.css +0 -1
  98. package/dist/dashboard/out/alt-logos/agent-relay-logo-128.png +0 -0
  99. package/dist/dashboard/out/alt-logos/agent-relay-logo-256.png +0 -0
  100. package/dist/dashboard/out/alt-logos/agent-relay-logo-32.png +0 -0
  101. package/dist/dashboard/out/alt-logos/agent-relay-logo-512.png +0 -0
  102. package/dist/dashboard/out/alt-logos/agent-relay-logo-64.png +0 -0
  103. package/dist/dashboard/out/alt-logos/agent-relay-logo.svg +0 -45
  104. package/dist/dashboard/out/alt-logos/logo.svg +0 -38
  105. package/dist/dashboard/out/alt-logos/monogram-logo-128.png +0 -0
  106. package/dist/dashboard/out/alt-logos/monogram-logo-256.png +0 -0
  107. package/dist/dashboard/out/alt-logos/monogram-logo-32.png +0 -0
  108. package/dist/dashboard/out/alt-logos/monogram-logo-512.png +0 -0
  109. package/dist/dashboard/out/alt-logos/monogram-logo-64.png +0 -0
  110. package/dist/dashboard/out/alt-logos/monogram-logo.svg +0 -38
  111. package/dist/dashboard/out/app/onboarding.html +0 -1
  112. package/dist/dashboard/out/app/onboarding.txt +0 -7
  113. package/dist/dashboard/out/app.html +0 -1
  114. package/dist/dashboard/out/app.txt +0 -7
  115. package/dist/dashboard/out/apple-icon.png +0 -0
  116. package/dist/dashboard/out/cloud/link.html +0 -1
  117. package/dist/dashboard/out/cloud/link.txt +0 -7
  118. package/dist/dashboard/out/complete-profile.html +0 -5
  119. package/dist/dashboard/out/complete-profile.txt +0 -7
  120. package/dist/dashboard/out/connect-repos.html +0 -1
  121. package/dist/dashboard/out/connect-repos.txt +0 -7
  122. package/dist/dashboard/out/history.html +0 -1
  123. package/dist/dashboard/out/history.txt +0 -7
  124. package/dist/dashboard/out/index.html +0 -1
  125. package/dist/dashboard/out/index.txt +0 -7
  126. package/dist/dashboard/out/login.html +0 -5
  127. package/dist/dashboard/out/login.txt +0 -7
  128. package/dist/dashboard/out/metrics.html +0 -1
  129. package/dist/dashboard/out/metrics.txt +0 -7
  130. package/dist/dashboard/out/pricing.html +0 -13
  131. package/dist/dashboard/out/pricing.txt +0 -7
  132. package/dist/dashboard/out/providers/setup/claude.html +0 -1
  133. package/dist/dashboard/out/providers/setup/claude.txt +0 -8
  134. package/dist/dashboard/out/providers/setup/codex.html +0 -1
  135. package/dist/dashboard/out/providers/setup/codex.txt +0 -8
  136. package/dist/dashboard/out/providers/setup/cursor.html +0 -1
  137. package/dist/dashboard/out/providers/setup/cursor.txt +0 -8
  138. package/dist/dashboard/out/providers.html +0 -1
  139. package/dist/dashboard/out/providers.txt +0 -7
  140. package/dist/dashboard/out/signup.html +0 -6
  141. package/dist/dashboard/out/signup.txt +0 -7
  142. package/dist/src/dashboard-server/index.d.ts +0 -8
  143. package/dist/src/dashboard-server/index.js +0 -8
  144. package/packages/dashboard/README.md +0 -48
  145. package/packages/dashboard/dist/health-worker-manager.d.ts +0 -62
  146. package/packages/dashboard/dist/health-worker-manager.js +0 -144
  147. package/packages/dashboard/dist/health-worker.d.ts +0 -9
  148. package/packages/dashboard/dist/health-worker.js +0 -79
  149. package/packages/dashboard/dist/index.d.ts +0 -20
  150. package/packages/dashboard/dist/index.js +0 -19
  151. package/packages/dashboard/dist/metrics.d.ts +0 -105
  152. package/packages/dashboard/dist/metrics.js +0 -193
  153. package/packages/dashboard/dist/needs-attention.d.ts +0 -24
  154. package/packages/dashboard/dist/needs-attention.js +0 -78
  155. package/packages/dashboard/dist/server.d.ts +0 -25
  156. package/packages/dashboard/dist/server.js +0 -5270
  157. package/packages/dashboard/dist/start.d.ts +0 -6
  158. package/packages/dashboard/dist/start.js +0 -13
  159. package/packages/dashboard/dist/types/threading.d.ts +0 -8
  160. package/packages/dashboard/dist/types/threading.js +0 -2
  161. package/packages/dashboard/dist/user-bridge.d.ts +0 -154
  162. package/packages/dashboard/dist/user-bridge.js +0 -372
  163. package/packages/dashboard/package.json +0 -65
  164. package/packages/dashboard/ui/app/app/onboarding/page.tsx +0 -394
  165. package/packages/dashboard/ui/app/app/page.tsx +0 -667
  166. package/packages/dashboard/ui/app/apple-icon.png +0 -0
  167. package/packages/dashboard/ui/app/cloud/link/page.tsx +0 -464
  168. package/packages/dashboard/ui/app/complete-profile/page.tsx +0 -204
  169. package/packages/dashboard/ui/app/connect-repos/page.tsx +0 -410
  170. package/packages/dashboard/ui/app/favicon.png +0 -0
  171. package/packages/dashboard/ui/app/globals.css +0 -59
  172. package/packages/dashboard/ui/app/history/page.tsx +0 -658
  173. package/packages/dashboard/ui/app/layout.tsx +0 -25
  174. package/packages/dashboard/ui/app/login/page.tsx +0 -424
  175. package/packages/dashboard/ui/app/metrics/page.tsx +0 -751
  176. package/packages/dashboard/ui/app/page.tsx +0 -59
  177. package/packages/dashboard/ui/app/pricing/page.tsx +0 -7
  178. package/packages/dashboard/ui/app/providers/page.tsx +0 -193
  179. package/packages/dashboard/ui/app/providers/setup/[provider]/ProviderSetupClient.tsx +0 -148
  180. package/packages/dashboard/ui/app/providers/setup/[provider]/constants.ts +0 -35
  181. package/packages/dashboard/ui/app/providers/setup/[provider]/page.tsx +0 -42
  182. package/packages/dashboard/ui/app/signup/page.tsx +0 -533
  183. package/packages/dashboard/ui/index.ts +0 -49
  184. package/packages/dashboard/ui/landing/LandingPage.tsx +0 -713
  185. package/packages/dashboard/ui/landing/PricingPage.tsx +0 -559
  186. package/packages/dashboard/ui/landing/index.ts +0 -6
  187. package/packages/dashboard/ui/landing/styles.css +0 -2850
  188. package/packages/dashboard/ui/lib/agent-merge.ts +0 -35
  189. package/packages/dashboard/ui/lib/api.ts +0 -1155
  190. package/packages/dashboard/ui/lib/cloudApi.ts +0 -877
  191. package/packages/dashboard/ui/lib/colors.ts +0 -218
  192. package/packages/dashboard/ui/lib/hierarchy.ts +0 -242
  193. package/packages/dashboard/ui/lib/stuckDetection.ts +0 -142
  194. package/packages/dashboard/ui/next-env.d.ts +0 -5
  195. package/packages/dashboard/ui/next.config.js +0 -41
  196. package/packages/dashboard/ui/package-lock.json +0 -2882
  197. package/packages/dashboard/ui/package.json +0 -33
  198. package/packages/dashboard/ui/postcss.config.js +0 -5
  199. package/packages/dashboard/ui/react-components/ActivityFeed.tsx +0 -216
  200. package/packages/dashboard/ui/react-components/AddWorkspaceModal.tsx +0 -170
  201. package/packages/dashboard/ui/react-components/AgentCard.tsx +0 -587
  202. package/packages/dashboard/ui/react-components/AgentList.tsx +0 -411
  203. package/packages/dashboard/ui/react-components/AgentProfilePanel.tsx +0 -564
  204. package/packages/dashboard/ui/react-components/App.tsx +0 -3033
  205. package/packages/dashboard/ui/react-components/BillingPanel.tsx +0 -922
  206. package/packages/dashboard/ui/react-components/BillingResult.tsx +0 -447
  207. package/packages/dashboard/ui/react-components/BroadcastComposer.tsx +0 -690
  208. package/packages/dashboard/ui/react-components/ChannelAdminPanel.tsx +0 -773
  209. package/packages/dashboard/ui/react-components/ChannelBrowser.tsx +0 -385
  210. package/packages/dashboard/ui/react-components/ChannelChat.tsx +0 -261
  211. package/packages/dashboard/ui/react-components/ChannelSidebar.tsx +0 -399
  212. package/packages/dashboard/ui/react-components/CloudSessionProvider.tsx +0 -130
  213. package/packages/dashboard/ui/react-components/CommandPalette.tsx +0 -815
  214. package/packages/dashboard/ui/react-components/ConfirmationDialog.tsx +0 -133
  215. package/packages/dashboard/ui/react-components/ConversationHistory.tsx +0 -518
  216. package/packages/dashboard/ui/react-components/CoordinatorPanel.tsx +0 -944
  217. package/packages/dashboard/ui/react-components/DecisionQueue.tsx +0 -717
  218. package/packages/dashboard/ui/react-components/DirectMessageView.tsx +0 -164
  219. package/packages/dashboard/ui/react-components/FileAutocomplete.tsx +0 -368
  220. package/packages/dashboard/ui/react-components/FleetOverview.tsx +0 -278
  221. package/packages/dashboard/ui/react-components/LogViewer.tsx +0 -310
  222. package/packages/dashboard/ui/react-components/LogViewerPanel.tsx +0 -482
  223. package/packages/dashboard/ui/react-components/Logo.tsx +0 -284
  224. package/packages/dashboard/ui/react-components/MentionAutocomplete.tsx +0 -384
  225. package/packages/dashboard/ui/react-components/MessageComposer.tsx +0 -457
  226. package/packages/dashboard/ui/react-components/MessageList.tsx +0 -649
  227. package/packages/dashboard/ui/react-components/MessageSenderName.tsx +0 -91
  228. package/packages/dashboard/ui/react-components/MessageStatusIndicator.tsx +0 -142
  229. package/packages/dashboard/ui/react-components/NewConversationModal.tsx +0 -400
  230. package/packages/dashboard/ui/react-components/NotificationToast.tsx +0 -488
  231. package/packages/dashboard/ui/react-components/OnlineUsersIndicator.tsx +0 -164
  232. package/packages/dashboard/ui/react-components/Pagination.tsx +0 -124
  233. package/packages/dashboard/ui/react-components/PricingPlans.tsx +0 -386
  234. package/packages/dashboard/ui/react-components/ProjectList.tsx +0 -625
  235. package/packages/dashboard/ui/react-components/ProviderAuthFlow.tsx +0 -853
  236. package/packages/dashboard/ui/react-components/ProviderConnectionList.tsx +0 -378
  237. package/packages/dashboard/ui/react-components/ProvisioningProgress.tsx +0 -730
  238. package/packages/dashboard/ui/react-components/RepoAccessPanel.tsx +0 -549
  239. package/packages/dashboard/ui/react-components/ServerCard.tsx +0 -202
  240. package/packages/dashboard/ui/react-components/SessionExpiredModal.tsx +0 -128
  241. package/packages/dashboard/ui/react-components/SpawnModal.tsx +0 -804
  242. package/packages/dashboard/ui/react-components/TaskAssignmentUI.tsx +0 -375
  243. package/packages/dashboard/ui/react-components/TerminalProviderSetup.tsx +0 -608
  244. package/packages/dashboard/ui/react-components/ThemeProvider.tsx +0 -325
  245. package/packages/dashboard/ui/react-components/ThinkingIndicator.tsx +0 -231
  246. package/packages/dashboard/ui/react-components/ThreadList.tsx +0 -198
  247. package/packages/dashboard/ui/react-components/ThreadPanel.tsx +0 -346
  248. package/packages/dashboard/ui/react-components/TrajectoryViewer.tsx +0 -698
  249. package/packages/dashboard/ui/react-components/TypingIndicator.tsx +0 -69
  250. package/packages/dashboard/ui/react-components/UsageBanner.tsx +0 -231
  251. package/packages/dashboard/ui/react-components/UserProfilePanel.tsx +0 -233
  252. package/packages/dashboard/ui/react-components/WorkspaceContext.tsx +0 -107
  253. package/packages/dashboard/ui/react-components/WorkspaceSelector.tsx +0 -234
  254. package/packages/dashboard/ui/react-components/WorkspaceStatusIndicator.tsx +0 -370
  255. package/packages/dashboard/ui/react-components/XTermInteractive.tsx +0 -510
  256. package/packages/dashboard/ui/react-components/XTermLogViewer.tsx +0 -719
  257. package/packages/dashboard/ui/react-components/channels/ChannelDialogs.tsx +0 -1411
  258. package/packages/dashboard/ui/react-components/channels/ChannelHeader.tsx +0 -317
  259. package/packages/dashboard/ui/react-components/channels/ChannelMessageList.tsx +0 -463
  260. package/packages/dashboard/ui/react-components/channels/ChannelViewV1.tsx +0 -146
  261. package/packages/dashboard/ui/react-components/channels/MessageInput.tsx +0 -288
  262. package/packages/dashboard/ui/react-components/channels/SearchInput.tsx +0 -172
  263. package/packages/dashboard/ui/react-components/channels/SearchResults.tsx +0 -336
  264. package/packages/dashboard/ui/react-components/channels/api.ts +0 -697
  265. package/packages/dashboard/ui/react-components/channels/index.ts +0 -76
  266. package/packages/dashboard/ui/react-components/channels/mockApi.ts +0 -344
  267. package/packages/dashboard/ui/react-components/channels/types.ts +0 -566
  268. package/packages/dashboard/ui/react-components/hooks/index.ts +0 -57
  269. package/packages/dashboard/ui/react-components/hooks/useAgentLogs.ts +0 -394
  270. package/packages/dashboard/ui/react-components/hooks/useAgents.ts +0 -127
  271. package/packages/dashboard/ui/react-components/hooks/useBroadcastDedup.ts +0 -86
  272. package/packages/dashboard/ui/react-components/hooks/useChannelAdmin.ts +0 -329
  273. package/packages/dashboard/ui/react-components/hooks/useChannelBrowser.ts +0 -239
  274. package/packages/dashboard/ui/react-components/hooks/useChannelCommands.ts +0 -138
  275. package/packages/dashboard/ui/react-components/hooks/useChannels.ts +0 -328
  276. package/packages/dashboard/ui/react-components/hooks/useDebounce.ts +0 -29
  277. package/packages/dashboard/ui/react-components/hooks/useDirectMessage.ts +0 -141
  278. package/packages/dashboard/ui/react-components/hooks/useMessages.ts +0 -309
  279. package/packages/dashboard/ui/react-components/hooks/useOrchestrator.ts +0 -364
  280. package/packages/dashboard/ui/react-components/hooks/usePinnedAgents.ts +0 -140
  281. package/packages/dashboard/ui/react-components/hooks/usePresence.ts +0 -340
  282. package/packages/dashboard/ui/react-components/hooks/useRecentRepos.ts +0 -130
  283. package/packages/dashboard/ui/react-components/hooks/useSession.ts +0 -209
  284. package/packages/dashboard/ui/react-components/hooks/useTrajectory.ts +0 -265
  285. package/packages/dashboard/ui/react-components/hooks/useWebSocket.ts +0 -169
  286. package/packages/dashboard/ui/react-components/hooks/useWorkspaceMembers.ts +0 -120
  287. package/packages/dashboard/ui/react-components/hooks/useWorkspaceRepos.ts +0 -73
  288. package/packages/dashboard/ui/react-components/hooks/useWorkspaceStatus.ts +0 -237
  289. package/packages/dashboard/ui/react-components/index.ts +0 -81
  290. package/packages/dashboard/ui/react-components/layout/Header.tsx +0 -355
  291. package/packages/dashboard/ui/react-components/layout/RepoContextHeader.tsx +0 -361
  292. package/packages/dashboard/ui/react-components/layout/Sidebar.archive.test.tsx +0 -126
  293. package/packages/dashboard/ui/react-components/layout/Sidebar.test.tsx +0 -691
  294. package/packages/dashboard/ui/react-components/layout/Sidebar.tsx +0 -930
  295. package/packages/dashboard/ui/react-components/layout/index.ts +0 -7
  296. package/packages/dashboard/ui/react-components/settings/BillingSettingsPanel.tsx +0 -564
  297. package/packages/dashboard/ui/react-components/settings/SettingsPage.tsx +0 -544
  298. package/packages/dashboard/ui/react-components/settings/TeamSettingsPanel.tsx +0 -560
  299. package/packages/dashboard/ui/react-components/settings/WorkspaceSettingsPanel.tsx +0 -1386
  300. package/packages/dashboard/ui/react-components/settings/index.ts +0 -11
  301. package/packages/dashboard/ui/react-components/settings/types.ts +0 -53
  302. package/packages/dashboard/ui/react-components/utils/messageFormatting.tsx +0 -370
  303. package/packages/dashboard/ui/tailwind.config.js +0 -148
  304. package/packages/dashboard/ui/types/index.ts +0 -304
  305. package/packages/dashboard/ui/types/threading.ts +0 -7
  306. package/packages/dashboard/ui-dist/404.html +0 -1
  307. package/packages/dashboard/ui-dist/_next/static/7MZPqYkVGw3EGzVBkVmY9/_buildManifest.js +0 -1
  308. package/packages/dashboard/ui-dist/_next/static/7MZPqYkVGw3EGzVBkVmY9/_ssgManifest.js +0 -1
  309. package/packages/dashboard/ui-dist/_next/static/chunks/116-a883fca163f3a5bc.js +0 -1
  310. package/packages/dashboard/ui-dist/_next/static/chunks/117-c8afed19e821a35d.js +0 -2
  311. package/packages/dashboard/ui-dist/_next/static/chunks/282-980c2eb8fff20123.js +0 -1
  312. package/packages/dashboard/ui-dist/_next/static/chunks/320-a6304232cd0ee2ce.js +0 -1
  313. package/packages/dashboard/ui-dist/_next/static/chunks/532-bace199897eeab37.js +0 -9
  314. package/packages/dashboard/ui-dist/_next/static/chunks/631-16b905e5920f9b59.js +0 -1
  315. package/packages/dashboard/ui-dist/_next/static/chunks/648-acb2ff9f77cbfbd3.js +0 -1
  316. package/packages/dashboard/ui-dist/_next/static/chunks/766-2aea80818f7eb0d8.js +0 -1
  317. package/packages/dashboard/ui-dist/_next/static/chunks/83-26d2bde54616ee90.js +0 -1
  318. package/packages/dashboard/ui-dist/_next/static/chunks/847-f1f467060f32afff.js +0 -1
  319. package/packages/dashboard/ui-dist/_next/static/chunks/891-5cb1513eeb97a891.js +0 -1
  320. package/packages/dashboard/ui-dist/_next/static/chunks/app/_not-found/page-60501fddbafba9dc.js +0 -1
  321. package/packages/dashboard/ui-dist/_next/static/chunks/app/app/onboarding/page-9914652442f7e4fb.js +0 -1
  322. package/packages/dashboard/ui-dist/_next/static/chunks/app/app/page-366fb7c078d4e9e0.js +0 -1
  323. package/packages/dashboard/ui-dist/_next/static/chunks/app/cloud/link/page-fa1d5842aa90e8a6.js +0 -1
  324. package/packages/dashboard/ui-dist/_next/static/chunks/app/complete-profile/page-dd64bbdf66b639cd.js +0 -1
  325. package/packages/dashboard/ui-dist/_next/static/chunks/app/connect-repos/page-113060009ef35bc2.js +0 -1
  326. package/packages/dashboard/ui-dist/_next/static/chunks/app/history/page-9965d2483011b846.js +0 -1
  327. package/packages/dashboard/ui-dist/_next/static/chunks/app/layout-6b91e33784c20610.js +0 -1
  328. package/packages/dashboard/ui-dist/_next/static/chunks/app/login/page-435eceb0073be027.js +0 -1
  329. package/packages/dashboard/ui-dist/_next/static/chunks/app/metrics/page-1e37ef8e73940b40.js +0 -1
  330. package/packages/dashboard/ui-dist/_next/static/chunks/app/page-8119d4246743574e.js +0 -1
  331. package/packages/dashboard/ui-dist/_next/static/chunks/app/pricing/page-9db3ebdfa567a7c9.js +0 -1
  332. package/packages/dashboard/ui-dist/_next/static/chunks/app/providers/page-ecb16ffd3b36262b.js +0 -1
  333. package/packages/dashboard/ui-dist/_next/static/chunks/app/providers/setup/[provider]/page-4dbe33f0f7691b7c.js +0 -1
  334. package/packages/dashboard/ui-dist/_next/static/chunks/app/signup/page-c7a0a28341365ae0.js +0 -1
  335. package/packages/dashboard/ui-dist/_next/static/chunks/e868780c-48e5f147c90a3a41.js +0 -18
  336. package/packages/dashboard/ui-dist/_next/static/chunks/fd9d1056-609918ca7b6280bb.js +0 -1
  337. package/packages/dashboard/ui-dist/_next/static/chunks/framework-f66176bb897dc684.js +0 -1
  338. package/packages/dashboard/ui-dist/_next/static/chunks/main-311c3db74dcfadb7.js +0 -1
  339. package/packages/dashboard/ui-dist/_next/static/chunks/main-app-fdbeb09028f57c9f.js +0 -1
  340. package/packages/dashboard/ui-dist/_next/static/chunks/pages/_app-72b849fbd24ac258.js +0 -1
  341. package/packages/dashboard/ui-dist/_next/static/chunks/pages/_error-7ba65e1336b92748.js +0 -1
  342. package/packages/dashboard/ui-dist/_next/static/chunks/polyfills-42372ed130431b0a.js +0 -1
  343. package/packages/dashboard/ui-dist/_next/static/chunks/webpack-1cdd8ed57114d5e1.js +0 -1
  344. package/packages/dashboard/ui-dist/_next/static/css/4034f236dd1a3178.css +0 -1
  345. package/packages/dashboard/ui-dist/_next/static/css/6892f8422896ef7a.css +0 -1
  346. package/packages/dashboard/ui-dist/_next/static/iJ3Uiz3IrqUJL7IxKZHiV/_buildManifest.js +0 -1
  347. package/packages/dashboard/ui-dist/_next/static/iJ3Uiz3IrqUJL7IxKZHiV/_ssgManifest.js +0 -1
  348. package/packages/dashboard/ui-dist/_next/static/l-jd878zUJ_IlraqEWMZc/_buildManifest.js +0 -1
  349. package/packages/dashboard/ui-dist/_next/static/l-jd878zUJ_IlraqEWMZc/_ssgManifest.js +0 -1
  350. package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-128.png +0 -0
  351. package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-256.png +0 -0
  352. package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-32.png +0 -0
  353. package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-512.png +0 -0
  354. package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo-64.png +0 -0
  355. package/packages/dashboard/ui-dist/alt-logos/agent-relay-logo.svg +0 -45
  356. package/packages/dashboard/ui-dist/alt-logos/logo.svg +0 -38
  357. package/packages/dashboard/ui-dist/alt-logos/monogram-logo-128.png +0 -0
  358. package/packages/dashboard/ui-dist/alt-logos/monogram-logo-256.png +0 -0
  359. package/packages/dashboard/ui-dist/alt-logos/monogram-logo-32.png +0 -0
  360. package/packages/dashboard/ui-dist/alt-logos/monogram-logo-512.png +0 -0
  361. package/packages/dashboard/ui-dist/alt-logos/monogram-logo-64.png +0 -0
  362. package/packages/dashboard/ui-dist/alt-logos/monogram-logo.svg +0 -38
  363. package/packages/dashboard/ui-dist/app/onboarding.html +0 -1
  364. package/packages/dashboard/ui-dist/app/onboarding.txt +0 -7
  365. package/packages/dashboard/ui-dist/app.html +0 -1
  366. package/packages/dashboard/ui-dist/app.txt +0 -7
  367. package/packages/dashboard/ui-dist/apple-icon.png +0 -0
  368. package/packages/dashboard/ui-dist/cloud/link.html +0 -1
  369. package/packages/dashboard/ui-dist/cloud/link.txt +0 -7
  370. package/packages/dashboard/ui-dist/complete-profile.html +0 -5
  371. package/packages/dashboard/ui-dist/complete-profile.txt +0 -7
  372. package/packages/dashboard/ui-dist/connect-repos.html +0 -1
  373. package/packages/dashboard/ui-dist/connect-repos.txt +0 -7
  374. package/packages/dashboard/ui-dist/history.html +0 -1
  375. package/packages/dashboard/ui-dist/history.txt +0 -7
  376. package/packages/dashboard/ui-dist/index.html +0 -1
  377. package/packages/dashboard/ui-dist/index.txt +0 -7
  378. package/packages/dashboard/ui-dist/login.html +0 -5
  379. package/packages/dashboard/ui-dist/login.txt +0 -7
  380. package/packages/dashboard/ui-dist/metrics.html +0 -1
  381. package/packages/dashboard/ui-dist/metrics.txt +0 -7
  382. package/packages/dashboard/ui-dist/pricing.html +0 -13
  383. package/packages/dashboard/ui-dist/pricing.txt +0 -7
  384. package/packages/dashboard/ui-dist/providers/setup/claude.html +0 -1
  385. package/packages/dashboard/ui-dist/providers/setup/claude.txt +0 -8
  386. package/packages/dashboard/ui-dist/providers/setup/codex.html +0 -1
  387. package/packages/dashboard/ui-dist/providers/setup/codex.txt +0 -8
  388. package/packages/dashboard/ui-dist/providers/setup/cursor.html +0 -1
  389. package/packages/dashboard/ui-dist/providers/setup/cursor.txt +0 -8
  390. package/packages/dashboard/ui-dist/providers.html +0 -1
  391. package/packages/dashboard/ui-dist/providers.txt +0 -7
  392. package/packages/dashboard/ui-dist/signup.html +0 -6
  393. package/packages/dashboard/ui-dist/signup.txt +0 -7
  394. package/packages/dashboard-server/dist/health-worker-manager.d.ts +0 -62
  395. package/packages/dashboard-server/dist/health-worker-manager.js +0 -144
  396. package/packages/dashboard-server/dist/health-worker.d.ts +0 -9
  397. package/packages/dashboard-server/dist/health-worker.js +0 -79
  398. package/packages/dashboard-server/dist/index.d.ts +0 -18
  399. package/packages/dashboard-server/dist/index.js +0 -17
  400. package/packages/dashboard-server/dist/metrics.d.ts +0 -105
  401. package/packages/dashboard-server/dist/metrics.js +0 -193
  402. package/packages/dashboard-server/dist/needs-attention.d.ts +0 -24
  403. package/packages/dashboard-server/dist/needs-attention.js +0 -78
  404. package/packages/dashboard-server/dist/server.d.ts +0 -25
  405. package/packages/dashboard-server/dist/server.js +0 -5158
  406. package/packages/dashboard-server/dist/start.d.ts +0 -6
  407. package/packages/dashboard-server/dist/start.js +0 -13
  408. package/packages/dashboard-server/dist/types/threading.d.ts +0 -8
  409. package/packages/dashboard-server/dist/types/threading.js +0 -2
  410. package/packages/dashboard-server/dist/user-bridge.d.ts +0 -158
  411. package/packages/dashboard-server/dist/user-bridge.js +0 -390
  412. 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
- }