@tmorrow/cre8-wc 2.3.0 → 2.3.2
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/a2ui/catalog-kg.json +6837 -116
- package/a2ui/catalog.compact.json +3 -3
- package/a2ui/catalog.json +73 -73
- package/a2ui/check-deploy-drift.mjs +147 -0
- package/a2ui/generate-catalog-kg.mjs +194 -18
- package/a2ui/kg-sources.mjs +291 -0
- package/a2ui/patterns/alert-banner.json +16 -0
- package/a2ui/patterns/data-table.json +67 -0
- package/a2ui/patterns/login-form.json +55 -0
- package/a2ui/patterns/modal-dialog.json +47 -0
- package/a2ui/patterns/page-layout.json +55 -0
- package/a2ui/patterns/tabbed-content.json +37 -0
- package/dist/assets/{Changelog-Documentation-BEz7qwHC.js → Changelog-Documentation-DyRD5g5c.js} +1 -1
- package/dist/assets/{Code-Guidelines-BRlChdnm.js → Code-Guidelines-DIxeIc7I.js} +1 -1
- package/dist/assets/{Color-6AOWCN3U-DeiMoXtk.js → Color-6AOWCN3U-Dznni4GY.js} +1 -1
- package/dist/assets/{Contributing-Guidelines-ZYkPHT5D.js → Contributing-Guidelines-C361mreO.js} +1 -1
- package/dist/assets/{DocsRenderer-JROSPFPF-DLyaYyWd.js → DocsRenderer-JROSPFPF-DVzuXMfE.js} +1 -1
- package/dist/assets/{Tokens-Documentation-DdehD3DX.js → Tokens-Documentation-DQ55nCPE.js} +1 -1
- package/dist/assets/{WithTooltip-7X4HQR7L-BWB3Yb4o.js → WithTooltip-7X4HQR7L-57g4vxQ5.js} +1 -1
- package/dist/assets/{accordion-item.stories-BAnUfHf7.js → accordion-item.stories-Cz0JPYkb.js} +1 -1
- package/dist/assets/{accordion.stories-B-5tkfuu.js → accordion.stories-CKPEtfSL.js} +1 -1
- package/dist/assets/{address-form.stories-DL1-wOd_.js → address-form.stories-clpPw22i.js} +1 -1
- package/dist/assets/{alert.stories-DkQjKtTE.js → alert.stories-UoZRIq2Z.js} +1 -1
- package/dist/assets/{badge-DyapNgMi.js → badge-Bf3zamLa.js} +1 -1
- package/dist/assets/{badge.stories-8NMDzMHB.js → badge.stories-BpZgJgka.js} +1 -1
- package/dist/assets/{band.stories-D5Z1gvOr.js → band.stories-CX5fEcU0.js} +1 -1
- package/dist/assets/{blocks-DTMWhAiD.js → blocks-F7P3fIJh.js} +5 -5
- package/dist/assets/{breadcrumbs.stories-CY40buuT.js → breadcrumbs.stories-CRuQAhFW.js} +1 -1
- package/dist/assets/{button-B559dEsw.js → button-BIrV07TC.js} +1 -1
- package/dist/assets/{button-group-Dg6GrxAH.js → button-group-Dnp9PfP1.js} +1 -1
- package/dist/assets/{button-group.stories-BxJK661K.js → button-group.stories-Br_EMXmB.js} +1 -1
- package/dist/assets/{button.stories-CzS_9O5r.js → button.stories-Dh9JhOw6.js} +1 -1
- package/dist/assets/{card-BoBkN7zZ.js → card-D7QkgRPU.js} +1 -1
- package/dist/assets/{card.stories-CJM3mMAl.js → card.stories-DZ6fUn4F.js} +1 -1
- package/dist/assets/{chart.stories-DTfsMOMw.js → chart.stories-5mvT-zpx.js} +1 -1
- package/dist/assets/{checkbox-field-item-D3itMvx5.js → checkbox-field-item-ysgkDLCX.js} +1 -1
- package/dist/assets/{checkbox-field-item.stories-dbJJd5j4.js → checkbox-field-item.stories-C-OuHysX.js} +1 -1
- package/dist/assets/{checkbox-field.stories-D0U38na0.js → checkbox-field.stories-DET4STIP.js} +1 -1
- package/dist/assets/{cre8-element-DmRct7AK.js → cre8-element-D3XuogmB.js} +1 -1
- package/dist/assets/{cre8-form-element-DOU8_QgO.js → cre8-form-element-CYVZKUkM.js} +1 -1
- package/dist/assets/{danger-button.stories-C9I-81sl.js → danger-button.stories-fAfsxvin.js} +1 -1
- package/dist/assets/{date-picker.stories-BLywvSGj.js → date-picker.stories-Ck6AgzHE.js} +1 -1
- package/dist/assets/{divider-D5Ptz_gO.js → divider-BY3ZlruA.js} +1 -1
- package/dist/assets/{divider.stories-DeZhkiUu.js → divider.stories-owgSQsO4.js} +1 -1
- package/dist/assets/{dropdown-CEMfVKWu.js → dropdown-C91qBvHH.js} +1 -1
- package/dist/assets/{dropdown-item.stories-Drl5X5AH.js → dropdown-item.stories-B_gF04eB.js} +1 -1
- package/dist/assets/{dropdown.stories-gErmDoak.js → dropdown.stories-CAVN9Hfk.js} +1 -1
- package/dist/assets/{f-po-ClP0V3UU.js → f-po-BibEwLg7.js} +1 -1
- package/dist/assets/{feature.stories-DMWFA4_w.js → feature.stories-BfyMh3-v.js} +1 -1
- package/dist/assets/{field-CyeqmMLD.js → field-BGNR3p0L.js} +1 -1
- package/dist/assets/{field-note-4gAB1YtN.js → field-note-BnKZocKm.js} +1 -1
- package/dist/assets/{field-note.stories-BIkt-4nw.js → field-note.stories-DY8NRFUg.js} +1 -1
- package/dist/assets/{field.stories-Bp-i75cD.js → field.stories-BPk8Sd15.js} +1 -1
- package/dist/assets/{field.styles-BuRZIGyO.js → field.styles-DluEkAA0.js} +1 -1
- package/dist/assets/{footer.stories-Dct4TXtx.js → footer.stories-DxcGN204.js} +1 -1
- package/dist/assets/{form-DdOes3CI.js → form-BEztLvfh.js} +1 -1
- package/dist/assets/{form.stories-Bxijt3vs.js → form.stories-Cm6F6p8Q.js} +1 -1
- package/dist/assets/{formatter-L2YTDE3Q-BC-dAH-7.js → formatter-L2YTDE3Q-EtWfIGsw.js} +1 -1
- package/dist/assets/{global-nav-item-B-CZOxU0.js → global-nav-item-BjYreeQ_.js} +1 -1
- package/dist/assets/{global-nav-item.stories-5fOY46FM.js → global-nav-item.stories-CtIfegX4.js} +1 -1
- package/dist/assets/{global-nav.stories-DKE_MdUD.js → global-nav.stories-CpxixIgP.js} +1 -1
- package/dist/assets/{grid-item-BoB-uijb.js → grid-item-DfRshyU7.js} +1 -1
- package/dist/assets/{grid.stories-CFmGCOQD.js → grid.stories-HoL4hFK5.js} +1 -1
- package/dist/assets/{header.stories-CTNVu9H3.js → header.stories-DtnMiHw5.js} +1 -1
- package/dist/assets/{heading-CLjq87aR.js → heading-Bd8rz14W.js} +1 -1
- package/dist/assets/{heading.stories-DtV0xOBN.js → heading.stories-D6LqhrSJ.js} +1 -1
- package/dist/assets/{hero.stories-Ca6F0_ZF.js → hero.stories-DbVmgYoe.js} +1 -1
- package/dist/assets/{icon-DPDhfDk5.js → icon-5TiNNxPR.js} +1 -1
- package/dist/assets/{icon.stories-C3Q7NyK3.js → icon.stories-CSF4vjWQ.js} +1 -1
- package/dist/assets/if-defined-BYzWFJjz.js +1 -0
- package/dist/assets/{iframe-Cd639NOt.js → iframe-DNXIQNo5.js} +4 -4
- package/dist/assets/{inline-alert.stories-DQzPNO1M.js → inline-alert.stories-DPeI6lZo.js} +1 -1
- package/dist/assets/{layout-container.stories-CEu1E5xz.js → layout-container.stories-DjnXlNhJ.js} +1 -1
- package/dist/assets/{layout.stories-C-r1Ysar.js → layout.stories-RpAgLydl.js} +1 -1
- package/dist/assets/{linelength-container.stories-Z1xot9Nf.js → linelength-container.stories-CBXpDJq9.js} +1 -1
- package/dist/assets/{link-D8WlhTPZ.js → link-Yrdg4UMD.js} +1 -1
- package/dist/assets/{link-list.stories-9cOc5cKF.js → link-list.stories-B5HBzRbn.js} +1 -1
- package/dist/assets/{link.stories-D54TIq-J.js → link.stories-CMfRfExj.js} +1 -1
- package/dist/assets/{list.stories-C1Jx4AhC.js → list.stories-DxiKX7Ag.js} +1 -1
- package/dist/assets/{loading-spinner-ByesL8fd.js → loading-spinner-Dtn9_2xi.js} +1 -1
- package/dist/assets/{loading-spinner.stories-B7qYKdri.js → loading-spinner.stories-BLxVyD_V.js} +1 -1
- package/dist/assets/{logo.stories-jiwYTlr2.js → logo.stories-Bp4xEAgc.js} +1 -1
- package/dist/assets/{main.stories-DIohnnzB.js → main.stories-Dl_ReGW2.js} +1 -1
- package/dist/assets/{modal-LqTEYNjw.js → modal-BkUVltsh.js} +1 -1
- package/dist/assets/{modal-DO_Vneby.js → modal-D805CQSw.js} +1 -1
- package/dist/assets/{modal.stories-Bf16sUUo.js → modal.stories-Cmt-pN5U.js} +1 -1
- package/dist/assets/{multi-select.stories-D2FX0drF.js → multi-select.stories-BUY8eZbU.js} +1 -1
- package/dist/assets/{nav-container.stories-Dz8D1KTt.js → nav-container.stories-8-Hdrqet.js} +1 -1
- package/dist/assets/{page-header.stories-QSawevlA.js → page-header.stories-DnIfsM6p.js} +1 -1
- package/dist/assets/{pagination.stories-zXMokh9Q.js → pagination.stories-BGHD1N4G.js} +1 -1
- package/dist/assets/{percent-bar.stories-CExBGXPP.js → percent-bar.stories-BHkYQ9QF.js} +1 -1
- package/dist/assets/{popover.stories-wZjzpaSh.js → popover.stories-_kYFHU0l.js} +1 -1
- package/dist/assets/{primary-nav.stories-B9chy1Uv.js → primary-nav.stories-CtvK3j2S.js} +1 -1
- package/dist/assets/{progress-meter-OmPLl0CJ.js → progress-meter-BlWAgZUd.js} +1 -1
- package/dist/assets/{progress-meter.stories-BY73_kXC.js → progress-meter.stories-GeVuGj_S.js} +1 -1
- package/dist/assets/{progress-steps-item-DX7cfkY6.js → progress-steps-item-DJNftsaD.js} +1 -1
- package/dist/assets/{progress-steps-item.stories-CUJlwofh.js → progress-steps-item.stories-1UHAaQUG.js} +1 -1
- package/dist/assets/{progress-steps.stories-B9o0nT3v.js → progress-steps.stories-BeZeRh7H.js} +1 -1
- package/dist/assets/{radio-field-item-ApN9fT3r.js → radio-field-item-CT1M0B3m.js} +1 -1
- package/dist/assets/{radio-field-item.stories-5eMm6X-l.js → radio-field-item.stories-BI1bjaVr.js} +1 -1
- package/dist/assets/{radio-field.stories-nUhPXwi3.js → radio-field.stories-BImvG2r2.js} +1 -1
- package/dist/assets/{remove-tag-1irQee-a.js → remove-tag-4TqbdK7Q.js} +1 -1
- package/dist/assets/{remove-tag.stories-CBKcGI5F.js → remove-tag.stories-BRl0J94X.js} +1 -1
- package/dist/assets/{sample-modal.stories-D2h88MGz.js → sample-modal.stories-DF5OldDU.js} +1 -1
- package/dist/assets/{section.stories-FSvR1k6O.js → section.stories-ElOjlSK7.js} +1 -1
- package/dist/assets/{select-tile-C0MvyMiv.js → select-tile-DNBzrxMY.js} +1 -1
- package/dist/assets/{select-tile-list.stories-B6tc2fV5.js → select-tile-list.stories-oKhYBTxt.js} +1 -1
- package/dist/assets/{select-tile.stories-BeJuC0QL.js → select-tile.stories-vu14aNAr.js} +1 -1
- package/dist/assets/{select.stories-iqUp3i6o.js → select.stories-CyxFtumd.js} +1 -1
- package/dist/assets/{sign-in.stories-LiBRbPNv.js → sign-in.stories-BLk1lY2i.js} +1 -1
- package/dist/assets/{skeleton-loader.stories-BKrmx5lC.js → skeleton-loader.stories-B9RgJ96w.js} +1 -1
- package/dist/assets/{split-button.stories-CzGaEK2m.js → split-button.stories-DAoFf1Px.js} +1 -1
- package/dist/assets/{spread-t5SXTlkZ.js → spread-DycKdtF1.js} +1 -1
- package/dist/assets/state-CETXgFRU.js +1 -0
- package/dist/assets/{submenu.stories-PZXeOJN7.js → submenu.stories-JGU9u6xB.js} +1 -1
- package/dist/assets/{syntaxhighlighter-T5IQBZDB-wKvCRvsc.js → syntaxhighlighter-T5IQBZDB-BWE8R-LG.js} +1 -1
- package/dist/assets/{table-header-CbbWqMDC.js → table-header-BFBYVGrO.js} +1 -1
- package/dist/assets/{table-object.stories-BhUz4NJk.js → table-object.stories-DZlKjO9A.js} +1 -1
- package/dist/assets/{table.stories-kpLio1OA.js → table.stories-BXgbpGTm.js} +1 -1
- package/dist/assets/{tabs.stories-DX6mOsXJ.js → tabs.stories-DavvGpOC.js} +1 -1
- package/dist/assets/{tag-BhnWTIDT.js → tag-CB0gsxGW.js} +1 -1
- package/dist/assets/{tag-list.stories-Bbkyxw29.js → tag-list.stories-CwO4ONea.js} +1 -1
- package/dist/assets/{tag.stories-eiczN1_F.js → tag.stories-CyhRz7Ae.js} +1 -1
- package/dist/assets/{tertiary-nav.stories-BmZ5z1S7.js → tertiary-nav.stories-D0avN5fj.js} +1 -1
- package/dist/assets/{text-link-B1JUg0aF.js → text-link-DeikfyWI.js} +1 -1
- package/dist/assets/{text-link.stories-P9lrKEa2.js → text-link.stories-DJ0ePcYU.js} +1 -1
- package/dist/assets/{text-passage-DfLhIsZs.js → text-passage-Cw8VlQkR.js} +1 -1
- package/dist/assets/{text-passage.stories-CSpA8rpO.js → text-passage.stories-B7S5M-Zh.js} +1 -1
- package/dist/assets/{tooltip.stories-CreTe2cH.js → tooltip.stories-CbsS1Mok.js} +1 -1
- package/dist/assets/{utility-nav.stories-D5lUQ87g.js → utility-nav.stories-BlsohD-7.js} +1 -1
- package/dist/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-Bold.woff2 +0 -0
- package/dist/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-LatinExt.woff2 +0 -0
- package/dist/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-Medium.woff2 +0 -0
- package/dist/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-Regular.woff2 +0 -0
- package/dist/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-SemiBold.woff2 +0 -0
- package/dist/design-tokens/brands/cre8-vivid/css/fonts.css +31 -0
- package/dist/design-tokens/brands/cre8-vivid/css/tokens_brand.css +609 -0
- package/dist/design-tokens/brands/cre8-vivid/css/tokens_cre8-vivid.css +248 -0
- package/dist/iframe.html +1 -1
- package/dist/project.json +1 -1
- package/dist/sb-addons/storybook-5/manager-bundle.js +1 -1
- package/lib/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-Bold.woff2 +0 -0
- package/lib/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-LatinExt.woff2 +0 -0
- package/lib/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-Medium.woff2 +0 -0
- package/lib/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-Regular.woff2 +0 -0
- package/lib/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-SemiBold.woff2 +0 -0
- package/lib/design-tokens/brands/cre8-vivid/css/fonts.css +31 -0
- package/lib/design-tokens/brands/cre8-vivid/css/tokens_brand.css +609 -0
- package/lib/design-tokens/brands/cre8-vivid/css/tokens_cre8-vivid.css +248 -0
- package/lib/design-tokens/brands/cre8-vivid/css/tokens_cre8-vivid.module.d.ts +3 -0
- package/lib/design-tokens/brands/cre8-vivid/css/tokens_cre8-vivid.module.d.ts.map +1 -0
- package/lib/design-tokens/brands/cre8-vivid/css/tokens_cre8-vivid.module.js +890 -0
- package/lib/design-tokens/brands/cre8-vivid/css/tokens_cre8-vivid.module.js.map +1 -0
- package/lib/scripts/generate-mcp-manifest.js +1 -0
- package/lib/scripts/generate-mcp-manifest.js.map +1 -1
- package/mcp-manifest.json +21 -21
- package/package.json +2 -1
- package/react-manifest.json +19 -19
- package/dist/assets/if-defined-CxQseQbA.js +0 -1
- package/dist/assets/state-XoJdIlqR.js +0 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"contractVersion": 1,
|
|
3
|
-
"sourceCatalog": "https://cre8.dev/a2ui/catalogs/cre8-wc/2.
|
|
4
|
-
"libraryVersion": "2.
|
|
3
|
+
"sourceCatalog": "https://cre8.dev/a2ui/catalogs/cre8-wc/2.3.1",
|
|
4
|
+
"libraryVersion": "2.3.1",
|
|
5
5
|
"componentCount": 86,
|
|
6
6
|
"components": [
|
|
7
7
|
{
|
|
@@ -1662,7 +1662,7 @@
|
|
|
1662
1662
|
},
|
|
1663
1663
|
{
|
|
1664
1664
|
"name": "cre8-progress-steps",
|
|
1665
|
-
"category": "
|
|
1665
|
+
"category": "Feedback",
|
|
1666
1666
|
"props": {
|
|
1667
1667
|
"steps": {
|
|
1668
1668
|
"type": "array"
|
package/a2ui/catalog.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
-
"$id": "https://cre8.dev/a2ui/catalogs/cre8-wc/2.
|
|
3
|
+
"$id": "https://cre8.dev/a2ui/catalogs/cre8-wc/2.3.1",
|
|
4
4
|
"title": "cre8-wc A2UI Catalog",
|
|
5
5
|
"description": "cre8 Web Components is a library of presentational UI web components to be consumed by # web applications.",
|
|
6
6
|
"x-native-events": [
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"x-a2ui": {
|
|
55
55
|
"catalogId": "cre8-wc",
|
|
56
56
|
"library": "@tmorrow/cre8-wc",
|
|
57
|
-
"libraryVersion": "2.
|
|
57
|
+
"libraryVersion": "2.3.1",
|
|
58
58
|
"tagPrefix": "cre8",
|
|
59
59
|
"framework": "Lit 3.3.1"
|
|
60
60
|
},
|
|
@@ -167,6 +167,9 @@
|
|
|
167
167
|
{
|
|
168
168
|
"$ref": "#/$defs/components/cre8-progress-meter"
|
|
169
169
|
},
|
|
170
|
+
{
|
|
171
|
+
"$ref": "#/$defs/components/cre8-progress-steps"
|
|
172
|
+
},
|
|
170
173
|
{
|
|
171
174
|
"$ref": "#/$defs/components/cre8-progress-steps-item"
|
|
172
175
|
},
|
|
@@ -317,9 +320,6 @@
|
|
|
317
320
|
{
|
|
318
321
|
"$ref": "#/$defs/components/cre8-utility-nav-item"
|
|
319
322
|
},
|
|
320
|
-
{
|
|
321
|
-
"$ref": "#/$defs/components/cre8-progress-steps"
|
|
322
|
-
},
|
|
323
323
|
{
|
|
324
324
|
"$ref": "#/$defs/components/cre8-heading"
|
|
325
325
|
},
|
|
@@ -3291,6 +3291,74 @@
|
|
|
3291
3291
|
},
|
|
3292
3292
|
"additionalProperties": false
|
|
3293
3293
|
},
|
|
3294
|
+
"cre8-progress-steps": {
|
|
3295
|
+
"type": "object",
|
|
3296
|
+
"title": "cre8-progress-steps",
|
|
3297
|
+
"x-category": "Feedback",
|
|
3298
|
+
"description": "The Progress Steps component is used to display where a user is in a multistep process.\nIt clearly indicates the total number of steps, which steps are complete and incomplete,\nand which step you’re currently on. They help users estimate how long a task will take and can be\nused to track status on orders.\n\nThe Progress Steps component should be used as a parent component for `cre8-progress-steps-item` components.\nThese Components serve a contextual purpose and don't provide any functionality.\n\n# How to Use\n\nProgress Steps is used when there is ample horizontal space and two to six steps. It displays each step by name\nand number to help users understand exactly where they are in a process. It is the preferred option for desktop.\nProgress Steps should change to Compact Steps on mobile web to conserve space.\n\nProgress Steps can also be used to track order status. It provides a quick visual of how an order is progressing\nwith options to alert users of any problems along the way. When used for order status, Progress Steps should\nchange to Vertical Steps on mobile web to conserve space while allowing alerts and messages to remain visible.",
|
|
3299
|
+
"required": [
|
|
3300
|
+
"component"
|
|
3301
|
+
],
|
|
3302
|
+
"properties": {
|
|
3303
|
+
"component": {
|
|
3304
|
+
"const": "cre8-progress-steps",
|
|
3305
|
+
"description": "Component tag name"
|
|
3306
|
+
},
|
|
3307
|
+
"props": {
|
|
3308
|
+
"type": "object",
|
|
3309
|
+
"additionalProperties": false,
|
|
3310
|
+
"properties": {
|
|
3311
|
+
"steps": {
|
|
3312
|
+
"type": "array",
|
|
3313
|
+
"items": {
|
|
3314
|
+
"type": "object",
|
|
3315
|
+
"properties": {
|
|
3316
|
+
"name": {
|
|
3317
|
+
"type": "string"
|
|
3318
|
+
},
|
|
3319
|
+
"message": {
|
|
3320
|
+
"type": "string"
|
|
3321
|
+
},
|
|
3322
|
+
"state": {
|
|
3323
|
+
"type": "string",
|
|
3324
|
+
"enum": [
|
|
3325
|
+
"error",
|
|
3326
|
+
"warning",
|
|
3327
|
+
"complete",
|
|
3328
|
+
"current"
|
|
3329
|
+
]
|
|
3330
|
+
}
|
|
3331
|
+
},
|
|
3332
|
+
"required": [
|
|
3333
|
+
"name"
|
|
3334
|
+
],
|
|
3335
|
+
"additionalProperties": false
|
|
3336
|
+
},
|
|
3337
|
+
"description": "Steps for a data-driven progress indicator. Note that the visible label is\neach item's `name` prop rather than its content — `cre8-progress-steps-item`\ndoes not render children, which is easy to get wrong by hand.",
|
|
3338
|
+
"x-kind": "attribute"
|
|
3339
|
+
}
|
|
3340
|
+
}
|
|
3341
|
+
},
|
|
3342
|
+
"children": {
|
|
3343
|
+
"type": "array",
|
|
3344
|
+
"description": "The Progress Steps Item components that represent the steps in the multistep process.",
|
|
3345
|
+
"items": {
|
|
3346
|
+
"$ref": "#/$defs/Child"
|
|
3347
|
+
}
|
|
3348
|
+
},
|
|
3349
|
+
"events": {
|
|
3350
|
+
"type": "object",
|
|
3351
|
+
"description": "Event bindings. Each key is an event name; the value names the handler to emit.",
|
|
3352
|
+
"propertyNames": {
|
|
3353
|
+
"$ref": "#/$defs/NativeEventName"
|
|
3354
|
+
},
|
|
3355
|
+
"additionalProperties": {
|
|
3356
|
+
"$ref": "#/$defs/EventBinding"
|
|
3357
|
+
}
|
|
3358
|
+
}
|
|
3359
|
+
},
|
|
3360
|
+
"additionalProperties": false
|
|
3361
|
+
},
|
|
3294
3362
|
"cre8-progress-steps-item": {
|
|
3295
3363
|
"type": "object",
|
|
3296
3364
|
"title": "cre8-progress-steps-item",
|
|
@@ -7402,74 +7470,6 @@
|
|
|
7402
7470
|
},
|
|
7403
7471
|
"additionalProperties": false
|
|
7404
7472
|
},
|
|
7405
|
-
"cre8-progress-steps": {
|
|
7406
|
-
"type": "object",
|
|
7407
|
-
"title": "cre8-progress-steps",
|
|
7408
|
-
"x-category": "Other",
|
|
7409
|
-
"description": "The Progress Steps component is used to display where a user is in a multistep process.\nIt clearly indicates the total number of steps, which steps are complete and incomplete,\nand which step you’re currently on. They help users estimate how long a task will take and can be\nused to track status on orders.\n\nThe Progress Steps component should be used as a parent component for `cre8-progress-steps-item` components.\nThese Components serve a contextual purpose and don't provide any functionality.\n\n# How to Use\n\nProgress Steps is used when there is ample horizontal space and two to six steps. It displays each step by name\nand number to help users understand exactly where they are in a process. It is the preferred option for desktop.\nProgress Steps should change to Compact Steps on mobile web to conserve space.\n\nProgress Steps can also be used to track order status. It provides a quick visual of how an order is progressing\nwith options to alert users of any problems along the way. When used for order status, Progress Steps should\nchange to Vertical Steps on mobile web to conserve space while allowing alerts and messages to remain visible.",
|
|
7410
|
-
"required": [
|
|
7411
|
-
"component"
|
|
7412
|
-
],
|
|
7413
|
-
"properties": {
|
|
7414
|
-
"component": {
|
|
7415
|
-
"const": "cre8-progress-steps",
|
|
7416
|
-
"description": "Component tag name"
|
|
7417
|
-
},
|
|
7418
|
-
"props": {
|
|
7419
|
-
"type": "object",
|
|
7420
|
-
"additionalProperties": false,
|
|
7421
|
-
"properties": {
|
|
7422
|
-
"steps": {
|
|
7423
|
-
"type": "array",
|
|
7424
|
-
"items": {
|
|
7425
|
-
"type": "object",
|
|
7426
|
-
"properties": {
|
|
7427
|
-
"name": {
|
|
7428
|
-
"type": "string"
|
|
7429
|
-
},
|
|
7430
|
-
"message": {
|
|
7431
|
-
"type": "string"
|
|
7432
|
-
},
|
|
7433
|
-
"state": {
|
|
7434
|
-
"type": "string",
|
|
7435
|
-
"enum": [
|
|
7436
|
-
"error",
|
|
7437
|
-
"warning",
|
|
7438
|
-
"complete",
|
|
7439
|
-
"current"
|
|
7440
|
-
]
|
|
7441
|
-
}
|
|
7442
|
-
},
|
|
7443
|
-
"required": [
|
|
7444
|
-
"name"
|
|
7445
|
-
],
|
|
7446
|
-
"additionalProperties": false
|
|
7447
|
-
},
|
|
7448
|
-
"description": "Steps for a data-driven progress indicator. Note that the visible label is\neach item's `name` prop rather than its content — `cre8-progress-steps-item`\ndoes not render children, which is easy to get wrong by hand.",
|
|
7449
|
-
"x-kind": "attribute"
|
|
7450
|
-
}
|
|
7451
|
-
}
|
|
7452
|
-
},
|
|
7453
|
-
"children": {
|
|
7454
|
-
"type": "array",
|
|
7455
|
-
"description": "The Progress Steps Item components that represent the steps in the multistep process.",
|
|
7456
|
-
"items": {
|
|
7457
|
-
"$ref": "#/$defs/Child"
|
|
7458
|
-
}
|
|
7459
|
-
},
|
|
7460
|
-
"events": {
|
|
7461
|
-
"type": "object",
|
|
7462
|
-
"description": "Event bindings. Each key is an event name; the value names the handler to emit.",
|
|
7463
|
-
"propertyNames": {
|
|
7464
|
-
"$ref": "#/$defs/NativeEventName"
|
|
7465
|
-
},
|
|
7466
|
-
"additionalProperties": {
|
|
7467
|
-
"$ref": "#/$defs/EventBinding"
|
|
7468
|
-
}
|
|
7469
|
-
}
|
|
7470
|
-
},
|
|
7471
|
-
"additionalProperties": false
|
|
7472
|
-
},
|
|
7473
7473
|
"cre8-heading": {
|
|
7474
7474
|
"type": "object",
|
|
7475
7475
|
"title": "cre8-heading",
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Deployment-drift check for the knowledge graph.
|
|
4
|
+
*
|
|
5
|
+
* Generation keeps catalog-kg.json honest with the library it was built from.
|
|
6
|
+
* It does nothing about a copy of that file that was deployed and then left
|
|
7
|
+
* behind — which is how the Claude plugin served 1.0.27 (via the unscoped
|
|
8
|
+
* `cre8-mcp` package) while the checkout was on 2.3.x. This script compares the local graph against every other place
|
|
9
|
+
* one is served from and exits non-zero if any of them differ.
|
|
10
|
+
*
|
|
11
|
+
* Targets, each optional:
|
|
12
|
+
* --url <base> a running cre8-mcp API (a Vercel deployment, a local
|
|
13
|
+
* dev server).
|
|
14
|
+
* Fetches <base>/a2ui/runtime/catalog-kg.json.
|
|
15
|
+
* Repeatable. Also read from CRE8_MCP_URLS (comma-separated).
|
|
16
|
+
* --file <path> another checkout or bundle's catalog-kg.json
|
|
17
|
+
* (a plugin's vendored copy, an npm tarball). Repeatable.
|
|
18
|
+
* --npm [<version>] the published @tmorrow/cre8-wc package (latest by
|
|
19
|
+
* default) — what anyone installing the connector gets.
|
|
20
|
+
* --plugin <.mcp.json> a Claude plugin's server config. Resolves the npm
|
|
21
|
+
* package its `npx` line runs, then checks the
|
|
22
|
+
* @tmorrow/cre8-wc that package depends on. This is
|
|
23
|
+
* the surface that drifted furthest: the plugin ran
|
|
24
|
+
* the unscoped `cre8-mcp` (0.5.0, Feb 2026), which
|
|
25
|
+
* bundles its own 1.0.27 manifest and depends on no
|
|
26
|
+
* design-system package at all.
|
|
27
|
+
*
|
|
28
|
+
* pnpm --filter @tmorrow/cre8-wc check:deploy-drift -- --npm --plugin .claude/marketplaces/tmorrow_ai/cre8/.mcp.json
|
|
29
|
+
*/
|
|
30
|
+
import { createHash } from 'node:crypto';
|
|
31
|
+
import { readFileSync, mkdtempSync, rmSync } from 'node:fs';
|
|
32
|
+
import { tmpdir } from 'node:os';
|
|
33
|
+
import { dirname, join, resolve } from 'node:path';
|
|
34
|
+
import { execSync } from 'node:child_process';
|
|
35
|
+
import { fileURLToPath } from 'node:url';
|
|
36
|
+
|
|
37
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
38
|
+
const localPath = resolve(__dirname, 'catalog-kg.json');
|
|
39
|
+
|
|
40
|
+
const args = process.argv.slice(2);
|
|
41
|
+
const urls = (process.env.CRE8_MCP_URLS ?? '').split(',').map((s) => s.trim()).filter(Boolean);
|
|
42
|
+
const files = [];
|
|
43
|
+
const plugins = [];
|
|
44
|
+
let npm = null;
|
|
45
|
+
for (let i = 0; i < args.length; i++) {
|
|
46
|
+
if (args[i] === '--url') urls.push(args[++i]);
|
|
47
|
+
else if (args[i] === '--file') files.push(args[++i]);
|
|
48
|
+
else if (args[i] === '--plugin') plugins.push(args[++i]);
|
|
49
|
+
else if (args[i] === '--npm') npm = args[i + 1] && !args[i + 1].startsWith('--') ? args[++i] : 'latest';
|
|
50
|
+
else { console.error(`unknown argument ${args[i]}`); process.exit(2); }
|
|
51
|
+
}
|
|
52
|
+
if (!urls.length && !files.length && !npm && !plugins.length) {
|
|
53
|
+
console.error('nothing to compare against: pass --url, --file or --npm (or set CRE8_MCP_URLS)');
|
|
54
|
+
process.exit(2);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const fingerprint = (kg) => ({
|
|
58
|
+
library_version: kg.meta?.library_version ?? null,
|
|
59
|
+
components: kg.nodes?.filter((n) => n.type === 'component').length ?? 0,
|
|
60
|
+
categories: kg.nodes?.filter((n) => n.type === 'category').length ?? 0,
|
|
61
|
+
contains_edges: kg.meta?.contains_edges ?? kg.edges?.filter((e) => e.rel === 'CONTAINS').length ?? 0,
|
|
62
|
+
patterns: kg.nodes?.filter((n) => n.type === 'pattern').length ?? 0,
|
|
63
|
+
sha256: createHash('sha256').update(JSON.stringify({ nodes: kg.nodes, edges: kg.edges })).digest('hex').slice(0, 12),
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const local = fingerprint(JSON.parse(readFileSync(localPath, 'utf8')));
|
|
67
|
+
const targets = [];
|
|
68
|
+
|
|
69
|
+
for (const url of urls) {
|
|
70
|
+
const endpoint = `${url.replace(/\/$/, '')}/a2ui/runtime/catalog-kg.json`;
|
|
71
|
+
try {
|
|
72
|
+
const res = await fetch(endpoint);
|
|
73
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
74
|
+
targets.push({ name: endpoint, fp: fingerprint(await res.json()) });
|
|
75
|
+
} catch (err) {
|
|
76
|
+
targets.push({ name: endpoint, error: err?.message ?? String(err) });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
for (const file of files) {
|
|
80
|
+
try {
|
|
81
|
+
targets.push({ name: file, fp: fingerprint(JSON.parse(readFileSync(resolve(file), 'utf8'))) });
|
|
82
|
+
} catch (err) {
|
|
83
|
+
targets.push({ name: file, error: err?.message ?? String(err) });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** The catalog-kg.json inside a published @tmorrow/cre8-wc, or an error. */
|
|
87
|
+
function fromNpm(spec) {
|
|
88
|
+
const dir = mkdtempSync(join(tmpdir(), 'cre8-kg-'));
|
|
89
|
+
try {
|
|
90
|
+
const tgz = execSync(`npm pack ${spec} --pack-destination ${dir} --silent`, { encoding: 'utf8' }).trim().split('\n').pop();
|
|
91
|
+
execSync(`tar -xzf ${join(dir, tgz)} -C ${dir} package/a2ui/catalog-kg.json`);
|
|
92
|
+
return { fp: fingerprint(JSON.parse(readFileSync(join(dir, 'package', 'a2ui', 'catalog-kg.json'), 'utf8'))) };
|
|
93
|
+
} catch (err) {
|
|
94
|
+
return { error: `no catalog-kg.json in the published package (${err?.message?.split('\n')[0] ?? err})` };
|
|
95
|
+
} finally {
|
|
96
|
+
rmSync(dir, { recursive: true, force: true });
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (npm) {
|
|
101
|
+
const name = `@tmorrow/cre8-wc@${npm}`;
|
|
102
|
+
targets.push({ name, ...fromNpm(name) });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
for (const file of plugins) {
|
|
106
|
+
let label = file;
|
|
107
|
+
try {
|
|
108
|
+
const cfg = JSON.parse(readFileSync(resolve(file), 'utf8'));
|
|
109
|
+
const servers = Object.values(cfg.mcpServers ?? {});
|
|
110
|
+
const server = servers.find((s) => s.command === 'npx') ?? servers[0];
|
|
111
|
+
const pkg = (server?.args ?? []).find((a) => !a.startsWith('-'));
|
|
112
|
+
if (!pkg) throw new Error('no npx package in mcpServers');
|
|
113
|
+
label = `plugin → ${pkg}`;
|
|
114
|
+
const view = JSON.parse(execSync(`npm view ${pkg} version dependencies --json`, { encoding: 'utf8' }));
|
|
115
|
+
const wcRange = view.dependencies?.['@tmorrow/cre8-wc'];
|
|
116
|
+
if (!wcRange) {
|
|
117
|
+
targets.push({ name: `${label}@${view.version}`, error: 'does not depend on @tmorrow/cre8-wc — it bundles its own catalog and can never be graph-backed' });
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
const wcVersion = JSON.parse(execSync(`npm view "@tmorrow/cre8-wc@${wcRange}" version --json`, { encoding: 'utf8' }));
|
|
121
|
+
const resolved = Array.isArray(wcVersion) ? wcVersion.at(-1) : wcVersion;
|
|
122
|
+
targets.push({ name: `${label}@${view.version} (wc ${resolved})`, ...fromNpm(`@tmorrow/cre8-wc@${resolved}`) });
|
|
123
|
+
} catch (err) {
|
|
124
|
+
targets.push({ name: label, error: err?.message?.split('\n')[0] ?? String(err) });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const keys = Object.keys(local);
|
|
129
|
+
const pad = (s, n) => String(s).padEnd(n);
|
|
130
|
+
console.log(pad('', 34) + keys.map((k) => pad(k, 17)).join(''));
|
|
131
|
+
console.log(pad('local checkout', 34) + keys.map((k) => pad(local[k], 17)).join(''));
|
|
132
|
+
let drifted = 0;
|
|
133
|
+
for (const t of targets) {
|
|
134
|
+
if (t.error) {
|
|
135
|
+
drifted++;
|
|
136
|
+
console.log(`${pad(t.name.slice(0, 33), 34)}DRIFTED: ${t.error}`);
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const same = t.fp.sha256 === local.sha256;
|
|
140
|
+
if (!same) drifted++;
|
|
141
|
+
console.log(pad(t.name.slice(0, 33), 34) + keys.map((k) => pad(t.fp[k] === local[k] ? t.fp[k] : `${t.fp[k]} !!`, 17)).join(''));
|
|
142
|
+
}
|
|
143
|
+
if (drifted) {
|
|
144
|
+
console.error(`\n${drifted} deployment(s) do not serve the graph this checkout builds. Redeploy them with the library.`);
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
console.log('\nall deployments serve the same knowledge graph as this checkout');
|
|
@@ -1,31 +1,61 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generates catalog-kg.json
|
|
3
|
-
* catalog that cre8-mcp's KG-backed handlers serve.
|
|
2
|
+
* Generates catalog-kg.json — the knowledge graph cre8-mcp serves.
|
|
4
3
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* This is the single source of truth for everything cre8-mcp says about
|
|
5
|
+
* *relationships* between components. The catalog (catalog.json) says what
|
|
6
|
+
* each component accepts; this graph says what goes where, and why it is
|
|
7
|
+
* believed. Every tool that answers a structural question — get_composition,
|
|
8
|
+
* get_content_model, get_patterns, list_components — reads this file, and so
|
|
9
|
+
* does the eval oracle (evals/cre8-a2ui-vs-mcp/oracle/build_oracle.py). One
|
|
10
|
+
* regeneration refreshes all of them; nothing downstream re-derives.
|
|
8
11
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Deterministic: same inputs in, same graph out. Runs after
|
|
13
|
+
* generate-catalog.mjs, so `build:a2ui` keeps manifest -> catalog -> kg aligned.
|
|
14
|
+
*
|
|
15
|
+
* Nodes
|
|
16
|
+
* category cat:<Name>
|
|
17
|
+
* component <tag> props, slots, accepts_children, category,
|
|
18
|
+
* exemplar (smallest authored A2UI subtree)
|
|
19
|
+
* slot slot:<tag>:<name>
|
|
20
|
+
* enum_prop prop:<tag>:<prop>
|
|
21
|
+
* pattern pattern:<slug> name, description, spec (authored A2UI, validated)
|
|
22
|
+
*
|
|
23
|
+
* Edges
|
|
24
|
+
* BELONGS_TO component -> category
|
|
25
|
+
* HAS_SLOT component -> slot
|
|
26
|
+
* HAS_ENUM_PROP component -> enum_prop
|
|
27
|
+
* CONTAINS parent -> child { slot, count, evidence:[{kind,file}] }
|
|
28
|
+
* Only ever from observed artifacts (stories, component
|
|
29
|
+
* render templates, a2ui examples, a2ui patterns) — never
|
|
30
|
+
* from the naming rule. See kg-sources.mjs for the readers.
|
|
31
|
+
* USED_IN_PATTERN component -> pattern
|
|
32
|
+
* IN_FAMILY component <-> component sharing a name prefix. Undirected
|
|
33
|
+
* on purpose: cre8-tag-list contains cre8-tag, and the names
|
|
34
|
+
* do not say so.
|
|
35
|
+
* EXTENDS component -> base class (from graphify: Cre8FormElement …)
|
|
36
|
+
* IMPORTS component -> component, module-level (from graphify)
|
|
14
37
|
*/
|
|
15
38
|
import { readFileSync, writeFileSync } from 'node:fs';
|
|
16
39
|
import { fileURLToPath } from 'node:url';
|
|
17
40
|
import { dirname, resolve } from 'node:path';
|
|
41
|
+
import { newContainment, scanComponentsDir, scanExamples, scanGraphify, scanPatterns } from './kg-sources.mjs';
|
|
42
|
+
import { registerCatalog, validateSpec } from './index.js';
|
|
18
43
|
|
|
19
44
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
20
45
|
|
|
21
46
|
const catalogPath = resolve(__dirname, 'catalog.json');
|
|
22
47
|
const pkgPath = resolve(__dirname, '..', 'package.json');
|
|
23
48
|
const outPath = resolve(__dirname, 'catalog-kg.json');
|
|
49
|
+
const componentsDir = resolve(__dirname, '..', 'components');
|
|
50
|
+
const examplesDir = resolve(__dirname, 'examples');
|
|
51
|
+
const patternsDir = resolve(__dirname, 'patterns');
|
|
52
|
+
const graphifyPath = process.env.CRE8_GRAPHIFY ?? resolve(__dirname, '..', '..', '..', 'graphify-out', 'graph.json');
|
|
24
53
|
|
|
25
54
|
const catalog = JSON.parse(readFileSync(catalogPath, 'utf8'));
|
|
26
55
|
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
|
|
27
56
|
|
|
28
57
|
const components = catalog.$defs?.components ?? {};
|
|
58
|
+
const knownTags = new Set(Object.keys(components));
|
|
29
59
|
|
|
30
60
|
/** Collapses whitespace/newlines and truncates with an ellipsis. */
|
|
31
61
|
const summarize = (text, max) => {
|
|
@@ -34,21 +64,38 @@ const summarize = (text, max) => {
|
|
|
34
64
|
return flat.length > max ? `${flat.slice(0, max)}…` : flat;
|
|
35
65
|
};
|
|
36
66
|
|
|
67
|
+
// ─── evidence ───────────────────────────────────────────────────────────────
|
|
68
|
+
|
|
69
|
+
const stories = newContainment();
|
|
70
|
+
const sources = newContainment();
|
|
71
|
+
const scanned = scanComponentsDir(componentsDir, { stories, sources });
|
|
72
|
+
const examples = scanExamples(examplesDir);
|
|
73
|
+
const patternSet = scanPatterns(patternsDir);
|
|
74
|
+
const graphify = scanGraphify(graphifyPath, knownTags);
|
|
75
|
+
|
|
37
76
|
const nodes = [];
|
|
38
77
|
const edges = [];
|
|
39
78
|
|
|
40
|
-
//
|
|
79
|
+
// ─── categories ─────────────────────────────────────────────────────────────
|
|
80
|
+
|
|
81
|
+
// A component's category comes from the manifest's x-category. A component
|
|
82
|
+
// with none is not silently filed under "Other" any more: it is reported at
|
|
83
|
+
// the end and the build fails, because "Other" is exactly the kind of
|
|
84
|
+
// hand-maintained metadata this graph exists to stop drifting.
|
|
85
|
+
const uncategorized = [];
|
|
41
86
|
const categories = new Set();
|
|
42
|
-
for (const def of Object.
|
|
43
|
-
|
|
87
|
+
for (const [tag, def] of Object.entries(components)) {
|
|
88
|
+
if (!def['x-category'] || def['x-category'] === 'Other') uncategorized.push(tag);
|
|
89
|
+
else categories.add(def['x-category']);
|
|
44
90
|
}
|
|
45
91
|
for (const label of [...categories].sort()) {
|
|
46
92
|
nodes.push({ id: `cat:${label}`, type: 'category', label });
|
|
47
93
|
}
|
|
48
94
|
|
|
49
|
-
//
|
|
95
|
+
// ─── components, slots, enum props ──────────────────────────────────────────
|
|
96
|
+
|
|
50
97
|
for (const [tag, def] of Object.entries(components)) {
|
|
51
|
-
const category = def['x-category']
|
|
98
|
+
const category = def['x-category'] ?? null;
|
|
52
99
|
const propDefs = def.properties?.props?.properties ?? {};
|
|
53
100
|
const slotNames = Object.keys(def.properties?.slots?.properties ?? {});
|
|
54
101
|
const slotDescriptions = def['x-slot-descriptions'] ?? {};
|
|
@@ -64,6 +111,7 @@ for (const [tag, def] of Object.entries(components)) {
|
|
|
64
111
|
};
|
|
65
112
|
}
|
|
66
113
|
|
|
114
|
+
const ex = examples.exemplar.get(tag);
|
|
67
115
|
nodes.push({
|
|
68
116
|
id: tag,
|
|
69
117
|
type: 'component',
|
|
@@ -72,8 +120,10 @@ for (const [tag, def] of Object.entries(components)) {
|
|
|
72
120
|
props,
|
|
73
121
|
slots: slotNames,
|
|
74
122
|
accepts_children: Boolean(def.properties?.children),
|
|
123
|
+
extends: graphify.extends.get(tag) ?? null,
|
|
124
|
+
exemplar: ex ? { source: ex.source, path: ex.path, spec: ex.spec } : null,
|
|
75
125
|
});
|
|
76
|
-
edges.push({ from: tag, to: `cat:${category}`, rel: 'BELONGS_TO' });
|
|
126
|
+
if (category) edges.push({ from: tag, to: `cat:${category}`, rel: 'BELONGS_TO' });
|
|
77
127
|
|
|
78
128
|
for (const slotName of slotNames) {
|
|
79
129
|
const id = `slot:${tag}:${slotName}`;
|
|
@@ -102,14 +152,125 @@ for (const [tag, def] of Object.entries(components)) {
|
|
|
102
152
|
}
|
|
103
153
|
}
|
|
104
154
|
|
|
155
|
+
// ─── CONTAINS: merged evidence ──────────────────────────────────────────────
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* HTML and A2UI name the same position differently: unslotted markup is
|
|
159
|
+
* `children` in HTML, but for a component whose content model is slots the
|
|
160
|
+
* spec calls it `slots.default`. The graph speaks A2UI, because that is what
|
|
161
|
+
* the tools emit and validate — so the catalog's content model for the parent
|
|
162
|
+
* decides, and a story's unslotted child lands in `default` on a slotted
|
|
163
|
+
* component and in `children` (null) on a children component.
|
|
164
|
+
*/
|
|
165
|
+
const a2uiSlot = (parent, slot) => {
|
|
166
|
+
const def = components[parent];
|
|
167
|
+
const takesChildren = Boolean(def?.properties?.children);
|
|
168
|
+
const slotNames = Object.keys(def?.properties?.slots?.properties ?? {});
|
|
169
|
+
if (slot == null) return takesChildren || !slotNames.includes('default') ? null : 'default';
|
|
170
|
+
if (slot === 'default' && takesChildren) return null;
|
|
171
|
+
return slot;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
/** key "parent|slot|child" -> { count, evidence: Map<kind, Set<file>> } */
|
|
175
|
+
const contains = new Map();
|
|
176
|
+
const merge = (kind, containment) => {
|
|
177
|
+
for (const [parent, bySlot] of containment) {
|
|
178
|
+
if (!knownTags.has(parent)) continue;
|
|
179
|
+
for (const [rawSlot, byChild] of bySlot) {
|
|
180
|
+
const slot = a2uiSlot(parent, rawSlot);
|
|
181
|
+
for (const [child, rec] of byChild) {
|
|
182
|
+
if (!knownTags.has(child)) continue; // cre8-icon-legacy and friends are not in the catalog
|
|
183
|
+
const key = `${parent}|${slot ?? ''}|${child}`;
|
|
184
|
+
const e = contains.get(key) ?? { parent, slot, child, count: 0, evidence: new Map() };
|
|
185
|
+
e.count += rec.count;
|
|
186
|
+
const files = e.evidence.get(kind) ?? new Set();
|
|
187
|
+
for (const f of rec.files) files.add(f);
|
|
188
|
+
e.evidence.set(kind, files);
|
|
189
|
+
contains.set(key, e);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
merge('source', sources);
|
|
195
|
+
merge('story', stories);
|
|
196
|
+
merge('example', examples.containment);
|
|
197
|
+
merge('pattern', patternSet.containment);
|
|
198
|
+
|
|
199
|
+
const containsEdges = [...contains.values()]
|
|
200
|
+
.sort((a, b) => a.parent.localeCompare(b.parent) || (a.slot ?? '').localeCompare(b.slot ?? '') || a.child.localeCompare(b.child))
|
|
201
|
+
.map((e) => ({
|
|
202
|
+
from: e.parent,
|
|
203
|
+
to: e.child,
|
|
204
|
+
rel: 'CONTAINS',
|
|
205
|
+
slot: e.slot,
|
|
206
|
+
count: e.count,
|
|
207
|
+
evidence: [...e.evidence].flatMap(([kind, files]) => [...files].sort().map((file) => ({ kind, file }))),
|
|
208
|
+
}));
|
|
209
|
+
edges.push(...containsEdges);
|
|
210
|
+
|
|
211
|
+
// ─── patterns ───────────────────────────────────────────────────────────────
|
|
212
|
+
|
|
213
|
+
// A pattern is an authored spec, so it is held to the same bar as anything an
|
|
214
|
+
// agent would emit: it must validate against the catalog it ships with.
|
|
215
|
+
const registered = registerCatalog(catalog);
|
|
216
|
+
const invalidPatterns = [];
|
|
217
|
+
for (const p of patternSet.patterns) {
|
|
218
|
+
try {
|
|
219
|
+
validateSpec(p.spec, registered);
|
|
220
|
+
} catch (err) {
|
|
221
|
+
invalidPatterns.push(`${p.source}: ${err?.message ?? err}`);
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
nodes.push({
|
|
225
|
+
id: `pattern:${p.slug}`,
|
|
226
|
+
type: 'pattern',
|
|
227
|
+
name: p.name,
|
|
228
|
+
description: p.description,
|
|
229
|
+
source: p.source,
|
|
230
|
+
spec: p.spec,
|
|
231
|
+
components: p.components,
|
|
232
|
+
});
|
|
233
|
+
for (const tag of p.components) edges.push({ from: tag, to: `pattern:${p.slug}`, rel: 'USED_IN_PATTERN' });
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// ─── IN_FAMILY ──────────────────────────────────────────────────────────────
|
|
237
|
+
|
|
238
|
+
const tags = [...knownTags].sort();
|
|
239
|
+
for (const a of tags) {
|
|
240
|
+
for (const b of tags) {
|
|
241
|
+
if (a < b && (b.startsWith(`${a}-`) || a.startsWith(`${b}-`))) {
|
|
242
|
+
edges.push({ from: a, to: b, rel: 'IN_FAMILY' });
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// ─── EXTENDS / IMPORTS ──────────────────────────────────────────────────────
|
|
248
|
+
|
|
249
|
+
for (const [tag, base] of [...graphify.extends].sort()) {
|
|
250
|
+
edges.push({ from: tag, to: `class:${base}`, rel: 'EXTENDS' });
|
|
251
|
+
}
|
|
252
|
+
for (const [from, set] of [...graphify.imports].sort()) {
|
|
253
|
+
for (const to of [...set].sort()) edges.push({ from, to, rel: 'IMPORTS' });
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// ─── write ──────────────────────────────────────────────────────────────────
|
|
257
|
+
|
|
105
258
|
const kg = {
|
|
106
259
|
meta: {
|
|
107
|
-
generated_from: 'catalog.json',
|
|
260
|
+
generated_from: ['catalog.json', 'components/*/*.stories.ts', 'components/*/*.ts', 'a2ui/examples/*.json', 'a2ui/patterns/*.json', graphify.found ? 'graphify-out/graph.json' : null].filter(Boolean),
|
|
108
261
|
catalog_id: 'cre8-wc',
|
|
109
262
|
library: pkg.name,
|
|
110
263
|
library_version: pkg.version,
|
|
264
|
+
graphify_commit: graphify.commit,
|
|
265
|
+
evidence: {
|
|
266
|
+
story_files: scanned.storyFiles,
|
|
267
|
+
source_files: scanned.sourceFiles,
|
|
268
|
+
example_files: examples.files,
|
|
269
|
+
pattern_files: patternSet.patterns.map((p) => p.source.replace('a2ui/patterns/', '')),
|
|
270
|
+
},
|
|
111
271
|
total_nodes: nodes.length,
|
|
112
272
|
total_edges: edges.length,
|
|
273
|
+
contains_edges: containsEdges.length,
|
|
113
274
|
},
|
|
114
275
|
nodes,
|
|
115
276
|
edges,
|
|
@@ -118,5 +279,20 @@ const kg = {
|
|
|
118
279
|
writeFileSync(outPath, `${JSON.stringify(kg, null, 2)}\n`, 'utf8');
|
|
119
280
|
console.log(
|
|
120
281
|
`catalog-kg.json: ${nodes.length} nodes, ${edges.length} edges `
|
|
121
|
-
+ `(${
|
|
282
|
+
+ `(${knownTags.size} components, ${categories.size} categories, `
|
|
283
|
+
+ `${containsEdges.length} CONTAINS from ${scanned.storyFiles} stories + ${scanned.sourceFiles} sources + ${examples.files.length} examples + ${patternSet.patterns.length} patterns`
|
|
284
|
+
+ `${graphify.found ? `, graphify@${(graphify.commit ?? '').slice(0, 7)}` : ', no graphify graph'})`,
|
|
122
285
|
);
|
|
286
|
+
|
|
287
|
+
if (invalidPatterns.length) {
|
|
288
|
+
console.error(`\ncatalog-kg: ${invalidPatterns.length} pattern(s) do not validate against the catalog:\n ${invalidPatterns.join('\n ')}`);
|
|
289
|
+
process.exit(1);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (uncategorized.length) {
|
|
293
|
+
console.error(
|
|
294
|
+
`\ncatalog-kg: ${uncategorized.length} component(s) have no category: ${uncategorized.join(', ')}\n`
|
|
295
|
+
+ 'Add them to CATEGORY_MAP in scripts/generate-mcp-manifest.ts — "Other" is not a category.',
|
|
296
|
+
);
|
|
297
|
+
process.exit(1);
|
|
298
|
+
}
|