@tmorrow/cre8-wc 2.3.1 → 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.
Files changed (160) hide show
  1. package/a2ui/catalog-kg.json +6837 -116
  2. package/a2ui/catalog.compact.json +3 -3
  3. package/a2ui/catalog.json +73 -73
  4. package/a2ui/check-deploy-drift.mjs +147 -0
  5. package/a2ui/generate-catalog-kg.mjs +194 -18
  6. package/a2ui/kg-sources.mjs +291 -0
  7. package/a2ui/patterns/alert-banner.json +16 -0
  8. package/a2ui/patterns/data-table.json +67 -0
  9. package/a2ui/patterns/login-form.json +55 -0
  10. package/a2ui/patterns/modal-dialog.json +47 -0
  11. package/a2ui/patterns/page-layout.json +55 -0
  12. package/a2ui/patterns/tabbed-content.json +37 -0
  13. package/dist/assets/{Changelog-Documentation-DOFtrp0l.js → Changelog-Documentation-DyRD5g5c.js} +1 -1
  14. package/dist/assets/{Code-Guidelines-DOpFovRV.js → Code-Guidelines-DIxeIc7I.js} +1 -1
  15. package/dist/assets/{Color-6AOWCN3U-BTESbN-y.js → Color-6AOWCN3U-Dznni4GY.js} +1 -1
  16. package/dist/assets/{Contributing-Guidelines-CiT1zg3Q.js → Contributing-Guidelines-C361mreO.js} +1 -1
  17. package/dist/assets/{DocsRenderer-JROSPFPF-CmyeTng-.js → DocsRenderer-JROSPFPF-DVzuXMfE.js} +1 -1
  18. package/dist/assets/{Tokens-Documentation-fmAKrN46.js → Tokens-Documentation-DQ55nCPE.js} +1 -1
  19. package/dist/assets/{WithTooltip-7X4HQR7L-Dpmimnc2.js → WithTooltip-7X4HQR7L-57g4vxQ5.js} +1 -1
  20. package/dist/assets/{accordion-item.stories-C9Bb64L6.js → accordion-item.stories-Cz0JPYkb.js} +1 -1
  21. package/dist/assets/{accordion.stories-C8BjZxDt.js → accordion.stories-CKPEtfSL.js} +1 -1
  22. package/dist/assets/{address-form.stories-ScjvN6iD.js → address-form.stories-clpPw22i.js} +1 -1
  23. package/dist/assets/{alert.stories-CzqQEZwk.js → alert.stories-UoZRIq2Z.js} +1 -1
  24. package/dist/assets/{badge-DcS8KYQD.js → badge-Bf3zamLa.js} +1 -1
  25. package/dist/assets/{badge.stories-Bc-yiiuH.js → badge.stories-BpZgJgka.js} +1 -1
  26. package/dist/assets/{band.stories-D9kccmGR.js → band.stories-CX5fEcU0.js} +1 -1
  27. package/dist/assets/{blocks-C_CCjW0W.js → blocks-F7P3fIJh.js} +5 -5
  28. package/dist/assets/{breadcrumbs.stories-DVucmPSY.js → breadcrumbs.stories-CRuQAhFW.js} +1 -1
  29. package/dist/assets/{button-DveXG-ss.js → button-BIrV07TC.js} +1 -1
  30. package/dist/assets/{button-group-jImwLK6C.js → button-group-Dnp9PfP1.js} +1 -1
  31. package/dist/assets/{button-group.stories-C79ddoQs.js → button-group.stories-Br_EMXmB.js} +1 -1
  32. package/dist/assets/{button.stories-8k8QO5YH.js → button.stories-Dh9JhOw6.js} +1 -1
  33. package/dist/assets/{card-BH9ImBMA.js → card-D7QkgRPU.js} +1 -1
  34. package/dist/assets/{card.stories-BSi6kF0g.js → card.stories-DZ6fUn4F.js} +1 -1
  35. package/dist/assets/{chart.stories-BSqnOQgJ.js → chart.stories-5mvT-zpx.js} +1 -1
  36. package/dist/assets/{checkbox-field-item-BEC6dGE4.js → checkbox-field-item-ysgkDLCX.js} +1 -1
  37. package/dist/assets/{checkbox-field-item.stories-CUv16wmO.js → checkbox-field-item.stories-C-OuHysX.js} +1 -1
  38. package/dist/assets/{checkbox-field.stories-DqPhKSJO.js → checkbox-field.stories-DET4STIP.js} +1 -1
  39. package/dist/assets/{cre8-element-5D-9EYYr.js → cre8-element-D3XuogmB.js} +1 -1
  40. package/dist/assets/{cre8-form-element-CNXiLVOR.js → cre8-form-element-CYVZKUkM.js} +1 -1
  41. package/dist/assets/{danger-button.stories-LylzneXF.js → danger-button.stories-fAfsxvin.js} +1 -1
  42. package/dist/assets/{date-picker.stories-p9PLWnWO.js → date-picker.stories-Ck6AgzHE.js} +1 -1
  43. package/dist/assets/{divider-CGOVnVcb.js → divider-BY3ZlruA.js} +1 -1
  44. package/dist/assets/{divider.stories-DOsvRVXD.js → divider.stories-owgSQsO4.js} +1 -1
  45. package/dist/assets/{dropdown-Dw6J0VB-.js → dropdown-C91qBvHH.js} +1 -1
  46. package/dist/assets/{dropdown-item.stories-BQ30eir7.js → dropdown-item.stories-B_gF04eB.js} +1 -1
  47. package/dist/assets/{dropdown.stories-CyDYe6KW.js → dropdown.stories-CAVN9Hfk.js} +1 -1
  48. package/dist/assets/{f-po-BQd7CCl4.js → f-po-BibEwLg7.js} +1 -1
  49. package/dist/assets/{feature.stories-Cscqh_iq.js → feature.stories-BfyMh3-v.js} +1 -1
  50. package/dist/assets/{field-MMWcTliE.js → field-BGNR3p0L.js} +1 -1
  51. package/dist/assets/{field-note-Bpw7_N-2.js → field-note-BnKZocKm.js} +1 -1
  52. package/dist/assets/{field-note.stories-CF6YSXo4.js → field-note.stories-DY8NRFUg.js} +1 -1
  53. package/dist/assets/{field.stories-khpMJCm2.js → field.stories-BPk8Sd15.js} +1 -1
  54. package/dist/assets/{field.styles-BoG5epfO.js → field.styles-DluEkAA0.js} +1 -1
  55. package/dist/assets/{footer.stories-B98beiAi.js → footer.stories-DxcGN204.js} +1 -1
  56. package/dist/assets/{form-DeL212s2.js → form-BEztLvfh.js} +1 -1
  57. package/dist/assets/{form.stories-DODF6MTZ.js → form.stories-Cm6F6p8Q.js} +1 -1
  58. package/dist/assets/{formatter-L2YTDE3Q-BZOYlppp.js → formatter-L2YTDE3Q-EtWfIGsw.js} +1 -1
  59. package/dist/assets/{global-nav-item-M_Bh-USr.js → global-nav-item-BjYreeQ_.js} +1 -1
  60. package/dist/assets/{global-nav-item.stories-D1rYGmTZ.js → global-nav-item.stories-CtIfegX4.js} +1 -1
  61. package/dist/assets/{global-nav.stories-Bao3NLXU.js → global-nav.stories-CpxixIgP.js} +1 -1
  62. package/dist/assets/{grid-item-C33Dx1PK.js → grid-item-DfRshyU7.js} +1 -1
  63. package/dist/assets/{grid.stories-B52T8r0W.js → grid.stories-HoL4hFK5.js} +1 -1
  64. package/dist/assets/{header.stories-DJ9o8w_2.js → header.stories-DtnMiHw5.js} +1 -1
  65. package/dist/assets/{heading-B0taz64_.js → heading-Bd8rz14W.js} +1 -1
  66. package/dist/assets/{heading.stories-Bcl5rWGp.js → heading.stories-D6LqhrSJ.js} +1 -1
  67. package/dist/assets/{hero.stories-CFfC1SdJ.js → hero.stories-DbVmgYoe.js} +1 -1
  68. package/dist/assets/{icon-1uQoSddP.js → icon-5TiNNxPR.js} +1 -1
  69. package/dist/assets/{icon.stories-B2ObVxZM.js → icon.stories-CSF4vjWQ.js} +1 -1
  70. package/dist/assets/if-defined-BYzWFJjz.js +1 -0
  71. package/dist/assets/{iframe-Xcrj_hym.js → iframe-DNXIQNo5.js} +4 -4
  72. package/dist/assets/{inline-alert.stories-BF5eiNA0.js → inline-alert.stories-DPeI6lZo.js} +1 -1
  73. package/dist/assets/{layout-container.stories-BR3VmdO_.js → layout-container.stories-DjnXlNhJ.js} +1 -1
  74. package/dist/assets/{layout.stories-BYDxp7cP.js → layout.stories-RpAgLydl.js} +1 -1
  75. package/dist/assets/{linelength-container.stories-DexAK0U3.js → linelength-container.stories-CBXpDJq9.js} +1 -1
  76. package/dist/assets/{link-DTIPpEoL.js → link-Yrdg4UMD.js} +1 -1
  77. package/dist/assets/{link-list.stories-CJrrudo_.js → link-list.stories-B5HBzRbn.js} +1 -1
  78. package/dist/assets/{link.stories-CcPCOGBJ.js → link.stories-CMfRfExj.js} +1 -1
  79. package/dist/assets/{list.stories-yO9LkJAF.js → list.stories-DxiKX7Ag.js} +1 -1
  80. package/dist/assets/{loading-spinner-CB4fUQUZ.js → loading-spinner-Dtn9_2xi.js} +1 -1
  81. package/dist/assets/{loading-spinner.stories-DX_a1FDd.js → loading-spinner.stories-BLxVyD_V.js} +1 -1
  82. package/dist/assets/{logo.stories-BzchSODP.js → logo.stories-Bp4xEAgc.js} +1 -1
  83. package/dist/assets/{main.stories-BUCeYuaP.js → main.stories-Dl_ReGW2.js} +1 -1
  84. package/dist/assets/{modal-Cy3trDel.js → modal-BkUVltsh.js} +1 -1
  85. package/dist/assets/{modal-DkSg_-L1.js → modal-D805CQSw.js} +1 -1
  86. package/dist/assets/{modal.stories-MArx7xER.js → modal.stories-Cmt-pN5U.js} +1 -1
  87. package/dist/assets/{multi-select.stories-DovUtQeg.js → multi-select.stories-BUY8eZbU.js} +1 -1
  88. package/dist/assets/{nav-container.stories-JIi3T3ZH.js → nav-container.stories-8-Hdrqet.js} +1 -1
  89. package/dist/assets/{page-header.stories-UG8CW21H.js → page-header.stories-DnIfsM6p.js} +1 -1
  90. package/dist/assets/{pagination.stories-Dt4t691F.js → pagination.stories-BGHD1N4G.js} +1 -1
  91. package/dist/assets/{percent-bar.stories-Yd22_Y0-.js → percent-bar.stories-BHkYQ9QF.js} +1 -1
  92. package/dist/assets/{popover.stories-CYGGIeZB.js → popover.stories-_kYFHU0l.js} +1 -1
  93. package/dist/assets/{primary-nav.stories-DKsO9kZG.js → primary-nav.stories-CtvK3j2S.js} +1 -1
  94. package/dist/assets/{progress-meter-DI2runk8.js → progress-meter-BlWAgZUd.js} +1 -1
  95. package/dist/assets/{progress-meter.stories-CGPZ5hGE.js → progress-meter.stories-GeVuGj_S.js} +1 -1
  96. package/dist/assets/{progress-steps-item-B31UPMMA.js → progress-steps-item-DJNftsaD.js} +1 -1
  97. package/dist/assets/{progress-steps-item.stories-DjL2E6NP.js → progress-steps-item.stories-1UHAaQUG.js} +1 -1
  98. package/dist/assets/{progress-steps.stories-Bqao2HX_.js → progress-steps.stories-BeZeRh7H.js} +1 -1
  99. package/dist/assets/{radio-field-item-C0bshxVl.js → radio-field-item-CT1M0B3m.js} +1 -1
  100. package/dist/assets/{radio-field-item.stories-mGDgsH2y.js → radio-field-item.stories-BI1bjaVr.js} +1 -1
  101. package/dist/assets/{radio-field.stories-DPQEn2nB.js → radio-field.stories-BImvG2r2.js} +1 -1
  102. package/dist/assets/{remove-tag-DggKf8tv.js → remove-tag-4TqbdK7Q.js} +1 -1
  103. package/dist/assets/{remove-tag.stories-BEv98h4W.js → remove-tag.stories-BRl0J94X.js} +1 -1
  104. package/dist/assets/{sample-modal.stories-hH-pQmLW.js → sample-modal.stories-DF5OldDU.js} +1 -1
  105. package/dist/assets/{section.stories-257ppaeU.js → section.stories-ElOjlSK7.js} +1 -1
  106. package/dist/assets/{select-tile-EhbY9v0c.js → select-tile-DNBzrxMY.js} +1 -1
  107. package/dist/assets/{select-tile-list.stories-czP31ahg.js → select-tile-list.stories-oKhYBTxt.js} +1 -1
  108. package/dist/assets/{select-tile.stories-BSuQVXhf.js → select-tile.stories-vu14aNAr.js} +1 -1
  109. package/dist/assets/{select.stories-q_WTHHRz.js → select.stories-CyxFtumd.js} +1 -1
  110. package/dist/assets/{sign-in.stories-CwImT7MX.js → sign-in.stories-BLk1lY2i.js} +1 -1
  111. package/dist/assets/{skeleton-loader.stories-CQKGkhsk.js → skeleton-loader.stories-B9RgJ96w.js} +1 -1
  112. package/dist/assets/{split-button.stories-ZNBQ2SNu.js → split-button.stories-DAoFf1Px.js} +1 -1
  113. package/dist/assets/{spread-CLDPfDo7.js → spread-DycKdtF1.js} +1 -1
  114. package/dist/assets/state-CETXgFRU.js +1 -0
  115. package/dist/assets/{submenu.stories-C2HQ7S0-.js → submenu.stories-JGU9u6xB.js} +1 -1
  116. package/dist/assets/{syntaxhighlighter-T5IQBZDB-Dt5CQpEL.js → syntaxhighlighter-T5IQBZDB-BWE8R-LG.js} +1 -1
  117. package/dist/assets/{table-header-KMJz4lGv.js → table-header-BFBYVGrO.js} +1 -1
  118. package/dist/assets/{table-object.stories-8JpO7mEP.js → table-object.stories-DZlKjO9A.js} +1 -1
  119. package/dist/assets/{table.stories-DY4MKiQU.js → table.stories-BXgbpGTm.js} +1 -1
  120. package/dist/assets/{tabs.stories-CtqjM6cH.js → tabs.stories-DavvGpOC.js} +1 -1
  121. package/dist/assets/{tag-cdmFcZjR.js → tag-CB0gsxGW.js} +1 -1
  122. package/dist/assets/{tag-list.stories-CcRDtQOH.js → tag-list.stories-CwO4ONea.js} +1 -1
  123. package/dist/assets/{tag.stories-CibxsGkC.js → tag.stories-CyhRz7Ae.js} +1 -1
  124. package/dist/assets/{tertiary-nav.stories-BmuDNMGm.js → tertiary-nav.stories-D0avN5fj.js} +1 -1
  125. package/dist/assets/{text-link-BfepDxf2.js → text-link-DeikfyWI.js} +1 -1
  126. package/dist/assets/{text-link.stories-DD914cTl.js → text-link.stories-DJ0ePcYU.js} +1 -1
  127. package/dist/assets/{text-passage-t4zdIHJW.js → text-passage-Cw8VlQkR.js} +1 -1
  128. package/dist/assets/{text-passage.stories-_NygxSJU.js → text-passage.stories-B7S5M-Zh.js} +1 -1
  129. package/dist/assets/{tooltip.stories-DjcebD_S.js → tooltip.stories-CbsS1Mok.js} +1 -1
  130. package/dist/assets/{utility-nav.stories-DOj5F9A3.js → utility-nav.stories-BlsohD-7.js} +1 -1
  131. package/dist/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-Bold.woff2 +0 -0
  132. package/dist/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-LatinExt.woff2 +0 -0
  133. package/dist/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-Medium.woff2 +0 -0
  134. package/dist/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-Regular.woff2 +0 -0
  135. package/dist/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-SemiBold.woff2 +0 -0
  136. package/dist/design-tokens/brands/cre8-vivid/css/fonts.css +31 -0
  137. package/dist/design-tokens/brands/cre8-vivid/css/tokens_brand.css +609 -0
  138. package/dist/design-tokens/brands/cre8-vivid/css/tokens_cre8-vivid.css +248 -0
  139. package/dist/iframe.html +1 -1
  140. package/dist/project.json +1 -1
  141. package/dist/sb-addons/storybook-5/manager-bundle.js +1 -1
  142. package/lib/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-Bold.woff2 +0 -0
  143. package/lib/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-LatinExt.woff2 +0 -0
  144. package/lib/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-Medium.woff2 +0 -0
  145. package/lib/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-Regular.woff2 +0 -0
  146. package/lib/design-tokens/brands/cre8-vivid/css/assets/fonts/PlusJakartaSans-SemiBold.woff2 +0 -0
  147. package/lib/design-tokens/brands/cre8-vivid/css/fonts.css +31 -0
  148. package/lib/design-tokens/brands/cre8-vivid/css/tokens_brand.css +609 -0
  149. package/lib/design-tokens/brands/cre8-vivid/css/tokens_cre8-vivid.css +248 -0
  150. package/lib/design-tokens/brands/cre8-vivid/css/tokens_cre8-vivid.module.d.ts +3 -0
  151. package/lib/design-tokens/brands/cre8-vivid/css/tokens_cre8-vivid.module.d.ts.map +1 -0
  152. package/lib/design-tokens/brands/cre8-vivid/css/tokens_cre8-vivid.module.js +890 -0
  153. package/lib/design-tokens/brands/cre8-vivid/css/tokens_cre8-vivid.module.js.map +1 -0
  154. package/lib/scripts/generate-mcp-manifest.js +1 -0
  155. package/lib/scripts/generate-mcp-manifest.js.map +1 -1
  156. package/mcp-manifest.json +21 -21
  157. package/package.json +2 -1
  158. package/react-manifest.json +19 -19
  159. package/dist/assets/if-defined-Ds7WzQ_M.js +0 -1
  160. package/dist/assets/state-aQwEJ_0z.js +0 -1
@@ -0,0 +1,291 @@
1
+ /**
2
+ * Evidence readers for generate-catalog-kg.mjs.
3
+ *
4
+ * Each reader walks one kind of shipped, authored artifact and reports the
5
+ * component nestings it actually contains. Nothing here infers nesting from
6
+ * names — composition.ts documents why a synthesized skeleton is confidently
7
+ * wrong. A nesting exists in the graph only because some artifact in this
8
+ * repo demonstrates it, and every CONTAINS edge carries the files that do.
9
+ *
10
+ * stories components/<name>/<name>.stories.ts — lit `html` templates.
11
+ * The widest corpus: every component ships at least one story,
12
+ * and compound families (table, tabs, nav) are exercised in full.
13
+ * sources components/<name>/<name>.ts — a component's own render()
14
+ * template. When cre8-table-object renders cre8-table-row itself,
15
+ * that is the library asserting the nesting, not an example.
16
+ * examples a2ui/examples/*.json — authored A2UI specs. The only source
17
+ * that speaks the spec's own children-vs-slots vocabulary, so it
18
+ * is also where exemplar subtrees come from.
19
+ * graphify graphify-out/graph.json — the AST graph. It does not know
20
+ * which tag renders inside which, so it contributes no CONTAINS
21
+ * edges. It does know class inheritance (Cre8FormElement) and
22
+ * module imports, which become EXTENDS and IMPORTS edges.
23
+ */
24
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
25
+ import { join } from 'node:path';
26
+
27
+ /** parent -> slot|null -> child -> { count, files:Set } */
28
+ export function newContainment() {
29
+ return new Map();
30
+ }
31
+
32
+ export function note(containment, parent, slot, child, file) {
33
+ const bySlot = containment.get(parent) ?? new Map();
34
+ const byChild = bySlot.get(slot) ?? new Map();
35
+ const rec = byChild.get(child) ?? { count: 0, files: new Set() };
36
+ rec.count += 1;
37
+ rec.files.add(file);
38
+ byChild.set(child, rec);
39
+ bySlot.set(slot, byChild);
40
+ containment.set(parent, bySlot);
41
+ }
42
+
43
+ // ─── lit / HTML templates ────────────────────────────────────────────────────
44
+
45
+ const VOID = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'source', 'track', 'wbr']);
46
+ const TAG_RE = /<(\/)?([a-zA-Z][\w-]*)((?:\s+[^<>]*?)?)\s*(\/)?>/g;
47
+
48
+ /**
49
+ * Walks every tag in a template string and records, for each cre8-* element,
50
+ * its nearest cre8-* ancestor and the `slot="…"` attribute it carries.
51
+ * Interpolations (`${…}`) are left in place; they never contain a literal
52
+ * `<tag` in this codebase and a stray one only costs a spurious pair.
53
+ */
54
+ export function scanTemplate(text, file, containment, tagPrefix = 'cre8-', implicitParent = null) {
55
+ // A story whose args literal already places the root itself (an item
56
+ // story that renders `<cre8-radio-field><cre8-radio-field-item>…`) is
57
+ // not slotting that literal into the root; the explicit nesting wins.
58
+ if (implicitParent && new RegExp(`<${implicitParent}[\\s>]`).test(text)) implicitParent = null;
59
+ const stack = [];
60
+ let m;
61
+ TAG_RE.lastIndex = 0;
62
+ while ((m = TAG_RE.exec(text))) {
63
+ const [, closing, rawName, attrs, selfClosing] = m;
64
+ const name = rawName.toLowerCase();
65
+ if (name === 'style' || name === 'script') continue;
66
+ if (closing) {
67
+ // Pop to the matching open tag; tolerate sloppy markup in stories.
68
+ const i = stack.map((s) => s.name).lastIndexOf(name);
69
+ if (i >= 0) stack.length = i;
70
+ continue;
71
+ }
72
+ if (name.startsWith(tagPrefix)) {
73
+ const explicit = [...stack].reverse().find((s) => s.name.startsWith(tagPrefix))?.name;
74
+ // Implicit attribution never runs upward in a family: an item
75
+ // story that renders its own parent as context is not evidence
76
+ // that cre8-dropdown-item contains cre8-dropdown.
77
+ const parent = explicit ?? (implicitParent && !implicitParent.startsWith(`${name}-`) ? implicitParent : null);
78
+ if (parent && parent !== name) {
79
+ const slotMatch = /\bslot\s*=\s*["']([^"']+)["']/.exec(attrs ?? '');
80
+ note(containment, parent, slotMatch ? slotMatch[1] : null, name, file);
81
+ }
82
+ }
83
+ if (!selfClosing && !VOID.has(name)) stack.push({ name });
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Every string literal in a file that contains markup: html`…` templates,
89
+ * and the plain template/quoted strings stories keep their slotted markup
90
+ * in (`args: { default: \`<cre8-tab>…</cre8-tab>\` }`, rendered through
91
+ * unsafeHTML inside the story's root component).
92
+ */
93
+ function readMarkupLiterals(src) {
94
+ const out = [];
95
+ for (let i = 0; i < src.length; i++) {
96
+ const ch = src[i];
97
+ if (ch === '/' && src[i + 1] === '/') { i = src.indexOf('\n', i); if (i < 0) break; continue; }
98
+ if (ch === '/' && src[i + 1] === '*') { i = src.indexOf('*/', i + 2); if (i < 0) break; i += 1; continue; }
99
+ if (ch === '`') {
100
+ let depth = 0;
101
+ let j = i + 1;
102
+ for (; j < src.length; j++) {
103
+ const c = src[j];
104
+ if (c === '\\') { j++; continue; }
105
+ if (c === '`' && depth === 0) break;
106
+ if (c === '$' && src[j + 1] === '{') { depth++; j++; continue; }
107
+ if (c === '}' && depth > 0) depth--;
108
+ }
109
+ const body = src.slice(i + 1, j);
110
+ if (body.includes('<')) out.push(body);
111
+ i = j;
112
+ } else if (ch === '"' || ch === "'") {
113
+ let j = i + 1;
114
+ for (; j < src.length && src[j] !== ch && src[j] !== '\n'; j++) if (src[j] === '\\') j++;
115
+ const body = src.slice(i + 1, j);
116
+ if (body.includes('<')) out.push(body);
117
+ i = j;
118
+ }
119
+ }
120
+ return out;
121
+ }
122
+
123
+ /** The tag a stories file is about: `component: 'cre8-tabs'` in its default export. */
124
+ function storyRoot(src) {
125
+ const m = /^\s*component:\s*['"]([\w-]+)['"]/m.exec(src);
126
+ if (!m) return null;
127
+ return m[1].startsWith('cre8-') ? m[1] : `cre8-${m[1]}`;
128
+ }
129
+
130
+ export function scanComponentsDir(componentsDir, { stories, sources }) {
131
+ if (!existsSync(componentsDir)) return { storyFiles: 0, sourceFiles: 0 };
132
+ let storyFiles = 0;
133
+ let sourceFiles = 0;
134
+ for (const dir of readdirSync(componentsDir)) {
135
+ const base = join(componentsDir, dir);
136
+ const story = join(base, `${dir}.stories.ts`);
137
+ const source = join(base, `${dir}.ts`);
138
+ if (existsSync(story)) {
139
+ storyFiles++;
140
+ const rel = `components/${dir}/${dir}.stories.ts`;
141
+ const src = readFileSync(story, 'utf8');
142
+ // Markup in a story's args is rendered inside the story's root
143
+ // component, so a literal with no cre8 ancestor of its own is
144
+ // nested under that root.
145
+ const root = storyRoot(src);
146
+ for (const lit of readMarkupLiterals(src)) scanTemplate(lit, rel, stories, 'cre8-', root);
147
+ }
148
+ if (existsSync(source)) {
149
+ sourceFiles++;
150
+ const rel = `components/${dir}/${dir}.ts`;
151
+ for (const lit of readMarkupLiterals(readFileSync(source, 'utf8'))) scanTemplate(lit, rel, sources);
152
+ }
153
+ }
154
+ return { storyFiles, sourceFiles };
155
+ }
156
+
157
+ // ─── A2UI example specs ──────────────────────────────────────────────────────
158
+
159
+ function sizeOf(node) {
160
+ if (typeof node === 'string') return 1;
161
+ let total = 1;
162
+ for (const c of node.children ?? []) total += sizeOf(c);
163
+ for (const list of Object.values(node.slots ?? {})) for (const c of list) total += sizeOf(c);
164
+ return total;
165
+ }
166
+
167
+ /**
168
+ * Returns containment plus the smallest authored subtree rooted at each
169
+ * component — the exemplar get_composition hands back.
170
+ */
171
+ export function scanExamples(examplesDir) {
172
+ const containment = newContainment();
173
+ const exemplar = new Map();
174
+ if (!existsSync(examplesDir)) return { containment, exemplar, files: [] };
175
+ const files = readdirSync(examplesDir).filter((f) => f.endsWith('.json')).sort();
176
+
177
+ const visit = (node, file, path) => {
178
+ if (typeof node === 'string' || typeof node?.component !== 'string') return;
179
+ const existing = exemplar.get(node.component);
180
+ if (!existing || sizeOf(node) < existing.size) {
181
+ exemplar.set(node.component, { source: `a2ui/examples/${file}`, path, spec: node, size: sizeOf(node) });
182
+ }
183
+ (node.children ?? []).forEach((c, i) => {
184
+ if (typeof c !== 'string') note(containment, node.component, null, c.component, `a2ui/examples/${file}`);
185
+ visit(c, file, `${path}.children[${i}]`);
186
+ });
187
+ for (const [slot, list] of Object.entries(node.slots ?? {})) {
188
+ list.forEach((c, i) => {
189
+ if (typeof c !== 'string') note(containment, node.component, slot, c.component, `a2ui/examples/${file}`);
190
+ visit(c, file, `${path}.slots.${slot}[${i}]`);
191
+ });
192
+ }
193
+ };
194
+ for (const f of files) {
195
+ try { visit(JSON.parse(readFileSync(join(examplesDir, f), 'utf8')), f, '$'); } catch { /* suite's problem */ }
196
+ }
197
+ return { containment, exemplar, files };
198
+ }
199
+
200
+ // ─── graphify AST graph ──────────────────────────────────────────────────────
201
+
202
+ /**
203
+ * Class inheritance and module imports between component files, keyed by the
204
+ * component *tag* so they join the catalog. Class names map to tags by the
205
+ * library's convention (Cre8TableRow -> cre8-table-row); anything that does
206
+ * not resolve to a catalog tag is dropped rather than guessed.
207
+ */
208
+ export function scanGraphify(graphPath, knownTags) {
209
+ const out = { extends: new Map(), imports: new Map(), commit: null, found: false };
210
+ if (!existsSync(graphPath)) return out;
211
+ const g = JSON.parse(readFileSync(graphPath, 'utf8'));
212
+ out.found = true;
213
+ out.commit = g.built_at_commit ?? null;
214
+ const nodes = new Map(g.nodes.map((n) => [n.id, n]));
215
+
216
+ const classToTag = (label) => {
217
+ if (!/^Cre8[A-Z]/.test(label)) return null;
218
+ const tag = 'cre8' + label.slice(4).replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`);
219
+ return knownTags.has(tag) ? tag : null;
220
+ };
221
+ const fileToTag = (file) => {
222
+ const m = /components\/([^/]+)\/\1\.ts$/.exec(file ?? '');
223
+ const tag = m ? `cre8-${m[1]}` : null;
224
+ return tag && knownTags.has(tag) ? tag : null;
225
+ };
226
+
227
+ for (const l of g.links ?? []) {
228
+ const s = nodes.get(l.source);
229
+ const t = nodes.get(l.target);
230
+ if (!s || !t) continue;
231
+ if (l.relation === 'inherits') {
232
+ const tag = classToTag(s.label);
233
+ if (tag) out.extends.set(tag, t.label);
234
+ } else if (l.relation === 'imports_from' || l.relation === 'imports') {
235
+ const from = fileToTag(s.source_file);
236
+ const to = fileToTag(t.source_file);
237
+ if (from && to && from !== to) {
238
+ const set = out.imports.get(from) ?? new Set();
239
+ set.add(to);
240
+ out.imports.set(from, set);
241
+ }
242
+ }
243
+ }
244
+ return out;
245
+ }
246
+
247
+ // ─── pattern specs ───────────────────────────────────────────────────────────
248
+
249
+ /**
250
+ * Patterns are authored A2UI specs under a2ui/patterns/*.json:
251
+ * { name, description, spec }
252
+ * They used to be HTML strings in scripts/mcp-static-data.json that nothing
253
+ * validated and nothing else could read. As specs they validate against the
254
+ * catalog at build time, render to web or React through generate_code, and
255
+ * count as containment evidence like any other authored artifact.
256
+ */
257
+ export function scanPatterns(patternsDir) {
258
+ const containment = newContainment();
259
+ const patterns = [];
260
+ if (!existsSync(patternsDir)) return { containment, patterns };
261
+ const files = readdirSync(patternsDir).filter((f) => f.endsWith('.json')).sort();
262
+
263
+ const visit = (node, file, used) => {
264
+ if (typeof node === 'string' || typeof node?.component !== 'string') return;
265
+ used.add(node.component);
266
+ for (const c of node.children ?? []) {
267
+ if (typeof c !== 'string') note(containment, node.component, null, c.component, `a2ui/patterns/${file}`);
268
+ visit(c, file, used);
269
+ }
270
+ for (const [slot, list] of Object.entries(node.slots ?? {})) {
271
+ for (const c of list) {
272
+ if (typeof c !== 'string') note(containment, node.component, slot, c.component, `a2ui/patterns/${file}`);
273
+ visit(c, file, used);
274
+ }
275
+ }
276
+ };
277
+ for (const f of files) {
278
+ const raw = JSON.parse(readFileSync(join(patternsDir, f), 'utf8'));
279
+ const used = new Set();
280
+ visit(raw.spec, f, used);
281
+ patterns.push({
282
+ slug: f.replace(/\.json$/, ''),
283
+ name: raw.name,
284
+ description: raw.description,
285
+ source: `a2ui/patterns/${f}`,
286
+ spec: raw.spec,
287
+ components: [...used].sort(),
288
+ });
289
+ }
290
+ return { containment, patterns };
291
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "name": "Alert Banner",
3
+ "description": "Dismissible alert at top of page. The message is slots.default; a call to action goes in slots.cta.",
4
+ "spec": {
5
+ "component": "cre8-alert",
6
+ "props": {
7
+ "status": "info",
8
+ "variant": "banner"
9
+ },
10
+ "slots": {
11
+ "default": [
12
+ "Important announcement message here."
13
+ ]
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "Data Table",
3
+ "description": "Table with header and data rows. Every level is required: cells live in rows, rows in a header or body, header and body in the table. A table that skips a level renders, and is wrong.",
4
+ "spec": {
5
+ "component": "cre8-table",
6
+ "props": {
7
+ "variant": "striped",
8
+ "isHoverable": true
9
+ },
10
+ "children": [
11
+ {
12
+ "component": "cre8-table-header",
13
+ "children": [
14
+ {
15
+ "component": "cre8-table-row",
16
+ "slots": {
17
+ "default": [
18
+ {
19
+ "component": "cre8-table-header-cell",
20
+ "children": [
21
+ "Name"
22
+ ]
23
+ },
24
+ {
25
+ "component": "cre8-table-header-cell",
26
+ "children": [
27
+ "Status"
28
+ ]
29
+ }
30
+ ]
31
+ }
32
+ }
33
+ ]
34
+ },
35
+ {
36
+ "component": "cre8-table-body",
37
+ "children": [
38
+ {
39
+ "component": "cre8-table-row",
40
+ "slots": {
41
+ "default": [
42
+ {
43
+ "component": "cre8-table-cell",
44
+ "children": [
45
+ "Item 1"
46
+ ]
47
+ },
48
+ {
49
+ "component": "cre8-table-cell",
50
+ "children": [
51
+ {
52
+ "component": "cre8-badge",
53
+ "props": {
54
+ "text": "Active",
55
+ "status": "success"
56
+ }
57
+ }
58
+ ]
59
+ }
60
+ ]
61
+ }
62
+ }
63
+ ]
64
+ }
65
+ ]
66
+ }
67
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "Login Form",
3
+ "description": "Standard login form with email and password. Three things make it submit rather than merely look right: a cre8-form (or real <form>) wrapper (cre8 form components participate via ElementInternals, which is inert outside one), type=\"submit\" on the button (cre8-button defaults to type=\"button\"), and a name on every field (setFormValue contributes nothing to FormData without one). Note that required does not block submission on its own \u2014 cre8 form elements never map constraint attributes into setValidity, so enforce it with setCustomValidity() or a submit handler.",
4
+ "spec": {
5
+ "component": "cre8-form",
6
+ "children": [
7
+ {
8
+ "component": "cre8-card",
9
+ "slots": {
10
+ "default": [
11
+ {
12
+ "component": "cre8-heading",
13
+ "props": {
14
+ "tagVariant": "h2",
15
+ "type": "headline-default"
16
+ },
17
+ "children": [
18
+ "Sign In"
19
+ ]
20
+ },
21
+ {
22
+ "component": "cre8-field",
23
+ "props": {
24
+ "label": "Email",
25
+ "name": "email",
26
+ "type": "email",
27
+ "autocomplete": "email",
28
+ "required": true
29
+ }
30
+ },
31
+ {
32
+ "component": "cre8-field",
33
+ "props": {
34
+ "label": "Password",
35
+ "name": "password",
36
+ "type": "password",
37
+ "autocomplete": "current-password",
38
+ "required": true
39
+ }
40
+ },
41
+ {
42
+ "component": "cre8-button",
43
+ "props": {
44
+ "text": "Sign In",
45
+ "variant": "primary",
46
+ "fullWidth": true,
47
+ "type": "submit"
48
+ }
49
+ }
50
+ ]
51
+ }
52
+ }
53
+ ]
54
+ }
55
+ }
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "Modal Dialog",
3
+ "description": "Modal with header, body, and footer actions. These buttons are deliberately type=\"button\": they are not in a form, so they do nothing until click handlers are attached \u2014 bind events on both before shipping. If the modal instead collects input, wrap the body and footer in a cre8-form and give Confirm type=\"submit\" \u2014 see the Login Form pattern. Use ariaLabel, not aria-label: the modal renders its inner role=\"dialog\" label from the ariaLabel property, and a host aria-label attribute leaves that dialog unlabelled.",
4
+ "spec": {
5
+ "component": "cre8-modal",
6
+ "props": {
7
+ "isActive": true,
8
+ "ariaLabel": "Confirmation"
9
+ },
10
+ "slots": {
11
+ "header": [
12
+ "Confirm Action"
13
+ ],
14
+ "default": [
15
+ {
16
+ "component": "cre8-text-passage",
17
+ "children": [
18
+ "Are you sure you want to proceed?"
19
+ ]
20
+ }
21
+ ],
22
+ "footer": [
23
+ {
24
+ "component": "cre8-button-group",
25
+ "children": [
26
+ {
27
+ "component": "cre8-button",
28
+ "props": {
29
+ "text": "Cancel",
30
+ "variant": "secondary",
31
+ "type": "button"
32
+ }
33
+ },
34
+ {
35
+ "component": "cre8-button",
36
+ "props": {
37
+ "text": "Confirm",
38
+ "variant": "primary",
39
+ "type": "button"
40
+ }
41
+ }
42
+ ]
43
+ }
44
+ ]
45
+ }
46
+ }
47
+ }
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "Page Layout",
3
+ "description": "Standard page with header, main content, and footer. cre8-global-nav and cre8-footer expose no logo or copyright slot; content addressed to a slot that does not exist is never assigned and renders nowhere, so both go in the default slot.",
4
+ "spec": {
5
+ "component": "cre8-layout",
6
+ "children": [
7
+ {
8
+ "component": "cre8-header",
9
+ "slots": {
10
+ "default": [
11
+ {
12
+ "component": "cre8-logo"
13
+ },
14
+ {
15
+ "component": "cre8-global-nav",
16
+ "children": [
17
+ {
18
+ "component": "cre8-global-nav-item",
19
+ "props": {
20
+ "href": "/",
21
+ "text": "Home"
22
+ }
23
+ }
24
+ ]
25
+ }
26
+ ]
27
+ }
28
+ },
29
+ {
30
+ "component": "cre8-main",
31
+ "children": [
32
+ {
33
+ "component": "cre8-layout-container",
34
+ "children": [
35
+ {
36
+ "component": "cre8-text-passage",
37
+ "children": [
38
+ "Page content"
39
+ ]
40
+ }
41
+ ]
42
+ }
43
+ ]
44
+ },
45
+ {
46
+ "component": "cre8-footer",
47
+ "slots": {
48
+ "default": [
49
+ "2024 Company Name"
50
+ ]
51
+ }
52
+ }
53
+ ]
54
+ }
55
+ }
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "Tabbed Content",
3
+ "description": "Content organized in tabs. cre8-tab has no label, tab-id or selected prop: the label is its text content, and cre8-tabs pairs each tab with the panel at the same position and assigns index/isActive itself. Tabs go in slots.default, panels in slots.panel. Set activeIndex on cre8-tabs to choose the initial tab (defaults to 0).",
4
+ "spec": {
5
+ "component": "cre8-tabs",
6
+ "slots": {
7
+ "default": [
8
+ {
9
+ "component": "cre8-tab",
10
+ "children": [
11
+ "Tab 1"
12
+ ]
13
+ },
14
+ {
15
+ "component": "cre8-tab",
16
+ "children": [
17
+ "Tab 2"
18
+ ]
19
+ }
20
+ ],
21
+ "panel": [
22
+ {
23
+ "component": "cre8-tab-panel",
24
+ "children": [
25
+ "Content for Tab 1"
26
+ ]
27
+ },
28
+ {
29
+ "component": "cre8-tab-panel",
30
+ "children": [
31
+ "Content for Tab 2"
32
+ ]
33
+ }
34
+ ]
35
+ }
36
+ }
37
+ }
@@ -1,3 +1,3 @@
1
- import{u as r,j as t,M as s}from"./blocks-C_CCjW0W.js";import"./preload-helper-PPVm8Dsz.js";import"./_commonjsHelpers-DaWZu8wl.js";import"./iframe-Xcrj_hym.js";import"./chunk-EUVGDK4H-rHCQfRxh.js";function o(n){const e={h1:"h1",p:"p",...r(),...n.components};return t.jsxs(t.Fragment,{children:[t.jsx(s,{title:"Documentation/Changelog"}),`
1
+ import{u as r,j as t,M as s}from"./blocks-F7P3fIJh.js";import"./preload-helper-PPVm8Dsz.js";import"./_commonjsHelpers-DaWZu8wl.js";import"./iframe-DNXIQNo5.js";import"./chunk-EUVGDK4H-rHCQfRxh.js";function o(n){const e={h1:"h1",p:"p",...r(),...n.components};return t.jsxs(t.Fragment,{children:[t.jsx(s,{title:"Documentation/Changelog"}),`
2
2
  `,t.jsx(e.h1,{id:"changelog",children:"Changelog"}),`
3
3
  `,t.jsx(e.p,{children:"Please check the CHANGELOG.md file in the project root for version history and updates."})]})}function p(n={}){const{wrapper:e}={...r(),...n.components};return e?t.jsx(e,{...n,children:t.jsx(o,{...n})}):o(n)}export{p as default};
@@ -1,3 +1,3 @@
1
- import{u as s,j as e,M as i}from"./blocks-C_CCjW0W.js";import"./preload-helper-PPVm8Dsz.js";import"./_commonjsHelpers-DaWZu8wl.js";import"./iframe-Xcrj_hym.js";import"./chunk-EUVGDK4H-rHCQfRxh.js";function o(n){const t={h1:"h1",p:"p",...s(),...n.components};return e.jsxs(e.Fragment,{children:[e.jsx(i,{title:"Documentation/Code Guidelines"}),`
1
+ import{u as s,j as e,M as i}from"./blocks-F7P3fIJh.js";import"./preload-helper-PPVm8Dsz.js";import"./_commonjsHelpers-DaWZu8wl.js";import"./iframe-DNXIQNo5.js";import"./chunk-EUVGDK4H-rHCQfRxh.js";function o(n){const t={h1:"h1",p:"p",...s(),...n.components};return e.jsxs(e.Fragment,{children:[e.jsx(i,{title:"Documentation/Code Guidelines"}),`
2
2
  `,e.jsx(t.h1,{id:"code-guidelines",children:"Code Guidelines"}),`
3
3
  `,e.jsx(t.p,{children:"Please check the docs/CODE_GUIDELINES.md file for coding standards and best practices."})]})}function u(n={}){const{wrapper:t}={...s(),...n.components};return t?e.jsx(t,{...n,children:e.jsx(o,{...n})}):o(n)}export{u as default};