@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.
- package/README.md +14 -5
- package/dist/app/adapt-data-widget.d.ts +1 -22
- package/dist/app/adapt-data-widget.d.ts.map +1 -1
- package/dist/app/adapt-data-widget.js +1 -35
- package/dist/app/adapt-data-widget.js.map +1 -1
- package/dist/app/builder/BuilderBanners.d.ts +7 -2
- package/dist/app/builder/BuilderBanners.d.ts.map +1 -1
- package/dist/app/builder/BuilderBanners.js +8 -3
- package/dist/app/builder/BuilderBanners.js.map +1 -1
- package/dist/app/builder/CanvasRow.d.ts +4 -2
- package/dist/app/builder/CanvasRow.d.ts.map +1 -1
- package/dist/app/builder/CanvasRow.js +29 -17
- package/dist/app/builder/CanvasRow.js.map +1 -1
- package/dist/app/builder/CatalogueSheet.d.ts.map +1 -1
- package/dist/app/builder/CatalogueSheet.js +14 -6
- package/dist/app/builder/CatalogueSheet.js.map +1 -1
- package/dist/app/builder/CellPropsSheet.d.ts +7 -3
- package/dist/app/builder/CellPropsSheet.d.ts.map +1 -1
- package/dist/app/builder/CellPropsSheet.js +10 -3
- package/dist/app/builder/CellPropsSheet.js.map +1 -1
- package/dist/app/builder/DiscardDialog.d.ts +18 -0
- package/dist/app/builder/DiscardDialog.d.ts.map +1 -0
- package/dist/app/builder/DiscardDialog.js +18 -0
- package/dist/app/builder/DiscardDialog.js.map +1 -0
- package/dist/app/builder/EmptyHint.d.ts +4 -0
- package/dist/app/builder/EmptyHint.d.ts.map +1 -1
- package/dist/app/builder/EmptyHint.js +6 -1
- package/dist/app/builder/EmptyHint.js.map +1 -1
- package/dist/app/builder/LayoutSurface.d.ts +33 -9
- package/dist/app/builder/LayoutSurface.d.ts.map +1 -1
- package/dist/app/builder/LayoutSurface.js +74 -23
- package/dist/app/builder/LayoutSurface.js.map +1 -1
- package/dist/app/builder/PipelineStrip.d.ts +5 -2
- package/dist/app/builder/PipelineStrip.d.ts.map +1 -1
- package/dist/app/builder/PipelineStrip.js +33 -15
- package/dist/app/builder/PipelineStrip.js.map +1 -1
- package/dist/app/builder/SaveDialog.d.ts +9 -1
- package/dist/app/builder/SaveDialog.d.ts.map +1 -1
- package/dist/app/builder/SaveDialog.js +9 -3
- package/dist/app/builder/SaveDialog.js.map +1 -1
- package/dist/app/builder/Toolbar.d.ts +14 -4
- package/dist/app/builder/Toolbar.d.ts.map +1 -1
- package/dist/app/builder/Toolbar.js +24 -7
- package/dist/app/builder/Toolbar.js.map +1 -1
- package/dist/app/builder/Workspace.d.ts +23 -3
- package/dist/app/builder/Workspace.d.ts.map +1 -1
- package/dist/app/builder/Workspace.js +58 -8
- package/dist/app/builder/Workspace.js.map +1 -1
- package/dist/app/builder/builder-model.d.ts +146 -3
- package/dist/app/builder/builder-model.d.ts.map +1 -1
- package/dist/app/builder/builder-model.js +196 -5
- package/dist/app/builder/builder-model.js.map +1 -1
- package/dist/app/builder/labels.d.ts +13 -62
- package/dist/app/builder/labels.d.ts.map +1 -1
- package/dist/app/builder/labels.js +9 -58
- package/dist/app/builder/labels.js.map +1 -1
- package/dist/app/builder/reveal.d.ts +10 -0
- package/dist/app/builder/reveal.d.ts.map +1 -0
- package/dist/app/builder/reveal.js +10 -0
- package/dist/app/builder/reveal.js.map +1 -0
- package/dist/app/builder/status-chip.d.ts.map +1 -1
- package/dist/app/builder/status-chip.js +3 -2
- package/dist/app/builder/status-chip.js.map +1 -1
- package/dist/app/builder/use-builder-catalogue.d.ts +5 -1
- package/dist/app/builder/use-builder-catalogue.d.ts.map +1 -1
- package/dist/app/builder/use-builder-catalogue.js +50 -17
- package/dist/app/builder/use-builder-catalogue.js.map +1 -1
- package/dist/app/builder/use-builder-session.d.ts +30 -0
- package/dist/app/builder/use-builder-session.d.ts.map +1 -0
- package/dist/app/builder/use-builder-session.js +58 -0
- package/dist/app/builder/use-builder-session.js.map +1 -0
- package/dist/app/builder/use-display-resolver.d.ts +17 -0
- package/dist/app/builder/use-display-resolver.d.ts.map +1 -0
- package/dist/app/builder/use-display-resolver.js +16 -0
- package/dist/app/builder/use-display-resolver.js.map +1 -0
- package/dist/app/builder/use-save-dashboard.d.ts +3 -1
- package/dist/app/builder/use-save-dashboard.d.ts.map +1 -1
- package/dist/app/builder/use-save-dashboard.js +3 -1
- package/dist/app/builder/use-save-dashboard.js.map +1 -1
- package/dist/app/index.d.ts +8 -3
- package/dist/app/index.d.ts.map +1 -1
- package/dist/app/index.js +8 -2
- package/dist/app/index.js.map +1 -1
- package/dist/app/layout-builder.d.ts +18 -25
- package/dist/app/layout-builder.d.ts.map +1 -1
- package/dist/app/layout-builder.js +84 -78
- package/dist/app/layout-builder.js.map +1 -1
- package/dist/app/mcp-app-view-chrome.d.ts +103 -20
- package/dist/app/mcp-app-view-chrome.d.ts.map +1 -1
- package/dist/app/mcp-app-view-chrome.js +125 -40
- package/dist/app/mcp-app-view-chrome.js.map +1 -1
- package/dist/app/mcp-app-view-states.d.ts +23 -0
- package/dist/app/mcp-app-view-states.d.ts.map +1 -0
- package/dist/app/mcp-app-view-states.js +55 -0
- package/dist/app/mcp-app-view-states.js.map +1 -0
- package/dist/app/mcp-app-view.d.ts +72 -5
- package/dist/app/mcp-app-view.d.ts.map +1 -1
- package/dist/app/mcp-app-view.js +241 -141
- package/dist/app/mcp-app-view.js.map +1 -1
- package/dist/app/mcp-toolkit-app.d.ts +8 -2
- package/dist/app/mcp-toolkit-app.d.ts.map +1 -1
- package/dist/app/mcp-toolkit-app.js +33 -4
- package/dist/app/mcp-toolkit-app.js.map +1 -1
- package/dist/app/mcp-use-host-bridge.d.ts +15 -6
- package/dist/app/mcp-use-host-bridge.d.ts.map +1 -1
- package/dist/app/mcp-use-host-bridge.js +51 -22
- package/dist/app/mcp-use-host-bridge.js.map +1 -1
- package/dist/app/model-context.d.ts +71 -0
- package/dist/app/model-context.d.ts.map +1 -0
- package/dist/app/model-context.js +101 -0
- package/dist/app/model-context.js.map +1 -0
- package/dist/app/use-build-mode-focus.d.ts +33 -0
- package/dist/app/use-build-mode-focus.d.ts.map +1 -0
- package/dist/app/use-build-mode-focus.js +59 -0
- package/dist/app/use-build-mode-focus.js.map +1 -0
- package/dist/app/use-view-actions.d.ts +31 -0
- package/dist/app/use-view-actions.d.ts.map +1 -0
- package/dist/app/use-view-actions.js +81 -0
- package/dist/app/use-view-actions.js.map +1 -0
- package/dist/app/use-view-lifecycle.d.ts +42 -0
- package/dist/app/use-view-lifecycle.d.ts.map +1 -0
- package/dist/app/use-view-lifecycle.js +81 -0
- package/dist/app/use-view-lifecycle.js.map +1 -0
- package/dist/app/view-lifecycle.d.ts +185 -0
- package/dist/app/view-lifecycle.d.ts.map +1 -0
- package/dist/app/view-lifecycle.js +207 -0
- package/dist/app/view-lifecycle.js.map +1 -0
- package/dist/app/widget-fixture.d.ts +10 -3
- package/dist/app/widget-fixture.d.ts.map +1 -1
- package/dist/app/widget-fixture.js +21 -8
- package/dist/app/widget-fixture.js.map +1 -1
- package/dist/app/widget-props-sheet.d.ts +6 -10
- package/dist/app/widget-props-sheet.d.ts.map +1 -1
- package/dist/app/widget-props-sheet.js +25 -20
- package/dist/app/widget-props-sheet.js.map +1 -1
- package/dist/app/widget-renderer.d.ts +41 -1
- package/dist/app/widget-renderer.d.ts.map +1 -1
- package/dist/app/widget-renderer.js +82 -31
- package/dist/app/widget-renderer.js.map +1 -1
- package/dist/components/DrillButton.d.ts +9 -6
- package/dist/components/DrillButton.d.ts.map +1 -1
- package/dist/components/DrillButton.js +9 -6
- package/dist/components/DrillButton.js.map +1 -1
- package/dist/components/EmptyState.d.ts +33 -0
- package/dist/components/EmptyState.d.ts.map +1 -0
- package/dist/components/EmptyState.js +19 -0
- package/dist/components/EmptyState.js.map +1 -0
- package/dist/components/ErrorState.d.ts +53 -0
- package/dist/components/ErrorState.d.ts.map +1 -0
- package/dist/components/ErrorState.js +77 -0
- package/dist/components/ErrorState.js.map +1 -0
- package/dist/components/FilterBar.d.ts +16 -5
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +13 -5
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/GroupCard.d.ts.map +1 -1
- package/dist/components/GroupCard.js +2 -1
- package/dist/components/GroupCard.js.map +1 -1
- package/dist/components/KpiGrid.d.ts +70 -18
- package/dist/components/KpiGrid.d.ts.map +1 -1
- package/dist/components/KpiGrid.js +112 -23
- package/dist/components/KpiGrid.js.map +1 -1
- package/dist/components/ListFooter.d.ts +32 -4
- package/dist/components/ListFooter.d.ts.map +1 -1
- package/dist/components/ListFooter.js +35 -6
- package/dist/components/ListFooter.js.map +1 -1
- package/dist/components/PagedListFooter.d.ts +57 -0
- package/dist/components/PagedListFooter.d.ts.map +1 -0
- package/dist/components/PagedListFooter.js +27 -0
- package/dist/components/PagedListFooter.js.map +1 -0
- package/dist/components/Pills.d.ts +36 -12
- package/dist/components/Pills.d.ts.map +1 -1
- package/dist/components/Pills.js +29 -8
- package/dist/components/Pills.js.map +1 -1
- package/dist/components/SectionHeading.d.ts +3 -1
- package/dist/components/SectionHeading.d.ts.map +1 -1
- package/dist/components/SectionHeading.js +6 -2
- package/dist/components/SectionHeading.js.map +1 -1
- package/dist/components/Toast.d.ts +43 -0
- package/dist/components/Toast.d.ts.map +1 -0
- package/dist/components/Toast.js +106 -0
- package/dist/components/Toast.js.map +1 -0
- package/dist/components/WidgetHeader.d.ts +34 -10
- package/dist/components/WidgetHeader.d.ts.map +1 -1
- package/dist/components/WidgetHeader.js +11 -6
- package/dist/components/WidgetHeader.js.map +1 -1
- package/dist/hooks/index.d.ts +4 -4
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/tool-result-recovery-model.d.ts +155 -0
- package/dist/hooks/tool-result-recovery-model.d.ts.map +1 -0
- package/dist/hooks/tool-result-recovery-model.js +273 -0
- package/dist/hooks/tool-result-recovery-model.js.map +1 -0
- package/dist/hooks/use-tool-query.d.ts +56 -14
- package/dist/hooks/use-tool-query.d.ts.map +1 -1
- package/dist/hooks/use-tool-query.js +102 -25
- package/dist/hooks/use-tool-query.js.map +1 -1
- package/dist/hooks/use-tool-result-recovery.d.ts +61 -44
- package/dist/hooks/use-tool-result-recovery.d.ts.map +1 -1
- package/dist/hooks/use-tool-result-recovery.js +62 -110
- package/dist/hooks/use-tool-result-recovery.js.map +1 -1
- package/dist/hooks/use-view-data.d.ts +55 -7
- package/dist/hooks/use-view-data.d.ts.map +1 -1
- package/dist/hooks/use-view-data.js +81 -11
- package/dist/hooks/use-view-data.js.map +1 -1
- package/dist/hooks/use-view-tool-query.d.ts +12 -7
- package/dist/hooks/use-view-tool-query.d.ts.map +1 -1
- package/dist/hooks/use-view-tool-query.js +15 -14
- package/dist/hooks/use-view-tool-query.js.map +1 -1
- package/dist/index.d.ts +27 -13
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +29 -7
- package/dist/index.js.map +1 -1
- package/dist/lib/focus-return.d.ts +61 -0
- package/dist/lib/focus-return.d.ts.map +1 -0
- package/dist/lib/focus-return.js +46 -0
- package/dist/lib/focus-return.js.map +1 -0
- package/dist/lib/focus-ring.d.ts +18 -0
- package/dist/lib/focus-ring.d.ts.map +1 -0
- package/dist/lib/focus-ring.js +18 -0
- package/dist/lib/focus-ring.js.map +1 -0
- package/dist/lib/icon-stroke.d.ts +12 -0
- package/dist/lib/icon-stroke.d.ts.map +1 -0
- package/dist/lib/icon-stroke.js +12 -0
- package/dist/lib/icon-stroke.js.map +1 -0
- package/dist/lib/parse-tool-result.d.ts +23 -1
- package/dist/lib/parse-tool-result.d.ts.map +1 -1
- package/dist/lib/parse-tool-result.js +38 -2
- package/dist/lib/parse-tool-result.js.map +1 -1
- package/dist/lib/toast-model.d.ts +86 -0
- package/dist/lib/toast-model.d.ts.map +1 -0
- package/dist/lib/toast-model.js +102 -0
- package/dist/lib/toast-model.js.map +1 -0
- package/dist/lib/tone-utils.d.ts +95 -9
- package/dist/lib/tone-utils.d.ts.map +1 -1
- package/dist/lib/tone-utils.js +100 -9
- package/dist/lib/tone-utils.js.map +1 -1
- package/dist/lib/tool-query.d.ts +107 -0
- package/dist/lib/tool-query.d.ts.map +1 -0
- package/dist/lib/tool-query.js +182 -0
- package/dist/lib/tool-query.js.map +1 -0
- package/dist/lib/tool-result-observer.d.ts +108 -0
- package/dist/lib/tool-result-observer.d.ts.map +1 -0
- package/dist/lib/tool-result-observer.js +158 -0
- package/dist/lib/tool-result-observer.js.map +1 -0
- package/dist/lib/typography.d.ts +37 -0
- package/dist/lib/typography.d.ts.map +1 -0
- package/dist/lib/typography.js +41 -0
- package/dist/lib/typography.js.map +1 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +11 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/locale/index.d.ts +3 -1
- package/dist/locale/index.d.ts.map +1 -1
- package/dist/locale/index.js +2 -1
- package/dist/locale/index.js.map +1 -1
- package/dist/locale/locale-provider.d.ts +42 -1
- package/dist/locale/locale-provider.d.ts.map +1 -1
- package/dist/locale/locale-provider.js +44 -3
- package/dist/locale/locale-provider.js.map +1 -1
- package/dist/locale/message-types.d.ts +336 -0
- package/dist/locale/message-types.d.ts.map +1 -0
- package/dist/locale/message-types.js +7 -0
- package/dist/locale/message-types.js.map +1 -0
- package/dist/locale/messages-de.d.ts +9 -0
- package/dist/locale/messages-de.d.ts.map +1 -0
- package/dist/locale/messages-de.js +185 -0
- package/dist/locale/messages-de.js.map +1 -0
- package/dist/locale/messages-en.d.ts +8 -0
- package/dist/locale/messages-en.d.ts.map +1 -0
- package/dist/locale/messages-en.js +184 -0
- package/dist/locale/messages-en.js.map +1 -0
- package/dist/locale/toolkit-messages.d.ts +57 -0
- package/dist/locale/toolkit-messages.d.ts.map +1 -0
- package/dist/locale/toolkit-messages.js +103 -0
- package/dist/locale/toolkit-messages.js.map +1 -0
- package/dist/primitives/alert.d.ts +1 -1
- package/dist/primitives/alert.d.ts.map +1 -1
- package/dist/primitives/alert.js +6 -2
- package/dist/primitives/alert.js.map +1 -1
- package/dist/primitives/badge.d.ts +1 -1
- package/dist/primitives/badge.d.ts.map +1 -1
- package/dist/primitives/badge.js +19 -6
- package/dist/primitives/badge.js.map +1 -1
- package/dist/primitives/button.d.ts +1 -1
- package/dist/primitives/button.d.ts.map +1 -1
- package/dist/primitives/button.js +12 -8
- package/dist/primitives/button.js.map +1 -1
- package/dist/primitives/card.js +4 -4
- package/dist/primitives/card.js.map +1 -1
- package/dist/primitives/dialog.d.ts +7 -3
- package/dist/primitives/dialog.d.ts.map +1 -1
- package/dist/primitives/dialog.js +22 -8
- package/dist/primitives/dialog.js.map +1 -1
- package/dist/primitives/input.d.ts.map +1 -1
- package/dist/primitives/input.js +4 -1
- package/dist/primitives/input.js.map +1 -1
- package/dist/primitives/scroll-area.js +1 -1
- package/dist/primitives/scroll-area.js.map +1 -1
- package/dist/primitives/select.d.ts.map +1 -1
- package/dist/primitives/select.js +6 -3
- package/dist/primitives/select.js.map +1 -1
- package/dist/primitives/sheet.d.ts +3 -1
- package/dist/primitives/sheet.d.ts.map +1 -1
- package/dist/primitives/sheet.js +17 -7
- package/dist/primitives/sheet.js.map +1 -1
- package/dist/primitives/skeleton.js +1 -1
- package/dist/primitives/skeleton.js.map +1 -1
- package/dist/primitives/switch.d.ts.map +1 -1
- package/dist/primitives/switch.js +2 -1
- package/dist/primitives/switch.js.map +1 -1
- package/dist/primitives/tabs.d.ts.map +1 -1
- package/dist/primitives/tabs.js +5 -3
- package/dist/primitives/tabs.js.map +1 -1
- package/dist/providers/query-provider.d.ts +32 -1
- package/dist/providers/query-provider.d.ts.map +1 -1
- package/dist/providers/query-provider.js +53 -4
- package/dist/providers/query-provider.js.map +1 -1
- package/dist/render-cases-primitives.js +1 -1
- package/dist/render-cases-primitives.js.map +1 -1
- package/dist/render-cases.d.ts.map +1 -1
- package/dist/render-cases.js +48 -6
- package/dist/render-cases.js.map +1 -1
- package/dist/render-effects.d.ts +42 -0
- package/dist/render-effects.d.ts.map +1 -0
- package/dist/render-effects.js +81 -0
- package/dist/render-effects.js.map +1 -0
- package/dist/render-scan.d.ts +25 -0
- package/dist/render-scan.d.ts.map +1 -0
- package/dist/render-scan.js +66 -0
- package/dist/render-scan.js.map +1 -0
- package/dist/theme/cd-tokens.d.ts +66 -0
- package/dist/theme/cd-tokens.d.ts.map +1 -0
- package/dist/theme/cd-tokens.js +64 -0
- package/dist/theme/cd-tokens.js.map +1 -0
- package/dist/theme/create-theme.d.ts +214 -39
- package/dist/theme/create-theme.d.ts.map +1 -1
- package/dist/theme/create-theme.js +204 -13
- package/dist/theme/create-theme.js.map +1 -1
- package/dist/theme/fonts.d.ts +38 -0
- package/dist/theme/fonts.d.ts.map +1 -0
- package/dist/theme/fonts.js +56 -0
- package/dist/theme/fonts.js.map +1 -0
- package/dist/theme/host-fonts.d.ts +39 -0
- package/dist/theme/host-fonts.d.ts.map +1 -0
- package/dist/theme/host-fonts.js +44 -0
- package/dist/theme/host-fonts.js.map +1 -0
- package/dist/theme/index.d.ts +8 -1
- package/dist/theme/index.d.ts.map +1 -1
- package/dist/theme/index.js +5 -1
- package/dist/theme/index.js.map +1 -1
- package/dist/theme/portal-container.d.ts +16 -0
- package/dist/theme/portal-container.d.ts.map +1 -0
- package/dist/theme/portal-container.js +19 -0
- package/dist/theme/portal-container.js.map +1 -0
- package/dist/theme/presets.d.ts +24 -9
- package/dist/theme/presets.d.ts.map +1 -1
- package/dist/theme/presets.js +44 -11
- package/dist/theme/presets.js.map +1 -1
- package/dist/theme/theme-provider.d.ts +27 -9
- package/dist/theme/theme-provider.d.ts.map +1 -1
- package/dist/theme/theme-provider.js +42 -20
- package/dist/theme/theme-provider.js.map +1 -1
- package/package.json +11 -5
- package/src/app/adapt-data-widget.tsx +2 -42
- package/src/app/builder/BuilderBanners.tsx +26 -13
- package/src/app/builder/CanvasRow.tsx +79 -32
- package/src/app/builder/CatalogueSheet.tsx +58 -35
- package/src/app/builder/CellPropsSheet.tsx +17 -2
- package/src/app/builder/DiscardDialog.tsx +59 -0
- package/src/app/builder/EmptyHint.tsx +16 -11
- package/src/app/builder/LayoutSurface.tsx +207 -67
- package/src/app/builder/PipelineStrip.tsx +265 -156
- package/src/app/builder/SaveDialog.tsx +25 -14
- package/src/app/builder/Toolbar.tsx +154 -57
- package/src/app/builder/Workspace.tsx +226 -56
- package/src/app/builder/builder-feedback.test.tsx +75 -0
- package/src/app/builder/builder-model.test.ts +5 -0
- package/src/app/builder/builder-model.ts +346 -6
- package/src/app/builder/builder-model.ux.test.ts +456 -0
- package/src/app/builder/builder-ux.test.tsx +844 -0
- package/src/app/builder/labels.ts +15 -121
- package/src/app/builder/reveal.ts +10 -0
- package/src/app/builder/status-chip.tsx +8 -4
- package/src/app/builder/use-builder-catalogue.ts +62 -19
- package/src/app/builder/use-builder-session.ts +68 -0
- package/src/app/builder/use-display-resolver.ts +24 -0
- package/src/app/builder/use-save-dashboard.ts +5 -0
- package/src/app/index.ts +20 -3
- package/src/app/layout-builder.tsx +193 -186
- package/src/app/mcp-app-view-chrome.test.tsx +487 -14
- package/src/app/mcp-app-view-chrome.tsx +328 -100
- package/src/app/mcp-app-view-states.tsx +140 -0
- package/src/app/mcp-app-view.effects.test.tsx +292 -0
- package/src/app/mcp-app-view.test.tsx +478 -0
- package/src/app/mcp-app-view.tsx +447 -190
- package/src/app/mcp-toolkit-app.test.tsx +40 -0
- package/src/app/mcp-toolkit-app.tsx +39 -8
- package/src/app/mcp-use-host-bridge.test.tsx +180 -0
- package/src/app/mcp-use-host-bridge.tsx +67 -24
- package/src/app/model-context.test.tsx +116 -0
- package/src/app/model-context.tsx +125 -0
- package/src/app/use-build-mode-focus.ts +62 -0
- package/src/app/use-view-actions.ts +89 -0
- package/src/app/use-view-lifecycle.ts +122 -0
- package/src/app/view-lifecycle.test.ts +443 -0
- package/src/app/view-lifecycle.ts +334 -0
- package/src/app/widget-fixture.effects.test.tsx +51 -0
- package/src/app/widget-fixture.render.test.tsx +81 -0
- package/src/app/widget-fixture.tsx +34 -11
- package/src/app/widget-props-sheet.tsx +67 -39
- package/src/app/widget-renderer.render.test.tsx +131 -0
- package/src/app/widget-renderer.tsx +136 -38
- package/src/components/DrillButton.tsx +24 -10
- package/src/components/EmptyState.tsx +83 -0
- package/src/components/ErrorState.tsx +204 -0
- package/src/components/FilterBar.test.tsx +82 -0
- package/src/components/FilterBar.tsx +56 -27
- package/src/components/GroupCard.tsx +3 -2
- package/src/components/KpiGrid.test.tsx +279 -0
- package/src/components/KpiGrid.tsx +329 -91
- package/src/components/ListFooter.test.tsx +116 -0
- package/src/components/ListFooter.tsx +110 -12
- package/src/components/PagedListFooter.test.tsx +140 -0
- package/src/components/PagedListFooter.tsx +107 -0
- package/src/components/Pills.test.tsx +77 -0
- package/src/components/Pills.tsx +78 -16
- package/src/components/SectionHeading.tsx +9 -3
- package/src/components/Toast.tsx +206 -0
- package/src/components/WidgetHeader.test.tsx +78 -0
- package/src/components/WidgetHeader.tsx +63 -16
- package/src/components/feedback-states.test.tsx +314 -0
- package/src/components/tone-figures.test.tsx +58 -0
- package/src/fonts.css +19 -0
- package/src/globals.css +9 -165
- package/src/hooks/index.ts +6 -3
- package/src/hooks/tool-result-recovery-model.test.ts +744 -0
- package/src/hooks/tool-result-recovery-model.ts +418 -0
- package/src/hooks/use-tool-query.effects.test.tsx +205 -0
- package/src/hooks/use-tool-query.ts +156 -33
- package/src/hooks/use-tool-result-recovery.effects.test.tsx +141 -0
- package/src/hooks/use-tool-result-recovery.test.ts +28 -5
- package/src/hooks/use-tool-result-recovery.ts +101 -131
- package/src/hooks/use-view-data.test.tsx +169 -0
- package/src/hooks/use-view-data.ts +131 -10
- package/src/hooks/use-view-tool-query.ts +25 -19
- package/src/i18n-coverage.test.tsx +425 -0
- package/src/index.ts +102 -13
- package/src/lib/focus-return.test.ts +288 -0
- package/src/lib/focus-return.ts +96 -0
- package/src/lib/focus-ring.ts +20 -0
- package/src/lib/icon-stroke.test.ts +59 -0
- package/src/lib/icon-stroke.ts +13 -0
- package/src/lib/parse-tool-result.test.ts +46 -1
- package/src/lib/parse-tool-result.ts +40 -2
- package/src/lib/toast-model.test.ts +233 -0
- package/src/lib/toast-model.ts +165 -0
- package/src/lib/tone-utils.test.ts +125 -16
- package/src/lib/tone-utils.ts +144 -15
- package/src/lib/tool-query.test.ts +569 -0
- package/src/lib/tool-query.ts +253 -0
- package/src/lib/tool-result-observer.test.ts +296 -0
- package/src/lib/tool-result-observer.ts +211 -0
- package/src/lib/typography.test.ts +45 -0
- package/src/lib/typography.ts +47 -0
- package/src/lib/utils.ts +12 -1
- package/src/locale/index.ts +14 -1
- package/src/locale/locale-provider.test.tsx +87 -0
- package/src/locale/locale-provider.tsx +90 -3
- package/src/locale/message-types.ts +337 -0
- package/src/locale/messages-de.ts +198 -0
- package/src/locale/messages-en.ts +196 -0
- package/src/locale/toolkit-messages.test.ts +349 -0
- package/src/locale/toolkit-messages.ts +143 -0
- package/src/no-hardcoded-copy.test.ts +432 -0
- package/src/primitives/alert.tsx +7 -2
- package/src/primitives/badge.tsx +19 -7
- package/src/primitives/button.tsx +13 -8
- package/src/primitives/card.tsx +4 -4
- package/src/primitives/dialog.tsx +42 -8
- package/src/primitives/input.tsx +5 -3
- package/src/primitives/scroll-area.tsx +1 -1
- package/src/primitives/select.tsx +7 -4
- package/src/primitives/sheet.tsx +33 -6
- package/src/primitives/skeleton.tsx +1 -1
- package/src/primitives/switch.tsx +4 -2
- package/src/primitives/tabs.tsx +9 -6
- package/src/providers/query-provider.test.tsx +154 -0
- package/src/providers/query-provider.tsx +66 -5
- package/src/render-cases-primitives.tsx +1 -1
- package/src/render-cases.tsx +82 -6
- package/src/render-effects.tsx +96 -0
- package/src/render-scan.ts +75 -0
- package/src/theme/cd-tokens.generated.css +48 -0
- package/src/theme/cd-tokens.test.ts +109 -0
- package/src/theme/cd-tokens.ts +67 -0
- package/src/theme/create-theme.test.ts +253 -5
- package/src/theme/create-theme.ts +341 -41
- package/src/theme/fonts.test.ts +85 -0
- package/src/theme/fonts.ts +72 -0
- package/src/theme/host-fonts.test.ts +135 -0
- package/src/theme/host-fonts.ts +52 -0
- package/src/theme/index.ts +15 -1
- package/src/theme/portal-container.ts +20 -0
- package/src/theme/presets.ts +44 -11
- package/src/theme/theme-css.test.ts +619 -0
- package/src/theme/theme-provider.test.tsx +82 -0
- package/src/theme/theme-provider.tsx +60 -24
- package/src/theme.css +344 -0
- package/ui-catalog.json +783 -49
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The plain logic behind `useToolQuery`, `useViewToolQuery`, `useViewData`
|
|
3
|
+
* and `useToolMutation` (toolkit#176 K18): the effective cache key and its
|
|
4
|
+
* collision guard, the opt-in retry policy for tool errors, the TanStack
|
|
5
|
+
* options a tool query runs with, and per-call mutation callbacks that fire
|
|
6
|
+
* for EVERY call. No React, no `mcp-use/react`, so it is unit-tested without
|
|
7
|
+
* a renderer.
|
|
8
|
+
*/
|
|
9
|
+
import { type MutateOptions, type MutationFunctionContext, type QueryClient, type UseQueryOptions } from "@tanstack/react-query";
|
|
10
|
+
/** A `(name, args)` tool caller — the shape of `useCallTool()` and `HostBridge.callTool`. */
|
|
11
|
+
export type ToolCaller = (name: string, args: object) => Promise<unknown>;
|
|
12
|
+
/**
|
|
13
|
+
* TanStack query options a tool query passes through: everything except the
|
|
14
|
+
* key and the fetcher, which the hooks build from the tool and its args
|
|
15
|
+
* (`retry`, `retryDelay`, `staleTime`, `placeholderData` / `keepPreviousData`,
|
|
16
|
+
* `initialData` + `initialDataUpdatedAt`, `enabled`, `select`, …).
|
|
17
|
+
*/
|
|
18
|
+
export type UseToolQueryOptions<TData = unknown, TSelected = TData> = Omit<UseQueryOptions<TData, Error, TSelected>, "queryKey" | "queryFn">;
|
|
19
|
+
/**
|
|
20
|
+
* Neither an `AppQueryProvider` `callTool` nor a `HostBridgeProvider` is in
|
|
21
|
+
* reach, so the query cannot call any tool. Never retried: nothing changes
|
|
22
|
+
* until the mount does.
|
|
23
|
+
*/
|
|
24
|
+
export declare class NoToolTransportError extends Error {
|
|
25
|
+
constructor(toolName: string);
|
|
26
|
+
}
|
|
27
|
+
/** Retries {@link shouldRetryToolCall} grants a failed transport (TanStack's own default count). */
|
|
28
|
+
export declare const TOOL_QUERY_RETRIES = 3;
|
|
29
|
+
/**
|
|
30
|
+
* A retry policy for tool queries: up to {@link TOOL_QUERY_RETRIES} retries
|
|
31
|
+
* for a failed transport, none for a tool's own `isError` answer
|
|
32
|
+
* (`isToolError`) or a missing transport — repeating a deterministic answer
|
|
33
|
+
* only repeats it and holds the error back about 7 s.
|
|
34
|
+
*
|
|
35
|
+
* Opt-in in 2.x (the hooks keep the client's `retry`, TanStack's 3 by
|
|
36
|
+
* default, because a tool may also answer a transient failure with
|
|
37
|
+
* `isError`): pass `retry: shouldRetryToolCall` to a hook, or set it as the
|
|
38
|
+
* client's default (`queryClient.setDefaultOptions`, or an `AppQueryProvider`
|
|
39
|
+
* `client` of your own).
|
|
40
|
+
*/
|
|
41
|
+
export declare function shouldRetryToolCall(failureCount: number, error: unknown): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* The effective cache key of a tool query (toolkit#176 K18).
|
|
44
|
+
*
|
|
45
|
+
* - 2.x default: the caller's key, then the args (`[...queryKey, args]`), so
|
|
46
|
+
* two callers sharing a key with different args get separate entries.
|
|
47
|
+
* - `toolNameInKey`: the caller's key, the tool name, then the args
|
|
48
|
+
* (`[...queryKey, toolName, args]`), so two tools never share an entry,
|
|
49
|
+
* whatever key their callers pass. Opt-in in 2.x (`AppQueryProvider` /
|
|
50
|
+
* `McpAppView` `toolNameInQueryKey`), the default from the next major.
|
|
51
|
+
*
|
|
52
|
+
* Build exact keys (`getQueryData`, `setQueryData`, `cancelQueries` with
|
|
53
|
+
* `exact: true`) with this helper, or with `useToolQueryKey`, which reads the
|
|
54
|
+
* provider's setting, rather than by hand: code that goes through them keeps
|
|
55
|
+
* working when the default changes. Prefix invalidation by `queryKey`
|
|
56
|
+
* matches either way.
|
|
57
|
+
*/
|
|
58
|
+
export declare function toolQueryKey(queryKey: readonly unknown[], toolName: string, args: object, toolNameInKey?: boolean): unknown[];
|
|
59
|
+
/**
|
|
60
|
+
* Claim the cache key `keyId` (`hashKey` of a {@link toolQueryKey}) for
|
|
61
|
+
* `toolName` on `client`. Returns the tool that held it
|
|
62
|
+
* before when that is ANOTHER tool — a collision the hooks report — else
|
|
63
|
+
* `null`. The latest claim wins, so each collision is reported once per
|
|
64
|
+
* switch.
|
|
65
|
+
*/
|
|
66
|
+
export declare function claimToolQueryKey(client: QueryClient, keyId: string, toolName: string): string | null;
|
|
67
|
+
/** The console line for a {@link claimToolQueryKey} collision. */
|
|
68
|
+
export declare function toolKeyCollisionMessage(keyId: string, toolName: string, previous: string): string;
|
|
69
|
+
/** How {@link toolQueryOptions} decodes a result and builds the key. */
|
|
70
|
+
export interface ToolQueryBuild<TData> {
|
|
71
|
+
/** Decodes the tool result. Default: `parseToolResult` (structured-first). */
|
|
72
|
+
decode?: (result: unknown) => TData;
|
|
73
|
+
/** Put the tool name into the key (see {@link toolQueryKey}). Default `false`. */
|
|
74
|
+
toolNameInKey?: boolean;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The TanStack options of a tool query: the caller's options, the
|
|
78
|
+
* {@link toolQueryKey} and a fetcher that calls `toolName` and decodes the
|
|
79
|
+
* result. `retry` stays the caller's, else the client's default; only a
|
|
80
|
+
* missing transport is never retried. Without a transport the fetcher fails
|
|
81
|
+
* with {@link NoToolTransportError} instead of leaving the query idle.
|
|
82
|
+
*/
|
|
83
|
+
export declare function toolQueryOptions<TData, TSelected = TData>(queryKey: readonly unknown[], toolName: string, args: object, callTool: ToolCaller | undefined, opts?: UseToolQueryOptions<TData, TSelected>, build?: ToolQueryBuild<TData>): UseQueryOptions<TData, Error, TSelected>;
|
|
84
|
+
/**
|
|
85
|
+
* Seed `queryKey` with host-delivered `seed`: written when the entry is
|
|
86
|
+
* empty, or when the seed is a payload this client has not seeded for the
|
|
87
|
+
* key before (a new delivery). Returns whether the cache was written.
|
|
88
|
+
*/
|
|
89
|
+
export declare function seedToolQuery(client: QueryClient, queryKey: readonly unknown[], seed: unknown, updatedAt?: number): boolean;
|
|
90
|
+
/** Callbacks of one `mutate` call, typed as TanStack's per-call options. */
|
|
91
|
+
export type PerCallCallbacks<TData, TVariables> = MutateOptions<TData, Error, TVariables, unknown>;
|
|
92
|
+
/**
|
|
93
|
+
* Fire one call's per-call `onSuccess` / `onError` / `onSettled` once `call`
|
|
94
|
+
* settles — for EVERY call. TanStack's own `mutate` keeps only the latest
|
|
95
|
+
* call's callbacks, so two quick calls (retrying two incidents in a row)
|
|
96
|
+
* would confirm only the second. `context()` is read when the call settles:
|
|
97
|
+
* `null` (the component unmounted) skips the callbacks, as TanStack does.
|
|
98
|
+
* A rejected `call` is handled here, never left unhandled.
|
|
99
|
+
*/
|
|
100
|
+
export declare function settleEachCall<TData, TVariables>(call: Promise<TData>, variables: TVariables, callbacks: PerCallCallbacks<TData, TVariables> | undefined, context: () => MutationFunctionContext | null): void;
|
|
101
|
+
/**
|
|
102
|
+
* Invalidate the query keys (prefixes) a mutation names: matching ACTIVE
|
|
103
|
+
* queries refetch now, inactive ones are only marked stale and refetch when
|
|
104
|
+
* they are next used — never a refetch of every inactive cached page.
|
|
105
|
+
*/
|
|
106
|
+
export declare function invalidateToolQueries(client: QueryClient, keys: readonly (readonly unknown[])[] | undefined): Promise<void>;
|
|
107
|
+
//# sourceMappingURL=tool-query.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-query.d.ts","sourceRoot":"","sources":["../../src/lib/tool-query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The plain logic behind `useToolQuery`, `useViewToolQuery`, `useViewData`
|
|
3
|
+
* and `useToolMutation` (toolkit#176 K18): the effective cache key and its
|
|
4
|
+
* collision guard, the opt-in retry policy for tool errors, the TanStack
|
|
5
|
+
* options a tool query runs with, and per-call mutation callbacks that fire
|
|
6
|
+
* for EVERY call. No React, no `mcp-use/react`, so it is unit-tested without
|
|
7
|
+
* a renderer.
|
|
8
|
+
*/
|
|
9
|
+
import { hashKey, } from "@tanstack/react-query";
|
|
10
|
+
import { isToolError, parseToolResult } from "./parse-tool-result.js";
|
|
11
|
+
/**
|
|
12
|
+
* Neither an `AppQueryProvider` `callTool` nor a `HostBridgeProvider` is in
|
|
13
|
+
* reach, so the query cannot call any tool. Never retried: nothing changes
|
|
14
|
+
* until the mount does.
|
|
15
|
+
*/
|
|
16
|
+
export class NoToolTransportError extends Error {
|
|
17
|
+
constructor(toolName) {
|
|
18
|
+
super(`[mcp-toolkit] cannot call "${toolName}": no tool transport. Mount the widget under ` +
|
|
19
|
+
"AppQueryProvider with callTool, or a HostBridgeProvider.");
|
|
20
|
+
this.name = "NoToolTransportError";
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Retries {@link shouldRetryToolCall} grants a failed transport (TanStack's own default count). */
|
|
24
|
+
export const TOOL_QUERY_RETRIES = 3;
|
|
25
|
+
/**
|
|
26
|
+
* A retry policy for tool queries: up to {@link TOOL_QUERY_RETRIES} retries
|
|
27
|
+
* for a failed transport, none for a tool's own `isError` answer
|
|
28
|
+
* (`isToolError`) or a missing transport — repeating a deterministic answer
|
|
29
|
+
* only repeats it and holds the error back about 7 s.
|
|
30
|
+
*
|
|
31
|
+
* Opt-in in 2.x (the hooks keep the client's `retry`, TanStack's 3 by
|
|
32
|
+
* default, because a tool may also answer a transient failure with
|
|
33
|
+
* `isError`): pass `retry: shouldRetryToolCall` to a hook, or set it as the
|
|
34
|
+
* client's default (`queryClient.setDefaultOptions`, or an `AppQueryProvider`
|
|
35
|
+
* `client` of your own).
|
|
36
|
+
*/
|
|
37
|
+
export function shouldRetryToolCall(failureCount, error) {
|
|
38
|
+
if (isToolError(error) || error instanceof NoToolTransportError)
|
|
39
|
+
return false;
|
|
40
|
+
return failureCount < TOOL_QUERY_RETRIES;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* The effective cache key of a tool query (toolkit#176 K18).
|
|
44
|
+
*
|
|
45
|
+
* - 2.x default: the caller's key, then the args (`[...queryKey, args]`), so
|
|
46
|
+
* two callers sharing a key with different args get separate entries.
|
|
47
|
+
* - `toolNameInKey`: the caller's key, the tool name, then the args
|
|
48
|
+
* (`[...queryKey, toolName, args]`), so two tools never share an entry,
|
|
49
|
+
* whatever key their callers pass. Opt-in in 2.x (`AppQueryProvider` /
|
|
50
|
+
* `McpAppView` `toolNameInQueryKey`), the default from the next major.
|
|
51
|
+
*
|
|
52
|
+
* Build exact keys (`getQueryData`, `setQueryData`, `cancelQueries` with
|
|
53
|
+
* `exact: true`) with this helper, or with `useToolQueryKey`, which reads the
|
|
54
|
+
* provider's setting, rather than by hand: code that goes through them keeps
|
|
55
|
+
* working when the default changes. Prefix invalidation by `queryKey`
|
|
56
|
+
* matches either way.
|
|
57
|
+
*/
|
|
58
|
+
export function toolQueryKey(queryKey, toolName, args, toolNameInKey = false) {
|
|
59
|
+
return toolNameInKey ? [...queryKey, toolName, args] : [...queryKey, args];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* The tool that last claimed each cache key, per client — the guard against
|
|
63
|
+
* two tools sharing one entry (their answers would overwrite each other).
|
|
64
|
+
*/
|
|
65
|
+
const keyOwners = new WeakMap();
|
|
66
|
+
/**
|
|
67
|
+
* Claim the cache key `keyId` (`hashKey` of a {@link toolQueryKey}) for
|
|
68
|
+
* `toolName` on `client`. Returns the tool that held it
|
|
69
|
+
* before when that is ANOTHER tool — a collision the hooks report — else
|
|
70
|
+
* `null`. The latest claim wins, so each collision is reported once per
|
|
71
|
+
* switch.
|
|
72
|
+
*/
|
|
73
|
+
export function claimToolQueryKey(client, keyId, toolName) {
|
|
74
|
+
const owners = keyOwners.get(client) ?? new Map();
|
|
75
|
+
keyOwners.set(client, owners);
|
|
76
|
+
const previous = owners.get(keyId);
|
|
77
|
+
owners.set(keyId, toolName);
|
|
78
|
+
return previous !== undefined && previous !== toolName ? previous : null;
|
|
79
|
+
}
|
|
80
|
+
/** The console line for a {@link claimToolQueryKey} collision. */
|
|
81
|
+
export function toolKeyCollisionMessage(keyId, toolName, previous) {
|
|
82
|
+
return (`[mcp-toolkit] the query key ${keyId} is used by "${previous}" and "${toolName}": ` +
|
|
83
|
+
"both share one cache entry and overwrite each other's answer. Give each tool its own queryKey.");
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* The TanStack options of a tool query: the caller's options, the
|
|
87
|
+
* {@link toolQueryKey} and a fetcher that calls `toolName` and decodes the
|
|
88
|
+
* result. `retry` stays the caller's, else the client's default; only a
|
|
89
|
+
* missing transport is never retried. Without a transport the fetcher fails
|
|
90
|
+
* with {@link NoToolTransportError} instead of leaving the query idle.
|
|
91
|
+
*/
|
|
92
|
+
export function toolQueryOptions(queryKey, toolName, args, callTool, opts, build = {}) {
|
|
93
|
+
const decode = build.decode ?? ((result) => parseToolResult(result));
|
|
94
|
+
return {
|
|
95
|
+
...opts,
|
|
96
|
+
// An omitted `retry` must stay omitted: an explicit `undefined` would
|
|
97
|
+
// shadow the client's default.
|
|
98
|
+
...(callTool ? null : { retry: false }),
|
|
99
|
+
queryKey: toolQueryKey(queryKey, toolName, args, build.toolNameInKey),
|
|
100
|
+
queryFn: async () => {
|
|
101
|
+
if (!callTool)
|
|
102
|
+
throw new NoToolTransportError(toolName);
|
|
103
|
+
return decode(await callTool(toolName, args));
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The content of the payload last seeded per query key, per client: a
|
|
109
|
+
* remounted or re-rendered OLD payload must not roll a refetched answer
|
|
110
|
+
* back, while a payload not seeded before is a new delivery and wins.
|
|
111
|
+
*/
|
|
112
|
+
const lastSeeded = new WeakMap();
|
|
113
|
+
function contentOf(value) {
|
|
114
|
+
try {
|
|
115
|
+
return JSON.stringify(value);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Seed `queryKey` with host-delivered `seed`: written when the entry is
|
|
123
|
+
* empty, or when the seed is a payload this client has not seeded for the
|
|
124
|
+
* key before (a new delivery). Returns whether the cache was written.
|
|
125
|
+
*/
|
|
126
|
+
export function seedToolQuery(client, queryKey, seed, updatedAt) {
|
|
127
|
+
const keyId = hashKey(queryKey);
|
|
128
|
+
const seeded = lastSeeded.get(client) ?? new Map();
|
|
129
|
+
lastSeeded.set(client, seeded);
|
|
130
|
+
const content = contentOf(seed);
|
|
131
|
+
const delivered = content === undefined || seeded.get(keyId) !== content;
|
|
132
|
+
if (content !== undefined)
|
|
133
|
+
seeded.set(keyId, content);
|
|
134
|
+
if (!delivered && client.getQueryData(queryKey) !== undefined)
|
|
135
|
+
return false;
|
|
136
|
+
client.setQueryData(queryKey, seed, updatedAt === undefined ? undefined : { updatedAt });
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
function settle(run) {
|
|
140
|
+
try {
|
|
141
|
+
run();
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
// Surface a throwing callback as an unhandled rejection, as TanStack
|
|
145
|
+
// does, without skipping the callbacks after it.
|
|
146
|
+
void Promise.reject(err instanceof Error ? err : new Error(String(err)));
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Fire one call's per-call `onSuccess` / `onError` / `onSettled` once `call`
|
|
151
|
+
* settles — for EVERY call. TanStack's own `mutate` keeps only the latest
|
|
152
|
+
* call's callbacks, so two quick calls (retrying two incidents in a row)
|
|
153
|
+
* would confirm only the second. `context()` is read when the call settles:
|
|
154
|
+
* `null` (the component unmounted) skips the callbacks, as TanStack does.
|
|
155
|
+
* A rejected `call` is handled here, never left unhandled.
|
|
156
|
+
*/
|
|
157
|
+
export function settleEachCall(call, variables, callbacks, context) {
|
|
158
|
+
call.then((data) => {
|
|
159
|
+
const ctx = callbacks ? context() : null;
|
|
160
|
+
if (!callbacks || !ctx)
|
|
161
|
+
return;
|
|
162
|
+
settle(() => callbacks.onSuccess?.(data, variables, undefined, ctx));
|
|
163
|
+
settle(() => callbacks.onSettled?.(data, null, variables, undefined, ctx));
|
|
164
|
+
}, (error) => {
|
|
165
|
+
const ctx = callbacks ? context() : null;
|
|
166
|
+
if (!callbacks || !ctx)
|
|
167
|
+
return;
|
|
168
|
+
settle(() => callbacks.onError?.(error, variables, undefined, ctx));
|
|
169
|
+
settle(() => callbacks.onSettled?.(undefined, error, variables, undefined, ctx));
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Invalidate the query keys (prefixes) a mutation names: matching ACTIVE
|
|
174
|
+
* queries refetch now, inactive ones are only marked stale and refetch when
|
|
175
|
+
* they are next used — never a refetch of every inactive cached page.
|
|
176
|
+
*/
|
|
177
|
+
export async function invalidateToolQueries(client, keys) {
|
|
178
|
+
if (!keys)
|
|
179
|
+
return;
|
|
180
|
+
await Promise.all(keys.map((queryKey) => client.invalidateQueries({ queryKey })));
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=tool-query.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-query.js","sourceRoot":"","sources":["../../src/lib/tool-query.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A passive observer of the MCP Apps (SEP-1865) host → view lifecycle
|
|
3
|
+
* notifications, read straight off the postMessage channel the view runtime
|
|
4
|
+
* itself listens on (toolkit#176 K13, N21).
|
|
5
|
+
*
|
|
6
|
+
* mcp-use 2.x latches only a result WITH `structuredContent` (or an
|
|
7
|
+
* `isError`); a content-only result, which claude.ai and Claude Desktop send,
|
|
8
|
+
* leaves its status `"pending"` forever, and its tool input merges partial and
|
|
9
|
+
* complete arguments into one field. Watching the notifications themselves
|
|
10
|
+
* tells the three cases apart that the latch cannot:
|
|
11
|
+
*
|
|
12
|
+
* - the host delivered a STRIPPED result (re-run the tool now, with the
|
|
13
|
+
* complete arguments it was called with),
|
|
14
|
+
* - the host delivered a structured result (the latch follows; never re-run),
|
|
15
|
+
* - nothing arrived yet (a slow tool on a compliant host: keep waiting).
|
|
16
|
+
*
|
|
17
|
+
* The last case is only certain when the observer was listening before the
|
|
18
|
+
* host answered `ui/initialize` ({@link ToolObservation.sawHandshake}): hosts
|
|
19
|
+
* send the lifecycle notifications after the handshake, so an observer that
|
|
20
|
+
* saw it has seen everything sent so far. `mountMcpToolkitApp` installs it
|
|
21
|
+
* ahead of `bootstrapView` for exactly that reason.
|
|
22
|
+
*
|
|
23
|
+
* Read-only: it never sends, never answers and never stops a message.
|
|
24
|
+
*/
|
|
25
|
+
/** What the host's `ui/notifications/tool-result` carried. */
|
|
26
|
+
export type ObservedToolResult = "none" | "structured" | "stripped" | "error";
|
|
27
|
+
/** Everything the observer learned about the rendering call so far. */
|
|
28
|
+
export interface ToolObservation {
|
|
29
|
+
/**
|
|
30
|
+
* The observer saw the host answer `ui/initialize`, so it was listening
|
|
31
|
+
* before any lifecycle notification could be sent: a result it has not
|
|
32
|
+
* seen has not been delivered yet.
|
|
33
|
+
*/
|
|
34
|
+
sawHandshake: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* The arguments of the complete `ui/notifications/tool-input` — never a
|
|
37
|
+
* partial stream (`tool-input-partial` is ignored). `undefined` until it
|
|
38
|
+
* arrived.
|
|
39
|
+
*/
|
|
40
|
+
completeInput: Record<string, unknown> | undefined;
|
|
41
|
+
/** What the first `ui/notifications/tool-result` carried. */
|
|
42
|
+
result: ObservedToolResult;
|
|
43
|
+
/** The host sent `ui/notifications/tool-cancelled`. */
|
|
44
|
+
cancelled: boolean;
|
|
45
|
+
}
|
|
46
|
+
export declare const EMPTY_TOOL_OBSERVATION: ToolObservation;
|
|
47
|
+
/** A host → view message the observer acts on. */
|
|
48
|
+
export type HostLifecycleMessage = {
|
|
49
|
+
kind: "handshake";
|
|
50
|
+
} | {
|
|
51
|
+
kind: "tool-input";
|
|
52
|
+
arguments: Record<string, unknown>;
|
|
53
|
+
} | {
|
|
54
|
+
kind: "tool-result";
|
|
55
|
+
result: Exclude<ObservedToolResult, "none">;
|
|
56
|
+
} | {
|
|
57
|
+
kind: "tool-cancelled";
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Classify a tool-result notification the way mcp-use 2.x's latch does: an
|
|
61
|
+
* `isError` result is an error, a result with `structuredContent` (even
|
|
62
|
+
* `null`) latches as ready, and anything else is the stripped, content-only
|
|
63
|
+
* result the latch ignores.
|
|
64
|
+
*/
|
|
65
|
+
export declare function classifyToolResult(params: Record<string, unknown>): Exclude<ObservedToolResult, "none">;
|
|
66
|
+
/**
|
|
67
|
+
* Decode one postMessage payload into the lifecycle message it is, or `null`
|
|
68
|
+
* for anything else (other methods, requests, responses, foreign traffic).
|
|
69
|
+
*/
|
|
70
|
+
export declare function classifyHostMessage(data: unknown): HostLifecycleMessage | null;
|
|
71
|
+
/**
|
|
72
|
+
* Fold one message into the observation. Like the mcp-use latch, the call
|
|
73
|
+
* settles once: after its result or cancellation, later inputs, results and
|
|
74
|
+
* cancellations change nothing.
|
|
75
|
+
*/
|
|
76
|
+
export declare function reduceToolObservation(state: ToolObservation, message: HostLifecycleMessage): ToolObservation;
|
|
77
|
+
/** The `window` slice the observer listens on (any `EventTarget`, e.g. in tests). */
|
|
78
|
+
export interface MessageEventSource {
|
|
79
|
+
addEventListener(type: "message", listener: (event: Event) => void): void;
|
|
80
|
+
removeEventListener(type: "message", listener: (event: Event) => void): void;
|
|
81
|
+
}
|
|
82
|
+
/** A subscribable observation, shaped for `useSyncExternalStore`. */
|
|
83
|
+
export interface ToolResultObserver {
|
|
84
|
+
subscribe: (listener: () => void) => () => void;
|
|
85
|
+
getSnapshot: () => ToolObservation;
|
|
86
|
+
/** Stop listening; the last observation stays readable. */
|
|
87
|
+
dispose: () => void;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Observe the lifecycle notifications arriving on `source`. `accept` filters
|
|
91
|
+
* the events (the view accepts only its host: `event.source === window.parent`,
|
|
92
|
+
* the same check the ext-apps transport makes).
|
|
93
|
+
*/
|
|
94
|
+
export declare function createToolResultObserver(source: MessageEventSource, accept?: (event: MessageEvent) => boolean): ToolResultObserver;
|
|
95
|
+
/**
|
|
96
|
+
* The view document's observer: installed once and kept for the document's
|
|
97
|
+
* lifetime (one document renders one view). `null` outside a browser and in
|
|
98
|
+
* a top-level window, where no host frames the view.
|
|
99
|
+
*
|
|
100
|
+
* It must listen before the view runtime connects, so it sees the
|
|
101
|
+
* handshake. This module therefore installs it as the bundle evaluates
|
|
102
|
+
* (below), ahead of any `bootstrapView` call in the entry module, whatever
|
|
103
|
+
* the mount; `mountMcpToolkitApp` calls it again (idempotent). Installed any
|
|
104
|
+
* later, it still sees what arrives afterwards, and the recovery falls back
|
|
105
|
+
* to its grace timer for the rest.
|
|
106
|
+
*/
|
|
107
|
+
export declare function installToolResultObserver(): ToolResultObserver | null;
|
|
108
|
+
//# sourceMappingURL=tool-result-observer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-result-observer.d.ts","sourceRoot":"","sources":["../../src/lib/tool-result-observer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,8DAA8D;AAC9D,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,YAAY,GAAG,UAAU,GAAG,OAAO,CAAA;AAE7E,uEAAuE;AACvE,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,YAAY,EAAE,OAAO,CAAA;IACrB;;;;OAIG;IACH,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAA;IAClD,6DAA6D;IAC7D,MAAM,EAAE,kBAAkB,CAAA;IAC1B,uDAAuD;IACvD,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,eAAO,MAAM,sBAAsB,EAAE,eAKnC,CAAA;AAEF,kDAAkD;AAClD,MAAM,MAAM,oBAAoB,GAC5B;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAA;CAAE,GACpE;IAAE,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAA;AAM9B;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAGrC;AAUD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,oBAAoB,GAAG,IAAI,CAmB9E;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,oBAAoB,GAC5B,eAAe,CAajB;AAED,qFAAqF;AACrF,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAA;IACzE,mBAAmB,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAA;CAC7E;AAED,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,IAAI,KAAK,MAAM,IAAI,CAAA;IAC/C,WAAW,EAAE,MAAM,eAAe,CAAA;IAClC,2DAA2D;IAC3D,OAAO,EAAE,MAAM,IAAI,CAAA;CACpB;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,kBAAkB,EAC1B,MAAM,GAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAoB,GACpD,kBAAkB,CA2BpB;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,IAAI,kBAAkB,GAAG,IAAI,CAMrE"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A passive observer of the MCP Apps (SEP-1865) host → view lifecycle
|
|
3
|
+
* notifications, read straight off the postMessage channel the view runtime
|
|
4
|
+
* itself listens on (toolkit#176 K13, N21).
|
|
5
|
+
*
|
|
6
|
+
* mcp-use 2.x latches only a result WITH `structuredContent` (or an
|
|
7
|
+
* `isError`); a content-only result, which claude.ai and Claude Desktop send,
|
|
8
|
+
* leaves its status `"pending"` forever, and its tool input merges partial and
|
|
9
|
+
* complete arguments into one field. Watching the notifications themselves
|
|
10
|
+
* tells the three cases apart that the latch cannot:
|
|
11
|
+
*
|
|
12
|
+
* - the host delivered a STRIPPED result (re-run the tool now, with the
|
|
13
|
+
* complete arguments it was called with),
|
|
14
|
+
* - the host delivered a structured result (the latch follows; never re-run),
|
|
15
|
+
* - nothing arrived yet (a slow tool on a compliant host: keep waiting).
|
|
16
|
+
*
|
|
17
|
+
* The last case is only certain when the observer was listening before the
|
|
18
|
+
* host answered `ui/initialize` ({@link ToolObservation.sawHandshake}): hosts
|
|
19
|
+
* send the lifecycle notifications after the handshake, so an observer that
|
|
20
|
+
* saw it has seen everything sent so far. `mountMcpToolkitApp` installs it
|
|
21
|
+
* ahead of `bootstrapView` for exactly that reason.
|
|
22
|
+
*
|
|
23
|
+
* Read-only: it never sends, never answers and never stops a message.
|
|
24
|
+
*/
|
|
25
|
+
export const EMPTY_TOOL_OBSERVATION = Object.freeze({
|
|
26
|
+
sawHandshake: false,
|
|
27
|
+
completeInput: undefined,
|
|
28
|
+
result: "none",
|
|
29
|
+
cancelled: false,
|
|
30
|
+
});
|
|
31
|
+
function isRecord(value) {
|
|
32
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Classify a tool-result notification the way mcp-use 2.x's latch does: an
|
|
36
|
+
* `isError` result is an error, a result with `structuredContent` (even
|
|
37
|
+
* `null`) latches as ready, and anything else is the stripped, content-only
|
|
38
|
+
* result the latch ignores.
|
|
39
|
+
*/
|
|
40
|
+
export function classifyToolResult(params) {
|
|
41
|
+
if (params.isError === true)
|
|
42
|
+
return "error";
|
|
43
|
+
return params.structuredContent === undefined ? "stripped" : "structured";
|
|
44
|
+
}
|
|
45
|
+
/** The host's answer to `ui/initialize`: a response carrying its capabilities or protocol version. */
|
|
46
|
+
function isHandshakeResponse(message) {
|
|
47
|
+
if (!("id" in message) || !isRecord(message.result))
|
|
48
|
+
return false;
|
|
49
|
+
return (isRecord(message.result.hostCapabilities) || typeof message.result.protocolVersion === "string");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Decode one postMessage payload into the lifecycle message it is, or `null`
|
|
53
|
+
* for anything else (other methods, requests, responses, foreign traffic).
|
|
54
|
+
*/
|
|
55
|
+
export function classifyHostMessage(data) {
|
|
56
|
+
if (!isRecord(data) || data.jsonrpc !== "2.0")
|
|
57
|
+
return null;
|
|
58
|
+
if (typeof data.method !== "string") {
|
|
59
|
+
return isHandshakeResponse(data) ? { kind: "handshake" } : null;
|
|
60
|
+
}
|
|
61
|
+
const params = isRecord(data.params) ? data.params : {};
|
|
62
|
+
switch (data.method) {
|
|
63
|
+
case "ui/notifications/tool-input":
|
|
64
|
+
return {
|
|
65
|
+
kind: "tool-input",
|
|
66
|
+
arguments: isRecord(params.arguments) ? params.arguments : {},
|
|
67
|
+
};
|
|
68
|
+
case "ui/notifications/tool-result":
|
|
69
|
+
return { kind: "tool-result", result: classifyToolResult(params) };
|
|
70
|
+
case "ui/notifications/tool-cancelled":
|
|
71
|
+
return { kind: "tool-cancelled" };
|
|
72
|
+
default:
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Fold one message into the observation. Like the mcp-use latch, the call
|
|
78
|
+
* settles once: after its result or cancellation, later inputs, results and
|
|
79
|
+
* cancellations change nothing.
|
|
80
|
+
*/
|
|
81
|
+
export function reduceToolObservation(state, message) {
|
|
82
|
+
if (message.kind === "handshake") {
|
|
83
|
+
return state.sawHandshake ? state : { ...state, sawHandshake: true };
|
|
84
|
+
}
|
|
85
|
+
if (state.result !== "none" || state.cancelled)
|
|
86
|
+
return state;
|
|
87
|
+
switch (message.kind) {
|
|
88
|
+
case "tool-input":
|
|
89
|
+
return { ...state, completeInput: message.arguments };
|
|
90
|
+
case "tool-result":
|
|
91
|
+
return { ...state, result: message.result };
|
|
92
|
+
case "tool-cancelled":
|
|
93
|
+
return { ...state, cancelled: true };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Observe the lifecycle notifications arriving on `source`. `accept` filters
|
|
98
|
+
* the events (the view accepts only its host: `event.source === window.parent`,
|
|
99
|
+
* the same check the ext-apps transport makes).
|
|
100
|
+
*/
|
|
101
|
+
export function createToolResultObserver(source, accept = () => true) {
|
|
102
|
+
let snapshot = EMPTY_TOOL_OBSERVATION;
|
|
103
|
+
const listeners = new Set();
|
|
104
|
+
const onMessage = (received) => {
|
|
105
|
+
// Only `message` events are subscribed: each one is a MessageEvent.
|
|
106
|
+
const event = received;
|
|
107
|
+
if (!accept(event))
|
|
108
|
+
return;
|
|
109
|
+
const message = classifyHostMessage(event.data);
|
|
110
|
+
if (!message)
|
|
111
|
+
return;
|
|
112
|
+
const next = reduceToolObservation(snapshot, message);
|
|
113
|
+
if (next === snapshot)
|
|
114
|
+
return;
|
|
115
|
+
snapshot = next;
|
|
116
|
+
for (const listener of [...listeners])
|
|
117
|
+
listener();
|
|
118
|
+
};
|
|
119
|
+
source.addEventListener("message", onMessage);
|
|
120
|
+
return {
|
|
121
|
+
subscribe: (listener) => {
|
|
122
|
+
listeners.add(listener);
|
|
123
|
+
return () => {
|
|
124
|
+
listeners.delete(listener);
|
|
125
|
+
};
|
|
126
|
+
},
|
|
127
|
+
getSnapshot: () => snapshot,
|
|
128
|
+
dispose: () => {
|
|
129
|
+
source.removeEventListener("message", onMessage);
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
let documentObserver = null;
|
|
134
|
+
/**
|
|
135
|
+
* The view document's observer: installed once and kept for the document's
|
|
136
|
+
* lifetime (one document renders one view). `null` outside a browser and in
|
|
137
|
+
* a top-level window, where no host frames the view.
|
|
138
|
+
*
|
|
139
|
+
* It must listen before the view runtime connects, so it sees the
|
|
140
|
+
* handshake. This module therefore installs it as the bundle evaluates
|
|
141
|
+
* (below), ahead of any `bootstrapView` call in the entry module, whatever
|
|
142
|
+
* the mount; `mountMcpToolkitApp` calls it again (idempotent). Installed any
|
|
143
|
+
* later, it still sees what arrives afterwards, and the recovery falls back
|
|
144
|
+
* to its grace timer for the rest.
|
|
145
|
+
*/
|
|
146
|
+
export function installToolResultObserver() {
|
|
147
|
+
if (documentObserver)
|
|
148
|
+
return documentObserver;
|
|
149
|
+
if (typeof window === "undefined" || window.parent === window)
|
|
150
|
+
return null;
|
|
151
|
+
const host = window.parent;
|
|
152
|
+
documentObserver = createToolResultObserver(window, (event) => event.source === host);
|
|
153
|
+
return documentObserver;
|
|
154
|
+
}
|
|
155
|
+
// Listen from the moment the view bundle evaluates (a passive listener; a
|
|
156
|
+
// no-op outside a framed browser document).
|
|
157
|
+
installToolResultObserver();
|
|
158
|
+
//# sourceMappingURL=tool-result-observer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-result-observer.js","sourceRoot":"","sources":["../../src/lib/tool-result-observer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The type scale of the kit (modeler-tool-design §4, adapted for embedded
|
|
3
|
+
* widgets): five steps, each a role in `theme.css` (`--text-<step>` with its
|
|
4
|
+
* line height and weight) and a Tailwind utility of the same name.
|
|
5
|
+
*
|
|
6
|
+
* | Step | Utility | Size / weight / line height | Use |
|
|
7
|
+
* | --------- | -------------- | --------------------------- | ------------------------------------------ |
|
|
8
|
+
* | `title` | `text-title` | 28 px / 700 / 1.2 | page title (the CI h2; a widget has no h1 40 px) |
|
|
9
|
+
* | `section` | `text-section` | 21 px / 600 / 1.3 | section title (CI h3) |
|
|
10
|
+
* | `body` | `text-body` | 16 px / 400 / 1.6 | running text: state and toast descriptions |
|
|
11
|
+
* | `dense` | `text-dense` | 14 px / 400 / 1.5 | dense tables and controls (inputs, chips, count pills, the inline alert box): the documented product exception, never running text |
|
|
12
|
+
* | `small` | `text-small` | 13 px / 400 / 1.5 | captions, labels, hints, meta rows: the FLOOR |
|
|
13
|
+
*
|
|
14
|
+
* Nothing renders below 13 px — no `text-xs` (12 px), no `text-[10px]`
|
|
15
|
+
* micro-labels (`examples/test/design-system.test.ts` enforces it). A label
|
|
16
|
+
* that used to be a 10–11 px uppercase caption is {@link MICRO_LABEL}: 13 px,
|
|
17
|
+
* semibold, normal case.
|
|
18
|
+
*
|
|
19
|
+
* Combine the utilities through the kit's `cn`: plain tailwind-merge does not
|
|
20
|
+
* know these sizes and would drop `text-small` next to a text colour.
|
|
21
|
+
*/
|
|
22
|
+
/** The five steps, smallest last. */
|
|
23
|
+
export declare const TYPE_STEPS: readonly ["title", "section", "body", "dense", "small"];
|
|
24
|
+
/** One step of the type scale. */
|
|
25
|
+
export type TypeStep = (typeof TYPE_STEPS)[number];
|
|
26
|
+
/** The utility class per step (`TYPE_SCALE.small` → `"text-small"`). */
|
|
27
|
+
export declare const TYPE_SCALE: Readonly<Record<TypeStep, `text-${TypeStep}`>>;
|
|
28
|
+
/** The smallest text the kit renders, in CSS px (CI §4 "klein"). */
|
|
29
|
+
export declare const TYPE_FLOOR_PX = 13;
|
|
30
|
+
/**
|
|
31
|
+
* A caption above a value or a column: table heads, KPI labels, group
|
|
32
|
+
* labels. 13 px semibold in normal case — the CI floor, where these used to
|
|
33
|
+
* be 10–11 px uppercase. Typography only: add the colour
|
|
34
|
+
* (`text-muted-foreground`) at the call site.
|
|
35
|
+
*/
|
|
36
|
+
export declare const MICRO_LABEL = "text-small font-semibold";
|
|
37
|
+
//# sourceMappingURL=typography.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typography.d.ts","sourceRoot":"","sources":["../../src/lib/typography.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,qCAAqC;AACrC,eAAO,MAAM,UAAU,yDAA0D,CAAA;AAEjF,kCAAkC;AAClC,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,CAAC,CAAA;AAElD,wEAAwE;AACxE,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,QAAQ,EAAE,CAAC,CAMrE,CAAA;AAED,oEAAoE;AACpE,eAAO,MAAM,aAAa,KAAK,CAAA;AAE/B;;;;;GAKG;AACH,eAAO,MAAM,WAAW,6BAA6B,CAAA"}
|