@aleph-alpha/lib-mcp 1.6.0 → 1.7.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/components-meta.json +175 -56
- package/dist/cli.js +170 -10
- package/dist/server.js +170 -10
- package/package.json +2 -2
package/components-meta.json
CHANGED
|
@@ -62,30 +62,19 @@
|
|
|
62
62
|
"_autoGenerated": true
|
|
63
63
|
},
|
|
64
64
|
"UiAlertDialog": {
|
|
65
|
-
"description": "
|
|
66
|
-
"category": "
|
|
67
|
-
"useCases": [
|
|
68
|
-
"confirm delete",
|
|
69
|
-
"destructive action",
|
|
70
|
-
"important confirmation",
|
|
71
|
-
"warning"
|
|
72
|
-
],
|
|
65
|
+
"description": "Root alert dialog. Uses core **`Dialog`** (`components/core/dialog/Dialog.vue` → **`DialogRoot`**) with **`modal: true`** Root uses core **`Dialog`** with modal enabled. Subcomponents use **`UiAlertDialog*`** / alert **`DialogContent`** for **`alertdialog`** semantics. Use **`v-model:model`** for controlled mode (unlike **`UiDialog`**, which uses **`v-model:open`**).",
|
|
66
|
+
"category": "Uncategorized",
|
|
67
|
+
"useCases": [],
|
|
73
68
|
"keywords": [
|
|
74
69
|
"alert",
|
|
75
|
-
"dialog"
|
|
76
|
-
"modal",
|
|
77
|
-
"confirm",
|
|
78
|
-
"warning",
|
|
79
|
-
"destructive",
|
|
80
|
-
"popup"
|
|
81
|
-
],
|
|
82
|
-
"related": [
|
|
83
|
-
"UiPopover"
|
|
70
|
+
"dialog"
|
|
84
71
|
],
|
|
72
|
+
"related": [],
|
|
85
73
|
"props": [],
|
|
86
74
|
"examples": [
|
|
87
75
|
"Default",
|
|
88
|
-
"Simple"
|
|
76
|
+
"Simple",
|
|
77
|
+
"FullWidthContent"
|
|
89
78
|
],
|
|
90
79
|
"_autoGenerated": true
|
|
91
80
|
},
|
|
@@ -427,6 +416,38 @@
|
|
|
427
416
|
],
|
|
428
417
|
"_autoGenerated": true
|
|
429
418
|
},
|
|
419
|
+
"UiDialog": {
|
|
420
|
+
"description": "A modal dialog for focused tasks and content. Description and `#actions` are optional.",
|
|
421
|
+
"category": "Overlays",
|
|
422
|
+
"useCases": [
|
|
423
|
+
"forms",
|
|
424
|
+
"details",
|
|
425
|
+
"multi-step flows",
|
|
426
|
+
"rich content"
|
|
427
|
+
],
|
|
428
|
+
"keywords": [
|
|
429
|
+
"dialog",
|
|
430
|
+
"modal",
|
|
431
|
+
"overlay",
|
|
432
|
+
"popup"
|
|
433
|
+
],
|
|
434
|
+
"related": [
|
|
435
|
+
"UiAlertDialog",
|
|
436
|
+
"UiSheet",
|
|
437
|
+
"UiDrawer"
|
|
438
|
+
],
|
|
439
|
+
"props": [],
|
|
440
|
+
"examples": [
|
|
441
|
+
"Default",
|
|
442
|
+
"Content",
|
|
443
|
+
"WithActionsSlot",
|
|
444
|
+
"TitleOnly",
|
|
445
|
+
"WithMaxWidth",
|
|
446
|
+
"CustomHeaderSlot",
|
|
447
|
+
"WithForm"
|
|
448
|
+
],
|
|
449
|
+
"_autoGenerated": true
|
|
450
|
+
},
|
|
430
451
|
"UiDrawer": {
|
|
431
452
|
"description": "A slide-out panel that appears from the edge of the screen. Use for secondary content, navigation menus, or forms that don't require full-page context.",
|
|
432
453
|
"category": "Overlays",
|
|
@@ -592,6 +613,82 @@
|
|
|
592
613
|
],
|
|
593
614
|
"_autoGenerated": true
|
|
594
615
|
},
|
|
616
|
+
"UiFileItem": {
|
|
617
|
+
"description": "Row showing a selected or uploading file with optional progress and errors.",
|
|
618
|
+
"category": "Form Inputs",
|
|
619
|
+
"useCases": [
|
|
620
|
+
"file upload list",
|
|
621
|
+
"attachment row"
|
|
622
|
+
],
|
|
623
|
+
"keywords": [
|
|
624
|
+
"file",
|
|
625
|
+
"upload",
|
|
626
|
+
"attachment",
|
|
627
|
+
"progress",
|
|
628
|
+
"item"
|
|
629
|
+
],
|
|
630
|
+
"related": [
|
|
631
|
+
"UiFileUploadBox",
|
|
632
|
+
"UiItem",
|
|
633
|
+
"UiButton"
|
|
634
|
+
],
|
|
635
|
+
"props": [
|
|
636
|
+
"filename",
|
|
637
|
+
"typeLabel",
|
|
638
|
+
"sizeLabel",
|
|
639
|
+
"progress",
|
|
640
|
+
"error",
|
|
641
|
+
"removeLabel",
|
|
642
|
+
"disabled"
|
|
643
|
+
],
|
|
644
|
+
"examples": [
|
|
645
|
+
"Default",
|
|
646
|
+
"WithProgress",
|
|
647
|
+
"Complete",
|
|
648
|
+
"WithError",
|
|
649
|
+
"Disabled",
|
|
650
|
+
"DisabledWithError",
|
|
651
|
+
"ProgressAndError",
|
|
652
|
+
"FilenameOnly",
|
|
653
|
+
"AllStates"
|
|
654
|
+
],
|
|
655
|
+
"_autoGenerated": true
|
|
656
|
+
},
|
|
657
|
+
"UiFileUploadBox": {
|
|
658
|
+
"description": "Drop zone + file picker for selecting files with optional type/size validation. **Emits:** see {@link UiFileUploadBoxEmits}.",
|
|
659
|
+
"category": "Components",
|
|
660
|
+
"useCases": [
|
|
661
|
+
"file upload area",
|
|
662
|
+
"drag and drop attachments"
|
|
663
|
+
],
|
|
664
|
+
"keywords": [
|
|
665
|
+
"file",
|
|
666
|
+
"upload",
|
|
667
|
+
"drag",
|
|
668
|
+
"drop",
|
|
669
|
+
"attachment",
|
|
670
|
+
"box"
|
|
671
|
+
],
|
|
672
|
+
"related": [
|
|
673
|
+
"UiFileItem",
|
|
674
|
+
"UiButton"
|
|
675
|
+
],
|
|
676
|
+
"props": [
|
|
677
|
+
"accept",
|
|
678
|
+
"multiple",
|
|
679
|
+
"maxFileSizeBytes",
|
|
680
|
+
"disabled",
|
|
681
|
+
"supportedTypesLabel",
|
|
682
|
+
"maxSizeLabel",
|
|
683
|
+
"dropLabel",
|
|
684
|
+
"chooseLabel",
|
|
685
|
+
"ariaLabel"
|
|
686
|
+
],
|
|
687
|
+
"examples": [
|
|
688
|
+
"Default"
|
|
689
|
+
],
|
|
690
|
+
"_autoGenerated": true
|
|
691
|
+
},
|
|
595
692
|
"UiIcon": {
|
|
596
693
|
"description": "An icon component using Lucide icons. Use for visual indicators, button decorations, or standalone meaningful graphics.",
|
|
597
694
|
"category": "Data Display",
|
|
@@ -741,7 +838,8 @@
|
|
|
741
838
|
"props": [
|
|
742
839
|
"variant",
|
|
743
840
|
"size",
|
|
744
|
-
"asChild"
|
|
841
|
+
"asChild",
|
|
842
|
+
"withListSemantics"
|
|
745
843
|
],
|
|
746
844
|
"examples": [
|
|
747
845
|
"Basic",
|
|
@@ -1167,43 +1265,6 @@
|
|
|
1167
1265
|
],
|
|
1168
1266
|
"_autoGenerated": true
|
|
1169
1267
|
},
|
|
1170
|
-
"UiSidebar": {
|
|
1171
|
-
"description": "A collapsible sidebar navigation component for application layouts. Use for primary navigation, page hierarchy, and secondary actions in dashboard-style applications.",
|
|
1172
|
-
"category": "Layout",
|
|
1173
|
-
"useCases": [
|
|
1174
|
-
"navigation",
|
|
1175
|
-
"dashboard layout",
|
|
1176
|
-
"app shell",
|
|
1177
|
-
"admin panel",
|
|
1178
|
-
"settings menu"
|
|
1179
|
-
],
|
|
1180
|
-
"keywords": [
|
|
1181
|
-
"sidebar",
|
|
1182
|
-
"navigation",
|
|
1183
|
-
"menu",
|
|
1184
|
-
"drawer",
|
|
1185
|
-
"collapsible",
|
|
1186
|
-
"layout"
|
|
1187
|
-
],
|
|
1188
|
-
"related": [
|
|
1189
|
-
"UiDrawer",
|
|
1190
|
-
"UiSheet"
|
|
1191
|
-
],
|
|
1192
|
-
"props": [
|
|
1193
|
-
"side",
|
|
1194
|
-
"variant",
|
|
1195
|
-
"collapsible"
|
|
1196
|
-
],
|
|
1197
|
-
"examples": [
|
|
1198
|
-
"Default",
|
|
1199
|
-
"WithSearch",
|
|
1200
|
-
"WithActions",
|
|
1201
|
-
"WithSubmenu",
|
|
1202
|
-
"WithSkeleton",
|
|
1203
|
-
"ProgrammaticControl"
|
|
1204
|
-
],
|
|
1205
|
-
"_autoGenerated": true
|
|
1206
|
-
},
|
|
1207
1268
|
"UiSkeleton": {
|
|
1208
1269
|
"description": "A placeholder loading state for content. Use to indicate loading state while preserving layout structure.",
|
|
1209
1270
|
"category": "Feedback",
|
|
@@ -1739,6 +1800,41 @@
|
|
|
1739
1800
|
],
|
|
1740
1801
|
"_autoGenerated": true
|
|
1741
1802
|
},
|
|
1803
|
+
"UiFileUpload": {
|
|
1804
|
+
"description": "Composition-friendly file upload (same API as {@link UiFileUploadBoxProps}). Implementation delegates to {@link UiFileUploadBox}.",
|
|
1805
|
+
"category": "Patterns",
|
|
1806
|
+
"useCases": [
|
|
1807
|
+
"file upload dialog",
|
|
1808
|
+
"drag and drop attachments"
|
|
1809
|
+
],
|
|
1810
|
+
"keywords": [
|
|
1811
|
+
"file",
|
|
1812
|
+
"upload",
|
|
1813
|
+
"drag",
|
|
1814
|
+
"drop",
|
|
1815
|
+
"attachment"
|
|
1816
|
+
],
|
|
1817
|
+
"related": [
|
|
1818
|
+
"UiFileItem",
|
|
1819
|
+
"UiDialog",
|
|
1820
|
+
"UiFileUploadBox"
|
|
1821
|
+
],
|
|
1822
|
+
"props": [],
|
|
1823
|
+
"examples": [
|
|
1824
|
+
"Default",
|
|
1825
|
+
"WithMockUploadProgress",
|
|
1826
|
+
"AcceptPdfDocxTxt",
|
|
1827
|
+
"AcceptImages",
|
|
1828
|
+
"AcceptSpreadsheet",
|
|
1829
|
+
"SingleFile",
|
|
1830
|
+
"MaxSize1Mb",
|
|
1831
|
+
"CustomMaxSizeLabel",
|
|
1832
|
+
"AnyTypeNoFooter",
|
|
1833
|
+
"Disabled",
|
|
1834
|
+
"CustomLabels"
|
|
1835
|
+
],
|
|
1836
|
+
"_autoGenerated": true
|
|
1837
|
+
},
|
|
1742
1838
|
"UiPlaceholder": {
|
|
1743
1839
|
"description": "Placeholder for foundation components (internal development use).",
|
|
1744
1840
|
"category": "Foundations",
|
|
@@ -1755,6 +1851,29 @@
|
|
|
1755
1851
|
"examples": [],
|
|
1756
1852
|
"_autoGenerated": true
|
|
1757
1853
|
},
|
|
1854
|
+
"UiSidebar": {
|
|
1855
|
+
"description": "Pattern wrapper props for the application sidebar shell. Same API as the underlying core `Sidebar` component.",
|
|
1856
|
+
"category": "Patterns",
|
|
1857
|
+
"useCases": [
|
|
1858
|
+
"app navigation",
|
|
1859
|
+
"dashboard sidebar",
|
|
1860
|
+
"collapsible layout"
|
|
1861
|
+
],
|
|
1862
|
+
"keywords": [
|
|
1863
|
+
"sidebar",
|
|
1864
|
+
"navigation",
|
|
1865
|
+
"layout",
|
|
1866
|
+
"shell"
|
|
1867
|
+
],
|
|
1868
|
+
"related": [],
|
|
1869
|
+
"props": [],
|
|
1870
|
+
"examples": [
|
|
1871
|
+
"Default",
|
|
1872
|
+
"Inset",
|
|
1873
|
+
"RightSide"
|
|
1874
|
+
],
|
|
1875
|
+
"_autoGenerated": true
|
|
1876
|
+
},
|
|
1758
1877
|
"UiTemplatePlaceholder": {
|
|
1759
1878
|
"description": "Placeholder for template components (internal development use).",
|
|
1760
1879
|
"category": "Templates",
|
package/dist/cli.js
CHANGED
|
@@ -21129,6 +21129,7 @@ import * as path5 from "node:path";
|
|
|
21129
21129
|
|
|
21130
21130
|
// src/readers/types-reader.ts
|
|
21131
21131
|
import * as path2 from "node:path";
|
|
21132
|
+
var TYPE_OR_INTERFACE = "(?:interface|type)";
|
|
21132
21133
|
function parseJSDoc(comment) {
|
|
21133
21134
|
const lines = comment.replace(/\/\*\*|\*\/|\*/g, "").split("\n").map((line) => line.trim()).filter(Boolean);
|
|
21134
21135
|
let description = "";
|
|
@@ -21169,7 +21170,7 @@ function extractType(text2, startIndex) {
|
|
|
21169
21170
|
function parseInterface(content, interfaceName) {
|
|
21170
21171
|
const props = [];
|
|
21171
21172
|
const interfaceRegex = new RegExp(
|
|
21172
|
-
`export\\s+
|
|
21173
|
+
`(?:export\\s+)?${TYPE_OR_INTERFACE}\\s+${interfaceName}\\s*(?:extends\\s+[^{]+)?(?:=\\s*)?\\{([\\s\\S]*?)\\n\\}`,
|
|
21173
21174
|
"m"
|
|
21174
21175
|
);
|
|
21175
21176
|
const match = content.match(interfaceRegex);
|
|
@@ -21201,7 +21202,7 @@ function parseInterface(content, interfaceName) {
|
|
|
21201
21202
|
function extractComponentDescription(content, interfaceName) {
|
|
21202
21203
|
const lines = content.split("\n");
|
|
21203
21204
|
const interfaceLineIndex = lines.findIndex(
|
|
21204
|
-
(line) => line.match(new RegExp(`export\\s
|
|
21205
|
+
(line) => line.match(new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+${interfaceName}`))
|
|
21205
21206
|
);
|
|
21206
21207
|
if (interfaceLineIndex === -1) {
|
|
21207
21208
|
return "";
|
|
@@ -21226,28 +21227,67 @@ function extractComponentDescription(content, interfaceName) {
|
|
|
21226
21227
|
}
|
|
21227
21228
|
return "";
|
|
21228
21229
|
}
|
|
21229
|
-
function
|
|
21230
|
+
function resolveUnionOrIntersectionProps(content, typeName) {
|
|
21231
|
+
const typeDefRegex = new RegExp(`export\\s+type\\s+${typeName}\\s*=\\s*([^;]+)`);
|
|
21232
|
+
const match = content.match(typeDefRegex);
|
|
21233
|
+
if (!match) return [];
|
|
21234
|
+
const referencedTypes = match[1].split(/[|&]/).map((t) => t.trim()).filter((t) => t.endsWith("Props"));
|
|
21235
|
+
if (referencedTypes.length === 0) return [];
|
|
21236
|
+
const firstBranch = referencedTypes[0];
|
|
21237
|
+
const extendsRegex = new RegExp(
|
|
21238
|
+
`(?:export\\s+)?${TYPE_OR_INTERFACE}\\s+${firstBranch}\\s+extends\\s+(\\w+)`
|
|
21239
|
+
);
|
|
21240
|
+
const extendsMatch = content.match(extendsRegex);
|
|
21241
|
+
const allProps = [];
|
|
21242
|
+
if (extendsMatch) {
|
|
21243
|
+
allProps.push(...parseInterface(content, extendsMatch[1]));
|
|
21244
|
+
}
|
|
21245
|
+
allProps.push(...parseInterface(content, firstBranch));
|
|
21246
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21247
|
+
return allProps.filter((p) => {
|
|
21248
|
+
if (seen.has(p.name)) return false;
|
|
21249
|
+
seen.add(p.name);
|
|
21250
|
+
return true;
|
|
21251
|
+
});
|
|
21252
|
+
}
|
|
21253
|
+
function readTypesFile(filePath, componentName) {
|
|
21230
21254
|
const content = readTextFile(filePath);
|
|
21231
21255
|
if (!content) {
|
|
21232
21256
|
return null;
|
|
21233
21257
|
}
|
|
21234
|
-
const
|
|
21258
|
+
const resolvedName = componentName || path2.basename(path2.dirname(filePath));
|
|
21259
|
+
const exactRegex = new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+(${resolvedName}Props)\\b`);
|
|
21260
|
+
let propsInterfaceMatch = content.match(exactRegex);
|
|
21261
|
+
if (!propsInterfaceMatch) {
|
|
21262
|
+
const prefixRegex = new RegExp(
|
|
21263
|
+
`export\\s+${TYPE_OR_INTERFACE}\\s+(${resolvedName}\\w*Props)\\b`
|
|
21264
|
+
);
|
|
21265
|
+
propsInterfaceMatch = content.match(prefixRegex);
|
|
21266
|
+
}
|
|
21267
|
+
if (!propsInterfaceMatch) {
|
|
21268
|
+
propsInterfaceMatch = content.match(
|
|
21269
|
+
new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+(Ui\\w+Props)\\b`)
|
|
21270
|
+
);
|
|
21271
|
+
}
|
|
21235
21272
|
if (!propsInterfaceMatch) {
|
|
21236
21273
|
return null;
|
|
21237
21274
|
}
|
|
21238
21275
|
const interfaceName = propsInterfaceMatch[1];
|
|
21239
|
-
const
|
|
21276
|
+
const matchedComponentName = interfaceName.replace("Props", "");
|
|
21240
21277
|
const description = extractComponentDescription(content, interfaceName);
|
|
21241
|
-
|
|
21278
|
+
let props = parseInterface(content, interfaceName);
|
|
21279
|
+
if (props.length === 0) {
|
|
21280
|
+
props = resolveUnionOrIntersectionProps(content, interfaceName);
|
|
21281
|
+
}
|
|
21242
21282
|
return {
|
|
21243
|
-
name:
|
|
21283
|
+
name: matchedComponentName,
|
|
21244
21284
|
description,
|
|
21245
21285
|
props
|
|
21246
21286
|
};
|
|
21247
21287
|
}
|
|
21248
21288
|
function readComponentTypes(componentDir) {
|
|
21249
21289
|
const typesPath = path2.join(componentDir, "types.ts");
|
|
21250
|
-
return readTypesFile(typesPath);
|
|
21290
|
+
return readTypesFile(typesPath, path2.basename(componentDir));
|
|
21251
21291
|
}
|
|
21252
21292
|
|
|
21253
21293
|
// src/constants.ts
|
|
@@ -21460,6 +21500,40 @@ function extractStories(content) {
|
|
|
21460
21500
|
}
|
|
21461
21501
|
return stories;
|
|
21462
21502
|
}
|
|
21503
|
+
function extractInlineRenderTemplates(content) {
|
|
21504
|
+
const examples = [];
|
|
21505
|
+
const storyExportRegex = /export\s+const\s+(\w+):\s*Story\s*=/g;
|
|
21506
|
+
let match;
|
|
21507
|
+
while ((match = storyExportRegex.exec(content)) !== null) {
|
|
21508
|
+
const storyName = match[1];
|
|
21509
|
+
if (storyName === "default") continue;
|
|
21510
|
+
const afterEquals = content.indexOf("{", match.index + match[0].length);
|
|
21511
|
+
if (afterEquals === -1) continue;
|
|
21512
|
+
const closingBrace = findMatchingBrace(content, afterEquals);
|
|
21513
|
+
if (closingBrace === -1) continue;
|
|
21514
|
+
const storyBlock = content.slice(afterEquals, closingBrace + 1);
|
|
21515
|
+
if (!storyBlock.includes("template:")) continue;
|
|
21516
|
+
const templateMatch = storyBlock.match(/template:\s*`([\s\S]*?)`/);
|
|
21517
|
+
if (!templateMatch) continue;
|
|
21518
|
+
const template = templateMatch[1].trim();
|
|
21519
|
+
if (!template) continue;
|
|
21520
|
+
const componentsMatch = storyBlock.match(/components:\s*\{([^}]+)\}/);
|
|
21521
|
+
const componentNames = componentsMatch ? componentsMatch[1].split(",").map((c) => c.trim()).filter(Boolean) : [];
|
|
21522
|
+
const imports = componentNames.length > 0 ? `<script setup>
|
|
21523
|
+
// Components: ${componentNames.join(", ")}
|
|
21524
|
+
</script>
|
|
21525
|
+
|
|
21526
|
+
` : "";
|
|
21527
|
+
examples.push({
|
|
21528
|
+
name: storyName,
|
|
21529
|
+
description: "",
|
|
21530
|
+
code: `${imports}<template>
|
|
21531
|
+
${template}
|
|
21532
|
+
</template>`
|
|
21533
|
+
});
|
|
21534
|
+
}
|
|
21535
|
+
return examples;
|
|
21536
|
+
}
|
|
21463
21537
|
function extractArgTypes(content) {
|
|
21464
21538
|
const argTypes = [];
|
|
21465
21539
|
const argTypesKeyIndex = content.indexOf("argTypes");
|
|
@@ -21516,6 +21590,56 @@ function extractTitle(content) {
|
|
|
21516
21590
|
const titleMatch = content.match(/title:\s*['"]([^'"]+)['"]/);
|
|
21517
21591
|
return titleMatch ? titleMatch[1] : "";
|
|
21518
21592
|
}
|
|
21593
|
+
function extractMetaArgs(content) {
|
|
21594
|
+
const metaDefaultIndex = content.indexOf("export default");
|
|
21595
|
+
if (metaDefaultIndex === -1) return void 0;
|
|
21596
|
+
const metaSection = content.slice(0, metaDefaultIndex);
|
|
21597
|
+
const argsKeyIndex = metaSection.lastIndexOf("args:");
|
|
21598
|
+
if (argsKeyIndex !== -1) {
|
|
21599
|
+
return extractArgsFromPosition(content, argsKeyIndex);
|
|
21600
|
+
}
|
|
21601
|
+
const afterExport = content.slice(metaDefaultIndex + "export default".length);
|
|
21602
|
+
const trimmed = afterExport.trimStart();
|
|
21603
|
+
if (!trimmed.startsWith("{")) return void 0;
|
|
21604
|
+
const blockStart = content.indexOf("{", metaDefaultIndex);
|
|
21605
|
+
const blockEnd = findMatchingBrace(content, blockStart);
|
|
21606
|
+
if (blockEnd === -1) return void 0;
|
|
21607
|
+
const metaBlock = content.slice(blockStart + 1, blockEnd);
|
|
21608
|
+
const inlineArgsIndex = metaBlock.indexOf("args:");
|
|
21609
|
+
if (inlineArgsIndex === -1) return void 0;
|
|
21610
|
+
return extractArgsFromPosition(content, blockStart + 1 + inlineArgsIndex);
|
|
21611
|
+
}
|
|
21612
|
+
function extractArgsFromPosition(content, argsKeyIndex) {
|
|
21613
|
+
const colonIndex = content.indexOf(":", argsKeyIndex + 4);
|
|
21614
|
+
if (colonIndex === -1) {
|
|
21615
|
+
return void 0;
|
|
21616
|
+
}
|
|
21617
|
+
const openingBraceIndex = content.indexOf("{", colonIndex);
|
|
21618
|
+
if (openingBraceIndex === -1) {
|
|
21619
|
+
return void 0;
|
|
21620
|
+
}
|
|
21621
|
+
const closingBraceIndex = findMatchingBrace(content, openingBraceIndex);
|
|
21622
|
+
if (closingBraceIndex === -1) {
|
|
21623
|
+
return void 0;
|
|
21624
|
+
}
|
|
21625
|
+
const argsBlock = content.slice(openingBraceIndex + 1, closingBraceIndex);
|
|
21626
|
+
const args = {};
|
|
21627
|
+
const kvRegex = /(\w+)\s*:\s*(?:'([^']*)'|"([^"]*)"|(\d+(?:\.\d+)?)|(\btrue\b|\bfalse\b))/g;
|
|
21628
|
+
let match;
|
|
21629
|
+
while ((match = kvRegex.exec(argsBlock)) !== null) {
|
|
21630
|
+
const key = match[1];
|
|
21631
|
+
if (match[2] !== void 0) {
|
|
21632
|
+
args[key] = match[2];
|
|
21633
|
+
} else if (match[3] !== void 0) {
|
|
21634
|
+
args[key] = match[3];
|
|
21635
|
+
} else if (match[4] !== void 0) {
|
|
21636
|
+
args[key] = Number(match[4]);
|
|
21637
|
+
} else if (match[5] !== void 0) {
|
|
21638
|
+
args[key] = match[5] === "true";
|
|
21639
|
+
}
|
|
21640
|
+
}
|
|
21641
|
+
return Object.keys(args).length > 0 ? args : void 0;
|
|
21642
|
+
}
|
|
21519
21643
|
function readStoriesFile(filePath) {
|
|
21520
21644
|
const content = readTextFile(filePath);
|
|
21521
21645
|
if (!content) {
|
|
@@ -21527,6 +21651,7 @@ function readStoriesFile(filePath) {
|
|
|
21527
21651
|
const storyTemplateMap = extractStories(content);
|
|
21528
21652
|
const examples = [];
|
|
21529
21653
|
const usageGuidance = [];
|
|
21654
|
+
const coveredStories = /* @__PURE__ */ new Set();
|
|
21530
21655
|
for (const [storyName, templateVar] of storyTemplateMap) {
|
|
21531
21656
|
const code = templateSources.get(templateVar);
|
|
21532
21657
|
const description = extractStoryJSDoc(content, storyName);
|
|
@@ -21536,16 +21661,29 @@ function readStoriesFile(filePath) {
|
|
|
21536
21661
|
description,
|
|
21537
21662
|
code
|
|
21538
21663
|
});
|
|
21664
|
+
coveredStories.add(storyName);
|
|
21539
21665
|
}
|
|
21540
21666
|
if (description) {
|
|
21541
21667
|
usageGuidance.push(description);
|
|
21542
21668
|
}
|
|
21543
21669
|
}
|
|
21670
|
+
const inlineExamples = extractInlineRenderTemplates(content);
|
|
21671
|
+
for (const example of inlineExamples) {
|
|
21672
|
+
if (!coveredStories.has(example.name)) {
|
|
21673
|
+
const description = extractStoryJSDoc(content, example.name);
|
|
21674
|
+
examples.push({ ...example, description });
|
|
21675
|
+
if (description) {
|
|
21676
|
+
usageGuidance.push(description);
|
|
21677
|
+
}
|
|
21678
|
+
}
|
|
21679
|
+
}
|
|
21680
|
+
const defaultArgs = extractMetaArgs(content);
|
|
21544
21681
|
return {
|
|
21545
21682
|
title,
|
|
21546
21683
|
examples,
|
|
21547
21684
|
argTypes,
|
|
21548
|
-
usageGuidance
|
|
21685
|
+
usageGuidance,
|
|
21686
|
+
defaultArgs
|
|
21549
21687
|
};
|
|
21550
21688
|
}
|
|
21551
21689
|
function readComponentStories(componentDir) {
|
|
@@ -21619,7 +21757,8 @@ function getComponentDocs(componentName) {
|
|
|
21619
21757
|
examples,
|
|
21620
21758
|
usageGuidance: [...new Set(usageGuidance)],
|
|
21621
21759
|
// Remove duplicates
|
|
21622
|
-
subComponents: subComponents && subComponents.length > 0 ? subComponents : void 0
|
|
21760
|
+
subComponents: subComponents && subComponents.length > 0 ? subComponents : void 0,
|
|
21761
|
+
defaultArgs: storiesInfo?.defaultArgs
|
|
21623
21762
|
};
|
|
21624
21763
|
}
|
|
21625
21764
|
|
|
@@ -21665,6 +21804,27 @@ function formatComponentDocs(docs) {
|
|
|
21665
21804
|
sections.push("## Props", "");
|
|
21666
21805
|
docs.props.forEach((prop) => sections.push(...formatProp(prop)));
|
|
21667
21806
|
}
|
|
21807
|
+
if (docs.defaultArgs && Object.keys(docs.defaultArgs).length > 0) {
|
|
21808
|
+
const filteredArgs = Object.entries(docs.defaultArgs).filter(([key, value]) => {
|
|
21809
|
+
const prop = docs.props.find((p) => p.name === key);
|
|
21810
|
+
if (!prop?.default) return true;
|
|
21811
|
+
return String(value) !== prop.default;
|
|
21812
|
+
});
|
|
21813
|
+
if (filteredArgs.length > 0) {
|
|
21814
|
+
sections.push("## Storybook Defaults", "");
|
|
21815
|
+
sections.push(
|
|
21816
|
+
"These are the recommended prop values used in the component's Storybook stories:",
|
|
21817
|
+
""
|
|
21818
|
+
);
|
|
21819
|
+
sections.push("| Prop | Value |");
|
|
21820
|
+
sections.push("|------|-------|");
|
|
21821
|
+
for (const [key, value] of filteredArgs) {
|
|
21822
|
+
const formatted = typeof value === "string" ? `"${value}"` : String(value);
|
|
21823
|
+
sections.push(`| \`${key}\` | \`${formatted}\` |`);
|
|
21824
|
+
}
|
|
21825
|
+
sections.push("");
|
|
21826
|
+
}
|
|
21827
|
+
}
|
|
21668
21828
|
if (docs.subComponents && docs.subComponents.length > 0) {
|
|
21669
21829
|
sections.push("## Sub-components", "");
|
|
21670
21830
|
docs.subComponents.forEach((name) => sections.push(`- \`${name}\``));
|
package/dist/server.js
CHANGED
|
@@ -21033,6 +21033,7 @@ function findMatchingBrace(text2, openingBraceIndex, openChar = "{", closeChar =
|
|
|
21033
21033
|
}
|
|
21034
21034
|
|
|
21035
21035
|
// src/readers/types-reader.ts
|
|
21036
|
+
var TYPE_OR_INTERFACE = "(?:interface|type)";
|
|
21036
21037
|
function parseJSDoc(comment) {
|
|
21037
21038
|
const lines = comment.replace(/\/\*\*|\*\/|\*/g, "").split("\n").map((line) => line.trim()).filter(Boolean);
|
|
21038
21039
|
let description = "";
|
|
@@ -21073,7 +21074,7 @@ function extractType(text2, startIndex) {
|
|
|
21073
21074
|
function parseInterface(content, interfaceName) {
|
|
21074
21075
|
const props = [];
|
|
21075
21076
|
const interfaceRegex = new RegExp(
|
|
21076
|
-
`export\\s+
|
|
21077
|
+
`(?:export\\s+)?${TYPE_OR_INTERFACE}\\s+${interfaceName}\\s*(?:extends\\s+[^{]+)?(?:=\\s*)?\\{([\\s\\S]*?)\\n\\}`,
|
|
21077
21078
|
"m"
|
|
21078
21079
|
);
|
|
21079
21080
|
const match = content.match(interfaceRegex);
|
|
@@ -21105,7 +21106,7 @@ function parseInterface(content, interfaceName) {
|
|
|
21105
21106
|
function extractComponentDescription(content, interfaceName) {
|
|
21106
21107
|
const lines = content.split("\n");
|
|
21107
21108
|
const interfaceLineIndex = lines.findIndex(
|
|
21108
|
-
(line) => line.match(new RegExp(`export\\s
|
|
21109
|
+
(line) => line.match(new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+${interfaceName}`))
|
|
21109
21110
|
);
|
|
21110
21111
|
if (interfaceLineIndex === -1) {
|
|
21111
21112
|
return "";
|
|
@@ -21130,28 +21131,67 @@ function extractComponentDescription(content, interfaceName) {
|
|
|
21130
21131
|
}
|
|
21131
21132
|
return "";
|
|
21132
21133
|
}
|
|
21133
|
-
function
|
|
21134
|
+
function resolveUnionOrIntersectionProps(content, typeName) {
|
|
21135
|
+
const typeDefRegex = new RegExp(`export\\s+type\\s+${typeName}\\s*=\\s*([^;]+)`);
|
|
21136
|
+
const match = content.match(typeDefRegex);
|
|
21137
|
+
if (!match) return [];
|
|
21138
|
+
const referencedTypes = match[1].split(/[|&]/).map((t) => t.trim()).filter((t) => t.endsWith("Props"));
|
|
21139
|
+
if (referencedTypes.length === 0) return [];
|
|
21140
|
+
const firstBranch = referencedTypes[0];
|
|
21141
|
+
const extendsRegex = new RegExp(
|
|
21142
|
+
`(?:export\\s+)?${TYPE_OR_INTERFACE}\\s+${firstBranch}\\s+extends\\s+(\\w+)`
|
|
21143
|
+
);
|
|
21144
|
+
const extendsMatch = content.match(extendsRegex);
|
|
21145
|
+
const allProps = [];
|
|
21146
|
+
if (extendsMatch) {
|
|
21147
|
+
allProps.push(...parseInterface(content, extendsMatch[1]));
|
|
21148
|
+
}
|
|
21149
|
+
allProps.push(...parseInterface(content, firstBranch));
|
|
21150
|
+
const seen = /* @__PURE__ */ new Set();
|
|
21151
|
+
return allProps.filter((p) => {
|
|
21152
|
+
if (seen.has(p.name)) return false;
|
|
21153
|
+
seen.add(p.name);
|
|
21154
|
+
return true;
|
|
21155
|
+
});
|
|
21156
|
+
}
|
|
21157
|
+
function readTypesFile(filePath, componentName) {
|
|
21134
21158
|
const content = readTextFile(filePath);
|
|
21135
21159
|
if (!content) {
|
|
21136
21160
|
return null;
|
|
21137
21161
|
}
|
|
21138
|
-
const
|
|
21162
|
+
const resolvedName = componentName || path.basename(path.dirname(filePath));
|
|
21163
|
+
const exactRegex = new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+(${resolvedName}Props)\\b`);
|
|
21164
|
+
let propsInterfaceMatch = content.match(exactRegex);
|
|
21165
|
+
if (!propsInterfaceMatch) {
|
|
21166
|
+
const prefixRegex = new RegExp(
|
|
21167
|
+
`export\\s+${TYPE_OR_INTERFACE}\\s+(${resolvedName}\\w*Props)\\b`
|
|
21168
|
+
);
|
|
21169
|
+
propsInterfaceMatch = content.match(prefixRegex);
|
|
21170
|
+
}
|
|
21171
|
+
if (!propsInterfaceMatch) {
|
|
21172
|
+
propsInterfaceMatch = content.match(
|
|
21173
|
+
new RegExp(`export\\s+${TYPE_OR_INTERFACE}\\s+(Ui\\w+Props)\\b`)
|
|
21174
|
+
);
|
|
21175
|
+
}
|
|
21139
21176
|
if (!propsInterfaceMatch) {
|
|
21140
21177
|
return null;
|
|
21141
21178
|
}
|
|
21142
21179
|
const interfaceName = propsInterfaceMatch[1];
|
|
21143
|
-
const
|
|
21180
|
+
const matchedComponentName = interfaceName.replace("Props", "");
|
|
21144
21181
|
const description = extractComponentDescription(content, interfaceName);
|
|
21145
|
-
|
|
21182
|
+
let props = parseInterface(content, interfaceName);
|
|
21183
|
+
if (props.length === 0) {
|
|
21184
|
+
props = resolveUnionOrIntersectionProps(content, interfaceName);
|
|
21185
|
+
}
|
|
21146
21186
|
return {
|
|
21147
|
-
name:
|
|
21187
|
+
name: matchedComponentName,
|
|
21148
21188
|
description,
|
|
21149
21189
|
props
|
|
21150
21190
|
};
|
|
21151
21191
|
}
|
|
21152
21192
|
function readComponentTypes(componentDir) {
|
|
21153
21193
|
const typesPath = path.join(componentDir, "types.ts");
|
|
21154
|
-
return readTypesFile(typesPath);
|
|
21194
|
+
return readTypesFile(typesPath, path.basename(componentDir));
|
|
21155
21195
|
}
|
|
21156
21196
|
|
|
21157
21197
|
// src/constants.ts
|
|
@@ -21364,6 +21404,40 @@ function extractStories(content) {
|
|
|
21364
21404
|
}
|
|
21365
21405
|
return stories;
|
|
21366
21406
|
}
|
|
21407
|
+
function extractInlineRenderTemplates(content) {
|
|
21408
|
+
const examples = [];
|
|
21409
|
+
const storyExportRegex = /export\s+const\s+(\w+):\s*Story\s*=/g;
|
|
21410
|
+
let match;
|
|
21411
|
+
while ((match = storyExportRegex.exec(content)) !== null) {
|
|
21412
|
+
const storyName = match[1];
|
|
21413
|
+
if (storyName === "default") continue;
|
|
21414
|
+
const afterEquals = content.indexOf("{", match.index + match[0].length);
|
|
21415
|
+
if (afterEquals === -1) continue;
|
|
21416
|
+
const closingBrace = findMatchingBrace(content, afterEquals);
|
|
21417
|
+
if (closingBrace === -1) continue;
|
|
21418
|
+
const storyBlock = content.slice(afterEquals, closingBrace + 1);
|
|
21419
|
+
if (!storyBlock.includes("template:")) continue;
|
|
21420
|
+
const templateMatch = storyBlock.match(/template:\s*`([\s\S]*?)`/);
|
|
21421
|
+
if (!templateMatch) continue;
|
|
21422
|
+
const template = templateMatch[1].trim();
|
|
21423
|
+
if (!template) continue;
|
|
21424
|
+
const componentsMatch = storyBlock.match(/components:\s*\{([^}]+)\}/);
|
|
21425
|
+
const componentNames = componentsMatch ? componentsMatch[1].split(",").map((c) => c.trim()).filter(Boolean) : [];
|
|
21426
|
+
const imports = componentNames.length > 0 ? `<script setup>
|
|
21427
|
+
// Components: ${componentNames.join(", ")}
|
|
21428
|
+
</script>
|
|
21429
|
+
|
|
21430
|
+
` : "";
|
|
21431
|
+
examples.push({
|
|
21432
|
+
name: storyName,
|
|
21433
|
+
description: "",
|
|
21434
|
+
code: `${imports}<template>
|
|
21435
|
+
${template}
|
|
21436
|
+
</template>`
|
|
21437
|
+
});
|
|
21438
|
+
}
|
|
21439
|
+
return examples;
|
|
21440
|
+
}
|
|
21367
21441
|
function extractArgTypes(content) {
|
|
21368
21442
|
const argTypes = [];
|
|
21369
21443
|
const argTypesKeyIndex = content.indexOf("argTypes");
|
|
@@ -21420,6 +21494,56 @@ function extractTitle(content) {
|
|
|
21420
21494
|
const titleMatch = content.match(/title:\s*['"]([^'"]+)['"]/);
|
|
21421
21495
|
return titleMatch ? titleMatch[1] : "";
|
|
21422
21496
|
}
|
|
21497
|
+
function extractMetaArgs(content) {
|
|
21498
|
+
const metaDefaultIndex = content.indexOf("export default");
|
|
21499
|
+
if (metaDefaultIndex === -1) return void 0;
|
|
21500
|
+
const metaSection = content.slice(0, metaDefaultIndex);
|
|
21501
|
+
const argsKeyIndex = metaSection.lastIndexOf("args:");
|
|
21502
|
+
if (argsKeyIndex !== -1) {
|
|
21503
|
+
return extractArgsFromPosition(content, argsKeyIndex);
|
|
21504
|
+
}
|
|
21505
|
+
const afterExport = content.slice(metaDefaultIndex + "export default".length);
|
|
21506
|
+
const trimmed = afterExport.trimStart();
|
|
21507
|
+
if (!trimmed.startsWith("{")) return void 0;
|
|
21508
|
+
const blockStart = content.indexOf("{", metaDefaultIndex);
|
|
21509
|
+
const blockEnd = findMatchingBrace(content, blockStart);
|
|
21510
|
+
if (blockEnd === -1) return void 0;
|
|
21511
|
+
const metaBlock = content.slice(blockStart + 1, blockEnd);
|
|
21512
|
+
const inlineArgsIndex = metaBlock.indexOf("args:");
|
|
21513
|
+
if (inlineArgsIndex === -1) return void 0;
|
|
21514
|
+
return extractArgsFromPosition(content, blockStart + 1 + inlineArgsIndex);
|
|
21515
|
+
}
|
|
21516
|
+
function extractArgsFromPosition(content, argsKeyIndex) {
|
|
21517
|
+
const colonIndex = content.indexOf(":", argsKeyIndex + 4);
|
|
21518
|
+
if (colonIndex === -1) {
|
|
21519
|
+
return void 0;
|
|
21520
|
+
}
|
|
21521
|
+
const openingBraceIndex = content.indexOf("{", colonIndex);
|
|
21522
|
+
if (openingBraceIndex === -1) {
|
|
21523
|
+
return void 0;
|
|
21524
|
+
}
|
|
21525
|
+
const closingBraceIndex = findMatchingBrace(content, openingBraceIndex);
|
|
21526
|
+
if (closingBraceIndex === -1) {
|
|
21527
|
+
return void 0;
|
|
21528
|
+
}
|
|
21529
|
+
const argsBlock = content.slice(openingBraceIndex + 1, closingBraceIndex);
|
|
21530
|
+
const args = {};
|
|
21531
|
+
const kvRegex = /(\w+)\s*:\s*(?:'([^']*)'|"([^"]*)"|(\d+(?:\.\d+)?)|(\btrue\b|\bfalse\b))/g;
|
|
21532
|
+
let match;
|
|
21533
|
+
while ((match = kvRegex.exec(argsBlock)) !== null) {
|
|
21534
|
+
const key = match[1];
|
|
21535
|
+
if (match[2] !== void 0) {
|
|
21536
|
+
args[key] = match[2];
|
|
21537
|
+
} else if (match[3] !== void 0) {
|
|
21538
|
+
args[key] = match[3];
|
|
21539
|
+
} else if (match[4] !== void 0) {
|
|
21540
|
+
args[key] = Number(match[4]);
|
|
21541
|
+
} else if (match[5] !== void 0) {
|
|
21542
|
+
args[key] = match[5] === "true";
|
|
21543
|
+
}
|
|
21544
|
+
}
|
|
21545
|
+
return Object.keys(args).length > 0 ? args : void 0;
|
|
21546
|
+
}
|
|
21423
21547
|
function readStoriesFile(filePath) {
|
|
21424
21548
|
const content = readTextFile(filePath);
|
|
21425
21549
|
if (!content) {
|
|
@@ -21431,6 +21555,7 @@ function readStoriesFile(filePath) {
|
|
|
21431
21555
|
const storyTemplateMap = extractStories(content);
|
|
21432
21556
|
const examples = [];
|
|
21433
21557
|
const usageGuidance = [];
|
|
21558
|
+
const coveredStories = /* @__PURE__ */ new Set();
|
|
21434
21559
|
for (const [storyName, templateVar] of storyTemplateMap) {
|
|
21435
21560
|
const code = templateSources.get(templateVar);
|
|
21436
21561
|
const description = extractStoryJSDoc(content, storyName);
|
|
@@ -21440,16 +21565,29 @@ function readStoriesFile(filePath) {
|
|
|
21440
21565
|
description,
|
|
21441
21566
|
code
|
|
21442
21567
|
});
|
|
21568
|
+
coveredStories.add(storyName);
|
|
21443
21569
|
}
|
|
21444
21570
|
if (description) {
|
|
21445
21571
|
usageGuidance.push(description);
|
|
21446
21572
|
}
|
|
21447
21573
|
}
|
|
21574
|
+
const inlineExamples = extractInlineRenderTemplates(content);
|
|
21575
|
+
for (const example of inlineExamples) {
|
|
21576
|
+
if (!coveredStories.has(example.name)) {
|
|
21577
|
+
const description = extractStoryJSDoc(content, example.name);
|
|
21578
|
+
examples.push({ ...example, description });
|
|
21579
|
+
if (description) {
|
|
21580
|
+
usageGuidance.push(description);
|
|
21581
|
+
}
|
|
21582
|
+
}
|
|
21583
|
+
}
|
|
21584
|
+
const defaultArgs = extractMetaArgs(content);
|
|
21448
21585
|
return {
|
|
21449
21586
|
title,
|
|
21450
21587
|
examples,
|
|
21451
21588
|
argTypes,
|
|
21452
|
-
usageGuidance
|
|
21589
|
+
usageGuidance,
|
|
21590
|
+
defaultArgs
|
|
21453
21591
|
};
|
|
21454
21592
|
}
|
|
21455
21593
|
function readComponentStories(componentDir) {
|
|
@@ -21523,7 +21661,8 @@ function getComponentDocs(componentName) {
|
|
|
21523
21661
|
examples,
|
|
21524
21662
|
usageGuidance: [...new Set(usageGuidance)],
|
|
21525
21663
|
// Remove duplicates
|
|
21526
|
-
subComponents: subComponents && subComponents.length > 0 ? subComponents : void 0
|
|
21664
|
+
subComponents: subComponents && subComponents.length > 0 ? subComponents : void 0,
|
|
21665
|
+
defaultArgs: storiesInfo?.defaultArgs
|
|
21527
21666
|
};
|
|
21528
21667
|
}
|
|
21529
21668
|
|
|
@@ -21569,6 +21708,27 @@ function formatComponentDocs(docs) {
|
|
|
21569
21708
|
sections.push("## Props", "");
|
|
21570
21709
|
docs.props.forEach((prop) => sections.push(...formatProp(prop)));
|
|
21571
21710
|
}
|
|
21711
|
+
if (docs.defaultArgs && Object.keys(docs.defaultArgs).length > 0) {
|
|
21712
|
+
const filteredArgs = Object.entries(docs.defaultArgs).filter(([key, value]) => {
|
|
21713
|
+
const prop = docs.props.find((p) => p.name === key);
|
|
21714
|
+
if (!prop?.default) return true;
|
|
21715
|
+
return String(value) !== prop.default;
|
|
21716
|
+
});
|
|
21717
|
+
if (filteredArgs.length > 0) {
|
|
21718
|
+
sections.push("## Storybook Defaults", "");
|
|
21719
|
+
sections.push(
|
|
21720
|
+
"These are the recommended prop values used in the component's Storybook stories:",
|
|
21721
|
+
""
|
|
21722
|
+
);
|
|
21723
|
+
sections.push("| Prop | Value |");
|
|
21724
|
+
sections.push("|------|-------|");
|
|
21725
|
+
for (const [key, value] of filteredArgs) {
|
|
21726
|
+
const formatted = typeof value === "string" ? `"${value}"` : String(value);
|
|
21727
|
+
sections.push(`| \`${key}\` | \`${formatted}\` |`);
|
|
21728
|
+
}
|
|
21729
|
+
sections.push("");
|
|
21730
|
+
}
|
|
21731
|
+
}
|
|
21572
21732
|
if (docs.subComponents && docs.subComponents.length > 0) {
|
|
21573
21733
|
sections.push("## Sub-components", "");
|
|
21574
21734
|
docs.subComponents.forEach((name) => sections.push(`- \`${name}\``));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aleph-alpha/lib-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/server.js",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"@aleph-alpha/tsconfig-frontend": "0.5.0"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"@aleph-alpha/ui-library": "1.
|
|
31
|
+
"@aleph-alpha/ui-library": "1.23.0"
|
|
32
32
|
},
|
|
33
33
|
"homepage": "https://docs.aleph-alpha.com",
|
|
34
34
|
"scripts": {
|