@miragon/mcp-toolkit-ui 2.6.0 → 2.8.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 (511) hide show
  1. package/README.md +14 -5
  2. package/dist/app/adapt-data-widget.d.ts +1 -22
  3. package/dist/app/adapt-data-widget.d.ts.map +1 -1
  4. package/dist/app/adapt-data-widget.js +1 -35
  5. package/dist/app/adapt-data-widget.js.map +1 -1
  6. package/dist/app/builder/BuilderBanners.d.ts +7 -2
  7. package/dist/app/builder/BuilderBanners.d.ts.map +1 -1
  8. package/dist/app/builder/BuilderBanners.js +8 -3
  9. package/dist/app/builder/BuilderBanners.js.map +1 -1
  10. package/dist/app/builder/CanvasRow.d.ts +4 -2
  11. package/dist/app/builder/CanvasRow.d.ts.map +1 -1
  12. package/dist/app/builder/CanvasRow.js +29 -17
  13. package/dist/app/builder/CanvasRow.js.map +1 -1
  14. package/dist/app/builder/CatalogueSheet.d.ts.map +1 -1
  15. package/dist/app/builder/CatalogueSheet.js +14 -6
  16. package/dist/app/builder/CatalogueSheet.js.map +1 -1
  17. package/dist/app/builder/CellPropsSheet.d.ts +7 -3
  18. package/dist/app/builder/CellPropsSheet.d.ts.map +1 -1
  19. package/dist/app/builder/CellPropsSheet.js +10 -3
  20. package/dist/app/builder/CellPropsSheet.js.map +1 -1
  21. package/dist/app/builder/DiscardDialog.d.ts +18 -0
  22. package/dist/app/builder/DiscardDialog.d.ts.map +1 -0
  23. package/dist/app/builder/DiscardDialog.js +18 -0
  24. package/dist/app/builder/DiscardDialog.js.map +1 -0
  25. package/dist/app/builder/EmptyHint.d.ts +4 -0
  26. package/dist/app/builder/EmptyHint.d.ts.map +1 -1
  27. package/dist/app/builder/EmptyHint.js +6 -1
  28. package/dist/app/builder/EmptyHint.js.map +1 -1
  29. package/dist/app/builder/LayoutSurface.d.ts +33 -9
  30. package/dist/app/builder/LayoutSurface.d.ts.map +1 -1
  31. package/dist/app/builder/LayoutSurface.js +74 -23
  32. package/dist/app/builder/LayoutSurface.js.map +1 -1
  33. package/dist/app/builder/PipelineStrip.d.ts +5 -2
  34. package/dist/app/builder/PipelineStrip.d.ts.map +1 -1
  35. package/dist/app/builder/PipelineStrip.js +33 -15
  36. package/dist/app/builder/PipelineStrip.js.map +1 -1
  37. package/dist/app/builder/SaveDialog.d.ts +9 -1
  38. package/dist/app/builder/SaveDialog.d.ts.map +1 -1
  39. package/dist/app/builder/SaveDialog.js +9 -3
  40. package/dist/app/builder/SaveDialog.js.map +1 -1
  41. package/dist/app/builder/Toolbar.d.ts +14 -4
  42. package/dist/app/builder/Toolbar.d.ts.map +1 -1
  43. package/dist/app/builder/Toolbar.js +24 -7
  44. package/dist/app/builder/Toolbar.js.map +1 -1
  45. package/dist/app/builder/Workspace.d.ts +23 -3
  46. package/dist/app/builder/Workspace.d.ts.map +1 -1
  47. package/dist/app/builder/Workspace.js +58 -8
  48. package/dist/app/builder/Workspace.js.map +1 -1
  49. package/dist/app/builder/builder-model.d.ts +146 -3
  50. package/dist/app/builder/builder-model.d.ts.map +1 -1
  51. package/dist/app/builder/builder-model.js +196 -5
  52. package/dist/app/builder/builder-model.js.map +1 -1
  53. package/dist/app/builder/labels.d.ts +13 -62
  54. package/dist/app/builder/labels.d.ts.map +1 -1
  55. package/dist/app/builder/labels.js +9 -58
  56. package/dist/app/builder/labels.js.map +1 -1
  57. package/dist/app/builder/reveal.d.ts +10 -0
  58. package/dist/app/builder/reveal.d.ts.map +1 -0
  59. package/dist/app/builder/reveal.js +10 -0
  60. package/dist/app/builder/reveal.js.map +1 -0
  61. package/dist/app/builder/status-chip.d.ts.map +1 -1
  62. package/dist/app/builder/status-chip.js +3 -2
  63. package/dist/app/builder/status-chip.js.map +1 -1
  64. package/dist/app/builder/use-builder-catalogue.d.ts +5 -1
  65. package/dist/app/builder/use-builder-catalogue.d.ts.map +1 -1
  66. package/dist/app/builder/use-builder-catalogue.js +50 -17
  67. package/dist/app/builder/use-builder-catalogue.js.map +1 -1
  68. package/dist/app/builder/use-builder-session.d.ts +30 -0
  69. package/dist/app/builder/use-builder-session.d.ts.map +1 -0
  70. package/dist/app/builder/use-builder-session.js +58 -0
  71. package/dist/app/builder/use-builder-session.js.map +1 -0
  72. package/dist/app/builder/use-display-resolver.d.ts +17 -0
  73. package/dist/app/builder/use-display-resolver.d.ts.map +1 -0
  74. package/dist/app/builder/use-display-resolver.js +16 -0
  75. package/dist/app/builder/use-display-resolver.js.map +1 -0
  76. package/dist/app/builder/use-save-dashboard.d.ts +3 -1
  77. package/dist/app/builder/use-save-dashboard.d.ts.map +1 -1
  78. package/dist/app/builder/use-save-dashboard.js +3 -1
  79. package/dist/app/builder/use-save-dashboard.js.map +1 -1
  80. package/dist/app/index.d.ts +8 -3
  81. package/dist/app/index.d.ts.map +1 -1
  82. package/dist/app/index.js +8 -2
  83. package/dist/app/index.js.map +1 -1
  84. package/dist/app/layout-builder.d.ts +18 -25
  85. package/dist/app/layout-builder.d.ts.map +1 -1
  86. package/dist/app/layout-builder.js +84 -78
  87. package/dist/app/layout-builder.js.map +1 -1
  88. package/dist/app/mcp-app-view-chrome.d.ts +103 -20
  89. package/dist/app/mcp-app-view-chrome.d.ts.map +1 -1
  90. package/dist/app/mcp-app-view-chrome.js +125 -40
  91. package/dist/app/mcp-app-view-chrome.js.map +1 -1
  92. package/dist/app/mcp-app-view-states.d.ts +23 -0
  93. package/dist/app/mcp-app-view-states.d.ts.map +1 -0
  94. package/dist/app/mcp-app-view-states.js +55 -0
  95. package/dist/app/mcp-app-view-states.js.map +1 -0
  96. package/dist/app/mcp-app-view.d.ts +72 -5
  97. package/dist/app/mcp-app-view.d.ts.map +1 -1
  98. package/dist/app/mcp-app-view.js +241 -141
  99. package/dist/app/mcp-app-view.js.map +1 -1
  100. package/dist/app/mcp-toolkit-app.d.ts +8 -2
  101. package/dist/app/mcp-toolkit-app.d.ts.map +1 -1
  102. package/dist/app/mcp-toolkit-app.js +33 -4
  103. package/dist/app/mcp-toolkit-app.js.map +1 -1
  104. package/dist/app/mcp-use-host-bridge.d.ts +15 -6
  105. package/dist/app/mcp-use-host-bridge.d.ts.map +1 -1
  106. package/dist/app/mcp-use-host-bridge.js +51 -22
  107. package/dist/app/mcp-use-host-bridge.js.map +1 -1
  108. package/dist/app/model-context.d.ts +71 -0
  109. package/dist/app/model-context.d.ts.map +1 -0
  110. package/dist/app/model-context.js +101 -0
  111. package/dist/app/model-context.js.map +1 -0
  112. package/dist/app/use-build-mode-focus.d.ts +33 -0
  113. package/dist/app/use-build-mode-focus.d.ts.map +1 -0
  114. package/dist/app/use-build-mode-focus.js +59 -0
  115. package/dist/app/use-build-mode-focus.js.map +1 -0
  116. package/dist/app/use-view-actions.d.ts +31 -0
  117. package/dist/app/use-view-actions.d.ts.map +1 -0
  118. package/dist/app/use-view-actions.js +81 -0
  119. package/dist/app/use-view-actions.js.map +1 -0
  120. package/dist/app/use-view-lifecycle.d.ts +42 -0
  121. package/dist/app/use-view-lifecycle.d.ts.map +1 -0
  122. package/dist/app/use-view-lifecycle.js +81 -0
  123. package/dist/app/use-view-lifecycle.js.map +1 -0
  124. package/dist/app/view-lifecycle.d.ts +185 -0
  125. package/dist/app/view-lifecycle.d.ts.map +1 -0
  126. package/dist/app/view-lifecycle.js +207 -0
  127. package/dist/app/view-lifecycle.js.map +1 -0
  128. package/dist/app/widget-fixture.d.ts +10 -3
  129. package/dist/app/widget-fixture.d.ts.map +1 -1
  130. package/dist/app/widget-fixture.js +21 -8
  131. package/dist/app/widget-fixture.js.map +1 -1
  132. package/dist/app/widget-props-sheet.d.ts +6 -10
  133. package/dist/app/widget-props-sheet.d.ts.map +1 -1
  134. package/dist/app/widget-props-sheet.js +25 -20
  135. package/dist/app/widget-props-sheet.js.map +1 -1
  136. package/dist/app/widget-renderer.d.ts +41 -1
  137. package/dist/app/widget-renderer.d.ts.map +1 -1
  138. package/dist/app/widget-renderer.js +82 -31
  139. package/dist/app/widget-renderer.js.map +1 -1
  140. package/dist/components/DrillButton.d.ts +9 -6
  141. package/dist/components/DrillButton.d.ts.map +1 -1
  142. package/dist/components/DrillButton.js +9 -6
  143. package/dist/components/DrillButton.js.map +1 -1
  144. package/dist/components/EmptyState.d.ts +33 -0
  145. package/dist/components/EmptyState.d.ts.map +1 -0
  146. package/dist/components/EmptyState.js +19 -0
  147. package/dist/components/EmptyState.js.map +1 -0
  148. package/dist/components/ErrorState.d.ts +53 -0
  149. package/dist/components/ErrorState.d.ts.map +1 -0
  150. package/dist/components/ErrorState.js +77 -0
  151. package/dist/components/ErrorState.js.map +1 -0
  152. package/dist/components/FilterBar.d.ts +16 -5
  153. package/dist/components/FilterBar.d.ts.map +1 -1
  154. package/dist/components/FilterBar.js +13 -5
  155. package/dist/components/FilterBar.js.map +1 -1
  156. package/dist/components/GroupCard.d.ts.map +1 -1
  157. package/dist/components/GroupCard.js +2 -1
  158. package/dist/components/GroupCard.js.map +1 -1
  159. package/dist/components/KpiGrid.d.ts +70 -18
  160. package/dist/components/KpiGrid.d.ts.map +1 -1
  161. package/dist/components/KpiGrid.js +112 -23
  162. package/dist/components/KpiGrid.js.map +1 -1
  163. package/dist/components/ListFooter.d.ts +32 -4
  164. package/dist/components/ListFooter.d.ts.map +1 -1
  165. package/dist/components/ListFooter.js +35 -6
  166. package/dist/components/ListFooter.js.map +1 -1
  167. package/dist/components/PagedListFooter.d.ts +57 -0
  168. package/dist/components/PagedListFooter.d.ts.map +1 -0
  169. package/dist/components/PagedListFooter.js +27 -0
  170. package/dist/components/PagedListFooter.js.map +1 -0
  171. package/dist/components/Pills.d.ts +36 -12
  172. package/dist/components/Pills.d.ts.map +1 -1
  173. package/dist/components/Pills.js +29 -8
  174. package/dist/components/Pills.js.map +1 -1
  175. package/dist/components/SectionHeading.d.ts +3 -1
  176. package/dist/components/SectionHeading.d.ts.map +1 -1
  177. package/dist/components/SectionHeading.js +6 -2
  178. package/dist/components/SectionHeading.js.map +1 -1
  179. package/dist/components/Toast.d.ts +43 -0
  180. package/dist/components/Toast.d.ts.map +1 -0
  181. package/dist/components/Toast.js +106 -0
  182. package/dist/components/Toast.js.map +1 -0
  183. package/dist/components/WidgetHeader.d.ts +34 -10
  184. package/dist/components/WidgetHeader.d.ts.map +1 -1
  185. package/dist/components/WidgetHeader.js +11 -6
  186. package/dist/components/WidgetHeader.js.map +1 -1
  187. package/dist/hooks/index.d.ts +4 -4
  188. package/dist/hooks/index.d.ts.map +1 -1
  189. package/dist/hooks/index.js +1 -1
  190. package/dist/hooks/index.js.map +1 -1
  191. package/dist/hooks/tool-result-recovery-model.d.ts +155 -0
  192. package/dist/hooks/tool-result-recovery-model.d.ts.map +1 -0
  193. package/dist/hooks/tool-result-recovery-model.js +273 -0
  194. package/dist/hooks/tool-result-recovery-model.js.map +1 -0
  195. package/dist/hooks/use-tool-query.d.ts +56 -14
  196. package/dist/hooks/use-tool-query.d.ts.map +1 -1
  197. package/dist/hooks/use-tool-query.js +102 -25
  198. package/dist/hooks/use-tool-query.js.map +1 -1
  199. package/dist/hooks/use-tool-result-recovery.d.ts +61 -44
  200. package/dist/hooks/use-tool-result-recovery.d.ts.map +1 -1
  201. package/dist/hooks/use-tool-result-recovery.js +62 -110
  202. package/dist/hooks/use-tool-result-recovery.js.map +1 -1
  203. package/dist/hooks/use-view-data.d.ts +55 -7
  204. package/dist/hooks/use-view-data.d.ts.map +1 -1
  205. package/dist/hooks/use-view-data.js +81 -11
  206. package/dist/hooks/use-view-data.js.map +1 -1
  207. package/dist/hooks/use-view-tool-query.d.ts +12 -7
  208. package/dist/hooks/use-view-tool-query.d.ts.map +1 -1
  209. package/dist/hooks/use-view-tool-query.js +15 -14
  210. package/dist/hooks/use-view-tool-query.js.map +1 -1
  211. package/dist/index.d.ts +27 -13
  212. package/dist/index.d.ts.map +1 -1
  213. package/dist/index.js +29 -7
  214. package/dist/index.js.map +1 -1
  215. package/dist/lib/focus-return.d.ts +61 -0
  216. package/dist/lib/focus-return.d.ts.map +1 -0
  217. package/dist/lib/focus-return.js +46 -0
  218. package/dist/lib/focus-return.js.map +1 -0
  219. package/dist/lib/focus-ring.d.ts +18 -0
  220. package/dist/lib/focus-ring.d.ts.map +1 -0
  221. package/dist/lib/focus-ring.js +18 -0
  222. package/dist/lib/focus-ring.js.map +1 -0
  223. package/dist/lib/icon-stroke.d.ts +12 -0
  224. package/dist/lib/icon-stroke.d.ts.map +1 -0
  225. package/dist/lib/icon-stroke.js +12 -0
  226. package/dist/lib/icon-stroke.js.map +1 -0
  227. package/dist/lib/parse-tool-result.d.ts +23 -1
  228. package/dist/lib/parse-tool-result.d.ts.map +1 -1
  229. package/dist/lib/parse-tool-result.js +38 -2
  230. package/dist/lib/parse-tool-result.js.map +1 -1
  231. package/dist/lib/toast-model.d.ts +86 -0
  232. package/dist/lib/toast-model.d.ts.map +1 -0
  233. package/dist/lib/toast-model.js +102 -0
  234. package/dist/lib/toast-model.js.map +1 -0
  235. package/dist/lib/tone-utils.d.ts +95 -9
  236. package/dist/lib/tone-utils.d.ts.map +1 -1
  237. package/dist/lib/tone-utils.js +100 -9
  238. package/dist/lib/tone-utils.js.map +1 -1
  239. package/dist/lib/tool-query.d.ts +107 -0
  240. package/dist/lib/tool-query.d.ts.map +1 -0
  241. package/dist/lib/tool-query.js +182 -0
  242. package/dist/lib/tool-query.js.map +1 -0
  243. package/dist/lib/tool-result-observer.d.ts +108 -0
  244. package/dist/lib/tool-result-observer.d.ts.map +1 -0
  245. package/dist/lib/tool-result-observer.js +158 -0
  246. package/dist/lib/tool-result-observer.js.map +1 -0
  247. package/dist/lib/typography.d.ts +37 -0
  248. package/dist/lib/typography.d.ts.map +1 -0
  249. package/dist/lib/typography.js +41 -0
  250. package/dist/lib/typography.js.map +1 -0
  251. package/dist/lib/utils.d.ts.map +1 -1
  252. package/dist/lib/utils.js +11 -1
  253. package/dist/lib/utils.js.map +1 -1
  254. package/dist/locale/index.d.ts +3 -1
  255. package/dist/locale/index.d.ts.map +1 -1
  256. package/dist/locale/index.js +2 -1
  257. package/dist/locale/index.js.map +1 -1
  258. package/dist/locale/locale-provider.d.ts +42 -1
  259. package/dist/locale/locale-provider.d.ts.map +1 -1
  260. package/dist/locale/locale-provider.js +44 -3
  261. package/dist/locale/locale-provider.js.map +1 -1
  262. package/dist/locale/message-types.d.ts +336 -0
  263. package/dist/locale/message-types.d.ts.map +1 -0
  264. package/dist/locale/message-types.js +7 -0
  265. package/dist/locale/message-types.js.map +1 -0
  266. package/dist/locale/messages-de.d.ts +9 -0
  267. package/dist/locale/messages-de.d.ts.map +1 -0
  268. package/dist/locale/messages-de.js +185 -0
  269. package/dist/locale/messages-de.js.map +1 -0
  270. package/dist/locale/messages-en.d.ts +8 -0
  271. package/dist/locale/messages-en.d.ts.map +1 -0
  272. package/dist/locale/messages-en.js +184 -0
  273. package/dist/locale/messages-en.js.map +1 -0
  274. package/dist/locale/toolkit-messages.d.ts +57 -0
  275. package/dist/locale/toolkit-messages.d.ts.map +1 -0
  276. package/dist/locale/toolkit-messages.js +103 -0
  277. package/dist/locale/toolkit-messages.js.map +1 -0
  278. package/dist/primitives/alert.d.ts +1 -1
  279. package/dist/primitives/alert.d.ts.map +1 -1
  280. package/dist/primitives/alert.js +6 -2
  281. package/dist/primitives/alert.js.map +1 -1
  282. package/dist/primitives/badge.d.ts +1 -1
  283. package/dist/primitives/badge.d.ts.map +1 -1
  284. package/dist/primitives/badge.js +19 -6
  285. package/dist/primitives/badge.js.map +1 -1
  286. package/dist/primitives/button.d.ts +1 -1
  287. package/dist/primitives/button.d.ts.map +1 -1
  288. package/dist/primitives/button.js +12 -8
  289. package/dist/primitives/button.js.map +1 -1
  290. package/dist/primitives/card.js +4 -4
  291. package/dist/primitives/card.js.map +1 -1
  292. package/dist/primitives/dialog.d.ts +7 -3
  293. package/dist/primitives/dialog.d.ts.map +1 -1
  294. package/dist/primitives/dialog.js +22 -8
  295. package/dist/primitives/dialog.js.map +1 -1
  296. package/dist/primitives/input.d.ts.map +1 -1
  297. package/dist/primitives/input.js +4 -1
  298. package/dist/primitives/input.js.map +1 -1
  299. package/dist/primitives/scroll-area.js +1 -1
  300. package/dist/primitives/scroll-area.js.map +1 -1
  301. package/dist/primitives/select.d.ts.map +1 -1
  302. package/dist/primitives/select.js +6 -3
  303. package/dist/primitives/select.js.map +1 -1
  304. package/dist/primitives/sheet.d.ts +3 -1
  305. package/dist/primitives/sheet.d.ts.map +1 -1
  306. package/dist/primitives/sheet.js +17 -7
  307. package/dist/primitives/sheet.js.map +1 -1
  308. package/dist/primitives/skeleton.js +1 -1
  309. package/dist/primitives/skeleton.js.map +1 -1
  310. package/dist/primitives/switch.d.ts.map +1 -1
  311. package/dist/primitives/switch.js +2 -1
  312. package/dist/primitives/switch.js.map +1 -1
  313. package/dist/primitives/tabs.d.ts.map +1 -1
  314. package/dist/primitives/tabs.js +5 -3
  315. package/dist/primitives/tabs.js.map +1 -1
  316. package/dist/providers/query-provider.d.ts +32 -1
  317. package/dist/providers/query-provider.d.ts.map +1 -1
  318. package/dist/providers/query-provider.js +53 -4
  319. package/dist/providers/query-provider.js.map +1 -1
  320. package/dist/render-cases-primitives.js +1 -1
  321. package/dist/render-cases-primitives.js.map +1 -1
  322. package/dist/render-cases.d.ts.map +1 -1
  323. package/dist/render-cases.js +48 -6
  324. package/dist/render-cases.js.map +1 -1
  325. package/dist/render-effects.d.ts +42 -0
  326. package/dist/render-effects.d.ts.map +1 -0
  327. package/dist/render-effects.js +81 -0
  328. package/dist/render-effects.js.map +1 -0
  329. package/dist/render-scan.d.ts +25 -0
  330. package/dist/render-scan.d.ts.map +1 -0
  331. package/dist/render-scan.js +66 -0
  332. package/dist/render-scan.js.map +1 -0
  333. package/dist/theme/cd-tokens.d.ts +66 -0
  334. package/dist/theme/cd-tokens.d.ts.map +1 -0
  335. package/dist/theme/cd-tokens.js +64 -0
  336. package/dist/theme/cd-tokens.js.map +1 -0
  337. package/dist/theme/create-theme.d.ts +214 -39
  338. package/dist/theme/create-theme.d.ts.map +1 -1
  339. package/dist/theme/create-theme.js +204 -13
  340. package/dist/theme/create-theme.js.map +1 -1
  341. package/dist/theme/fonts.d.ts +38 -0
  342. package/dist/theme/fonts.d.ts.map +1 -0
  343. package/dist/theme/fonts.js +56 -0
  344. package/dist/theme/fonts.js.map +1 -0
  345. package/dist/theme/host-fonts.d.ts +39 -0
  346. package/dist/theme/host-fonts.d.ts.map +1 -0
  347. package/dist/theme/host-fonts.js +44 -0
  348. package/dist/theme/host-fonts.js.map +1 -0
  349. package/dist/theme/index.d.ts +8 -1
  350. package/dist/theme/index.d.ts.map +1 -1
  351. package/dist/theme/index.js +5 -1
  352. package/dist/theme/index.js.map +1 -1
  353. package/dist/theme/portal-container.d.ts +16 -0
  354. package/dist/theme/portal-container.d.ts.map +1 -0
  355. package/dist/theme/portal-container.js +19 -0
  356. package/dist/theme/portal-container.js.map +1 -0
  357. package/dist/theme/presets.d.ts +24 -9
  358. package/dist/theme/presets.d.ts.map +1 -1
  359. package/dist/theme/presets.js +44 -11
  360. package/dist/theme/presets.js.map +1 -1
  361. package/dist/theme/theme-provider.d.ts +27 -9
  362. package/dist/theme/theme-provider.d.ts.map +1 -1
  363. package/dist/theme/theme-provider.js +42 -20
  364. package/dist/theme/theme-provider.js.map +1 -1
  365. package/package.json +11 -5
  366. package/src/app/adapt-data-widget.tsx +2 -42
  367. package/src/app/builder/BuilderBanners.tsx +26 -13
  368. package/src/app/builder/CanvasRow.tsx +79 -32
  369. package/src/app/builder/CatalogueSheet.tsx +58 -35
  370. package/src/app/builder/CellPropsSheet.tsx +17 -2
  371. package/src/app/builder/DiscardDialog.tsx +59 -0
  372. package/src/app/builder/EmptyHint.tsx +16 -11
  373. package/src/app/builder/LayoutSurface.tsx +207 -67
  374. package/src/app/builder/PipelineStrip.tsx +265 -156
  375. package/src/app/builder/SaveDialog.tsx +25 -14
  376. package/src/app/builder/Toolbar.tsx +154 -57
  377. package/src/app/builder/Workspace.tsx +226 -56
  378. package/src/app/builder/builder-feedback.test.tsx +75 -0
  379. package/src/app/builder/builder-model.test.ts +5 -0
  380. package/src/app/builder/builder-model.ts +346 -6
  381. package/src/app/builder/builder-model.ux.test.ts +456 -0
  382. package/src/app/builder/builder-ux.test.tsx +844 -0
  383. package/src/app/builder/labels.ts +15 -121
  384. package/src/app/builder/reveal.ts +10 -0
  385. package/src/app/builder/status-chip.tsx +8 -4
  386. package/src/app/builder/use-builder-catalogue.ts +62 -19
  387. package/src/app/builder/use-builder-session.ts +68 -0
  388. package/src/app/builder/use-display-resolver.ts +24 -0
  389. package/src/app/builder/use-save-dashboard.ts +5 -0
  390. package/src/app/index.ts +20 -3
  391. package/src/app/layout-builder.tsx +193 -186
  392. package/src/app/mcp-app-view-chrome.test.tsx +487 -14
  393. package/src/app/mcp-app-view-chrome.tsx +328 -100
  394. package/src/app/mcp-app-view-states.tsx +140 -0
  395. package/src/app/mcp-app-view.effects.test.tsx +292 -0
  396. package/src/app/mcp-app-view.test.tsx +478 -0
  397. package/src/app/mcp-app-view.tsx +447 -190
  398. package/src/app/mcp-toolkit-app.test.tsx +40 -0
  399. package/src/app/mcp-toolkit-app.tsx +39 -8
  400. package/src/app/mcp-use-host-bridge.test.tsx +180 -0
  401. package/src/app/mcp-use-host-bridge.tsx +67 -24
  402. package/src/app/model-context.test.tsx +116 -0
  403. package/src/app/model-context.tsx +125 -0
  404. package/src/app/use-build-mode-focus.ts +62 -0
  405. package/src/app/use-view-actions.ts +89 -0
  406. package/src/app/use-view-lifecycle.ts +122 -0
  407. package/src/app/view-lifecycle.test.ts +443 -0
  408. package/src/app/view-lifecycle.ts +334 -0
  409. package/src/app/widget-fixture.effects.test.tsx +51 -0
  410. package/src/app/widget-fixture.render.test.tsx +81 -0
  411. package/src/app/widget-fixture.tsx +34 -11
  412. package/src/app/widget-props-sheet.tsx +67 -39
  413. package/src/app/widget-renderer.render.test.tsx +131 -0
  414. package/src/app/widget-renderer.tsx +136 -38
  415. package/src/components/DrillButton.tsx +24 -10
  416. package/src/components/EmptyState.tsx +83 -0
  417. package/src/components/ErrorState.tsx +204 -0
  418. package/src/components/FilterBar.test.tsx +82 -0
  419. package/src/components/FilterBar.tsx +56 -27
  420. package/src/components/GroupCard.tsx +3 -2
  421. package/src/components/KpiGrid.test.tsx +279 -0
  422. package/src/components/KpiGrid.tsx +329 -91
  423. package/src/components/ListFooter.test.tsx +116 -0
  424. package/src/components/ListFooter.tsx +110 -12
  425. package/src/components/PagedListFooter.test.tsx +140 -0
  426. package/src/components/PagedListFooter.tsx +107 -0
  427. package/src/components/Pills.test.tsx +77 -0
  428. package/src/components/Pills.tsx +78 -16
  429. package/src/components/SectionHeading.tsx +9 -3
  430. package/src/components/Toast.tsx +206 -0
  431. package/src/components/WidgetHeader.test.tsx +78 -0
  432. package/src/components/WidgetHeader.tsx +63 -16
  433. package/src/components/feedback-states.test.tsx +314 -0
  434. package/src/components/tone-figures.test.tsx +58 -0
  435. package/src/fonts.css +19 -0
  436. package/src/globals.css +9 -165
  437. package/src/hooks/index.ts +6 -3
  438. package/src/hooks/tool-result-recovery-model.test.ts +744 -0
  439. package/src/hooks/tool-result-recovery-model.ts +418 -0
  440. package/src/hooks/use-tool-query.effects.test.tsx +205 -0
  441. package/src/hooks/use-tool-query.ts +156 -33
  442. package/src/hooks/use-tool-result-recovery.effects.test.tsx +141 -0
  443. package/src/hooks/use-tool-result-recovery.test.ts +28 -5
  444. package/src/hooks/use-tool-result-recovery.ts +101 -131
  445. package/src/hooks/use-view-data.test.tsx +169 -0
  446. package/src/hooks/use-view-data.ts +131 -10
  447. package/src/hooks/use-view-tool-query.ts +25 -19
  448. package/src/i18n-coverage.test.tsx +425 -0
  449. package/src/index.ts +102 -13
  450. package/src/lib/focus-return.test.ts +288 -0
  451. package/src/lib/focus-return.ts +96 -0
  452. package/src/lib/focus-ring.ts +20 -0
  453. package/src/lib/icon-stroke.test.ts +59 -0
  454. package/src/lib/icon-stroke.ts +13 -0
  455. package/src/lib/parse-tool-result.test.ts +46 -1
  456. package/src/lib/parse-tool-result.ts +40 -2
  457. package/src/lib/toast-model.test.ts +233 -0
  458. package/src/lib/toast-model.ts +165 -0
  459. package/src/lib/tone-utils.test.ts +125 -16
  460. package/src/lib/tone-utils.ts +144 -15
  461. package/src/lib/tool-query.test.ts +569 -0
  462. package/src/lib/tool-query.ts +253 -0
  463. package/src/lib/tool-result-observer.test.ts +296 -0
  464. package/src/lib/tool-result-observer.ts +211 -0
  465. package/src/lib/typography.test.ts +45 -0
  466. package/src/lib/typography.ts +47 -0
  467. package/src/lib/utils.ts +12 -1
  468. package/src/locale/index.ts +14 -1
  469. package/src/locale/locale-provider.test.tsx +87 -0
  470. package/src/locale/locale-provider.tsx +90 -3
  471. package/src/locale/message-types.ts +337 -0
  472. package/src/locale/messages-de.ts +198 -0
  473. package/src/locale/messages-en.ts +196 -0
  474. package/src/locale/toolkit-messages.test.ts +349 -0
  475. package/src/locale/toolkit-messages.ts +143 -0
  476. package/src/no-hardcoded-copy.test.ts +432 -0
  477. package/src/primitives/alert.tsx +7 -2
  478. package/src/primitives/badge.tsx +19 -7
  479. package/src/primitives/button.tsx +13 -8
  480. package/src/primitives/card.tsx +4 -4
  481. package/src/primitives/dialog.tsx +42 -8
  482. package/src/primitives/input.tsx +5 -3
  483. package/src/primitives/scroll-area.tsx +1 -1
  484. package/src/primitives/select.tsx +7 -4
  485. package/src/primitives/sheet.tsx +33 -6
  486. package/src/primitives/skeleton.tsx +1 -1
  487. package/src/primitives/switch.tsx +4 -2
  488. package/src/primitives/tabs.tsx +9 -6
  489. package/src/providers/query-provider.test.tsx +154 -0
  490. package/src/providers/query-provider.tsx +66 -5
  491. package/src/render-cases-primitives.tsx +1 -1
  492. package/src/render-cases.tsx +82 -6
  493. package/src/render-effects.tsx +96 -0
  494. package/src/render-scan.ts +75 -0
  495. package/src/theme/cd-tokens.generated.css +48 -0
  496. package/src/theme/cd-tokens.test.ts +109 -0
  497. package/src/theme/cd-tokens.ts +67 -0
  498. package/src/theme/create-theme.test.ts +253 -5
  499. package/src/theme/create-theme.ts +341 -41
  500. package/src/theme/fonts.test.ts +85 -0
  501. package/src/theme/fonts.ts +72 -0
  502. package/src/theme/host-fonts.test.ts +135 -0
  503. package/src/theme/host-fonts.ts +52 -0
  504. package/src/theme/index.ts +15 -1
  505. package/src/theme/portal-container.ts +20 -0
  506. package/src/theme/presets.ts +44 -11
  507. package/src/theme/theme-css.test.ts +619 -0
  508. package/src/theme/theme-provider.test.tsx +82 -0
  509. package/src/theme/theme-provider.tsx +60 -24
  510. package/src/theme.css +344 -0
  511. package/ui-catalog.json +783 -49
@@ -1,47 +1,124 @@
1
- import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
2
- import { useCallTool } from "../providers/query-provider.js";
1
+ import { useCallback, useEffect, useRef } from "react";
2
+ import { hashKey, useMutation, useQuery, useQueryClient, } from "@tanstack/react-query";
3
+ import { useCallTool, useToolNameInQueryKey } from "../providers/query-provider.js";
3
4
  import { parseToolResult } from "../lib/parse-tool-result.js";
5
+ import { claimToolQueryKey, invalidateToolQueries, NoToolTransportError, settleEachCall, toolKeyCollisionMessage, toolQueryKey, toolQueryOptions, } from "../lib/tool-query.js";
6
+ /**
7
+ * The exact cache key `useToolQuery`, `useViewToolQuery` and `useViewData`
8
+ * use for this tool and args under the nearest `AppQueryProvider`:
9
+ * `toolQueryKey` with the provider's `toolNameInQueryKey` setting. For
10
+ * `getQueryData`, `setQueryData` or `cancelQueries({ exact: true })`; prefix
11
+ * invalidation needs only the caller's `queryKey`. A new array per render.
12
+ */
13
+ export function useToolQueryKey(queryKey, toolName, args) {
14
+ return toolQueryKey(queryKey, toolName, args, useToolNameInQueryKey());
15
+ }
16
+ /**
17
+ * Warns when two tools use one cache key (toolkit#176 K18): their answers
18
+ * would overwrite each other. Only the 2.x key can collide: with the tool
19
+ * name in the key (`toolNameInQueryKey`), two tools never share one.
20
+ */
21
+ export function useToolKeyGuard(queryKey, toolName, args) {
22
+ const client = useQueryClient();
23
+ const keyId = hashKey(useToolQueryKey(queryKey, toolName, args));
24
+ useEffect(() => {
25
+ const previous = claimToolQueryKey(client, keyId, toolName);
26
+ if (previous !== null)
27
+ console.warn(toolKeyCollisionMessage(keyId, toolName, previous));
28
+ }, [client, keyId, toolName]);
29
+ }
30
+ /**
31
+ * Fetches a query again once a tool transport arrives, when it failed for
32
+ * want of one ({@link NoToolTransportError}): a `callTool` that resolves
33
+ * after the first render. TanStack refetches on a new key or `enabled`,
34
+ * never on a new fetcher, so the query would keep the error until a remount.
35
+ */
36
+ export function useRefetchOnTransport(callTool, query) {
37
+ const { error, refetch } = query;
38
+ useEffect(() => {
39
+ if (callTool && error instanceof NoToolTransportError)
40
+ void refetch();
41
+ }, [callTool, error, refetch]);
42
+ }
4
43
  /**
5
44
  * Loads data from a widget tool via TanStack Query.
6
45
  *
7
- * `args` is appended to the effective query key so two callers that share
8
- * the supplied `queryKey` but pass different `args` get separate cache
9
- * entries (otherwise the second caller silently reads stale data from the
10
- * first — the classic queryKey-vs-args trap). `select` transforms data on
11
- * each read without mutating the cache.
46
+ * The effective cache key is `[...queryKey, args]` (`toolQueryKey`): two
47
+ * callers that share `queryKey` but pass different `args` get separate
48
+ * entries. Two tools must not share a key and args; the hook warns when they
49
+ * do. Under an `AppQueryProvider` with `toolNameInQueryKey` (opt-in in 2.x,
50
+ * the default from the next major) the key is `[...queryKey, toolName,
51
+ * args]` and two tools never collide; `useToolQueryKey` returns the key in
52
+ * force. `opts` passes TanStack's query options through (`retry`,
53
+ * `retryDelay`, `staleTime`, `placeholderData` / `keepPreviousData`,
54
+ * `initialData` + `initialDataUpdatedAt`, `enabled`, `select`, …), and the
55
+ * result exposes `refetch`, `failureCount` and `failureReason`. `retry`
56
+ * defaults to the client's; `retry: shouldRetryToolCall` stops retrying a
57
+ * tool's own `isError` answer.
58
+ *
59
+ * The tool goes through `AppQueryProvider`'s `callTool`, else the nearest
60
+ * `HostBridgeProvider`'s bridge; with neither, the query fails with a
61
+ * "no tool transport" error instead of idling, and fetches once one arrives.
12
62
  */
13
63
  export function useToolQuery(queryKey, toolName, args, opts) {
14
64
  const callTool = useCallTool();
15
- return useQuery({
16
- queryKey: [...queryKey, args],
17
- queryFn: async () => {
18
- if (!callTool)
19
- throw new Error("callTool not available");
20
- const result = await callTool(toolName, args);
21
- return parseToolResult(result);
22
- },
23
- select: opts?.select,
24
- enabled: !!callTool && (opts?.enabled ?? true),
25
- });
65
+ const toolNameInKey = useToolNameInQueryKey();
66
+ useToolKeyGuard(queryKey, toolName, args);
67
+ const query = useQuery(toolQueryOptions(queryKey, toolName, args, callTool, opts, {
68
+ toolNameInKey,
69
+ }));
70
+ useRefetchOnTransport(callTool, query);
71
+ return query;
26
72
  }
27
73
  /**
28
- * Executes a mutation via a widget tool and invalidates configured query keys.
74
+ * Executes a mutation via a widget tool and invalidates `invalidateKeys`
75
+ * after each successful call (`invalidateQueries`: active queries refetch,
76
+ * inactive ones are marked stale and refetch when they are next used).
77
+ *
78
+ * `mutate(args, { onSuccess, onError, onSettled })` fires its per-call
79
+ * callbacks for EVERY call while the component is mounted, not only for the
80
+ * latest one (TanStack's own rule), so two quick calls each get their
81
+ * confirmation. The hook-level callbacks in `opts` run first; the
82
+ * invalidation runs before the hook-level `onSuccess`.
29
83
  */
30
84
  export function useToolMutation(toolName, opts) {
31
85
  const callTool = useCallTool();
32
86
  const queryClient = useQueryClient();
33
- return useMutation({
87
+ const { invalidateKeys, onSuccess, ...options } = opts ?? {};
88
+ const mutation = useMutation({
89
+ ...options,
34
90
  mutationFn: async (args) => {
35
91
  if (!callTool)
36
- throw new Error("callTool not available");
92
+ throw new NoToolTransportError(toolName);
37
93
  const result = await callTool(toolName, args);
38
94
  return parseToolResult(result);
39
95
  },
40
- onSuccess: async () => {
41
- if (opts?.invalidateKeys) {
42
- await Promise.all(opts.invalidateKeys.map((key) => queryClient.refetchQueries({ queryKey: key })));
43
- }
96
+ onSuccess: async (data, variables, onMutateResult, context) => {
97
+ await invalidateToolQueries(queryClient, invalidateKeys);
98
+ await onSuccess?.(data, variables, onMutateResult, context);
44
99
  },
45
100
  });
101
+ // Per-call callbacks fire only while mounted (TanStack's rule, kept), with
102
+ // the latest meta/mutationKey. Both refs are written in effects and read
103
+ // only when a call settles, so `mutate` stays stable across renders.
104
+ const mounted = useRef(false);
105
+ const scope = useRef({
106
+ meta: undefined,
107
+ mutationKey: undefined,
108
+ });
109
+ useEffect(() => {
110
+ scope.current = { meta: options.meta, mutationKey: options.mutationKey };
111
+ });
112
+ useEffect(() => {
113
+ mounted.current = true;
114
+ return () => {
115
+ mounted.current = false;
116
+ };
117
+ }, []);
118
+ const { mutateAsync } = mutation;
119
+ const mutate = useCallback((variables, callbacks) => {
120
+ settleEachCall(mutateAsync(variables), variables, callbacks, () => mounted.current ? { client: queryClient, ...scope.current } : null);
121
+ }, [mutateAsync, queryClient]);
122
+ return { ...mutation, mutate };
46
123
  }
47
124
  //# sourceMappingURL=use-tool-query.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-tool-query.js","sourceRoot":"","sources":["../../src/hooks/use-tool-query.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAC7E,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAA;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAO7D;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAmB,EACnB,QAAgB,EAChB,IAAY,EACZ,IAA4C;IAE5C,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAE9B,OAAO,QAAQ,CAA0B;QACvC,QAAQ,EAAE,CAAC,GAAG,QAAQ,EAAE,IAAI,CAAC;QAC7B,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,CAAC,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;YACxD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;YAC7C,OAAO,eAAe,CAAQ,MAAM,CAAC,CAAA;QACvC,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,MAAM;QACpB,OAAO,EAAE,CAAC,CAAC,QAAQ,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI,IAAI,CAAC;KAC/C,CAAC,CAAA;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,IAAuC;IAEvC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,WAAW,GAAG,cAAc,EAAE,CAAA;IAEpC,OAAO,WAAW,CAAwC;QACxD,UAAU,EAAE,KAAK,EAAE,IAA6B,EAAE,EAAE;YAClD,IAAI,CAAC,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAA;YACxD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;YAC7C,OAAO,eAAe,CAAQ,MAAM,CAAC,CAAA;QACvC,CAAC;QACD,SAAS,EAAE,KAAK,IAAI,EAAE;YACpB,IAAI,IAAI,EAAE,cAAc,EAAE,CAAC;gBACzB,MAAM,OAAO,CAAC,GAAG,CACf,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,WAAW,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,CAChF,CAAA;YACH,CAAC;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC"}
1
+ {"version":3,"file":"use-tool-query.js","sourceRoot":"","sources":["../../src/hooks/use-tool-query.ts"],"names":[],"mappings":"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"}
@@ -1,45 +1,49 @@
1
+ import { type ToolResultObserver } from "../lib/tool-result-observer.js";
2
+ import { type RecoveryPolicy, type ToolResultRecoveryState } from "./tool-result-recovery-model.js";
3
+ export { decodeRecoveredResult } from "./tool-result-recovery-model.js";
4
+ export type { RecoveryBlockReason, RecoveryPolicy, ToolResultRecoveryState, ToolSafety, } from "./tool-result-recovery-model.js";
1
5
  /**
2
6
  * Recovery for hosts that deliver the `ui/notifications/tool-result`
3
7
  * notification without `structuredContent` (observed on claude.ai and Claude
4
- * Desktop, which forward only the model-facing `content` blocks). Since
5
- * mcp-use 2.x such a result is not even observable: the `useToolContext`
6
- * latch ignores content-only successes, so the tool status stays `"pending"`
7
- * forever and the shell would idle on its loading skeleton.
8
+ * Desktop, which forward only the model-facing `content` blocks). mcp-use
9
+ * 2.x's `useToolContext` latch ignores such a content-only result, so its
10
+ * status stays `"pending"` forever and the shell would idle on its skeleton.
8
11
  *
9
- * Because the stripped notification is invisible, readiness is inferred two
10
- * ways: the hard `resultReady` signal (the latch fired but the payload is
11
- * invalid), or a grace timer — once the originating tool is known and no
12
- * result has latched within
13
- * {@link ToolResultRecoveryOptions.assumeStrippedAfterMs}, the result is
14
- * assumed delivered-but-stripped. Either way the hook re-executes the
15
- * originating tool once via the host bridge's official `callTool` — tool-call
16
- * RESPONSES carry `structuredContent` intact on those hosts — and exposes the
17
- * decoded payload. Spec-conforming hosts (e.g. the mcp-use inspector) deliver
18
- * a valid payload up front, so the recovery never fires there.
12
+ * The hook re-executes the originating tool once via the host bridge's
13
+ * `callTool` — tool-call RESPONSES carry `structuredContent` intact on those
14
+ * hosts — and exposes the decoded payload. When it does so (toolkit#176):
19
15
  *
20
- * A call the host cancelled is never recovered: since mcp-use 2.7.1 the
21
- * cancellation latches as `status: "error"` (a `ToolCancelledError`), which
22
- * would otherwise count as a ready-but-invalid result — re-executing it would
23
- * override the user's decision to stop the call.
16
+ * - **Only when the host stripped the result.** A passive observer of the
17
+ * host's lifecycle notifications (`installToolResultObserver`) sees the
18
+ * content-only result itself, so the recovery fires as it arrives, and a
19
+ * slow tool on a compliant host is never re-run (K13): no result has
20
+ * arrived because none was sent. Where the observer cannot vouch for that
21
+ * (no browser frame, or installed after the handshake), the 2.x grace timer
22
+ * ({@link ToolResultRecoveryOptions.assumeStrippedAfterMs}) still infers a
23
+ * stripped result, once the call's arguments arrived.
24
+ * - **With the call's complete arguments** (N21): the observer's complete
25
+ * `tool-input`, never a partial stream; an equal re-delivery is the same run.
26
+ * - **Never for a cancelled or failed call:** re-running repeats the failure
27
+ * or overrides the user's stop; the shell renders that state and offers an
28
+ * explicit retry.
29
+ * - **Only for a tool the policy allows** ({@link ToolResultRecoveryOptions.policy}):
30
+ * by default never one the host reports as writing (`readOnlyHint: false`
31
+ * or `destructiveHint: true` in `hostContext.toolInfo.tool.annotations`).
32
+ * A blocked recovery is reported (`blocked`) so the view can show its error.
24
33
  *
25
- * Assumes the originating tool is a read-only render pipeline (true for all
26
- * toolkit `render-view`/`show_*` tools) — the re-execution must be safe to
27
- * repeat, and may rarely run concurrently with the original invocation when
28
- * the grace timer beats a slow but conforming host.
34
+ * The decision and its timer live in `createRecoveryController`; this hook
35
+ * only binds it to React.
29
36
  */
30
37
  /**
31
- * Default grace period before a silent latch counts as a stripped result.
32
- * Long enough for a conforming host to latch a typical render tool first,
33
- * short enough that users on stripping hosts are not left staring at the
34
- * skeleton noticeably.
38
+ * Default grace period before a silent latch counts as a stripped result —
39
+ * used only where the transport observer cannot vouch that nothing arrived.
35
40
  */
36
41
  export declare const DEFAULT_ASSUME_STRIPPED_AFTER_MS = 2500;
37
42
  export interface ToolResultRecoveryOptions {
38
43
  /**
39
44
  * The latch fired (`useToolContext().status !== "pending"`) — a structured
40
45
  * result, a tool error, or a host cancellation arrived. On hosts that strip
41
- * `structuredContent` this never turns true; the grace timer below covers
42
- * that case.
46
+ * `structuredContent` this never turns true.
43
47
  */
44
48
  resultReady: boolean;
45
49
  /**
@@ -48,12 +52,17 @@ export interface ToolResultRecoveryOptions {
48
52
  * attempt already in flight is dropped. Defaults to `false`.
49
53
  */
50
54
  cancelled?: boolean;
51
- /** The payload the host delivered (`useToolContext().toolOutput`). */
52
- props: unknown;
53
55
  /**
54
- * Validates a candidate payload. MUST be referentially stable (module-level
55
- * function or memoised) — it is an effect dependency.
56
+ * The originating call latched a tool error (`useToolContext().status ===
57
+ * "error"` without a cancellation): an `isError` result or a failed call.
58
+ * Suppresses the recovery exactly like {@link cancelled} — the shell shows
59
+ * the error instead of silently re-running a call that just failed
60
+ * (toolkit#176). Defaults to `false`.
56
61
  */
62
+ errored?: boolean;
63
+ /** The payload the host delivered (`useToolContext().toolOutput`). */
64
+ props: unknown;
65
+ /** Validates a candidate payload. */
57
66
  isValid: (value: unknown) => boolean;
58
67
  /** The tool arguments from `ui/notifications/tool-input` (`useToolContext().toolInput`). */
59
68
  toolInput: Record<string, unknown> | null | undefined;
@@ -63,18 +72,19 @@ export interface ToolResultRecoveryOptions {
63
72
  callTool: (name: string, args: Record<string, unknown>) => Promise<unknown>;
64
73
  /**
65
74
  * Grace period in ms after which a silent latch counts as a stripped
66
- * result. Armed once the originating tool is known while `resultReady` is
67
- * still false; re-armed on every `toolInput` update, because streaming
68
- * arguments mean the invocation may not have finished yet. Defaults to
75
+ * result. Applies only where the transport observer cannot vouch that no
76
+ * result arrived (see above); restarts for new arguments. Defaults to
69
77
  * {@link DEFAULT_ASSUME_STRIPPED_AFTER_MS}.
70
78
  */
71
79
  assumeStrippedAfterMs?: number;
72
- }
73
- export interface ToolResultRecoveryState<T> {
74
- /** The recovered payload, `null` until the re-execution resolved (or when it failed). */
75
- data: T | null;
76
- /** `true` when the single recovery attempt failed — the shell keeps its skeleton, no retry loop. */
77
- failed: boolean;
80
+ /** Which tools may be re-executed on their own. Default `"auto"`. */
81
+ policy?: RecoveryPolicy;
82
+ /**
83
+ * The transport observer. Defaults to the document's
84
+ * (`installToolResultObserver()`); `null` disables it, leaving the grace
85
+ * timer to decide alone (the 2.x behaviour).
86
+ */
87
+ observer?: ToolResultObserver | null;
78
88
  }
79
89
  /**
80
90
  * Resolves the originating tool name from the host context's `toolInfo`.
@@ -83,9 +93,16 @@ export interface ToolResultRecoveryState<T> {
83
93
  */
84
94
  export declare function resolveRecoveryToolName(hostContext: unknown): string | undefined;
85
95
  /**
86
- * Decodes a re-executed tool result and validates it. Exposed for tests;
87
- * the hook uses it on the `callTool` response.
96
+ * Whether a latched or assumed-stripped result may be recovered at all: the
97
+ * call was neither cancelled nor failed. Kept for existing imports; the full
98
+ * rule (observer, policy, arguments) is `decideRecovery`.
99
+ * @deprecated Use `decideRecovery` from the recovery model.
88
100
  */
89
- export declare function decodeRecoveredResult<T>(result: unknown, isValid: (value: unknown) => boolean): T | null;
101
+ export declare function isRecoveryReady(state: {
102
+ resultReady: boolean;
103
+ assumedReady: boolean;
104
+ cancelled: boolean;
105
+ errored: boolean;
106
+ }): boolean;
90
107
  export declare function useToolResultRecovery<T>(options: ToolResultRecoveryOptions): ToolResultRecoveryState<T>;
91
108
  //# sourceMappingURL=use-tool-result-recovery.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-tool-result-recovery.d.ts","sourceRoot":"","sources":["../../src/hooks/use-tool-result-recovery.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,OAAO,CAAA;AAEpD,MAAM,WAAW,yBAAyB;IACxC;;;;;OAKG;IACH,WAAW,EAAE,OAAO,CAAA;IACpB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,sEAAsE;IACtE,KAAK,EAAE,OAAO,CAAA;IACd;;;OAGG;IACH,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAA;IACpC,4FAA4F;IAC5F,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAAA;IACrD,gGAAgG;IAChG,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAAA;IACvD,oCAAoC;IACpC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3E;;;;;;OAMG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,uBAAuB,CAAC,CAAC;IACxC,yFAAyF;IACzF,IAAI,EAAE,CAAC,GAAG,IAAI,CAAA;IACd,oGAAoG;IACpG,MAAM,EAAE,OAAO,CAAA;CAChB;AAID;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAehF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GACnC,CAAC,GAAG,IAAI,CAQV;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,OAAO,EAAE,yBAAyB,GACjC,uBAAuB,CAAC,CAAC,CAAC,CAsF5B"}
1
+ {"version":3,"file":"use-tool-result-recovery.d.ts","sourceRoot":"","sources":["../../src/hooks/use-tool-result-recovery.ts"],"names":[],"mappings":"AACA,OAAO,EAA6B,KAAK,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AACnG,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC7B,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AACvE,YAAY,EACV,mBAAmB,EACnB,cAAc,EACd,uBAAuB,EACvB,UAAU,GACX,MAAM,iCAAiC,CAAA;AAExC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH;;;GAGG;AACH,eAAO,MAAM,gCAAgC,OAAO,CAAA;AAEpD,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,WAAW,EAAE,OAAO,CAAA;IACpB;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,sEAAsE;IACtE,KAAK,EAAE,OAAO,CAAA;IACd,qCAAqC;IACrC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAA;IACpC,4FAA4F;IAC5F,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAAA;IACrD,gGAAgG;IAChG,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,GAAG,SAAS,CAAA;IACvD,oCAAoC;IACpC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3E;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,qEAAqE;IACrE,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAA;CACrC;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAehF;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,WAAW,EAAE,OAAO,CAAA;IACpB,YAAY,EAAE,OAAO,CAAA;IACrB,SAAS,EAAE,OAAO,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;CACjB,GAAG,OAAO,CAGV;AAED,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,OAAO,EAAE,yBAAyB,GACjC,uBAAuB,CAAC,CAAC,CAAC,CAyC5B"}
@@ -1,42 +1,44 @@
1
- import { useEffect, useRef, useState } from "react";
2
- import { parseToolResult } from "../lib/parse-tool-result.js";
1
+ import { useEffect, useState, useSyncExternalStore } from "react";
2
+ import { installToolResultObserver } from "../lib/tool-result-observer.js";
3
+ import { createRecoveryController, } from "./tool-result-recovery-model.js";
4
+ export { decodeRecoveredResult } from "./tool-result-recovery-model.js";
3
5
  /**
4
6
  * Recovery for hosts that deliver the `ui/notifications/tool-result`
5
7
  * notification without `structuredContent` (observed on claude.ai and Claude
6
- * Desktop, which forward only the model-facing `content` blocks). Since
7
- * mcp-use 2.x such a result is not even observable: the `useToolContext`
8
- * latch ignores content-only successes, so the tool status stays `"pending"`
9
- * forever and the shell would idle on its loading skeleton.
8
+ * Desktop, which forward only the model-facing `content` blocks). mcp-use
9
+ * 2.x's `useToolContext` latch ignores such a content-only result, so its
10
+ * status stays `"pending"` forever and the shell would idle on its skeleton.
10
11
  *
11
- * Because the stripped notification is invisible, readiness is inferred two
12
- * ways: the hard `resultReady` signal (the latch fired but the payload is
13
- * invalid), or a grace timer — once the originating tool is known and no
14
- * result has latched within
15
- * {@link ToolResultRecoveryOptions.assumeStrippedAfterMs}, the result is
16
- * assumed delivered-but-stripped. Either way the hook re-executes the
17
- * originating tool once via the host bridge's official `callTool` — tool-call
18
- * RESPONSES carry `structuredContent` intact on those hosts — and exposes the
19
- * decoded payload. Spec-conforming hosts (e.g. the mcp-use inspector) deliver
20
- * a valid payload up front, so the recovery never fires there.
12
+ * The hook re-executes the originating tool once via the host bridge's
13
+ * `callTool` — tool-call RESPONSES carry `structuredContent` intact on those
14
+ * hosts — and exposes the decoded payload. When it does so (toolkit#176):
21
15
  *
22
- * A call the host cancelled is never recovered: since mcp-use 2.7.1 the
23
- * cancellation latches as `status: "error"` (a `ToolCancelledError`), which
24
- * would otherwise count as a ready-but-invalid result — re-executing it would
25
- * override the user's decision to stop the call.
16
+ * - **Only when the host stripped the result.** A passive observer of the
17
+ * host's lifecycle notifications (`installToolResultObserver`) sees the
18
+ * content-only result itself, so the recovery fires as it arrives, and a
19
+ * slow tool on a compliant host is never re-run (K13): no result has
20
+ * arrived because none was sent. Where the observer cannot vouch for that
21
+ * (no browser frame, or installed after the handshake), the 2.x grace timer
22
+ * ({@link ToolResultRecoveryOptions.assumeStrippedAfterMs}) still infers a
23
+ * stripped result, once the call's arguments arrived.
24
+ * - **With the call's complete arguments** (N21): the observer's complete
25
+ * `tool-input`, never a partial stream; an equal re-delivery is the same run.
26
+ * - **Never for a cancelled or failed call:** re-running repeats the failure
27
+ * or overrides the user's stop; the shell renders that state and offers an
28
+ * explicit retry.
29
+ * - **Only for a tool the policy allows** ({@link ToolResultRecoveryOptions.policy}):
30
+ * by default never one the host reports as writing (`readOnlyHint: false`
31
+ * or `destructiveHint: true` in `hostContext.toolInfo.tool.annotations`).
32
+ * A blocked recovery is reported (`blocked`) so the view can show its error.
26
33
  *
27
- * Assumes the originating tool is a read-only render pipeline (true for all
28
- * toolkit `render-view`/`show_*` tools) — the re-execution must be safe to
29
- * repeat, and may rarely run concurrently with the original invocation when
30
- * the grace timer beats a slow but conforming host.
34
+ * The decision and its timer live in `createRecoveryController`; this hook
35
+ * only binds it to React.
31
36
  */
32
37
  /**
33
- * Default grace period before a silent latch counts as a stripped result.
34
- * Long enough for a conforming host to latch a typical render tool first,
35
- * short enough that users on stripping hosts are not left staring at the
36
- * skeleton noticeably.
38
+ * Default grace period before a silent latch counts as a stripped result —
39
+ * used only where the transport observer cannot vouch that nothing arrived.
37
40
  */
38
41
  export const DEFAULT_ASSUME_STRIPPED_AFTER_MS = 2500;
39
- const IDLE = { data: null, failed: false };
40
42
  /**
41
43
  * Resolves the originating tool name from the host context's `toolInfo`.
42
44
  * Reads the SEP-1865 shape first (`toolInfo.tool.name`), then the flattened
@@ -62,92 +64,42 @@ export function resolveRecoveryToolName(hostContext) {
62
64
  return undefined;
63
65
  }
64
66
  /**
65
- * Decodes a re-executed tool result and validates it. Exposed for tests;
66
- * the hook uses it on the `callTool` response.
67
+ * Whether a latched or assumed-stripped result may be recovered at all: the
68
+ * call was neither cancelled nor failed. Kept for existing imports; the full
69
+ * rule (observer, policy, arguments) is `decideRecovery`.
70
+ * @deprecated Use `decideRecovery` from the recovery model.
67
71
  */
68
- export function decodeRecoveredResult(result, isValid) {
69
- let decoded;
70
- try {
71
- decoded = parseToolResult(result);
72
- }
73
- catch {
74
- return null;
75
- }
76
- return decoded !== null && isValid(decoded) ? decoded : null;
72
+ export function isRecoveryReady(state) {
73
+ if (state.cancelled || state.errored)
74
+ return false;
75
+ return state.resultReady || state.assumedReady;
77
76
  }
78
77
  export function useToolResultRecovery(options) {
79
- const { resultReady, cancelled = false, props, isValid, toolInput, hostContext, callTool, assumeStrippedAfterMs = DEFAULT_ASSUME_STRIPPED_AFTER_MS, } = options;
80
- const [state, setState] = useState(IDLE);
81
- // Single-flight: the promise ref survives StrictMode's dev-mode
82
- // effect re-run (cleanup + setup on the same instance), so the re-run
83
- // re-subscribes to the SAME in-flight call instead of firing a second one.
84
- const flightRef = useRef(null);
85
- const flightInputRef = useRef(null);
86
- const toolName = resolveRecoveryToolName(hostContext);
87
- // A stripped result is unobservable (the 2.x latch ignores content-only
88
- // results), so infer it: once a recovery could fire but the latch has been
89
- // silent for the grace period, treat the result as delivered-but-stripped.
90
- // Re-armed on every toolInput identity change — streaming arguments mean
91
- // the invocation may still be running, so the grace period starts over.
92
- // The re-arm is a render-phase reset (not an effect) so the cascading-
93
- // render lint stays satisfied; the timer effect below restarts anyway
94
- // because toolInput is one of its dependencies.
95
- const [assumedReady, setAssumedReady] = useState(false);
96
- const [prevTimerInput, setPrevTimerInput] = useState(toolInput);
97
- if (prevTimerInput !== toolInput) {
98
- setPrevTimerInput(toolInput);
99
- if (assumedReady)
100
- setAssumedReady(false);
101
- }
78
+ const { resultReady, cancelled = false, errored = false, props, isValid, toolInput, hostContext, callTool, assumeStrippedAfterMs = DEFAULT_ASSUME_STRIPPED_AFTER_MS, policy = "auto", observer, } = options;
79
+ // One controller per mount; it survives StrictMode's effect re-run, so an
80
+ // in-flight call is never fired twice.
81
+ const [controller] = useState(() => createRecoveryController({
82
+ observer: observer === undefined ? installToolResultObserver() : observer,
83
+ }));
102
84
  useEffect(() => {
103
- if (resultReady || cancelled || toolName === undefined)
104
- return;
105
- const timer = setTimeout(() => setAssumedReady(true), assumeStrippedAfterMs);
106
- return () => clearTimeout(timer);
107
- }, [resultReady, cancelled, toolName, toolInput, assumeStrippedAfterMs]);
108
- // A cancelled call never counts as ready, so the effect below invalidates
109
- // any in-flight attempt the same way it does for a superseded run.
110
- const ready = !cancelled && (resultReady || assumedReady);
85
+ controller.start();
86
+ return () => controller.stop();
87
+ }, [controller]);
111
88
  useEffect(() => {
112
- // A new tool run (result no longer ready, or fresh tool-input identity)
113
- // invalidates any previous recovery attempt and re-arms the single-flight.
114
- if (flightRef.current && (!ready || flightInputRef.current !== toolInput)) {
115
- flightRef.current = null;
116
- setState((prev) => (prev.data === null && !prev.failed ? prev : IDLE));
117
- }
118
- // Never fire on conforming hosts (valid payload) or before the
119
- // originating tool is known.
120
- if (!ready || isValid(props) || toolName === undefined)
121
- return;
122
- if (!flightRef.current) {
123
- flightInputRef.current = toolInput;
124
- flightRef.current = (async () => {
125
- try {
126
- const result = await callTool(toolName, toolInput ?? {});
127
- const data = decodeRecoveredResult(result, isValid);
128
- if (data !== null)
129
- return { data, failed: false };
130
- console.warn(`[mcp-toolkit] tool-result recovery: re-executing "${toolName}" returned no usable payload`);
131
- return { data: null, failed: true };
132
- }
133
- catch (err) {
134
- console.warn(`[mcp-toolkit] tool-result recovery for "${toolName}" failed:`, err);
135
- return { data: null, failed: true };
136
- }
137
- })();
138
- }
139
- const flight = flightRef.current;
140
- let stale = false;
141
- void flight.then((outcome) => {
142
- // Drop the outcome when this subscription was superseded or the flight
143
- // was invalidated by a newer tool run.
144
- if (!stale && flightRef.current === flight)
145
- setState(outcome);
89
+ controller.update({
90
+ resultReady,
91
+ cancelled,
92
+ errored,
93
+ props,
94
+ isValid,
95
+ toolInput,
96
+ hostContext,
97
+ callTool,
98
+ policy,
99
+ graceMs: assumeStrippedAfterMs,
100
+ resolveToolName: resolveRecoveryToolName,
146
101
  });
147
- return () => {
148
- stale = true;
149
- };
150
- }, [ready, props, isValid, toolName, toolInput, callTool]);
151
- return state;
102
+ });
103
+ return useSyncExternalStore(controller.subscribe, controller.getState, controller.getState);
152
104
  }
153
105
  //# sourceMappingURL=use-tool-result-recovery.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-tool-result-recovery.js","sourceRoot":"","sources":["../../src/hooks/use-tool-result-recovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,IAAI,CAAA;AA8CpD,MAAM,IAAI,GAAmC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;AAE1E;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,WAAoB;IAC1D,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IACrE,MAAM,IAAI,GAAI,WAAuC,CAAC,QAAQ,CAAA;IAC9D,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IACvD,MAAM,GAAG,GAAG,IAA+B,CAAA;IAC3C,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAA;IACrB,MAAM,UAAU,GAAG;QACjB,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAgC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QACrF,GAAG,CAAC,IAAI;QACR,GAAG,CAAC,QAAQ;KACb,CAAA;IACD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,SAAS,CAAA;IAC7E,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAe,EACf,OAAoC;IAEpC,IAAI,OAAgB,CAAA;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,eAAe,CAAU,MAAM,CAAC,CAAA;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,OAAO,KAAK,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAE,OAAa,CAAC,CAAC,CAAC,IAAI,CAAA;AACrE,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,OAAkC;IAElC,MAAM,EACJ,WAAW,EACX,SAAS,GAAG,KAAK,EACjB,KAAK,EACL,OAAO,EACP,SAAS,EACT,WAAW,EACX,QAAQ,EACR,qBAAqB,GAAG,gCAAgC,GACzD,GAAG,OAAO,CAAA;IACX,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAA6B,IAAI,CAAC,CAAA;IACpE,gEAAgE;IAChE,sEAAsE;IACtE,2EAA2E;IAC3E,MAAM,SAAS,GAAG,MAAM,CAA6C,IAAI,CAAC,CAAA;IAC1E,MAAM,cAAc,GAAG,MAAM,CAAU,IAAI,CAAC,CAAA;IAE5C,MAAM,QAAQ,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAA;IAErD,wEAAwE;IACxE,2EAA2E;IAC3E,2EAA2E;IAC3E,yEAAyE;IACzE,wEAAwE;IACxE,uEAAuE;IACvE,sEAAsE;IACtE,gDAAgD;IAChD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACvD,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAU,SAAS,CAAC,CAAA;IACxE,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;QACjC,iBAAiB,CAAC,SAAS,CAAC,CAAA;QAC5B,IAAI,YAAY;YAAE,eAAe,CAAC,KAAK,CAAC,CAAA;IAC1C,CAAC;IACD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,WAAW,IAAI,SAAS,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAM;QAC9D,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,qBAAqB,CAAC,CAAA;QAC5E,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAA;IAClC,CAAC,EAAE,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,qBAAqB,CAAC,CAAC,CAAA;IAExE,0EAA0E;IAC1E,mEAAmE;IACnE,MAAM,KAAK,GAAG,CAAC,SAAS,IAAI,CAAC,WAAW,IAAI,YAAY,CAAC,CAAA;IAEzD,SAAS,CAAC,GAAG,EAAE;QACb,wEAAwE;QACxE,2EAA2E;QAC3E,IAAI,SAAS,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,cAAc,CAAC,OAAO,KAAK,SAAS,CAAC,EAAE,CAAC;YAC1E,SAAS,CAAC,OAAO,GAAG,IAAI,CAAA;YACxB,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;QACxE,CAAC;QACD,+DAA+D;QAC/D,6BAA6B;QAC7B,IAAI,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAM;QAE9D,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;YACvB,cAAc,CAAC,OAAO,GAAG,SAAS,CAAA;YAClC,SAAS,CAAC,OAAO,GAAG,CAAC,KAAK,IAAyC,EAAE;gBACnE,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,SAAS,IAAI,EAAE,CAAC,CAAA;oBACxD,MAAM,IAAI,GAAG,qBAAqB,CAAI,MAAM,EAAE,OAAO,CAAC,CAAA;oBACtD,IAAI,IAAI,KAAK,IAAI;wBAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;oBACjD,OAAO,CAAC,IAAI,CACV,qDAAqD,QAAQ,8BAA8B,CAC5F,CAAA;oBACD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;gBACrC,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,IAAI,CAAC,2CAA2C,QAAQ,WAAW,EAAE,GAAG,CAAC,CAAA;oBACjF,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAA;gBACrC,CAAC;YACH,CAAC,CAAC,EAAE,CAAA;QACN,CAAC;QAED,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,CAAA;QAChC,IAAI,KAAK,GAAG,KAAK,CAAA;QACjB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;YAC3B,uEAAuE;YACvE,uCAAuC;YACvC,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC,OAAO,KAAK,MAAM;gBAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;QAC/D,CAAC,CAAC,CAAA;QACF,OAAO,GAAG,EAAE;YACV,KAAK,GAAG,IAAI,CAAA;QACd,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAA;IAE1D,OAAO,KAAK,CAAA;AACd,CAAC"}
1
+ {"version":3,"file":"use-tool-result-recovery.js","sourceRoot":"","sources":["../../src/hooks/use-tool-result-recovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,OAAO,CAAA;AACjE,OAAO,EAAE,yBAAyB,EAA2B,MAAM,gCAAgC,CAAA;AACnG,OAAO,EACL,wBAAwB,GAGzB,MAAM,iCAAiC,CAAA;AAExC,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAA;AAQvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,IAAI,CAAA;AAkDpD;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,WAAoB;IAC1D,IAAI,CAAC,WAAW,IAAI,OAAO,WAAW,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IACrE,MAAM,IAAI,GAAI,WAAuC,CAAC,QAAQ,CAAA;IAC9D,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAA;IACvD,MAAM,GAAG,GAAG,IAA+B,CAAA;IAC3C,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAA;IACrB,MAAM,UAAU,GAAG;QACjB,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAE,IAAgC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QACrF,GAAG,CAAC,IAAI;QACR,GAAG,CAAC,QAAQ;KACb,CAAA;IACD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,SAAS,CAAA;IAC7E,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,KAK/B;IACC,IAAI,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO;QAAE,OAAO,KAAK,CAAA;IAClD,OAAO,KAAK,CAAC,WAAW,IAAI,KAAK,CAAC,YAAY,CAAA;AAChD,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,OAAkC;IAElC,MAAM,EACJ,WAAW,EACX,SAAS,GAAG,KAAK,EACjB,OAAO,GAAG,KAAK,EACf,KAAK,EACL,OAAO,EACP,SAAS,EACT,WAAW,EACX,QAAQ,EACR,qBAAqB,GAAG,gCAAgC,EACxD,MAAM,GAAG,MAAM,EACf,QAAQ,GACT,GAAG,OAAO,CAAA;IACX,0EAA0E;IAC1E,uCAAuC;IACvC,MAAM,CAAC,UAAU,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CACjC,wBAAwB,CAAI;QAC1B,QAAQ,EAAE,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,yBAAyB,EAAE,CAAC,CAAC,CAAC,QAAQ;KAC1E,CAAC,CACH,CAAA;IACD,SAAS,CAAC,GAAG,EAAE;QACb,UAAU,CAAC,KAAK,EAAE,CAAA;QAClB,OAAO,GAAG,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,CAAA;IAChC,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAA;IAChB,SAAS,CAAC,GAAG,EAAE;QACb,UAAU,CAAC,MAAM,CAAC;YAChB,WAAW;YACX,SAAS;YACT,OAAO;YACP,KAAK;YACL,OAAO;YACP,SAAS;YACT,WAAW;YACX,QAAQ;YACR,MAAM;YACN,OAAO,EAAE,qBAAqB;YAC9B,eAAe,EAAE,uBAAuB;SACzC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IACF,OAAO,oBAAoB,CAAC,UAAU,CAAC,SAAS,EAAE,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;AAC7F,CAAC"}