@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,24 +1,31 @@
1
1
  import type { ReactElement } from "react"
2
+ import { ExternalLink, Inbox } from "lucide-react"
2
3
  import {
3
4
  Button,
4
5
  CountPill,
5
6
  DrillButton,
7
+ EmptyState,
8
+ ErrorState,
6
9
  FilterBar,
7
10
  GridItem,
8
11
  GridLayout,
9
12
  GroupCard,
10
13
  KpiGrid,
14
+ KpiGridSkeleton,
11
15
  ListFooter,
12
16
  LivePill,
13
17
  LocaleProvider,
18
+ PagedListFooter,
14
19
  SectionHeading,
20
+ StatusBadge,
15
21
  ThemeProvider,
16
22
  themePresets,
23
+ ToastProvider,
17
24
  useLocale,
18
25
  WidgetHeader,
19
26
  } from "./index.js"
20
27
  import { createStandaloneHostBridge, HostBridgeProvider, useHostBridge } from "./app/host-bridge.js"
21
- import { HostModelContext } from "./app/adapt-data-widget.js"
28
+ import { HostModelContext } from "./app/model-context.js"
22
29
  import { WidgetFixtureHost, type FixtureWidget } from "./app/widget-fixture.js"
23
30
  import { PRIMITIVE_RENDER_CASES, type RenderCase } from "./render-cases-primitives.js"
24
31
 
@@ -107,11 +114,17 @@ export const RENDER_CASES: RenderCase[] = [
107
114
  trendDirection: "up",
108
115
  },
109
116
  { label: "Done", value: 12, fraction: "/19", tone: "success" },
110
- { label: "Total", value: 19, onClick: noop, ariaLabel: "Show all" },
117
+ { label: "Total", value: 19, onClick: noop, actionHint: "Shows all orders" },
111
118
  ]}
112
119
  />
113
120
  ),
114
121
  },
122
+ {
123
+ // A skeleton has no text; the marker is its busy state.
124
+ name: "KpiGridSkeleton",
125
+ marker: 'aria-busy="true"',
126
+ render: () => <KpiGridSkeleton cells={4} boxed />,
127
+ },
115
128
  {
116
129
  name: "LivePill",
117
130
  marker: "RC:LivePill",
@@ -122,6 +135,11 @@ export const RENDER_CASES: RenderCase[] = [
122
135
  marker: "RC:CountPill",
123
136
  render: () => <CountPill tone="warning">RC:CountPill</CountPill>,
124
137
  },
138
+ {
139
+ name: "StatusBadge",
140
+ marker: "RC:StatusBadge",
141
+ render: () => <StatusBadge tone="warning">RC:StatusBadge</StatusBadge>,
142
+ },
125
143
  {
126
144
  name: "SectionHeading",
127
145
  marker: "RC:SectionHeading",
@@ -132,9 +150,9 @@ export const RENDER_CASES: RenderCase[] = [
132
150
  marker: "RC:WidgetHeader",
133
151
  render: () => (
134
152
  <WidgetHeader
135
- icon="✓"
136
- iconTone="info"
153
+ as="h2"
137
154
  title="RC:WidgetHeader"
155
+ badge={<StatusBadge tone="info">Running</StatusBadge>}
138
156
  sub={<LivePill>Live</LivePill>}
139
157
  actions={
140
158
  <Button size="sm" variant="ghost" onClick={noop}>
@@ -174,7 +192,7 @@ export const RENDER_CASES: RenderCase[] = [
174
192
  name: "DrillButton",
175
193
  marker: "RC:DrillButton",
176
194
  render: () => (
177
- <DrillButton onDrill={noop} icon="↗" size="sm" ariaLabel="Open order o-1001">
195
+ <DrillButton onDrill={noop} icon={<ExternalLink />} size="sm" ariaLabel="Open order o-1001">
178
196
  RC:DrillButton
179
197
  </DrillButton>
180
198
  ),
@@ -184,6 +202,64 @@ export const RENDER_CASES: RenderCase[] = [
184
202
  marker: "of 42 tasks",
185
203
  render: () => <ListFooter shown={8} total={42} hasMore onLoadMore={noop} noun="tasks" />,
186
204
  },
205
+ {
206
+ name: "PagedListFooter",
207
+ marker: "of 3 orders",
208
+ render: () => (
209
+ <PagedListFooter
210
+ paged={{
211
+ items: ["o-1", "o-2"],
212
+ total: 3,
213
+ hasMore: true,
214
+ loadMore: noop,
215
+ refreshing: true,
216
+ firstPage: {},
217
+ loadMoreError: new Error("HTTP 503"),
218
+ }}
219
+ noun="orders"
220
+ />
221
+ ),
222
+ },
223
+
224
+ // ── Feedback and states ──
225
+ {
226
+ // The provider renders its children plus the (empty) live region.
227
+ name: "ToastProvider",
228
+ marker: "RC:ToastProvider",
229
+ render: () => (
230
+ <ToastProvider>
231
+ <div>RC:ToastProvider</div>
232
+ </ToastProvider>
233
+ ),
234
+ },
235
+ {
236
+ name: "EmptyState",
237
+ marker: "RC:EmptyState",
238
+ render: () => (
239
+ <EmptyState
240
+ icon={<Inbox />}
241
+ title="RC:EmptyState"
242
+ description="No orders in this period."
243
+ action={
244
+ <Button size="sm" onClick={noop}>
245
+ New order
246
+ </Button>
247
+ }
248
+ />
249
+ ),
250
+ },
251
+ {
252
+ name: "ErrorState",
253
+ marker: "RC:ErrorState",
254
+ render: () => (
255
+ <ErrorState
256
+ title="RC:ErrorState"
257
+ description="Check the connection and try again."
258
+ details="HTTP 503 Service Unavailable"
259
+ onRetry={noop}
260
+ />
261
+ ),
262
+ },
187
263
 
188
264
  // ── Host seam / providers ──
189
265
  {
@@ -212,7 +288,7 @@ export const RENDER_CASES: RenderCase[] = [
212
288
  name: "ThemeProvider",
213
289
  marker: "RC:ThemeProvider",
214
290
  render: () => (
215
- <ThemeProvider theme={themePresets.miragon} mode="dark">
291
+ <ThemeProvider theme={themePresets.emerald} mode="dark">
216
292
  <div>RC:ThemeProvider</div>
217
293
  </ThemeProvider>
218
294
  ),
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Effect-running renders for the WIRING tests SSR cannot see: effects,
3
+ * subscriptions and timers of the view lifecycle and the data hooks
4
+ * (toolkit#176 review). `react-dom/client` + `act` in a test file that opts
5
+ * into a DOM with `// @vitest-environment happy-dom`. Not an interaction kit:
6
+ * the house render path stays SSR (`renderToStaticMarkup`), and these tests
7
+ * drive hooks through their inputs; a `click()` only where the wiring starts
8
+ * at a button.
9
+ */
10
+ import { act, useEffect, type ReactNode } from "react"
11
+ import { createRoot } from "react-dom/client"
12
+
13
+ // React warns about updates outside act() unless the runtime says it is a test.
14
+ ;(globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean }).IS_REACT_ACT_ENVIRONMENT = true
15
+
16
+ /**
17
+ * Run `work` in an ASYNC act scope: the promises it starts (a tool call that
18
+ * resolves, a state update after it) settle, and their renders commit,
19
+ * before the scope ends.
20
+ */
21
+ export function inAct(work: () => unknown): Promise<void> {
22
+ return act(() => {
23
+ work()
24
+ return Promise.resolve()
25
+ })
26
+ }
27
+
28
+ export interface EffectRender {
29
+ container: HTMLElement
30
+ /** Render `node` into the same root (a new host state, new props). */
31
+ rerender: (node: ReactNode) => Promise<void>
32
+ /** Unmount and run the cleanups; a second call does nothing. */
33
+ unmount: () => Promise<void>
34
+ }
35
+
36
+ /** Mount `node` and run its effects. */
37
+ export async function renderWithEffects(node: ReactNode): Promise<EffectRender> {
38
+ const container = document.createElement("div")
39
+ document.body.append(container)
40
+ const root = createRoot(container)
41
+ await inAct(() => root.render(node))
42
+ let mounted = true
43
+ return {
44
+ container,
45
+ rerender: (next) => inAct(() => root.render(next)),
46
+ unmount: async () => {
47
+ if (!mounted) return
48
+ mounted = false
49
+ await inAct(() => root.unmount())
50
+ container.remove()
51
+ },
52
+ }
53
+ }
54
+
55
+ /**
56
+ * Settle pending promises and the effects and renders they cause, with real
57
+ * timers: TanStack Query notifies its observers on a 0 ms timer, so each
58
+ * round lets one land (under fake timers use {@link advanceTimers}).
59
+ */
60
+ export async function flushEffects(rounds = 3): Promise<void> {
61
+ for (let round = 0; round < rounds; round++) {
62
+ await act(async () => {
63
+ await new Promise((resolve) => setTimeout(resolve, 0))
64
+ })
65
+ }
66
+ }
67
+
68
+ /** Advance fake timers by `ms` inside act, so the renders they cause commit. */
69
+ export function advanceTimers(advance: (ms: number) => unknown, ms: number): Promise<void> {
70
+ return inAct(() => advance(ms))
71
+ }
72
+
73
+ /**
74
+ * Renders `useValue` in a probe and keeps its latest committed value: read
75
+ * `current` after a render or flush.
76
+ */
77
+ export function hookProbe<T>(useValue: () => T): {
78
+ Probe: () => null
79
+ current: () => T
80
+ } {
81
+ const box: { value?: { current: T } } = {}
82
+ function Probe(): null {
83
+ const value = useValue()
84
+ useEffect(() => {
85
+ box.value = { current: value }
86
+ })
87
+ return null
88
+ }
89
+ return {
90
+ Probe,
91
+ current: () => {
92
+ if (!box.value) throw new Error("the probe has not committed yet")
93
+ return box.value.current
94
+ },
95
+ }
96
+ }
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Read SSR markup (`renderToStaticMarkup`) the way a user — sighted or with a
3
+ * screen reader — meets it: its text nodes plus the attributes that carry
4
+ * text (accessible names, tooltips, placeholders). DATA/TEST support module
5
+ * like `render-cases.tsx`: the a11y and i18n render suites scan through it,
6
+ * so it stays pure and dependency-free. React's SSR output is well-formed
7
+ * (attributes always double-quoted), which is what keeps these regexes honest.
8
+ */
9
+
10
+ /** Attributes whose value a user reads or hears. */
11
+ export const TEXT_ATTRIBUTES = [
12
+ "aria-label",
13
+ "aria-description",
14
+ "aria-roledescription",
15
+ "aria-valuetext",
16
+ "title",
17
+ "placeholder",
18
+ "alt",
19
+ ] as const
20
+
21
+ const NAMED_ENTITIES: Record<string, string> = {
22
+ amp: "&",
23
+ lt: "<",
24
+ gt: ">",
25
+ quot: '"',
26
+ apos: "'",
27
+ nbsp: " ",
28
+ }
29
+
30
+ /** Decode the HTML entities React's SSR emits (named, decimal and hex). */
31
+ export function decodeEntities(text: string): string {
32
+ return text.replace(/&(#x[0-9a-f]+|#\d+|[a-z]+);/gi, (whole, ref: string) => {
33
+ if (ref.startsWith("#x") || ref.startsWith("#X")) {
34
+ return String.fromCodePoint(Number.parseInt(ref.slice(2), 16))
35
+ }
36
+ if (ref.startsWith("#")) return String.fromCodePoint(Number.parseInt(ref.slice(1), 10))
37
+ return NAMED_ENTITIES[ref.toLowerCase()] ?? whole
38
+ })
39
+ }
40
+
41
+ /** One piece of user-facing text in the markup. */
42
+ export interface MarkupText {
43
+ /** `"text"` for a text node, else the attribute name. */
44
+ source: string
45
+ value: string
46
+ }
47
+
48
+ /** Every non-blank text node and text-bearing attribute value, decoded. */
49
+ export function userFacingTexts(html: string): MarkupText[] {
50
+ const out: MarkupText[] = []
51
+ const withoutRawText = html.replace(/<(script|style)\b[^>]*>[\s\S]*?<\/\1>/gi, "")
52
+ for (const chunk of withoutRawText.split(/<[^>]*>/)) {
53
+ const value = decodeEntities(chunk).trim()
54
+ if (value) out.push({ source: "text", value })
55
+ }
56
+ for (const tag of withoutRawText.match(/<[a-z][^>]*>/gi) ?? []) {
57
+ for (const name of TEXT_ATTRIBUTES) {
58
+ const value = attribute(tag, name)
59
+ if (value?.trim()) out.push({ source: name, value: value.trim() })
60
+ }
61
+ }
62
+ return out
63
+ }
64
+
65
+ /** The opening tags of every element named `tag` (e.g. `"button"`). */
66
+ export function openingTags(html: string, tag: string): string[] {
67
+ return html.match(new RegExp(`<${tag}(?=[\\s>/])[^>]*>`, "gi")) ?? []
68
+ }
69
+
70
+ /** The decoded value of `name` on one opening tag, `undefined` when absent. */
71
+ export function attribute(openingTag: string, name: string): string | undefined {
72
+ const escaped = name.replace(/[-]/g, "\\-")
73
+ const match = new RegExp(`\\s${escaped}="([^"]*)"`, "i").exec(openingTag)
74
+ return match ? decodeEntities(match[1] ?? "") : undefined
75
+ }
@@ -0,0 +1,48 @@
1
+ /* Aus Miragon/corporate-identity übernommen (miragon-brand 1.8.0, modeler-tool-design/assets/cd-tokens.generated.css). Nicht ändern, zum Aktualisieren neu aus der Skill kopieren. */
2
+ /* AUTOMATISCH GENERIERT aus brand/tokens.json. Nicht von Hand ändern, sondern die Quelle bearbeiten und `npm run tokens:build` laufen lassen. */
3
+ :root {
4
+ --cd-blau: #335DE5;
5
+ --cd-gruen: #00E676;
6
+ --cd-grau: #F9F7F7;
7
+ --cd-schwarz: #1D1D1D;
8
+ --cd-weiss: #FFFFFF;
9
+ --cd-blau-link: #2B50D4;
10
+ --cd-blau-hell: #6B8AFF;
11
+ --cd-success: #00E676;
12
+ --cd-success-soft: #DAFBEB;
13
+ --cd-success-hell: #00E676;
14
+ --cd-warning: #FFB000;
15
+ --cd-warning-soft: #FFF1D2;
16
+ --cd-warning-hell: #FFB000;
17
+ --cd-danger: #CD1839;
18
+ --cd-danger-soft: #FBEEF0;
19
+ --cd-danger-hell: #FB6D73;
20
+ --cd-info: #335DE5;
21
+ --cd-info-soft: #EEF1FD;
22
+ --cd-info-hell: #6B8AFF;
23
+ --cd-linie: #E6E2E2;
24
+ --cd-kontur: #8F8A8A;
25
+ --cd-text-leise: #6B6666;
26
+ --cd-gradient-brand: linear-gradient(120deg, #335DE5 30%, #00E676);
27
+ --cd-gradient-format: linear-gradient(135deg, #335DE5 0%, #00E676 140%);
28
+ --cd-space-1: 4px;
29
+ --cd-space-2: 8px;
30
+ --cd-space-3: 16px;
31
+ --cd-space-4: 24px;
32
+ --cd-space-5: 32px;
33
+ --cd-space-6: 48px;
34
+ --cd-space-7: 64px;
35
+ --cd-space-8: 96px;
36
+ --cd-radius-sm: 6px;
37
+ --cd-radius-md: 12px;
38
+ --cd-radius-lg: 16px;
39
+ --cd-radius-pill: 999px;
40
+ --cd-shadow-1: 0 1px 2px rgba(29, 29, 29, 0.06), 0 1px 3px rgba(29, 29, 29, 0.10);
41
+ --cd-shadow-2: 0 4px 12px rgba(29, 29, 29, 0.10);
42
+ --cd-shadow-3: 0 12px 32px rgba(29, 29, 29, 0.16);
43
+ --cd-motion-fast: 150ms;
44
+ --cd-motion-base: 250ms;
45
+ --cd-motion-slow: 400ms;
46
+ --cd-ease: cubic-bezier(0.4, 0, 0.2, 1);
47
+ --cd-ease-out: cubic-bezier(0, 0, 0.2, 1);
48
+ }
@@ -0,0 +1,109 @@
1
+ /// <reference types="node" />
2
+ import { createHash } from "node:crypto"
3
+ import { existsSync, readdirSync, readFileSync } from "node:fs"
4
+ import { homedir } from "node:os"
5
+ import { join } from "node:path"
6
+ import { describe, expect, it } from "vitest"
7
+ import { CD_TOKENS, CD_TOKENS_VERSION } from "./cd-tokens.js"
8
+
9
+ /**
10
+ * Drift guard for the vendored Miragon corporate-design tokens
11
+ * (modeler-tool-design §13): the copy must stay the skill's file, unchanged.
12
+ *
13
+ * `cd-tokens.generated.css` = ONE marker line + the upstream file byte for
14
+ * byte. Upstream is miragon-brand's `modeler-tool-design/assets/
15
+ * cd-tokens.generated.css`. When a checkout of the plugin is reachable
16
+ * (`MIRAGON_CD_TOKENS` or a Claude plugin cache under $HOME), the copy is
17
+ * compared to it directly; everywhere else (CI) the pinned hash below holds it.
18
+ *
19
+ * To re-vendor: copy the new upstream file below the marker line, update the
20
+ * version in the marker, CD_TOKENS_VERSION, UPSTREAM_SHA256 and CD_TOKENS,
21
+ * then copy the result to docs/.vitepress/theme/ (the docs site vendors the
22
+ * same file; examples/test/docs-theme.test.ts holds the two byte-identical).
23
+ */
24
+ const UPSTREAM_SHA256 = "36d76f3a330a1250d332c6862be1dc4f7564d2461e7051d9a565ba723ef2c379"
25
+ const UPSTREAM_REL = join("skills", "modeler-tool-design", "assets", "cd-tokens.generated.css")
26
+ const MARKER =
27
+ `/* Aus Miragon/corporate-identity übernommen (miragon-brand ${CD_TOKENS_VERSION}, ` +
28
+ "modeler-tool-design/assets/cd-tokens.generated.css). Nicht ändern, zum Aktualisieren neu aus der Skill kopieren. */\n"
29
+
30
+ const vendored = readFileSync(new URL("./cd-tokens.generated.css", import.meta.url), "utf8")
31
+ const upstreamPart = vendored.slice(MARKER.length)
32
+
33
+ /** A reachable upstream copy of this version, or null (CI). */
34
+ function findUpstream(): string | null {
35
+ const explicit = process.env.MIRAGON_CD_TOKENS
36
+ if (explicit) return existsSync(explicit) ? explicit : null
37
+ const home = homedir()
38
+ let entries: string[]
39
+ try {
40
+ entries = readdirSync(home).filter((name) => name.startsWith(".claude"))
41
+ } catch {
42
+ return null
43
+ }
44
+ for (const dir of entries) {
45
+ const candidate = join(
46
+ home,
47
+ dir,
48
+ "plugins",
49
+ "cache",
50
+ "miragon-agent-skills",
51
+ "miragon-brand",
52
+ CD_TOKENS_VERSION,
53
+ UPSTREAM_REL,
54
+ )
55
+ if (existsSync(candidate)) return candidate
56
+ }
57
+ return null
58
+ }
59
+
60
+ /** `--cd-name: value;` declarations of the vendored `:root`. */
61
+ function cssTokens(css: string): Record<string, string> {
62
+ const out: Record<string, string> = {}
63
+ for (const match of css.matchAll(/--cd-([a-z0-9-]+):\s*([^;]+);/g)) {
64
+ out[match[1] as string] = (match[2] as string).trim()
65
+ }
66
+ return out
67
+ }
68
+
69
+ describe("cd-tokens.generated.css (vendored, never edited)", () => {
70
+ it("starts with the generated-file marker naming the brand version", () => {
71
+ expect(vendored.startsWith(MARKER)).toBe(true)
72
+ })
73
+
74
+ it("is the upstream file byte for byte below the marker (pinned hash)", () => {
75
+ const hash = createHash("sha256").update(upstreamPart, "utf8").digest("hex")
76
+ expect(hash, "re-vendor from the skill instead of editing the copy").toBe(UPSTREAM_SHA256)
77
+ })
78
+
79
+ it("is byte-identical to the skill's file when a plugin checkout is reachable", () => {
80
+ const upstream = findUpstream()
81
+ // Off-machine (CI) the pinned hash above is the guard; say so loudly.
82
+ if (!upstream) {
83
+ console.warn(
84
+ `cd-tokens drift: no miragon-brand ${CD_TOKENS_VERSION} checkout found — relying on the pinned hash`,
85
+ )
86
+ return
87
+ }
88
+ expect(upstreamPart).toBe(readFileSync(upstream, "utf8"))
89
+ })
90
+ })
91
+
92
+ describe("CD_TOKENS (the TS mirror of :root)", () => {
93
+ const css = cssTokens(upstreamPart)
94
+
95
+ it("mirrors every --cd-* token value exactly", () => {
96
+ for (const [name, value] of Object.entries(css)) {
97
+ expect(CD_TOKENS[name as keyof typeof CD_TOKENS], `--cd-${name}`).toBe(value)
98
+ }
99
+ })
100
+
101
+ it("declares no token the CSS does not", () => {
102
+ expect(Object.keys(CD_TOKENS).sort()).toEqual(Object.keys(css).sort())
103
+ })
104
+
105
+ it("parses a non-trivial token set (the parser itself is alive)", () => {
106
+ expect(Object.keys(css).length).toBeGreaterThanOrEqual(40)
107
+ expect(css.blau).toBe("#335DE5")
108
+ })
109
+ })
@@ -0,0 +1,67 @@
1
+ /**
2
+ * The Miragon corporate-design tokens (`--cd-*`) as plain TypeScript, for code
3
+ * that cannot read CSS variables — an SVG or canvas renderer (BPMN overlays,
4
+ * chart marks), a server-side image, a test. Keys are the CSS names without the
5
+ * `--cd-` prefix.
6
+ *
7
+ * The source of truth is the vendored `cd-tokens.generated.css` next to this
8
+ * file (miragon-brand 1.8.0, copied unchanged from Miragon/corporate-identity).
9
+ * This module mirrors it value for value; `cd-tokens.test.ts` fails on any
10
+ * drift (modeler-tool-design §13). Never edit a value here without re-vendoring
11
+ * the CSS first.
12
+ *
13
+ * UI code styles through the role tokens (`bg-primary`, `text-link`,
14
+ * `border-danger`, …), never through these constants.
15
+ */
16
+ export const CD_TOKENS = {
17
+ blau: "#335DE5",
18
+ gruen: "#00E676",
19
+ grau: "#F9F7F7",
20
+ schwarz: "#1D1D1D",
21
+ weiss: "#FFFFFF",
22
+ "blau-link": "#2B50D4",
23
+ "blau-hell": "#6B8AFF",
24
+ success: "#00E676",
25
+ "success-soft": "#DAFBEB",
26
+ "success-hell": "#00E676",
27
+ warning: "#FFB000",
28
+ "warning-soft": "#FFF1D2",
29
+ "warning-hell": "#FFB000",
30
+ danger: "#CD1839",
31
+ "danger-soft": "#FBEEF0",
32
+ "danger-hell": "#FB6D73",
33
+ info: "#335DE5",
34
+ "info-soft": "#EEF1FD",
35
+ "info-hell": "#6B8AFF",
36
+ linie: "#E6E2E2",
37
+ kontur: "#8F8A8A",
38
+ "text-leise": "#6B6666",
39
+ "gradient-brand": "linear-gradient(120deg, #335DE5 30%, #00E676)",
40
+ "gradient-format": "linear-gradient(135deg, #335DE5 0%, #00E676 140%)",
41
+ "space-1": "4px",
42
+ "space-2": "8px",
43
+ "space-3": "16px",
44
+ "space-4": "24px",
45
+ "space-5": "32px",
46
+ "space-6": "48px",
47
+ "space-7": "64px",
48
+ "space-8": "96px",
49
+ "radius-sm": "6px",
50
+ "radius-md": "12px",
51
+ "radius-lg": "16px",
52
+ "radius-pill": "999px",
53
+ "shadow-1": "0 1px 2px rgba(29, 29, 29, 0.06), 0 1px 3px rgba(29, 29, 29, 0.10)",
54
+ "shadow-2": "0 4px 12px rgba(29, 29, 29, 0.10)",
55
+ "shadow-3": "0 12px 32px rgba(29, 29, 29, 0.16)",
56
+ "motion-fast": "150ms",
57
+ "motion-base": "250ms",
58
+ "motion-slow": "400ms",
59
+ ease: "cubic-bezier(0.4, 0, 0.2, 1)",
60
+ "ease-out": "cubic-bezier(0, 0, 0.2, 1)",
61
+ } as const
62
+
63
+ /** A key of {@link CD_TOKENS} — the `--cd-*` name without its prefix. */
64
+ export type CdTokenName = keyof typeof CD_TOKENS
65
+
66
+ /** The miragon-brand release the vendored tokens come from. */
67
+ export const CD_TOKENS_VERSION = "1.8.0"