@dxos/plugin-thread 0.8.4-main.422d1c7879 → 0.8.4-main.43cb759274

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 (532) hide show
  1. package/LICENSE +102 -5
  2. package/PLUGIN.mdl +271 -0
  3. package/README.md +1 -1
  4. package/dist/lib/neutral/ChannelArticle-UJHPOUWA.mjs +28 -0
  5. package/dist/lib/neutral/ChannelArticle-UJHPOUWA.mjs.map +7 -0
  6. package/dist/lib/neutral/ChannelChat-LZEDFJVD.mjs +10 -0
  7. package/dist/lib/neutral/CommentsCompanion-FOUIGCEK.mjs +208 -0
  8. package/dist/lib/neutral/CommentsCompanion-FOUIGCEK.mjs.map +7 -0
  9. package/dist/lib/neutral/ThreadContainer-QWB6WRMI.mjs +61 -0
  10. package/dist/lib/neutral/ThreadContainer-QWB6WRMI.mjs.map +7 -0
  11. package/dist/lib/neutral/ThreadPlugin.mjs +109 -0
  12. package/dist/lib/neutral/ThreadPlugin.mjs.map +7 -0
  13. package/dist/lib/neutral/ThreadPlugin.node.mjs +40 -0
  14. package/dist/lib/neutral/ThreadPlugin.node.mjs.map +7 -0
  15. package/dist/lib/neutral/ThreadPlugin.workerd.mjs +24 -0
  16. package/dist/lib/neutral/ThreadPlugin.workerd.mjs.map +7 -0
  17. package/dist/lib/neutral/ThreadSettings-5MKTDK3A.mjs +15 -0
  18. package/dist/lib/neutral/ThreadSettings-5MKTDK3A.mjs.map +7 -0
  19. package/dist/lib/{browser/add-message-VPPFFLFL.mjs → neutral/add-message-RDIABSIX.mjs} +48 -23
  20. package/dist/lib/neutral/add-message-RDIABSIX.mjs.map +7 -0
  21. package/dist/lib/neutral/agent-runner-RB7N5HLD.mjs +244 -0
  22. package/dist/lib/neutral/agent-runner-RB7N5HLD.mjs.map +7 -0
  23. package/dist/lib/neutral/app-graph-builder-PDLRFYSI.mjs +120 -0
  24. package/dist/lib/neutral/app-graph-builder-PDLRFYSI.mjs.map +7 -0
  25. package/dist/lib/neutral/append-channel-message-TBBQUVMH.mjs +40 -0
  26. package/dist/lib/neutral/append-channel-message-TBBQUVMH.mjs.map +7 -0
  27. package/dist/lib/neutral/blueprint-definition-S3EBOH4R.mjs +15 -0
  28. package/dist/lib/neutral/blueprint-definition-S3EBOH4R.mjs.map +7 -0
  29. package/dist/lib/neutral/blueprints/index.mjs +8 -0
  30. package/dist/lib/neutral/capabilities/index.mjs +27 -0
  31. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  32. package/dist/lib/neutral/chunk-35GUWXBB.mjs +48 -0
  33. package/dist/lib/neutral/chunk-35GUWXBB.mjs.map +7 -0
  34. package/dist/lib/{browser/blueprints/index.mjs → neutral/chunk-5T5LPLBN.mjs} +5 -6
  35. package/dist/lib/neutral/chunk-5T5LPLBN.mjs.map +7 -0
  36. package/dist/lib/neutral/chunk-BHEZLLXG.mjs +55 -0
  37. package/dist/lib/neutral/chunk-BHEZLLXG.mjs.map +7 -0
  38. package/dist/lib/neutral/chunk-HQZWTDJC.mjs +164 -0
  39. package/dist/lib/neutral/chunk-HQZWTDJC.mjs.map +7 -0
  40. package/dist/lib/neutral/chunk-IQBZZAMX.mjs +335 -0
  41. package/dist/lib/neutral/chunk-IQBZZAMX.mjs.map +7 -0
  42. package/dist/lib/neutral/chunk-JJETHBAZ.mjs +8 -0
  43. package/dist/lib/neutral/chunk-JJETHBAZ.mjs.map +7 -0
  44. package/dist/lib/neutral/chunk-JLY4NVTA.mjs +38 -0
  45. package/dist/lib/neutral/chunk-JLY4NVTA.mjs.map +7 -0
  46. package/dist/lib/neutral/chunk-QFDT33VT.mjs +69 -0
  47. package/dist/lib/neutral/chunk-QFDT33VT.mjs.map +7 -0
  48. package/dist/lib/neutral/components/index.mjs +541 -0
  49. package/dist/lib/neutral/components/index.mjs.map +7 -0
  50. package/dist/lib/neutral/containers/index.mjs +15 -0
  51. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  52. package/dist/lib/{browser/create-UGT7V733.mjs → neutral/create-VXM6HJMN.mjs} +20 -14
  53. package/dist/lib/neutral/create-VXM6HJMN.mjs.map +7 -0
  54. package/dist/lib/neutral/create-channel-FSJOMRHF.mjs +19 -0
  55. package/dist/lib/neutral/create-channel-FSJOMRHF.mjs.map +7 -0
  56. package/dist/lib/neutral/create-object-D5XEG7MQ.mjs +28 -0
  57. package/dist/lib/neutral/create-object-D5XEG7MQ.mjs.map +7 -0
  58. package/dist/lib/{browser/create-proposals-CMK7S7VS.mjs → neutral/create-proposals-ILYIYJEN.mjs} +5 -6
  59. package/dist/lib/neutral/create-proposals-ILYIYJEN.mjs.map +7 -0
  60. package/dist/lib/{browser/delete-FSFVU6ZA.mjs → neutral/delete-6KZERY6K.mjs} +9 -11
  61. package/dist/lib/neutral/delete-6KZERY6K.mjs.map +7 -0
  62. package/dist/lib/{browser/delete-message-XL5M5J33.mjs → neutral/delete-message-PATSHW36.mjs} +9 -19
  63. package/dist/lib/neutral/delete-message-PATSHW36.mjs.map +7 -0
  64. package/dist/lib/neutral/hooks/index.mjs +10 -0
  65. package/dist/lib/neutral/index.mjs +32 -0
  66. package/dist/lib/neutral/index.mjs.map +7 -0
  67. package/dist/lib/neutral/markdown-5UHAAC5Z.mjs +83 -0
  68. package/dist/lib/neutral/markdown-5UHAAC5Z.mjs.map +7 -0
  69. package/dist/lib/neutral/meta.json +1 -0
  70. package/dist/lib/neutral/meta.mjs +10 -0
  71. package/dist/lib/neutral/meta.mjs.map +7 -0
  72. package/dist/lib/neutral/on-create-space-6NLTBGGD.mjs +23 -0
  73. package/dist/lib/neutral/on-create-space-6NLTBGGD.mjs.map +7 -0
  74. package/dist/lib/neutral/operation-handler-RU6K2S4L.mjs +13 -0
  75. package/dist/lib/neutral/operation-handler-RU6K2S4L.mjs.map +7 -0
  76. package/dist/lib/neutral/operations/index.mjs +8 -0
  77. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  78. package/dist/lib/neutral/plugin.mjs +16 -0
  79. package/dist/lib/neutral/plugin.mjs.map +7 -0
  80. package/dist/lib/neutral/react-surface-TUMXARMI.mjs +76 -0
  81. package/dist/lib/neutral/react-surface-TUMXARMI.mjs.map +7 -0
  82. package/dist/lib/neutral/respond-to-thread-ROQA3B6U.mjs +32 -0
  83. package/dist/lib/neutral/respond-to-thread-ROQA3B6U.mjs.map +7 -0
  84. package/dist/lib/{browser/restore-2ZGMKUSD.mjs → neutral/restore-SP4HADCE.mjs} +6 -7
  85. package/dist/lib/neutral/restore-SP4HADCE.mjs.map +7 -0
  86. package/dist/lib/{browser/restore-message-OYEGWPII.mjs → neutral/restore-message-TVIC66VL.mjs} +8 -17
  87. package/dist/lib/neutral/restore-message-TVIC66VL.mjs.map +7 -0
  88. package/dist/lib/{browser/select-VG2XLULE.mjs → neutral/select-DLHPEKEA.mjs} +7 -9
  89. package/dist/lib/neutral/select-DLHPEKEA.mjs.map +7 -0
  90. package/dist/lib/neutral/set-agent-config-7GEYCG7Y.mjs +20 -0
  91. package/dist/lib/neutral/set-agent-config-7GEYCG7Y.mjs.map +7 -0
  92. package/dist/lib/neutral/settings-HK4EB6TF.mjs +30 -0
  93. package/dist/lib/neutral/settings-HK4EB6TF.mjs.map +7 -0
  94. package/dist/lib/neutral/state-UU7VEAKV.mjs +22 -0
  95. package/dist/lib/neutral/state-UU7VEAKV.mjs.map +7 -0
  96. package/dist/lib/neutral/testing/index.mjs +58 -0
  97. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  98. package/dist/lib/{browser/toggle-resolved-MM6YC5BU.mjs → neutral/toggle-resolved-GMAD3SZ2.mjs} +8 -17
  99. package/dist/lib/neutral/toggle-resolved-GMAD3SZ2.mjs.map +7 -0
  100. package/dist/lib/neutral/translations.mjs +91 -0
  101. package/dist/lib/neutral/translations.mjs.map +7 -0
  102. package/dist/lib/neutral/types/index.mjs +16 -0
  103. package/dist/lib/neutral/types/index.mjs.map +7 -0
  104. package/dist/lib/neutral/undo-mappings-HOKL2L3M.mjs +54 -0
  105. package/dist/lib/neutral/undo-mappings-HOKL2L3M.mjs.map +7 -0
  106. package/dist/types/src/ThreadPlugin.d.ts +1 -0
  107. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  108. package/dist/types/src/ThreadPlugin.node.d.ts +4 -0
  109. package/dist/types/src/ThreadPlugin.node.d.ts.map +1 -0
  110. package/dist/types/src/ThreadPlugin.test.d.ts +2 -0
  111. package/dist/types/src/ThreadPlugin.test.d.ts.map +1 -0
  112. package/dist/types/src/ThreadPlugin.workerd.d.ts +4 -0
  113. package/dist/types/src/ThreadPlugin.workerd.d.ts.map +1 -0
  114. package/dist/types/src/blueprints/thread-blueprint.d.ts +2 -2
  115. package/dist/types/src/blueprints/thread-blueprint.d.ts.map +1 -1
  116. package/dist/types/src/capabilities/agent-runner.d.ts +22 -0
  117. package/dist/types/src/capabilities/agent-runner.d.ts.map +1 -0
  118. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  119. package/dist/types/src/capabilities/blueprint-definition.d.ts +2 -2
  120. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -1
  121. package/dist/types/src/capabilities/create-object.d.ts +11 -0
  122. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  123. package/dist/types/src/capabilities/index.d.ts +10 -8
  124. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  125. package/dist/types/src/capabilities/markdown.d.ts.map +1 -1
  126. package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
  127. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -1
  128. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  129. package/dist/types/src/capabilities/settings.d.ts.map +1 -1
  130. package/dist/types/src/capabilities/state.d.ts.map +1 -1
  131. package/dist/types/src/capabilities/undo-mappings.d.ts.map +1 -1
  132. package/dist/types/src/components/Chat/Chat.d.ts +51 -0
  133. package/dist/types/src/components/Chat/Chat.d.ts.map +1 -0
  134. package/dist/types/src/components/Chat/index.d.ts +2 -0
  135. package/dist/types/src/components/Chat/index.d.ts.map +1 -0
  136. package/dist/types/src/components/CommentsPanel/CommentsPanel.d.ts.map +1 -1
  137. package/dist/types/src/components/CommentsPanel/CommentsPanel.stories.d.ts +70 -70
  138. package/dist/types/src/components/CommentsPanel/CommentsPanel.stories.d.ts.map +1 -1
  139. package/dist/types/src/components/CommentsPanel/CommentsThread.d.ts.map +1 -1
  140. package/dist/types/src/components/MessagePanel/MessagePanel.d.ts.map +1 -1
  141. package/dist/types/src/components/ThreadSettings/ThreadSettings.d.ts.map +1 -1
  142. package/dist/types/src/components/ThreadSettings/ThreadSettings.stories.d.ts +70 -70
  143. package/dist/types/src/components/ThreadSettings/ThreadSettings.stories.d.ts.map +1 -1
  144. package/dist/types/src/components/index.d.ts +1 -1
  145. package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts +13 -0
  146. package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts.map +1 -0
  147. package/dist/types/src/containers/ChannelArticle/ChannelArticle.stories.d.ts +162 -0
  148. package/dist/types/src/containers/ChannelArticle/ChannelArticle.stories.d.ts.map +1 -0
  149. package/dist/types/src/containers/ChannelArticle/index.d.ts +2 -0
  150. package/dist/types/src/containers/{CallDebugPanel → ChannelArticle}/index.d.ts.map +1 -1
  151. package/dist/types/src/containers/ChannelChat/ChannelChat.d.ts +20 -0
  152. package/dist/types/src/containers/ChannelChat/ChannelChat.d.ts.map +1 -0
  153. package/dist/types/src/containers/ChannelChat/index.d.ts +4 -0
  154. package/dist/types/src/containers/ChannelChat/index.d.ts.map +1 -0
  155. package/dist/types/src/containers/CommentsCompanion/CommentsCompanion.d.ts +11 -0
  156. package/dist/types/src/containers/CommentsCompanion/CommentsCompanion.d.ts.map +1 -0
  157. package/dist/types/src/containers/CommentsCompanion/CommentsCompanion.stories.d.ts +198 -0
  158. package/dist/types/src/containers/CommentsCompanion/CommentsCompanion.stories.d.ts.map +1 -0
  159. package/dist/types/src/containers/CommentsCompanion/index.d.ts +2 -0
  160. package/dist/types/src/containers/CommentsCompanion/index.d.ts.map +1 -0
  161. package/dist/types/src/containers/ThreadContainer/ThreadContainer.d.ts +20 -0
  162. package/dist/types/src/containers/ThreadContainer/ThreadContainer.d.ts.map +1 -0
  163. package/dist/types/src/containers/{ChatContainer/ChatContainer.stories.d.ts → ThreadContainer/ThreadContainer.stories.d.ts} +71 -71
  164. package/dist/types/src/containers/ThreadContainer/ThreadContainer.stories.d.ts.map +1 -0
  165. package/dist/types/src/containers/ThreadContainer/index.d.ts +4 -0
  166. package/dist/types/src/containers/ThreadContainer/index.d.ts.map +1 -0
  167. package/dist/types/src/containers/index.d.ts +4 -5
  168. package/dist/types/src/containers/index.d.ts.map +1 -1
  169. package/dist/types/src/extensions/threads.d.ts +3 -3
  170. package/dist/types/src/extensions/threads.d.ts.map +1 -1
  171. package/dist/types/src/hooks/analytics.d.ts.map +1 -1
  172. package/dist/types/src/hooks/index.d.ts +0 -4
  173. package/dist/types/src/hooks/index.d.ts.map +1 -1
  174. package/dist/types/src/hooks/useStatus.d.ts.map +1 -1
  175. package/dist/types/src/index.d.ts +2 -3
  176. package/dist/types/src/index.d.ts.map +1 -1
  177. package/dist/types/src/meta.d.ts +1 -1
  178. package/dist/types/src/meta.d.ts.map +1 -1
  179. package/dist/types/src/operations/add-message.d.ts +3 -3
  180. package/dist/types/src/operations/add-message.d.ts.map +1 -1
  181. package/dist/types/src/operations/append-channel-message.d.ts +5 -0
  182. package/dist/types/src/operations/append-channel-message.d.ts.map +1 -0
  183. package/dist/types/src/operations/create-channel.d.ts +3 -3
  184. package/dist/types/src/operations/create-channel.d.ts.map +1 -1
  185. package/dist/types/src/operations/create-proposals.d.ts +3 -3
  186. package/dist/types/src/operations/create-proposals.d.ts.map +1 -1
  187. package/dist/types/src/operations/create.d.ts +3 -3
  188. package/dist/types/src/operations/create.d.ts.map +1 -1
  189. package/dist/types/src/operations/delete-message.d.ts +3 -3
  190. package/dist/types/src/operations/delete-message.d.ts.map +1 -1
  191. package/dist/types/src/operations/delete.d.ts +3 -3
  192. package/dist/types/src/operations/delete.d.ts.map +1 -1
  193. package/dist/types/src/operations/index.d.ts +1 -2
  194. package/dist/types/src/operations/index.d.ts.map +1 -1
  195. package/dist/types/src/operations/on-create-space.d.ts +3 -3
  196. package/dist/types/src/operations/on-create-space.d.ts.map +1 -1
  197. package/dist/types/src/operations/respond-to-thread.d.ts +5 -0
  198. package/dist/types/src/operations/respond-to-thread.d.ts.map +1 -0
  199. package/dist/types/src/operations/restore-message.d.ts +3 -3
  200. package/dist/types/src/operations/restore-message.d.ts.map +1 -1
  201. package/dist/types/src/operations/restore.d.ts +3 -3
  202. package/dist/types/src/operations/restore.d.ts.map +1 -1
  203. package/dist/types/src/operations/select.d.ts +3 -3
  204. package/dist/types/src/operations/select.d.ts.map +1 -1
  205. package/dist/types/src/operations/set-agent-config.d.ts +5 -0
  206. package/dist/types/src/operations/set-agent-config.d.ts.map +1 -0
  207. package/dist/types/src/operations/toggle-resolved.d.ts +3 -3
  208. package/dist/types/src/operations/toggle-resolved.d.ts.map +1 -1
  209. package/dist/types/src/plugin.d.ts +4 -0
  210. package/dist/types/src/plugin.d.ts.map +1 -0
  211. package/dist/types/src/should-trigger-agent.d.ts +22 -0
  212. package/dist/types/src/should-trigger-agent.d.ts.map +1 -0
  213. package/dist/types/src/should-trigger-agent.test.d.ts +2 -0
  214. package/dist/types/src/should-trigger-agent.test.d.ts.map +1 -0
  215. package/dist/types/src/testing/data.d.ts.map +1 -1
  216. package/dist/types/src/testing/index.d.ts +1 -1
  217. package/dist/types/src/testing/index.d.ts.map +1 -1
  218. package/dist/types/src/translations.d.ts +70 -70
  219. package/dist/types/src/translations.d.ts.map +1 -1
  220. package/dist/types/src/types/AgentIdentity.d.ts +27 -0
  221. package/dist/types/src/types/AgentIdentity.d.ts.map +1 -0
  222. package/dist/types/src/types/ThreadCapabilities.d.ts +34 -0
  223. package/dist/types/src/types/ThreadCapabilities.d.ts.map +1 -0
  224. package/dist/types/src/{operations/definitions.d.ts → types/ThreadOperation.d.ts} +1882 -1941
  225. package/dist/types/src/types/ThreadOperation.d.ts.map +1 -0
  226. package/dist/types/src/types/index.d.ts +4 -2
  227. package/dist/types/src/types/index.d.ts.map +1 -1
  228. package/dist/types/src/types/types.d.ts +1 -1
  229. package/dist/types/src/types/types.d.ts.map +1 -1
  230. package/dist/types/src/util.d.ts +6 -3
  231. package/dist/types/src/util.d.ts.map +1 -1
  232. package/dist/types/tsconfig.tsbuildinfo +1 -1
  233. package/package.json +133 -96
  234. package/src/ThreadPlugin.node.ts +39 -0
  235. package/src/ThreadPlugin.test.ts +37 -0
  236. package/src/ThreadPlugin.tsx +35 -65
  237. package/src/ThreadPlugin.workerd.ts +20 -0
  238. package/src/blueprints/thread-blueprint.ts +3 -4
  239. package/src/capabilities/agent-runner.ts +291 -0
  240. package/src/capabilities/app-graph-builder.ts +24 -74
  241. package/src/capabilities/blueprint-definition.ts +2 -0
  242. package/src/capabilities/create-object.ts +30 -0
  243. package/src/capabilities/index.ts +4 -3
  244. package/src/capabilities/markdown.ts +6 -2
  245. package/src/capabilities/operation-handler.ts +1 -1
  246. package/src/capabilities/react-surface.tsx +11 -27
  247. package/src/capabilities/settings.ts +1 -3
  248. package/src/capabilities/undo-mappings.ts +1 -1
  249. package/src/components/Chat/Chat.tsx +259 -0
  250. package/src/components/Chat/index.ts +5 -0
  251. package/src/components/CommentsPanel/CommentsPanel.stories.tsx +8 -7
  252. package/src/components/CommentsPanel/CommentsPanel.tsx +5 -5
  253. package/src/components/CommentsPanel/CommentsThread.tsx +16 -12
  254. package/src/components/MessagePanel/MessagePanel.tsx +8 -9
  255. package/src/components/ThreadSettings/ThreadSettings.stories.tsx +2 -1
  256. package/src/components/ThreadSettings/ThreadSettings.tsx +0 -1
  257. package/src/components/index.ts +1 -1
  258. package/src/containers/ChannelArticle/ChannelArticle.stories.tsx +105 -0
  259. package/src/containers/ChannelArticle/ChannelArticle.tsx +42 -0
  260. package/src/containers/ChannelArticle/index.ts +5 -0
  261. package/src/containers/ChannelChat/ChannelChat.tsx +75 -0
  262. package/src/containers/ChannelChat/index.ts +8 -0
  263. package/src/containers/CommentsCompanion/CommentsCompanion.stories.tsx +355 -0
  264. package/src/containers/{ThreadCompanion/ThreadCompanion.tsx → CommentsCompanion/CommentsCompanion.tsx} +33 -34
  265. package/src/containers/CommentsCompanion/index.ts +5 -0
  266. package/src/containers/{ChatContainer/ChatContainer.stories.tsx → ThreadContainer/ThreadContainer.stories.tsx} +10 -11
  267. package/src/containers/ThreadContainer/ThreadContainer.tsx +75 -0
  268. package/src/containers/ThreadContainer/index.ts +8 -0
  269. package/src/containers/index.ts +4 -5
  270. package/src/extensions/command.ts +1 -1
  271. package/src/extensions/threads.ts +13 -13
  272. package/src/hooks/analytics.ts +1 -1
  273. package/src/hooks/index.ts +0 -5
  274. package/src/index.ts +4 -4
  275. package/src/meta.ts +34 -8
  276. package/src/operations/add-message.ts +22 -9
  277. package/src/operations/append-channel-message.ts +37 -0
  278. package/src/operations/create-channel.ts +4 -4
  279. package/src/operations/create-proposals.ts +3 -3
  280. package/src/operations/create.ts +21 -6
  281. package/src/operations/delete-message.ts +6 -6
  282. package/src/operations/delete.ts +5 -5
  283. package/src/operations/index.ts +4 -4
  284. package/src/operations/on-create-space.ts +4 -4
  285. package/src/operations/respond-to-thread.ts +32 -0
  286. package/src/operations/restore-message.ts +5 -5
  287. package/src/operations/restore.ts +4 -4
  288. package/src/operations/select.ts +3 -3
  289. package/src/operations/set-agent-config.ts +24 -0
  290. package/src/operations/toggle-resolved.ts +5 -5
  291. package/src/plugin.ts +11 -0
  292. package/src/should-trigger-agent.test.ts +72 -0
  293. package/src/should-trigger-agent.ts +50 -0
  294. package/src/testing/index.ts +1 -1
  295. package/src/translations.ts +2 -1
  296. package/src/types/AgentIdentity.ts +35 -0
  297. package/src/types/ThreadCapabilities.ts +46 -0
  298. package/src/types/ThreadOperation.ts +225 -0
  299. package/src/types/index.ts +5 -2
  300. package/src/types/types.ts +0 -2
  301. package/src/util.ts +36 -4
  302. package/src/vite-env.d.ts +10 -0
  303. package/dist/lib/browser/add-message-VPPFFLFL.mjs.map +0 -7
  304. package/dist/lib/browser/blueprints/index.mjs.map +0 -7
  305. package/dist/lib/browser/chunk-MESW3R4Q.mjs +0 -61
  306. package/dist/lib/browser/chunk-MESW3R4Q.mjs.map +0 -7
  307. package/dist/lib/browser/chunk-VPM44Z35.mjs +0 -259
  308. package/dist/lib/browser/chunk-VPM44Z35.mjs.map +0 -7
  309. package/dist/lib/browser/create-UGT7V733.mjs.map +0 -7
  310. package/dist/lib/browser/create-channel-EF67LCS6.mjs +0 -21
  311. package/dist/lib/browser/create-channel-EF67LCS6.mjs.map +0 -7
  312. package/dist/lib/browser/create-channel-thread-CCZTSWQ6.mjs +0 -28
  313. package/dist/lib/browser/create-channel-thread-CCZTSWQ6.mjs.map +0 -7
  314. package/dist/lib/browser/create-proposals-CMK7S7VS.mjs.map +0 -7
  315. package/dist/lib/browser/delete-FSFVU6ZA.mjs.map +0 -7
  316. package/dist/lib/browser/delete-message-XL5M5J33.mjs.map +0 -7
  317. package/dist/lib/browser/index.mjs +0 -2334
  318. package/dist/lib/browser/index.mjs.map +0 -7
  319. package/dist/lib/browser/meta.json +0 -1
  320. package/dist/lib/browser/on-create-space-VYS2JGVT.mjs +0 -25
  321. package/dist/lib/browser/on-create-space-VYS2JGVT.mjs.map +0 -7
  322. package/dist/lib/browser/operations/index.mjs +0 -14
  323. package/dist/lib/browser/operations/index.mjs.map +0 -7
  324. package/dist/lib/browser/restore-2ZGMKUSD.mjs.map +0 -7
  325. package/dist/lib/browser/restore-message-OYEGWPII.mjs.map +0 -7
  326. package/dist/lib/browser/select-VG2XLULE.mjs.map +0 -7
  327. package/dist/lib/browser/toggle-resolved-MM6YC5BU.mjs.map +0 -7
  328. package/dist/lib/browser/types/index.mjs +0 -12
  329. package/dist/lib/node-esm/add-message-XWKHLNS6.mjs +0 -98
  330. package/dist/lib/node-esm/add-message-XWKHLNS6.mjs.map +0 -7
  331. package/dist/lib/node-esm/blueprints/index.mjs +0 -38
  332. package/dist/lib/node-esm/blueprints/index.mjs.map +0 -7
  333. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
  334. package/dist/lib/node-esm/chunk-JTHXNWKJ.mjs +0 -260
  335. package/dist/lib/node-esm/chunk-JTHXNWKJ.mjs.map +0 -7
  336. package/dist/lib/node-esm/chunk-SDRAQNSQ.mjs +0 -62
  337. package/dist/lib/node-esm/chunk-SDRAQNSQ.mjs.map +0 -7
  338. package/dist/lib/node-esm/create-XAYNDVU2.mjs +0 -56
  339. package/dist/lib/node-esm/create-XAYNDVU2.mjs.map +0 -7
  340. package/dist/lib/node-esm/create-channel-UYWUNB3L.mjs +0 -22
  341. package/dist/lib/node-esm/create-channel-UYWUNB3L.mjs.map +0 -7
  342. package/dist/lib/node-esm/create-channel-thread-UQF2SBHS.mjs +0 -29
  343. package/dist/lib/node-esm/create-channel-thread-UQF2SBHS.mjs.map +0 -7
  344. package/dist/lib/node-esm/create-proposals-5FJNURKH.mjs +0 -58
  345. package/dist/lib/node-esm/create-proposals-5FJNURKH.mjs.map +0 -7
  346. package/dist/lib/node-esm/delete-WRODXR3E.mjs +0 -60
  347. package/dist/lib/node-esm/delete-WRODXR3E.mjs.map +0 -7
  348. package/dist/lib/node-esm/delete-message-TAHCYTW2.mjs +0 -65
  349. package/dist/lib/node-esm/delete-message-TAHCYTW2.mjs.map +0 -7
  350. package/dist/lib/node-esm/index.mjs +0 -2335
  351. package/dist/lib/node-esm/index.mjs.map +0 -7
  352. package/dist/lib/node-esm/meta.json +0 -1
  353. package/dist/lib/node-esm/on-create-space-XDY2YXPV.mjs +0 -26
  354. package/dist/lib/node-esm/on-create-space-XDY2YXPV.mjs.map +0 -7
  355. package/dist/lib/node-esm/operations/index.mjs +0 -15
  356. package/dist/lib/node-esm/operations/index.mjs.map +0 -7
  357. package/dist/lib/node-esm/restore-T3QA7TSL.mjs +0 -34
  358. package/dist/lib/node-esm/restore-T3QA7TSL.mjs.map +0 -7
  359. package/dist/lib/node-esm/restore-message-WFTEVBEV.mjs +0 -43
  360. package/dist/lib/node-esm/restore-message-WFTEVBEV.mjs.map +0 -7
  361. package/dist/lib/node-esm/select-Q4UDWJJF.mjs +0 -27
  362. package/dist/lib/node-esm/select-Q4UDWJJF.mjs.map +0 -7
  363. package/dist/lib/node-esm/toggle-resolved-33XTAK2H.mjs +0 -46
  364. package/dist/lib/node-esm/toggle-resolved-33XTAK2H.mjs.map +0 -7
  365. package/dist/lib/node-esm/types/index.mjs +0 -13
  366. package/dist/types/src/calls/call-manager.d.ts +0 -87
  367. package/dist/types/src/calls/call-manager.d.ts.map +0 -1
  368. package/dist/types/src/calls/call-swarm-synchronizer.d.ts +0 -66
  369. package/dist/types/src/calls/call-swarm-synchronizer.d.ts.map +0 -1
  370. package/dist/types/src/calls/index.d.ts +0 -7
  371. package/dist/types/src/calls/index.d.ts.map +0 -1
  372. package/dist/types/src/calls/media-manager.d.ts +0 -60
  373. package/dist/types/src/calls/media-manager.d.ts.map +0 -1
  374. package/dist/types/src/calls/speaking-monitor.d.ts +0 -24
  375. package/dist/types/src/calls/speaking-monitor.d.ts.map +0 -1
  376. package/dist/types/src/calls/types.d.ts +0 -45
  377. package/dist/types/src/calls/types.d.ts.map +0 -1
  378. package/dist/types/src/calls/util/audio.d.ts +0 -6
  379. package/dist/types/src/calls/util/audio.d.ts.map +0 -1
  380. package/dist/types/src/calls/util/calls-service.d.ts +0 -77
  381. package/dist/types/src/calls/util/calls-service.d.ts.map +0 -1
  382. package/dist/types/src/calls/util/history-cache.d.ts +0 -11
  383. package/dist/types/src/calls/util/history-cache.d.ts.map +0 -1
  384. package/dist/types/src/calls/util/index.d.ts +0 -5
  385. package/dist/types/src/calls/util/index.d.ts.map +0 -1
  386. package/dist/types/src/calls/util/media.d.ts +0 -6
  387. package/dist/types/src/calls/util/media.d.ts.map +0 -1
  388. package/dist/types/src/calls/util/stub-media-streams.d.ts +0 -18
  389. package/dist/types/src/calls/util/stub-media-streams.d.ts.map +0 -1
  390. package/dist/types/src/calls/util/task-scheduling.d.ts +0 -17
  391. package/dist/types/src/calls/util/task-scheduling.d.ts.map +0 -1
  392. package/dist/types/src/calls-service.stories.d.ts +0 -23
  393. package/dist/types/src/calls-service.stories.d.ts.map +0 -1
  394. package/dist/types/src/capabilities/call-manager.d.ts +0 -6
  395. package/dist/types/src/capabilities/call-manager.d.ts.map +0 -1
  396. package/dist/types/src/capabilities/react-root.d.ts +0 -9
  397. package/dist/types/src/capabilities/react-root.d.ts.map +0 -1
  398. package/dist/types/src/components/Call/Call.d.ts +0 -17
  399. package/dist/types/src/components/Call/Call.d.ts.map +0 -1
  400. package/dist/types/src/components/Call/Toolbar.d.ts +0 -16
  401. package/dist/types/src/components/Call/Toolbar.d.ts.map +0 -1
  402. package/dist/types/src/components/Call/index.d.ts +0 -3
  403. package/dist/types/src/components/Call/index.d.ts.map +0 -1
  404. package/dist/types/src/components/Lobby/Lobby.d.ts +0 -15
  405. package/dist/types/src/components/Lobby/Lobby.d.ts.map +0 -1
  406. package/dist/types/src/components/Lobby/index.d.ts +0 -2
  407. package/dist/types/src/components/Lobby/index.d.ts.map +0 -1
  408. package/dist/types/src/components/Media/AudioStream.d.ts +0 -6
  409. package/dist/types/src/components/Media/AudioStream.d.ts.map +0 -1
  410. package/dist/types/src/components/Media/VideoObject.d.ts +0 -15
  411. package/dist/types/src/components/Media/VideoObject.d.ts.map +0 -1
  412. package/dist/types/src/components/Media/VideoObject.stories.d.ts +0 -22
  413. package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +0 -1
  414. package/dist/types/src/components/Media/index.d.ts +0 -3
  415. package/dist/types/src/components/Media/index.d.ts.map +0 -1
  416. package/dist/types/src/components/Participant/Participant.d.ts +0 -6
  417. package/dist/types/src/components/Participant/Participant.d.ts.map +0 -1
  418. package/dist/types/src/components/Participant/ParticipantGrid.d.ts +0 -11
  419. package/dist/types/src/components/Participant/ParticipantGrid.d.ts.map +0 -1
  420. package/dist/types/src/components/Participant/index.d.ts +0 -3
  421. package/dist/types/src/components/Participant/index.d.ts.map +0 -1
  422. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.d.ts +0 -32
  423. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.d.ts.map +0 -1
  424. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +0 -178
  425. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +0 -1
  426. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts +0 -21
  427. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts.map +0 -1
  428. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.d.ts +0 -12
  429. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.d.ts.map +0 -1
  430. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.stories.d.ts +0 -164
  431. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.stories.d.ts.map +0 -1
  432. package/dist/types/src/components/ResponsiveGrid/index.d.ts +0 -4
  433. package/dist/types/src/components/ResponsiveGrid/index.d.ts.map +0 -1
  434. package/dist/types/src/containers/CallDebugPanel/CallDebugPanel.d.ts +0 -15
  435. package/dist/types/src/containers/CallDebugPanel/CallDebugPanel.d.ts.map +0 -1
  436. package/dist/types/src/containers/CallDebugPanel/index.d.ts +0 -2
  437. package/dist/types/src/containers/CallSidebar/CallSidebar.d.ts +0 -3
  438. package/dist/types/src/containers/CallSidebar/CallSidebar.d.ts.map +0 -1
  439. package/dist/types/src/containers/CallSidebar/index.d.ts +0 -2
  440. package/dist/types/src/containers/CallSidebar/index.d.ts.map +0 -1
  441. package/dist/types/src/containers/ChannelContainer/ChannelContainer.d.ts +0 -12
  442. package/dist/types/src/containers/ChannelContainer/ChannelContainer.d.ts.map +0 -1
  443. package/dist/types/src/containers/ChannelContainer/ChannelContainer.stories.d.ts +0 -162
  444. package/dist/types/src/containers/ChannelContainer/ChannelContainer.stories.d.ts.map +0 -1
  445. package/dist/types/src/containers/ChannelContainer/index.d.ts +0 -2
  446. package/dist/types/src/containers/ChannelContainer/index.d.ts.map +0 -1
  447. package/dist/types/src/containers/ChatContainer/ChatContainer.d.ts +0 -16
  448. package/dist/types/src/containers/ChatContainer/ChatContainer.d.ts.map +0 -1
  449. package/dist/types/src/containers/ChatContainer/ChatContainer.stories.d.ts.map +0 -1
  450. package/dist/types/src/containers/ChatContainer/index.d.ts +0 -4
  451. package/dist/types/src/containers/ChatContainer/index.d.ts.map +0 -1
  452. package/dist/types/src/containers/ThreadCompanion/ThreadCompanion.d.ts +0 -8
  453. package/dist/types/src/containers/ThreadCompanion/ThreadCompanion.d.ts.map +0 -1
  454. package/dist/types/src/containers/ThreadCompanion/index.d.ts +0 -2
  455. package/dist/types/src/containers/ThreadCompanion/index.d.ts.map +0 -1
  456. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts +0 -2
  457. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts.map +0 -1
  458. package/dist/types/src/hooks/useDebugMode.d.ts +0 -2
  459. package/dist/types/src/hooks/useDebugMode.d.ts.map +0 -1
  460. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts +0 -2
  461. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts.map +0 -1
  462. package/dist/types/src/hooks/useVideoStreamTrack.d.ts +0 -3
  463. package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +0 -1
  464. package/dist/types/src/operations/create-channel-thread.d.ts +0 -5
  465. package/dist/types/src/operations/create-channel-thread.d.ts.map +0 -1
  466. package/dist/types/src/operations/definitions.d.ts.map +0 -1
  467. package/dist/types/src/testing/stories.d.ts +0 -3
  468. package/dist/types/src/testing/stories.d.ts.map +0 -1
  469. package/dist/types/src/types/Channel.d.ts +0 -715
  470. package/dist/types/src/types/Channel.d.ts.map +0 -1
  471. package/dist/types/src/types/capabilities.d.ts +0 -24
  472. package/dist/types/src/types/capabilities.d.ts.map +0 -1
  473. package/src/calls/call-manager.ts +0 -270
  474. package/src/calls/call-swarm-synchronizer.ts +0 -350
  475. package/src/calls/index.ts +0 -10
  476. package/src/calls/media-manager.ts +0 -378
  477. package/src/calls/speaking-monitor.ts +0 -85
  478. package/src/calls/types.ts +0 -74
  479. package/src/calls/util/audio.ts +0 -58
  480. package/src/calls/util/calls-service.ts +0 -580
  481. package/src/calls/util/history-cache.ts +0 -27
  482. package/src/calls/util/index.ts +0 -8
  483. package/src/calls/util/media.ts +0 -52
  484. package/src/calls/util/stub-media-streams.ts +0 -127
  485. package/src/calls/util/task-scheduling.ts +0 -92
  486. package/src/calls-service.stories.tsx +0 -230
  487. package/src/capabilities/call-manager.ts +0 -27
  488. package/src/capabilities/react-root.tsx +0 -20
  489. package/src/components/Call/Call.tsx +0 -93
  490. package/src/components/Call/Toolbar.tsx +0 -199
  491. package/src/components/Call/index.ts +0 -6
  492. package/src/components/Lobby/Lobby.tsx +0 -122
  493. package/src/components/Lobby/index.ts +0 -5
  494. package/src/components/Media/AudioStream.tsx +0 -67
  495. package/src/components/Media/VideoObject.stories.tsx +0 -59
  496. package/src/components/Media/VideoObject.tsx +0 -58
  497. package/src/components/Media/index.ts +0 -6
  498. package/src/components/Participant/Participant.tsx +0 -77
  499. package/src/components/Participant/ParticipantGrid.tsx +0 -88
  500. package/src/components/Participant/index.ts +0 -6
  501. package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +0 -157
  502. package/src/components/ResponsiveGrid/ResponsiveGrid.tsx +0 -341
  503. package/src/components/ResponsiveGrid/ResponsiveGridItem.tsx +0 -134
  504. package/src/components/ResponsiveGrid/ResponsivePanel.stories.tsx +0 -53
  505. package/src/components/ResponsiveGrid/ResponsivePanel.tsx +0 -31
  506. package/src/components/ResponsiveGrid/index.ts +0 -7
  507. package/src/containers/CallDebugPanel/CallDebugPanel.tsx +0 -173
  508. package/src/containers/CallDebugPanel/index.ts +0 -5
  509. package/src/containers/CallSidebar/CallSidebar.tsx +0 -18
  510. package/src/containers/CallSidebar/index.ts +0 -5
  511. package/src/containers/ChannelContainer/ChannelContainer.stories.tsx +0 -61
  512. package/src/containers/ChannelContainer/ChannelContainer.tsx +0 -223
  513. package/src/containers/ChannelContainer/index.ts +0 -5
  514. package/src/containers/ChatContainer/ChatContainer.tsx +0 -131
  515. package/src/containers/ChatContainer/index.ts +0 -8
  516. package/src/containers/ThreadCompanion/index.ts +0 -5
  517. package/src/hooks/useBlackCanvasStreamTrack.tsx +0 -27
  518. package/src/hooks/useDebugMode.ts +0 -25
  519. package/src/hooks/useInaudibleAudioStreamTrack.tsx +0 -27
  520. package/src/hooks/useVideoStreamTrack.tsx +0 -36
  521. package/src/operations/create-channel-thread.ts +0 -26
  522. package/src/operations/definitions.ts +0 -177
  523. package/src/testing/stories.ts +0 -51
  524. package/src/types/Channel.ts +0 -37
  525. package/src/types/capabilities.ts +0 -36
  526. package/src/typings/peermetrics-webrtc-stats.d.ts +0 -46
  527. package/src/typings.d.ts +0 -8
  528. /package/dist/lib/{browser/chunk-J5LGTIGS.mjs.map → neutral/ChannelChat-LZEDFJVD.mjs.map} +0 -0
  529. /package/dist/lib/{browser/types → neutral/blueprints}/index.mjs.map +0 -0
  530. /package/dist/lib/{browser → neutral}/chunk-J5LGTIGS.mjs +0 -0
  531. /package/dist/lib/{node-esm/chunk-HSLMI22Q.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
  532. /package/dist/lib/{node-esm/types → neutral/hooks}/index.mjs.map +0 -0
@@ -0,0 +1,259 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import React, { type RefObject, useLayoutEffect, useMemo, useRef, useState } from 'react';
6
+
7
+ import { type SpaceMember } from '@dxos/react-client/echo';
8
+ import { type Identity } from '@dxos/react-client/halo';
9
+ import { ScrollArea, type ThemedClassName, useThemeContext, useTranslation } from '@dxos/react-ui';
10
+ import { composable, composableProps } from '@dxos/react-ui';
11
+ import {
12
+ type MessageMetadata,
13
+ MessageTextbox,
14
+ Thread as ThreadComponent,
15
+ type ThreadRootProps,
16
+ threadLayout,
17
+ } from '@dxos/react-ui-thread';
18
+ import { type Message } from '@dxos/types';
19
+ import { createBasicExtensions, createThemeExtensions, listener, type Extension } from '@dxos/ui-editor';
20
+ import { mx } from '@dxos/ui-theme';
21
+ import { isNonNullable } from '@dxos/util';
22
+
23
+ import { meta } from '#meta';
24
+
25
+ import { command } from '../../extensions';
26
+ import { getMessageMetadata } from '../../util';
27
+ import { MessagePanel } from '../MessagePanel';
28
+
29
+ export type ChatProps = ThemedClassName<
30
+ {
31
+ /** Stable id used for the underlying thread root and message metadata. */
32
+ id: string;
33
+ /** Identity used to attribute outgoing messages in the textbox metadata. */
34
+ identity?: Identity;
35
+ /** Space members for rendering sender names/avatars on incoming messages. */
36
+ members: SpaceMember[];
37
+ /** Messages to render in order. */
38
+ messages: readonly Message.Message[];
39
+ /** Activity indicator (e.g. processing) shown beneath the textbox. */
40
+ activity?: boolean;
41
+ /**
42
+ * Called with the user's textbox content when they press send.
43
+ * Returning `true` signals the message was accepted; the textbox is then cleared.
44
+ */
45
+ onSend: (text: string) => boolean;
46
+ autoFocusTextbox?: boolean;
47
+ /**
48
+ * Where the composer sits relative to the messages.
49
+ * - `'top'` (default) — composer follows the messages at intrinsic height,
50
+ * suitable for inline comment threads.
51
+ * - `'bottom'` — composer pinned to the bottom of the panel, messages
52
+ * scrolling above it. Suitable for full-panel multi-party chat.
53
+ */
54
+ orientation?: ChatOrientation;
55
+ /**
56
+ * When true, hide the composer textbox and activity indicator. Used for
57
+ * channels whose source-of-truth lives elsewhere (e.g. externally-synced
58
+ * Slack/Discord channels keyed by a foreign id) — sending isn't meaningful
59
+ * because there is no local-write path back to the source.
60
+ */
61
+ readOnly?: boolean;
62
+ } & Pick<ThreadRootProps, 'current'>
63
+ >;
64
+
65
+ export type ChatOrientation = 'top' | 'bottom';
66
+
67
+ /**
68
+ * Pure chat UI: scrollable message list + composer textbox + activity indicator.
69
+ * Owns its own UI state (textbox content, scroll position, editor extensions) but
70
+ * does not load data or invoke operations — the caller passes messages and an
71
+ * `onSend` callback. Used by both `ThreadContainer` (AutoMerge `Thread`) and
72
+ * `ChannelArticle`'s feed-backed channel chat.
73
+ */
74
+ export const Chat = composable<HTMLDivElement, ChatProps>(
75
+ (
76
+ {
77
+ id,
78
+ identity,
79
+ members,
80
+ messages,
81
+ activity,
82
+ onSend,
83
+ autoFocusTextbox,
84
+ current,
85
+ orientation = 'top',
86
+ readOnly,
87
+ ...props
88
+ },
89
+ forwardedRef,
90
+ ) => {
91
+ const { t } = useTranslation(meta.id);
92
+ const { themeMode } = useThemeContext();
93
+
94
+ const scrollRef = useRef<HTMLDivElement | null>(null);
95
+ const sentinelRef = useRef<HTMLDivElement | null>(null);
96
+ const [autoFocus, setAutoFocus] = useState(autoFocusTextbox);
97
+
98
+ // Force the editor to remount after a successful send so its content resets.
99
+ const [_count, _setCount] = useState(0);
100
+
101
+ const textboxMetadata = getMessageMetadata(id, identity);
102
+ const messageRef = useRef('');
103
+ const extensions = useMemo(
104
+ () => [
105
+ createBasicExtensions({ placeholder: t('message.placeholder') }),
106
+ createThemeExtensions({ themeMode }),
107
+ listener({ onChange: ({ text }) => (messageRef.current = text) }),
108
+ command,
109
+ ],
110
+ [themeMode, _count],
111
+ );
112
+
113
+ const scrollToEnd = (behavior: ScrollBehavior) =>
114
+ setTimeout(() => sentinelRef.current?.scrollIntoView({ behavior, block: 'end' }), 10);
115
+
116
+ useLayoutEffect(() => {
117
+ scrollToEnd('instant');
118
+ }, []);
119
+ // NOTE: Auto-scroll on new messages is intentionally not implemented here. Smooth-scroll
120
+ // animations were causing ResizeObserver feedback loops with CodeMirror/ScrollArea. The
121
+ // proper fix is "scroll only if user is already at the bottom" — deferred to a follow-up.
122
+
123
+ const handleSend = () => {
124
+ const text = messageRef.current;
125
+ if (!text?.length) {
126
+ return false;
127
+ }
128
+
129
+ const accepted = onSend(text);
130
+ if (!accepted) {
131
+ return false;
132
+ }
133
+
134
+ messageRef.current = '';
135
+ setAutoFocus(true);
136
+ scrollToEnd('smooth');
137
+ _setCount((count) => count + 1);
138
+ return true;
139
+ };
140
+
141
+ const filteredMessages = messages.filter(isNonNullable);
142
+ const renderState: ChatRenderState = {
143
+ messages: filteredMessages,
144
+ members,
145
+ activity,
146
+ extensions,
147
+ autoFocus,
148
+ handleSend,
149
+ textboxMetadata,
150
+ scrollRef,
151
+ sentinelRef,
152
+ readOnly,
153
+ };
154
+
155
+ return orientation === 'bottom' ? (
156
+ <ChannelLayout
157
+ {...composableProps(props, { classNames: 'flex flex-col h-full min-h-0' })}
158
+ id={id}
159
+ ref={forwardedRef}
160
+ state={renderState}
161
+ />
162
+ ) : (
163
+ <ThreadLayout
164
+ {...composableProps(props, { classNames: 'dx-container grid-rows-[1fr_min-content_min-content]' })}
165
+ id={id}
166
+ current={current}
167
+ ref={forwardedRef}
168
+ state={renderState}
169
+ />
170
+ );
171
+ },
172
+ );
173
+
174
+ //
175
+ // Internal layout helpers — share state via the ChatRenderState bag.
176
+ //
177
+
178
+ type ChatRenderState = {
179
+ messages: Message.Message[];
180
+ members: SpaceMember[];
181
+ activity?: boolean;
182
+ extensions: Extension[];
183
+ autoFocus?: boolean;
184
+ handleSend: () => boolean;
185
+ textboxMetadata: MessageMetadata;
186
+ scrollRef: RefObject<HTMLDivElement | null>;
187
+ sentinelRef: RefObject<HTMLDivElement | null>;
188
+ readOnly?: boolean;
189
+ };
190
+
191
+ type LayoutProps = React.HTMLAttributes<HTMLDivElement> & {
192
+ id: string;
193
+ state: ChatRenderState;
194
+ };
195
+
196
+ /** Thread layout — composer follows messages at intrinsic height. */
197
+ const ThreadLayout = React.forwardRef<HTMLDivElement, LayoutProps & Pick<ThreadRootProps, 'current'>>(
198
+ ({ id, current, state, ...props }, ref) => {
199
+ const { t } = useTranslation(meta.id);
200
+ const { messages, members, activity, extensions, autoFocus, handleSend, textboxMetadata, sentinelRef, readOnly } =
201
+ state;
202
+ return (
203
+ <ThreadComponent.Root {...props} id={id} current={current} ref={ref}>
204
+ <ScrollArea.Root classNames='col-span-2' orientation='vertical'>
205
+ <ScrollArea.Viewport ref={sentinelRef}>
206
+ <div className={mx(threadLayout, 'place-self-end')}>
207
+ {messages.map((message) => (
208
+ <MessagePanel key={message.id} message={message} members={members} />
209
+ ))}
210
+ </div>
211
+ </ScrollArea.Viewport>
212
+ </ScrollArea.Root>
213
+ {!readOnly && (
214
+ <>
215
+ <MessageTextbox extensions={extensions} autoFocus={autoFocus} onSend={handleSend} {...textboxMetadata} />
216
+ <ThreadComponent.Status activity={activity}>{t('activity.message')}</ThreadComponent.Status>
217
+ </>
218
+ )}
219
+ </ThreadComponent.Root>
220
+ );
221
+ },
222
+ );
223
+
224
+ /** Channel layout — composer pinned to the bottom, messages scroll above it. */
225
+ const ChannelLayout = React.forwardRef<HTMLDivElement, LayoutProps>(({ id, state, ...props }, ref) => {
226
+ const { t } = useTranslation(meta.id);
227
+ const {
228
+ messages,
229
+ members,
230
+ activity,
231
+ extensions,
232
+ autoFocus,
233
+ handleSend,
234
+ textboxMetadata,
235
+ scrollRef,
236
+ sentinelRef,
237
+ readOnly,
238
+ } = state;
239
+ return (
240
+ <div {...props} id={id} ref={ref}>
241
+ <div ref={scrollRef} className='flex-1 min-h-0 overflow-y-auto'>
242
+ {messages.map((message) => (
243
+ <div key={message.id} className='grid grid-cols-[var(--dx-rail-size)_1fr] w-full'>
244
+ <MessagePanel message={message} members={members} />
245
+ </div>
246
+ ))}
247
+ <div ref={sentinelRef} />
248
+ </div>
249
+ {!readOnly && (
250
+ <>
251
+ <div className='shrink-0 grid grid-cols-[var(--dx-rail-size)_1fr]'>
252
+ <MessageTextbox extensions={extensions} autoFocus={autoFocus} onSend={handleSend} {...textboxMetadata} />
253
+ </div>
254
+ <div className='shrink-0 px-2 pb-1 text-xs text-description'>{activity ? t('activity.message') : null}</div>
255
+ </>
256
+ )}
257
+ </div>
258
+ );
259
+ });
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export * from './Chat';
@@ -6,28 +6,30 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
  import * as Effect from 'effect/Effect';
7
7
  import React from 'react';
8
8
 
9
- import { OperationPlugin, RuntimePlugin } from '@dxos/app-framework';
9
+ import { ProcessManagerPlugin } from '@dxos/app-framework';
10
10
  import { withPluginManager } from '@dxos/app-framework/testing';
11
11
  import { Obj, Query, Relation } from '@dxos/echo';
12
12
  import { TestSchema } from '@dxos/echo/testing';
13
- import { ClientPlugin } from '@dxos/plugin-client';
13
+ import { ClientPlugin } from '@dxos/plugin-client/testing';
14
14
  import { initializeIdentity } from '@dxos/plugin-client/testing';
15
15
  import { random } from '@dxos/random';
16
- import { useDatabase, useQuery } from '@dxos/react-client/echo';
16
+ import { useQuery, useSpaces } from '@dxos/react-client/echo';
17
17
  import { useIdentity } from '@dxos/react-client/halo';
18
18
  import { useAsyncEffect } from '@dxos/react-ui';
19
19
  import { withLayout, withTheme, Loading } from '@dxos/react-ui/testing';
20
20
  import { AnchoredTo, Message, Thread } from '@dxos/types';
21
21
 
22
+ import { translations } from '#translations';
23
+
22
24
  import { createCommentThread, createProposalThread } from '../../testing/data';
23
- import { translations } from '../../translations';
24
25
  import { CommentsPanel } from './CommentsPanel';
25
26
 
26
27
  random.seed(1);
27
28
 
28
29
  const DefaultStory = () => {
29
30
  const identity = useIdentity();
30
- const db = useDatabase();
31
+ const [space] = useSpaces();
32
+ const db = space?.db;
31
33
  const anchors = useQuery(db, Query.type(AnchoredTo.AnchoredTo));
32
34
 
33
35
  useAsyncEffect(async () => {
@@ -69,8 +71,7 @@ const meta = {
69
71
  // Currently this is required due to useOnEditAnalytics.
70
72
  withPluginManager({
71
73
  plugins: [
72
- OperationPlugin(),
73
- RuntimePlugin(),
74
+ ProcessManagerPlugin(),
74
75
  ClientPlugin({
75
76
  types: [Message.Message, Thread.Thread, AnchoredTo.AnchoredTo],
76
77
  onClientInitialized: ({ client }) =>
@@ -41,19 +41,19 @@ export const CommentsPanel = ({ anchors, currentId, showResolvedThreads, ...prop
41
41
 
42
42
  if (filteredAnchors.length === 0) {
43
43
  return (
44
- <div role='none' className='p-form-padding'>
44
+ <div className='p-form-padding'>
45
45
  <Message.Root>
46
- <Message.Title>
46
+ <Message.Content>
47
47
  <Trans
48
48
  {...{
49
49
  t,
50
50
  i18nKey: 'no-comments.message',
51
51
  components: {
52
- commentIcon: <Icon icon='ph--chat-text--regular' size={4} classNames='w-block' />,
52
+ commentIcon: <Icon icon='ph--chat-text--regular' size={4} classNames='dx-icon-inline' />,
53
53
  },
54
54
  }}
55
55
  />
56
- </Message.Title>
56
+ </Message.Content>
57
57
  </Message.Root>
58
58
  </div>
59
59
  );
@@ -63,7 +63,7 @@ export const CommentsPanel = ({ anchors, currentId, showResolvedThreads, ...prop
63
63
  <div>
64
64
  {filteredAnchors.map((anchor) => {
65
65
  const thread = Relation.getSource(anchor) as Thread.Thread;
66
- const threadId = Obj.getDXN(thread).toString();
66
+ const threadId = Obj.getURI(thread);
67
67
  return <CommentsThread key={threadId} anchor={anchor} current={currentId === threadId} {...props} />;
68
68
  })}
69
69
  </div>
@@ -54,10 +54,10 @@ export const CommentsThread = ({
54
54
  const detached = !anchor.anchor;
55
55
  const thread = Relation.getSource(anchor) as Thread.Thread;
56
56
  const [messages] = useObject(thread, 'messages');
57
- const activity = useStatus(space, Obj.getDXN(thread).toString());
57
+ const activity = useStatus(space, Obj.getURI(thread));
58
58
  const threadScrollRef = useRef<HTMLDivElement | null>(null);
59
59
 
60
- const textboxMetadata = getMessageMetadata(Obj.getDXN(thread).toString(), identity);
60
+ const textboxMetadata = getMessageMetadata(Obj.getURI(thread), identity);
61
61
 
62
62
  // TODO(wittjosiah): This is a hack to reset the editor after a message is sent.
63
63
  const [state, setState] = useState({});
@@ -97,14 +97,13 @@ export const CommentsThread = ({
97
97
 
98
98
  return (
99
99
  <ThreadComponent.Root
100
- id={Obj.getDXN(thread).toString()}
100
+ id={Obj.getURI(thread)}
101
101
  classNames='pt-2 border-b border-subdued-separator last:border-none'
102
102
  current={current}
103
103
  onClickCapture={handleAttend}
104
104
  onFocusCapture={handleAttend}
105
105
  >
106
106
  <div
107
- role='none'
108
107
  className={mx(
109
108
  'col-span-2 grid grid-cols-[var(--dx-rail-size)_1fr_min-content]',
110
109
  hoverableControls,
@@ -118,7 +117,7 @@ export const CommentsThread = ({
118
117
  ) : (
119
118
  <ThreadComponent.Header>{thread.name}</ThreadComponent.Header>
120
119
  )}
121
- <div role='none' className={buttonGroupClassNames}>
120
+ <div className={buttonGroupClassNames}>
122
121
  {thread.status === 'staged' && <Tag palette='neutral'>{t('draft.button')}</Tag>}
123
122
  {onResolve && !(thread?.status === 'staged') && (
124
123
  <IconButton
@@ -147,7 +146,7 @@ export const CommentsThread = ({
147
146
 
148
147
  {messages?.map((ref) => (
149
148
  <MessagePanel
150
- key={ref.dxn.toString()}
149
+ key={ref.uri}
151
150
  editable
152
151
  message={ref}
153
152
  members={members}
@@ -157,16 +156,21 @@ export const CommentsThread = ({
157
156
  ))}
158
157
 
159
158
  {/*
160
- TODO(wittjosiah): Can't autofocus this generally.
161
- There can be multiple threads with inputs and they can't all be focused.
162
- Also, it steals focus from documents when first rendered.
163
- Need to find a way to autofocus in one scenario only: when a new thread is created.
159
+ Autofocus only newly-created (draft) threads. Once the first message is
160
+ posted the thread transitions from 'staged' → 'active' and stops stealing
161
+ focus, satisfying the "one scenario only" constraint flagged in the
162
+ previous TODO (multiple active threads no longer fight for focus).
164
163
  */}
165
- <MessageTextbox extensions={extensions} onSend={handleComment} {...textboxMetadata} />
164
+ <MessageTextbox
165
+ autoFocus={thread.status === 'staged'}
166
+ extensions={extensions}
167
+ onSend={handleComment}
168
+ {...textboxMetadata}
169
+ />
166
170
 
167
171
  <ThreadComponent.Status activity={activity}>{t('activity.message')}</ThreadComponent.Status>
168
172
 
169
- <div role='none' className='h-px -mt-px' ref={threadScrollRef} />
173
+ <div className='h-px -mt-px' ref={threadScrollRef} />
170
174
  </ThreadComponent.Root>
171
175
  );
172
176
  };
@@ -82,7 +82,10 @@ export const MessagePanel = ({
82
82
  (message.sender.identityDid && member.identity.did === message.sender.identityDid) ||
83
83
  (message.sender.identityKey && PublicKey.equals(member.identity.identityKey, message.sender.identityKey)),
84
84
  )?.identity;
85
- const messageMetadata = getMessageMetadata(message.id, senderIdentity);
85
+ // Pass `message.sender` as the fallback so externally-synced messages
86
+ // (Slack, etc.) display the source-side sender name instead of "Anonymous"
87
+ // when no DXOS identity matches.
88
+ const messageMetadata = getMessageMetadata(message.id, senderIdentity, message.sender);
86
89
  const userIsAuthor = identity?.did === messageMetadata.authorId;
87
90
  const proposalBlock = message.blocks.find((block) => block._tag === 'proposal');
88
91
  const references = message.blocks.filter((block) => block._tag === 'reference').map((block) => block.reference);
@@ -90,14 +93,14 @@ export const MessagePanel = ({
90
93
  return (
91
94
  <MessageRoot {...messageMetadata} classNames={[hoverableControls, hoverableFocusedWithinControls]}>
92
95
  <MessageHeading authorName={messageMetadata.authorName} timestamp={messageMetadata.timestamp}>
93
- <div role='none' className={buttonGroupClassNames}>
96
+ <div className={buttonGroupClassNames}>
94
97
  {userIsAuthor && editable && (
95
98
  <IconButton
96
99
  data-testid={editing ? 'thread.message.save' : 'thread.message.edit'}
97
100
  variant='ghost'
98
101
  icon={editing ? 'ph--check--regular' : 'ph--pencil-simple--regular'}
99
102
  iconOnly
100
- label={t(editing ? 'save message label' : 'edit message label')}
103
+ label={t(editing ? 'save-message.label' : 'edit-message.label')}
101
104
  classNames={[buttonClassNames, hoverableControlItem]}
102
105
  onClick={handleEdit}
103
106
  />
@@ -188,15 +191,11 @@ const TextboxBlock = ({
188
191
  editing && view?.focus();
189
192
  }, [editing, view]);
190
193
 
191
- return <div role='none' ref={parentRef} className='me-4' {...focusAttributes} />;
194
+ return <div ref={parentRef} className='me-4' {...focusAttributes} />;
192
195
  };
193
196
 
194
197
  const ProposalBlock = ({ block }: { block: ContentBlock.Proposal }) => {
195
- return (
196
- <div role='none' className='me-4 italic'>
197
- {block.text}
198
- </div>
199
- );
198
+ return <div className='me-4 italic'>{block.text}</div>;
200
199
  };
201
200
 
202
201
  const MessageBlockObjectTile = forwardRef<HTMLDivElement, { subject: Obj.Unknown }>(({ subject }, forwardedRef) => {
@@ -6,7 +6,8 @@ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
6
 
7
7
  import { withLayout, withTheme } from '@dxos/react-ui/testing';
8
8
 
9
- import { translations } from '../../translations';
9
+ import { translations } from '#translations';
10
+
10
11
  import { ThreadSettings } from './ThreadSettings';
11
12
 
12
13
  const meta = {
@@ -13,7 +13,6 @@ import { type Settings } from '#types';
13
13
 
14
14
  export type ThreadSettingsProps = AppSurface.SettingsArticleProps<Settings.Settings>;
15
15
 
16
- // TODO(burdon): Settings.
17
16
  export const ThreadSettings = ({ settings: _settings }: ThreadSettingsProps) => {
18
17
  const { t: _t } = useTranslation(meta.id);
19
18
  return <SettingsForm.Viewport></SettingsForm.Viewport>;
@@ -4,7 +4,7 @@
4
4
 
5
5
  import { type ComponentType, lazy } from 'react';
6
6
 
7
- export * from './Call';
7
+ export * from './Chat';
8
8
  export * from './CommentsPanel';
9
9
  export * from './MessagePanel';
10
10
 
@@ -0,0 +1,105 @@
1
+ //
2
+ // Copyright 2023 DXOS.org
3
+ //
4
+
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
6
+ import * as Effect from 'effect/Effect';
7
+ import React from 'react';
8
+
9
+ import { Capability } from '@dxos/app-framework';
10
+ import { withPluginManager } from '@dxos/app-framework/testing';
11
+ import { AppCapabilities } from '@dxos/app-toolkit';
12
+ import { Feed, Query } from '@dxos/echo';
13
+ import { createFeedServiceLayer } from '@dxos/echo-db';
14
+ import { ClientPlugin } from '@dxos/plugin-client/testing';
15
+ import { initializeIdentity } from '@dxos/plugin-client/testing';
16
+ import { SpacePlugin } from '@dxos/plugin-space/testing';
17
+ import { corePlugins } from '@dxos/plugin-testing';
18
+ import { Config } from '@dxos/react-client';
19
+ import { useQuery, useSpaces } from '@dxos/react-client/echo';
20
+ import { withLayout, withTheme, Loading } from '@dxos/react-ui/testing';
21
+ import { Channel, Message, Thread } from '@dxos/types';
22
+
23
+ import { translations } from '#translations';
24
+
25
+ import { ThreadPlugin } from '../../ThreadPlugin';
26
+ import { ChannelArticle, type ChannelArticleProps } from './ChannelArticle';
27
+
28
+ // TODO(wittjosiah): Channel doesn't render full height.
29
+ const DefaultStory = ({ roomId }: ChannelArticleProps) => {
30
+ const [space] = useSpaces();
31
+ const [channel] = useQuery(space?.db, Query.type(Channel.Channel));
32
+ if (!channel) {
33
+ return <Loading data={{ channel }} />;
34
+ }
35
+
36
+ return <ChannelArticle subject={channel} attendableId='story' roomId={roomId} role='article' />;
37
+ };
38
+
39
+ const meta = {
40
+ title: 'plugins/plugin-thread/containers/ChannelArticle',
41
+ component: ChannelArticle,
42
+ render: DefaultStory,
43
+ decorators: [
44
+ withTheme(),
45
+ withLayout({ layout: 'column' }),
46
+ withPluginManager({
47
+ capabilities: [
48
+ Capability.contributes(AppCapabilities.Schema, [Channel.Channel, Feed.Feed, Thread.Thread, Message.Message]),
49
+ ],
50
+ plugins: [
51
+ ...corePlugins(),
52
+ ClientPlugin({
53
+ types: [Channel.Channel, Feed.Feed, Thread.Thread, Message.Message],
54
+ config: new Config({
55
+ runtime: {
56
+ services: {
57
+ edge: {
58
+ url: 'https://edge.dxos.workers.dev/',
59
+ },
60
+ iceProviders: [
61
+ {
62
+ urls: 'https://edge.dxos.workers.dev/ice',
63
+ },
64
+ ],
65
+ },
66
+ },
67
+ }),
68
+ onClientInitialized: ({ client }) =>
69
+ Effect.gen(function* () {
70
+ const { personalSpace } = yield* initializeIdentity(client);
71
+ const channel = personalSpace.db.add(Channel.make({ name: 'general' }));
72
+ const feed = yield* Effect.promise(() => channel.feed.load());
73
+ const seed = [
74
+ Message.make({ sender: { role: 'user' }, blocks: [{ _tag: 'text', text: 'Hello, channel.' }] }),
75
+ Message.make({
76
+ sender: { role: 'user' },
77
+ blocks: [{ _tag: 'text', text: 'Messages are stored in the feed.' }],
78
+ }),
79
+ ];
80
+ yield* Feed.append(feed, seed).pipe(Effect.provide(createFeedServiceLayer(personalSpace.queues)));
81
+ }),
82
+ }),
83
+ SpacePlugin({}),
84
+ ThreadPlugin(),
85
+ ],
86
+ }),
87
+ ],
88
+ parameters: {
89
+ translations,
90
+ },
91
+ } satisfies Meta<typeof ChannelArticle>;
92
+
93
+ export default meta;
94
+
95
+ type Story = StoryObj<typeof meta>;
96
+
97
+ export const Default: Story = {
98
+ args: {
99
+ // Fixed room for testing.
100
+ subject: undefined,
101
+ attendableId: 'story',
102
+ role: 'article',
103
+ roomId: '04a1d1911703b8e929d0649021a965',
104
+ },
105
+ };
@@ -0,0 +1,42 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { type AppSurface } from '@dxos/app-toolkit/ui';
8
+ import { getSpace } from '@dxos/react-client/echo';
9
+ import { Panel } from '@dxos/react-ui';
10
+ import { type Channel } from '@dxos/types';
11
+
12
+ import { ChannelChat } from '../ChannelChat';
13
+
14
+ export type ChannelArticleProps = AppSurface.ObjectArticleProps<
15
+ Channel.Channel | undefined,
16
+ {
17
+ roomId?: string;
18
+ fullscreen?: boolean;
19
+ }
20
+ >;
21
+
22
+ /**
23
+ * Renders the channel chat. The "Start video call" action and the in-call surface
24
+ * are contributed by plugin-calls — this container is call-agnostic.
25
+ */
26
+ // TODO(burdon): Create Radix style layout.
27
+ // TODO(burdon): Restore graph-driven toolbar so plugin-calls can contribute a "Start video call" action (F-1.1).
28
+ export const ChannelArticle = ({ subject: channel }: ChannelArticleProps) => {
29
+ const space = getSpace(channel);
30
+
31
+ if (channel && space) {
32
+ return (
33
+ <Panel.Root classNames='dx-document'>
34
+ <Panel.Content asChild>
35
+ <ChannelChat classNames='border' space={space} channel={channel} />
36
+ </Panel.Content>
37
+ </Panel.Root>
38
+ );
39
+ }
40
+
41
+ return null;
42
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export { ChannelArticle as default } from './ChannelArticle';