@signalflare-ai/ui 1.2.0 → 1.3.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 (317) hide show
  1. package/CHANGELOG.md +77 -1
  2. package/ai/component-registry.json +208 -550
  3. package/ai/component-registry.md +3042 -3115
  4. package/ai/schemas.ts +504 -96
  5. package/dist/.build-complete +1 -1
  6. package/dist/ai/schemas.d.ts.map +1 -1
  7. package/dist/{ai-actions-BdUZI3Gk.js → ai-actions-CBfz5XEf.js} +4 -4
  8. package/dist/{ai-actions-BdUZI3Gk.js.map → ai-actions-CBfz5XEf.js.map} +1 -1
  9. package/dist/{ai-agent-card-BR2NIYhi.js → ai-agent-card-CByAUe0q.js} +3 -3
  10. package/dist/ai-agent-card-CByAUe0q.js.map +1 -0
  11. package/dist/{ai-approval-Ba7mrKba.js → ai-approval-Ci8N70a7.js} +4 -3
  12. package/dist/{ai-approval-Ba7mrKba.js.map → ai-approval-Ci8N70a7.js.map} +1 -1
  13. package/dist/{ai-code-block-CZtoL73R.js → ai-code-block-P9TJHvaC.js} +37 -39
  14. package/dist/ai-code-block-P9TJHvaC.js.map +1 -0
  15. package/dist/{ai-conversation-Cc7WlaBg.js → ai-conversation-Qslfdi1t.js} +28 -42
  16. package/dist/ai-conversation-Qslfdi1t.js.map +1 -0
  17. package/dist/{ai-info-banner-C7EWPBj7.js → ai-info-banner-B_9vtGK3.js} +3 -3
  18. package/dist/{ai-info-banner-C7EWPBj7.js.map → ai-info-banner-B_9vtGK3.js.map} +1 -1
  19. package/dist/{ai-message-Bp7L68U_.js → ai-message-Ci3gwM7G.js} +6 -6
  20. package/dist/{ai-message-Bp7L68U_.js.map → ai-message-Ci3gwM7G.js.map} +1 -1
  21. package/dist/{ai-mission-header-TiCJfTNt.js → ai-mission-header-CaBc19-t.js} +2 -2
  22. package/dist/{ai-mission-header-TiCJfTNt.js.map → ai-mission-header-CaBc19-t.js.map} +1 -1
  23. package/dist/{ai-part-group-DNb9I446.js → ai-part-group-Dx1Mr92B.js} +5 -4
  24. package/dist/ai-part-group-Dx1Mr92B.js.map +1 -0
  25. package/dist/{ai-prompt-input-BVvov_KF.js → ai-prompt-input-Bm4XoSj2.js} +19 -17
  26. package/dist/ai-prompt-input-Bm4XoSj2.js.map +1 -0
  27. package/dist/{ai-question-GPPMk7YM.js → ai-question-OyJovxGe.js} +4 -3
  28. package/dist/{ai-question-GPPMk7YM.js.map → ai-question-OyJovxGe.js.map} +1 -1
  29. package/dist/{ai-reasoning-_feFjk56.js → ai-reasoning-BLfBXx3F.js} +9 -5
  30. package/dist/ai-reasoning-BLfBXx3F.js.map +1 -0
  31. package/dist/{ai-response-CvjV3WhV.js → ai-response-hbVCZJmo.js} +2 -2
  32. package/dist/{ai-response-CvjV3WhV.js.map → ai-response-hbVCZJmo.js.map} +1 -1
  33. package/dist/{ai-shimmer-j6lKIrjj.js → ai-shimmer-BamNMNK3.js} +2 -2
  34. package/dist/{ai-shimmer-j6lKIrjj.js.map → ai-shimmer-BamNMNK3.js.map} +1 -1
  35. package/dist/{ai-status-badge-CSU_QOdz.js → ai-status-badge-BZLczdkI.js} +2 -2
  36. package/dist/{ai-status-badge-CSU_QOdz.js.map → ai-status-badge-BZLczdkI.js.map} +1 -1
  37. package/dist/{ai-streaming-text-IWW1BhvZ.js → ai-streaming-text-DgYu64UH.js} +1 -1
  38. package/dist/{ai-streaming-text-IWW1BhvZ.js.map → ai-streaming-text-DgYu64UH.js.map} +1 -1
  39. package/dist/{ai-subagent-JA4iIMW3.js → ai-subagent-p97AI1h9.js} +3 -3
  40. package/dist/{ai-subagent-JA4iIMW3.js.map → ai-subagent-p97AI1h9.js.map} +1 -1
  41. package/dist/{ai-suggestion-BdO6MBuH.js → ai-suggestion-Bj6vF7CT.js} +3 -3
  42. package/dist/{ai-suggestion-BdO6MBuH.js.map → ai-suggestion-Bj6vF7CT.js.map} +1 -1
  43. package/dist/{ai-task-list-DYw4R1FA.js → ai-task-list-C_UQYpk9.js} +6 -4
  44. package/dist/{ai-task-list-DYw4R1FA.js.map → ai-task-list-C_UQYpk9.js.map} +1 -1
  45. package/dist/{ai-timeline-C42tOUT8.js → ai-timeline-CePL1LOU.js} +3 -3
  46. package/dist/ai-timeline-CePL1LOU.js.map +1 -0
  47. package/dist/{ai-tool-03jOTwUI.js → ai-tool-CfRcwmHT.js} +17 -11
  48. package/dist/ai-tool-CfRcwmHT.js.map +1 -0
  49. package/dist/{ai-usage-bar-BRf5LC_b.js → ai-usage-bar-45pVRCGA.js} +2 -2
  50. package/dist/{ai-usage-bar-BRf5LC_b.js.map → ai-usage-bar-45pVRCGA.js.map} +1 -1
  51. package/dist/{badge-BheXjMc8.js → badge-Beb-6uut.js} +5 -5
  52. package/dist/{badge-BheXjMc8.js.map → badge-Beb-6uut.js.map} +1 -1
  53. package/dist/{banner-CcsjunJg.js → banner-CCEksxPg.js} +3 -3
  54. package/dist/{banner-CcsjunJg.js.map → banner-CCEksxPg.js.map} +1 -1
  55. package/dist/{breadcrumbs-CouSyy3H.js → breadcrumbs-HiTmgaZ4.js} +5 -5
  56. package/dist/{breadcrumbs-CouSyy3H.js.map → breadcrumbs-HiTmgaZ4.js.map} +1 -1
  57. package/dist/{button-CO6-qPax.js → button-BHOgXJRU.js} +4 -4
  58. package/dist/{button-CO6-qPax.js.map → button-BHOgXJRU.js.map} +1 -1
  59. package/dist/catalog.js +1 -1
  60. package/dist/catalog.js.map +1 -1
  61. package/dist/{chart-Dg0qUeSc.js → chart-B9FfZdKs.js} +7 -7
  62. package/dist/chart-B9FfZdKs.js.map +1 -0
  63. package/dist/{checkbox-D7p4QKsC.js → checkbox-Cy_OCyay.js} +3 -3
  64. package/dist/{checkbox-D7p4QKsC.js.map → checkbox-Cy_OCyay.js.map} +1 -1
  65. package/dist/{clipboard-text-kLaMogs3.js → clipboard-text-CKSvNp9L.js} +6 -5
  66. package/dist/clipboard-text-CKSvNp9L.js.map +1 -0
  67. package/dist/{cn-YROP2_ox.js → cn-CmAOpn49.js} +2 -2
  68. package/dist/{cn-YROP2_ox.js.map → cn-CmAOpn49.js.map} +1 -1
  69. package/dist/{code-BN8InC0G.js → code-JsQz-0G_.js} +4 -4
  70. package/dist/{code-BN8InC0G.js.map → code-JsQz-0G_.js.map} +1 -1
  71. package/dist/{collapsible-D_ueZ0jz.js → collapsible-1kOZ-89L.js} +2 -2
  72. package/dist/{collapsible-D_ueZ0jz.js.map → collapsible-1kOZ-89L.js.map} +1 -1
  73. package/dist/{combobox-B7TOK0U2.js → combobox-CQwDmqgA.js} +4 -4
  74. package/dist/{combobox-B7TOK0U2.js.map → combobox-CQwDmqgA.js.map} +1 -1
  75. package/dist/command-line/cli.js +3 -3
  76. package/dist/{command-palette-CuNUyJca.js → command-palette-Bkuv3e6o.js} +20 -5
  77. package/dist/command-palette-Bkuv3e6o.js.map +1 -0
  78. package/dist/components/ai-actions.js +1 -1
  79. package/dist/components/ai-agent-card.js +1 -1
  80. package/dist/components/ai-approval.js +1 -1
  81. package/dist/components/ai-code-block.js +1 -1
  82. package/dist/components/ai-conversation.js +1 -1
  83. package/dist/components/ai-info-banner.js +1 -1
  84. package/dist/components/ai-message.js +1 -1
  85. package/dist/components/ai-mission-header.js +1 -1
  86. package/dist/components/ai-part-group.js +1 -1
  87. package/dist/components/ai-prompt-input.js +1 -1
  88. package/dist/components/ai-question.js +1 -1
  89. package/dist/components/ai-reasoning.js +1 -1
  90. package/dist/components/ai-response.js +1 -1
  91. package/dist/components/ai-shimmer.js +1 -1
  92. package/dist/components/ai-status-badge.js +1 -1
  93. package/dist/components/ai-streaming-text.js +1 -1
  94. package/dist/components/ai-subagent.js +1 -1
  95. package/dist/components/ai-suggestion.js +1 -1
  96. package/dist/components/ai-task-list.js +1 -1
  97. package/dist/components/ai-timeline.js +1 -1
  98. package/dist/components/ai-tool.js +1 -1
  99. package/dist/components/ai-usage-bar.js +1 -1
  100. package/dist/components/badge.js +1 -1
  101. package/dist/components/banner.js +1 -1
  102. package/dist/components/breadcrumbs.js +1 -1
  103. package/dist/components/button.js +1 -1
  104. package/dist/components/chart.js +2 -2
  105. package/dist/components/checkbox.js +1 -1
  106. package/dist/components/clipboard-text.js +1 -1
  107. package/dist/components/code.js +1 -1
  108. package/dist/components/collapsible.js +1 -1
  109. package/dist/components/combobox.js +1 -1
  110. package/dist/components/command-palette.js +1 -1
  111. package/dist/components/data-grid.js +1 -1
  112. package/dist/components/date-picker.js +1 -1
  113. package/dist/components/date-range-picker.js +1 -1
  114. package/dist/components/dialog.js +1 -1
  115. package/dist/components/dropdown.js +1 -1
  116. package/dist/components/empty.js +1 -1
  117. package/dist/components/field.js +1 -1
  118. package/dist/components/filters.js +1 -1
  119. package/dist/components/flow.js +1 -1
  120. package/dist/components/grid.js +1 -1
  121. package/dist/components/input.js +2 -2
  122. package/dist/components/label.js +1 -1
  123. package/dist/components/layer-card.js +1 -1
  124. package/dist/components/link.js +3 -3
  125. package/dist/components/link.js.map +1 -1
  126. package/dist/components/loader.js +2 -2
  127. package/dist/components/menubar.js +1 -1
  128. package/dist/components/meter.js +1 -1
  129. package/dist/components/pagination.js +1 -1
  130. package/dist/components/popover.js +1 -1
  131. package/dist/components/radio.js +1 -1
  132. package/dist/components/select.js +1 -1
  133. package/dist/components/sensitive-input.js +1 -1
  134. package/dist/components/sidebar.js +1 -1
  135. package/dist/components/signalflare-ai-logo.js +1 -1
  136. package/dist/components/sparkline.js +1 -1
  137. package/dist/components/stat-card.js +1 -1
  138. package/dist/components/surface.js +1 -1
  139. package/dist/components/switch.js +1 -1
  140. package/dist/components/table.js +1 -1
  141. package/dist/components/tabs.js +1 -1
  142. package/dist/components/text-roll.js +1 -1
  143. package/dist/components/text.js +1 -1
  144. package/dist/components/theme-toggle.js +1 -1
  145. package/dist/components/toast.js +1 -1
  146. package/dist/components/tooltip.js +1 -1
  147. package/dist/components/use-agent-harness.js +1 -1
  148. package/dist/{data-grid-DGHmU0w3.js → data-grid-DDSFMHud.js} +136 -53
  149. package/dist/data-grid-DDSFMHud.js.map +1 -0
  150. package/dist/{date-picker--ox89RBy.js → date-picker-O34AqG3f.js} +2 -2
  151. package/dist/{date-picker--ox89RBy.js.map → date-picker-O34AqG3f.js.map} +1 -1
  152. package/dist/{date-range-picker-DVa7QBqE.js → date-range-picker-YKYvum_r.js} +29 -39
  153. package/dist/{date-range-picker-DVa7QBqE.js.map → date-range-picker-YKYvum_r.js.map} +1 -1
  154. package/dist/{dialog-Bv1oSFOd.js → dialog-DYqu4aDO.js} +3 -3
  155. package/dist/{dialog-Bv1oSFOd.js.map → dialog-DYqu4aDO.js.map} +1 -1
  156. package/dist/{dist-B6iWiWwp.js → dist-6AtBsaJE.js} +153 -47
  157. package/dist/dist-6AtBsaJE.js.map +1 -0
  158. package/dist/{dropdown-B_nrGXjV.js → dropdown-XzbnRLYR.js} +15 -5
  159. package/dist/dropdown-XzbnRLYR.js.map +1 -0
  160. package/dist/{echart-CdOUaT-r.js → echart-DGBIVAv1.js} +23 -57
  161. package/dist/{echart-CdOUaT-r.js.map → echart-DGBIVAv1.js.map} +1 -1
  162. package/dist/{empty-DZnN0zKX.js → empty-C1tAkawe.js} +6 -6
  163. package/dist/{empty-DZnN0zKX.js.map → empty-C1tAkawe.js.map} +1 -1
  164. package/dist/{field-B_yVof52.js → field-DBpFzzBS.js} +3 -3
  165. package/dist/{field-B_yVof52.js.map → field-DBpFzzBS.js.map} +1 -1
  166. package/dist/{filters-cpJCY21R.js → filters-SmEl93za.js} +10 -10
  167. package/dist/filters-SmEl93za.js.map +1 -0
  168. package/dist/{flow-B4v198ot.js → flow-BLzgbq1T.js} +6 -6
  169. package/dist/flow-BLzgbq1T.js.map +1 -0
  170. package/dist/genui.js +2 -2
  171. package/dist/genui.js.map +1 -1
  172. package/dist/{grid-CEd64Lnh.js → grid-CifjQL-5.js} +2 -2
  173. package/dist/{grid-CEd64Lnh.js.map → grid-CifjQL-5.js.map} +1 -1
  174. package/dist/{highlight-to-react-D0Yav4jk.js → highlight-to-react-DN9dUCS2.js} +9 -15
  175. package/dist/highlight-to-react-DN9dUCS2.js.map +1 -0
  176. package/dist/index.js +71 -71
  177. package/dist/index.js.map +1 -1
  178. package/dist/{input-ClB_E4Lb.js → input-COmx2M_R.js} +5 -5
  179. package/dist/{input-ClB_E4Lb.js.map → input-COmx2M_R.js.map} +1 -1
  180. package/dist/{input-B2bbijRh.js → input-GkfMQZC_.js} +3 -3
  181. package/dist/{input-B2bbijRh.js.map → input-GkfMQZC_.js.map} +1 -1
  182. package/dist/{label-DUv_urO1.js → label-CiGZ464N.js} +3 -3
  183. package/dist/{label-DUv_urO1.js.map → label-CiGZ464N.js.map} +1 -1
  184. package/dist/{layer-card-BK7eYfwn.js → layer-card-8l8GuLQr.js} +2 -2
  185. package/dist/{layer-card-BK7eYfwn.js.map → layer-card-8l8GuLQr.js.map} +1 -1
  186. package/dist/{layout-DJHMMap2.js → layout-CWBE0qwx.js} +258 -154
  187. package/dist/layout-CWBE0qwx.js.map +1 -0
  188. package/dist/{link-provider-BUZKXaNE.js → link-provider-BSn8YJon.js} +2 -2
  189. package/dist/link-provider-BSn8YJon.js.map +1 -0
  190. package/dist/{loader-DAcc-Uag.js → loader-BEMz8pJO.js} +1 -1
  191. package/dist/{loader-DAcc-Uag.js.map → loader-BEMz8pJO.js.map} +1 -1
  192. package/dist/{measured-text-BI3dTJmH.js → measured-text-CXkdw9Yr.js} +45 -30
  193. package/dist/measured-text-CXkdw9Yr.js.map +1 -0
  194. package/dist/{menubar-Cxf3xeAt.js → menubar-CoOr4ocj.js} +3 -3
  195. package/dist/{menubar-Cxf3xeAt.js.map → menubar-CoOr4ocj.js.map} +1 -1
  196. package/dist/{meter-BFFe9l5b.js → meter-Pf_VOl59.js} +2 -2
  197. package/dist/{meter-BFFe9l5b.js.map → meter-Pf_VOl59.js.map} +1 -1
  198. package/dist/{pagination-yS372Tr4.js → pagination-DSY279Ta.js} +2 -2
  199. package/dist/{pagination-yS372Tr4.js.map → pagination-DSY279Ta.js.map} +1 -1
  200. package/dist/{popover-SRoJaCZr.js → popover-BY-e9co1.js} +2 -2
  201. package/dist/{popover-SRoJaCZr.js.map → popover-BY-e9co1.js.map} +1 -1
  202. package/dist/{radio-BcwhwYNB.js → radio-DZwL13j0.js} +2 -2
  203. package/dist/{radio-BcwhwYNB.js.map → radio-DZwL13j0.js.map} +1 -1
  204. package/dist/{select-DMhdoHMa.js → select-BFifYqHA.js} +6 -6
  205. package/dist/{select-DMhdoHMa.js.map → select-BFifYqHA.js.map} +1 -1
  206. package/dist/{sensitive-input-CJUpIRal.js → sensitive-input-DHLZcM73.js} +4 -4
  207. package/dist/{sensitive-input-CJUpIRal.js.map → sensitive-input-DHLZcM73.js.map} +1 -1
  208. package/dist/{sidebar-D4zrlYpn.js → sidebar-odGsdvG4.js} +6 -7
  209. package/dist/sidebar-odGsdvG4.js.map +1 -0
  210. package/dist/{signalflare-ai-logo-Bipogceq.js → signalflare-ai-logo-CNaDT_w8.js} +2 -2
  211. package/dist/{signalflare-ai-logo-Bipogceq.js.map → signalflare-ai-logo-CNaDT_w8.js.map} +1 -1
  212. package/dist/{skeleton-line-CH1-h6e2.js → skeleton-line-CxxYVTO2.js} +2 -2
  213. package/dist/{skeleton-line-CH1-h6e2.js.map → skeleton-line-CxxYVTO2.js.map} +1 -1
  214. package/dist/{sparkline-DHmgj1d0.js → sparkline-BQ-4j2W2.js} +2 -2
  215. package/dist/{sparkline-DHmgj1d0.js.map → sparkline-BQ-4j2W2.js.map} +1 -1
  216. package/dist/src/blocks/agent-harness/agent-harness.tsx +11 -11
  217. package/dist/src/blocks/commander/commander.tsx +15 -15
  218. package/dist/src/blocks/map-block/map-block.d.ts.map +1 -1
  219. package/dist/src/blocks/map-block/map-block.tsx +11 -7
  220. package/dist/src/components/ai-approval/ai-approval.d.ts.map +1 -1
  221. package/dist/src/components/ai-code-block/ai-code-block.d.ts +14 -13
  222. package/dist/src/components/ai-code-block/ai-code-block.d.ts.map +1 -1
  223. package/dist/src/components/ai-conversation/ai-conversation.d.ts.map +1 -1
  224. package/dist/src/components/ai-part-group/ai-part-group.d.ts.map +1 -1
  225. package/dist/src/components/ai-prompt-input/ai-prompt-input.d.ts.map +1 -1
  226. package/dist/src/components/ai-prompt-input/controller.d.ts.map +1 -1
  227. package/dist/src/components/ai-prompt-input/types.d.ts.map +1 -1
  228. package/dist/src/components/ai-question/ai-question.d.ts.map +1 -1
  229. package/dist/src/components/ai-reasoning/ai-reasoning.d.ts.map +1 -1
  230. package/dist/src/components/ai-response/ai-response.d.ts.map +1 -1
  231. package/dist/src/components/ai-subagent/ai-subagent.d.ts.map +1 -1
  232. package/dist/src/components/ai-tool/ai-tool.d.ts.map +1 -1
  233. package/dist/src/components/chart/echart.d.ts.map +1 -1
  234. package/dist/src/components/clipboard-text/clipboard-text.d.ts.map +1 -1
  235. package/dist/src/components/data-grid/data-grid.d.ts +2 -1
  236. package/dist/src/components/data-grid/data-grid.d.ts.map +1 -1
  237. package/dist/src/components/data-grid/features.d.ts +20 -0
  238. package/dist/src/components/data-grid/features.d.ts.map +1 -0
  239. package/dist/src/components/data-grid/types.d.ts +38 -7
  240. package/dist/src/components/data-grid/types.d.ts.map +1 -1
  241. package/dist/src/components/filters/filters.d.ts.map +1 -1
  242. package/dist/src/components/flow/use-children.d.ts +1 -1
  243. package/dist/src/components/link/link.d.ts.map +1 -1
  244. package/dist/src/components/sidebar/sidebar.d.ts +1 -1
  245. package/dist/src/components/signalflare-ai-logo/signalflare-ai-logo.d.ts.map +1 -1
  246. package/dist/src/components/text/text.d.ts +2 -1
  247. package/dist/src/components/text/text.d.ts.map +1 -1
  248. package/dist/src/components/text-roll/text-roll.d.ts.map +1 -1
  249. package/dist/src/components/theme-toggle/theme-toggle.d.ts.map +1 -1
  250. package/dist/src/components/toast/toast.d.ts.map +1 -1
  251. package/dist/src/utils/highlight-to-react.d.ts.map +1 -1
  252. package/dist/src/utils/measured-text.d.ts.map +1 -1
  253. package/dist/src/utils/use-measured-text.d.ts.map +1 -1
  254. package/dist/{stat-card-Ew-ofzEm.js → stat-card-Bspk4XFr.js} +4 -4
  255. package/dist/stat-card-Bspk4XFr.js.map +1 -0
  256. package/dist/styles/sf-standalone.css +1 -1
  257. package/dist/styles/theme-fedramp.css +3 -12
  258. package/dist/styles/theme-minimal.css +26 -104
  259. package/dist/styles/theme-sf.css +37 -142
  260. package/dist/{surface-DGwRlC0o.js → surface-CWdSFVUx.js} +3 -3
  261. package/dist/{surface-DGwRlC0o.js.map → surface-CWdSFVUx.js.map} +1 -1
  262. package/dist/{switch-BxAMfHdt.js → switch-TA4cByCJ.js} +5 -5
  263. package/dist/switch-TA4cByCJ.js.map +1 -0
  264. package/dist/{table-BBeAtYVZ.js → table-BM8JBGBs.js} +3 -3
  265. package/dist/{table-BBeAtYVZ.js.map → table-BM8JBGBs.js.map} +1 -1
  266. package/dist/{tabs-CeHu7Scn.js → tabs-bnH2vGLv.js} +2 -2
  267. package/dist/{tabs-CeHu7Scn.js.map → tabs-bnH2vGLv.js.map} +1 -1
  268. package/dist/{text-Cqryz7rk.js → text-iQ0YUFNg.js} +4 -5
  269. package/dist/{text-Cqryz7rk.js.map → text-iQ0YUFNg.js.map} +1 -1
  270. package/dist/{text-roll-Ch52hcQj.js → text-roll-C3U2jd2u.js} +5 -2
  271. package/dist/text-roll-C3U2jd2u.js.map +1 -0
  272. package/dist/{theme-toggle-LDfIKEqx.js → theme-toggle-BTVxD-fD.js} +10 -9
  273. package/dist/theme-toggle-BTVxD-fD.js.map +1 -0
  274. package/dist/{toast-CaFQNYng.js → toast-CgZVaAkw.js} +3 -3
  275. package/dist/{toast-CaFQNYng.js.map → toast-CgZVaAkw.js.map} +1 -1
  276. package/dist/{tooltip-g9lFsvcT.js → tooltip-uobk6Oh-.js} +3 -3
  277. package/dist/{tooltip-g9lFsvcT.js.map → tooltip-uobk6Oh-.js.map} +1 -1
  278. package/dist/{use-agent-harness-BTcNJdw4.js → use-agent-harness-Dl8w6X5O.js} +3 -3
  279. package/dist/{use-agent-harness-BTcNJdw4.js.map → use-agent-harness-Dl8w6X5O.js.map} +1 -1
  280. package/dist/utils.js +3 -3
  281. package/package.json +27 -25
  282. package/scripts/component-registry/discovery.ts +11 -10
  283. package/scripts/component-registry/example-cleanup.ts +8 -8
  284. package/scripts/component-registry/index.ts +6 -6
  285. package/scripts/component-registry/schema-generator.ts +1 -1
  286. package/scripts/component-registry/sub-components.ts +35 -23
  287. package/scripts/component-registry/utils.ts +11 -11
  288. package/scripts/component-registry/variant-parser.ts +17 -15
  289. package/scripts/convert-demos-to-stories.ts +5 -5
  290. package/scripts/theme-generator/config.ts +1 -5
  291. package/scripts/theme-generator/generate-css.ts +1 -1
  292. package/scripts/theme-generator/migrate.ts +3 -3
  293. package/dist/ai-agent-card-BR2NIYhi.js.map +0 -1
  294. package/dist/ai-code-block-CZtoL73R.js.map +0 -1
  295. package/dist/ai-conversation-Cc7WlaBg.js.map +0 -1
  296. package/dist/ai-part-group-DNb9I446.js.map +0 -1
  297. package/dist/ai-prompt-input-BVvov_KF.js.map +0 -1
  298. package/dist/ai-reasoning-_feFjk56.js.map +0 -1
  299. package/dist/ai-timeline-C42tOUT8.js.map +0 -1
  300. package/dist/ai-tool-03jOTwUI.js.map +0 -1
  301. package/dist/chart-Dg0qUeSc.js.map +0 -1
  302. package/dist/clipboard-text-kLaMogs3.js.map +0 -1
  303. package/dist/command-palette-CuNUyJca.js.map +0 -1
  304. package/dist/data-grid-DGHmU0w3.js.map +0 -1
  305. package/dist/dist-B6iWiWwp.js.map +0 -1
  306. package/dist/dropdown-B_nrGXjV.js.map +0 -1
  307. package/dist/filters-cpJCY21R.js.map +0 -1
  308. package/dist/flow-B4v198ot.js.map +0 -1
  309. package/dist/highlight-to-react-D0Yav4jk.js.map +0 -1
  310. package/dist/layout-DJHMMap2.js.map +0 -1
  311. package/dist/link-provider-BUZKXaNE.js.map +0 -1
  312. package/dist/measured-text-BI3dTJmH.js.map +0 -1
  313. package/dist/sidebar-D4zrlYpn.js.map +0 -1
  314. package/dist/stat-card-Ew-ofzEm.js.map +0 -1
  315. package/dist/switch-BxAMfHdt.js.map +0 -1
  316. package/dist/text-roll-Ch52hcQj.js.map +0 -1
  317. package/dist/theme-toggle-LDfIKEqx.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"use-agent-harness-BTcNJdw4.js","names":[],"sources":["../src/components/use-agent-harness/use-agent-harness.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useReducer, useRef } from \"react\";\n\n// ─── Variants (required by SignalFlare conventions) ───────────────────────────────────\n\nexport const SF_USE_AGENT_HARNESS_VARIANTS = {} as const;\nexport const SF_USE_AGENT_HARNESS_DEFAULT_VARIANTS = {} as const;\n\n// ─── Harness Event Types ──────────────────────────────────────────────────────\n\n/** All event types emitted by a Mastra Harness instance. */\nexport type HarnessEventType =\n | \"mode_changed\"\n | \"model_changed\"\n | \"thread_changed\"\n | \"thread_created\"\n | \"thread_deleted\"\n | \"state_changed\"\n | \"agent_start\"\n | \"agent_end\"\n | \"message_start\"\n | \"message_update\"\n | \"message_end\"\n | \"tool_start\"\n | \"tool_approval_required\"\n | \"tool_update\"\n | \"tool_end\"\n | \"tool_input_start\"\n | \"tool_input_delta\"\n | \"tool_input_end\"\n | \"usage_update\"\n | \"error\"\n | \"info\"\n | \"follow_up_queued\"\n | \"workspace_status_changed\"\n | \"workspace_ready\"\n | \"workspace_error\"\n | \"om_status\"\n | \"om_observation_start\"\n | \"om_observation_end\"\n | \"om_reflection_start\"\n | \"om_reflection_end\"\n | \"ask_question\"\n | \"question_answered\"\n | \"plan_approval_required\"\n | \"plan_approved\"\n | \"subagent_start\"\n | \"subagent_text_delta\"\n | \"subagent_tool_start\"\n | \"subagent_tool_end\"\n | \"subagent_end\"\n | \"subagent_model_changed\"\n | \"task_updated\"\n | \"thinking_start\"\n | \"thinking_delta\"\n | \"thinking_end\";\n\n/** Base shape of all harness events. */\nexport interface HarnessEventBase {\n type: HarnessEventType;\n}\n\nexport interface HarnessModeChangedEvent extends HarnessEventBase {\n type: \"mode_changed\";\n modeId: string;\n modeName: string;\n}\n\nexport interface HarnessModelChangedEvent extends HarnessEventBase {\n type: \"model_changed\";\n modelId: string;\n modelName?: string;\n}\n\nexport interface HarnessThreadChangedEvent extends HarnessEventBase {\n type: \"thread_changed\";\n threadId: string;\n}\n\nexport interface HarnessThreadCreatedEvent extends HarnessEventBase {\n type: \"thread_created\";\n threadId: string;\n}\n\nexport interface HarnessThreadDeletedEvent extends HarnessEventBase {\n type: \"thread_deleted\";\n threadId: string;\n}\n\nexport interface HarnessStateChangedEvent extends HarnessEventBase {\n type: \"state_changed\";\n state: Record<string, unknown>;\n changedKeys: string[];\n}\n\nexport interface HarnessAgentStartEvent extends HarnessEventBase {\n type: \"agent_start\";\n}\n\nexport interface HarnessAgentEndEvent extends HarnessEventBase {\n type: \"agent_end\";\n}\n\nexport interface HarnessMessageStartEvent extends HarnessEventBase {\n type: \"message_start\";\n messageId: string;\n role: \"assistant\" | \"user\" | \"system\";\n}\n\nexport interface HarnessMessageUpdateEvent extends HarnessEventBase {\n type: \"message_update\";\n messageId: string;\n delta: string;\n content?: string;\n}\n\nexport interface HarnessMessageEndEvent extends HarnessEventBase {\n type: \"message_end\";\n messageId: string;\n content: string;\n}\n\nexport interface HarnessToolStartEvent extends HarnessEventBase {\n type: \"tool_start\";\n toolCallId: string;\n toolName: string;\n messageId?: string;\n subagentId?: string;\n}\n\nexport interface HarnessToolApprovalRequiredEvent extends HarnessEventBase {\n type: \"tool_approval_required\";\n toolCallId: string;\n toolName: string;\n input?: unknown;\n messageId?: string;\n}\n\nexport interface HarnessToolUpdateEvent extends HarnessEventBase {\n type: \"tool_update\";\n toolCallId: string;\n summary?: string;\n progress?: number;\n}\n\nexport interface HarnessToolEndEvent extends HarnessEventBase {\n type: \"tool_end\";\n toolCallId: string;\n output?: unknown;\n error?: string;\n durationMs?: number;\n}\n\nexport interface HarnessToolInputStartEvent extends HarnessEventBase {\n type: \"tool_input_start\";\n toolCallId: string;\n}\n\nexport interface HarnessToolInputDeltaEvent extends HarnessEventBase {\n type: \"tool_input_delta\";\n toolCallId: string;\n delta: string;\n}\n\nexport interface HarnessToolInputEndEvent extends HarnessEventBase {\n type: \"tool_input_end\";\n toolCallId: string;\n input: unknown;\n}\n\nexport interface HarnessUsageUpdateEvent extends HarnessEventBase {\n type: \"usage_update\";\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n cost?: number;\n modelId?: string;\n}\n\nexport interface HarnessErrorEvent extends HarnessEventBase {\n type: \"error\";\n error: string | Error;\n messageId?: string;\n}\n\nexport interface HarnessInfoEvent extends HarnessEventBase {\n type: \"info\";\n message: string;\n}\n\nexport interface HarnessFollowUpQueuedEvent extends HarnessEventBase {\n type: \"follow_up_queued\";\n content: string;\n}\n\nexport interface HarnessWorkspaceStatusChangedEvent extends HarnessEventBase {\n type: \"workspace_status_changed\";\n status: string;\n}\n\nexport interface HarnessWorkspaceReadyEvent extends HarnessEventBase {\n type: \"workspace_ready\";\n}\n\nexport interface HarnessWorkspaceErrorEvent extends HarnessEventBase {\n type: \"workspace_error\";\n error: string | Error;\n}\n\nexport interface HarnessOMStatusEvent extends HarnessEventBase {\n type: \"om_status\";\n generationCount?: number;\n observationTokenCount?: number;\n activeObservations?: number;\n}\n\nexport interface HarnessOMObservationStartEvent extends HarnessEventBase {\n type: \"om_observation_start\";\n observationId?: string;\n}\n\nexport interface HarnessOMObservationEndEvent extends HarnessEventBase {\n type: \"om_observation_end\";\n observationId?: string;\n text?: string;\n durationMs?: number;\n}\n\nexport interface HarnessOMReflectionStartEvent extends HarnessEventBase {\n type: \"om_reflection_start\";\n}\n\nexport interface HarnessOMReflectionEndEvent extends HarnessEventBase {\n type: \"om_reflection_end\";\n text?: string;\n durationMs?: number;\n}\n\nexport interface HarnessAskQuestionEvent extends HarnessEventBase {\n type: \"ask_question\";\n questionId: string;\n question: string;\n header?: string;\n options?: Array<{ label: string; description?: string }>;\n multiple?: boolean;\n allowCustom?: boolean;\n}\n\nexport interface HarnessQuestionAnsweredEvent extends HarnessEventBase {\n type: \"question_answered\";\n questionId: string;\n answer: string;\n}\n\nexport interface HarnessPlanApprovalRequiredEvent extends HarnessEventBase {\n type: \"plan_approval_required\";\n planId: string;\n title: string;\n description?: string;\n steps?: Array<{ id: string; label: string; description?: string }>;\n}\n\nexport interface HarnessPlanApprovedEvent extends HarnessEventBase {\n type: \"plan_approved\";\n planId: string;\n}\n\nexport interface HarnessSubagentStartEvent extends HarnessEventBase {\n type: \"subagent_start\";\n subagentId: string;\n agentType?: string;\n name?: string;\n modelId?: string;\n parentMessageId?: string;\n}\n\nexport interface HarnessSubagentTextDeltaEvent extends HarnessEventBase {\n type: \"subagent_text_delta\";\n subagentId: string;\n delta: string;\n}\n\nexport interface HarnessSubagentToolStartEvent extends HarnessEventBase {\n type: \"subagent_tool_start\";\n subagentId: string;\n toolCallId: string;\n toolName: string;\n}\n\nexport interface HarnessSubagentToolEndEvent extends HarnessEventBase {\n type: \"subagent_tool_end\";\n subagentId: string;\n toolCallId: string;\n output?: unknown;\n error?: string;\n durationMs?: number;\n}\n\nexport interface HarnessSubagentEndEvent extends HarnessEventBase {\n type: \"subagent_end\";\n subagentId: string;\n error?: string;\n durationMs?: number;\n}\n\nexport interface HarnessSubagentModelChangedEvent extends HarnessEventBase {\n type: \"subagent_model_changed\";\n subagentId?: string;\n modelId: string;\n agentType?: string;\n}\n\nexport interface HarnessTaskUpdatedEvent extends HarnessEventBase {\n type: \"task_updated\";\n tasks: Array<{\n id: string;\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\" | \"cancelled\";\n priority?: \"high\" | \"medium\" | \"low\";\n }>;\n title?: string;\n}\n\n/** Emitted when the model begins a thinking/reasoning block. */\nexport interface HarnessThinkingStartEvent extends HarnessEventBase {\n type: \"thinking_start\";\n thinkingId: string;\n messageId: string;\n}\n\n/** Emitted for each incremental chunk of thinking text. */\nexport interface HarnessThinkingDeltaEvent extends HarnessEventBase {\n type: \"thinking_delta\";\n thinkingId: string;\n messageId: string;\n /** Incremental text to append. */\n delta: string;\n /** Full text so far (if available). */\n content?: string;\n}\n\n/** Emitted when a thinking block is complete. */\nexport interface HarnessThinkingEndEvent extends HarnessEventBase {\n type: \"thinking_end\";\n thinkingId: string;\n messageId: string;\n /** Final accumulated thinking text. */\n content: string;\n}\n\n/** Union of all typed harness events. */\nexport type HarnessEvent =\n | HarnessModeChangedEvent\n | HarnessModelChangedEvent\n | HarnessThreadChangedEvent\n | HarnessThreadCreatedEvent\n | HarnessThreadDeletedEvent\n | HarnessStateChangedEvent\n | HarnessAgentStartEvent\n | HarnessAgentEndEvent\n | HarnessMessageStartEvent\n | HarnessMessageUpdateEvent\n | HarnessMessageEndEvent\n | HarnessToolStartEvent\n | HarnessToolApprovalRequiredEvent\n | HarnessToolUpdateEvent\n | HarnessToolEndEvent\n | HarnessToolInputStartEvent\n | HarnessToolInputDeltaEvent\n | HarnessToolInputEndEvent\n | HarnessUsageUpdateEvent\n | HarnessErrorEvent\n | HarnessInfoEvent\n | HarnessFollowUpQueuedEvent\n | HarnessWorkspaceStatusChangedEvent\n | HarnessWorkspaceReadyEvent\n | HarnessWorkspaceErrorEvent\n | HarnessOMStatusEvent\n | HarnessOMObservationStartEvent\n | HarnessOMObservationEndEvent\n | HarnessOMReflectionStartEvent\n | HarnessOMReflectionEndEvent\n | HarnessAskQuestionEvent\n | HarnessQuestionAnsweredEvent\n | HarnessPlanApprovalRequiredEvent\n | HarnessPlanApprovedEvent\n | HarnessSubagentStartEvent\n | HarnessSubagentTextDeltaEvent\n | HarnessSubagentToolStartEvent\n | HarnessSubagentToolEndEvent\n | HarnessSubagentEndEvent\n | HarnessSubagentModelChangedEvent\n | HarnessTaskUpdatedEvent\n | HarnessThinkingStartEvent\n | HarnessThinkingDeltaEvent\n | HarnessThinkingEndEvent;\n\n// ─── Adapter Interface ────────────────────────────────────────────────────────\n\n/**\n * Minimal adapter interface for driving the AgentHarness UI.\n * Implement this to connect any event source — Mastra Harness, mock, replay, etc.\n */\nexport interface HarnessAdapter {\n /** Register an event listener. Returns an unsubscribe function. */\n subscribe: (listener: (event: HarnessEvent) => void) => () => void;\n /** Send a user message. */\n sendMessage: (params: {\n content: string;\n files?: Array<{ url: string; mediaType: string; filename: string }>;\n }) => void | Promise<void>;\n /** Respond to a pending tool approval. */\n respondToToolApproval?: (params: {\n decision: \"approve\" | \"decline\";\n }) => void | Promise<void>;\n /** Respond to a pending question. */\n respondToQuestion?: (params: {\n questionId: string;\n answer: string;\n }) => void | Promise<void>;\n /** Respond to a pending plan approval. */\n respondToPlanApproval?: (params: {\n planId: string;\n response: { action: \"approved\" | \"rejected\"; feedback?: string };\n }) => void | Promise<void>;\n /** Abort any in-progress generation. */\n abort?: () => void;\n /** Steer the agent mid-stream. */\n steer?: (params: { content: string }) => void;\n /** Select a mode. */\n selectMode?: (params: { modeId: string }) => void | Promise<void>;\n}\n\n/**\n * Create a HarnessAdapter from a real Mastra Harness instance.\n * The Mastra harness type is not imported to avoid a hard dependency.\n */\n// ─── Mastra → SignalFlare event translation ───────────────────────────────────────────\n\n/** Mastra's HarnessMessage content part (subset we care about). */\ntype MastraContentPart =\n | { type: \"text\"; text: string }\n | { type: \"thinking\"; thinking: string }\n | { type: \"tool_call\"; id: string; name: string; args: unknown }\n | { type: string; [key: string]: unknown };\n\n/** Mastra's HarnessMessage shape (from @mastra/core). */\ninterface MastraHarnessMessage {\n id: string;\n role: \"user\" | \"assistant\" | \"system\";\n content: MastraContentPart[];\n createdAt: Date;\n stopReason?: \"complete\" | \"tool_use\" | \"aborted\" | \"error\";\n}\n\n/** Mastra's raw HarnessEvent union (only the fields we translate). */\ntype MastraHarnessEvent =\n | { type: \"message_start\"; message: MastraHarnessMessage }\n | { type: \"message_update\"; message: MastraHarnessMessage }\n | { type: \"message_end\"; message: MastraHarnessMessage }\n | { type: string; [key: string]: unknown };\n\n/**\n * Translate a Mastra HarnessEvent into one or more SignalFlare HarnessEvents.\n *\n * Mastra sends full HarnessMessage objects on message_update/end, while SignalFlare\n * expects incremental deltas + separate thinking events. This function\n * bridges the gap.\n */\nfunction translateMastraEvent(\n mastraEvent: MastraHarnessEvent,\n prevMessages: Map<string, MastraHarnessMessage>\n): HarnessEvent[] {\n const out: HarnessEvent[] = [];\n\n if (\n mastraEvent.type === \"message_start\" ||\n mastraEvent.type === \"message_update\" ||\n mastraEvent.type === \"message_end\"\n ) {\n // TypeScript needs an explicit cast here because the catch-all arm in\n // MastraHarnessEvent doesn't carry `.message`. We've already narrowed via type.\n const msg = (\n mastraEvent as {\n type: \"message_start\" | \"message_update\" | \"message_end\";\n message: MastraHarnessMessage;\n }\n ).message;\n const prev = prevMessages.get(msg.id);\n\n if (mastraEvent.type === \"message_start\") {\n out.push({ type: \"message_start\", messageId: msg.id, role: msg.role });\n }\n\n // Extract text and thinking parts from content array\n const textParts = msg.content.filter(\n (p): p is { type: \"text\"; text: string } => p.type === \"text\"\n );\n const thinkingParts = msg.content.filter(\n (p): p is { type: \"thinking\"; thinking: string } => p.type === \"thinking\"\n );\n\n const fullText = textParts.map((p) => p.text).join(\"\");\n const prevText = prev\n ? prev.content\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\")\n : \"\";\n\n // Emit thinking blocks — each thinking part gets its own thinking_start/end\n // We compare against previous to only emit new/changed thinking blocks\n const prevThinking = prev\n ? prev.content.filter(\n (p): p is { type: \"thinking\"; thinking: string } =>\n p.type === \"thinking\"\n )\n : [];\n\n thinkingParts.forEach((part, i) => {\n const thinkingId = `${msg.id}-thinking-${i}`;\n const prevPart = prevThinking[i];\n if (!prevPart) {\n // New thinking block\n out.push({ type: \"thinking_start\", thinkingId, messageId: msg.id });\n if (part.thinking) {\n out.push({\n type: \"thinking_delta\",\n thinkingId,\n messageId: msg.id,\n delta: part.thinking,\n content: part.thinking,\n });\n }\n } else if (part.thinking !== prevPart.thinking) {\n // Updated thinking block — emit delta\n const delta = part.thinking.slice(prevPart.thinking.length);\n if (delta) {\n out.push({\n type: \"thinking_delta\",\n thinkingId,\n messageId: msg.id,\n delta,\n content: part.thinking,\n });\n }\n }\n });\n\n // Emit text delta if content changed\n if (fullText !== prevText && mastraEvent.type !== \"message_start\") {\n const delta = fullText.slice(prevText.length);\n out.push({\n type: \"message_update\",\n messageId: msg.id,\n delta,\n content: fullText,\n });\n }\n\n if (mastraEvent.type === \"message_end\") {\n // Finalize all thinking blocks\n thinkingParts.forEach((part, i) => {\n out.push({\n type: \"thinking_end\",\n thinkingId: `${msg.id}-thinking-${i}`,\n messageId: msg.id,\n content: part.thinking,\n });\n });\n out.push({ type: \"message_end\", messageId: msg.id, content: fullText });\n }\n\n prevMessages.set(msg.id, msg);\n return out;\n }\n\n // Pass through all other events as-is (they match SignalFlare's shape)\n return [mastraEvent as unknown as HarnessEvent];\n}\n\n/**\n * Wrap a Mastra `Harness` instance as a SignalFlare `HarnessAdapter`.\n *\n * Translates Mastra's event format (full `HarnessMessage` objects on\n * `message_update`) into SignalFlare's incremental event protocol, and extracts\n * `thinking` content parts into `thinking_start/delta/end` events so the\n * `AgentHarness` block can render them as collapsible reasoning blocks.\n */\nexport function fromMastraHarness(harness: {\n subscribe: (listener: (event: MastraHarnessEvent) => void) => () => void;\n sendMessage: (params: { content: string }) => void | Promise<void>;\n respondToToolApproval?: (params: {\n decision: \"approve\" | \"decline\";\n }) => void | Promise<void>;\n respondToQuestion?: (params: {\n questionId: string;\n answer: string;\n }) => void | Promise<void>;\n respondToPlanApproval?: (params: {\n planId: string;\n response: { action: \"approved\" | \"rejected\"; feedback?: string };\n }) => void | Promise<void>;\n abort?: () => void;\n steer?: (params: { content: string }) => void;\n selectMode?: (params: { modeId: string }) => void | Promise<void>;\n}): HarnessAdapter {\n return {\n subscribe(listener: (event: HarnessEvent) => void) {\n // Per-subscription message state for delta tracking\n const prevMessages = new Map<string, MastraHarnessMessage>();\n return harness.subscribe((mastraEvent) => {\n const translated = translateMastraEvent(mastraEvent, prevMessages);\n for (const ev of translated) listener(ev);\n });\n },\n sendMessage: harness.sendMessage.bind(harness),\n respondToToolApproval: harness.respondToToolApproval?.bind(harness),\n respondToQuestion: harness.respondToQuestion?.bind(harness),\n respondToPlanApproval: harness.respondToPlanApproval?.bind(harness),\n abort: harness.abort?.bind(harness),\n steer: harness.steer\n ? (params: { content: string }) => harness.steer!(params)\n : undefined,\n selectMode: harness.selectMode\n ? (params: { modeId: string }) => harness.selectMode!(params)\n : undefined,\n };\n}\n\n// ─── State Types ──────────────────────────────────────────────────────────────\n\n/** A single message in the conversation. */\nexport interface AgentMessage {\n id: string;\n role: \"user\" | \"assistant\" | \"system\";\n /** Accumulated text content. */\n content: string;\n /** Whether this message is currently streaming. */\n isStreaming: boolean;\n /** Tool calls attached to this message. */\n toolCallIds: string[];\n /** Subagent IDs spawned during this message. */\n subagentIds: string[];\n /** Thinking block IDs attached to this message (in order). */\n thinkingIds: string[];\n /** Whether this message has an active OM observation. */\n hasOMActivity: boolean;\n /** Whether this message has an approval request. */\n approvalMessageId?: string;\n /** Whether this message has a question. */\n questionId?: string;\n /** Whether this message has a plan approval. */\n planId?: string;\n}\n\n/** A model thinking/reasoning block attached to a message. */\nexport interface AgentThinking {\n id: string;\n /** Parent message ID. */\n messageId: string;\n /** Accumulated thinking text. */\n text: string;\n /** Whether this block is still streaming. */\n isStreaming: boolean;\n}\n\n/** Normalized tool call state. */\nexport interface AgentToolCall {\n id: string;\n toolName: string;\n /** Parent message ID (undefined if inside a subagent). */\n messageId?: string;\n /** Parent subagent ID (undefined if top-level). */\n subagentId?: string;\n state:\n | \"input-streaming\"\n | \"input-available\"\n | \"approval-requested\"\n | \"approval-responded\"\n | \"output-available\"\n | \"output-error\"\n | \"output-denied\";\n input?: unknown;\n inputBuffer?: string;\n output?: unknown;\n errorText?: string;\n summary?: string;\n durationMs?: number;\n approvalState?: \"awaiting\" | \"approved\" | \"declined\";\n /** Wall-clock ms when this tool call started. */\n startedAt?: number;\n /** Wall-clock ms when this tool call ended. */\n endedAt?: number;\n}\n\n/** Normalized subagent state. */\nexport interface AgentSubagent {\n id: string;\n agentType?: string;\n name?: string;\n modelId?: string;\n status: \"running\" | \"completed\" | \"error\";\n /** Accumulated text deltas. */\n content: string;\n /** Tool call IDs inside this subagent. */\n toolCallIds: string[];\n /** Parent message ID. */\n messageId?: string;\n durationMs?: number;\n error?: string;\n /** Wall-clock ms when this subagent started. */\n startedAt?: number;\n /** Wall-clock ms when this subagent ended. */\n endedAt?: number;\n}\n\n/** Observational memory activity item. */\nexport interface AgentOMActivity {\n id: string;\n type: \"observation\" | \"reflection\";\n status: \"streaming\" | \"completed\";\n text?: string;\n durationMs?: number;\n /** Which message this OM activity is attached to. */\n messageId?: string;\n}\n\n/** A pending question. */\nexport interface AgentQuestion {\n questionId: string;\n question: string;\n header?: string;\n options?: Array<{ label: string; description?: string }>;\n multiple?: boolean;\n allowCustom?: boolean;\n status: \"pending\" | \"answered\";\n answeredWith?: string;\n}\n\n/** A pending plan approval. */\nexport interface AgentPlanApproval {\n planId: string;\n title: string;\n description?: string;\n steps?: Array<{ id: string; label: string; description?: string }>;\n status: \"pending\" | \"approved\" | \"rejected\";\n}\n\n/** Task list state. */\nexport interface AgentTaskList {\n title?: string;\n tasks: Array<{\n id: string;\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\" | \"cancelled\";\n priority?: \"high\" | \"medium\" | \"low\";\n }>;\n}\n\n/** Usage/token stats. */\nexport interface AgentUsage {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n cost?: number;\n modelId?: string;\n}\n\n/** A notice/banner in the conversation. */\nexport interface AgentNotice {\n id: string;\n level: \"info\" | \"error\" | \"change\";\n message: string;\n /** Attach to a message ID for inline rendering, or undefined for standalone. */\n messageId?: string;\n}\n\n/** Full normalized harness UI state. */\nexport interface AgentHarnessState {\n /** Ordered list of message IDs. */\n messageIds: string[];\n /** Message map. */\n messages: Record<string, AgentMessage>;\n /** Tool call map. */\n toolCalls: Record<string, AgentToolCall>;\n /** Subagent map. */\n subagents: Record<string, AgentSubagent>;\n /** OM activity map. */\n omActivities: Record<string, AgentOMActivity>;\n /** Model thinking/reasoning blocks map. */\n thinkings: Record<string, AgentThinking>;\n /** Question map (by questionId). */\n questions: Record<string, AgentQuestion>;\n /** Plan approval map (by planId). */\n planApprovals: Record<string, AgentPlanApproval>;\n /** Notices/banners (inline in conversation). */\n notices: AgentNotice[];\n /** Current task list. */\n taskList: AgentTaskList | null;\n /** Token usage. */\n usage: AgentUsage | null;\n /** Whether the agent is currently running. */\n isRunning: boolean;\n /** Active mode. */\n modeId?: string;\n modeName?: string;\n /** Active model. */\n modelId?: string;\n modelName?: string;\n /** Active thread. */\n threadId?: string;\n /** Active pending tool approval (toolCallId). */\n pendingToolApprovalId?: string;\n /** Active pending question ID. */\n pendingQuestionId?: string;\n /** Active pending plan ID. */\n pendingPlanId?: string;\n /** Whether a workspace error is active. */\n workspaceError?: string;\n /**\n * Wall-clock ms when agent_start fired. Used by Commander timeline.\n * Resets on agent_start; cleared on RESET.\n */\n missionStartedAt?: number;\n /** Wall-clock ms when agent_end fired for the last run. */\n missionEndedAt?: number;\n /**\n * Ordered log of every event with its wall-clock timestamp.\n * Used by the Commander timeline to position blocks accurately.\n * Not rendered by AgentHarness — Commander reads it directly.\n */\n timeline: TimestampedHarnessEvent[];\n}\n\n/** A harness event stamped with the wall-clock time it was received. */\nexport interface TimestampedHarnessEvent {\n event: HarnessEvent;\n /** Date.now() at the moment the event was dispatched into the reducer. */\n timestamp: number;\n}\n\n// ─── Reducer ──────────────────────────────────────────────────────────────────\n\nconst initialState: AgentHarnessState = {\n messageIds: [],\n messages: {},\n toolCalls: {},\n subagents: {},\n omActivities: {},\n thinkings: {},\n questions: {},\n planApprovals: {},\n notices: [],\n taskList: null,\n usage: null,\n isRunning: false,\n timeline: [],\n};\n\n/**\n * Create an empty `AgentHarnessState` with optional partial overrides.\n *\n * Use this when operating in controlled mode — build or derive your own state\n * that conforms to `AgentHarnessState` and pass it directly to `<AgentHarness state={...} />`.\n *\n * @example\n * ```ts\n * const [state, setState] = useState(() => createAgentHarnessState());\n * ```\n */\nexport function createAgentHarnessState(\n partial?: Partial<AgentHarnessState>\n): AgentHarnessState {\n return { ...initialState, ...partial };\n}\n\nlet _noticeCounter = 0;\nfunction nextNoticeId() {\n return `notice-${++_noticeCounter}`;\n}\n\nfunction getErrorString(error: string | Error): string {\n return typeof error === \"string\" ? error : error.message;\n}\n\ntype AgentHarnessAction =\n | { type: \"EVENT\"; event: HarnessEvent; timestamp: number }\n | { type: \"RESET\" };\n\nfunction agentHarnessReducer(\n state: AgentHarnessState,\n action: AgentHarnessAction\n): AgentHarnessState {\n if (action.type === \"RESET\") return { ...initialState };\n\n const { event, timestamp } = action;\n\n // Append every event to the timeline log\n const timeline: TimestampedHarnessEvent[] = [\n ...state.timeline,\n { event, timestamp },\n ];\n\n switch (event.type) {\n // ── Agent lifecycle ─────────────────────────────────────────────────────\n case \"agent_start\":\n return {\n ...state,\n timeline,\n isRunning: true,\n missionStartedAt: state.missionStartedAt ?? timestamp,\n };\n\n case \"agent_end\":\n return {\n ...state,\n timeline,\n isRunning: false,\n missionEndedAt: timestamp,\n };\n\n // ── Message lifecycle ───────────────────────────────────────────────────\n case \"message_start\": {\n const msg: AgentMessage = {\n id: event.messageId,\n role: event.role,\n content: \"\",\n isStreaming: event.role === \"assistant\",\n toolCallIds: [],\n subagentIds: [],\n thinkingIds: [],\n hasOMActivity: false,\n };\n return {\n ...state,\n timeline,\n messageIds: [...state.messageIds, event.messageId],\n messages: { ...state.messages, [event.messageId]: msg },\n };\n }\n\n case \"message_update\": {\n const existing = state.messages[event.messageId];\n if (!existing) return { ...state, timeline };\n const newContent =\n event.content !== undefined\n ? event.content\n : existing.content + event.delta;\n return {\n ...state,\n timeline,\n messages: {\n ...state.messages,\n [event.messageId]: { ...existing, content: newContent },\n },\n };\n }\n\n case \"message_end\": {\n const existing = state.messages[event.messageId];\n if (!existing) return { ...state, timeline };\n return {\n ...state,\n timeline,\n messages: {\n ...state.messages,\n [event.messageId]: {\n ...existing,\n content: event.content,\n isStreaming: false,\n },\n },\n };\n }\n\n // ── Tool calls ──────────────────────────────────────────────────────────\n case \"tool_start\": {\n const toolCall: AgentToolCall = {\n id: event.toolCallId,\n toolName: event.toolName,\n messageId: event.messageId,\n subagentId: event.subagentId,\n state: \"input-streaming\",\n inputBuffer: \"\",\n startedAt: timestamp,\n };\n const updatedMessages = event.messageId\n ? {\n ...state.messages,\n [event.messageId]: {\n ...state.messages[event.messageId],\n toolCallIds: [\n ...(state.messages[event.messageId]?.toolCallIds ?? []),\n event.toolCallId,\n ],\n },\n }\n : state.messages;\n const updatedSubagents =\n event.subagentId && state.subagents[event.subagentId]\n ? {\n ...state.subagents,\n [event.subagentId]: {\n ...state.subagents[event.subagentId],\n toolCallIds: [\n ...state.subagents[event.subagentId].toolCallIds,\n event.toolCallId,\n ],\n },\n }\n : state.subagents;\n return {\n ...state,\n timeline,\n messages: updatedMessages,\n subagents: updatedSubagents,\n toolCalls: { ...state.toolCalls, [event.toolCallId]: toolCall },\n };\n }\n\n case \"tool_input_start\": {\n const tc = state.toolCalls[event.toolCallId];\n if (!tc) return { ...state, timeline };\n return {\n ...state,\n timeline,\n toolCalls: {\n ...state.toolCalls,\n [event.toolCallId]: {\n ...tc,\n state: \"input-streaming\",\n inputBuffer: \"\",\n },\n },\n };\n }\n\n case \"tool_input_delta\": {\n const tc = state.toolCalls[event.toolCallId];\n if (!tc) return { ...state, timeline };\n return {\n ...state,\n timeline,\n toolCalls: {\n ...state.toolCalls,\n [event.toolCallId]: {\n ...tc,\n inputBuffer: (tc.inputBuffer ?? \"\") + event.delta,\n },\n },\n };\n }\n\n case \"tool_input_end\": {\n const tc = state.toolCalls[event.toolCallId];\n if (!tc) return { ...state, timeline };\n return {\n ...state,\n timeline,\n toolCalls: {\n ...state.toolCalls,\n [event.toolCallId]: {\n ...tc,\n state: \"input-available\",\n input: event.input,\n inputBuffer: undefined,\n },\n },\n };\n }\n\n case \"tool_approval_required\": {\n const tc = state.toolCalls[event.toolCallId] ?? {\n id: event.toolCallId,\n toolName: event.toolName,\n messageId: event.messageId,\n state: \"approval-requested\" as const,\n toolCallIds: [],\n startedAt: timestamp,\n };\n return {\n ...state,\n timeline,\n pendingToolApprovalId: event.toolCallId,\n toolCalls: {\n ...state.toolCalls,\n [event.toolCallId]: {\n ...tc,\n state: \"approval-requested\",\n input: event.input ?? tc.input,\n approvalState: \"awaiting\",\n },\n },\n };\n }\n\n case \"tool_update\": {\n const tc = state.toolCalls[event.toolCallId];\n if (!tc) return { ...state, timeline };\n return {\n ...state,\n timeline,\n toolCalls: {\n ...state.toolCalls,\n [event.toolCallId]: { ...tc, summary: event.summary ?? tc.summary },\n },\n };\n }\n\n case \"tool_end\": {\n const tc = state.toolCalls[event.toolCallId];\n if (!tc) return { ...state, timeline };\n const pendingApprovalId =\n state.pendingToolApprovalId === event.toolCallId\n ? undefined\n : state.pendingToolApprovalId;\n return {\n ...state,\n timeline,\n pendingToolApprovalId: pendingApprovalId,\n toolCalls: {\n ...state.toolCalls,\n [event.toolCallId]: {\n ...tc,\n state: event.error ? \"output-error\" : \"output-available\",\n output: event.output,\n errorText: event.error,\n durationMs: event.durationMs,\n endedAt: timestamp,\n },\n },\n };\n }\n\n // ── Subagents ───────────────────────────────────────────────────────────\n case \"subagent_start\": {\n const subagent: AgentSubagent = {\n id: event.subagentId,\n agentType: event.agentType,\n name: event.name,\n modelId: event.modelId,\n status: \"running\",\n content: \"\",\n toolCallIds: [],\n messageId: event.parentMessageId,\n startedAt: timestamp,\n };\n const updatedMessages = event.parentMessageId\n ? {\n ...state.messages,\n [event.parentMessageId]: {\n ...state.messages[event.parentMessageId],\n subagentIds: [\n ...(state.messages[event.parentMessageId]?.subagentIds ?? []),\n event.subagentId,\n ],\n },\n }\n : state.messages;\n return {\n ...state,\n timeline,\n messages: updatedMessages,\n subagents: { ...state.subagents, [event.subagentId]: subagent },\n };\n }\n\n case \"subagent_text_delta\": {\n const sa = state.subagents[event.subagentId];\n if (!sa) return { ...state, timeline };\n return {\n ...state,\n timeline,\n subagents: {\n ...state.subagents,\n [event.subagentId]: { ...sa, content: sa.content + event.delta },\n },\n };\n }\n\n case \"subagent_tool_start\": {\n const tc: AgentToolCall = {\n id: event.toolCallId,\n toolName: event.toolName,\n subagentId: event.subagentId,\n state: \"input-streaming\",\n inputBuffer: \"\",\n startedAt: timestamp,\n };\n const sa = state.subagents[event.subagentId];\n const updatedSubagents = sa\n ? {\n ...state.subagents,\n [event.subagentId]: {\n ...sa,\n toolCallIds: [...sa.toolCallIds, event.toolCallId],\n },\n }\n : state.subagents;\n return {\n ...state,\n timeline,\n subagents: updatedSubagents,\n toolCalls: { ...state.toolCalls, [event.toolCallId]: tc },\n };\n }\n\n case \"subagent_tool_end\": {\n const tc = state.toolCalls[event.toolCallId];\n if (!tc) return { ...state, timeline };\n return {\n ...state,\n timeline,\n toolCalls: {\n ...state.toolCalls,\n [event.toolCallId]: {\n ...tc,\n state: event.error ? \"output-error\" : \"output-available\",\n output: event.output,\n errorText: event.error,\n durationMs: event.durationMs,\n endedAt: timestamp,\n },\n },\n };\n }\n\n case \"subagent_end\": {\n const sa = state.subagents[event.subagentId];\n if (!sa) return { ...state, timeline };\n return {\n ...state,\n timeline,\n subagents: {\n ...state.subagents,\n [event.subagentId]: {\n ...sa,\n status: event.error ? \"error\" : \"completed\",\n error: event.error,\n durationMs: event.durationMs,\n endedAt: timestamp,\n },\n },\n };\n }\n\n case \"subagent_model_changed\": {\n if (event.subagentId) {\n const sa = state.subagents[event.subagentId];\n if (!sa) return { ...state, timeline };\n return {\n ...state,\n timeline,\n subagents: {\n ...state.subagents,\n [event.subagentId]: { ...sa, modelId: event.modelId },\n },\n };\n }\n return { ...state, timeline };\n }\n\n // ── Observational Memory ────────────────────────────────────────────────\n case \"om_observation_start\": {\n const id = event.observationId ?? `om-obs-${Date.now()}`;\n const activity: AgentOMActivity = {\n id,\n type: \"observation\",\n status: \"streaming\",\n messageId: state.messageIds[state.messageIds.length - 1],\n };\n return {\n ...state,\n timeline,\n omActivities: { ...state.omActivities, [id]: activity },\n };\n }\n\n case \"om_observation_end\": {\n const id =\n event.observationId ??\n Object.keys(state.omActivities).find(\n (k) =>\n state.omActivities[k].type === \"observation\" &&\n state.omActivities[k].status === \"streaming\"\n );\n if (!id) return { ...state, timeline };\n return {\n ...state,\n timeline,\n omActivities: {\n ...state.omActivities,\n [id]: {\n ...state.omActivities[id],\n status: \"completed\",\n text: event.text,\n durationMs: event.durationMs,\n },\n },\n };\n }\n\n case \"om_reflection_start\": {\n const id = `om-ref-${Date.now()}`;\n const activity: AgentOMActivity = {\n id,\n type: \"reflection\",\n status: \"streaming\",\n messageId: state.messageIds[state.messageIds.length - 1],\n };\n return {\n ...state,\n timeline,\n omActivities: { ...state.omActivities, [id]: activity },\n };\n }\n\n case \"om_reflection_end\": {\n const id = Object.keys(state.omActivities).find(\n (k) =>\n state.omActivities[k].type === \"reflection\" &&\n state.omActivities[k].status === \"streaming\"\n );\n if (!id) return { ...state, timeline };\n return {\n ...state,\n timeline,\n omActivities: {\n ...state.omActivities,\n [id]: {\n ...state.omActivities[id],\n status: \"completed\",\n text: event.text,\n durationMs: event.durationMs,\n },\n },\n };\n }\n\n // ── Thinking / Reasoning ────────────────────────────────────────────────\n case \"thinking_start\": {\n const thinking: AgentThinking = {\n id: event.thinkingId,\n messageId: event.messageId,\n text: \"\",\n isStreaming: true,\n };\n const existingMsg = state.messages[event.messageId];\n return {\n ...state,\n timeline,\n thinkings: { ...state.thinkings, [event.thinkingId]: thinking },\n messages: existingMsg\n ? {\n ...state.messages,\n [event.messageId]: {\n ...existingMsg,\n thinkingIds: [...existingMsg.thinkingIds, event.thinkingId],\n },\n }\n : state.messages,\n };\n }\n\n case \"thinking_delta\": {\n const existing = state.thinkings[event.thinkingId];\n if (!existing) return { ...state, timeline };\n const newText =\n event.content !== undefined\n ? event.content\n : existing.text + event.delta;\n return {\n ...state,\n timeline,\n thinkings: {\n ...state.thinkings,\n [event.thinkingId]: { ...existing, text: newText },\n },\n };\n }\n\n case \"thinking_end\": {\n const existing = state.thinkings[event.thinkingId];\n if (!existing) return { ...state, timeline };\n return {\n ...state,\n timeline,\n thinkings: {\n ...state.thinkings,\n [event.thinkingId]: {\n ...existing,\n text: event.content,\n isStreaming: false,\n },\n },\n };\n }\n\n // ── Questions + Plans ───────────────────────────────────────────────────\n case \"ask_question\": {\n const q: AgentQuestion = {\n questionId: event.questionId,\n question: event.question,\n header: event.header,\n options: event.options,\n multiple: event.multiple,\n allowCustom: event.allowCustom,\n status: \"pending\",\n };\n // Associate the question with the last message so it renders on the right message\n const lastMsgId = state.messageIds[state.messageIds.length - 1];\n const updatedMessages = lastMsgId\n ? {\n ...state.messages,\n [lastMsgId]: {\n ...state.messages[lastMsgId],\n questionId: event.questionId,\n },\n }\n : state.messages;\n return {\n ...state,\n timeline,\n pendingQuestionId: event.questionId,\n questions: { ...state.questions, [event.questionId]: q },\n messages: updatedMessages,\n };\n }\n\n case \"question_answered\": {\n const q = state.questions[event.questionId];\n if (!q) return { ...state, timeline };\n return {\n ...state,\n timeline,\n pendingQuestionId:\n state.pendingQuestionId === event.questionId\n ? undefined\n : state.pendingQuestionId,\n questions: {\n ...state.questions,\n [event.questionId]: {\n ...q,\n status: \"answered\",\n answeredWith: event.answer,\n },\n },\n };\n }\n\n case \"plan_approval_required\": {\n const p: AgentPlanApproval = {\n planId: event.planId,\n title: event.title,\n description: event.description,\n steps: event.steps,\n status: \"pending\",\n };\n // Associate the plan with the last message so it renders on the right message\n const lastMsgId = state.messageIds[state.messageIds.length - 1];\n const updatedMessages = lastMsgId\n ? {\n ...state.messages,\n [lastMsgId]: { ...state.messages[lastMsgId], planId: event.planId },\n }\n : state.messages;\n return {\n ...state,\n timeline,\n pendingPlanId: event.planId,\n planApprovals: { ...state.planApprovals, [event.planId]: p },\n messages: updatedMessages,\n };\n }\n\n case \"plan_approved\": {\n const p = state.planApprovals[event.planId];\n if (!p) return { ...state, timeline };\n return {\n ...state,\n timeline,\n pendingPlanId:\n state.pendingPlanId === event.planId\n ? undefined\n : state.pendingPlanId,\n planApprovals: {\n ...state.planApprovals,\n [event.planId]: { ...p, status: \"approved\" },\n },\n };\n }\n\n // ── Tasks ───────────────────────────────────────────────────────────────\n case \"task_updated\":\n return {\n ...state,\n timeline,\n taskList: { tasks: event.tasks, title: event.title },\n };\n\n // ── Usage ───────────────────────────────────────────────────────────────\n case \"usage_update\":\n return {\n ...state,\n timeline,\n usage: {\n inputTokens: event.inputTokens,\n outputTokens: event.outputTokens,\n totalTokens: event.totalTokens,\n cost: event.cost,\n modelId: event.modelId,\n },\n };\n\n // ── Notices ─────────────────────────────────────────────────────────────\n case \"error\": {\n const notice: AgentNotice = {\n id: nextNoticeId(),\n level: \"error\",\n message: getErrorString(event.error),\n messageId: event.messageId,\n };\n return { ...state, timeline, notices: [...state.notices, notice] };\n }\n\n case \"info\": {\n const notice: AgentNotice = {\n id: nextNoticeId(),\n level: \"info\",\n message: event.message,\n };\n return { ...state, timeline, notices: [...state.notices, notice] };\n }\n\n case \"follow_up_queued\": {\n const notice: AgentNotice = {\n id: nextNoticeId(),\n level: \"info\",\n message: `Follow-up queued: ${event.content}`,\n };\n return { ...state, timeline, notices: [...state.notices, notice] };\n }\n\n case \"workspace_error\":\n return {\n ...state,\n timeline,\n workspaceError: getErrorString(event.error),\n };\n\n case \"workspace_ready\":\n return { ...state, timeline, workspaceError: undefined };\n\n case \"workspace_status_changed\": {\n const notice: AgentNotice = {\n id: nextNoticeId(),\n level: \"info\",\n message: `Workspace: ${event.status}`,\n };\n return { ...state, timeline, notices: [...state.notices, notice] };\n }\n\n case \"mode_changed\":\n return {\n ...state,\n timeline,\n modeId: event.modeId,\n modeName: event.modeName,\n };\n\n case \"model_changed\":\n return {\n ...state,\n timeline,\n modelId: event.modelId,\n modelName: event.modelName,\n };\n\n case \"thread_changed\":\n return { ...initialState, threadId: event.threadId, timeline };\n\n case \"thread_created\":\n case \"thread_deleted\":\n case \"state_changed\":\n case \"om_status\":\n return { ...state, timeline };\n\n default:\n return { ...state, timeline };\n }\n}\n\n// ─── Hook ─────────────────────────────────────────────────────────────────────\n\nexport interface UseAgentHarnessOptions {\n /** The harness adapter to subscribe to. Pass `null` to skip subscription. */\n adapter: HarnessAdapter | null;\n}\n\nexport interface UseAgentHarnessReturn {\n /** Full normalized harness UI state. */\n state: AgentHarnessState;\n /** Send a user message. */\n sendMessage: (params: {\n content: string;\n files?: Array<{ url: string; mediaType: string; filename: string }>;\n }) => Promise<void>;\n /** Respond to a pending tool approval. */\n respondToToolApproval: (decision: \"approve\" | \"decline\") => Promise<void>;\n /** Respond to a pending question. */\n respondToQuestion: (questionId: string, answer: string) => Promise<void>;\n /** Respond to a pending plan approval. */\n respondToPlanApproval: (\n planId: string,\n response: { action: \"approved\" | \"rejected\"; feedback?: string }\n ) => Promise<void>;\n /** Abort any in-progress generation. */\n abort: () => void;\n /** Steer the agent mid-stream. */\n steer: (content: string) => void;\n /** Select a mode. */\n selectMode: (modeId: string) => Promise<void>;\n /** Reset the state (e.g. after a thread switch). */\n reset: () => void;\n}\n\n/**\n * `useAgentHarness` — headless state hook for the AgentHarness UI.\n *\n * Subscribes to a `HarnessAdapter` and reduces all events into a single\n * normalized `AgentHarnessState` object that the `AgentHarness` block\n * (or any custom UI) can render from.\n *\n * @example\n * ```tsx\n * const adapter = fromMastraHarness(harness);\n * const { state, sendMessage, abort } = useAgentHarness({ adapter });\n * ```\n */\nexport function useAgentHarness({\n adapter,\n}: UseAgentHarnessOptions): UseAgentHarnessReturn {\n const [state, dispatch] = useReducer(agentHarnessReducer, initialState);\n\n // Keep a stable ref to the adapter so callbacks below don't stale-close\n const adapterRef = useRef<HarnessAdapter | null>(adapter);\n adapterRef.current = adapter;\n\n // Subscribe to harness events — stamp each with Date.now() for timeline\n useEffect(() => {\n if (!adapter) return;\n const unsubscribe = adapter.subscribe((event) => {\n dispatch({ type: \"EVENT\", event, timestamp: Date.now() });\n });\n return unsubscribe;\n }, [adapter]);\n\n const sendMessage = useCallback(\n async (params: {\n content: string;\n files?: Array<{ url: string; mediaType: string; filename: string }>;\n }) => {\n await adapterRef.current?.sendMessage(params);\n },\n []\n );\n\n const respondToToolApproval = useCallback(\n async (decision: \"approve\" | \"decline\") => {\n await adapterRef.current?.respondToToolApproval?.({ decision });\n },\n []\n );\n\n const respondToQuestion = useCallback(\n async (questionId: string, answer: string) => {\n await adapterRef.current?.respondToQuestion?.({ questionId, answer });\n },\n []\n );\n\n const respondToPlanApproval = useCallback(\n async (\n planId: string,\n response: { action: \"approved\" | \"rejected\"; feedback?: string }\n ) => {\n await adapterRef.current?.respondToPlanApproval?.({ planId, response });\n },\n []\n );\n\n const abort = useCallback(() => {\n adapterRef.current?.abort?.();\n }, []);\n\n const steer = useCallback((content: string) => {\n adapterRef.current?.steer?.({ content });\n }, []);\n\n const selectMode = useCallback(async (modeId: string) => {\n await adapterRef.current?.selectMode?.({ modeId });\n }, []);\n\n const reset = useCallback(() => {\n dispatch({ type: \"RESET\" });\n }, []);\n\n return {\n state,\n sendMessage,\n respondToToolApproval,\n respondToQuestion,\n respondToPlanApproval,\n abort,\n steer,\n selectMode,\n reset,\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"use-agent-harness-Dl8w6X5O.js","names":[],"sources":["../src/components/use-agent-harness/use-agent-harness.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useReducer, useRef } from \"react\";\n\n// ─── Variants (required by SignalFlare conventions) ───────────────────────────────────\n\nexport const SF_USE_AGENT_HARNESS_VARIANTS = {} as const;\nexport const SF_USE_AGENT_HARNESS_DEFAULT_VARIANTS = {} as const;\n\n// ─── Harness Event Types ──────────────────────────────────────────────────────\n\n/** All event types emitted by a Mastra Harness instance. */\nexport type HarnessEventType =\n | \"mode_changed\"\n | \"model_changed\"\n | \"thread_changed\"\n | \"thread_created\"\n | \"thread_deleted\"\n | \"state_changed\"\n | \"agent_start\"\n | \"agent_end\"\n | \"message_start\"\n | \"message_update\"\n | \"message_end\"\n | \"tool_start\"\n | \"tool_approval_required\"\n | \"tool_update\"\n | \"tool_end\"\n | \"tool_input_start\"\n | \"tool_input_delta\"\n | \"tool_input_end\"\n | \"usage_update\"\n | \"error\"\n | \"info\"\n | \"follow_up_queued\"\n | \"workspace_status_changed\"\n | \"workspace_ready\"\n | \"workspace_error\"\n | \"om_status\"\n | \"om_observation_start\"\n | \"om_observation_end\"\n | \"om_reflection_start\"\n | \"om_reflection_end\"\n | \"ask_question\"\n | \"question_answered\"\n | \"plan_approval_required\"\n | \"plan_approved\"\n | \"subagent_start\"\n | \"subagent_text_delta\"\n | \"subagent_tool_start\"\n | \"subagent_tool_end\"\n | \"subagent_end\"\n | \"subagent_model_changed\"\n | \"task_updated\"\n | \"thinking_start\"\n | \"thinking_delta\"\n | \"thinking_end\";\n\n/** Base shape of all harness events. */\nexport interface HarnessEventBase {\n type: HarnessEventType;\n}\n\nexport interface HarnessModeChangedEvent extends HarnessEventBase {\n type: \"mode_changed\";\n modeId: string;\n modeName: string;\n}\n\nexport interface HarnessModelChangedEvent extends HarnessEventBase {\n type: \"model_changed\";\n modelId: string;\n modelName?: string;\n}\n\nexport interface HarnessThreadChangedEvent extends HarnessEventBase {\n type: \"thread_changed\";\n threadId: string;\n}\n\nexport interface HarnessThreadCreatedEvent extends HarnessEventBase {\n type: \"thread_created\";\n threadId: string;\n}\n\nexport interface HarnessThreadDeletedEvent extends HarnessEventBase {\n type: \"thread_deleted\";\n threadId: string;\n}\n\nexport interface HarnessStateChangedEvent extends HarnessEventBase {\n type: \"state_changed\";\n state: Record<string, unknown>;\n changedKeys: string[];\n}\n\nexport interface HarnessAgentStartEvent extends HarnessEventBase {\n type: \"agent_start\";\n}\n\nexport interface HarnessAgentEndEvent extends HarnessEventBase {\n type: \"agent_end\";\n}\n\nexport interface HarnessMessageStartEvent extends HarnessEventBase {\n type: \"message_start\";\n messageId: string;\n role: \"assistant\" | \"user\" | \"system\";\n}\n\nexport interface HarnessMessageUpdateEvent extends HarnessEventBase {\n type: \"message_update\";\n messageId: string;\n delta: string;\n content?: string;\n}\n\nexport interface HarnessMessageEndEvent extends HarnessEventBase {\n type: \"message_end\";\n messageId: string;\n content: string;\n}\n\nexport interface HarnessToolStartEvent extends HarnessEventBase {\n type: \"tool_start\";\n toolCallId: string;\n toolName: string;\n messageId?: string;\n subagentId?: string;\n}\n\nexport interface HarnessToolApprovalRequiredEvent extends HarnessEventBase {\n type: \"tool_approval_required\";\n toolCallId: string;\n toolName: string;\n input?: unknown;\n messageId?: string;\n}\n\nexport interface HarnessToolUpdateEvent extends HarnessEventBase {\n type: \"tool_update\";\n toolCallId: string;\n summary?: string;\n progress?: number;\n}\n\nexport interface HarnessToolEndEvent extends HarnessEventBase {\n type: \"tool_end\";\n toolCallId: string;\n output?: unknown;\n error?: string;\n durationMs?: number;\n}\n\nexport interface HarnessToolInputStartEvent extends HarnessEventBase {\n type: \"tool_input_start\";\n toolCallId: string;\n}\n\nexport interface HarnessToolInputDeltaEvent extends HarnessEventBase {\n type: \"tool_input_delta\";\n toolCallId: string;\n delta: string;\n}\n\nexport interface HarnessToolInputEndEvent extends HarnessEventBase {\n type: \"tool_input_end\";\n toolCallId: string;\n input: unknown;\n}\n\nexport interface HarnessUsageUpdateEvent extends HarnessEventBase {\n type: \"usage_update\";\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n cost?: number;\n modelId?: string;\n}\n\nexport interface HarnessErrorEvent extends HarnessEventBase {\n type: \"error\";\n error: string | Error;\n messageId?: string;\n}\n\nexport interface HarnessInfoEvent extends HarnessEventBase {\n type: \"info\";\n message: string;\n}\n\nexport interface HarnessFollowUpQueuedEvent extends HarnessEventBase {\n type: \"follow_up_queued\";\n content: string;\n}\n\nexport interface HarnessWorkspaceStatusChangedEvent extends HarnessEventBase {\n type: \"workspace_status_changed\";\n status: string;\n}\n\nexport interface HarnessWorkspaceReadyEvent extends HarnessEventBase {\n type: \"workspace_ready\";\n}\n\nexport interface HarnessWorkspaceErrorEvent extends HarnessEventBase {\n type: \"workspace_error\";\n error: string | Error;\n}\n\nexport interface HarnessOMStatusEvent extends HarnessEventBase {\n type: \"om_status\";\n generationCount?: number;\n observationTokenCount?: number;\n activeObservations?: number;\n}\n\nexport interface HarnessOMObservationStartEvent extends HarnessEventBase {\n type: \"om_observation_start\";\n observationId?: string;\n}\n\nexport interface HarnessOMObservationEndEvent extends HarnessEventBase {\n type: \"om_observation_end\";\n observationId?: string;\n text?: string;\n durationMs?: number;\n}\n\nexport interface HarnessOMReflectionStartEvent extends HarnessEventBase {\n type: \"om_reflection_start\";\n}\n\nexport interface HarnessOMReflectionEndEvent extends HarnessEventBase {\n type: \"om_reflection_end\";\n text?: string;\n durationMs?: number;\n}\n\nexport interface HarnessAskQuestionEvent extends HarnessEventBase {\n type: \"ask_question\";\n questionId: string;\n question: string;\n header?: string;\n options?: Array<{ label: string; description?: string }>;\n multiple?: boolean;\n allowCustom?: boolean;\n}\n\nexport interface HarnessQuestionAnsweredEvent extends HarnessEventBase {\n type: \"question_answered\";\n questionId: string;\n answer: string;\n}\n\nexport interface HarnessPlanApprovalRequiredEvent extends HarnessEventBase {\n type: \"plan_approval_required\";\n planId: string;\n title: string;\n description?: string;\n steps?: Array<{ id: string; label: string; description?: string }>;\n}\n\nexport interface HarnessPlanApprovedEvent extends HarnessEventBase {\n type: \"plan_approved\";\n planId: string;\n}\n\nexport interface HarnessSubagentStartEvent extends HarnessEventBase {\n type: \"subagent_start\";\n subagentId: string;\n agentType?: string;\n name?: string;\n modelId?: string;\n parentMessageId?: string;\n}\n\nexport interface HarnessSubagentTextDeltaEvent extends HarnessEventBase {\n type: \"subagent_text_delta\";\n subagentId: string;\n delta: string;\n}\n\nexport interface HarnessSubagentToolStartEvent extends HarnessEventBase {\n type: \"subagent_tool_start\";\n subagentId: string;\n toolCallId: string;\n toolName: string;\n}\n\nexport interface HarnessSubagentToolEndEvent extends HarnessEventBase {\n type: \"subagent_tool_end\";\n subagentId: string;\n toolCallId: string;\n output?: unknown;\n error?: string;\n durationMs?: number;\n}\n\nexport interface HarnessSubagentEndEvent extends HarnessEventBase {\n type: \"subagent_end\";\n subagentId: string;\n error?: string;\n durationMs?: number;\n}\n\nexport interface HarnessSubagentModelChangedEvent extends HarnessEventBase {\n type: \"subagent_model_changed\";\n subagentId?: string;\n modelId: string;\n agentType?: string;\n}\n\nexport interface HarnessTaskUpdatedEvent extends HarnessEventBase {\n type: \"task_updated\";\n tasks: Array<{\n id: string;\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\" | \"cancelled\";\n priority?: \"high\" | \"medium\" | \"low\";\n }>;\n title?: string;\n}\n\n/** Emitted when the model begins a thinking/reasoning block. */\nexport interface HarnessThinkingStartEvent extends HarnessEventBase {\n type: \"thinking_start\";\n thinkingId: string;\n messageId: string;\n}\n\n/** Emitted for each incremental chunk of thinking text. */\nexport interface HarnessThinkingDeltaEvent extends HarnessEventBase {\n type: \"thinking_delta\";\n thinkingId: string;\n messageId: string;\n /** Incremental text to append. */\n delta: string;\n /** Full text so far (if available). */\n content?: string;\n}\n\n/** Emitted when a thinking block is complete. */\nexport interface HarnessThinkingEndEvent extends HarnessEventBase {\n type: \"thinking_end\";\n thinkingId: string;\n messageId: string;\n /** Final accumulated thinking text. */\n content: string;\n}\n\n/** Union of all typed harness events. */\nexport type HarnessEvent =\n | HarnessModeChangedEvent\n | HarnessModelChangedEvent\n | HarnessThreadChangedEvent\n | HarnessThreadCreatedEvent\n | HarnessThreadDeletedEvent\n | HarnessStateChangedEvent\n | HarnessAgentStartEvent\n | HarnessAgentEndEvent\n | HarnessMessageStartEvent\n | HarnessMessageUpdateEvent\n | HarnessMessageEndEvent\n | HarnessToolStartEvent\n | HarnessToolApprovalRequiredEvent\n | HarnessToolUpdateEvent\n | HarnessToolEndEvent\n | HarnessToolInputStartEvent\n | HarnessToolInputDeltaEvent\n | HarnessToolInputEndEvent\n | HarnessUsageUpdateEvent\n | HarnessErrorEvent\n | HarnessInfoEvent\n | HarnessFollowUpQueuedEvent\n | HarnessWorkspaceStatusChangedEvent\n | HarnessWorkspaceReadyEvent\n | HarnessWorkspaceErrorEvent\n | HarnessOMStatusEvent\n | HarnessOMObservationStartEvent\n | HarnessOMObservationEndEvent\n | HarnessOMReflectionStartEvent\n | HarnessOMReflectionEndEvent\n | HarnessAskQuestionEvent\n | HarnessQuestionAnsweredEvent\n | HarnessPlanApprovalRequiredEvent\n | HarnessPlanApprovedEvent\n | HarnessSubagentStartEvent\n | HarnessSubagentTextDeltaEvent\n | HarnessSubagentToolStartEvent\n | HarnessSubagentToolEndEvent\n | HarnessSubagentEndEvent\n | HarnessSubagentModelChangedEvent\n | HarnessTaskUpdatedEvent\n | HarnessThinkingStartEvent\n | HarnessThinkingDeltaEvent\n | HarnessThinkingEndEvent;\n\n// ─── Adapter Interface ────────────────────────────────────────────────────────\n\n/**\n * Minimal adapter interface for driving the AgentHarness UI.\n * Implement this to connect any event source — Mastra Harness, mock, replay, etc.\n */\nexport interface HarnessAdapter {\n /** Register an event listener. Returns an unsubscribe function. */\n subscribe: (listener: (event: HarnessEvent) => void) => () => void;\n /** Send a user message. */\n sendMessage: (params: {\n content: string;\n files?: Array<{ url: string; mediaType: string; filename: string }>;\n }) => void | Promise<void>;\n /** Respond to a pending tool approval. */\n respondToToolApproval?: (params: {\n decision: \"approve\" | \"decline\";\n }) => void | Promise<void>;\n /** Respond to a pending question. */\n respondToQuestion?: (params: {\n questionId: string;\n answer: string;\n }) => void | Promise<void>;\n /** Respond to a pending plan approval. */\n respondToPlanApproval?: (params: {\n planId: string;\n response: { action: \"approved\" | \"rejected\"; feedback?: string };\n }) => void | Promise<void>;\n /** Abort any in-progress generation. */\n abort?: () => void;\n /** Steer the agent mid-stream. */\n steer?: (params: { content: string }) => void;\n /** Select a mode. */\n selectMode?: (params: { modeId: string }) => void | Promise<void>;\n}\n\n/**\n * Create a HarnessAdapter from a real Mastra Harness instance.\n * The Mastra harness type is not imported to avoid a hard dependency.\n */\n// ─── Mastra → SignalFlare event translation ───────────────────────────────────────────\n\n/** Mastra's HarnessMessage content part (subset we care about). */\ntype MastraContentPart =\n | { type: \"text\"; text: string }\n | { type: \"thinking\"; thinking: string }\n | { type: \"tool_call\"; id: string; name: string; args: unknown }\n | { type: string; [key: string]: unknown };\n\n/** Mastra's HarnessMessage shape (from @mastra/core). */\ninterface MastraHarnessMessage {\n id: string;\n role: \"user\" | \"assistant\" | \"system\";\n content: MastraContentPart[];\n createdAt: Date;\n stopReason?: \"complete\" | \"tool_use\" | \"aborted\" | \"error\";\n}\n\n/** Mastra's raw HarnessEvent union (only the fields we translate). */\ntype MastraHarnessEvent =\n | { type: \"message_start\"; message: MastraHarnessMessage }\n | { type: \"message_update\"; message: MastraHarnessMessage }\n | { type: \"message_end\"; message: MastraHarnessMessage }\n | { type: string; [key: string]: unknown };\n\n/**\n * Translate a Mastra HarnessEvent into one or more SignalFlare HarnessEvents.\n *\n * Mastra sends full HarnessMessage objects on message_update/end, while SignalFlare\n * expects incremental deltas + separate thinking events. This function\n * bridges the gap.\n */\nfunction translateMastraEvent(\n mastraEvent: MastraHarnessEvent,\n prevMessages: Map<string, MastraHarnessMessage>\n): HarnessEvent[] {\n const out: HarnessEvent[] = [];\n\n if (\n mastraEvent.type === \"message_start\" ||\n mastraEvent.type === \"message_update\" ||\n mastraEvent.type === \"message_end\"\n ) {\n // TypeScript needs an explicit cast here because the catch-all arm in\n // MastraHarnessEvent doesn't carry `.message`. We've already narrowed via type.\n const msg = (\n mastraEvent as {\n type: \"message_start\" | \"message_update\" | \"message_end\";\n message: MastraHarnessMessage;\n }\n ).message;\n const prev = prevMessages.get(msg.id);\n\n if (mastraEvent.type === \"message_start\") {\n out.push({ type: \"message_start\", messageId: msg.id, role: msg.role });\n }\n\n // Extract text and thinking parts from content array\n const textParts = msg.content.filter(\n (p): p is { type: \"text\"; text: string } => p.type === \"text\"\n );\n const thinkingParts = msg.content.filter(\n (p): p is { type: \"thinking\"; thinking: string } => p.type === \"thinking\"\n );\n\n const fullText = textParts.map((p) => p.text).join(\"\");\n const prevText = prev\n ? prev.content\n .filter((p): p is { type: \"text\"; text: string } => p.type === \"text\")\n .map((p) => p.text)\n .join(\"\")\n : \"\";\n\n // Emit thinking blocks — each thinking part gets its own thinking_start/end\n // We compare against previous to only emit new/changed thinking blocks\n const prevThinking = prev\n ? prev.content.filter(\n (p): p is { type: \"thinking\"; thinking: string } =>\n p.type === \"thinking\"\n )\n : [];\n\n thinkingParts.forEach((part, i) => {\n const thinkingId = `${msg.id}-thinking-${i}`;\n const prevPart = prevThinking[i];\n if (!prevPart) {\n // New thinking block\n out.push({ type: \"thinking_start\", thinkingId, messageId: msg.id });\n if (part.thinking) {\n out.push({\n type: \"thinking_delta\",\n thinkingId,\n messageId: msg.id,\n delta: part.thinking,\n content: part.thinking,\n });\n }\n } else if (part.thinking !== prevPart.thinking) {\n // Updated thinking block — emit delta\n const delta = part.thinking.slice(prevPart.thinking.length);\n if (delta) {\n out.push({\n type: \"thinking_delta\",\n thinkingId,\n messageId: msg.id,\n delta,\n content: part.thinking,\n });\n }\n }\n });\n\n // Emit text delta if content changed\n if (fullText !== prevText && mastraEvent.type !== \"message_start\") {\n const delta = fullText.slice(prevText.length);\n out.push({\n type: \"message_update\",\n messageId: msg.id,\n delta,\n content: fullText,\n });\n }\n\n if (mastraEvent.type === \"message_end\") {\n // Finalize all thinking blocks\n thinkingParts.forEach((part, i) => {\n out.push({\n type: \"thinking_end\",\n thinkingId: `${msg.id}-thinking-${i}`,\n messageId: msg.id,\n content: part.thinking,\n });\n });\n out.push({ type: \"message_end\", messageId: msg.id, content: fullText });\n }\n\n prevMessages.set(msg.id, msg);\n return out;\n }\n\n // Pass through all other events as-is (they match SignalFlare's shape)\n return [mastraEvent as unknown as HarnessEvent];\n}\n\n/**\n * Wrap a Mastra `Harness` instance as a SignalFlare `HarnessAdapter`.\n *\n * Translates Mastra's event format (full `HarnessMessage` objects on\n * `message_update`) into SignalFlare's incremental event protocol, and extracts\n * `thinking` content parts into `thinking_start/delta/end` events so the\n * `AgentHarness` block can render them as collapsible reasoning blocks.\n */\nexport function fromMastraHarness(harness: {\n subscribe: (listener: (event: MastraHarnessEvent) => void) => () => void;\n sendMessage: (params: { content: string }) => void | Promise<void>;\n respondToToolApproval?: (params: {\n decision: \"approve\" | \"decline\";\n }) => void | Promise<void>;\n respondToQuestion?: (params: {\n questionId: string;\n answer: string;\n }) => void | Promise<void>;\n respondToPlanApproval?: (params: {\n planId: string;\n response: { action: \"approved\" | \"rejected\"; feedback?: string };\n }) => void | Promise<void>;\n abort?: () => void;\n steer?: (params: { content: string }) => void;\n selectMode?: (params: { modeId: string }) => void | Promise<void>;\n}): HarnessAdapter {\n return {\n subscribe(listener: (event: HarnessEvent) => void) {\n // Per-subscription message state for delta tracking\n const prevMessages = new Map<string, MastraHarnessMessage>();\n return harness.subscribe((mastraEvent) => {\n const translated = translateMastraEvent(mastraEvent, prevMessages);\n for (const ev of translated) listener(ev);\n });\n },\n sendMessage: harness.sendMessage.bind(harness),\n respondToToolApproval: harness.respondToToolApproval?.bind(harness),\n respondToQuestion: harness.respondToQuestion?.bind(harness),\n respondToPlanApproval: harness.respondToPlanApproval?.bind(harness),\n abort: harness.abort?.bind(harness),\n steer: harness.steer\n ? (params: { content: string }) => harness.steer!(params)\n : undefined,\n selectMode: harness.selectMode\n ? (params: { modeId: string }) => harness.selectMode!(params)\n : undefined,\n };\n}\n\n// ─── State Types ──────────────────────────────────────────────────────────────\n\n/** A single message in the conversation. */\nexport interface AgentMessage {\n id: string;\n role: \"user\" | \"assistant\" | \"system\";\n /** Accumulated text content. */\n content: string;\n /** Whether this message is currently streaming. */\n isStreaming: boolean;\n /** Tool calls attached to this message. */\n toolCallIds: string[];\n /** Subagent IDs spawned during this message. */\n subagentIds: string[];\n /** Thinking block IDs attached to this message (in order). */\n thinkingIds: string[];\n /** Whether this message has an active OM observation. */\n hasOMActivity: boolean;\n /** Whether this message has an approval request. */\n approvalMessageId?: string;\n /** Whether this message has a question. */\n questionId?: string;\n /** Whether this message has a plan approval. */\n planId?: string;\n}\n\n/** A model thinking/reasoning block attached to a message. */\nexport interface AgentThinking {\n id: string;\n /** Parent message ID. */\n messageId: string;\n /** Accumulated thinking text. */\n text: string;\n /** Whether this block is still streaming. */\n isStreaming: boolean;\n}\n\n/** Normalized tool call state. */\nexport interface AgentToolCall {\n id: string;\n toolName: string;\n /** Parent message ID (undefined if inside a subagent). */\n messageId?: string;\n /** Parent subagent ID (undefined if top-level). */\n subagentId?: string;\n state:\n | \"input-streaming\"\n | \"input-available\"\n | \"approval-requested\"\n | \"approval-responded\"\n | \"output-available\"\n | \"output-error\"\n | \"output-denied\";\n input?: unknown;\n inputBuffer?: string;\n output?: unknown;\n errorText?: string;\n summary?: string;\n durationMs?: number;\n approvalState?: \"awaiting\" | \"approved\" | \"declined\";\n /** Wall-clock ms when this tool call started. */\n startedAt?: number;\n /** Wall-clock ms when this tool call ended. */\n endedAt?: number;\n}\n\n/** Normalized subagent state. */\nexport interface AgentSubagent {\n id: string;\n agentType?: string;\n name?: string;\n modelId?: string;\n status: \"running\" | \"completed\" | \"error\";\n /** Accumulated text deltas. */\n content: string;\n /** Tool call IDs inside this subagent. */\n toolCallIds: string[];\n /** Parent message ID. */\n messageId?: string;\n durationMs?: number;\n error?: string;\n /** Wall-clock ms when this subagent started. */\n startedAt?: number;\n /** Wall-clock ms when this subagent ended. */\n endedAt?: number;\n}\n\n/** Observational memory activity item. */\nexport interface AgentOMActivity {\n id: string;\n type: \"observation\" | \"reflection\";\n status: \"streaming\" | \"completed\";\n text?: string;\n durationMs?: number;\n /** Which message this OM activity is attached to. */\n messageId?: string;\n}\n\n/** A pending question. */\nexport interface AgentQuestion {\n questionId: string;\n question: string;\n header?: string;\n options?: Array<{ label: string; description?: string }>;\n multiple?: boolean;\n allowCustom?: boolean;\n status: \"pending\" | \"answered\";\n answeredWith?: string;\n}\n\n/** A pending plan approval. */\nexport interface AgentPlanApproval {\n planId: string;\n title: string;\n description?: string;\n steps?: Array<{ id: string; label: string; description?: string }>;\n status: \"pending\" | \"approved\" | \"rejected\";\n}\n\n/** Task list state. */\nexport interface AgentTaskList {\n title?: string;\n tasks: Array<{\n id: string;\n content: string;\n status: \"pending\" | \"in_progress\" | \"completed\" | \"cancelled\";\n priority?: \"high\" | \"medium\" | \"low\";\n }>;\n}\n\n/** Usage/token stats. */\nexport interface AgentUsage {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n cost?: number;\n modelId?: string;\n}\n\n/** A notice/banner in the conversation. */\nexport interface AgentNotice {\n id: string;\n level: \"info\" | \"error\" | \"change\";\n message: string;\n /** Attach to a message ID for inline rendering, or undefined for standalone. */\n messageId?: string;\n}\n\n/** Full normalized harness UI state. */\nexport interface AgentHarnessState {\n /** Ordered list of message IDs. */\n messageIds: string[];\n /** Message map. */\n messages: Record<string, AgentMessage>;\n /** Tool call map. */\n toolCalls: Record<string, AgentToolCall>;\n /** Subagent map. */\n subagents: Record<string, AgentSubagent>;\n /** OM activity map. */\n omActivities: Record<string, AgentOMActivity>;\n /** Model thinking/reasoning blocks map. */\n thinkings: Record<string, AgentThinking>;\n /** Question map (by questionId). */\n questions: Record<string, AgentQuestion>;\n /** Plan approval map (by planId). */\n planApprovals: Record<string, AgentPlanApproval>;\n /** Notices/banners (inline in conversation). */\n notices: AgentNotice[];\n /** Current task list. */\n taskList: AgentTaskList | null;\n /** Token usage. */\n usage: AgentUsage | null;\n /** Whether the agent is currently running. */\n isRunning: boolean;\n /** Active mode. */\n modeId?: string;\n modeName?: string;\n /** Active model. */\n modelId?: string;\n modelName?: string;\n /** Active thread. */\n threadId?: string;\n /** Active pending tool approval (toolCallId). */\n pendingToolApprovalId?: string;\n /** Active pending question ID. */\n pendingQuestionId?: string;\n /** Active pending plan ID. */\n pendingPlanId?: string;\n /** Whether a workspace error is active. */\n workspaceError?: string;\n /**\n * Wall-clock ms when agent_start fired. Used by Commander timeline.\n * Resets on agent_start; cleared on RESET.\n */\n missionStartedAt?: number;\n /** Wall-clock ms when agent_end fired for the last run. */\n missionEndedAt?: number;\n /**\n * Ordered log of every event with its wall-clock timestamp.\n * Used by the Commander timeline to position blocks accurately.\n * Not rendered by AgentHarness — Commander reads it directly.\n */\n timeline: TimestampedHarnessEvent[];\n}\n\n/** A harness event stamped with the wall-clock time it was received. */\nexport interface TimestampedHarnessEvent {\n event: HarnessEvent;\n /** Date.now() at the moment the event was dispatched into the reducer. */\n timestamp: number;\n}\n\n// ─── Reducer ──────────────────────────────────────────────────────────────────\n\nconst initialState: AgentHarnessState = {\n messageIds: [],\n messages: {},\n toolCalls: {},\n subagents: {},\n omActivities: {},\n thinkings: {},\n questions: {},\n planApprovals: {},\n notices: [],\n taskList: null,\n usage: null,\n isRunning: false,\n timeline: [],\n};\n\n/**\n * Create an empty `AgentHarnessState` with optional partial overrides.\n *\n * Use this when operating in controlled mode — build or derive your own state\n * that conforms to `AgentHarnessState` and pass it directly to `<AgentHarness state={...} />`.\n *\n * @example\n * ```ts\n * const [state, setState] = useState(() => createAgentHarnessState());\n * ```\n */\nexport function createAgentHarnessState(\n partial?: Partial<AgentHarnessState>\n): AgentHarnessState {\n return { ...initialState, ...partial };\n}\n\nlet _noticeCounter = 0;\nfunction nextNoticeId() {\n return `notice-${++_noticeCounter}`;\n}\n\nfunction getErrorString(error: string | Error): string {\n return typeof error === \"string\" ? error : error.message;\n}\n\ntype AgentHarnessAction =\n | { type: \"EVENT\"; event: HarnessEvent; timestamp: number }\n | { type: \"RESET\" };\n\nfunction agentHarnessReducer(\n state: AgentHarnessState,\n action: AgentHarnessAction\n): AgentHarnessState {\n if (action.type === \"RESET\") return { ...initialState };\n\n const { event, timestamp } = action;\n\n // Append every event to the timeline log\n const timeline: TimestampedHarnessEvent[] = [\n ...state.timeline,\n { event, timestamp },\n ];\n\n switch (event.type) {\n // ── Agent lifecycle ─────────────────────────────────────────────────────\n case \"agent_start\":\n return {\n ...state,\n timeline,\n isRunning: true,\n missionStartedAt: state.missionStartedAt ?? timestamp,\n };\n\n case \"agent_end\":\n return {\n ...state,\n timeline,\n isRunning: false,\n missionEndedAt: timestamp,\n };\n\n // ── Message lifecycle ───────────────────────────────────────────────────\n case \"message_start\": {\n const msg: AgentMessage = {\n id: event.messageId,\n role: event.role,\n content: \"\",\n isStreaming: event.role === \"assistant\",\n toolCallIds: [],\n subagentIds: [],\n thinkingIds: [],\n hasOMActivity: false,\n };\n return {\n ...state,\n timeline,\n messageIds: [...state.messageIds, event.messageId],\n messages: { ...state.messages, [event.messageId]: msg },\n };\n }\n\n case \"message_update\": {\n const existing = state.messages[event.messageId];\n if (!existing) return { ...state, timeline };\n const newContent =\n event.content === undefined\n ? existing.content + event.delta\n : event.content;\n return {\n ...state,\n timeline,\n messages: {\n ...state.messages,\n [event.messageId]: { ...existing, content: newContent },\n },\n };\n }\n\n case \"message_end\": {\n const existing = state.messages[event.messageId];\n if (!existing) return { ...state, timeline };\n return {\n ...state,\n timeline,\n messages: {\n ...state.messages,\n [event.messageId]: {\n ...existing,\n content: event.content,\n isStreaming: false,\n },\n },\n };\n }\n\n // ── Tool calls ──────────────────────────────────────────────────────────\n case \"tool_start\": {\n const toolCall: AgentToolCall = {\n id: event.toolCallId,\n toolName: event.toolName,\n messageId: event.messageId,\n subagentId: event.subagentId,\n state: \"input-streaming\",\n inputBuffer: \"\",\n startedAt: timestamp,\n };\n const updatedMessages = event.messageId\n ? {\n ...state.messages,\n [event.messageId]: {\n ...state.messages[event.messageId],\n toolCallIds: [\n ...(state.messages[event.messageId]?.toolCallIds ?? []),\n event.toolCallId,\n ],\n },\n }\n : state.messages;\n const updatedSubagents =\n event.subagentId && state.subagents[event.subagentId]\n ? {\n ...state.subagents,\n [event.subagentId]: {\n ...state.subagents[event.subagentId],\n toolCallIds: [\n ...state.subagents[event.subagentId].toolCallIds,\n event.toolCallId,\n ],\n },\n }\n : state.subagents;\n return {\n ...state,\n timeline,\n messages: updatedMessages,\n subagents: updatedSubagents,\n toolCalls: { ...state.toolCalls, [event.toolCallId]: toolCall },\n };\n }\n\n case \"tool_input_start\": {\n const tc = state.toolCalls[event.toolCallId];\n if (!tc) return { ...state, timeline };\n return {\n ...state,\n timeline,\n toolCalls: {\n ...state.toolCalls,\n [event.toolCallId]: {\n ...tc,\n state: \"input-streaming\",\n inputBuffer: \"\",\n },\n },\n };\n }\n\n case \"tool_input_delta\": {\n const tc = state.toolCalls[event.toolCallId];\n if (!tc) return { ...state, timeline };\n return {\n ...state,\n timeline,\n toolCalls: {\n ...state.toolCalls,\n [event.toolCallId]: {\n ...tc,\n inputBuffer: (tc.inputBuffer ?? \"\") + event.delta,\n },\n },\n };\n }\n\n case \"tool_input_end\": {\n const tc = state.toolCalls[event.toolCallId];\n if (!tc) return { ...state, timeline };\n return {\n ...state,\n timeline,\n toolCalls: {\n ...state.toolCalls,\n [event.toolCallId]: {\n ...tc,\n state: \"input-available\",\n input: event.input,\n inputBuffer: undefined,\n },\n },\n };\n }\n\n case \"tool_approval_required\": {\n const tc = state.toolCalls[event.toolCallId] ?? {\n id: event.toolCallId,\n toolName: event.toolName,\n messageId: event.messageId,\n state: \"approval-requested\" as const,\n toolCallIds: [],\n startedAt: timestamp,\n };\n return {\n ...state,\n timeline,\n pendingToolApprovalId: event.toolCallId,\n toolCalls: {\n ...state.toolCalls,\n [event.toolCallId]: {\n ...tc,\n state: \"approval-requested\",\n input: event.input ?? tc.input,\n approvalState: \"awaiting\",\n },\n },\n };\n }\n\n case \"tool_update\": {\n const tc = state.toolCalls[event.toolCallId];\n if (!tc) return { ...state, timeline };\n return {\n ...state,\n timeline,\n toolCalls: {\n ...state.toolCalls,\n [event.toolCallId]: { ...tc, summary: event.summary ?? tc.summary },\n },\n };\n }\n\n case \"tool_end\": {\n const tc = state.toolCalls[event.toolCallId];\n if (!tc) return { ...state, timeline };\n const pendingApprovalId =\n state.pendingToolApprovalId === event.toolCallId\n ? undefined\n : state.pendingToolApprovalId;\n return {\n ...state,\n timeline,\n pendingToolApprovalId: pendingApprovalId,\n toolCalls: {\n ...state.toolCalls,\n [event.toolCallId]: {\n ...tc,\n state: event.error ? \"output-error\" : \"output-available\",\n output: event.output,\n errorText: event.error,\n durationMs: event.durationMs,\n endedAt: timestamp,\n },\n },\n };\n }\n\n // ── Subagents ───────────────────────────────────────────────────────────\n case \"subagent_start\": {\n const subagent: AgentSubagent = {\n id: event.subagentId,\n agentType: event.agentType,\n name: event.name,\n modelId: event.modelId,\n status: \"running\",\n content: \"\",\n toolCallIds: [],\n messageId: event.parentMessageId,\n startedAt: timestamp,\n };\n const updatedMessages = event.parentMessageId\n ? {\n ...state.messages,\n [event.parentMessageId]: {\n ...state.messages[event.parentMessageId],\n subagentIds: [\n ...(state.messages[event.parentMessageId]?.subagentIds ?? []),\n event.subagentId,\n ],\n },\n }\n : state.messages;\n return {\n ...state,\n timeline,\n messages: updatedMessages,\n subagents: { ...state.subagents, [event.subagentId]: subagent },\n };\n }\n\n case \"subagent_text_delta\": {\n const sa = state.subagents[event.subagentId];\n if (!sa) return { ...state, timeline };\n return {\n ...state,\n timeline,\n subagents: {\n ...state.subagents,\n [event.subagentId]: { ...sa, content: sa.content + event.delta },\n },\n };\n }\n\n case \"subagent_tool_start\": {\n const tc: AgentToolCall = {\n id: event.toolCallId,\n toolName: event.toolName,\n subagentId: event.subagentId,\n state: \"input-streaming\",\n inputBuffer: \"\",\n startedAt: timestamp,\n };\n const sa = state.subagents[event.subagentId];\n const updatedSubagents = sa\n ? {\n ...state.subagents,\n [event.subagentId]: {\n ...sa,\n toolCallIds: [...sa.toolCallIds, event.toolCallId],\n },\n }\n : state.subagents;\n return {\n ...state,\n timeline,\n subagents: updatedSubagents,\n toolCalls: { ...state.toolCalls, [event.toolCallId]: tc },\n };\n }\n\n case \"subagent_tool_end\": {\n const tc = state.toolCalls[event.toolCallId];\n if (!tc) return { ...state, timeline };\n return {\n ...state,\n timeline,\n toolCalls: {\n ...state.toolCalls,\n [event.toolCallId]: {\n ...tc,\n state: event.error ? \"output-error\" : \"output-available\",\n output: event.output,\n errorText: event.error,\n durationMs: event.durationMs,\n endedAt: timestamp,\n },\n },\n };\n }\n\n case \"subagent_end\": {\n const sa = state.subagents[event.subagentId];\n if (!sa) return { ...state, timeline };\n return {\n ...state,\n timeline,\n subagents: {\n ...state.subagents,\n [event.subagentId]: {\n ...sa,\n status: event.error ? \"error\" : \"completed\",\n error: event.error,\n durationMs: event.durationMs,\n endedAt: timestamp,\n },\n },\n };\n }\n\n case \"subagent_model_changed\": {\n if (event.subagentId) {\n const sa = state.subagents[event.subagentId];\n if (!sa) return { ...state, timeline };\n return {\n ...state,\n timeline,\n subagents: {\n ...state.subagents,\n [event.subagentId]: { ...sa, modelId: event.modelId },\n },\n };\n }\n return { ...state, timeline };\n }\n\n // ── Observational Memory ────────────────────────────────────────────────\n case \"om_observation_start\": {\n const id = event.observationId ?? `om-obs-${Date.now()}`;\n const activity: AgentOMActivity = {\n id,\n type: \"observation\",\n status: \"streaming\",\n messageId: state.messageIds[state.messageIds.length - 1],\n };\n return {\n ...state,\n timeline,\n omActivities: { ...state.omActivities, [id]: activity },\n };\n }\n\n case \"om_observation_end\": {\n const id =\n event.observationId ??\n Object.keys(state.omActivities).find(\n (k) =>\n state.omActivities[k].type === \"observation\" &&\n state.omActivities[k].status === \"streaming\"\n );\n if (!id) return { ...state, timeline };\n return {\n ...state,\n timeline,\n omActivities: {\n ...state.omActivities,\n [id]: {\n ...state.omActivities[id],\n status: \"completed\",\n text: event.text,\n durationMs: event.durationMs,\n },\n },\n };\n }\n\n case \"om_reflection_start\": {\n const id = `om-ref-${Date.now()}`;\n const activity: AgentOMActivity = {\n id,\n type: \"reflection\",\n status: \"streaming\",\n messageId: state.messageIds[state.messageIds.length - 1],\n };\n return {\n ...state,\n timeline,\n omActivities: { ...state.omActivities, [id]: activity },\n };\n }\n\n case \"om_reflection_end\": {\n const id = Object.keys(state.omActivities).find(\n (k) =>\n state.omActivities[k].type === \"reflection\" &&\n state.omActivities[k].status === \"streaming\"\n );\n if (!id) return { ...state, timeline };\n return {\n ...state,\n timeline,\n omActivities: {\n ...state.omActivities,\n [id]: {\n ...state.omActivities[id],\n status: \"completed\",\n text: event.text,\n durationMs: event.durationMs,\n },\n },\n };\n }\n\n // ── Thinking / Reasoning ────────────────────────────────────────────────\n case \"thinking_start\": {\n const thinking: AgentThinking = {\n id: event.thinkingId,\n messageId: event.messageId,\n text: \"\",\n isStreaming: true,\n };\n const existingMsg = state.messages[event.messageId];\n return {\n ...state,\n timeline,\n thinkings: { ...state.thinkings, [event.thinkingId]: thinking },\n messages: existingMsg\n ? {\n ...state.messages,\n [event.messageId]: {\n ...existingMsg,\n thinkingIds: [...existingMsg.thinkingIds, event.thinkingId],\n },\n }\n : state.messages,\n };\n }\n\n case \"thinking_delta\": {\n const existing = state.thinkings[event.thinkingId];\n if (!existing) return { ...state, timeline };\n const newText =\n event.content === undefined\n ? existing.text + event.delta\n : event.content;\n return {\n ...state,\n timeline,\n thinkings: {\n ...state.thinkings,\n [event.thinkingId]: { ...existing, text: newText },\n },\n };\n }\n\n case \"thinking_end\": {\n const existing = state.thinkings[event.thinkingId];\n if (!existing) return { ...state, timeline };\n return {\n ...state,\n timeline,\n thinkings: {\n ...state.thinkings,\n [event.thinkingId]: {\n ...existing,\n text: event.content,\n isStreaming: false,\n },\n },\n };\n }\n\n // ── Questions + Plans ───────────────────────────────────────────────────\n case \"ask_question\": {\n const q: AgentQuestion = {\n questionId: event.questionId,\n question: event.question,\n header: event.header,\n options: event.options,\n multiple: event.multiple,\n allowCustom: event.allowCustom,\n status: \"pending\",\n };\n // Associate the question with the last message so it renders on the right message\n const lastMsgId = state.messageIds[state.messageIds.length - 1];\n const updatedMessages = lastMsgId\n ? {\n ...state.messages,\n [lastMsgId]: {\n ...state.messages[lastMsgId],\n questionId: event.questionId,\n },\n }\n : state.messages;\n return {\n ...state,\n timeline,\n pendingQuestionId: event.questionId,\n questions: { ...state.questions, [event.questionId]: q },\n messages: updatedMessages,\n };\n }\n\n case \"question_answered\": {\n const q = state.questions[event.questionId];\n if (!q) return { ...state, timeline };\n return {\n ...state,\n timeline,\n pendingQuestionId:\n state.pendingQuestionId === event.questionId\n ? undefined\n : state.pendingQuestionId,\n questions: {\n ...state.questions,\n [event.questionId]: {\n ...q,\n status: \"answered\",\n answeredWith: event.answer,\n },\n },\n };\n }\n\n case \"plan_approval_required\": {\n const p: AgentPlanApproval = {\n planId: event.planId,\n title: event.title,\n description: event.description,\n steps: event.steps,\n status: \"pending\",\n };\n // Associate the plan with the last message so it renders on the right message\n const lastMsgId = state.messageIds[state.messageIds.length - 1];\n const updatedMessages = lastMsgId\n ? {\n ...state.messages,\n [lastMsgId]: { ...state.messages[lastMsgId], planId: event.planId },\n }\n : state.messages;\n return {\n ...state,\n timeline,\n pendingPlanId: event.planId,\n planApprovals: { ...state.planApprovals, [event.planId]: p },\n messages: updatedMessages,\n };\n }\n\n case \"plan_approved\": {\n const p = state.planApprovals[event.planId];\n if (!p) return { ...state, timeline };\n return {\n ...state,\n timeline,\n pendingPlanId:\n state.pendingPlanId === event.planId\n ? undefined\n : state.pendingPlanId,\n planApprovals: {\n ...state.planApprovals,\n [event.planId]: { ...p, status: \"approved\" },\n },\n };\n }\n\n // ── Tasks ───────────────────────────────────────────────────────────────\n case \"task_updated\":\n return {\n ...state,\n timeline,\n taskList: { tasks: event.tasks, title: event.title },\n };\n\n // ── Usage ───────────────────────────────────────────────────────────────\n case \"usage_update\":\n return {\n ...state,\n timeline,\n usage: {\n inputTokens: event.inputTokens,\n outputTokens: event.outputTokens,\n totalTokens: event.totalTokens,\n cost: event.cost,\n modelId: event.modelId,\n },\n };\n\n // ── Notices ─────────────────────────────────────────────────────────────\n case \"error\": {\n const notice: AgentNotice = {\n id: nextNoticeId(),\n level: \"error\",\n message: getErrorString(event.error),\n messageId: event.messageId,\n };\n return { ...state, timeline, notices: [...state.notices, notice] };\n }\n\n case \"info\": {\n const notice: AgentNotice = {\n id: nextNoticeId(),\n level: \"info\",\n message: event.message,\n };\n return { ...state, timeline, notices: [...state.notices, notice] };\n }\n\n case \"follow_up_queued\": {\n const notice: AgentNotice = {\n id: nextNoticeId(),\n level: \"info\",\n message: `Follow-up queued: ${event.content}`,\n };\n return { ...state, timeline, notices: [...state.notices, notice] };\n }\n\n case \"workspace_error\":\n return {\n ...state,\n timeline,\n workspaceError: getErrorString(event.error),\n };\n\n case \"workspace_ready\":\n return { ...state, timeline, workspaceError: undefined };\n\n case \"workspace_status_changed\": {\n const notice: AgentNotice = {\n id: nextNoticeId(),\n level: \"info\",\n message: `Workspace: ${event.status}`,\n };\n return { ...state, timeline, notices: [...state.notices, notice] };\n }\n\n case \"mode_changed\":\n return {\n ...state,\n timeline,\n modeId: event.modeId,\n modeName: event.modeName,\n };\n\n case \"model_changed\":\n return {\n ...state,\n timeline,\n modelId: event.modelId,\n modelName: event.modelName,\n };\n\n case \"thread_changed\":\n return { ...initialState, threadId: event.threadId, timeline };\n\n case \"thread_created\":\n case \"thread_deleted\":\n case \"state_changed\":\n case \"om_status\":\n return { ...state, timeline };\n\n default:\n return { ...state, timeline };\n }\n}\n\n// ─── Hook ─────────────────────────────────────────────────────────────────────\n\nexport interface UseAgentHarnessOptions {\n /** The harness adapter to subscribe to. Pass `null` to skip subscription. */\n adapter: HarnessAdapter | null;\n}\n\nexport interface UseAgentHarnessReturn {\n /** Full normalized harness UI state. */\n state: AgentHarnessState;\n /** Send a user message. */\n sendMessage: (params: {\n content: string;\n files?: Array<{ url: string; mediaType: string; filename: string }>;\n }) => Promise<void>;\n /** Respond to a pending tool approval. */\n respondToToolApproval: (decision: \"approve\" | \"decline\") => Promise<void>;\n /** Respond to a pending question. */\n respondToQuestion: (questionId: string, answer: string) => Promise<void>;\n /** Respond to a pending plan approval. */\n respondToPlanApproval: (\n planId: string,\n response: { action: \"approved\" | \"rejected\"; feedback?: string }\n ) => Promise<void>;\n /** Abort any in-progress generation. */\n abort: () => void;\n /** Steer the agent mid-stream. */\n steer: (content: string) => void;\n /** Select a mode. */\n selectMode: (modeId: string) => Promise<void>;\n /** Reset the state (e.g. after a thread switch). */\n reset: () => void;\n}\n\n/**\n * `useAgentHarness` — headless state hook for the AgentHarness UI.\n *\n * Subscribes to a `HarnessAdapter` and reduces all events into a single\n * normalized `AgentHarnessState` object that the `AgentHarness` block\n * (or any custom UI) can render from.\n *\n * @example\n * ```tsx\n * const adapter = fromMastraHarness(harness);\n * const { state, sendMessage, abort } = useAgentHarness({ adapter });\n * ```\n */\nexport function useAgentHarness({\n adapter,\n}: UseAgentHarnessOptions): UseAgentHarnessReturn {\n const [state, dispatch] = useReducer(agentHarnessReducer, initialState);\n\n // Keep a stable ref to the adapter so callbacks below don't stale-close\n const adapterRef = useRef<HarnessAdapter | null>(adapter);\n adapterRef.current = adapter;\n\n // Subscribe to harness events — stamp each with Date.now() for timeline\n useEffect(() => {\n if (!adapter) return;\n const unsubscribe = adapter.subscribe((event) => {\n dispatch({ type: \"EVENT\", event, timestamp: Date.now() });\n });\n return unsubscribe;\n }, [adapter]);\n\n const sendMessage = useCallback(\n async (params: {\n content: string;\n files?: Array<{ url: string; mediaType: string; filename: string }>;\n }) => {\n await adapterRef.current?.sendMessage(params);\n },\n []\n );\n\n const respondToToolApproval = useCallback(\n async (decision: \"approve\" | \"decline\") => {\n await adapterRef.current?.respondToToolApproval?.({ decision });\n },\n []\n );\n\n const respondToQuestion = useCallback(\n async (questionId: string, answer: string) => {\n await adapterRef.current?.respondToQuestion?.({ questionId, answer });\n },\n []\n );\n\n const respondToPlanApproval = useCallback(\n async (\n planId: string,\n response: { action: \"approved\" | \"rejected\"; feedback?: string }\n ) => {\n await adapterRef.current?.respondToPlanApproval?.({ planId, response });\n },\n []\n );\n\n const abort = useCallback(() => {\n adapterRef.current?.abort?.();\n }, []);\n\n const steer = useCallback((content: string) => {\n adapterRef.current?.steer?.({ content });\n }, []);\n\n const selectMode = useCallback(async (modeId: string) => {\n await adapterRef.current?.selectMode?.({ modeId });\n }, []);\n\n const reset = useCallback(() => {\n dispatch({ type: \"RESET\" });\n }, []);\n\n return {\n state,\n sendMessage,\n respondToToolApproval,\n respondToQuestion,\n respondToPlanApproval,\n abort,\n steer,\n selectMode,\n reset,\n };\n}\n"],"mappings":"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"}
package/dist/utils.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { n as safeRandomId, t as cn } from "./cn-YROP2_ox.js";
3
- import { n as useLinkComponent, t as LinkProvider } from "./link-provider-BUZKXaNE.js";
4
- import { n as useMeasuredText, t as MeasuredText } from "./measured-text-BI3dTJmH.js";
2
+ import { n as safeRandomId, t as cn } from "./cn-CmAOpn49.js";
3
+ import { n as useLinkComponent, t as LinkProvider } from "./link-provider-BSn8YJon.js";
4
+ import { n as useMeasuredText, t as MeasuredText } from "./measured-text-CXkdw9Yr.js";
5
5
  export { LinkProvider, MeasuredText, cn, safeRandomId, useLinkComponent, useMeasuredText };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signalflare-ai/ui",
3
- "version": "1.2.0",
3
+ "version": "1.3.0",
4
4
  "private": false,
5
5
  "description": "SignalFlare AI component library for building modern web applications",
6
6
  "keywords": [
@@ -550,65 +550,67 @@
550
550
  "build-storybook": "storybook build"
551
551
  },
552
552
  "dependencies": {
553
- "@base-ui/react": "1.4.1",
554
- "@chenglou/pretext": "^0.0.6",
555
- "@json-render/core": "^0.18.0",
556
- "@json-render/react": "^0.18.0",
553
+ "@base-ui/react": "1.5.0",
554
+ "@chenglou/pretext": "^0.0.7",
555
+ "@json-render/core": "^0.19.0",
556
+ "@json-render/react": "^0.19.0",
557
557
  "@tanstack/react-store": "^0.11.0",
558
558
  "@tanstack/store": "^0.11.0",
559
559
  "clsx": "^2.1.1",
560
- "tailwind-merge": "^3.4.0"
560
+ "tailwind-merge": "^3.6.0"
561
561
  },
562
562
  "devDependencies": {
563
- "@storybook/addon-mcp": "^0.5.0",
564
- "@storybook/addon-themes": "^10.3.5",
565
- "@storybook/addon-vitest": "^10.3.5",
566
- "@storybook/react-vite": "^10.3.5",
563
+ "@storybook/addon-mcp": "^0.6.0",
564
+ "@storybook/addon-themes": "^10.4.2",
565
+ "@storybook/addon-vitest": "^10.4.2",
566
+ "@storybook/react-vite": "^10.4.2",
567
567
  "@streamdown/code": "^1.1.1",
568
568
  "@tailwindcss/cli": "catalog:",
569
569
  "@tailwindcss/vite": "catalog:",
570
- "@tanstack/intent": "^0.0.34",
571
- "@tanstack/react-table": "^8.21.0",
572
- "@tanstack/react-virtual": "^3.13.24",
570
+ "@tanstack/intent": "^0.0.41",
571
+ "@tanstack/react-table": "9.0.0-alpha.52",
572
+ "@tanstack/react-virtual": "^3.14.2",
573
573
  "@testing-library/react": "16.3.2",
574
574
  "@testing-library/user-event": "14.6.1",
575
575
  "@types/leaflet": "^1.9.21",
576
576
  "@types/node": "catalog:",
577
577
  "@types/react": "catalog:",
578
578
  "@types/react-dom": "catalog:",
579
- "@vitejs/plugin-react": "^6.0.1",
580
- "@vitest/browser": "^4.1.5",
579
+ "@vitejs/plugin-react": "^6.0.2",
580
+ "@vitest/browser": "^4.1.8",
581
+ "@vitest/browser-playwright": "4.1.8",
582
+ "@vitest/coverage-v8": "^4.1.8",
581
583
  "@vitest/ui": "catalog:",
582
- "echarts": "^6.0.0",
584
+ "echarts": "^6.1.0",
583
585
  "h3-js": "^4.4.0",
584
586
  "happy-dom": "catalog:",
585
587
  "leaflet": "^1.9.4",
586
- "motion": "^12.38.0",
588
+ "motion": "^12.40.0",
587
589
  "oxlint": "catalog:",
588
- "playwright": "^1.52.0",
590
+ "playwright": "^1.60.0",
589
591
  "plop": "4.0.5",
590
592
  "react-day-picker": "^9.13.2",
591
- "storybook": "^10.3.5",
593
+ "storybook": "^10.4.2",
592
594
  "streamdown": "^2.5.0",
593
- "sugar-high": "^1.0.0",
595
+ "sugar-high": "^1.2.1",
594
596
  "tailwindcss": "catalog:",
595
597
  "ts-json-schema-generator": "2.9.0",
596
598
  "typescript": "catalog:",
597
599
  "vite": "catalog:",
598
600
  "vite-plugin-dts": "catalog:",
599
601
  "vitest": "catalog:",
600
- "zod": "^4.3.6"
602
+ "zod": "^4.4.3"
601
603
  },
602
604
  "peerDependencies": {
603
605
  "@phosphor-icons/react": "^2.1.10",
604
606
  "@streamdown/code": "^1.1.1",
605
- "@tanstack/react-table": "^8.21.0",
606
- "@tanstack/react-virtual": "^3.13.22",
607
+ "@tanstack/react-table": "9.0.0-alpha.52",
608
+ "@tanstack/react-virtual": "^3.13.26",
607
609
  "echarts": "^6.0.0",
608
610
  "motion": "^12.38.0",
609
- "react": "^19.2.5",
611
+ "react": "^19.2.7",
610
612
  "react-day-picker": "^9.13.2",
611
- "react-dom": "^19.2.5",
613
+ "react-dom": "^19.2.7",
612
614
  "streamdown": "^2.5.0",
613
615
  "sugar-high": "^1.0.0",
614
616
  "zod": "^3.25.67 || ^4.3.6"
@@ -104,7 +104,7 @@ export function detectExportsFromIndex(dirPath: string): DetectedExports {
104
104
 
105
105
  // Match named exports: export { Foo, Bar, type BazProps } from "./file"
106
106
  // Also handles: export { Foo } from "./file"
107
- const exportPattern = /export\s*\{([^}]+)\}/g;
107
+ const exportPattern = /export\s*\{([^}]+)\}/gu;
108
108
  let match: RegExpExecArray | null;
109
109
 
110
110
  const namedExports: string[] = [];
@@ -120,13 +120,13 @@ export function detectExportsFromIndex(dirPath: string): DetectedExports {
120
120
 
121
121
  for (const item of items) {
122
122
  // Check if it's a type export: "type FooProps" or "type Foo as Bar"
123
- const typeMatch = /^type\s+(\w+)(?:\s+as\s+(\w+))?/.exec(item);
123
+ const typeMatch = /^type\s+(\w+)(?:\s+as\s+(\w+))?/u.exec(item);
124
124
  if (typeMatch) {
125
125
  // Use aliased name if present, otherwise original name
126
126
  typeExports.push(typeMatch[2] || typeMatch[1]);
127
127
  } else {
128
128
  // Regular named export, could have "as" alias: "Foo as Bar"
129
- const nameMatch = /^(\w+)(?:\s+as\s+(\w+))?/.exec(item);
129
+ const nameMatch = /^(\w+)(?:\s+as\s+(\w+))?/u.exec(item);
130
130
  if (nameMatch) {
131
131
  // Use aliased name if present, otherwise original name
132
132
  namedExports.push(nameMatch[2] || nameMatch[1]);
@@ -136,7 +136,7 @@ export function detectExportsFromIndex(dirPath: string): DetectedExports {
136
136
  }
137
137
 
138
138
  // Also match direct exports: export const Foo = ...
139
- const directExportPattern = /export\s+(?:const|function)\s+(\w+)/g;
139
+ const directExportPattern = /export\s+(?:const|function)\s+(\w+)/gu;
140
140
  while ((match = directExportPattern.exec(content)) !== null) {
141
141
  namedExports.push(match[1]);
142
142
  }
@@ -196,9 +196,9 @@ export function detectPropsTypeFromFile(
196
196
 
197
197
  // Look for interface/type that ends with Props (both exported and non-exported)
198
198
  // Pattern: [export] interface FooProps or [export] type FooProps
199
- const exportedPropsPattern = /export\s+(?:interface|type)\s+(\w+Props)/g;
199
+ const exportedPropsPattern = /export\s+(?:interface|type)\s+(\w+Props)/gu;
200
200
  const nonExportedPropsPattern =
201
- /(?:^|\n)\s*(?:interface|type)\s+(\w+Props)\s*[=<{]/g;
201
+ /(?:^|\n)\s*(?:interface|type)\s+(\w+Props)\s*[=<{]/gu;
202
202
 
203
203
  const exportedTypes: string[] = [];
204
204
  const nonExportedTypes: string[] = [];
@@ -243,7 +243,7 @@ function extractDescriptionFromJSDoc(jsdocContent: string): string | null {
243
243
  const lines: string[] = [];
244
244
 
245
245
  for (const rawLine of jsdocContent.split("\n")) {
246
- const line = rawLine.replace(/^\s*\*\s?/, "").trim();
246
+ const line = rawLine.replace(/^\s*\*\s?/u, "").trim();
247
247
 
248
248
  // Stop at any @tag
249
249
  if (line.startsWith("@")) {
@@ -291,7 +291,8 @@ export function extractDescription(
291
291
  // First, find the position of the component declaration
292
292
  // Handles: export function X, export const X =, function X(
293
293
  const componentDeclPattern = new RegExp(
294
- `(?:export\\s+)?(?:function|const)\\s+${componentName}\\s*(?:=|\\()`
294
+ `(?:export\\s+)?(?:function|const)\\s+${componentName}\\s*(?:=|\\()`,
295
+ "u"
295
296
  );
296
297
  const componentMatch = content.match(componentDeclPattern);
297
298
 
@@ -302,7 +303,7 @@ export function extractDescription(
302
303
  const componentPos = componentMatch.index;
303
304
 
304
305
  // Find all JSDoc comments in the file
305
- const jsdocPattern = /\/\*\*\s*\n([\s\S]*?)\*\//g;
306
+ const jsdocPattern = /\/\*\*\s*\n([\s\S]*?)\*\//gu;
306
307
  let lastJSDoc: { content: string; endPos: number } | null = null;
307
308
  let match: RegExpExecArray | null;
308
309
 
@@ -317,7 +318,7 @@ export function extractDescription(
317
318
  // Check if this JSDoc is immediately before the component
318
319
  // (only whitespace/newlines between JSDoc end and component declaration)
319
320
  const textBetween = content.slice(jsdocEndPos, componentPos);
320
- if (/^\s*$/.test(textBetween)) {
321
+ if (/^\s*$/u.test(textBetween)) {
321
322
  lastJSDoc = { content: match[1], endPos: jsdocEndPos };
322
323
  }
323
324
  }
@@ -21,26 +21,26 @@ export function cleanupExample(example: string): string {
21
21
  let cleaned = example;
22
22
 
23
23
  // Fix stringified functions: prop="() => {}" -> prop={() => {}}
24
- cleaned = cleaned.replace(/(\w+)="(\(\)\s*=>\s*\{[^}]*\})"/g, "$1={$2}");
24
+ cleaned = cleaned.replace(/(\w+)="(\(\)\s*=>\s*\{[^}]*\})"/gu, "$1={$2}");
25
25
 
26
26
  // Fix stringified arrays: prop={`[...]`} -> prop={[...]}
27
27
  // Match prop={`[...multiline content...]`}
28
- cleaned = cleaned.replace(/(\w+)=\{`(\[[\s\S]*?\])`\}/g, "$1={$2}");
28
+ cleaned = cleaned.replace(/(\w+)=\{`(\[[\s\S]*?\])`\}/gu, "$1={$2}");
29
29
 
30
30
  // Fix escaped template literals: \` -> `
31
- cleaned = cleaned.replace(/\\`/g, "`");
31
+ cleaned = cleaned.replace(/\\`/gu, "`");
32
32
 
33
33
  // Fix double backticks that result from escaping: {``content``} -> {`content`}
34
34
  // This happens when template literals get double-escaped
35
- cleaned = cleaned.replace(/\{``/g, "{`");
36
- cleaned = cleaned.replace(/``\}/g, "`}");
35
+ cleaned = cleaned.replace(/\{``/gu, "{`");
36
+ cleaned = cleaned.replace(/``\}/gu, "`}");
37
37
 
38
38
  // Fix unquoted identifiers that should be strings (common in Checkbox labels)
39
39
  // label={Checked} -> label="Checked" (when it's clearly meant to be a string)
40
40
  const identifierAsStringProps = ["label"];
41
41
  for (const prop of identifierAsStringProps) {
42
42
  // Match prop={SingleWord} where SingleWord is a simple identifier (not a component or expression)
43
- const pattern = new RegExp(`(${prop})=\\{([A-Z][a-z]+)\\}(?![\\w.])`, "g");
43
+ const pattern = new RegExp(`(${prop})=\\{([A-Z][a-z]+)\\}(?![\\w.])`, "gu");
44
44
  cleaned = cleaned.replace(pattern, '$1="$2"');
45
45
  }
46
46
 
@@ -91,7 +91,7 @@ export function shouldIncludeExample(
91
91
  }
92
92
 
93
93
  // Skip examples that are just the component with no props (not useful)
94
- const emptyPattern = new RegExp(`^<${componentName}\\s*/>$`);
94
+ const emptyPattern = new RegExp(`^<${componentName}\\s*/>$`, "u");
95
95
  if (emptyPattern.test(example.trim())) {
96
96
  return false;
97
97
  }
@@ -122,7 +122,7 @@ const seenExampleSignatures = new Map<string, Set<string>>();
122
122
  */
123
123
  export function getExampleSignature(example: string): string {
124
124
  // Extract prop assignments like variant="primary" or size="sm"
125
- const propPattern = /(\w+)=["'{]/g;
125
+ const propPattern = /(\w+)=["'{]/gu;
126
126
  const props: string[] = [];
127
127
  let match: RegExpExecArray | null;
128
128
  while ((match = propPattern.exec(example)) !== null) {
@@ -548,15 +548,15 @@ async function processComponent(
548
548
  const additionalProps = ADDITIONAL_COMPONENT_PROPS[config.name];
549
549
  if (additionalProps) {
550
550
  for (const [propName, propSchema] of Object.entries(additionalProps)) {
551
- if (!props[propName]) {
552
- props[propName] = propSchema;
553
- } else {
551
+ if (props[propName]) {
554
552
  if (propSchema.type) {
555
553
  props[propName].type = propSchema.type;
556
554
  }
557
555
  if (propSchema.description) {
558
556
  props[propName].description = propSchema.description;
559
557
  }
558
+ } else {
559
+ props[propName] = propSchema;
560
560
  }
561
561
  }
562
562
  }
@@ -575,9 +575,7 @@ async function processComponent(
575
575
 
576
576
  // Determine examples
577
577
  let examples: readonly string[];
578
- if (config.examples !== undefined) {
579
- examples = config.examples;
580
- } else {
578
+ if (config.examples === undefined) {
581
579
  const extracted = input.storyExamples.get(config.name);
582
580
  examples = extracted?.aiExamples ?? [];
583
581
  if (examples.length > 0 && CLI_FLAGS.verbose) {
@@ -585,6 +583,8 @@ async function processComponent(
585
583
  ` → Auto-extracted ${examples.length} examples from stories`
586
584
  );
587
585
  }
586
+ } else {
587
+ examples = config.examples;
588
588
  }
589
589
 
590
590
  // Detect and process sub-components
@@ -75,7 +75,7 @@ function generateComponentPropsSchema(
75
75
  const zodType = propTypeToZod(propSchema);
76
76
  // Replace newlines with spaces to keep comments on a single line
77
77
  const sanitizedDescription = propSchema.description
78
- ?.replace(/\n+/g, " ")
78
+ ?.replace(/\n+/gu, " ")
79
79
  .trim();
80
80
  const comment = sanitizedDescription ? ` // ${sanitizedDescription}` : "";
81
81
  return ` ${propName}: ${zodType},${comment}`;