@dxos/plugin-assistant 0.10.0 → 0.11.0

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 (611) hide show
  1. package/PLUGIN.mdl +3 -28
  2. package/dist/lib/AssistantPlugin.mjs +2 -0
  3. package/dist/lib/AssistantPlugin.node.mjs +55 -0
  4. package/dist/lib/AssistantPlugin.node.mjs.map +1 -0
  5. package/dist/lib/AssistantPlugin.workerd.mjs +43 -0
  6. package/dist/lib/AssistantPlugin.workerd.mjs.map +1 -0
  7. package/dist/lib/capabilities.mjs +24 -0
  8. package/dist/lib/capabilities.mjs.map +1 -0
  9. package/dist/lib/chunk-AgentArticle.mjs +52 -0
  10. package/dist/lib/chunk-AgentArticle.mjs.map +1 -0
  11. package/dist/lib/chunk-AgentProperties.mjs +35 -0
  12. package/dist/lib/chunk-AgentProperties.mjs.map +1 -0
  13. package/dist/lib/chunk-AssistantPlugin.mjs +88 -0
  14. package/dist/lib/chunk-AssistantPlugin.mjs.map +1 -0
  15. package/dist/lib/chunk-AssistantSettings.mjs +285 -0
  16. package/dist/lib/chunk-AssistantSettings.mjs.map +1 -0
  17. package/dist/lib/chunk-ChatArticle.mjs +121 -0
  18. package/dist/lib/chunk-ChatArticle.mjs.map +1 -0
  19. package/dist/lib/chunk-ChatCompanion.mjs +116 -0
  20. package/dist/lib/chunk-ChatCompanion.mjs.map +1 -0
  21. package/dist/lib/chunk-ChatDialog.mjs +73 -0
  22. package/dist/lib/chunk-ChatDialog.mjs.map +1 -0
  23. package/dist/lib/chunk-IntegrationPrompt.mjs +73 -0
  24. package/dist/lib/chunk-IntegrationPrompt.mjs.map +1 -0
  25. package/dist/lib/chunk-SpaceHomePrompt.mjs +104 -0
  26. package/dist/lib/chunk-SpaceHomePrompt.mjs.map +1 -0
  27. package/dist/lib/chunk-SpaceHomeSuggestions.mjs +60 -0
  28. package/dist/lib/chunk-SpaceHomeSuggestions.mjs.map +1 -0
  29. package/dist/lib/chunk-TracePanel.mjs +127 -0
  30. package/dist/lib/chunk-TracePanel.mjs.map +1 -0
  31. package/dist/lib/chunk-TracePanel2.mjs +7 -0
  32. package/dist/lib/chunk-TracePanel2.mjs.map +1 -0
  33. package/dist/lib/chunk-TriggerStatus.mjs +72 -0
  34. package/dist/lib/chunk-TriggerStatus.mjs.map +1 -0
  35. package/dist/lib/chunk-agent-hydrator.mjs +22 -0
  36. package/dist/lib/chunk-agent-hydrator.mjs.map +1 -0
  37. package/dist/lib/chunk-agent-service.mjs +21 -0
  38. package/dist/lib/chunk-agent-service.mjs.map +1 -0
  39. package/dist/lib/{neutral/ai-context-LIKJYMIN.mjs → chunk-ai-context.mjs} +8 -12
  40. package/dist/lib/chunk-ai-context.mjs.map +1 -0
  41. package/dist/lib/chunk-ai-service.mjs +27 -0
  42. package/dist/lib/chunk-ai-service.mjs.map +1 -0
  43. package/dist/lib/chunk-app-graph-builder.mjs +179 -0
  44. package/dist/lib/chunk-app-graph-builder.mjs.map +1 -0
  45. package/dist/lib/chunk-automation-templates.mjs +99 -0
  46. package/dist/lib/chunk-automation-templates.mjs.map +1 -0
  47. package/dist/lib/chunk-companion-chat-provisioner.mjs +123 -0
  48. package/dist/lib/chunk-companion-chat-provisioner.mjs.map +1 -0
  49. package/dist/lib/chunk-connector.mjs +60 -0
  50. package/dist/lib/chunk-connector.mjs.map +1 -0
  51. package/dist/lib/chunk-constants.mjs +9 -0
  52. package/dist/lib/chunk-constants.mjs.map +1 -0
  53. package/dist/lib/chunk-context.mjs +7 -0
  54. package/dist/lib/chunk-context.mjs.map +1 -0
  55. package/dist/lib/chunk-create-chat.mjs +53 -0
  56. package/dist/lib/chunk-create-chat.mjs.map +1 -0
  57. package/dist/lib/chunk-create-object.mjs +70 -0
  58. package/dist/lib/chunk-create-object.mjs.map +1 -0
  59. package/dist/lib/chunk-edge-model-resolver.mjs +64 -0
  60. package/dist/lib/chunk-edge-model-resolver.mjs.map +1 -0
  61. package/dist/lib/chunk-ensure-companion-chat.mjs +49 -0
  62. package/dist/lib/chunk-ensure-companion-chat.mjs.map +1 -0
  63. package/dist/lib/chunk-extensions.mjs +78 -0
  64. package/dist/lib/chunk-extensions.mjs.map +1 -0
  65. package/dist/lib/chunk-fork-chat.mjs +83 -0
  66. package/dist/lib/chunk-fork-chat.mjs.map +1 -0
  67. package/dist/lib/chunk-generate-home-suggestions.mjs +71 -0
  68. package/dist/lib/chunk-generate-home-suggestions.mjs.map +1 -0
  69. package/dist/lib/chunk-local-model-resolver.mjs +25 -0
  70. package/dist/lib/chunk-local-model-resolver.mjs.map +1 -0
  71. package/dist/lib/chunk-markdown-extension.mjs +27 -0
  72. package/dist/lib/chunk-markdown-extension.mjs.map +1 -0
  73. package/dist/lib/{neutral/chunk-L7AR4VTA.mjs → chunk-meta.mjs} +20 -25
  74. package/dist/lib/chunk-meta.mjs.map +1 -0
  75. package/dist/lib/chunk-operation-handler.mjs +13 -0
  76. package/dist/lib/chunk-operation-handler.mjs.map +1 -0
  77. package/dist/lib/chunk-paths.mjs +8 -0
  78. package/dist/lib/chunk-paths.mjs.map +1 -0
  79. package/dist/lib/chunk-processor.mjs +432 -0
  80. package/dist/lib/chunk-processor.mjs.map +1 -0
  81. package/dist/lib/chunk-react-surface.mjs +177 -0
  82. package/dist/lib/chunk-react-surface.mjs.map +1 -0
  83. package/dist/lib/chunk-run-prompt-in-new-chat.mjs +96 -0
  84. package/dist/lib/chunk-run-prompt-in-new-chat.mjs.map +1 -0
  85. package/dist/lib/chunk-set-current-chat.mjs +43 -0
  86. package/dist/lib/chunk-set-current-chat.mjs.map +1 -0
  87. package/dist/lib/chunk-settings.mjs +23 -0
  88. package/dist/lib/chunk-settings.mjs.map +1 -0
  89. package/dist/lib/chunk-skill-definition.mjs +42 -0
  90. package/dist/lib/chunk-skill-definition.mjs.map +1 -0
  91. package/dist/lib/chunk-skills.mjs +19 -0
  92. package/dist/lib/chunk-skills.mjs.map +1 -0
  93. package/dist/lib/chunk-state.mjs +32 -0
  94. package/dist/lib/chunk-state.mjs.map +1 -0
  95. package/dist/lib/chunk-toggle-trace-panel-debug.mjs +18 -0
  96. package/dist/lib/chunk-toggle-trace-panel-debug.mjs.map +1 -0
  97. package/dist/lib/chunk-toolkit.mjs +12 -0
  98. package/dist/lib/chunk-toolkit.mjs.map +1 -0
  99. package/dist/lib/chunk-types.mjs +332 -0
  100. package/dist/lib/chunk-types.mjs.map +1 -0
  101. package/dist/lib/chunk-update-chat-name.mjs +63 -0
  102. package/dist/lib/chunk-update-chat-name.mjs.map +1 -0
  103. package/dist/lib/components.mjs +2616 -0
  104. package/dist/lib/components.mjs.map +1 -0
  105. package/dist/lib/containers.mjs +17 -0
  106. package/dist/lib/containers.mjs.map +1 -0
  107. package/dist/lib/execution-graph.mjs +961 -0
  108. package/dist/lib/execution-graph.mjs.map +1 -0
  109. package/dist/lib/extensions.mjs +2 -0
  110. package/dist/lib/hooks.mjs +674 -0
  111. package/dist/lib/hooks.mjs.map +1 -0
  112. package/dist/lib/index.mjs +5 -0
  113. package/dist/lib/meta.mjs +2 -0
  114. package/dist/lib/operations.mjs +7 -0
  115. package/dist/lib/operations.mjs.map +1 -0
  116. package/dist/lib/plugin.mjs +9 -0
  117. package/dist/lib/plugin.mjs.map +1 -0
  118. package/dist/lib/plugin.workerd.mjs +2 -0
  119. package/dist/lib/skills.mjs +2 -0
  120. package/dist/lib/testing.mjs +2 -0
  121. package/dist/lib/translations.mjs +207 -0
  122. package/dist/lib/translations.mjs.map +1 -0
  123. package/dist/lib/types.mjs +2 -0
  124. package/dist/types/src/AssistantPlugin.d.ts.map +1 -1
  125. package/dist/types/src/AssistantPlugin.node.d.ts.map +1 -1
  126. package/dist/types/src/AssistantPlugin.workerd.d.ts.map +1 -1
  127. package/dist/types/src/capabilities/AssistantSurfaces.d.ts +22 -0
  128. package/dist/types/src/capabilities/AssistantSurfaces.d.ts.map +1 -0
  129. package/dist/types/src/capabilities/agent-hydrator.d.ts +1 -1
  130. package/dist/types/src/capabilities/agent-service.d.ts +1 -1
  131. package/dist/types/src/capabilities/agent-service.d.ts.map +1 -1
  132. package/dist/types/src/capabilities/ai-context.d.ts +1 -1
  133. package/dist/types/src/capabilities/ai-service.d.ts +1 -1
  134. package/dist/types/src/capabilities/app-graph-builder.d.ts +12 -1
  135. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  136. package/dist/types/src/capabilities/automation-templates.d.ts +1 -1
  137. package/dist/types/src/capabilities/companion-chat-provisioner.d.ts +1 -1
  138. package/dist/types/src/capabilities/connector.d.ts +1 -1
  139. package/dist/types/src/capabilities/create-object.d.ts +1 -1
  140. package/dist/types/src/capabilities/edge-model-resolver.d.ts +1 -1
  141. package/dist/types/src/capabilities/edge-model-resolver.d.ts.map +1 -1
  142. package/dist/types/src/capabilities/index.d.ts +0 -2
  143. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  144. package/dist/types/src/capabilities/local-model-resolver.d.ts +1 -1
  145. package/dist/types/src/capabilities/local-model-resolver.d.ts.map +1 -1
  146. package/dist/types/src/capabilities/markdown-extension.d.ts +1 -1
  147. package/dist/types/src/capabilities/operation-handler.d.ts +1 -1
  148. package/dist/types/src/capabilities/react-surface.d.ts +1 -1
  149. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  150. package/dist/types/src/capabilities/settings.d.ts +1 -1
  151. package/dist/types/src/capabilities/skill-definition.d.ts.map +1 -1
  152. package/dist/types/src/capabilities/standalone-chats-query.test.d.ts +2 -0
  153. package/dist/types/src/capabilities/standalone-chats-query.test.d.ts.map +1 -0
  154. package/dist/types/src/capabilities/state.d.ts +1 -1
  155. package/dist/types/src/capabilities/toolkit.d.ts +1 -1
  156. package/dist/types/src/components/AgentProperties/AgentProperties.d.ts +4 -1
  157. package/dist/types/src/components/AgentProperties/AgentProperties.d.ts.map +1 -1
  158. package/dist/types/src/components/AgentProperties/AgentProperties.stories.d.ts.map +1 -1
  159. package/dist/types/src/components/Chat/Chat.d.ts +21 -8
  160. package/dist/types/src/components/Chat/Chat.d.ts.map +1 -1
  161. package/dist/types/src/components/Chat/{Chat.stories.d.ts → Error.stories.d.ts} +1 -1
  162. package/dist/types/src/components/Chat/Error.stories.d.ts.map +1 -0
  163. package/dist/types/src/components/Chat/context.d.ts +8 -0
  164. package/dist/types/src/components/Chat/context.d.ts.map +1 -1
  165. package/dist/types/src/components/Chat/events.d.ts +5 -0
  166. package/dist/types/src/components/Chat/events.d.ts.map +1 -1
  167. package/dist/types/src/components/Chat/thread.d.ts +42 -0
  168. package/dist/types/src/components/Chat/thread.d.ts.map +1 -0
  169. package/dist/types/src/components/Chat/thread.test.d.ts +2 -0
  170. package/dist/types/src/components/Chat/thread.test.d.ts.map +1 -0
  171. package/dist/types/src/components/ChatPrompt/ChatActions.d.ts.map +1 -1
  172. package/dist/types/src/components/ChatPrompt/ChatOptions.stories.d.ts.map +1 -1
  173. package/dist/types/src/components/ChatPrompt/ChatPrompt.d.ts +5 -3
  174. package/dist/types/src/components/ChatPrompt/ChatPrompt.d.ts.map +1 -1
  175. package/dist/types/src/components/ChatPrompt/index.d.ts +0 -1
  176. package/dist/types/src/components/ChatPrompt/index.d.ts.map +1 -1
  177. package/dist/types/src/components/ChatThread/Anchor.stories.d.ts.map +1 -1
  178. package/dist/types/src/components/ChatThread/ChatThread.d.ts +8 -3
  179. package/dist/types/src/components/ChatThread/ChatThread.d.ts.map +1 -1
  180. package/dist/types/src/components/ChatThread/ChatThread.stories.d.ts +30 -2
  181. package/dist/types/src/components/ChatThread/ChatThread.stories.d.ts.map +1 -1
  182. package/dist/types/src/components/ChatThread/Link.d.ts.map +1 -1
  183. package/dist/types/src/components/ChatThread/index.d.ts +1 -0
  184. package/dist/types/src/components/ChatThread/index.d.ts.map +1 -1
  185. package/dist/types/src/components/ChatThread/registry.d.ts.map +1 -1
  186. package/dist/types/src/components/ChatThread/sync/index.d.ts +3 -0
  187. package/dist/types/src/components/ChatThread/sync/index.d.ts.map +1 -0
  188. package/dist/types/src/components/ChatThread/{sync.d.ts → sync/sync.d.ts} +46 -2
  189. package/dist/types/src/components/ChatThread/sync/sync.d.ts.map +1 -0
  190. package/dist/types/src/components/ChatThread/sync/sync.test.d.ts.map +1 -0
  191. package/dist/types/src/components/ChatThread/sync/tool-widget-state.d.ts.map +1 -0
  192. package/dist/types/src/components/ChatThread/sync/tool-widget-state.test.d.ts.map +1 -0
  193. package/dist/types/src/components/ChatThread/widgets/BranchWidget.d.ts +15 -0
  194. package/dist/types/src/components/ChatThread/widgets/BranchWidget.d.ts.map +1 -0
  195. package/dist/types/src/components/ChatThread/widgets/BranchWidget.stories.d.ts +21 -0
  196. package/dist/types/src/components/ChatThread/widgets/BranchWidget.stories.d.ts.map +1 -0
  197. package/dist/types/src/components/ChatThread/widgets/BranchWidget.test.d.ts +2 -0
  198. package/dist/types/src/components/ChatThread/widgets/BranchWidget.test.d.ts.map +1 -0
  199. package/dist/types/src/components/ChatThread/widgets/ReferenceWidget.d.ts.map +1 -1
  200. package/dist/types/src/components/ChatThread/widgets/SuggestionWidget.d.ts.map +1 -1
  201. package/dist/types/src/components/ChatThread/widgets/ToolWidget.d.ts +1 -2
  202. package/dist/types/src/components/ChatThread/widgets/ToolWidget.d.ts.map +1 -1
  203. package/dist/types/src/components/ChatThread/widgets/defaults.d.ts +6 -0
  204. package/dist/types/src/components/ChatThread/widgets/defaults.d.ts.map +1 -1
  205. package/dist/types/src/components/ChatThread/widgets/format-time.d.ts +2 -0
  206. package/dist/types/src/components/ChatThread/widgets/format-time.d.ts.map +1 -0
  207. package/dist/types/src/components/ChatThread/widgets/index.d.ts +4 -1
  208. package/dist/types/src/components/ChatThread/widgets/index.d.ts.map +1 -1
  209. package/dist/types/src/components/ChatThread/widgets/is-tool-message.d.ts +3 -0
  210. package/dist/types/src/components/ChatThread/widgets/is-tool-message.d.ts.map +1 -0
  211. package/dist/types/src/components/ConnectorAuthMenu/ConnectorAuthMenu.d.ts +16 -0
  212. package/dist/types/src/components/ConnectorAuthMenu/ConnectorAuthMenu.d.ts.map +1 -0
  213. package/dist/types/src/components/ConnectorAuthMenu/ConnectorAuthMenu.stories.d.ts +210 -0
  214. package/dist/types/src/components/ConnectorAuthMenu/ConnectorAuthMenu.stories.d.ts.map +1 -0
  215. package/dist/types/src/components/ConnectorAuthMenu/index.d.ts +2 -0
  216. package/dist/types/src/components/ConnectorAuthMenu/index.d.ts.map +1 -0
  217. package/dist/types/src/components/ProcessTree/ProcessTree.d.ts +1 -1
  218. package/dist/types/src/components/ProcessTree/ProcessTree.d.ts.map +1 -1
  219. package/dist/types/src/components/TaskList/TaskList.d.ts +9 -11
  220. package/dist/types/src/components/TaskList/TaskList.d.ts.map +1 -1
  221. package/dist/types/src/components/TaskList/TaskList.stories.d.ts +3 -4
  222. package/dist/types/src/components/TaskList/TaskList.stories.d.ts.map +1 -1
  223. package/dist/types/src/components/ToolBlock/ToolBlock.d.ts +1 -2
  224. package/dist/types/src/components/ToolBlock/ToolBlock.d.ts.map +1 -1
  225. package/dist/types/src/components/ToolBlock/index.d.ts +1 -0
  226. package/dist/types/src/components/ToolBlock/index.d.ts.map +1 -1
  227. package/dist/types/src/components/ToolBlock/is-tool-message.d.ts +3 -0
  228. package/dist/types/src/components/ToolBlock/is-tool-message.d.ts.map +1 -0
  229. package/dist/types/src/components/Toolbox/Toolbox.d.ts +1 -1
  230. package/dist/types/src/components/Toolbox/Toolbox.d.ts.map +1 -1
  231. package/dist/types/src/components/index.d.ts +1 -0
  232. package/dist/types/src/components/index.d.ts.map +1 -1
  233. package/dist/types/src/containers/AgentArticle/AgentArticle.d.ts +5 -2
  234. package/dist/types/src/containers/AgentArticle/AgentArticle.d.ts.map +1 -1
  235. package/dist/types/src/containers/AgentArticle/AgentArticle.stories.d.ts.map +1 -1
  236. package/dist/types/src/containers/AgentProperties/AgentProperties.d.ts +4 -1
  237. package/dist/types/src/containers/AgentProperties/AgentProperties.d.ts.map +1 -1
  238. package/dist/types/src/containers/AssistantSettings/AssistantSettings.d.ts +4 -1
  239. package/dist/types/src/containers/AssistantSettings/AssistantSettings.d.ts.map +1 -1
  240. package/dist/types/src/containers/AssistantSettings/AssistantSettings.stories.d.ts +4 -1
  241. package/dist/types/src/containers/AssistantSettings/AssistantSettings.stories.d.ts.map +1 -1
  242. package/dist/types/src/containers/AssistantSettings/OllamaModels.d.ts +4 -6
  243. package/dist/types/src/containers/AssistantSettings/OllamaModels.d.ts.map +1 -1
  244. package/dist/types/src/containers/ChatArticle/ChatArticle.d.ts.map +1 -1
  245. package/dist/types/src/containers/ChatArticle/ChatArticle.stories.d.ts +22 -1
  246. package/dist/types/src/containers/ChatArticle/ChatArticle.stories.d.ts.map +1 -1
  247. package/dist/types/src/containers/ChatCompanion/ChatCompanion.d.ts.map +1 -1
  248. package/dist/types/src/containers/ChatDialog/ChatDialog.d.ts +4 -1
  249. package/dist/types/src/containers/ChatDialog/ChatDialog.d.ts.map +1 -1
  250. package/dist/types/src/containers/IntegrationPrompt/IntegrationPrompt.d.ts +4 -7
  251. package/dist/types/src/containers/IntegrationPrompt/IntegrationPrompt.d.ts.map +1 -1
  252. package/dist/types/src/containers/SpaceHomePrompt/SpaceHomePrompt.d.ts +4 -9
  253. package/dist/types/src/containers/SpaceHomePrompt/SpaceHomePrompt.d.ts.map +1 -1
  254. package/dist/types/src/containers/SpaceHomeSuggestions/SpaceHomeSuggestions.d.ts +5 -7
  255. package/dist/types/src/containers/SpaceHomeSuggestions/SpaceHomeSuggestions.d.ts.map +1 -1
  256. package/dist/types/src/containers/TracePanel/TracePanel.d.ts +1 -1
  257. package/dist/types/src/containers/TracePanel/TracePanel.d.ts.map +1 -1
  258. package/dist/types/src/containers/TracePanel/TracePanel.stories.d.ts.map +1 -1
  259. package/dist/types/src/containers/TriggerStatus/TriggerStatus.d.ts +15 -1
  260. package/dist/types/src/containers/TriggerStatus/TriggerStatus.d.ts.map +1 -1
  261. package/dist/types/src/containers/index.d.ts +0 -1
  262. package/dist/types/src/containers/index.d.ts.map +1 -1
  263. package/dist/types/src/execution-graph/execution-graph.d.ts +12 -1
  264. package/dist/types/src/execution-graph/execution-graph.d.ts.map +1 -1
  265. package/dist/types/src/execution-graph/index.d.ts +1 -1
  266. package/dist/types/src/execution-graph/index.d.ts.map +1 -1
  267. package/dist/types/src/execution-graph/pending-block-status.d.ts.map +1 -1
  268. package/dist/types/src/execution-graph/span-tree.d.ts +17 -0
  269. package/dist/types/src/execution-graph/span-tree.d.ts.map +1 -1
  270. package/dist/types/src/feed-logger.d.ts +1 -1
  271. package/dist/types/src/feed-logger.d.ts.map +1 -1
  272. package/dist/types/src/hooks/index.d.ts +1 -1
  273. package/dist/types/src/hooks/index.d.ts.map +1 -1
  274. package/dist/types/src/hooks/useChatProcessor.d.ts.map +1 -1
  275. package/dist/types/src/hooks/useChatToolbarActions.d.ts.map +1 -1
  276. package/dist/types/src/hooks/useContextObjects.d.ts +1 -1
  277. package/dist/types/src/hooks/useContextObjects.d.ts.map +1 -1
  278. package/dist/types/src/hooks/useSelectionContext.d.ts +13 -0
  279. package/dist/types/src/hooks/useSelectionContext.d.ts.map +1 -0
  280. package/dist/types/src/hooks/useSelectionContext.test.d.ts +2 -0
  281. package/dist/types/src/hooks/useSelectionContext.test.d.ts.map +1 -0
  282. package/dist/types/src/hooks/useTraceMessages.d.ts.map +1 -1
  283. package/dist/types/src/operations/index.d.ts.map +1 -1
  284. package/dist/types/src/processor/index.d.ts +1 -0
  285. package/dist/types/src/processor/index.d.ts.map +1 -1
  286. package/dist/types/src/processor/processor.d.ts +5 -2
  287. package/dist/types/src/processor/processor.d.ts.map +1 -1
  288. package/dist/types/src/processor/prompt.d.ts +18 -0
  289. package/dist/types/src/processor/prompt.d.ts.map +1 -0
  290. package/dist/types/src/processor/prompt.test.d.ts +2 -0
  291. package/dist/types/src/processor/prompt.test.d.ts.map +1 -0
  292. package/dist/types/src/processor/streaming.node.test.d.ts +2 -0
  293. package/dist/types/src/processor/streaming.node.test.d.ts.map +1 -0
  294. package/dist/types/src/skills/assistant/skill.d.ts.map +1 -1
  295. package/dist/types/src/templates/scaffold.d.ts +1 -1
  296. package/dist/types/src/templates/scaffold.d.ts.map +1 -1
  297. package/dist/types/src/translations.d.ts.map +1 -1
  298. package/dist/types/src/types/AssistantCapabilities.d.ts +1 -1
  299. package/dist/types/src/types/AssistantCapabilities.d.ts.map +1 -1
  300. package/dist/types/src/types/AssistantOperation.d.ts +2 -13
  301. package/dist/types/src/types/AssistantOperation.d.ts.map +1 -1
  302. package/dist/types/src/types/ChatSurface.d.ts +2 -2
  303. package/dist/types/src/types/ChatSurface.d.ts.map +1 -1
  304. package/dist/types/src/types/Ollama.d.ts +1 -1
  305. package/dist/types/src/types/Ollama.d.ts.map +1 -1
  306. package/dist/types/tsconfig.tsbuildinfo +1 -1
  307. package/dx.config.ts +1 -0
  308. package/package.json +106 -105
  309. package/src/AssistantPlugin.node.ts +1 -2
  310. package/src/AssistantPlugin.test.ts +60 -62
  311. package/src/AssistantPlugin.ts +1 -10
  312. package/src/AssistantPlugin.workerd.ts +1 -2
  313. package/src/capabilities/AssistantSurfaces.tsx +86 -0
  314. package/src/capabilities/agent-service.ts +1 -1
  315. package/src/capabilities/app-graph-builder.ts +31 -17
  316. package/src/capabilities/companion-chat-provisioner.ts +12 -11
  317. package/src/capabilities/connector.ts +3 -3
  318. package/src/capabilities/edge-model-resolver.ts +5 -2
  319. package/src/capabilities/index.ts +0 -2
  320. package/src/capabilities/react-surface.ts +135 -0
  321. package/src/capabilities/skill-definition.ts +4 -0
  322. package/src/capabilities/standalone-chats-query.test.ts +51 -0
  323. package/src/capabilities/state.ts +1 -1
  324. package/src/components/AgentProperties/AgentProperties.stories.tsx +6 -7
  325. package/src/components/AgentProperties/AgentProperties.tsx +37 -30
  326. package/src/components/Chat/Chat.tsx +275 -59
  327. package/src/components/Chat/{Chat.stories.tsx → Error.stories.tsx} +1 -1
  328. package/src/components/Chat/context.ts +8 -0
  329. package/src/components/Chat/events.ts +5 -0
  330. package/src/components/Chat/thread.test.ts +127 -0
  331. package/src/components/Chat/thread.ts +87 -0
  332. package/src/components/ChatPrompt/ChatActions.tsx +8 -8
  333. package/src/components/ChatPrompt/ChatMcpErrors.tsx +2 -2
  334. package/src/components/ChatPrompt/ChatOptions.stories.tsx +2 -1
  335. package/src/components/ChatPrompt/ChatOptions.tsx +5 -5
  336. package/src/components/ChatPrompt/ChatPrompt.tsx +33 -6
  337. package/src/components/ChatPrompt/index.ts +0 -1
  338. package/src/components/ChatThread/Anchor.stories.tsx +2 -1
  339. package/src/components/ChatThread/ChatThread.stories.tsx +99 -4
  340. package/src/components/ChatThread/ChatThread.tsx +34 -6
  341. package/src/components/ChatThread/Link.tsx +1 -0
  342. package/src/components/ChatThread/index.ts +2 -0
  343. package/src/components/ChatThread/registry.tsx +28 -4
  344. package/src/components/ChatThread/sync/index.ts +6 -0
  345. package/src/components/ChatThread/{sync.test.ts → sync/sync.test.ts} +167 -7
  346. package/src/components/ChatThread/{sync.ts → sync/sync.ts} +97 -3
  347. package/src/components/ChatThread/{tool-widget-state.ts → sync/tool-widget-state.ts} +1 -3
  348. package/src/components/ChatThread/widgets/BranchWidget.stories.tsx +83 -0
  349. package/src/components/ChatThread/widgets/BranchWidget.test.ts +55 -0
  350. package/src/components/ChatThread/widgets/BranchWidget.tsx +61 -0
  351. package/src/components/ChatThread/widgets/FallbackWidget.tsx +2 -2
  352. package/src/components/ChatThread/widgets/ReasoningWidget.ts +1 -1
  353. package/src/components/ChatThread/widgets/ReferenceWidget.ts +1 -6
  354. package/src/components/ChatThread/widgets/SuggestionWidget.ts +12 -3
  355. package/src/components/ChatThread/widgets/SummaryWidget.tsx +1 -1
  356. package/src/components/ChatThread/widgets/ToolWidget.tsx +15 -9
  357. package/src/components/ChatThread/widgets/defaults.ts +7 -1
  358. package/src/components/ChatThread/widgets/format-time.ts +45 -0
  359. package/src/components/ChatThread/widgets/index.ts +4 -1
  360. package/src/components/ChatThread/widgets/is-tool-message.ts +13 -0
  361. package/src/components/ConnectorAuthMenu/ConnectorAuthMenu.stories.tsx +177 -0
  362. package/src/components/ConnectorAuthMenu/ConnectorAuthMenu.tsx +82 -0
  363. package/src/components/ConnectorAuthMenu/index.ts +5 -0
  364. package/src/components/ProcessTree/ProcessTree.stories.tsx +1 -1
  365. package/src/components/TaskList/TaskList.stories.tsx +19 -26
  366. package/src/components/TaskList/TaskList.tsx +32 -104
  367. package/src/components/ToolBlock/ToolBlock.tsx +1 -5
  368. package/src/components/ToolBlock/index.ts +1 -0
  369. package/src/components/ToolBlock/is-tool-message.ts +13 -0
  370. package/src/components/Toolbox/Toolbox.tsx +1 -1
  371. package/src/components/index.ts +1 -0
  372. package/src/containers/AgentArticle/AgentArticle.stories.tsx +18 -11
  373. package/src/containers/AgentArticle/AgentArticle.tsx +27 -151
  374. package/src/containers/AgentProperties/AgentProperties.tsx +21 -17
  375. package/src/containers/AssistantSettings/AssistantSettings.tsx +2 -0
  376. package/src/containers/AssistantSettings/OllamaModels.tsx +6 -4
  377. package/src/containers/ChatArticle/ChatArticle.stories.tsx +200 -27
  378. package/src/containers/ChatArticle/ChatArticle.tsx +25 -5
  379. package/src/containers/ChatCompanion/ChatCompanion.tsx +45 -10
  380. package/src/containers/ChatDialog/ChatDialog.tsx +4 -1
  381. package/src/containers/IntegrationPrompt/IntegrationPrompt.tsx +9 -6
  382. package/src/containers/SpaceHomePrompt/SpaceHomePrompt.tsx +2 -0
  383. package/src/containers/SpaceHomeSuggestions/SpaceHomeSuggestions.tsx +40 -39
  384. package/src/containers/TracePanel/TracePanel.stories.tsx +9 -4
  385. package/src/containers/TracePanel/TracePanel.tsx +22 -6
  386. package/src/containers/TriggerStatus/TriggerStatus.tsx +9 -16
  387. package/src/containers/index.ts +0 -1
  388. package/src/execution-graph/SPEC.md +60 -2
  389. package/src/execution-graph/execution-graph.ts +15 -2
  390. package/src/execution-graph/index.ts +1 -0
  391. package/src/execution-graph/pending-block-status.ts +3 -2
  392. package/src/execution-graph/span-tree.test.ts +87 -1
  393. package/src/execution-graph/span-tree.ts +95 -0
  394. package/src/feed-logger.ts +6 -6
  395. package/src/hooks/index.ts +1 -1
  396. package/src/hooks/useChatProcessor.ts +2 -1
  397. package/src/hooks/useChatToolbarActions.ts +22 -19
  398. package/src/hooks/useContextObjects.ts +9 -3
  399. package/src/hooks/useSelectionContext.test.ts +93 -0
  400. package/src/hooks/useSelectionContext.ts +72 -0
  401. package/src/hooks/useSkillRegistry.ts +1 -1
  402. package/src/hooks/useTraceMessages.ts +5 -3
  403. package/src/operations/create-chat.ts +2 -2
  404. package/src/operations/fork-chat.ts +2 -2
  405. package/src/operations/generate-home-suggestions.test.ts +2 -2
  406. package/src/operations/index.ts +0 -1
  407. package/src/operations/prompt.node.test.ts +1 -1
  408. package/src/paths.ts +3 -3
  409. package/src/processor/index.ts +1 -0
  410. package/src/processor/processor.node.test.ts +1 -1
  411. package/src/processor/processor.ts +33 -5
  412. package/src/processor/prompt.test.ts +37 -0
  413. package/src/processor/prompt.ts +42 -0
  414. package/src/processor/streaming.node.test.ts +196 -0
  415. package/src/skills/assistant/skill.node.test.ts +2 -2
  416. package/src/skills/assistant/skill.ts +3 -5
  417. package/src/templates/routine-templates.test.ts +1 -2
  418. package/src/templates/scaffold.ts +3 -3
  419. package/src/testing/data/trace-timeline-multiple.dx.json +1 -1
  420. package/src/testing/data/trace-timeline-remote.dx.json +1 -1
  421. package/src/testing/data/trace-timeline.dx.json +1 -2
  422. package/src/testing/trace-timeline.node.test.ts +3 -3
  423. package/src/translations.ts +11 -10
  424. package/src/types/AssistantCapabilities.ts +1 -1
  425. package/src/types/AssistantOperation.ts +8 -31
  426. package/src/types/ChatSurface.ts +3 -3
  427. package/src/types/Ollama.ts +1 -1
  428. package/dist/lib/neutral/AgentArticle-GV6EEW3I.mjs +0 -161
  429. package/dist/lib/neutral/AgentArticle-GV6EEW3I.mjs.map +0 -7
  430. package/dist/lib/neutral/AgentProperties-LFTEYJ54.mjs +0 -40
  431. package/dist/lib/neutral/AgentProperties-LFTEYJ54.mjs.map +0 -7
  432. package/dist/lib/neutral/AssistantPlugin.mjs +0 -10
  433. package/dist/lib/neutral/AssistantPlugin.mjs.map +0 -7
  434. package/dist/lib/neutral/AssistantPlugin.node.mjs +0 -72
  435. package/dist/lib/neutral/AssistantPlugin.node.mjs.map +0 -7
  436. package/dist/lib/neutral/AssistantPlugin.workerd.mjs +0 -13
  437. package/dist/lib/neutral/AssistantPlugin.workerd.mjs.map +0 -7
  438. package/dist/lib/neutral/AssistantSettings-3N5M5VCN.mjs +0 -302
  439. package/dist/lib/neutral/AssistantSettings-3N5M5VCN.mjs.map +0 -7
  440. package/dist/lib/neutral/ChatArticle-OO7GGEFW.mjs +0 -8
  441. package/dist/lib/neutral/ChatArticle-OO7GGEFW.mjs.map +0 -7
  442. package/dist/lib/neutral/ChatCompanion-GIFJRY6I.mjs +0 -128
  443. package/dist/lib/neutral/ChatCompanion-GIFJRY6I.mjs.map +0 -7
  444. package/dist/lib/neutral/ChatDialog-5MXN4MXS.mjs +0 -74
  445. package/dist/lib/neutral/ChatDialog-5MXN4MXS.mjs.map +0 -7
  446. package/dist/lib/neutral/IntegrationPrompt-2HJQFYJE.mjs +0 -72
  447. package/dist/lib/neutral/IntegrationPrompt-2HJQFYJE.mjs.map +0 -7
  448. package/dist/lib/neutral/PlanArticle-VPK2IYWU.mjs +0 -34
  449. package/dist/lib/neutral/PlanArticle-VPK2IYWU.mjs.map +0 -7
  450. package/dist/lib/neutral/SpaceHomePrompt-ISAB76LD.mjs +0 -114
  451. package/dist/lib/neutral/SpaceHomePrompt-ISAB76LD.mjs.map +0 -7
  452. package/dist/lib/neutral/SpaceHomeSuggestions-IDH77QQR.mjs +0 -63
  453. package/dist/lib/neutral/SpaceHomeSuggestions-IDH77QQR.mjs.map +0 -7
  454. package/dist/lib/neutral/TracePanel-JKNWADJ4.mjs +0 -12
  455. package/dist/lib/neutral/TracePanel-JKNWADJ4.mjs.map +0 -7
  456. package/dist/lib/neutral/TriggerStatus-FURRBHYA.mjs +0 -95
  457. package/dist/lib/neutral/TriggerStatus-FURRBHYA.mjs.map +0 -7
  458. package/dist/lib/neutral/agent-hydrator-OBO3RHLO.mjs +0 -23
  459. package/dist/lib/neutral/agent-hydrator-OBO3RHLO.mjs.map +0 -7
  460. package/dist/lib/neutral/agent-service-XFJ4VQMT.mjs +0 -32
  461. package/dist/lib/neutral/agent-service-XFJ4VQMT.mjs.map +0 -7
  462. package/dist/lib/neutral/ai-context-LIKJYMIN.mjs.map +0 -7
  463. package/dist/lib/neutral/ai-service-DM6YXWUC.mjs +0 -44
  464. package/dist/lib/neutral/ai-service-DM6YXWUC.mjs.map +0 -7
  465. package/dist/lib/neutral/app-graph-builder-OPVOEQY7.mjs +0 -249
  466. package/dist/lib/neutral/app-graph-builder-OPVOEQY7.mjs.map +0 -7
  467. package/dist/lib/neutral/automation-templates-MADJLXGJ.mjs +0 -97
  468. package/dist/lib/neutral/automation-templates-MADJLXGJ.mjs.map +0 -7
  469. package/dist/lib/neutral/capabilities/index.mjs +0 -47
  470. package/dist/lib/neutral/capabilities/index.mjs.map +0 -7
  471. package/dist/lib/neutral/chunk-5IHQ52KJ.mjs +0 -9
  472. package/dist/lib/neutral/chunk-5IHQ52KJ.mjs.map +0 -7
  473. package/dist/lib/neutral/chunk-6Q4OBGIK.mjs +0 -420
  474. package/dist/lib/neutral/chunk-6Q4OBGIK.mjs.map +0 -7
  475. package/dist/lib/neutral/chunk-BXI2R4OO.mjs +0 -410
  476. package/dist/lib/neutral/chunk-BXI2R4OO.mjs.map +0 -7
  477. package/dist/lib/neutral/chunk-CMPLPDYE.mjs +0 -30
  478. package/dist/lib/neutral/chunk-CMPLPDYE.mjs.map +0 -7
  479. package/dist/lib/neutral/chunk-GPHT3HYS.mjs +0 -8
  480. package/dist/lib/neutral/chunk-GPHT3HYS.mjs.map +0 -7
  481. package/dist/lib/neutral/chunk-HKLSFB5I.mjs +0 -90
  482. package/dist/lib/neutral/chunk-HKLSFB5I.mjs.map +0 -7
  483. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +0 -10
  484. package/dist/lib/neutral/chunk-J5LGTIGS.mjs.map +0 -7
  485. package/dist/lib/neutral/chunk-L7AR4VTA.mjs.map +0 -7
  486. package/dist/lib/neutral/chunk-LS72HWMM.mjs +0 -42
  487. package/dist/lib/neutral/chunk-LS72HWMM.mjs.map +0 -7
  488. package/dist/lib/neutral/chunk-OZWZGIV2.mjs +0 -12
  489. package/dist/lib/neutral/chunk-OZWZGIV2.mjs.map +0 -7
  490. package/dist/lib/neutral/chunk-QOKLFHUS.mjs +0 -13
  491. package/dist/lib/neutral/chunk-QOKLFHUS.mjs.map +0 -7
  492. package/dist/lib/neutral/chunk-SCTHQVIJ.mjs +0 -155
  493. package/dist/lib/neutral/chunk-SCTHQVIJ.mjs.map +0 -7
  494. package/dist/lib/neutral/chunk-U4LTLBAX.mjs +0 -56
  495. package/dist/lib/neutral/chunk-U4LTLBAX.mjs.map +0 -7
  496. package/dist/lib/neutral/chunk-UPKFUZ6V.mjs +0 -115
  497. package/dist/lib/neutral/chunk-UPKFUZ6V.mjs.map +0 -7
  498. package/dist/lib/neutral/chunk-V2Y4XE3O.mjs +0 -12
  499. package/dist/lib/neutral/chunk-V2Y4XE3O.mjs.map +0 -7
  500. package/dist/lib/neutral/chunk-VTK5R4H3.mjs +0 -9
  501. package/dist/lib/neutral/chunk-VTK5R4H3.mjs.map +0 -7
  502. package/dist/lib/neutral/chunk-XVGEJWJX.mjs +0 -133
  503. package/dist/lib/neutral/chunk-XVGEJWJX.mjs.map +0 -7
  504. package/dist/lib/neutral/companion-chat-provisioner-IQV5VIVE.mjs +0 -126
  505. package/dist/lib/neutral/companion-chat-provisioner-IQV5VIVE.mjs.map +0 -7
  506. package/dist/lib/neutral/components/index.mjs +0 -2527
  507. package/dist/lib/neutral/components/index.mjs.map +0 -7
  508. package/dist/lib/neutral/connector-ITLLTBPZ.mjs +0 -70
  509. package/dist/lib/neutral/connector-ITLLTBPZ.mjs.map +0 -7
  510. package/dist/lib/neutral/containers/index.mjs +0 -31
  511. package/dist/lib/neutral/containers/index.mjs.map +0 -7
  512. package/dist/lib/neutral/create-chat-YGVZZYGP.mjs +0 -56
  513. package/dist/lib/neutral/create-chat-YGVZZYGP.mjs.map +0 -7
  514. package/dist/lib/neutral/create-object-5PAEJ6KM.mjs +0 -76
  515. package/dist/lib/neutral/create-object-5PAEJ6KM.mjs.map +0 -7
  516. package/dist/lib/neutral/edge-model-resolver-WDJWDZTT.mjs +0 -55
  517. package/dist/lib/neutral/edge-model-resolver-WDJWDZTT.mjs.map +0 -7
  518. package/dist/lib/neutral/ensure-companion-chat-AMOF3C66.mjs +0 -58
  519. package/dist/lib/neutral/ensure-companion-chat-AMOF3C66.mjs.map +0 -7
  520. package/dist/lib/neutral/execution-graph/index.mjs +0 -977
  521. package/dist/lib/neutral/execution-graph/index.mjs.map +0 -7
  522. package/dist/lib/neutral/extensions/index.mjs +0 -8
  523. package/dist/lib/neutral/extensions/index.mjs.map +0 -7
  524. package/dist/lib/neutral/fork-chat-RMAAYYQF.mjs +0 -92
  525. package/dist/lib/neutral/fork-chat-RMAAYYQF.mjs.map +0 -7
  526. package/dist/lib/neutral/generate-home-suggestions-6MM2XWPV.mjs +0 -93
  527. package/dist/lib/neutral/generate-home-suggestions-6MM2XWPV.mjs.map +0 -7
  528. package/dist/lib/neutral/hooks/index.mjs +0 -877
  529. package/dist/lib/neutral/hooks/index.mjs.map +0 -7
  530. package/dist/lib/neutral/index.mjs +0 -42
  531. package/dist/lib/neutral/index.mjs.map +0 -7
  532. package/dist/lib/neutral/local-model-resolver-I2BENFFS.mjs +0 -24
  533. package/dist/lib/neutral/local-model-resolver-I2BENFFS.mjs.map +0 -7
  534. package/dist/lib/neutral/markdown-extension-R4TKDTIF.mjs +0 -41
  535. package/dist/lib/neutral/markdown-extension-R4TKDTIF.mjs.map +0 -7
  536. package/dist/lib/neutral/meta.json +0 -1
  537. package/dist/lib/neutral/meta.mjs +0 -12
  538. package/dist/lib/neutral/meta.mjs.map +0 -7
  539. package/dist/lib/neutral/migrations-7DEMVBOG.mjs +0 -28
  540. package/dist/lib/neutral/migrations-7DEMVBOG.mjs.map +0 -7
  541. package/dist/lib/neutral/navigation-resolver-PYGP2DAW.mjs +0 -18
  542. package/dist/lib/neutral/navigation-resolver-PYGP2DAW.mjs.map +0 -7
  543. package/dist/lib/neutral/operation-handler-2LEN45GP.mjs +0 -8
  544. package/dist/lib/neutral/operation-handler-2LEN45GP.mjs.map +0 -7
  545. package/dist/lib/neutral/operations/index.mjs +0 -8
  546. package/dist/lib/neutral/operations/index.mjs.map +0 -7
  547. package/dist/lib/neutral/plugin.mjs +0 -16
  548. package/dist/lib/neutral/plugin.mjs.map +0 -7
  549. package/dist/lib/neutral/plugin.workerd.mjs +0 -13
  550. package/dist/lib/neutral/plugin.workerd.mjs.map +0 -7
  551. package/dist/lib/neutral/react-surface-HEJEK44F.mjs +0 -171
  552. package/dist/lib/neutral/react-surface-HEJEK44F.mjs.map +0 -7
  553. package/dist/lib/neutral/resolve-navigation-targets-PBQ3OLUE.mjs +0 -28
  554. package/dist/lib/neutral/resolve-navigation-targets-PBQ3OLUE.mjs.map +0 -7
  555. package/dist/lib/neutral/run-prompt-in-new-chat-RNUJE2FM.mjs +0 -102
  556. package/dist/lib/neutral/run-prompt-in-new-chat-RNUJE2FM.mjs.map +0 -7
  557. package/dist/lib/neutral/set-current-chat-VWBPSIMZ.mjs +0 -48
  558. package/dist/lib/neutral/set-current-chat-VWBPSIMZ.mjs.map +0 -7
  559. package/dist/lib/neutral/settings-7Q3RITIT.mjs +0 -28
  560. package/dist/lib/neutral/settings-7Q3RITIT.mjs.map +0 -7
  561. package/dist/lib/neutral/skill-definition-553MQRTR.mjs +0 -8
  562. package/dist/lib/neutral/skill-definition-553MQRTR.mjs.map +0 -7
  563. package/dist/lib/neutral/skills/index.mjs +0 -8
  564. package/dist/lib/neutral/skills/index.mjs.map +0 -7
  565. package/dist/lib/neutral/state-4LGAKSSD.mjs +0 -34
  566. package/dist/lib/neutral/state-4LGAKSSD.mjs.map +0 -7
  567. package/dist/lib/neutral/testing.mjs +0 -8
  568. package/dist/lib/neutral/testing.mjs.map +0 -7
  569. package/dist/lib/neutral/toggle-trace-panel-debug-JGTB6KVJ.mjs +0 -21
  570. package/dist/lib/neutral/toggle-trace-panel-debug-JGTB6KVJ.mjs.map +0 -7
  571. package/dist/lib/neutral/toolkit-ETWLG5NT.mjs +0 -8
  572. package/dist/lib/neutral/toolkit-ETWLG5NT.mjs.map +0 -7
  573. package/dist/lib/neutral/translations.mjs +0 -217
  574. package/dist/lib/neutral/translations.mjs.map +0 -7
  575. package/dist/lib/neutral/types/index.mjs +0 -24
  576. package/dist/lib/neutral/types/index.mjs.map +0 -7
  577. package/dist/lib/neutral/update-chat-name-IJJELRR6.mjs +0 -61
  578. package/dist/lib/neutral/update-chat-name-IJJELRR6.mjs.map +0 -7
  579. package/dist/types/src/capabilities/migrations.d.ts +0 -5
  580. package/dist/types/src/capabilities/migrations.d.ts.map +0 -1
  581. package/dist/types/src/capabilities/navigation-resolver.d.ts +0 -5
  582. package/dist/types/src/capabilities/navigation-resolver.d.ts.map +0 -1
  583. package/dist/types/src/components/Chat/Chat.stories.d.ts.map +0 -1
  584. package/dist/types/src/components/ChatPrompt/ChatStatusIndicator.d.ts +0 -10
  585. package/dist/types/src/components/ChatPrompt/ChatStatusIndicator.d.ts.map +0 -1
  586. package/dist/types/src/components/ChatThread/sync.d.ts.map +0 -1
  587. package/dist/types/src/components/ChatThread/sync.test.d.ts.map +0 -1
  588. package/dist/types/src/components/ChatThread/tool-widget-state.d.ts.map +0 -1
  589. package/dist/types/src/components/ChatThread/tool-widget-state.test.d.ts.map +0 -1
  590. package/dist/types/src/containers/PlanArticle/PlanArticle.d.ts +0 -6
  591. package/dist/types/src/containers/PlanArticle/PlanArticle.d.ts.map +0 -1
  592. package/dist/types/src/containers/PlanArticle/index.d.ts +0 -2
  593. package/dist/types/src/containers/PlanArticle/index.d.ts.map +0 -1
  594. package/dist/types/src/hooks/useFlush.d.ts +0 -6
  595. package/dist/types/src/hooks/useFlush.d.ts.map +0 -1
  596. package/dist/types/src/operations/resolve-navigation-targets.d.ts +0 -5
  597. package/dist/types/src/operations/resolve-navigation-targets.d.ts.map +0 -1
  598. package/src/AssistantPlugin.conversations.json +0 -1
  599. package/src/capabilities/migrations.ts +0 -28
  600. package/src/capabilities/navigation-resolver.ts +0 -20
  601. package/src/capabilities/react-surface.tsx +0 -177
  602. package/src/components/ChatPrompt/ChatStatusIndicator.tsx +0 -42
  603. package/src/components/ChatThread/DEBUG.md +0 -64
  604. package/src/containers/PlanArticle/PlanArticle.tsx +0 -37
  605. package/src/containers/PlanArticle/index.ts +0 -5
  606. package/src/hooks/useFlush.ts +0 -35
  607. package/src/operations/resolve-navigation-targets.ts +0 -44
  608. /package/dist/types/src/components/ChatThread/{sync.test.d.ts → sync/sync.test.d.ts} +0 -0
  609. /package/dist/types/src/components/ChatThread/{tool-widget-state.d.ts → sync/tool-widget-state.d.ts} +0 -0
  610. /package/dist/types/src/components/ChatThread/{tool-widget-state.test.d.ts → sync/tool-widget-state.test.d.ts} +0 -0
  611. /package/src/components/ChatThread/{tool-widget-state.test.ts → sync/tool-widget-state.test.ts} +0 -0
@@ -0,0 +1,127 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Array from 'effect/Array';
6
+ import { describe, test } from 'vitest';
7
+
8
+ import { Feed, Obj } from '@dxos/echo';
9
+ import { Message } from '@dxos/types';
10
+
11
+ import { byAppendOrder, projectThread, resolveRewind } from './thread';
12
+
13
+ describe('byAppendOrder', () => {
14
+ test('orders by feed position when it discriminates', ({ expect }) => {
15
+ const a = positioned(message('a'), 2);
16
+ const b = positioned(message('b'), 1);
17
+ expect(sortText([a, b])).toEqual(['b', 'a']);
18
+ });
19
+
20
+ // Positions are assigned by the server: with no position authority every block reports `+Infinity`,
21
+ // and a query returns an unordered set, so position alone leaves them arbitrary.
22
+ test('falls back to created when positions are absent', ({ expect }) => {
23
+ const first = message('first');
24
+ const second = message('second');
25
+ expect(sortText([second, first])).toEqual(['first', 'second']);
26
+ });
27
+
28
+ test('an unpositioned message sorts after a positioned one', ({ expect }) => {
29
+ const acknowledged = positioned(message('acknowledged'), 7);
30
+ const local = message('local');
31
+ expect(sortText([local, acknowledged])).toEqual(['acknowledged', 'local']);
32
+ });
33
+ });
34
+
35
+ describe('projectThread', () => {
36
+ test('a feed with no lineage projects to itself', ({ expect }) => {
37
+ const messages = [message('one'), message('two'), message('three')];
38
+ expect(text(projectThread({ feedMessages: messages }).messages)).toEqual(['one', 'two', 'three']);
39
+ });
40
+
41
+ test('pending messages are appended and deduped against the feed', ({ expect }) => {
42
+ const persisted = message('persisted');
43
+ const pending = message('pending');
44
+ const { messages } = projectThread({
45
+ feedMessages: [persisted, pending],
46
+ pendingMessages: [pending],
47
+ });
48
+ expect(text(messages)).toEqual(['persisted', 'pending']);
49
+ });
50
+
51
+ test('lineage hides the turns a fork abandoned', ({ expect }) => {
52
+ const first = message('first');
53
+ const answer = message('answer');
54
+ const abandoned = message('abandoned');
55
+ const retry = message('retry');
56
+ Feed.setParent(retry, answer);
57
+
58
+ const { messages } = projectThread({ feedMessages: [first, answer, abandoned, retry] });
59
+ expect(text(messages)).toEqual(['first', 'answer', 'retry']);
60
+ });
61
+
62
+ // Edit-and-resend: rewinding to a prompt discards the prompt and everything after it, so the user can
63
+ // revise the question rather than stare at it unanswered.
64
+ test('a pending rewind truncates to what precedes it', ({ expect }) => {
65
+ const first = message('first');
66
+ const answer = message('answer');
67
+ const asked = message('asked');
68
+ const replied = message('replied');
69
+
70
+ const { messages } = projectThread({
71
+ feedMessages: [first, answer, asked, replied],
72
+ rewindFrom: asked.id,
73
+ });
74
+ expect(text(messages)).toEqual(['first', 'answer']);
75
+ });
76
+
77
+ test('rewinding to the first turn empties the thread', ({ expect }) => {
78
+ const first = message('first');
79
+ const answer = message('answer');
80
+ const { messages } = projectThread({ feedMessages: [first, answer], rewindFrom: first.id });
81
+ expect(messages).toEqual([]);
82
+ });
83
+
84
+ test('a stale rewind pointer falls back to the feed lineage', ({ expect }) => {
85
+ const first = message('first');
86
+ const answer = message('answer');
87
+ const { messages } = projectThread({
88
+ feedMessages: [first, answer],
89
+ rewindFrom: message('never replicated').id,
90
+ });
91
+ expect(text(messages)).toEqual(['first', 'answer']);
92
+ });
93
+
94
+ test('an empty feed projects nothing', ({ expect }) => {
95
+ expect(projectThread({ feedMessages: [] }).messages).toEqual([]);
96
+ });
97
+ });
98
+
99
+ describe('resolveRewind', () => {
100
+ test('returns the discard point and the prompt text to restore', ({ expect }) => {
101
+ const prompt = message('what is a feed?');
102
+ const resolved = resolveRewind([message('earlier'), prompt], prompt.id);
103
+ expect(resolved).toEqual({ rewindFrom: prompt.id, text: 'what is a feed?' });
104
+ });
105
+
106
+ test('an absent message resolves to nothing, so a stale click is a no-op', ({ expect }) => {
107
+ expect(resolveRewind([message('only')], message('absent').id)).toBeUndefined();
108
+ });
109
+ });
110
+
111
+ let clock = 0;
112
+
113
+ const message = (text: string, sender: 'user' | 'assistant' = 'user') =>
114
+ Message.make({ created: new Date(clock++).toISOString(), sender, blocks: [{ _tag: 'text', text }] });
115
+
116
+ /** Stamps the queue position a position authority would have assigned. */
117
+ const positioned = (message: Message.Message, position: number) => {
118
+ Obj.update(message, (message) => {
119
+ Obj.getMeta(message).keys.push({ source: Feed.POSITION_KEY, id: String(position) });
120
+ });
121
+ return message;
122
+ };
123
+
124
+ const text = (messages: readonly Message.Message[]) =>
125
+ messages.map((message) => (message.blocks[0] as { text: string }).text);
126
+
127
+ const sortText = (messages: Message.Message[]) => text(Array.sort(messages, byAppendOrder));
@@ -0,0 +1,87 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Array from 'effect/Array';
6
+ import * as Order from 'effect/Order';
7
+
8
+ import { Feed } from '@dxos/echo';
9
+ import { Message } from '@dxos/types';
10
+
11
+ /**
12
+ * Append order for {@link Feed.history}, which walks lineage positionally rather than by time.
13
+ *
14
+ * Position is authoritative but server-assigned: locally-written blocks — and every block until a
15
+ * position authority acknowledges them — report `+Infinity`, and a query returns an unordered set, so
16
+ * position alone leaves them in arbitrary order. `created` breaks those ties: sound locally, where one
17
+ * conversation's messages come off one clock, and consulted only when position cannot decide.
18
+ */
19
+ export const byAppendOrder: Order.Order<Message.Message> = (a, b) => {
20
+ const positionA = Feed.getPosition(a);
21
+ const positionB = Feed.getPosition(b);
22
+ if (positionA !== positionB) {
23
+ return positionA < positionB ? -1 : 1;
24
+ }
25
+ return a.created < b.created ? -1 : a.created > b.created ? 1 : 0;
26
+ };
27
+
28
+ export type ThreadProjection = {
29
+ /** The turns to render, in append order. */
30
+ messages: Message.Message[];
31
+ };
32
+
33
+ /**
34
+ * The turns a thread should render: those reachable from the feed's head, so a rewind's abandoned turns
35
+ * disappear from the view exactly as they disappear from the model's history.
36
+ *
37
+ * A pending `rewindFrom` truncates the view to what precedes it — the rewound-to prompt and everything
38
+ * after it, since the point of rewinding to a prompt is to re-ask it. The pointer is cleared by the next
39
+ * append (which turns the fork into lineage), so a rewind that is never followed through stays visible
40
+ * as a truncated thread with the prompt restored in the composer.
41
+ */
42
+ export const projectThread = ({
43
+ feedMessages,
44
+ pendingMessages = [],
45
+ rewindFrom,
46
+ }: {
47
+ feedMessages: readonly Message.Message[];
48
+ /** Messages produced by the current turn that are not in the feed yet. */
49
+ pendingMessages?: readonly Message.Message[];
50
+ /** Earliest message a pending rewind discards. */
51
+ rewindFrom?: string;
52
+ }): ThreadProjection => {
53
+ const all = Array.dedupeWith([...feedMessages, ...pendingMessages], ({ id: a }, { id: b }) => a === b);
54
+ const sorted = Array.sort(all, byAppendOrder);
55
+
56
+ if (rewindFrom !== undefined) {
57
+ const index = sorted.findIndex((message) => message.id === rewindFrom);
58
+ if (index === 0) {
59
+ // Rewound to the first turn: nothing precedes it.
60
+ return { messages: [] };
61
+ }
62
+ if (index > 0) {
63
+ return { messages: Feed.history(sorted, { head: sorted[index - 1].id }).items };
64
+ }
65
+ // Not present — a stale pointer (e.g. the message never replicated); fall through to the feed's
66
+ // own lineage rather than blanking the thread.
67
+ }
68
+
69
+ return { messages: Feed.history(sorted).items };
70
+ };
71
+
72
+ /**
73
+ * What a rewind to `messageId` implies: the messages to discard from, and the prompt text to restore so
74
+ * the user can edit and resend it.
75
+ *
76
+ * Returns `undefined` when the message is absent, so a stale click is a no-op rather than a truncation.
77
+ */
78
+ export const resolveRewind = (
79
+ messages: readonly Message.Message[],
80
+ messageId: string,
81
+ ): { rewindFrom: string; text: string } | undefined => {
82
+ const message = messages.find((candidate) => candidate.id === messageId);
83
+ if (!message) {
84
+ return undefined;
85
+ }
86
+ return { rewindFrom: messageId, text: Message.extractText(message) };
87
+ };
@@ -13,6 +13,11 @@ import { meta } from '#meta';
13
13
 
14
14
  import { type ChatEvent } from '../Chat/events';
15
15
 
16
+ type AudioInputDevice = {
17
+ deviceId: string;
18
+ label: string;
19
+ };
20
+
16
21
  export type ChatActionsProps = ThemedClassName<
17
22
  PropsWithChildren<{
18
23
  docId?: string;
@@ -23,11 +28,6 @@ export type ChatActionsProps = ThemedClassName<
23
28
  }>
24
29
  >;
25
30
 
26
- type AudioInputDevice = {
27
- deviceId: string;
28
- label: string;
29
- };
30
-
31
31
  export const ChatActions = ({
32
32
  classNames,
33
33
  children,
@@ -179,7 +179,6 @@ export const ChatActions = ({
179
179
  ))}
180
180
 
181
181
  <DropdownMenu.Separator />
182
-
183
182
  <DropdownMenu.CheckboxItem
184
183
  checked={entityExtraction}
185
184
  onCheckedChange={handleEntityExtractionChange}
@@ -210,9 +209,10 @@ export const ChatActions = ({
210
209
  )}
211
210
 
212
211
  <IconButton
213
- // disabled={!processing} // TODO(dmaretskyi): Set processing state correctly on rehydrated agents.
212
+ disabled={!processing} // TODO(dmaretskyi): Set processing state correctly on rehydrated agents.
214
213
  variant='ghost'
215
- icon='ph--x--regular'
214
+ classNames={processing && 'text-error-text'}
215
+ icon={processing ? 'ph--square--duotone' : 'ph--square--regular'}
216
216
  iconOnly
217
217
  label={t('cancel-processing.button')}
218
218
  onClick={() => {
@@ -34,7 +34,7 @@ export const ChatMcpErrors = ({ classNames, processor }: ChatMcpErrorsProps) =>
34
34
  return (
35
35
  <Message.Root classNames={['m-1', classNames]} valence='warning'>
36
36
  <Message.Title onClose={handleDismiss}>{t('mcp-server-error.label')}</Message.Title>
37
- <Message.Content asChild>
37
+ <Message.Body asChild>
38
38
  <ul className='flex flex-col gap-0.5 text-sm'>
39
39
  {errors.map((error) => (
40
40
  <li key={`${error.url}::${error.protocol}`} className='truncate'>
@@ -44,7 +44,7 @@ export const ChatMcpErrors = ({ classNames, processor }: ChatMcpErrorsProps) =>
44
44
  </li>
45
45
  ))}
46
46
  </ul>
47
- </Message.Content>
47
+ </Message.Body>
48
48
  </Message.Root>
49
49
  );
50
50
  };
@@ -10,13 +10,14 @@ import { withPluginManager } from '@dxos/app-framework/testing';
10
10
  import { Chat } from '@dxos/assistant-toolkit';
11
11
  import { capabilities } from '@dxos/assistant-toolkit/testing';
12
12
  import { Feed, Filter, Ref } from '@dxos/echo';
13
+ import { useQuery } from '@dxos/echo-react';
13
14
  import { ChessPlugin } from '@dxos/plugin-chess/testing';
14
15
  import { ClientPlugin } from '@dxos/plugin-client/testing';
15
16
  import { initializeIdentity } from '@dxos/plugin-client/testing';
16
17
  import { MapPlugin } from '@dxos/plugin-map/testing';
17
18
  import { TablePlugin } from '@dxos/plugin-table/testing';
18
19
  import { corePlugins } from '@dxos/plugin-testing';
19
- import { useQuery, useRegistry, useSpaces } from '@dxos/react-client/echo';
20
+ import { useRegistry, useSpaces } from '@dxos/react-client/echo';
20
21
  import { Loading, withTheme } from '@dxos/react-ui/testing';
21
22
  import { Organization, Person } from '@dxos/types';
22
23
 
@@ -7,7 +7,7 @@ import React, { type JSX, useCallback, useMemo, useState } from 'react';
7
7
  import { type AiContext } from '@dxos/assistant';
8
8
  import { type Chat as ChatModule, McpServer } from '@dxos/assistant-toolkit';
9
9
  import { type Database, Filter, Obj, type Registry, Type, URI } from '@dxos/echo';
10
- import { useObject, useQuery } from '@dxos/react-client/echo';
10
+ import { useObject, useQuery } from '@dxos/echo-react';
11
11
  import { IconButton, Input, Popover, Select, useTranslation } from '@dxos/react-ui';
12
12
  import { Listbox } from '@dxos/react-ui-list';
13
13
  import { SearchList, useSearchListResults } from '@dxos/react-ui-search';
@@ -79,14 +79,14 @@ export const ChatOptions = ({ chat, db, context, registry, presets, preset, onPr
79
79
  <ModelsPanel presets={presets} preset={preset} onPresetChange={onPresetChange} />
80
80
  </Tabs.Panel>
81
81
  <Tabs.Tablist classNames={[styles.toolbar]}>
82
- <Tabs.IconTab value='view' icon='ph--eye--regular' label={t('chat-view.title')} />
83
- <Tabs.IconTab value='skills' icon='ph--blueprint--regular' label={t('options.skills.title')} />
84
- <Tabs.IconTab
82
+ <Tabs.IconButton value='view' icon='ph--eye--regular' label={t('chat-view.title')} />
83
+ <Tabs.IconButton value='skills' icon='ph--blueprint--regular' label={t('options.skills.title')} />
84
+ <Tabs.IconButton
85
85
  value='mcp-servers'
86
86
  icon='ph--plugs-connected--regular'
87
87
  label={t('options.mcp.title')}
88
88
  />
89
- <Tabs.IconTab value='model' icon='ph--cpu--regular' label={t('options.chat-model.title')} />
89
+ <Tabs.IconButton value='model' icon='ph--cpu--regular' label={t('options.chat-model.title')} />
90
90
  </Tabs.Tablist>
91
91
  </Tabs.Viewport>
92
92
  </Tabs.Root>
@@ -8,9 +8,17 @@ import React, { useCallback, useEffect, useId, useMemo, useRef } from 'react';
8
8
 
9
9
  import { type Chat } from '@dxos/assistant-toolkit';
10
10
  import { type Event } from '@dxos/async';
11
- import { type Database } from '@dxos/echo';
11
+ import { Project } from '@dxos/compute';
12
+ import { type Database, Obj } from '@dxos/echo';
13
+ import { useObject } from '@dxos/echo-react';
12
14
  import { Input, type ThemedClassName, useDynamicRef, useTranslation } from '@dxos/react-ui';
13
- import { ChatEditor, type ChatEditorController, type ChatEditorProps } from '@dxos/react-ui-chat';
15
+ import {
16
+ ChatEditor,
17
+ type ChatEditorController,
18
+ type ChatEditorProps,
19
+ ChatStatusIndicator,
20
+ commands,
21
+ } from '@dxos/react-ui-chat';
14
22
  import { pendingText } from '@dxos/ui-editor';
15
23
  import { mx } from '@dxos/ui-theme';
16
24
  import { type Merge } from '@dxos/util';
@@ -20,12 +28,11 @@ import { meta } from '#meta';
20
28
  import { type ChatPresetProps } from '#types';
21
29
 
22
30
  import { type AiChatProcessor } from '../../processor';
23
- import { type ChatEvent } from '../Chat/events';
31
+ import { type ChatEvent } from '../Chat';
24
32
  import { ChatActions, type ChatActionsProps } from './ChatActions';
25
33
  import { ChatMcpErrors } from './ChatMcpErrors';
26
34
  import { ChatOptions } from './ChatOptions';
27
35
  import { ChatReferences } from './ChatReferences';
28
- import { ChatStatusIndicator } from './ChatStatusIndicator';
29
36
  import { useChatVoiceInput } from './useChatVoiceInput';
30
37
 
31
38
  export type ChatPromptProps = Merge<
@@ -40,6 +47,8 @@ export type ChatPromptProps = Merge<
40
47
  /** Read-only indicator of whether the configured provider is the remote (online) service. */
41
48
  online?: boolean;
42
49
  placeholder?: ChatEditorProps['placeholder'];
50
+ /** Object the chat is attached to; its project instructions (if any) supply sentinel-command completion. */
51
+ companionTo?: Obj.Unknown;
43
52
  }>,
44
53
  ChatPresetProps
45
54
  >;
@@ -57,6 +66,7 @@ export const ChatPrompt = ({
57
66
  settings = true,
58
67
  presets,
59
68
  preset,
69
+ companionTo,
60
70
  }: ChatPromptProps) => {
61
71
  const { t } = useTranslation(meta.profile.key);
62
72
 
@@ -80,7 +90,23 @@ export const ChatPrompt = ({
80
90
  useChatVoiceInput(docId, editorRef);
81
91
 
82
92
  const keymapExtensions = useChatKeymapExtensions({ event });
83
- const extensions = useMemo(() => [keymapExtensions, pendingText()], [keymapExtensions]);
93
+
94
+ // Sentinel-command completion is sourced from the bound project's instructions, if any.
95
+ const [companion] = useObject(companionTo);
96
+ const [instructions] = useObject(Obj.instanceOf(Project.Project, companion) ? companion.instructions : undefined);
97
+ const commandsRef = useDynamicRef(instructions?.commands ?? []);
98
+ const commandsExtension = useMemo(
99
+ () =>
100
+ commands({
101
+ getCommands: () => commandsRef.current.map(({ sentinel, description }) => ({ sentinel, description })),
102
+ }),
103
+ [commandsRef],
104
+ );
105
+
106
+ const extensions = useMemo(
107
+ () => [keymapExtensions, pendingText(), commandsExtension],
108
+ [keymapExtensions, commandsExtension],
109
+ );
84
110
 
85
111
  const handleSubmit = useCallback<NonNullable<ChatEditorProps['onSubmit']>>(
86
112
  (text) => {
@@ -105,7 +131,7 @@ export const ChatPrompt = ({
105
131
  className={mx(
106
132
  'flex flex-col w-full dx-density-md',
107
133
  outline &&
108
- 'bg-group-surface rounded-sm border border-subdued-separator transition transition-border [&:has(.cm-content:focus)]:border-separator',
134
+ 'dx-group-surface rounded-sm border border-subdued-separator transition transition-border [&:has(.cm-content:focus)]:border-separator',
109
135
  classNames,
110
136
  )}
111
137
  >
@@ -116,6 +142,7 @@ export const ChatPrompt = ({
116
142
  <ChatEditor
117
143
  ref={editorRef}
118
144
  autoFocus
145
+ markdown
119
146
  lineWrapping
120
147
  classNames='col-span-2 pt-0.5'
121
148
  placeholder={placeholder ?? t('prompt.placeholder')}
@@ -8,5 +8,4 @@ export * from './ChatOptions';
8
8
  export * from './ChatPresets';
9
9
  export * from './ChatPrompt';
10
10
  export * from './ChatReferences';
11
- export * from './ChatStatusIndicator';
12
11
  export * from './ChatStatus';
@@ -8,12 +8,13 @@ import React from 'react';
8
8
 
9
9
  import { withPluginManager } from '@dxos/app-framework/testing';
10
10
  import { Database, Filter, Obj } from '@dxos/echo';
11
+ import { useQuery } from '@dxos/echo-react';
11
12
  import { DxAnchor } from '@dxos/lit-ui/react';
12
13
  import { ClientPlugin } from '@dxos/plugin-client/testing';
13
14
  import { initializeIdentity } from '@dxos/plugin-client/testing';
14
15
  import { PreviewPlugin } from '@dxos/plugin-preview/testing';
15
16
  import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
16
- import { useQuery, useSpaces } from '@dxos/react-client/echo';
17
+ import { useSpaces } from '@dxos/react-client/echo';
17
18
  import { Loading, withLayout } from '@dxos/react-ui/testing';
18
19
  import { Organization } from '@dxos/types';
19
20
 
@@ -7,15 +7,18 @@ import * as Effect from 'effect/Effect';
7
7
  import * as Fiber from 'effect/Fiber';
8
8
  import * as Layer from 'effect/Layer';
9
9
  import React, { useEffect, useMemo, useState } from 'react';
10
+ import { expect, userEvent, waitFor, within } from 'storybook/test';
10
11
 
11
12
  import { withPluginManager } from '@dxos/app-framework/testing';
12
13
  import { Database, Feed, Filter, Query } from '@dxos/echo';
14
+ import { useQuery } from '@dxos/echo-react';
13
15
  import { EffectEx } from '@dxos/effect';
14
16
  import { ClientPlugin, initializeIdentity } from '@dxos/plugin-client/testing';
15
17
  import { PreviewPlugin } from '@dxos/plugin-preview/testing';
16
18
  import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
17
19
  import { random } from '@dxos/random';
18
- import { useQuery, useSpaces } from '@dxos/react-client/echo';
20
+ import { useSpaces } from '@dxos/react-client/echo';
21
+ import { Button } from '@dxos/react-ui';
19
22
  import { EditorPreviewProvider } from '@dxos/react-ui-editor';
20
23
  import { Loading, withLayout, withTheme } from '@dxos/react-ui/testing';
21
24
  import { Message, Organization, Person } from '@dxos/types';
@@ -29,9 +32,15 @@ random.seed(1);
29
32
 
30
33
  type MessageGenerator = Effect.Effect<void, never, Database.Service | Feed.ContextFeedService>;
31
34
 
32
- type StoryArgs = { generator?: MessageGenerator[]; delay?: number; wait?: boolean } & ChatThreadProps;
35
+ type StoryArgs = {
36
+ generator?: MessageGenerator[];
37
+ delay?: number;
38
+ wait?: boolean;
39
+ /** Render a toggle that unmounts and remounts the thread, reproducing navigating away and back. */
40
+ remountable?: boolean;
41
+ } & ChatThreadProps;
33
42
 
34
- const DefaultStory = ({ generator = [], delay = 0, wait, ...props }: StoryArgs) => {
43
+ const DefaultStory = ({ generator = [], delay = 0, wait, remountable, ...props }: StoryArgs) => {
35
44
  const [space] = useSpaces();
36
45
  const feed = useMemo<Feed.Feed | undefined>(
37
46
  () => (space ? space.db.add(Feed.make({ name: 'chat' })) : undefined),
@@ -73,11 +82,32 @@ const DefaultStory = ({ generator = [], delay = 0, wait, ...props }: StoryArgs)
73
82
 
74
83
  return (
75
84
  <EditorPreviewProvider onLookup={async ({ dxn, label }) => ({ label, text: dxn })}>
76
- <ChatThread {...props} messages={messages} />
85
+ {remountable ? (
86
+ <RemountableThread {...props} messages={messages} />
87
+ ) : (
88
+ <ChatThread {...props} messages={messages} />
89
+ )}
77
90
  </EditorPreviewProvider>
78
91
  );
79
92
  };
80
93
 
94
+ /**
95
+ * Unmount/remount harness. Returning to a chat remounts the thread, which re-walks the messages and
96
+ * replaces the document — and a full replace clears accumulated widget props, so tool rows depend on
97
+ * the rehydration that follows it. Mounting fresh never exercises that path.
98
+ */
99
+ const RemountableThread = (props: ChatThreadProps) => {
100
+ const [mounted, setMounted] = useState(true);
101
+ return (
102
+ <div className='flex flex-col h-full'>
103
+ <Button data-testid='story.toggleMount' onClick={() => setMounted((value) => !value)}>
104
+ {mounted ? 'Unmount' : 'Mount'}
105
+ </Button>
106
+ {mounted && <ChatThread {...props} />}
107
+ </div>
108
+ );
109
+ };
110
+
81
111
  const meta = {
82
112
  title: 'plugins/plugin-assistant/components/ChatThread',
83
113
  component: ChatThread,
@@ -117,6 +147,35 @@ export const Default: Story = {
117
147
  },
118
148
  };
119
149
 
150
+ /**
151
+ * Every user prompt carries a rewind toolbar. It is emitted as its own markdown block after the
152
+ * `<prompt>` tag; a single newline between them would let CommonMark absorb the toolbar into the
153
+ * prompt's HTML block, so this asserts the tag actually parses into a widget.
154
+ */
155
+ export const Rewind: Story = {
156
+ args: {
157
+ generator: createMessageGenerator(),
158
+ wait: true,
159
+ },
160
+ play: async ({ canvasElement }) => {
161
+ const canvas = within(canvasElement);
162
+ const buttons = await waitFor(
163
+ async () => {
164
+ const found = canvas.queryAllByTestId('chat.rewind');
165
+ await expect(found.length).toBeGreaterThan(0);
166
+ return found;
167
+ },
168
+ { timeout: 10_000 },
169
+ );
170
+
171
+ // One toolbar per user prompt.
172
+ const prompts = canvasElement.querySelectorAll('.cm-prompt, [data-prompt]');
173
+ if (prompts.length > 0) {
174
+ await expect(buttons.length).toBe(prompts.length);
175
+ }
176
+ },
177
+ };
178
+
120
179
  export const Delayed: Story = {
121
180
  args: {
122
181
  generator: createMessageGenerator(),
@@ -128,3 +187,39 @@ export const Delayed: Story = {
128
187
  },
129
188
  },
130
189
  };
190
+
191
+ /**
192
+ * Tool rows must survive navigating away and back.
193
+ *
194
+ * They render from out-of-band widget state, not from the document: `blockToMarkdown` emits a
195
+ * `<toolCall id/>` placeholder and pushes the blocks via `updateWidget`; an empty state renders an
196
+ * empty row. On remount `MessageSyncer.reset` replaces the document, which fires `xmlTagResetEffect`
197
+ * and clears that state, then rehydrates it — and that rehydration used to be dropped, because the
198
+ * rebuild it triggers replaces the widget instances the editor was routing updates through
199
+ * (`xml-tags.test.ts`, "state reaches a mounted widget after a rebuild replaced its decoration
200
+ * instance").
201
+ */
202
+ export const Remount: Story = {
203
+ args: {
204
+ generator: createMessageGenerator(),
205
+ wait: true,
206
+ remountable: true,
207
+ },
208
+ play: async ({ canvasElement }) => {
209
+ const canvas = within(canvasElement);
210
+
211
+ // Streaming path: the tool rows render as the messages land.
212
+ await expect(canvas.findByText(/Calling search/, undefined, { timeout: 10_000 })).resolves.toBeTruthy();
213
+ await expect(canvas.findByText(/Calling create/, undefined, { timeout: 10_000 })).resolves.toBeTruthy();
214
+
215
+ // Away and back.
216
+ const toggle = await canvas.findByTestId('story.toggleMount');
217
+ await userEvent.click(toggle);
218
+ await waitFor(() => expect(canvas.queryByText(/Calling search/)).toBeNull());
219
+ await userEvent.click(toggle);
220
+
221
+ // Replay path: same rows, rebuilt from the messages rather than from streaming updates.
222
+ await expect(canvas.findByText(/Calling search/, undefined, { timeout: 10_000 })).resolves.toBeTruthy();
223
+ await expect(canvas.findByText(/Calling create/, undefined, { timeout: 10_000 })).resolves.toBeTruthy();
224
+ },
225
+ };