@vertesia/ui 1.5.0-dev.20260722.120446Z → 1.5.0-dev.20260725.083715Z

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 (307) hide show
  1. package/lib/core/components/shadcn/filters/filterBar.d.ts.map +1 -1
  2. package/lib/core/components/shadcn/filters/filterBar.js +1 -1
  3. package/lib/core/components/shadcn/filters/filterBar.js.map +1 -1
  4. package/lib/core/components/shadcn/modal/dialog.d.ts +1 -1
  5. package/lib/core/components/shadcn/modal/dialog.d.ts.map +1 -1
  6. package/lib/core/components/shadcn/modal/dialog.js +2 -0
  7. package/lib/core/components/shadcn/modal/dialog.js.map +1 -1
  8. package/lib/core/components/shadcn/tabs.d.ts +12 -1
  9. package/lib/core/components/shadcn/tabs.d.ts.map +1 -1
  10. package/lib/core/components/shadcn/tabs.js +12 -4
  11. package/lib/core/components/shadcn/tabs.js.map +1 -1
  12. package/lib/features/agent/chat/AgentRightPanel.d.ts +5 -1
  13. package/lib/features/agent/chat/AgentRightPanel.d.ts.map +1 -1
  14. package/lib/features/agent/chat/AgentRightPanel.js +2 -2
  15. package/lib/features/agent/chat/AgentRightPanel.js.map +1 -1
  16. package/lib/features/agent/chat/ArtifactsTab.d.ts +5 -1
  17. package/lib/features/agent/chat/ArtifactsTab.d.ts.map +1 -1
  18. package/lib/features/agent/chat/ArtifactsTab.js +48 -11
  19. package/lib/features/agent/chat/ArtifactsTab.js.map +1 -1
  20. package/lib/features/agent/chat/DocumentEditingActionCard.d.ts +6 -0
  21. package/lib/features/agent/chat/DocumentEditingActionCard.d.ts.map +1 -0
  22. package/lib/features/agent/chat/DocumentEditingActionCard.js +129 -0
  23. package/lib/features/agent/chat/DocumentEditingActionCard.js.map +1 -0
  24. package/lib/features/agent/chat/ModernAgentConversation.d.ts +19 -1
  25. package/lib/features/agent/chat/ModernAgentConversation.d.ts.map +1 -1
  26. package/lib/features/agent/chat/ModernAgentConversation.js +125 -27
  27. package/lib/features/agent/chat/ModernAgentConversation.js.map +1 -1
  28. package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.d.ts +45 -0
  29. package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.d.ts.map +1 -0
  30. package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.js +40 -0
  31. package/lib/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.js.map +1 -0
  32. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts +3 -1
  33. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.d.ts.map +1 -1
  34. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js +94 -49
  35. package/lib/features/agent/chat/ModernAgentOutput/AllMessagesMixed.js.map +1 -1
  36. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts +2 -1
  37. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.d.ts.map +1 -1
  38. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js +9 -5
  39. package/lib/features/agent/chat/ModernAgentOutput/AttachmentPreview.js.map +1 -1
  40. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts +25 -0
  41. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.d.ts.map +1 -0
  42. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js +33 -0
  43. package/lib/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.js.map +1 -0
  44. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts +3 -1
  45. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.d.ts.map +1 -1
  46. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js +22 -24
  47. package/lib/features/agent/chat/ModernAgentOutput/MessageItem.js.map +1 -1
  48. package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.d.ts +14 -0
  49. package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.d.ts.map +1 -0
  50. package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.js +21 -0
  51. package/lib/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.js.map +1 -0
  52. package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.d.ts +30 -0
  53. package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.d.ts.map +1 -0
  54. package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.js +53 -0
  55. package/lib/features/agent/chat/ModernAgentOutput/ResourceChip.js.map +1 -0
  56. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.d.ts.map +1 -1
  57. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js +21 -2
  58. package/lib/features/agent/chat/ModernAgentOutput/ToolCallGroup.js.map +1 -1
  59. package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.d.ts +6 -0
  60. package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.d.ts.map +1 -0
  61. package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.js +29 -0
  62. package/lib/features/agent/chat/ModernAgentOutput/resourceLinks.js.map +1 -0
  63. package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.d.ts +33 -0
  64. package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.d.ts.map +1 -0
  65. package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.js +129 -0
  66. package/lib/features/agent/chat/ModernAgentOutput/resourceSummary.js.map +1 -0
  67. package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts +7 -0
  68. package/lib/features/agent/chat/ModernAgentOutput/utils.d.ts.map +1 -1
  69. package/lib/features/agent/chat/ModernAgentOutput/utils.js +11 -1
  70. package/lib/features/agent/chat/ModernAgentOutput/utils.js.map +1 -1
  71. package/lib/features/agent/chat/hooks/useAgentStream.d.ts +1 -1
  72. package/lib/features/agent/chat/hooks/useAgentStream.d.ts.map +1 -1
  73. package/lib/features/agent/chat/hooks/useAgentStream.js +24 -9
  74. package/lib/features/agent/chat/hooks/useAgentStream.js.map +1 -1
  75. package/lib/features/agent/chat/index.d.ts +2 -1
  76. package/lib/features/agent/chat/index.d.ts.map +1 -1
  77. package/lib/features/agent/chat/index.js +3 -0
  78. package/lib/features/agent/chat/index.js.map +1 -1
  79. package/lib/features/store/objects/DocumentSearchResults.js +2 -2
  80. package/lib/features/store/objects/DocumentSearchResults.js.map +1 -1
  81. package/lib/features/store/objects/components/ContentOverview.d.ts +2 -1
  82. package/lib/features/store/objects/components/ContentOverview.d.ts.map +1 -1
  83. package/lib/features/store/objects/components/ContentOverview.js +86 -15
  84. package/lib/features/store/objects/components/ContentOverview.js.map +1 -1
  85. package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.d.ts +16 -0
  86. package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.d.ts.map +1 -0
  87. package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.js +116 -0
  88. package/lib/features/store/objects/components/DocumentEditingConfigurationSelector.js.map +1 -0
  89. package/lib/features/store/objects/components/DocumentEditingLockStatus.d.ts +7 -0
  90. package/lib/features/store/objects/components/DocumentEditingLockStatus.d.ts.map +1 -0
  91. package/lib/features/store/objects/components/DocumentEditingLockStatus.js +13 -0
  92. package/lib/features/store/objects/components/DocumentEditingLockStatus.js.map +1 -0
  93. package/lib/features/store/objects/components/DocumentEditingPanel.d.ts +48 -0
  94. package/lib/features/store/objects/components/DocumentEditingPanel.d.ts.map +1 -0
  95. package/lib/features/store/objects/components/DocumentEditingPanel.js +720 -0
  96. package/lib/features/store/objects/components/DocumentEditingPanel.js.map +1 -0
  97. package/lib/features/store/objects/components/TextEditorPanel.d.ts.map +1 -1
  98. package/lib/features/store/objects/components/TextEditorPanel.js +22 -9
  99. package/lib/features/store/objects/components/TextEditorPanel.js.map +1 -1
  100. package/lib/features/store/objects/components/documentArtifactRefs.d.ts +26 -0
  101. package/lib/features/store/objects/components/documentArtifactRefs.d.ts.map +1 -0
  102. package/lib/features/store/objects/components/documentArtifactRefs.js +52 -0
  103. package/lib/features/store/objects/components/documentArtifactRefs.js.map +1 -0
  104. package/lib/features/store/objects/components/documentEditingAgentConfig.d.ts +4 -0
  105. package/lib/features/store/objects/components/documentEditingAgentConfig.d.ts.map +1 -0
  106. package/lib/features/store/objects/components/documentEditingAgentConfig.js +40 -0
  107. package/lib/features/store/objects/components/documentEditingAgentConfig.js.map +1 -0
  108. package/lib/features/store/objects/components/documentEditingPrompts.d.ts +3 -0
  109. package/lib/features/store/objects/components/documentEditingPrompts.d.ts.map +1 -0
  110. package/lib/features/store/objects/components/documentEditingPrompts.js +13 -0
  111. package/lib/features/store/objects/components/documentEditingPrompts.js.map +1 -0
  112. package/lib/features/store/objects/components/documentEditingRun.d.ts +27 -0
  113. package/lib/features/store/objects/components/documentEditingRun.d.ts.map +1 -0
  114. package/lib/features/store/objects/components/documentEditingRun.js +126 -0
  115. package/lib/features/store/objects/components/documentEditingRun.js.map +1 -0
  116. package/lib/features/store/objects/components/documentEditingTarget.d.ts +20 -0
  117. package/lib/features/store/objects/components/documentEditingTarget.d.ts.map +1 -0
  118. package/lib/features/store/objects/components/documentEditingTarget.js +40 -0
  119. package/lib/features/store/objects/components/documentEditingTarget.js.map +1 -0
  120. package/lib/features/store/objects/components/index.d.ts +1 -0
  121. package/lib/features/store/objects/components/index.d.ts.map +1 -1
  122. package/lib/features/store/objects/components/index.js +1 -0
  123. package/lib/features/store/objects/components/index.js.map +1 -1
  124. package/lib/features/store/objects/components/useContentPanelHooks.d.ts +5 -1
  125. package/lib/features/store/objects/components/useContentPanelHooks.d.ts.map +1 -1
  126. package/lib/features/store/objects/components/useContentPanelHooks.js +53 -29
  127. package/lib/features/store/objects/components/useContentPanelHooks.js.map +1 -1
  128. package/lib/features/store/objects/components/useDownloadFile.d.ts +2 -1
  129. package/lib/features/store/objects/components/useDownloadFile.d.ts.map +1 -1
  130. package/lib/features/store/objects/components/useDownloadFile.js +3 -0
  131. package/lib/features/store/objects/components/useDownloadFile.js.map +1 -1
  132. package/lib/features/store/objects/selection/actions/StartWorkflowButton.js +1 -1
  133. package/lib/features/store/objects/selection/actions/StartWorkflowButton.js.map +1 -1
  134. package/lib/i18n/locales/ar.json +118 -1
  135. package/lib/i18n/locales/de.json +118 -1
  136. package/lib/i18n/locales/en.json +118 -0
  137. package/lib/i18n/locales/es.json +118 -1
  138. package/lib/i18n/locales/fr.json +118 -1
  139. package/lib/i18n/locales/it.json +118 -1
  140. package/lib/i18n/locales/ja.json +118 -1
  141. package/lib/i18n/locales/ko.json +118 -1
  142. package/lib/i18n/locales/pt.json +118 -1
  143. package/lib/i18n/locales/ru.json +118 -1
  144. package/lib/i18n/locales/tr.json +118 -1
  145. package/lib/i18n/locales/zh-TW.json +118 -1
  146. package/lib/i18n/locales/zh.json +118 -1
  147. package/lib/rich-text/EditorToolbar.d.ts +37 -0
  148. package/lib/rich-text/EditorToolbar.d.ts.map +1 -0
  149. package/lib/rich-text/EditorToolbar.js +215 -0
  150. package/lib/rich-text/EditorToolbar.js.map +1 -0
  151. package/lib/rich-text/VertesiaRichTextEditor.d.ts +26 -0
  152. package/lib/rich-text/VertesiaRichTextEditor.d.ts.map +1 -0
  153. package/lib/rich-text/VertesiaRichTextEditor.js +67 -0
  154. package/lib/rich-text/VertesiaRichTextEditor.js.map +1 -0
  155. package/lib/rich-text/index.d.ts +2 -0
  156. package/lib/rich-text/index.d.ts.map +1 -0
  157. package/lib/rich-text/index.js +2 -0
  158. package/lib/rich-text/index.js.map +1 -0
  159. package/lib/vertesia-ui-core.js +2 -2
  160. package/lib/vertesia-ui-core.js.map +1 -1
  161. package/lib/vertesia-ui-features.js +35 -30
  162. package/lib/vertesia-ui-features.js.map +1 -1
  163. package/lib/vertesia-ui-i18n.js +14 -14
  164. package/lib/vertesia-ui-i18n.js.map +1 -1
  165. package/lib/vertesia-ui-rich-text.js +5 -0
  166. package/lib/vertesia-ui-rich-text.js.map +1 -0
  167. package/lib/vertesia-ui-widgets.js +25 -7
  168. package/lib/vertesia-ui-widgets.js.map +1 -1
  169. package/lib/widgets/markdown/AgentResourceResolver.d.ts +31 -0
  170. package/lib/widgets/markdown/AgentResourceResolver.d.ts.map +1 -0
  171. package/lib/widgets/markdown/AgentResourceResolver.js +39 -0
  172. package/lib/widgets/markdown/AgentResourceResolver.js.map +1 -0
  173. package/lib/widgets/markdown/ArtifactEditingSurface.d.ts +63 -0
  174. package/lib/widgets/markdown/ArtifactEditingSurface.d.ts.map +1 -0
  175. package/lib/widgets/markdown/ArtifactEditingSurface.js +582 -0
  176. package/lib/widgets/markdown/ArtifactEditingSurface.js.map +1 -0
  177. package/lib/widgets/markdown/CollaborativeMarkdownRenderer.d.ts +69 -0
  178. package/lib/widgets/markdown/CollaborativeMarkdownRenderer.d.ts.map +1 -0
  179. package/lib/widgets/markdown/CollaborativeMarkdownRenderer.js +374 -0
  180. package/lib/widgets/markdown/CollaborativeMarkdownRenderer.js.map +1 -0
  181. package/lib/widgets/markdown/MarkdownLink.d.ts +3 -1
  182. package/lib/widgets/markdown/MarkdownLink.d.ts.map +1 -1
  183. package/lib/widgets/markdown/MarkdownLink.js +41 -14
  184. package/lib/widgets/markdown/MarkdownLink.js.map +1 -1
  185. package/lib/widgets/markdown/MarkdownRenderer.d.ts +8 -1
  186. package/lib/widgets/markdown/MarkdownRenderer.d.ts.map +1 -1
  187. package/lib/widgets/markdown/MarkdownRenderer.js +20 -4
  188. package/lib/widgets/markdown/MarkdownRenderer.js.map +1 -1
  189. package/lib/widgets/markdown/index.d.ts +5 -1
  190. package/lib/widgets/markdown/index.d.ts.map +1 -1
  191. package/lib/widgets/markdown/index.js +5 -1
  192. package/lib/widgets/markdown/index.js.map +1 -1
  193. package/lib/widgets/markdown/normalizeCustomSchemeLinks.d.ts.map +1 -1
  194. package/lib/widgets/markdown/normalizeCustomSchemeLinks.js +14 -2
  195. package/lib/widgets/markdown/normalizeCustomSchemeLinks.js.map +1 -1
  196. package/lib/widgets/markdown/textDiff.d.ts +52 -0
  197. package/lib/widgets/markdown/textDiff.d.ts.map +1 -0
  198. package/lib/widgets/markdown/textDiff.js +362 -0
  199. package/lib/widgets/markdown/textDiff.js.map +1 -0
  200. package/lib/widgets/markdown/useArtifactContent.d.ts +5 -3
  201. package/lib/widgets/markdown/useArtifactContent.d.ts.map +1 -1
  202. package/lib/widgets/markdown/useArtifactContent.js +6 -3
  203. package/lib/widgets/markdown/useArtifactContent.js.map +1 -1
  204. package/lib/widgets/markdown/useResolvedUrl.d.ts +1 -5
  205. package/lib/widgets/markdown/useResolvedUrl.d.ts.map +1 -1
  206. package/lib/widgets/markdown/useResolvedUrl.js +19 -31
  207. package/lib/widgets/markdown/useResolvedUrl.js.map +1 -1
  208. package/lib/widgets/xml-viewer/hooks/useXMLViewer.d.ts +9 -0
  209. package/lib/widgets/xml-viewer/hooks/useXMLViewer.d.ts.map +1 -1
  210. package/lib/widgets/xml-viewer/hooks/useXMLViewer.js +20 -17
  211. package/lib/widgets/xml-viewer/hooks/useXMLViewer.js.map +1 -1
  212. package/package.json +13 -9
  213. package/src/__tests__/a11y.test.tsx +4 -1
  214. package/src/__tests__/axe-helper.ts +17 -7
  215. package/src/__tests__/setup.ts +25 -0
  216. package/src/core/components/shadcn/filters/filterBar.tsx +1 -0
  217. package/src/core/components/shadcn/modal/dialog.tsx +3 -1
  218. package/src/core/components/shadcn/tabs.test.tsx +65 -0
  219. package/src/core/components/shadcn/tabs.tsx +25 -3
  220. package/src/features/agent/chat/AgentRightPanel.tsx +16 -1
  221. package/src/features/agent/chat/ArtifactsTab.test.tsx +55 -0
  222. package/src/features/agent/chat/ArtifactsTab.tsx +203 -52
  223. package/src/features/agent/chat/DocumentEditingActionCard.test.tsx +105 -0
  224. package/src/features/agent/chat/DocumentEditingActionCard.tsx +210 -0
  225. package/src/features/agent/chat/ModernAgentConversation.test.tsx +237 -40
  226. package/src/features/agent/chat/ModernAgentConversation.tsx +247 -75
  227. package/src/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.test.tsx +79 -0
  228. package/src/features/agent/chat/ModernAgentOutput/AgentMarkdownAnchor.tsx +94 -0
  229. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.test.tsx +257 -34
  230. package/src/features/agent/chat/ModernAgentOutput/AllMessagesMixed.tsx +217 -105
  231. package/src/features/agent/chat/ModernAgentOutput/AttachmentPreview.tsx +17 -0
  232. package/src/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.test.tsx +44 -0
  233. package/src/features/agent/chat/ModernAgentOutput/CollapsibleAgentMarkdown.tsx +88 -0
  234. package/src/features/agent/chat/ModernAgentOutput/MessageItem.tsx +30 -46
  235. package/src/features/agent/chat/ModernAgentOutput/ResourceChangeSummary.tsx +40 -0
  236. package/src/features/agent/chat/ModernAgentOutput/ResourceChip.test.tsx +148 -0
  237. package/src/features/agent/chat/ModernAgentOutput/ResourceChip.tsx +141 -0
  238. package/src/features/agent/chat/ModernAgentOutput/ToolCallGroup.tsx +33 -1
  239. package/src/features/agent/chat/ModernAgentOutput/resourceLinks.tsx +43 -0
  240. package/src/features/agent/chat/ModernAgentOutput/resourceSummary.test.ts +229 -0
  241. package/src/features/agent/chat/ModernAgentOutput/resourceSummary.ts +152 -0
  242. package/src/features/agent/chat/ModernAgentOutput/utils.test.ts +17 -0
  243. package/src/features/agent/chat/ModernAgentOutput/utils.ts +14 -1
  244. package/src/features/agent/chat/hooks/useAgentStream.test.tsx +188 -0
  245. package/src/features/agent/chat/hooks/useAgentStream.ts +28 -8
  246. package/src/features/agent/chat/index.ts +11 -0
  247. package/src/features/store/objects/DocumentSearchResults.tsx +2 -2
  248. package/src/features/store/objects/components/ContentOverview.tsx +216 -65
  249. package/src/features/store/objects/components/DocumentEditingConfigurationSelector.test.ts +34 -0
  250. package/src/features/store/objects/components/DocumentEditingConfigurationSelector.tsx +211 -0
  251. package/src/features/store/objects/components/DocumentEditingLockStatus.test.tsx +32 -0
  252. package/src/features/store/objects/components/DocumentEditingLockStatus.tsx +45 -0
  253. package/src/features/store/objects/components/DocumentEditingPanel.test.tsx +336 -0
  254. package/src/features/store/objects/components/DocumentEditingPanel.tsx +1236 -0
  255. package/src/features/store/objects/components/TextEditorPanel.test.tsx +48 -0
  256. package/src/features/store/objects/components/TextEditorPanel.tsx +41 -20
  257. package/src/features/store/objects/components/documentArtifactRefs.test.ts +65 -0
  258. package/src/features/store/objects/components/documentArtifactRefs.ts +72 -0
  259. package/src/features/store/objects/components/documentEditingAgentConfig.test.ts +28 -0
  260. package/src/features/store/objects/components/documentEditingAgentConfig.ts +41 -0
  261. package/src/features/store/objects/components/documentEditingPrompts.test.ts +26 -0
  262. package/src/features/store/objects/components/documentEditingPrompts.ts +12 -0
  263. package/src/features/store/objects/components/documentEditingRun.test.ts +176 -0
  264. package/src/features/store/objects/components/documentEditingRun.ts +184 -0
  265. package/src/features/store/objects/components/documentEditingTarget.test.ts +96 -0
  266. package/src/features/store/objects/components/documentEditingTarget.ts +63 -0
  267. package/src/features/store/objects/components/index.ts +1 -0
  268. package/src/features/store/objects/components/useContentPanelHooks.ts +52 -27
  269. package/src/features/store/objects/components/useDownloadFile.test.ts +20 -0
  270. package/src/features/store/objects/components/useDownloadFile.ts +5 -1
  271. package/src/features/store/objects/selection/actions/StartWorkflowButton.tsx +2 -2
  272. package/src/i18n/locales/ar.json +118 -1
  273. package/src/i18n/locales/de.json +118 -1
  274. package/src/i18n/locales/en.json +118 -0
  275. package/src/i18n/locales/es.json +118 -1
  276. package/src/i18n/locales/fr.json +118 -1
  277. package/src/i18n/locales/it.json +118 -1
  278. package/src/i18n/locales/ja.json +118 -1
  279. package/src/i18n/locales/ko.json +118 -1
  280. package/src/i18n/locales/pt.json +118 -1
  281. package/src/i18n/locales/ru.json +118 -1
  282. package/src/i18n/locales/tr.json +118 -1
  283. package/src/i18n/locales/zh-TW.json +118 -1
  284. package/src/i18n/locales/zh.json +118 -1
  285. package/src/rich-text/EditorToolbar.tsx +708 -0
  286. package/src/rich-text/VertesiaRichTextEditor.test.tsx +211 -0
  287. package/src/rich-text/VertesiaRichTextEditor.tsx +241 -0
  288. package/src/rich-text/index.ts +9 -0
  289. package/src/session/UserSession.test.ts +11 -11
  290. package/src/widgets/markdown/AgentResourceResolver.test.ts +24 -0
  291. package/src/widgets/markdown/AgentResourceResolver.tsx +70 -0
  292. package/src/widgets/markdown/ArtifactEditingSurface.test.tsx +537 -0
  293. package/src/widgets/markdown/ArtifactEditingSurface.tsx +878 -0
  294. package/src/widgets/markdown/CollaborativeMarkdownRenderer.test.tsx +484 -0
  295. package/src/widgets/markdown/CollaborativeMarkdownRenderer.tsx +825 -0
  296. package/src/widgets/markdown/MarkdownLink.test.tsx +122 -0
  297. package/src/widgets/markdown/MarkdownLink.tsx +102 -17
  298. package/src/widgets/markdown/MarkdownRenderer.tsx +30 -3
  299. package/src/widgets/markdown/index.ts +39 -1
  300. package/src/widgets/markdown/normalizeCustomSchemeLinks.ts +15 -2
  301. package/src/widgets/markdown/textDiff.test.ts +156 -0
  302. package/src/widgets/markdown/textDiff.ts +399 -0
  303. package/src/widgets/markdown/useArtifactContent.ts +9 -3
  304. package/src/widgets/markdown/useResolvedUrl.test.ts +29 -40
  305. package/src/widgets/markdown/useResolvedUrl.ts +33 -35
  306. package/src/widgets/xml-viewer/hooks/useXMLViewer.test.ts +26 -0
  307. package/src/widgets/xml-viewer/hooks/useXMLViewer.ts +23 -18
@@ -0,0 +1,210 @@
1
+ import { cn } from '@vertesia/ui/core';
2
+ import { useUITranslation } from '@vertesia/ui/i18n';
3
+ import {
4
+ diffWordSegments,
5
+ type MarkdownBlockType,
6
+ type MarkdownEditingAction,
7
+ type MarkdownEditingResource,
8
+ } from '@vertesia/ui/widgets';
9
+ import { MessageSquareText, PencilLine } from 'lucide-react';
10
+ import { type ReactNode, useMemo } from 'react';
11
+ import { CollapsibleAgentMarkdown } from './ModernAgentOutput/CollapsibleAgentMarkdown.js';
12
+
13
+ const BLOCK_TYPES = new Set<MarkdownBlockType>([
14
+ 'heading',
15
+ 'paragraph',
16
+ 'list',
17
+ 'list_item',
18
+ 'blockquote',
19
+ 'code_block',
20
+ 'table',
21
+ 'separator',
22
+ ]);
23
+
24
+ function asRecord(value: unknown): Record<string, unknown> | undefined {
25
+ return value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : undefined;
26
+ }
27
+
28
+ function readString(record: Record<string, unknown> | undefined, key: string): string | undefined {
29
+ const value = record?.[key];
30
+ return typeof value === 'string' && value.length > 0 ? value : undefined;
31
+ }
32
+
33
+ function parseResource(value: unknown): MarkdownEditingResource | undefined {
34
+ const resource = asRecord(value);
35
+ const kind = readString(resource, 'kind');
36
+ if (kind === 'store_document') {
37
+ const documentId = readString(resource, 'document_id');
38
+ if (!documentId) return undefined;
39
+ const name = readString(resource, 'name');
40
+ return { kind, document_id: documentId, ...(name ? { name } : {}) };
41
+ }
42
+ if (kind === 'agent_artifact') {
43
+ const runId = readString(resource, 'run_id');
44
+ const path = readString(resource, 'path');
45
+ return runId && path ? { kind, run_id: runId, path } : undefined;
46
+ }
47
+ return undefined;
48
+ }
49
+
50
+ export function parseMarkdownEditingAction(value: unknown): MarkdownEditingAction | undefined {
51
+ const action = asRecord(value);
52
+ const anchor = asRecord(action?.anchor);
53
+ const operationId = readString(action, 'operation_id');
54
+ const actionType = readString(action, 'action');
55
+ const blockId = readString(anchor, 'block_id');
56
+ const blockType = readString(anchor, 'block_type');
57
+ const exactText = readString(anchor, 'exact_text');
58
+ const resource = parseResource(action?.resource);
59
+ if (
60
+ !operationId ||
61
+ (actionType !== 'comment' && actionType !== 'edit') ||
62
+ !blockId ||
63
+ !blockType ||
64
+ !BLOCK_TYPES.has(blockType as MarkdownBlockType) ||
65
+ !exactText ||
66
+ !resource
67
+ ) {
68
+ return undefined;
69
+ }
70
+
71
+ const baseVersion = readString(action, 'base_version');
72
+ const comment = readString(action, 'comment');
73
+ const userChange = asRecord(action?.user_change);
74
+ const before = readString(userChange, 'before');
75
+ const after = readString(userChange, 'after');
76
+ if (actionType === 'comment' && !comment) return undefined;
77
+ if (actionType === 'edit' && (!before || !after)) return undefined;
78
+
79
+ const updatedDocumentId = readString(action, 'updated_document_id');
80
+ return {
81
+ operation_id: operationId,
82
+ resource,
83
+ ...(baseVersion ? { base_version: baseVersion } : {}),
84
+ action: actionType,
85
+ anchor: {
86
+ block_id: blockId,
87
+ block_type: blockType as MarkdownBlockType,
88
+ exact_text: exactText,
89
+ },
90
+ ...(comment ? { comment } : {}),
91
+ ...(before && after ? { user_change: { before, after } } : {}),
92
+ ...(action?.applied === true ? { applied: true } : {}),
93
+ ...(updatedDocumentId ? { updated_document_id: updatedDocumentId } : {}),
94
+ };
95
+ }
96
+
97
+ function shortenId(id: string): string {
98
+ return id.length > 12 ? `${id.slice(0, 4)}…${id.slice(-4)}` : id;
99
+ }
100
+
101
+ function resourceLabel(resource: MarkdownEditingResource): string {
102
+ if (resource.kind === 'store_document') return resource.name || shortenId(resource.document_id);
103
+ return resource.path;
104
+ }
105
+
106
+ // A referenced block is a preview, not a document title — keep headings at body scale so a heading
107
+ // block doesn't render as a full-size H1, and trim the outer block margins.
108
+ const COMPACT_MARKDOWN_CLASS = [
109
+ '[&_h1]:text-base [&_h2]:text-base [&_h3]:text-base [&_h4]:text-base [&_h5]:text-base [&_h6]:text-base',
110
+ '[&_h1]:leading-snug [&_h2]:leading-snug [&_h3]:leading-snug',
111
+ '[&_:first-child]:mt-0 [&_:last-child]:mb-0',
112
+ ].join(' ');
113
+
114
+ function SourcePreview({ children, className }: { children: ReactNode; className?: string }) {
115
+ return (
116
+ <pre
117
+ className={cn(
118
+ 'm-0 max-h-48 overflow-auto whitespace-pre-wrap font-mono text-xs leading-5 text-foreground/80',
119
+ className,
120
+ )}
121
+ >
122
+ {children}
123
+ </pre>
124
+ );
125
+ }
126
+
127
+ function ChangeDiff({ before, after }: { before: string; after: string }) {
128
+ const segments = useMemo(() => diffWordSegments(before, after), [before, after]);
129
+ return (
130
+ <SourcePreview>
131
+ {segments.map((segment, index) => {
132
+ if (segment.type === 'removed') {
133
+ return (
134
+ <del
135
+ key={index}
136
+ className="rounded-xs bg-mixer-destructive/15 text-destructive line-through decoration-destructive/50"
137
+ >
138
+ {segment.text}
139
+ </del>
140
+ );
141
+ }
142
+ if (segment.type === 'added') {
143
+ return (
144
+ <ins key={index} className="rounded-xs bg-mixer-success/15 text-success no-underline">
145
+ {segment.text}
146
+ </ins>
147
+ );
148
+ }
149
+ return <span key={index}>{segment.text}</span>;
150
+ })}
151
+ </SourcePreview>
152
+ );
153
+ }
154
+
155
+ export function DocumentEditingActionCard({ action }: { action: MarkdownEditingAction }) {
156
+ const { t } = useUITranslation();
157
+ const isComment = action.action === 'comment';
158
+ const isApplied = action.applied === true;
159
+ const blockType = action.anchor.block_type.replaceAll('_', ' ');
160
+ const Icon = isComment ? MessageSquareText : PencilLine;
161
+ const artifactRunId = action.resource.kind === 'agent_artifact' ? action.resource.run_id : undefined;
162
+
163
+ return (
164
+ <div className="min-w-0 space-y-2 text-start" data-document-edit-action={action.action}>
165
+ <div className="flex min-w-0 items-center gap-1.5 text-sm text-muted">
166
+ <Icon className="size-4 shrink-0" aria-hidden="true" />
167
+ <span className="shrink-0 font-medium text-foreground">
168
+ {isComment
169
+ ? t('agent.documentEditCardComment')
170
+ : isApplied
171
+ ? t('agent.documentEditCardApplied')
172
+ : t('agent.documentEditCardDirectEdit')}
173
+ </span>
174
+ <span aria-hidden="true">·</span>
175
+ <span className="shrink-0 capitalize">{blockType}</span>
176
+ <span aria-hidden="true">·</span>
177
+ <span className="truncate">{resourceLabel(action.resource)}</span>
178
+ </div>
179
+
180
+ {isComment ? (
181
+ <>
182
+ {action.comment ? (
183
+ <CollapsibleAgentMarkdown
184
+ artifactRunId={artifactRunId}
185
+ disableCollapse
186
+ className={COMPACT_MARKDOWN_CLASS}
187
+ >
188
+ {action.comment}
189
+ </CollapsibleAgentMarkdown>
190
+ ) : null}
191
+ <CollapsibleAgentMarkdown
192
+ artifactRunId={artifactRunId}
193
+ disableCollapse
194
+ className={cn(
195
+ 'border-s-2 border-mixer-muted/30 ps-3 text-foreground/70',
196
+ COMPACT_MARKDOWN_CLASS,
197
+ )}
198
+ >
199
+ {action.anchor.exact_text}
200
+ </CollapsibleAgentMarkdown>
201
+ </>
202
+ ) : (
203
+ <ChangeDiff
204
+ before={action.user_change?.before ?? action.anchor.exact_text}
205
+ after={action.user_change?.after ?? ''}
206
+ />
207
+ )}
208
+ </div>
209
+ );
210
+ }
@@ -85,53 +85,79 @@ vi.mock('./ModernAgentOutput/MessageInput', () => ({
85
85
  },
86
86
  }));
87
87
 
88
- vi.mock('./ModernAgentOutput/AllMessagesMixed', () => ({
89
- default: ({
90
- messages,
91
- streamingMessages,
92
- isCompleted,
93
- bottomRef,
94
- onSendMessage,
95
- showInitialRequest,
96
- renderRequestInputControls,
97
- activeWorkstream,
98
- onActiveWorkstreamChange,
99
- }: {
100
- messages: AgentMessage[];
101
- streamingMessages: Map<string, unknown>;
102
- isCompleted?: boolean;
103
- bottomRef: React.RefObject<HTMLDivElement>;
104
- onSendMessage?: (message: string, metadata?: Record<string, unknown>) => void;
105
- showInitialRequest?: boolean;
106
- renderRequestInputControls?: boolean;
107
- activeWorkstream?: string;
108
- onActiveWorkstreamChange?: (workstreamId: string) => void;
109
- }) => {
110
- mocks.allMessagesMixedProps({
88
+ vi.mock('./ModernAgentOutput/AllMessagesMixed', async () => {
89
+ const { useAgentResourceResolver } = await import('@vertesia/ui/widgets');
90
+ return {
91
+ default: ({
111
92
  messages,
112
93
  streamingMessages,
113
94
  isCompleted,
95
+ bottomRef,
114
96
  onSendMessage,
97
+ onOpenArtifact,
115
98
  showInitialRequest,
116
99
  renderRequestInputControls,
117
100
  activeWorkstream,
118
101
  onActiveWorkstreamChange,
119
- });
120
- return (
121
- <div>
122
- <div data-testid="rendered-message-count">{messages.length}</div>
123
- <div data-testid="rendered-streaming-count">{streamingMessages.size}</div>
124
- <button type="button" disabled={!onSendMessage} onClick={() => onSendMessage?.('follow up')}>
125
- inline send
126
- </button>
127
- <div ref={bottomRef} data-testid="bottom-sentinel" />
128
- </div>
129
- );
130
- },
131
- }));
102
+ }: {
103
+ messages: AgentMessage[];
104
+ streamingMessages: Map<string, unknown>;
105
+ isCompleted?: boolean;
106
+ bottomRef: React.RefObject<HTMLDivElement>;
107
+ onSendMessage?: (message: string, metadata?: Record<string, unknown>) => void;
108
+ onOpenArtifact?: (path: string) => void;
109
+ showInitialRequest?: boolean;
110
+ renderRequestInputControls?: boolean;
111
+ activeWorkstream?: string;
112
+ onActiveWorkstreamChange?: (workstreamId: string) => void;
113
+ }) => {
114
+ const resolveResource = useAgentResourceResolver();
115
+ const resourceTarget = resolveResource(
116
+ { type: 'document', id: 'document-1' },
117
+ { source: 'structured', workflowRunId: 'agent-run-1' },
118
+ );
119
+ mocks.allMessagesMixedProps({
120
+ messages,
121
+ streamingMessages,
122
+ isCompleted,
123
+ onSendMessage,
124
+ onOpenArtifact,
125
+ showInitialRequest,
126
+ renderRequestInputControls,
127
+ activeWorkstream,
128
+ onActiveWorkstreamChange,
129
+ });
130
+ return (
131
+ <div>
132
+ <div data-testid="rendered-message-count">{messages.length}</div>
133
+ <div data-testid="rendered-streaming-count">{streamingMessages.size}</div>
134
+ <div data-testid="resource-target">
135
+ {resourceTarget.kind === 'navigate' ? resourceTarget.href : resourceTarget.kind}
136
+ </div>
137
+ <button type="button" disabled={!onSendMessage} onClick={() => onSendMessage?.('follow up')}>
138
+ inline send
139
+ </button>
140
+ <button
141
+ type="button"
142
+ disabled={!onOpenArtifact}
143
+ onClick={() => onOpenArtifact?.('files/report.md')}
144
+ >
145
+ open artifact
146
+ </button>
147
+ <div ref={bottomRef} data-testid="bottom-sentinel" />
148
+ </div>
149
+ );
150
+ },
151
+ };
152
+ });
132
153
 
133
154
  vi.mock('./AgentRightPanel.js', () => ({
134
- AgentRightPanel: (props: { activeWorkstreams?: Array<{ workstream_id: string; status: string }> }) => {
155
+ AgentRightPanel: (props: {
156
+ activeWorkstreams?: Array<{ workstream_id: string; status: string }>;
157
+ onSendMessage?: (message: string, metadata?: Record<string, unknown>) => void;
158
+ selectedArtifactPath?: string | null;
159
+ activeTab?: string;
160
+ }) => {
135
161
  mocks.rightPanelProps(props);
136
162
  return <div data-testid="agent-right-panel" />;
137
163
  },
@@ -213,6 +239,17 @@ function latestAllMessagesMixedProps() {
213
239
  | undefined;
214
240
  }
215
241
 
242
+ function latestRightPanelProps() {
243
+ const calls = mocks.rightPanelProps.mock.calls;
244
+ return calls[calls.length - 1]?.[0] as
245
+ | {
246
+ onSendMessage?: (message: string, metadata?: Record<string, unknown>) => void;
247
+ selectedArtifactPath?: string | null;
248
+ activeTab?: string;
249
+ }
250
+ | undefined;
251
+ }
252
+
216
253
  describe('ModernAgentConversation send handling', () => {
217
254
  beforeEach(() => {
218
255
  vi.clearAllMocks();
@@ -253,6 +290,63 @@ describe('ModernAgentConversation send handling', () => {
253
290
  vi.restoreAllMocks();
254
291
  });
255
292
 
293
+ it('reports when the main agent turn starts and returns to idle', async () => {
294
+ const onAgentWorkingChange = vi.fn();
295
+ mockStreamState({
296
+ messages: [createMessage(AgentMessageType.QUESTION, 'make an edit')],
297
+ isCompleted: false,
298
+ agentRunStatus: 'RUNNING',
299
+ });
300
+
301
+ const view = renderConversation({ onAgentWorkingChange });
302
+
303
+ await waitFor(() => expect(onAgentWorkingChange).toHaveBeenLastCalledWith(true));
304
+
305
+ mockStreamState({
306
+ messages: [
307
+ createMessage(AgentMessageType.QUESTION, 'make an edit'),
308
+ createMessage(AgentMessageType.IDLE, 'Waiting for your command...'),
309
+ ],
310
+ isCompleted: true,
311
+ agentRunStatus: 'RUNNING',
312
+ });
313
+ view.rerender(
314
+ <ModernAgentConversation
315
+ agentRunId="agent-run-1"
316
+ title="Agent"
317
+ hideHeader
318
+ hideMessageInput
319
+ showRightPanel={false}
320
+ onAgentWorkingChange={onAgentWorkingChange}
321
+ />,
322
+ );
323
+
324
+ await waitFor(() => expect(onAgentWorkingChange).toHaveBeenLastCalledWith(false));
325
+ });
326
+
327
+ it('reports a failed workflow as idle even when its final stream message is an error', async () => {
328
+ const onAgentWorkingChange = vi.fn();
329
+ mockStreamState({
330
+ messages: [createMessage(AgentMessageType.ERROR, 'Agent failed')],
331
+ isCompleted: false,
332
+ agentRunStatus: 'FAILED',
333
+ });
334
+
335
+ renderConversation({ onAgentWorkingChange });
336
+
337
+ await waitFor(() => expect(onAgentWorkingChange).toHaveBeenLastCalledWith(false));
338
+ });
339
+
340
+ it('provides its resourceResolver prop to conversation content', () => {
341
+ mockStreamState({ messages: [createMessage(AgentMessageType.COMPLETE, 'done')] });
342
+
343
+ renderConversation({
344
+ resourceResolver: (resource) => ({ kind: 'navigate', href: `/host/documents/${resource.id}` }),
345
+ });
346
+
347
+ expect(screen.getByTestId('resource-target').textContent).toBe('/host/documents/document-1');
348
+ });
349
+
256
350
  it('restarts a terminal continuable run before sending the follow-up message', async () => {
257
351
  mockStreamState({
258
352
  messages: [createMessage(AgentMessageType.COMPLETE, 'done')],
@@ -286,6 +380,62 @@ describe('ModernAgentConversation send handling', () => {
286
380
  expect(mocks.updateOptimisticMessageStatus).toHaveBeenCalledWith(expect.any(String), 'received');
287
381
  });
288
382
 
383
+ it('opens a Markdown artifact in the side panel and allows collaboration for an active run', async () => {
384
+ mocks.useAgentPlans.mockReturnValue({
385
+ plans: [],
386
+ activePlanIndex: 0,
387
+ setActivePlanIndex: vi.fn(),
388
+ workstreamStatusMap: new Map(),
389
+ showInput: true,
390
+ showSlidingPanel: true,
391
+ setShowSlidingPanel: vi.fn(),
392
+ });
393
+ mockStreamState({
394
+ messages: [createMessage(AgentMessageType.IDLE, 'Waiting for your command...')],
395
+ isCompleted: true,
396
+ agentRunStatus: 'RUNNING',
397
+ });
398
+
399
+ renderConversation({ showRightPanel: true, showArtifacts: true, interactive: true });
400
+
401
+ fireEvent.click(screen.getByRole('button', { name: 'open artifact' }));
402
+
403
+ await waitFor(() => {
404
+ expect(latestRightPanelProps()).toEqual(
405
+ expect.objectContaining({
406
+ activeTab: 'artifacts',
407
+ selectedArtifactPath: 'files/report.md',
408
+ onSendMessage: expect.any(Function),
409
+ }),
410
+ );
411
+ });
412
+ });
413
+
414
+ it('keeps artifacts read-only when their originating run is completed', () => {
415
+ mocks.useAgentPlans.mockReturnValue({
416
+ plans: [],
417
+ activePlanIndex: 0,
418
+ setActivePlanIndex: vi.fn(),
419
+ workstreamStatusMap: new Map(),
420
+ showInput: true,
421
+ showSlidingPanel: true,
422
+ setShowSlidingPanel: vi.fn(),
423
+ });
424
+ mockStreamState({
425
+ messages: [createMessage(AgentMessageType.COMPLETE, 'done')],
426
+ agentRunStatus: 'COMPLETED',
427
+ });
428
+
429
+ renderConversation({
430
+ showRightPanel: true,
431
+ showArtifacts: true,
432
+ interactive: true,
433
+ onRestart: vi.fn(),
434
+ });
435
+
436
+ expect(latestRightPanelProps()?.onSendMessage).toBeUndefined();
437
+ });
438
+
289
439
  it('binds ready uploaded files into the sent message and clears them after send', async () => {
290
440
  const clearProcessingFiles = vi.fn();
291
441
  const readyFile: ConversationFile = {
@@ -325,9 +475,8 @@ describe('ModernAgentConversation send handling', () => {
325
475
  });
326
476
 
327
477
  const userInputCall = mocks.sendSignal.mock.calls.find((call) => call[1] === 'UserInput');
328
- expect((userInputCall?.[2] as { message: string }).message).toContain(
329
- '[report.pdf](artifact:files/report.pdf)',
330
- );
478
+ const userInputPayload = userInputCall?.[2] as { message: string } | undefined;
479
+ expect(userInputPayload?.message).toContain('[report.pdf](artifact:files/report.pdf)');
331
480
  await waitFor(() => {
332
481
  expect(clearProcessingFiles).toHaveBeenCalledTimes(1);
333
482
  });
@@ -1339,6 +1488,54 @@ describe('ModernAgentConversation send handling', () => {
1339
1488
  );
1340
1489
  });
1341
1490
 
1491
+ it('hides a stale request overlay when a terminal run cannot continue', () => {
1492
+ mockStreamState({
1493
+ messages: [
1494
+ {
1495
+ ...createMessage(AgentMessageType.REQUEST_INPUT, 'What is your favorite color?'),
1496
+ details: {
1497
+ ux: {
1498
+ options: [
1499
+ { id: 'red', label: 'Red' },
1500
+ { id: 'blue', label: 'Blue' },
1501
+ ],
1502
+ },
1503
+ },
1504
+ },
1505
+ ],
1506
+ agentRunStatus: 'COMPLETED',
1507
+ });
1508
+
1509
+ renderConversation();
1510
+
1511
+ expect(screen.queryByText('What is your favorite color?')).toBeNull();
1512
+ expect(screen.queryByRole('button', { name: /Blue/ })).toBeNull();
1513
+ });
1514
+
1515
+ it('keeps a pending request overlay when a terminal run can restart', () => {
1516
+ mockStreamState({
1517
+ messages: [
1518
+ {
1519
+ ...createMessage(AgentMessageType.REQUEST_INPUT, 'What is your favorite color?'),
1520
+ details: {
1521
+ ux: {
1522
+ options: [
1523
+ { id: 'red', label: 'Red' },
1524
+ { id: 'blue', label: 'Blue' },
1525
+ ],
1526
+ },
1527
+ },
1528
+ },
1529
+ ],
1530
+ agentRunStatus: 'COMPLETED',
1531
+ });
1532
+
1533
+ renderConversation({ onRestart: vi.fn() });
1534
+
1535
+ expect(screen.getByText('What is your favorite color?')).not.toBeNull();
1536
+ expect(screen.getByRole('button', { name: /Blue/ })).not.toBeNull();
1537
+ });
1538
+
1342
1539
  it('passes commented approval denial metadata through the request overlay signal', async () => {
1343
1540
  mockStreamState({
1344
1541
  messages: [