@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
@@ -4,130 +4,24 @@
4
4
  * Extracted from `layout-builder.tsx` so the presentational sub-components
5
5
  * (Toolbar, PipelineStrip, Workspace, CatalogueSheet, SaveDialog, PreviewPane)
6
6
  * can depend on the labels without importing the orchestrating container —
7
- * which would create an import cycle. React-free and `mcp-use`-free.
7
+ * which would create an import cycle. React-free and `mcp-use`-free. The
8
+ * strings themselves live in the toolkit catalog (`locale/messages-*.ts`).
8
9
  */
9
10
 
10
- export interface LayoutBuilderLabels {
11
- title?: string
12
- builderBadge?: string
13
- previewBadge?: string
14
- catalogue?: string
15
- save?: string
16
- done?: string
17
- viewLayoutTab?: string
18
- viewPipelineTab?: string
19
- viewPreviewTab?: string
20
- saveDialogTitle?: string
21
- saveDialogDescription?: string
22
- saveNameLabel?: string
23
- saveDescriptionLabel?: string
24
- saveConfirm?: string
25
- cancel?: string
26
- pipelineHeader?: string
27
- keysHeader?: string
28
- stepsHeader?: string
29
- keyName?: string
30
- keyValue?: string
31
- stepContextId?: string
32
- stepPickerLabel?: string
33
- addKey?: string
34
- addStep?: string
35
- emptyKeys?: string
36
- emptySteps?: string
37
- statusUpToDate?: string
38
- statusPending?: string
39
- statusRefreshing?: string
40
- paletteHeader?: string
41
- paletteEmpty?: string
42
- canvasEmpty?: string
43
- canvasDropHint?: string
44
- addRow?: string
45
- addTab?: string
46
- removeRow?: string
47
- renameTab?: string
48
- removeTab?: string
49
- tabsLabel?: string
50
- catalogueDescription?: string
51
- catalogueKeys?: string
52
- catalogueSteps?: string
53
- catalogueUnreachable?: string
54
- catalogueUnreachableEmpty?: string
55
- catalogueProducedBy?: string
56
- catalogueConsumedBy?: string
57
- catalogueNeedsKeys?: string
58
- cataloguePickKey?: string
59
- catalogueAddProducingStep?: string
60
- catalogueLive?: string
61
- catalogueMissing?: string
62
- /** Banner shown when the catalogue fetch fails (prefixes the reason). */
63
- catalogueError?: string
64
- /** Heading for the pipeline-validation warning banner. */
65
- validationWarning?: string
66
- /** Inline message when a save fails (prefixes the reason). */
67
- saveError?: string
68
- /** Inline message when a tab rename is rejected (duplicate label). */
69
- renameDuplicate?: string
70
- }
11
+ import { TOOLKIT_MESSAGES, type BuilderMessages } from "../../locale/toolkit-messages.js"
71
12
 
72
- export const DEFAULT_LABELS: Required<LayoutBuilderLabels> = {
73
- title: "View Builder",
74
- builderBadge: "Builder",
75
- previewBadge: "Preview",
76
- catalogue: "Catalogue",
77
- save: "Save",
78
- done: "Done",
79
- viewLayoutTab: "Layout",
80
- viewPipelineTab: "Pipeline",
81
- viewPreviewTab: "Preview",
82
- saveDialogTitle: "Save dashboard",
83
- saveDialogDescription:
84
- "Persists the current layout along with the keys and steps that populate it.",
85
- saveNameLabel: "Name",
86
- saveDescriptionLabel: "Description",
87
- saveConfirm: "Save dashboard",
88
- cancel: "Cancel",
89
- pipelineHeader: "Pipeline",
90
- keysHeader: "Keys",
91
- stepsHeader: "Steps",
92
- keyName: "key",
93
- keyValue: 'value, "literal", true, {…}',
94
- stepContextId: "ctx id",
95
- stepPickerLabel: "pick a step",
96
- addKey: "Add key",
97
- addStep: "Add step",
98
- emptyKeys: "No keys seeded.",
99
- emptySteps: "No steps configured.",
100
- statusUpToDate: "Up to date",
101
- statusPending: "Applying soon…",
102
- statusRefreshing: "Applying…",
103
- paletteHeader: "Palette",
104
- paletteEmpty: "No widgets reachable yet — seed a key or add a step.",
105
- canvasEmpty: "Drag a widget here, or click one in the palette.",
106
- canvasDropHint: "Drop to add",
107
- addRow: "Add row",
108
- addTab: "Add tab",
109
- removeRow: "Remove row",
110
- renameTab: "Rename tab",
111
- removeTab: "Remove tab",
112
- tabsLabel: "Tabs",
113
- catalogueDescription:
114
- "Every key and widget the framework knows about, whether or not it's reachable right now.",
115
- catalogueKeys: "Keys",
116
- catalogueSteps: "Steps",
117
- catalogueUnreachable: "Unreachable widgets",
118
- catalogueUnreachableEmpty: "Every registered widget is reachable.",
119
- catalogueProducedBy: "produced by",
120
- catalogueConsumedBy: "consumed by",
121
- catalogueNeedsKeys: "needs",
122
- cataloguePickKey: "Add as key",
123
- catalogueAddProducingStep: "Add producing step",
124
- catalogueLive: "live",
125
- catalogueMissing: "missing",
126
- catalogueError: "Couldn't refresh the builder catalogue",
127
- validationWarning: "This pipeline won't render as configured",
128
- saveError: "Couldn't save",
129
- renameDuplicate: "A tab with that name already exists.",
130
- }
13
+ /**
14
+ * Override strings for every user-facing caption in the builder. Each field
15
+ * defaults to the active locale's toolkit catalog (`useToolkitMessages().builder`).
16
+ */
17
+ export type LayoutBuilderLabels = Partial<BuilderMessages>
18
+
19
+ /**
20
+ * English builder strings.
21
+ * @deprecated Read the active locale's strings with `useToolkitMessages().builder`
22
+ * (or `TOOLKIT_MESSAGES.en.builder`); this alias stays for existing imports.
23
+ */
24
+ export const DEFAULT_LABELS: Required<LayoutBuilderLabels> = TOOLKIT_MESSAGES.en.builder
131
25
 
132
26
  /**
133
27
  * MIME type used to carry a widget id across the palette → canvas drag.
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Secondary builder controls (row, tab and cell actions) stay quiet until the
3
+ * pointer is over their group or focus is anywhere inside it, and are always
4
+ * visible where nothing can hover (touch screens). Spread it on the controls'
5
+ * container inside an element with `group`; a control that is never revealed
6
+ * by hover alone is a CI §12 rule ("alles per Tastatur bedienbar"), guarded by
7
+ * `builder-ux.test.tsx`.
8
+ */
9
+ export const REVEAL_ON_INTENT =
10
+ "opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100 focus-within:opacity-100 [@media(hover:none)]:opacity-100"
@@ -1,4 +1,5 @@
1
1
  import { CircleDot, Loader2 } from "lucide-react"
2
+ import { TONE_DOT, TONE_TEXT } from "../../lib/tone-utils.js"
2
3
  import type { LayoutBuilderLabels, RefreshStatus } from "./labels.js"
3
4
 
4
5
  /**
@@ -22,15 +23,18 @@ export function StatusChip({
22
23
  }
23
24
  if (status === "pending") {
24
25
  return (
25
- <span className="inline-flex items-center gap-1.5 text-amber-600 dark:text-amber-400">
26
- <span className="size-1.5 animate-pulse rounded-full bg-amber-500" />
26
+ <span className={`inline-flex items-center gap-1.5 ${TONE_TEXT.warning}`}>
27
+ <span
28
+ aria-hidden="true"
29
+ className={`size-1.5 animate-pulse rounded-full ${TONE_DOT.warning}`}
30
+ />
27
31
  {L.statusPending}
28
32
  </span>
29
33
  )
30
34
  }
31
35
  return (
32
- <span className="text-primary inline-flex items-center gap-1.5">
33
- <Loader2 className="size-3 animate-spin" />
36
+ <span className={`inline-flex items-center gap-1.5 ${TONE_TEXT.info}`}>
37
+ <Loader2 aria-hidden="true" className="size-3 animate-spin" />
34
38
  {L.statusRefreshing}
35
39
  </span>
36
40
  )
@@ -1,6 +1,8 @@
1
1
  import { useCallback, useEffect, useMemo, useRef, useState } from "react"
2
2
  import type {
3
3
  AvailableStep,
4
+ CatalogueApp,
5
+ DisplayText,
4
6
  KeyCatalogEntry,
5
7
  PipelineContext,
6
8
  PipelineStepRef,
@@ -22,6 +24,17 @@ import type { RefreshStatus } from "./labels.js"
22
24
 
23
25
  const EMPTY_CONTEXT: PipelineContext = { steps: {}, keys: {}, errors: [] }
24
26
 
27
+ /** What the builder reads from a `get-builder-catalogue` response (every field optional). */
28
+ interface CatalogueSnapshot {
29
+ reachableWidgets?: ReachableWidget[]
30
+ unreachableWidgets?: UnreachableWidget[]
31
+ availableSteps?: AvailableStep[]
32
+ keyCatalog?: KeyCatalogEntry[]
33
+ validationIssues?: string[]
34
+ context?: WireContext
35
+ apps?: CatalogueApp[]
36
+ }
37
+
25
38
  /**
26
39
  * Owns the builder's live catalogue: the snapshots fetched from the app-only
27
40
  * `get-builder-catalogue` tool (the LLM never sees this data), the refresh
@@ -49,6 +62,9 @@ export function useBuilderCatalogue({
49
62
  const [liveCatalog, setLiveCatalog] = useState<KeyCatalogEntry[]>([])
50
63
  const [liveSteps, setLiveSteps] = useState<AvailableStep[]>([])
51
64
  const [liveContext, setLiveContext] = useState<PipelineContext>(EMPTY_CONTEXT)
65
+ // The titled apps (the palette's group headings); the catalogue leaves the
66
+ // field out when no app has a title.
67
+ const [liveApps, setLiveApps] = useState<CatalogueApp[]>([])
52
68
  // Pipeline validation issues from the catalogue (Finding [10]/[6]). The
53
69
  // catalogue is fail-soft, but `render-view` is fail-hard, so we surface
54
70
  // these so the user sees — before committing — that the pipeline as
@@ -61,6 +77,26 @@ export function useBuilderCatalogue({
61
77
  // instead of only `console.warn`-ing, so the user knows the palette/context
62
78
  // may be stale. Cleared on the next successful refresh.
63
79
  const [refreshError, setRefreshError] = useState<string | null>(null)
80
+ // The first fetch has settled (answer or failure). Until then the palette
81
+ // shows a loading state, not "no elements" (CI §9: a skeleton while loading).
82
+ const [loaded, setLoaded] = useState(false)
83
+
84
+ // Takes over what one catalogue response carries; a field it lacks keeps
85
+ // the last snapshot.
86
+ const applySnapshot = useCallback((sc: CatalogueSnapshot | null) => {
87
+ if (sc?.reachableWidgets) setLiveReachable(sc.reachableWidgets)
88
+ if (sc?.unreachableWidgets) setLiveUnreachable(sc.unreachableWidgets)
89
+ if (sc?.availableSteps) setLiveSteps(sc.availableSteps)
90
+ if (sc?.keyCatalog) setLiveCatalog(sc.keyCatalog)
91
+ if (sc?.context) setLiveContext(toPipelineContext(sc.context))
92
+ // Absent `apps` means no app has a title (not "unchanged").
93
+ if (sc) setLiveApps(sc.apps ?? [])
94
+ // Pipeline issues are fail-soft in the catalogue but fail-hard in
95
+ // render-view; surface them so the user sees the render path wouldn't
96
+ // run as configured (Finding [10]/[6]). Coerce undefined → [] so a
97
+ // fixed pipeline clears a previously-shown warning.
98
+ setValidationIssues(sc?.validationIssues ?? [])
99
+ }, [])
64
100
 
65
101
  const refreshBuilder = useCallback(async () => {
66
102
  setStatus("refreshing")
@@ -69,24 +105,7 @@ export function useBuilderCatalogue({
69
105
  keys: entriesToKeys(keyEntries),
70
106
  steps: stepEntries.filter((s) => s.step.trim().length > 0),
71
107
  })
72
- const sc = parseToolResult<{
73
- reachableWidgets?: ReachableWidget[]
74
- unreachableWidgets?: UnreachableWidget[]
75
- availableSteps?: AvailableStep[]
76
- keyCatalog?: KeyCatalogEntry[]
77
- validationIssues?: string[]
78
- context?: WireContext
79
- } | null>(result)
80
- if (sc?.reachableWidgets) setLiveReachable(sc.reachableWidgets)
81
- if (sc?.unreachableWidgets) setLiveUnreachable(sc.unreachableWidgets)
82
- if (sc?.availableSteps) setLiveSteps(sc.availableSteps)
83
- if (sc?.keyCatalog) setLiveCatalog(sc.keyCatalog)
84
- if (sc?.context) setLiveContext(toPipelineContext(sc.context))
85
- // Pipeline issues are fail-soft in the catalogue but fail-hard in
86
- // render-view; surface them so the user sees the render path wouldn't
87
- // run as configured (Finding [10]/[6]). Coerce undefined → [] so a
88
- // fixed pipeline clears a previously-shown warning.
89
- setValidationIssues(sc?.validationIssues ?? [])
108
+ applySnapshot(parseToolResult<CatalogueSnapshot | null>(result))
90
109
  // A successful fetch clears any stale failure banner.
91
110
  setRefreshError(null)
92
111
  } catch (err) {
@@ -104,13 +123,19 @@ export function useBuilderCatalogue({
104
123
  setRefreshError(reason)
105
124
  } finally {
106
125
  setStatus("idle")
126
+ setLoaded(true)
107
127
  }
108
- }, [catalogueToolName, callTool, keyEntries, stepEntries])
128
+ }, [applySnapshot, catalogueToolName, callTool, keyEntries, stepEntries])
109
129
 
110
130
  const refreshRef = useRef(refreshBuilder)
111
131
  useEffect(() => {
112
132
  refreshRef.current = refreshBuilder
113
133
  }, [refreshBuilder])
134
+ // Retry of the catalogue error state: fetch again right away, with the
135
+ // current keys and steps.
136
+ const retryCatalogue = useCallback(() => {
137
+ void refreshRef.current()
138
+ }, [])
114
139
  const isFirstRun = useRef(true)
115
140
  useEffect(() => {
116
141
  if (isFirstRun.current) {
@@ -149,6 +174,20 @@ export function useBuilderCatalogue({
149
174
  return map
150
175
  }, [liveReachable, liveUnreachable])
151
176
 
177
+ // Display text (title, summary, their keys) per widget id, from both lists:
178
+ // a canvas cell or the props sheet may name a widget the current keys do
179
+ // not reach.
180
+ const displayByWidgetId = useMemo(() => {
181
+ const map = new Map<string, DisplayText>()
182
+ for (const w of [...liveUnreachable, ...liveReachable]) map.set(w.id, w)
183
+ return map
184
+ }, [liveReachable, liveUnreachable])
185
+
186
+ const appDisplayByName = useMemo(
187
+ () => new Map<string, DisplayText>(liveApps.map((app) => [app.name, app])),
188
+ [liveApps],
189
+ )
190
+
152
191
  const paletteByApp = useMemo(() => {
153
192
  const groups = new Map<string, ReachableWidget[]>()
154
193
  for (const w of liveReachable) {
@@ -177,9 +216,13 @@ export function useBuilderCatalogue({
177
216
  liveContext,
178
217
  validationIssues,
179
218
  status,
219
+ loaded,
180
220
  refreshError,
221
+ retryCatalogue,
181
222
  widgetById,
182
223
  propsSchemaByWidgetId,
224
+ displayByWidgetId,
225
+ appDisplayByName,
183
226
  paletteByApp,
184
227
  liveKeyCount,
185
228
  stepsByApp,
@@ -0,0 +1,68 @@
1
+ import { useCallback, useState } from "react"
2
+ import {
3
+ draftStatus,
4
+ viewAfterAdvancedToggle,
5
+ type BuilderView,
6
+ type DraftStatus,
7
+ } from "./builder-model.js"
8
+
9
+ // -------------------------------------------------------------------------- //
10
+ // Builder session state that is not the draft itself
11
+ // -------------------------------------------------------------------------- //
12
+
13
+ /**
14
+ * Which builder view is shown and whether advanced mode is on. The data
15
+ * sources (keys, steps, context ids) and the catalogue are technical, so they
16
+ * live behind "Advanced"; switching it off leaves a now hidden view for the
17
+ * layout.
18
+ */
19
+ export function useBuilderMode() {
20
+ const [advanced, setAdvanced] = useState(false)
21
+ const [view, setView] = useState<BuilderView>("layout")
22
+ const toggleAdvanced = useCallback(() => {
23
+ const next = !advanced
24
+ setAdvanced(next)
25
+ setView(viewAfterAdvancedToggle(view, next))
26
+ }, [advanced, view])
27
+ /** The empty layout's one next step: show the data sources. */
28
+ const openDataSources = useCallback(() => {
29
+ setAdvanced(true)
30
+ setView("pipeline")
31
+ }, [])
32
+ return { advanced, view, setView, toggleAdvanced, openDataSources }
33
+ }
34
+
35
+ /**
36
+ * Inline rename feedback. The reducer rejects duplicate tab labels and bumps
37
+ * `renameRejectedAt`; each bump shows "name already exists" until the inline
38
+ * editor closes (render-phase setState, the house pattern for derived state).
39
+ */
40
+ export function useRenameFeedback(renameRejectedAt: number, editingTabIdx: number | null): boolean {
41
+ const [renameRejected, setRenameRejected] = useState(false)
42
+ const [prevRenameRejectedAt, setPrevRenameRejectedAt] = useState(renameRejectedAt)
43
+ if (renameRejectedAt !== prevRenameRejectedAt) {
44
+ setPrevRenameRejectedAt(renameRejectedAt)
45
+ setRenameRejected(true)
46
+ }
47
+ const [prevEditingTabIdx, setPrevEditingTabIdx] = useState(editingTabIdx)
48
+ if (editingTabIdx !== prevEditingTabIdx) {
49
+ setPrevEditingTabIdx(editingTabIdx)
50
+ if (editingTabIdx === null) setRenameRejected(false)
51
+ }
52
+ return renameRejected
53
+ }
54
+
55
+ /**
56
+ * Tracks the draft against the view before editing and the last saved
57
+ * dashboard (see `draftStatus`). `snapshot` is the current `builderSnapshot`;
58
+ * the first one is the pre-edit baseline.
59
+ */
60
+ export function useDraftStatus(snapshot: string): DraftStatus & {
61
+ /** Records `saved` (the snapshot that went into a saved dashboard). */
62
+ markSaved: (saved: string) => void
63
+ } {
64
+ const [baseline] = useState(snapshot)
65
+ const [saved, setSaved] = useState<string | null>(null)
66
+ const markSaved = useCallback((value: string) => setSaved(value), [])
67
+ return { ...draftStatus(snapshot, baseline, saved), markSaved }
68
+ }
@@ -0,0 +1,24 @@
1
+ import { useMemo } from "react"
2
+ import { useToolkitLocale, useTranslate } from "../../locale/locale-provider.js"
3
+ import { keyResolverFrom, type DisplayKeyResolver } from "./builder-model.js"
4
+
5
+ /** What the builder needs to turn a definition's display text into words. */
6
+ export interface DisplayResolver {
7
+ /** The locale the builder's own text is in (a `LocaleProvider`'s, else the host's). */
8
+ locale: string
9
+ /** Resolves a `titleKey`/`summaryKey` through the `LocaleProvider`'s translator. */
10
+ resolveKey: DisplayKeyResolver
11
+ }
12
+
13
+ /**
14
+ * Binds `displayLabel` / `propFieldText` to the builder's locale: inline
15
+ * per-locale titles follow the same language as the builder chrome around
16
+ * them, and i18n keys resolve through the nearest `LocaleProvider`'s
17
+ * translator (outside one, keys stay unknown and the inline text or the id
18
+ * shows instead).
19
+ */
20
+ export function useDisplayResolver(): DisplayResolver {
21
+ const locale = useToolkitLocale()
22
+ const translate = useTranslate()
23
+ return useMemo(() => ({ locale, resolveKey: keyResolverFrom(translate) }), [locale, translate])
24
+ }
@@ -22,6 +22,7 @@ export function useSaveDashboard({
22
22
  stepEntries,
23
23
  draft,
24
24
  onSaved,
25
+ onSuccess,
25
26
  }: {
26
27
  callTool: (name: string, args: object) => Promise<unknown>
27
28
  saveToolName: string
@@ -31,6 +32,8 @@ export function useSaveDashboard({
31
32
  stepEntries: PipelineStepRef[]
32
33
  draft: DraftLayout
33
34
  onSaved?: (result: { id: string; name: string }) => void
35
+ /** Confirms every successful save (the builder raises a toast), with the saved name. */
36
+ onSuccess?: (name: string) => void
34
37
  }) {
35
38
  const [isBusy, setBusy] = useState(false)
36
39
  const [saveOpen, setSaveOpen] = useState(false)
@@ -56,6 +59,7 @@ export function useSaveDashboard({
56
59
  })
57
60
  const saved = parseToolResult<{ id?: string; name?: string } | null>(result)
58
61
  setSaveOpen(false)
62
+ onSuccess?.(saved?.name ?? saveName.trim())
59
63
  if (saved?.id && onSaved) {
60
64
  onSaved({
61
65
  id: saved.id,
@@ -75,6 +79,7 @@ export function useSaveDashboard({
75
79
  draft,
76
80
  keyEntries,
77
81
  onSaved,
82
+ onSuccess,
78
83
  saveDescription,
79
84
  saveName,
80
85
  saveToolName,
package/src/app/index.ts CHANGED
@@ -1,6 +1,20 @@
1
1
  export { McpAppView } from "./mcp-app-view.js"
2
- export type { McpAppViewProps, McpAppViewLabels } from "./mcp-app-view.js"
2
+ export type {
3
+ McpAppViewProps,
4
+ McpAppViewLabels,
5
+ DescribeStep,
6
+ DescribeViewError,
7
+ ViewErrorKind,
8
+ RecoveryPolicy,
9
+ ViewTitleLevel,
10
+ ViewTitleMode,
11
+ } from "./mcp-app-view.js"
3
12
  export { McpToolkitApp, mountMcpToolkitApp } from "./mcp-toolkit-app.js"
13
+ // The passive host-lifecycle observer behind the stripped-result recovery
14
+ // (toolkit#176): installed as the bundle evaluates; a custom shell may call it
15
+ // explicitly before its own `bootstrapView`.
16
+ export { installToolResultObserver } from "../lib/tool-result-observer.js"
17
+ export type { ToolObservation, ToolResultObserver } from "../lib/tool-result-observer.js"
4
18
  export {
5
19
  WidgetRenderer,
6
20
  WidgetErrorBoundary,
@@ -10,10 +24,12 @@ export {
10
24
  export type { WidgetRendererProps, WidgetComponent } from "./widget-renderer.js"
11
25
  export { LayoutBuilder } from "./layout-builder.js"
12
26
  export type { LayoutBuilderProps, LayoutBuilderLabels } from "./layout-builder.js"
27
+ export type { BuilderExitCommit } from "./builder/builder-model.js"
13
28
 
14
29
  // App-level value modules that import `mcp-use/react` (ModelContext, the 2.x
15
30
  // view hooks) — exported from this subpath only, never the root barrel.
16
- export { adaptDataWidget, HostModelContext } from "./adapt-data-widget.js"
31
+ export { adaptDataWidget } from "./adapt-data-widget.js"
32
+ export { HostModelContext, useHostModelContext } from "./model-context.js"
17
33
  export type { DescribeForModel } from "./adapt-data-widget.js"
18
34
  export { useHostActions, buildShowWidgetIntent } from "./use-host-actions.js"
19
35
  export type { HostActions } from "./use-host-actions.js"
@@ -36,7 +52,8 @@ export type {
36
52
  OpenAiAppsSdk,
37
53
  StandaloneHostBridgeOptions,
38
54
  } from "./host-bridge.js"
39
- export { McpUseHostBridgeProvider, useIsInsideMcpUseView } from "./mcp-use-host-bridge.js"
55
+ export { McpUseHostBridgeProvider } from "./mcp-use-host-bridge.js"
56
+ export { useIsInsideMcpUseView } from "./model-context.js"
40
57
 
41
58
  // Storybook-style harness for developing widgets in isolation with fixture
42
59
  // data and a simulated HostBridge. Lives under ./app to keep every host-facing