@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,6 +1,7 @@
1
1
  import { memo, useMemo } from "react"
2
- import { ArrowDownToLine, ArrowRightToLine, Plus, X } from "lucide-react"
2
+ import { ArrowDownToLine, ArrowRightToLine, LucideProvider, Plus, X } from "lucide-react"
3
3
  import type { AvailableStep, KeyCatalogEntry, PipelineStepRef } from "@miragon/mcp-toolkit-core"
4
+ import { DENSE_ICON_STROKE } from "../../lib/icon-stroke.js"
4
5
  import { Badge } from "../../primitives/badge.js"
5
6
  import { Button } from "../../primitives/button.js"
6
7
  import { Input } from "../../primitives/input.js"
@@ -11,14 +12,231 @@ import {
11
12
  SelectTrigger,
12
13
  SelectValue,
13
14
  } from "../../primitives/select.js"
14
- import { formatLiveKeyValue, valueTypeLabel, type KeyEntry } from "./builder-model.js"
15
+ import {
16
+ displayLabel,
17
+ formatLiveKeyValue,
18
+ valueTypeLabel,
19
+ type DisplayKeyResolver,
20
+ type KeyEntry,
21
+ } from "./builder-model.js"
15
22
  import type { LayoutBuilderLabels, RefreshStatus } from "./labels.js"
16
23
  import { StatusChip } from "./status-chip.js"
24
+ import { useDisplayResolver } from "./use-display-resolver.js"
17
25
 
18
26
  // -------------------------------------------------------------------------- //
19
- // Pipeline strip — compact horizontal Keys + Steps
27
+ // Pipeline strip — the data sources (advanced mode): keys + steps
20
28
  // -------------------------------------------------------------------------- //
21
29
 
30
+ type Labels = Required<LayoutBuilderLabels>
31
+
32
+ /** "needs a, b · provides c" in words (no arrow glyphs): a step's contract. */
33
+ function StepContract({ L, step }: { L: Labels; step: AvailableStep }) {
34
+ return (
35
+ <span className="text-muted-foreground text-small flex flex-wrap gap-x-2">
36
+ <span>
37
+ {L.catalogueNeedsKeys}{" "}
38
+ <span className="font-mono">
39
+ {step.requires.length ? step.requires.join(", ") : L.noInputs}
40
+ </span>
41
+ </span>
42
+ <span>
43
+ {L.stepProvides}{" "}
44
+ <span className="font-mono">
45
+ {step.produces.length ? step.produces.join(", ") : L.noOutputs}
46
+ </span>
47
+ </span>
48
+ </span>
49
+ )
50
+ }
51
+
52
+ function KeyRows({
53
+ L,
54
+ keyEntries,
55
+ keyCatalog,
56
+ liveKeys,
57
+ onUpdateKey,
58
+ onRemoveKey,
59
+ }: {
60
+ L: Labels
61
+ keyEntries: KeyEntry[]
62
+ keyCatalog: KeyCatalogEntry[]
63
+ liveKeys: Record<string, unknown>
64
+ onUpdateKey: (idx: number, patch: Partial<KeyEntry>) => void
65
+ onRemoveKey: (idx: number) => void
66
+ }) {
67
+ return (
68
+ <ul className="flex flex-col gap-1">
69
+ {keyEntries.map((entry, idx) => {
70
+ const livePreview = formatLiveKeyValue(liveKeys[entry.name], L.catalogueLive)
71
+ const usedNames = new Set(
72
+ keyEntries.map((e, i) => (i === idx ? "" : e.name)).filter(Boolean),
73
+ )
74
+ const pickable = keyCatalog.filter((c) => c.key === entry.name || !usedNames.has(c.key))
75
+ return (
76
+ <li key={idx} className="grid grid-cols-2 items-center gap-1">
77
+ <Select
78
+ value={entry.name || undefined}
79
+ onValueChange={(value) => onUpdateKey(idx, { name: value })}
80
+ >
81
+ <SelectTrigger aria-label={L.keyName} className="text-small h-7 min-w-0 font-mono">
82
+ {/* The trigger names the chosen key only; who uses it shows in the list. */}
83
+ <SelectValue placeholder={L.keyName}>{entry.name || null}</SelectValue>
84
+ </SelectTrigger>
85
+ <SelectContent>
86
+ {pickable.length === 0 ? (
87
+ <div className="text-muted-foreground text-small px-2 py-1.5 italic">
88
+ {L.noMoreKeys}
89
+ </div>
90
+ ) : (
91
+ pickable.map((c) => (
92
+ <SelectItem key={c.key} value={c.key} className="py-1.5">
93
+ <div className="flex flex-col gap-0.5">
94
+ <span className="text-small font-mono">{c.key}</span>
95
+ {c.consumedByWidgets.length + c.consumedBySteps.length > 0 && (
96
+ <span className="text-muted-foreground text-small">
97
+ {L.catalogueConsumedBy}{" "}
98
+ <span className="font-mono">
99
+ {[...c.consumedByWidgets, ...c.consumedBySteps].join(", ")}
100
+ </span>
101
+ </span>
102
+ )}
103
+ </div>
104
+ </SelectItem>
105
+ ))
106
+ )}
107
+ </SelectContent>
108
+ </Select>
109
+ <div className="flex min-w-0 items-center gap-1">
110
+ <div className="relative min-w-0 flex-1">
111
+ <Input
112
+ aria-label={L.keyValueFor(entry.name)}
113
+ value={entry.rawValue}
114
+ onChange={(e) => onUpdateKey(idx, { rawValue: e.target.value })}
115
+ placeholder={livePreview ?? L.keyValue}
116
+ className="text-small h-7 pr-14 font-mono"
117
+ />
118
+ <span
119
+ className="text-muted-foreground text-small pointer-events-none absolute top-1/2 right-2 -translate-y-1/2 tabular-nums"
120
+ title={L.parsedType}
121
+ >
122
+ {L.valueType(valueTypeLabel(entry.rawValue))}
123
+ </span>
124
+ </div>
125
+ <Button
126
+ variant="ghost"
127
+ size="icon-xs"
128
+ onClick={() => onRemoveKey(idx)}
129
+ aria-label={L.removeKey}
130
+ >
131
+ <X aria-hidden="true" />
132
+ </Button>
133
+ </div>
134
+ </li>
135
+ )
136
+ })}
137
+ </ul>
138
+ )
139
+ }
140
+
141
+ function StepRows({
142
+ L,
143
+ stepEntries,
144
+ stepLookup,
145
+ stepsByApp,
146
+ locale,
147
+ resolveKey,
148
+ onUpdateStep,
149
+ onRemoveStep,
150
+ }: {
151
+ L: Labels
152
+ stepEntries: PipelineStepRef[]
153
+ stepLookup: Map<string, AvailableStep>
154
+ stepsByApp: [string, AvailableStep[]][]
155
+ locale: string
156
+ resolveKey: DisplayKeyResolver
157
+ onUpdateStep: (idx: number, patch: Partial<PipelineStepRef>) => void
158
+ onRemoveStep: (idx: number) => void
159
+ }) {
160
+ return (
161
+ <ul className="flex flex-col gap-1">
162
+ {stepEntries.map((step, idx) => {
163
+ const meta = stepLookup.get(step.step)
164
+ const selected = meta ? displayLabel(meta, meta.id, locale, resolveKey).label : step.step
165
+ return (
166
+ <li key={idx} className="flex flex-col gap-0.5">
167
+ <div className="flex items-center gap-1">
168
+ <Input
169
+ aria-label={L.stepContextId}
170
+ value={step.id}
171
+ onChange={(e) => onUpdateStep(idx, { id: e.target.value })}
172
+ placeholder={L.stepContextId}
173
+ className="text-small h-7 w-24 font-mono"
174
+ />
175
+ <Select
176
+ value={step.step || undefined}
177
+ onValueChange={(value) => onUpdateStep(idx, { step: value })}
178
+ >
179
+ <SelectTrigger
180
+ aria-label={L.stepPickerLabel}
181
+ className="text-small h-7 min-w-0 flex-1"
182
+ >
183
+ {/* The trigger names the chosen step only; its contract follows below. */}
184
+ <SelectValue placeholder={L.stepPickerLabel}>
185
+ {step.step ? selected : null}
186
+ </SelectValue>
187
+ </SelectTrigger>
188
+ <SelectContent>
189
+ {stepsByApp.map(([app, items]) => (
190
+ <div key={app}>
191
+ <div className="text-muted-foreground text-small px-2 py-1 font-semibold">
192
+ {app}
193
+ </div>
194
+ {items.map((s) => {
195
+ const name = displayLabel(s, s.id, locale, resolveKey)
196
+ return (
197
+ <SelectItem key={s.id} value={s.id} className="py-2">
198
+ <div className="flex flex-col gap-0.5">
199
+ <span className="text-small font-medium">{name.label}</span>
200
+ {name.summary && (
201
+ <span className="text-muted-foreground text-small">
202
+ {name.summary}
203
+ </span>
204
+ )}
205
+ {name.hint && (
206
+ <span className="text-muted-foreground text-small font-mono">
207
+ {name.hint}
208
+ </span>
209
+ )}
210
+ <StepContract L={L} step={s} />
211
+ </div>
212
+ </SelectItem>
213
+ )
214
+ })}
215
+ </div>
216
+ ))}
217
+ </SelectContent>
218
+ </Select>
219
+ <Button
220
+ variant="ghost"
221
+ size="icon-xs"
222
+ onClick={() => onRemoveStep(idx)}
223
+ aria-label={L.removeStep}
224
+ >
225
+ <X aria-hidden="true" />
226
+ </Button>
227
+ </div>
228
+ {meta && (
229
+ <div className="ml-1 pl-24">
230
+ <StepContract L={L} step={meta} />
231
+ </div>
232
+ )}
233
+ </li>
234
+ )
235
+ })}
236
+ </ul>
237
+ )
238
+ }
239
+
22
240
  function PipelineStripImpl({
23
241
  L,
24
242
  keyEntries,
@@ -35,7 +253,7 @@ function PipelineStripImpl({
35
253
  onRemoveStep,
36
254
  status,
37
255
  }: {
38
- L: Required<LayoutBuilderLabels>
256
+ L: Labels
39
257
  keyEntries: KeyEntry[]
40
258
  stepEntries: PipelineStepRef[]
41
259
  keyCatalog: KeyCatalogEntry[]
@@ -50,6 +268,7 @@ function PipelineStripImpl({
50
268
  onRemoveStep: (idx: number) => void
51
269
  status: RefreshStatus
52
270
  }) {
271
+ const { locale, resolveKey } = useDisplayResolver()
53
272
  const stepLookup = useMemo(() => {
54
273
  const map = new Map<string, AvailableStep>()
55
274
  for (const s of availableSteps) map.set(s.id, s)
@@ -58,97 +277,36 @@ function PipelineStripImpl({
58
277
 
59
278
  return (
60
279
  <section className="bg-muted/30 -mx-1 rounded-lg border px-3 py-3">
61
- <div className="mb-2 flex items-center gap-2">
62
- <span className="text-muted-foreground text-[10px] font-semibold tracking-[0.12em] uppercase">
63
- {L.pipelineHeader}
64
- </span>
65
- <span className="text-muted-foreground/60 text-[10px]">· auto-applies on edit</span>
66
- <div className="ml-auto text-[11px]">
280
+ <div className="mb-2 flex flex-wrap items-center gap-2">
281
+ <h3 className="text-muted-foreground text-small font-semibold">{L.pipelineHeader}</h3>
282
+ <span className="text-muted-foreground text-small">{L.autoApplies}</span>
283
+ <div className="text-small ml-auto">
67
284
  <StatusChip status={status} L={L} />
68
285
  </div>
69
286
  </div>
70
287
 
71
288
  <div className="grid grid-cols-1 gap-x-6 gap-y-3 lg:grid-cols-2">
72
289
  <div className="flex flex-col gap-1.5">
73
- <div className="text-muted-foreground flex items-center gap-1.5 text-[11px] font-semibold">
74
- <ArrowRightToLine className="size-3" />
290
+ <div className="text-muted-foreground text-small flex items-center gap-1.5 font-semibold">
291
+ <ArrowRightToLine aria-hidden="true" className="size-3.5" />
75
292
  {L.keysHeader}
76
- <Badge variant="outline" className="px-1.5 text-[10px]">
293
+ <Badge variant="outline" className="px-1.5">
77
294
  {keyEntries.length}
78
295
  </Badge>
79
296
  </div>
80
297
  {keyEntries.length === 0 ? (
81
- <div className="text-muted-foreground rounded-md border border-dashed px-2 py-1.5 text-xs italic">
298
+ <div className="text-muted-foreground text-small rounded-md border border-dashed px-2 py-1.5 italic">
82
299
  {L.emptyKeys}
83
300
  </div>
84
301
  ) : (
85
- <ul className="flex flex-col gap-1">
86
- {keyEntries.map((entry, idx) => {
87
- const livePreview = formatLiveKeyValue(liveKeys[entry.name])
88
- const usedNames = new Set(
89
- keyEntries.map((e, i) => (i === idx ? "" : e.name)).filter(Boolean),
90
- )
91
- const pickable = keyCatalog.filter(
92
- (c) => c.key === entry.name || !usedNames.has(c.key),
93
- )
94
- return (
95
- <li key={idx} className="grid grid-cols-2 items-center gap-1">
96
- <Select
97
- value={entry.name || undefined}
98
- onValueChange={(value) => onUpdateKey(idx, { name: value })}
99
- >
100
- <SelectTrigger className="h-7 min-w-0 font-mono text-xs">
101
- <SelectValue placeholder={L.keyName} />
102
- </SelectTrigger>
103
- <SelectContent>
104
- {pickable.length === 0 ? (
105
- <div className="text-muted-foreground px-2 py-1.5 text-xs italic">
106
- No more keys available.
107
- </div>
108
- ) : (
109
- pickable.map((c) => (
110
- <SelectItem key={c.key} value={c.key} className="py-1.5">
111
- <div className="flex flex-col gap-0.5">
112
- <span className="font-mono text-xs">{c.key}</span>
113
- {c.consumedByWidgets.length + c.consumedBySteps.length > 0 && (
114
- <span className="text-muted-foreground/80 font-mono text-[10px]">
115
- → {[...c.consumedByWidgets, ...c.consumedBySteps].join(", ")}
116
- </span>
117
- )}
118
- </div>
119
- </SelectItem>
120
- ))
121
- )}
122
- </SelectContent>
123
- </Select>
124
- <div className="flex min-w-0 items-center gap-1">
125
- <div className="relative min-w-0 flex-1">
126
- <Input
127
- value={entry.rawValue}
128
- onChange={(e) => onUpdateKey(idx, { rawValue: e.target.value })}
129
- placeholder={livePreview ?? L.keyValue}
130
- className="h-7 pr-10 font-mono text-xs"
131
- />
132
- <span
133
- className="text-muted-foreground/70 pointer-events-none absolute top-1/2 right-2 -translate-y-1/2 font-mono text-[10px] tabular-nums"
134
- title="parsed type"
135
- >
136
- {valueTypeLabel(entry.rawValue)}
137
- </span>
138
- </div>
139
- <Button
140
- variant="ghost"
141
- size="icon-xs"
142
- onClick={() => onRemoveKey(idx)}
143
- aria-label="Remove key"
144
- >
145
- <X />
146
- </Button>
147
- </div>
148
- </li>
149
- )
150
- })}
151
- </ul>
302
+ <KeyRows
303
+ L={L}
304
+ keyEntries={keyEntries}
305
+ keyCatalog={keyCatalog}
306
+ liveKeys={liveKeys}
307
+ onUpdateKey={onUpdateKey}
308
+ onRemoveKey={onRemoveKey}
309
+ />
152
310
  )}
153
311
  <Button
154
312
  variant="ghost"
@@ -156,91 +314,33 @@ function PipelineStripImpl({
156
314
  onClick={() => onAddKey()}
157
315
  className="text-muted-foreground hover:text-foreground self-start"
158
316
  >
159
- <Plus /> {L.addKey}
317
+ <Plus aria-hidden="true" /> {L.addKey}
160
318
  </Button>
161
319
  </div>
162
320
 
163
321
  <div className="flex flex-col gap-1.5">
164
- <div className="text-muted-foreground flex items-center gap-1.5 text-[11px] font-semibold">
165
- <ArrowDownToLine className="size-3" />
322
+ <div className="text-muted-foreground text-small flex items-center gap-1.5 font-semibold">
323
+ <ArrowDownToLine aria-hidden="true" className="size-3.5" />
166
324
  {L.stepsHeader}
167
- <Badge variant="outline" className="px-1.5 text-[10px]">
325
+ <Badge variant="outline" className="px-1.5">
168
326
  {stepEntries.length}
169
327
  </Badge>
170
328
  </div>
171
329
  {stepEntries.length === 0 ? (
172
- <div className="text-muted-foreground rounded-md border border-dashed px-2 py-1.5 text-xs italic">
330
+ <div className="text-muted-foreground text-small rounded-md border border-dashed px-2 py-1.5 italic">
173
331
  {L.emptySteps}
174
332
  </div>
175
333
  ) : (
176
- <ul className="flex flex-col gap-1">
177
- {stepEntries.map((step, idx) => {
178
- const meta = stepLookup.get(step.step)
179
- return (
180
- <li key={idx} className="flex flex-col gap-0.5">
181
- <div className="flex items-center gap-1">
182
- <Input
183
- value={step.id}
184
- onChange={(e) => onUpdateStep(idx, { id: e.target.value })}
185
- placeholder={L.stepContextId}
186
- className="h-7 w-24 font-mono text-xs"
187
- />
188
- <Select
189
- value={step.step || undefined}
190
- onValueChange={(value) => onUpdateStep(idx, { step: value })}
191
- >
192
- <SelectTrigger className="h-7 flex-1 text-xs">
193
- <SelectValue placeholder={L.stepPickerLabel} />
194
- </SelectTrigger>
195
- <SelectContent>
196
- {stepsByApp.map(([app, items]) => (
197
- <div key={app}>
198
- <div className="text-muted-foreground px-2 py-1 text-[10px] font-semibold tracking-wide uppercase">
199
- {app}
200
- </div>
201
- {items.map((s) => (
202
- <SelectItem key={s.id} value={s.id} className="py-2">
203
- <div className="flex flex-col gap-0.5">
204
- <span className="font-mono text-xs">{s.id}</span>
205
- <div className="text-muted-foreground flex flex-wrap gap-x-2 text-[10px]">
206
- <span className="font-mono">
207
- ←{" "}
208
- {s.requires.length ? s.requires.join(", ") : "(no inputs)"}
209
- </span>
210
- <span className="font-mono">
211
- → {s.produces.length ? s.produces.join(", ") : "(none)"}
212
- </span>
213
- </div>
214
- </div>
215
- </SelectItem>
216
- ))}
217
- </div>
218
- ))}
219
- </SelectContent>
220
- </Select>
221
- <Button
222
- variant="ghost"
223
- size="icon-xs"
224
- onClick={() => onRemoveStep(idx)}
225
- aria-label="Remove step"
226
- >
227
- <X />
228
- </Button>
229
- </div>
230
- {meta && (
231
- <div className="text-muted-foreground/80 ml-1 flex flex-wrap gap-x-2 pl-24 text-[10px]">
232
- <span className="font-mono">
233
- ← {meta.requires.length ? meta.requires.join(", ") : "(no inputs)"}
234
- </span>
235
- <span className="font-mono">
236
- → {meta.produces.length ? meta.produces.join(", ") : "(none)"}
237
- </span>
238
- </div>
239
- )}
240
- </li>
241
- )
242
- })}
243
- </ul>
334
+ <StepRows
335
+ L={L}
336
+ stepEntries={stepEntries}
337
+ stepLookup={stepLookup}
338
+ stepsByApp={stepsByApp}
339
+ locale={locale}
340
+ resolveKey={resolveKey}
341
+ onUpdateStep={onUpdateStep}
342
+ onRemoveStep={onRemoveStep}
343
+ />
244
344
  )}
245
345
  <Button
246
346
  variant="ghost"
@@ -249,7 +349,7 @@ function PipelineStripImpl({
249
349
  disabled={availableSteps.length === 0}
250
350
  className="text-muted-foreground hover:text-foreground self-start"
251
351
  >
252
- <Plus /> {L.addStep}
352
+ <Plus aria-hidden="true" /> {L.addStep}
253
353
  </Button>
254
354
  </div>
255
355
  </div>
@@ -257,4 +357,13 @@ function PipelineStripImpl({
257
357
  )
258
358
  }
259
359
 
260
- export const PipelineStrip = memo(PipelineStripImpl)
360
+ /** A dense chrome bar: its Lucide icons draw at stroke 2 (CI §11), not the view's 2.5. */
361
+ function DensePipelineStrip(props: Parameters<typeof PipelineStripImpl>[0]) {
362
+ return (
363
+ <LucideProvider strokeWidth={DENSE_ICON_STROKE}>
364
+ <PipelineStripImpl {...props} />
365
+ </LucideProvider>
366
+ )
367
+ }
368
+
369
+ export const PipelineStrip = memo(DensePipelineStrip)
@@ -1,4 +1,4 @@
1
- import { AlertTriangle } from "lucide-react"
1
+ import { ErrorState } from "../../components/ErrorState.js"
2
2
  import { Button } from "../../primitives/button.js"
3
3
  import {
4
4
  Dialog,
@@ -16,10 +16,17 @@ import type { LayoutBuilderLabels } from "./labels.js"
16
16
  // Save dialog
17
17
  // -------------------------------------------------------------------------- //
18
18
 
19
+ /**
20
+ * Names the draft and saves it as a dashboard. Its description mentions Apply
21
+ * only where there is one (`canApply`: the builder has an `onExit`). Opens
22
+ * with the focus on the name field and hands it back to "Save as dashboard"
23
+ * when it closes.
24
+ */
19
25
  export function SaveDialog({
20
26
  L,
21
27
  open,
22
28
  onOpenChange,
29
+ canApply,
23
30
  name,
24
31
  setName,
25
32
  description,
@@ -31,6 +38,8 @@ export function SaveDialog({
31
38
  L: Required<LayoutBuilderLabels>
32
39
  open: boolean
33
40
  onOpenChange: (open: boolean) => void
41
+ /** The builder has a view to apply the draft to (an `onExit`). */
42
+ canApply: boolean
34
43
  name: string
35
44
  setName: (v: string) => void
36
45
  description: string
@@ -44,16 +53,19 @@ export function SaveDialog({
44
53
  <DialogContent>
45
54
  <DialogHeader>
46
55
  <DialogTitle>{L.saveDialogTitle}</DialogTitle>
47
- <DialogDescription>{L.saveDialogDescription}</DialogDescription>
56
+ <DialogDescription>
57
+ {canApply ? L.saveDialogDescription : L.saveDialogDescriptionStandalone}
58
+ </DialogDescription>
48
59
  </DialogHeader>
49
60
  <div className="flex flex-col gap-3">
50
61
  <label className="flex flex-col gap-1 text-sm">
51
62
  <span className="font-medium">{L.saveNameLabel}</span>
63
+ {/* No autoFocus: the dialog focuses this first field itself, and
64
+ only then notes where to hand the focus back on close. */}
52
65
  <Input
53
66
  value={name}
54
67
  onChange={(e) => setName(e.target.value)}
55
- placeholder="Invoice overview"
56
- autoFocus
68
+ placeholder={L.saveNamePlaceholder}
57
69
  />
58
70
  </label>
59
71
  <label className="flex flex-col gap-1 text-sm">
@@ -61,19 +73,18 @@ export function SaveDialog({
61
73
  <Input
62
74
  value={description}
63
75
  onChange={(e) => setDescription(e.target.value)}
64
- placeholder="Optional"
76
+ placeholder={L.saveDescriptionPlaceholder}
65
77
  />
66
78
  </label>
79
+ {/* What happened and what to do in catalog words; the raw reason
80
+ only under Details. The Save button below is the retry. */}
67
81
  {error && (
68
- <div
69
- className="border-destructive/30 bg-destructive/10 text-destructive flex items-start gap-2 rounded-md border px-3 py-2 text-xs"
70
- role="alert"
71
- >
72
- <AlertTriangle className="mt-0.5 size-3.5 shrink-0" aria-hidden="true" />
73
- <span className="min-w-0 break-words">
74
- <span className="font-medium">{L.saveError}:</span> {error}
75
- </span>
76
- </div>
82
+ <ErrorState
83
+ variant="inline"
84
+ title={L.saveError}
85
+ description={L.saveErrorHint}
86
+ details={error}
87
+ />
77
88
  )}
78
89
  </div>
79
90
  <DialogFooter>