@aleph-alpha/lib-mcp 2.0.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +75 -14
- package/chat-kit-components-meta.json +90 -0
- package/components-meta.json +179 -77
- package/dist/cli.js +31 -10
- package/dist/scripts/generate-component-meta.js +76 -31
- package/dist/server.js +31 -10
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,17 +1,30 @@
|
|
|
1
1
|
# @aleph-alpha/lib-mcp
|
|
2
2
|
|
|
3
|
-
MCP (Model Context Protocol) Server for UI Library component discovery tools.
|
|
3
|
+
MCP (Model Context Protocol) Server for UI Library and ChatKit component discovery tools.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
This package provides an MCP server that enables AI assistants (like Claude and Cursor) to discover and understand
|
|
7
|
+
This package provides an MCP server that enables AI assistants (like Claude and Cursor) to discover and understand components from:
|
|
8
|
+
|
|
9
|
+
- [`@aleph-alpha/ui-library`](../ui-library) — `Ui*` components
|
|
10
|
+
- [`@aleph-alpha/chat-kit`](../chat-kit) — `Ck*` components
|
|
11
|
+
|
|
12
|
+
It offers tools to list available components and retrieve detailed documentation including props, examples, and usage guidance.
|
|
8
13
|
|
|
9
14
|
## Installation
|
|
10
15
|
|
|
16
|
+
Install `@aleph-alpha/lib-mcp` together with the component packages whose docs you want to query. UI Library is required; ChatKit is optional and only needed if you want `Ck*` component docs.
|
|
17
|
+
|
|
11
18
|
```bash
|
|
19
|
+
# UI Library only
|
|
12
20
|
pnpm add @aleph-alpha/lib-mcp @aleph-alpha/ui-library
|
|
21
|
+
|
|
22
|
+
# UI Library + ChatKit
|
|
23
|
+
pnpm add @aleph-alpha/lib-mcp @aleph-alpha/ui-library @aleph-alpha/chat-kit
|
|
13
24
|
```
|
|
14
25
|
|
|
26
|
+
> ChatKit docs require `@aleph-alpha/chat-kit` to publish its `src/` directory (component `types.ts` and `*.stories.ts` files). If `get_chat_kit_docs` returns "Could not find chat-kit source directory", upgrade `@aleph-alpha/chat-kit` to a version that includes `src/` in its published files.
|
|
27
|
+
|
|
15
28
|
## Usage
|
|
16
29
|
|
|
17
30
|
### Configure MCP Server
|
|
@@ -24,6 +37,9 @@ npx @aleph-alpha/lib-mcp mcp-install
|
|
|
24
37
|
|
|
25
38
|
# For both Claude Code and Cursor
|
|
26
39
|
npx @aleph-alpha/lib-mcp mcp-install --cursor
|
|
40
|
+
|
|
41
|
+
# For VS Code
|
|
42
|
+
npx @aleph-alpha/lib-mcp mcp-install --vscode
|
|
27
43
|
```
|
|
28
44
|
|
|
29
45
|
After installation, restart your IDE to activate the MCP tools.
|
|
@@ -32,9 +48,11 @@ After installation, restart your IDE to activate the MCP tools.
|
|
|
32
48
|
|
|
33
49
|
Once configured, the following tools are available to your AI assistant:
|
|
34
50
|
|
|
35
|
-
####
|
|
51
|
+
#### UI Library tools
|
|
52
|
+
|
|
53
|
+
##### `list_components`
|
|
36
54
|
|
|
37
|
-
Lists all available UI components. Supports optional filtering by name, category, or description.
|
|
55
|
+
Lists all available UI Library components. Supports optional filtering by name, category, or description.
|
|
38
56
|
|
|
39
57
|
```
|
|
40
58
|
list_components
|
|
@@ -42,9 +60,9 @@ list_components --filter="button"
|
|
|
42
60
|
list_components --filter="form"
|
|
43
61
|
```
|
|
44
62
|
|
|
45
|
-
|
|
63
|
+
##### `get_component_docs`
|
|
46
64
|
|
|
47
|
-
Retrieves full documentation for a specific component including:
|
|
65
|
+
Retrieves full documentation for a specific UI Library component including:
|
|
48
66
|
|
|
49
67
|
- Component description
|
|
50
68
|
- Props with types, defaults, and descriptions
|
|
@@ -57,6 +75,45 @@ get_component_docs UiButton
|
|
|
57
75
|
get_component_docs Button # "Ui" prefix is optional
|
|
58
76
|
```
|
|
59
77
|
|
|
78
|
+
#### ChatKit tools
|
|
79
|
+
|
|
80
|
+
Available when `@aleph-alpha/chat-kit` is installed alongside this package.
|
|
81
|
+
|
|
82
|
+
##### `list_chat_kit_components`
|
|
83
|
+
|
|
84
|
+
Lists all available ChatKit (`Ck*`) components. Supports optional filtering by name, category, or description.
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
list_chat_kit_components
|
|
88
|
+
list_chat_kit_components --filter="history"
|
|
89
|
+
list_chat_kit_components --filter="message"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
##### `get_chat_kit_docs`
|
|
93
|
+
|
|
94
|
+
Retrieves full documentation for a specific ChatKit component, with the same shape as `get_component_docs`:
|
|
95
|
+
|
|
96
|
+
- Component description
|
|
97
|
+
- Props with types, defaults, and descriptions
|
|
98
|
+
- Sub-components (if applicable)
|
|
99
|
+
- Usage guidance
|
|
100
|
+
- Code examples
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
get_chat_kit_docs CkHistory
|
|
104
|
+
get_chat_kit_docs History # "Ck" prefix is optional
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
#### Setup tool
|
|
108
|
+
|
|
109
|
+
##### `get_setup_guide`
|
|
110
|
+
|
|
111
|
+
Returns the setup and installation guide for integrating the UI library into a project (UnoCSS config, Vite config, required dependencies, and MCP setup instructions).
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
get_setup_guide
|
|
115
|
+
```
|
|
116
|
+
|
|
60
117
|
## Development
|
|
61
118
|
|
|
62
119
|
### Building
|
|
@@ -67,6 +124,8 @@ pnpm build
|
|
|
67
124
|
|
|
68
125
|
### Generating Component Metadata
|
|
69
126
|
|
|
127
|
+
Regenerates `components-meta.json` (UI Library) and `chat-kit-components-meta.json` (ChatKit) by scanning each package's source files.
|
|
128
|
+
|
|
70
129
|
```bash
|
|
71
130
|
pnpm generate:component-meta
|
|
72
131
|
```
|
|
@@ -79,21 +138,23 @@ pnpm test
|
|
|
79
138
|
|
|
80
139
|
## How It Works
|
|
81
140
|
|
|
82
|
-
The MCP server reads component metadata from:
|
|
141
|
+
The MCP server reads component metadata from each package's source layout:
|
|
83
142
|
|
|
84
143
|
1. **`types.ts`**: Extracts props, their types, descriptions, and component-level JSDoc tags (`@category`, `@useCases`, `@keywords`, `@related`)
|
|
85
144
|
2. **`*.stories.ts`**: Extracts code examples and usage guidance from Storybook stories
|
|
86
|
-
3. **`
|
|
145
|
+
3. **`index.ts`**: Detects sub-component exports for the documented component
|
|
146
|
+
4. **`components-meta.json` / `chat-kit-components-meta.json`**: Pre-generated metadata for faster lookups
|
|
147
|
+
|
|
148
|
+
UI Library components are read from `@aleph-alpha/ui-library/src/**`, and ChatKit components from `@aleph-alpha/chat-kit/src/components/**`. Both packages must publish their `src/` directory for docs to resolve when consumed from `node_modules`.
|
|
87
149
|
|
|
88
150
|
## CLI Commands
|
|
89
151
|
|
|
90
|
-
| Command
|
|
91
|
-
|
|
92
|
-
| `mcp-install` | Configure MCP server for IDE |
|
|
93
|
-
| `serve`
|
|
94
|
-
| `--help`
|
|
152
|
+
| Command | Description |
|
|
153
|
+
| ------------- | ----------------------------------------------------------------------- |
|
|
154
|
+
| `mcp-install` | Configure MCP server for IDE (`--cursor`, `--vscode` to add extra IDEs) |
|
|
155
|
+
| `serve` | Start the MCP server (used internally by IDE) |
|
|
156
|
+
| `--help` | Show help message |
|
|
95
157
|
|
|
96
158
|
## License
|
|
97
159
|
|
|
98
160
|
Apache-2.0
|
|
99
|
-
|
|
@@ -103,6 +103,95 @@
|
|
|
103
103
|
],
|
|
104
104
|
"_autoGenerated": true
|
|
105
105
|
},
|
|
106
|
+
"CkFeedbackButton": {
|
|
107
|
+
"description": "Binary thumbs up / thumbs down feedback control for assistant messages. Fully prop-driven: the host application owns the selection and lock state and decides when (or if) to persist it to a backend. Labels default to those provided by `useChatKitLabels` (which can be translated via `provideChatKitLabels`). The `ariaLabel*` props override the injected labels on a per-instance basis when set.",
|
|
108
|
+
"category": "Feedback",
|
|
109
|
+
"useCases": [
|
|
110
|
+
"like or dislike an assistant reply",
|
|
111
|
+
"collect binary message rating",
|
|
112
|
+
"lock feedback after submission",
|
|
113
|
+
"rate AI response"
|
|
114
|
+
],
|
|
115
|
+
"keywords": [
|
|
116
|
+
"feedback",
|
|
117
|
+
"thumbs up",
|
|
118
|
+
"thumbs down",
|
|
119
|
+
"like",
|
|
120
|
+
"dislike",
|
|
121
|
+
"rating",
|
|
122
|
+
"vote",
|
|
123
|
+
"action",
|
|
124
|
+
"message",
|
|
125
|
+
"button"
|
|
126
|
+
],
|
|
127
|
+
"related": [
|
|
128
|
+
"CkMessageActionButton",
|
|
129
|
+
"CkCopyMessageActionButton",
|
|
130
|
+
"CkAgentMessage",
|
|
131
|
+
"CkConversation"
|
|
132
|
+
],
|
|
133
|
+
"props": [
|
|
134
|
+
"value",
|
|
135
|
+
"locked",
|
|
136
|
+
"disabled",
|
|
137
|
+
"ariaLabelThumbsUp",
|
|
138
|
+
"ariaLabelThumbsDown",
|
|
139
|
+
"ariaLabelGroup"
|
|
140
|
+
],
|
|
141
|
+
"examples": [
|
|
142
|
+
"Default",
|
|
143
|
+
"SelectedUp",
|
|
144
|
+
"SelectedDown",
|
|
145
|
+
"Locked",
|
|
146
|
+
"Disabled",
|
|
147
|
+
"SubmitOnSelect"
|
|
148
|
+
],
|
|
149
|
+
"_autoGenerated": true
|
|
150
|
+
},
|
|
151
|
+
"CkFileItemsList": {
|
|
152
|
+
"description": "Horizontal list of file attachments; collapses to a popover once the count exceeds `maxInline`.",
|
|
153
|
+
"category": "Form Inputs",
|
|
154
|
+
"useCases": [
|
|
155
|
+
"user message attachments",
|
|
156
|
+
"prompt input previews",
|
|
157
|
+
"chat file row"
|
|
158
|
+
],
|
|
159
|
+
"keywords": [
|
|
160
|
+
"files",
|
|
161
|
+
"attachments",
|
|
162
|
+
"file list",
|
|
163
|
+
"popover",
|
|
164
|
+
"chat",
|
|
165
|
+
"file",
|
|
166
|
+
"items",
|
|
167
|
+
"list"
|
|
168
|
+
],
|
|
169
|
+
"related": [
|
|
170
|
+
"UiFileItem",
|
|
171
|
+
"UiPopover"
|
|
172
|
+
],
|
|
173
|
+
"props": [
|
|
174
|
+
"files",
|
|
175
|
+
"maxInline",
|
|
176
|
+
"size",
|
|
177
|
+
"isRemovable",
|
|
178
|
+
"removeLabel",
|
|
179
|
+
"disabled",
|
|
180
|
+
"triggerLabel",
|
|
181
|
+
"triggerAriaLabel",
|
|
182
|
+
"listLabel",
|
|
183
|
+
"popoverClass"
|
|
184
|
+
],
|
|
185
|
+
"examples": [
|
|
186
|
+
"Inline",
|
|
187
|
+
"Collapsed",
|
|
188
|
+
"Removable",
|
|
189
|
+
"CustomItem",
|
|
190
|
+
"Clickable",
|
|
191
|
+
"Disabled"
|
|
192
|
+
],
|
|
193
|
+
"_autoGenerated": true
|
|
194
|
+
},
|
|
106
195
|
"CkHistoryItem": {
|
|
107
196
|
"description": "A single chat history entry with title, optional meta line, active indicator, and a trailing action control (plain button or popover). Sidebar-agnostic: can be used anywhere, not only inside a sidebar.",
|
|
108
197
|
"category": "Actions",
|
|
@@ -443,6 +532,7 @@
|
|
|
443
532
|
],
|
|
444
533
|
"examples": [
|
|
445
534
|
"Default",
|
|
535
|
+
"ChainOfThought",
|
|
446
536
|
"WithIcon",
|
|
447
537
|
"WithCustomAvatarFallback",
|
|
448
538
|
"NoIcon",
|
package/components-meta.json
CHANGED
|
@@ -62,14 +62,26 @@
|
|
|
62
62
|
"_autoGenerated": true
|
|
63
63
|
},
|
|
64
64
|
"UiAlertDialog": {
|
|
65
|
-
"description": "
|
|
66
|
-
"category": "
|
|
67
|
-
"useCases": [
|
|
65
|
+
"description": "A modal dialog for confirmations that interrupt the user. Use for destructive actions, important decisions, or critical confirmations.",
|
|
66
|
+
"category": "Overlays",
|
|
67
|
+
"useCases": [
|
|
68
|
+
"confirm delete",
|
|
69
|
+
"destructive action",
|
|
70
|
+
"important confirmation",
|
|
71
|
+
"warning"
|
|
72
|
+
],
|
|
68
73
|
"keywords": [
|
|
69
74
|
"alert",
|
|
70
|
-
"dialog"
|
|
75
|
+
"dialog",
|
|
76
|
+
"modal",
|
|
77
|
+
"confirm",
|
|
78
|
+
"warning",
|
|
79
|
+
"destructive",
|
|
80
|
+
"popup"
|
|
81
|
+
],
|
|
82
|
+
"related": [
|
|
83
|
+
"UiPopover"
|
|
71
84
|
],
|
|
72
|
-
"related": [],
|
|
73
85
|
"props": [],
|
|
74
86
|
"examples": [
|
|
75
87
|
"Default",
|
|
@@ -102,9 +114,10 @@
|
|
|
102
114
|
"props": [],
|
|
103
115
|
"examples": [
|
|
104
116
|
"Default",
|
|
117
|
+
"Sizes",
|
|
105
118
|
"Fallback",
|
|
106
119
|
"Multiple",
|
|
107
|
-
"
|
|
120
|
+
"AvatarGroup"
|
|
108
121
|
],
|
|
109
122
|
"_autoGenerated": true
|
|
110
123
|
},
|
|
@@ -205,6 +218,7 @@
|
|
|
205
218
|
"WithIconSlot",
|
|
206
219
|
"AsChild",
|
|
207
220
|
"AllVariants",
|
|
221
|
+
"DisabledHoverBleed",
|
|
208
222
|
"IconSizes",
|
|
209
223
|
"AllVariantsAndSizes"
|
|
210
224
|
],
|
|
@@ -526,7 +540,7 @@
|
|
|
526
540
|
"WithRadioItems",
|
|
527
541
|
"WithDestructiveAction",
|
|
528
542
|
"WithSubmenu",
|
|
529
|
-
"
|
|
543
|
+
"WithIconTrigger",
|
|
530
544
|
"WithSoftToggleTrigger",
|
|
531
545
|
"WithSoftToggleTriggerAndText",
|
|
532
546
|
"WithAvatarTrigger"
|
|
@@ -633,12 +647,15 @@
|
|
|
633
647
|
"upload",
|
|
634
648
|
"attachment",
|
|
635
649
|
"progress",
|
|
650
|
+
"success",
|
|
651
|
+
"error",
|
|
636
652
|
"item"
|
|
637
653
|
],
|
|
638
654
|
"related": [
|
|
639
655
|
"UiFileUploadBox",
|
|
640
656
|
"UiItem",
|
|
641
|
-
"UiButton"
|
|
657
|
+
"UiButton",
|
|
658
|
+
"UiProgress"
|
|
642
659
|
],
|
|
643
660
|
"props": [
|
|
644
661
|
"filename",
|
|
@@ -647,24 +664,64 @@
|
|
|
647
664
|
"progress",
|
|
648
665
|
"error",
|
|
649
666
|
"removeLabel",
|
|
650
|
-
"
|
|
667
|
+
"progressLabel",
|
|
668
|
+
"removable",
|
|
669
|
+
"disabled",
|
|
670
|
+
"size",
|
|
671
|
+
"mediaTone",
|
|
672
|
+
"mediaIcon"
|
|
651
673
|
],
|
|
652
674
|
"examples": [
|
|
653
675
|
"Default",
|
|
654
|
-
"
|
|
655
|
-
"
|
|
656
|
-
"
|
|
676
|
+
"DefaultWithProgress",
|
|
677
|
+
"DefaultSuccess",
|
|
678
|
+
"DefaultError",
|
|
679
|
+
"SmallWithProgress",
|
|
680
|
+
"SmallSuccess",
|
|
681
|
+
"SmallError",
|
|
682
|
+
"NonRemovable",
|
|
657
683
|
"Disabled",
|
|
658
|
-
"
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
684
|
+
"AllVariants"
|
|
685
|
+
],
|
|
686
|
+
"_autoGenerated": true
|
|
687
|
+
},
|
|
688
|
+
"UiFileType": {
|
|
689
|
+
"description": "Round 32×32 badge that visualises a file type with a tone + icon. Mirrors the Figma `Filetype` component (`AA26 / File Upload / Filetype`, node id `26438:42144`): - `Type=Text` (`pdf` / `doc` / `docx` / `txt` / `rtf`) → `accent-pink` + `file` - `Type=Markdown` (`html` / `htm` / `md` / `mdx`) → `accent-soft` + `code-xml` - `Type=Tabular` (`csv` / `tsv` / `xls` / `xlsx`) → `accent-yellow` + `table-2` - everything else → `default` + `file`",
|
|
690
|
+
"category": "Data Display",
|
|
691
|
+
"useCases": [
|
|
692
|
+
"file-type indicator",
|
|
693
|
+
"attachment badge"
|
|
694
|
+
],
|
|
695
|
+
"keywords": [
|
|
696
|
+
"file",
|
|
697
|
+
"badge",
|
|
698
|
+
"attachment",
|
|
699
|
+
"filetype",
|
|
700
|
+
"icon",
|
|
701
|
+
"type"
|
|
702
|
+
],
|
|
703
|
+
"related": [
|
|
704
|
+
"UiFileItem",
|
|
705
|
+
"UiFileUploadBox"
|
|
706
|
+
],
|
|
707
|
+
"props": [
|
|
708
|
+
"filename",
|
|
709
|
+
"tone",
|
|
710
|
+
"icon",
|
|
711
|
+
"error",
|
|
712
|
+
"loading"
|
|
713
|
+
],
|
|
714
|
+
"examples": [
|
|
715
|
+
"Default",
|
|
716
|
+
"ErrorState",
|
|
717
|
+
"AllTypes",
|
|
718
|
+
"ToneOverrides"
|
|
662
719
|
],
|
|
663
720
|
"_autoGenerated": true
|
|
664
721
|
},
|
|
665
722
|
"UiFileUploadBox": {
|
|
666
723
|
"description": "Drop zone + file picker for selecting files with optional type/size validation. **Emits:** see {@link UiFileUploadBoxEmits}.",
|
|
667
|
-
"category": "
|
|
724
|
+
"category": "Form Inputs",
|
|
668
725
|
"useCases": [
|
|
669
726
|
"file upload area",
|
|
670
727
|
"drag and drop attachments"
|
|
@@ -698,69 +755,34 @@
|
|
|
698
755
|
"_autoGenerated": true
|
|
699
756
|
},
|
|
700
757
|
"UiIcon": {
|
|
701
|
-
"description": "
|
|
702
|
-
"category": "
|
|
703
|
-
"useCases": [],
|
|
704
|
-
"keywords": [
|
|
705
|
-
"icon"
|
|
706
|
-
],
|
|
707
|
-
"related": [],
|
|
708
|
-
"props": [
|
|
709
|
-
"name",
|
|
710
|
-
"size",
|
|
711
|
-
"strokeWidth",
|
|
712
|
-
"ariaLabel"
|
|
713
|
-
],
|
|
714
|
-
"examples": [
|
|
715
|
-
"Default",
|
|
716
|
-
"Sizes",
|
|
717
|
-
"InIconButton"
|
|
718
|
-
],
|
|
719
|
-
"_autoGenerated": true
|
|
720
|
-
},
|
|
721
|
-
"UiIconButton": {
|
|
722
|
-
"description": "A button that displays only an icon without text. Use for compact actions like close, edit, delete, or toolbar buttons. It is being merged into `UiButton` — use `UiButton` with an icon-only child and an `aria-label` instead (e.g. `<UiButton size=\"icon-sm\" aria-label=\"Close\"><UiIcon name=\"x\" /></UiButton>`).",
|
|
723
|
-
"category": "Actions",
|
|
758
|
+
"description": "An icon component using Lucide icons. Use for visual indicators, button decorations, or standalone meaningful graphics.",
|
|
759
|
+
"category": "Data Display",
|
|
724
760
|
"useCases": [
|
|
725
|
-
"
|
|
726
|
-
"
|
|
727
|
-
"
|
|
728
|
-
"
|
|
761
|
+
"visual indicator",
|
|
762
|
+
"button icon",
|
|
763
|
+
"status icon",
|
|
764
|
+
"decorative graphic"
|
|
729
765
|
],
|
|
730
766
|
"keywords": [
|
|
731
|
-
"iconbutton",
|
|
732
767
|
"icon",
|
|
733
|
-
"
|
|
734
|
-
"
|
|
735
|
-
"
|
|
736
|
-
"
|
|
737
|
-
"delete"
|
|
768
|
+
"symbol",
|
|
769
|
+
"graphic",
|
|
770
|
+
"lucide",
|
|
771
|
+
"svg"
|
|
738
772
|
],
|
|
739
773
|
"related": [
|
|
740
|
-
"UiButton"
|
|
741
|
-
"UiIcon"
|
|
774
|
+
"UiButton"
|
|
742
775
|
],
|
|
743
776
|
"props": [
|
|
744
|
-
"
|
|
777
|
+
"name",
|
|
745
778
|
"size",
|
|
746
|
-
"
|
|
747
|
-
"type",
|
|
748
|
-
"disabled",
|
|
749
|
-
"loading",
|
|
779
|
+
"strokeWidth",
|
|
750
780
|
"ariaLabel"
|
|
751
781
|
],
|
|
752
782
|
"examples": [
|
|
753
783
|
"Default",
|
|
754
|
-
"
|
|
755
|
-
"
|
|
756
|
-
"Outline",
|
|
757
|
-
"Ghost",
|
|
758
|
-
"Link",
|
|
759
|
-
"Loading",
|
|
760
|
-
"Disabled",
|
|
761
|
-
"AllVariants",
|
|
762
|
-
"AllSizes",
|
|
763
|
-
"AsChild"
|
|
784
|
+
"Sizes",
|
|
785
|
+
"IconLibrary"
|
|
764
786
|
],
|
|
765
787
|
"_autoGenerated": true
|
|
766
788
|
},
|
|
@@ -831,7 +853,6 @@
|
|
|
831
853
|
"menu",
|
|
832
854
|
"settings",
|
|
833
855
|
"navigation",
|
|
834
|
-
"selectable",
|
|
835
856
|
"card"
|
|
836
857
|
],
|
|
837
858
|
"related": [
|
|
@@ -842,6 +863,9 @@
|
|
|
842
863
|
"props": [
|
|
843
864
|
"variant",
|
|
844
865
|
"size",
|
|
866
|
+
"title",
|
|
867
|
+
"description",
|
|
868
|
+
"desc",
|
|
845
869
|
"asChild",
|
|
846
870
|
"withListSemantics"
|
|
847
871
|
],
|
|
@@ -849,16 +873,14 @@
|
|
|
849
873
|
"Basic",
|
|
850
874
|
"Variants",
|
|
851
875
|
"Sizes",
|
|
876
|
+
"CustomSlots",
|
|
852
877
|
"WithIcon",
|
|
853
|
-
"
|
|
854
|
-
"
|
|
878
|
+
"Actions",
|
|
879
|
+
"ActionTooltip",
|
|
880
|
+
"Media",
|
|
855
881
|
"Group",
|
|
856
|
-
"WithHeaderAndFooter",
|
|
857
882
|
"AsLink",
|
|
858
|
-
"
|
|
859
|
-
"NotificationList",
|
|
860
|
-
"EmptyStateWithInvite",
|
|
861
|
-
"AllStates"
|
|
883
|
+
"AllVariants"
|
|
862
884
|
],
|
|
863
885
|
"_autoGenerated": true
|
|
864
886
|
},
|
|
@@ -1166,6 +1188,36 @@
|
|
|
1166
1188
|
],
|
|
1167
1189
|
"_autoGenerated": true
|
|
1168
1190
|
},
|
|
1191
|
+
"UiResizable": {
|
|
1192
|
+
"description": "A resizable panel layout for splitting available space into user-adjustable regions. Use for sidebars, inspectors, editors, and other dense layouts where users need control over panel sizes.",
|
|
1193
|
+
"category": "Layout",
|
|
1194
|
+
"useCases": [
|
|
1195
|
+
"split pane",
|
|
1196
|
+
"resizable sidebar",
|
|
1197
|
+
"editor layout",
|
|
1198
|
+
"inspector panel"
|
|
1199
|
+
],
|
|
1200
|
+
"keywords": [
|
|
1201
|
+
"resizable",
|
|
1202
|
+
"splitter",
|
|
1203
|
+
"panel",
|
|
1204
|
+
"pane",
|
|
1205
|
+
"layout",
|
|
1206
|
+
"sidebar"
|
|
1207
|
+
],
|
|
1208
|
+
"related": [
|
|
1209
|
+
"UiSheet",
|
|
1210
|
+
"UiSeparator"
|
|
1211
|
+
],
|
|
1212
|
+
"props": [],
|
|
1213
|
+
"examples": [
|
|
1214
|
+
"Default",
|
|
1215
|
+
"Vertical",
|
|
1216
|
+
"Collapsible",
|
|
1217
|
+
"PixelSizing"
|
|
1218
|
+
],
|
|
1219
|
+
"_autoGenerated": true
|
|
1220
|
+
},
|
|
1169
1221
|
"UiSelect": {
|
|
1170
1222
|
"description": "A dropdown select for choosing from a list of options. Use for form fields where users must pick one value from many.",
|
|
1171
1223
|
"category": "Form Inputs",
|
|
@@ -1193,6 +1245,7 @@
|
|
|
1193
1245
|
"Default",
|
|
1194
1246
|
"WithGroups",
|
|
1195
1247
|
"WithDisabledItems",
|
|
1248
|
+
"WithIcons",
|
|
1196
1249
|
"Disabled",
|
|
1197
1250
|
"Sizes",
|
|
1198
1251
|
"Multiple",
|
|
@@ -1349,6 +1402,48 @@
|
|
|
1349
1402
|
],
|
|
1350
1403
|
"_autoGenerated": true
|
|
1351
1404
|
},
|
|
1405
|
+
"UiSnackbar": {
|
|
1406
|
+
"description": "Toast notification container (Sonner). Place once near the app root, then call `toast()` (or `toast.success()`, `toast.error()`, etc.) from anywhere to display a non-blocking notification.",
|
|
1407
|
+
"category": "Feedback",
|
|
1408
|
+
"useCases": [
|
|
1409
|
+
"success confirmation",
|
|
1410
|
+
"error notice",
|
|
1411
|
+
"undo action",
|
|
1412
|
+
"async progress",
|
|
1413
|
+
"background updates"
|
|
1414
|
+
],
|
|
1415
|
+
"keywords": [
|
|
1416
|
+
"snackbar",
|
|
1417
|
+
"toast",
|
|
1418
|
+
"sonner",
|
|
1419
|
+
"notification",
|
|
1420
|
+
"alert",
|
|
1421
|
+
"message",
|
|
1422
|
+
"banner",
|
|
1423
|
+
"undo"
|
|
1424
|
+
],
|
|
1425
|
+
"related": [
|
|
1426
|
+
"UiAlert",
|
|
1427
|
+
"UiAlertDialog"
|
|
1428
|
+
],
|
|
1429
|
+
"props": [],
|
|
1430
|
+
"examples": [
|
|
1431
|
+
"SuccessHigh",
|
|
1432
|
+
"SuccessLow",
|
|
1433
|
+
"InfoHigh",
|
|
1434
|
+
"InfoLow",
|
|
1435
|
+
"WarningHigh",
|
|
1436
|
+
"WarningLow",
|
|
1437
|
+
"ErrorHigh",
|
|
1438
|
+
"ErrorLow",
|
|
1439
|
+
"AllVariants",
|
|
1440
|
+
"Default",
|
|
1441
|
+
"WithDescription",
|
|
1442
|
+
"PromiseSnackbar",
|
|
1443
|
+
"WithDialog"
|
|
1444
|
+
],
|
|
1445
|
+
"_autoGenerated": true
|
|
1446
|
+
},
|
|
1352
1447
|
"UiSpinner": {
|
|
1353
1448
|
"description": "An animated loading indicator. Use while content is loading or an action is processing.",
|
|
1354
1449
|
"category": "Feedback",
|
|
@@ -1593,9 +1688,12 @@
|
|
|
1593
1688
|
"props": [
|
|
1594
1689
|
"modelValue",
|
|
1595
1690
|
"defaultValue",
|
|
1691
|
+
"active",
|
|
1596
1692
|
"disabled",
|
|
1597
1693
|
"variant",
|
|
1598
|
-
"size"
|
|
1694
|
+
"size",
|
|
1695
|
+
"leftIcon",
|
|
1696
|
+
"rightIcon"
|
|
1599
1697
|
],
|
|
1600
1698
|
"examples": [
|
|
1601
1699
|
"Default",
|
|
@@ -1681,7 +1779,7 @@
|
|
|
1681
1779
|
],
|
|
1682
1780
|
"examples": [
|
|
1683
1781
|
"Default",
|
|
1684
|
-
"
|
|
1782
|
+
"WithIconTrigger",
|
|
1685
1783
|
"InstantDelay",
|
|
1686
1784
|
"LongDelay",
|
|
1687
1785
|
"Disabled",
|
|
@@ -1722,8 +1820,11 @@
|
|
|
1722
1820
|
"WithSorting",
|
|
1723
1821
|
"WithPagination",
|
|
1724
1822
|
"WithToolbar",
|
|
1823
|
+
"WithColumnsFilter",
|
|
1725
1824
|
"WithGlobalFilter",
|
|
1726
1825
|
"WithRowSelection",
|
|
1826
|
+
"WithDraggableColumns",
|
|
1827
|
+
"WithExpandableRows",
|
|
1727
1828
|
"FullExample",
|
|
1728
1829
|
"WithCustomEmptyText",
|
|
1729
1830
|
"WithCustomEmptySlot",
|
|
@@ -1875,6 +1976,7 @@
|
|
|
1875
1976
|
"props": [],
|
|
1876
1977
|
"examples": [
|
|
1877
1978
|
"Default",
|
|
1979
|
+
"Resizable",
|
|
1878
1980
|
"Inset",
|
|
1879
1981
|
"RightSide"
|
|
1880
1982
|
],
|
package/dist/cli.js
CHANGED
|
@@ -21425,11 +21425,15 @@ function detectCategoryDirs() {
|
|
|
21425
21425
|
return [];
|
|
21426
21426
|
}
|
|
21427
21427
|
const entries = fs4.readdirSync(srcPath, { withFileTypes: true });
|
|
21428
|
-
return entries.filter((entry) => entry.isDirectory()).filter(
|
|
21428
|
+
return entries.filter((entry) => entry.isDirectory()).filter(
|
|
21429
|
+
(entry) => !entry.name.startsWith(".") && entry.name !== "node_modules"
|
|
21430
|
+
).filter((entry) => {
|
|
21429
21431
|
try {
|
|
21430
21432
|
const dirPath = path4.join(srcPath, entry.name);
|
|
21431
21433
|
const subEntries = fs4.readdirSync(dirPath, { withFileTypes: true });
|
|
21432
|
-
return subEntries.some(
|
|
21434
|
+
return subEntries.some(
|
|
21435
|
+
(sub) => sub.isDirectory() && sub.name.startsWith(COMPONENT_PREFIX)
|
|
21436
|
+
);
|
|
21433
21437
|
} catch {
|
|
21434
21438
|
return false;
|
|
21435
21439
|
}
|
|
@@ -21970,7 +21974,10 @@ function parseInterface2(content, interfaceName) {
|
|
|
21970
21974
|
const propName = propMatch[2];
|
|
21971
21975
|
const isOptional = !!propMatch[3];
|
|
21972
21976
|
const typeStartIndex = propMatch.index + propMatch[0].length;
|
|
21973
|
-
const { type: propType, endIndex } = extractType2(
|
|
21977
|
+
const { type: propType, endIndex } = extractType2(
|
|
21978
|
+
interfaceBody,
|
|
21979
|
+
typeStartIndex
|
|
21980
|
+
);
|
|
21974
21981
|
propStartRegex.lastIndex = endIndex + 1;
|
|
21975
21982
|
const jsdoc = parseJSDoc2(jsdocComment);
|
|
21976
21983
|
props.push({
|
|
@@ -21987,7 +21994,9 @@ function parseInterface2(content, interfaceName) {
|
|
|
21987
21994
|
function extractComponentDescription2(content, interfaceName) {
|
|
21988
21995
|
const lines = content.split("\n");
|
|
21989
21996
|
const interfaceLineIndex = lines.findIndex(
|
|
21990
|
-
(line) => line.match(
|
|
21997
|
+
(line) => line.match(
|
|
21998
|
+
new RegExp(`export\\s+${TYPE_OR_INTERFACE2}\\s+${interfaceName}`)
|
|
21999
|
+
)
|
|
21991
22000
|
);
|
|
21992
22001
|
if (interfaceLineIndex === -1) {
|
|
21993
22002
|
return "";
|
|
@@ -22013,7 +22022,9 @@ function extractComponentDescription2(content, interfaceName) {
|
|
|
22013
22022
|
return "";
|
|
22014
22023
|
}
|
|
22015
22024
|
function resolveUnionOrIntersectionProps2(content, typeName) {
|
|
22016
|
-
const typeDefRegex = new RegExp(
|
|
22025
|
+
const typeDefRegex = new RegExp(
|
|
22026
|
+
`export\\s+type\\s+${typeName}\\s*=\\s*([^;]+)`
|
|
22027
|
+
);
|
|
22017
22028
|
const match = content.match(typeDefRegex);
|
|
22018
22029
|
if (!match) return [];
|
|
22019
22030
|
const referencedTypes = match[1].split(/[|&]/).map((t) => t.trim()).filter((t) => t.endsWith("Props"));
|
|
@@ -22041,7 +22052,9 @@ function readChatKitTypesFile(filePath, componentName) {
|
|
|
22041
22052
|
return null;
|
|
22042
22053
|
}
|
|
22043
22054
|
const resolvedName = componentName || path9.basename(path9.dirname(filePath));
|
|
22044
|
-
const exactRegex = new RegExp(
|
|
22055
|
+
const exactRegex = new RegExp(
|
|
22056
|
+
`export\\s+${TYPE_OR_INTERFACE2}\\s+(${resolvedName}Props)\\b`
|
|
22057
|
+
);
|
|
22045
22058
|
let propsInterfaceMatch = content.match(exactRegex);
|
|
22046
22059
|
if (!propsInterfaceMatch) {
|
|
22047
22060
|
const prefixRegex = new RegExp(
|
|
@@ -22307,7 +22320,9 @@ async function startServer() {
|
|
|
22307
22320
|
server.tool(
|
|
22308
22321
|
"list_chat_kit_components",
|
|
22309
22322
|
"List all Chat Kit components. Optionally filter by name, category, or description.",
|
|
22310
|
-
{
|
|
22323
|
+
{
|
|
22324
|
+
filter: external_exports.string().optional().describe("Filter by name/category/description")
|
|
22325
|
+
},
|
|
22311
22326
|
async ({ filter }) => {
|
|
22312
22327
|
try {
|
|
22313
22328
|
const components = listChatKitComponents(filter);
|
|
@@ -22322,7 +22337,10 @@ async function startServer() {
|
|
|
22322
22337
|
},
|
|
22323
22338
|
{}
|
|
22324
22339
|
);
|
|
22325
|
-
const sections = [
|
|
22340
|
+
const sections = [
|
|
22341
|
+
`Found ${components.length} chat-kit component(s):`,
|
|
22342
|
+
""
|
|
22343
|
+
];
|
|
22326
22344
|
Object.entries(grouped).forEach(([category, comps]) => {
|
|
22327
22345
|
sections.push(`## ${category}`, "");
|
|
22328
22346
|
comps.forEach((comp) => {
|
|
@@ -22339,11 +22357,14 @@ async function startServer() {
|
|
|
22339
22357
|
server.tool(
|
|
22340
22358
|
"get_chat_kit_docs",
|
|
22341
22359
|
"Get full documentation for a Chat Kit component including props, examples, and usage.",
|
|
22342
|
-
{
|
|
22360
|
+
{
|
|
22361
|
+
componentName: external_exports.string().describe('Component name (e.g., "CkChatBubble" or "ChatBubble")')
|
|
22362
|
+
},
|
|
22343
22363
|
async ({ componentName }) => {
|
|
22344
22364
|
try {
|
|
22345
22365
|
const docs = getChatKitComponentDocs(componentName);
|
|
22346
|
-
if (!docs)
|
|
22366
|
+
if (!docs)
|
|
22367
|
+
return error2(`Chat Kit component "${componentName}" not found.`);
|
|
22347
22368
|
return text(formatComponentDocs(docs));
|
|
22348
22369
|
} catch (e) {
|
|
22349
22370
|
return handleError(e);
|
|
@@ -97,11 +97,15 @@ function detectCategoryDirs() {
|
|
|
97
97
|
return [];
|
|
98
98
|
}
|
|
99
99
|
const entries = fs3.readdirSync(srcPath, { withFileTypes: true });
|
|
100
|
-
return entries.filter((entry) => entry.isDirectory()).filter(
|
|
100
|
+
return entries.filter((entry) => entry.isDirectory()).filter(
|
|
101
|
+
(entry) => !entry.name.startsWith(".") && entry.name !== "node_modules"
|
|
102
|
+
).filter((entry) => {
|
|
101
103
|
try {
|
|
102
104
|
const dirPath = path2.join(srcPath, entry.name);
|
|
103
105
|
const subEntries = fs3.readdirSync(dirPath, { withFileTypes: true });
|
|
104
|
-
return subEntries.some(
|
|
106
|
+
return subEntries.some(
|
|
107
|
+
(sub) => sub.isDirectory() && sub.name.startsWith(COMPONENT_PREFIX)
|
|
108
|
+
);
|
|
105
109
|
} catch {
|
|
106
110
|
return false;
|
|
107
111
|
}
|
|
@@ -177,29 +181,11 @@ var __filename2 = fileURLToPath2(import.meta.url);
|
|
|
177
181
|
var __dirname2 = path3.dirname(__filename2);
|
|
178
182
|
var PACKAGE_ROOT = getPackageRoot();
|
|
179
183
|
var OUTPUT_PATH = path3.join(PACKAGE_ROOT, "components-meta.json");
|
|
180
|
-
var CHAT_KIT_OUTPUT_PATH = path3.join(
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
const declarationMatch = content.match(declarationRegex);
|
|
186
|
-
if (!declarationMatch || declarationMatch.index === void 0) {
|
|
187
|
-
return { description: "", useCases: [], keywords: [], related: [] };
|
|
188
|
-
}
|
|
189
|
-
const contentBefore = content.substring(0, declarationMatch.index);
|
|
190
|
-
const jsdocEndIndex = contentBefore.lastIndexOf("*/");
|
|
191
|
-
if (jsdocEndIndex === -1) {
|
|
192
|
-
return { description: "", useCases: [], keywords: [], related: [] };
|
|
193
|
-
}
|
|
194
|
-
const betweenJsdocAndDeclaration = contentBefore.substring(jsdocEndIndex + 2);
|
|
195
|
-
if (betweenJsdocAndDeclaration.trim() !== "") {
|
|
196
|
-
return { description: "", useCases: [], keywords: [], related: [] };
|
|
197
|
-
}
|
|
198
|
-
const jsdocStartIndex = contentBefore.lastIndexOf("/**");
|
|
199
|
-
if (jsdocStartIndex === -1 || jsdocStartIndex > jsdocEndIndex) {
|
|
200
|
-
return { description: "", useCases: [], keywords: [], related: [] };
|
|
201
|
-
}
|
|
202
|
-
const jsdoc = contentBefore.substring(jsdocStartIndex + 3, jsdocEndIndex);
|
|
184
|
+
var CHAT_KIT_OUTPUT_PATH = path3.join(
|
|
185
|
+
PACKAGE_ROOT,
|
|
186
|
+
"chat-kit-components-meta.json"
|
|
187
|
+
);
|
|
188
|
+
function parseJSDocBlock(jsdoc) {
|
|
203
189
|
const lines = jsdoc.split("\n").map((l) => l.replace(/^\s*\*\s?/, "").trim());
|
|
204
190
|
let description = "";
|
|
205
191
|
const useCases = [];
|
|
@@ -224,6 +210,51 @@ function extractJSDocTags(content, interfaceName) {
|
|
|
224
210
|
}
|
|
225
211
|
return { description, useCases, keywords, related, category };
|
|
226
212
|
}
|
|
213
|
+
function extractJSDocTags(content, interfaceName) {
|
|
214
|
+
const declarationRegex = new RegExp(
|
|
215
|
+
`export\\s+(?:interface|type)\\s+${escapeRegex(interfaceName)}\\b`
|
|
216
|
+
);
|
|
217
|
+
const declarationMatch = content.match(declarationRegex);
|
|
218
|
+
if (!declarationMatch || declarationMatch.index === void 0) {
|
|
219
|
+
return { description: "", useCases: [], keywords: [], related: [] };
|
|
220
|
+
}
|
|
221
|
+
const contentBefore = content.substring(0, declarationMatch.index);
|
|
222
|
+
const jsdocEndIndex = contentBefore.lastIndexOf("*/");
|
|
223
|
+
if (jsdocEndIndex === -1) {
|
|
224
|
+
return { description: "", useCases: [], keywords: [], related: [] };
|
|
225
|
+
}
|
|
226
|
+
const betweenJsdocAndDeclaration = contentBefore.substring(jsdocEndIndex + 2);
|
|
227
|
+
if (betweenJsdocAndDeclaration.trim() !== "") {
|
|
228
|
+
return { description: "", useCases: [], keywords: [], related: [] };
|
|
229
|
+
}
|
|
230
|
+
const jsdocStartIndex = contentBefore.lastIndexOf("/**");
|
|
231
|
+
if (jsdocStartIndex === -1 || jsdocStartIndex > jsdocEndIndex) {
|
|
232
|
+
return { description: "", useCases: [], keywords: [], related: [] };
|
|
233
|
+
}
|
|
234
|
+
const jsdoc = contentBefore.substring(jsdocStartIndex + 3, jsdocEndIndex);
|
|
235
|
+
return parseJSDocBlock(jsdoc);
|
|
236
|
+
}
|
|
237
|
+
function findBestJSDocSource(content, componentName, primaryInterfaceName) {
|
|
238
|
+
const primary = extractJSDocTags(content, primaryInterfaceName);
|
|
239
|
+
if (primary.category) return primary;
|
|
240
|
+
const propsRegex = new RegExp(
|
|
241
|
+
`export\\s+(?:interface|type)\\s+(${escapeRegex(componentName)}\\w*Props)\\b`,
|
|
242
|
+
"g"
|
|
243
|
+
);
|
|
244
|
+
let propsMatch;
|
|
245
|
+
while ((propsMatch = propsRegex.exec(content)) !== null) {
|
|
246
|
+
if (propsMatch[1] === primaryInterfaceName) continue;
|
|
247
|
+
const tags = extractJSDocTags(content, propsMatch[1]);
|
|
248
|
+
if (tags.category) return tags;
|
|
249
|
+
}
|
|
250
|
+
const blockRegex = /\/\*\*([\s\S]*?)\*\//g;
|
|
251
|
+
let blockMatch;
|
|
252
|
+
while ((blockMatch = blockRegex.exec(content)) !== null) {
|
|
253
|
+
const tags = parseJSDocBlock(blockMatch[1]);
|
|
254
|
+
if (tags.category) return tags;
|
|
255
|
+
}
|
|
256
|
+
return primary;
|
|
257
|
+
}
|
|
227
258
|
function extractKeywordsFromName(componentName) {
|
|
228
259
|
const name = componentName.replace(/^(?:Ui|Ck)/, "");
|
|
229
260
|
return name.replace(/([a-z])([A-Z])/g, "$1 $2").toLowerCase().split(/\s+/).filter((word) => word.length > 2);
|
|
@@ -265,15 +296,23 @@ function processComponent(componentDir, componentName) {
|
|
|
265
296
|
typesContent = fs4.readFileSync(typesPath, "utf-8");
|
|
266
297
|
}
|
|
267
298
|
const escapedName = escapeRegex(componentName);
|
|
268
|
-
const exactPropsRegex = new RegExp(
|
|
299
|
+
const exactPropsRegex = new RegExp(
|
|
300
|
+
`export\\s+(?:interface|type)\\s+(${escapedName}Props)\\b`
|
|
301
|
+
);
|
|
269
302
|
const exactMatch = typesContent.match(exactPropsRegex);
|
|
270
303
|
const subComponentPropsRegex = new RegExp(
|
|
271
304
|
`export\\s+(?:interface|type)\\s+(${escapedName}\\w*Props)\\b`
|
|
272
305
|
);
|
|
273
306
|
const subComponentMatch = typesContent.match(subComponentPropsRegex);
|
|
274
|
-
const anyPropsMatch = typesContent.match(
|
|
307
|
+
const anyPropsMatch = typesContent.match(
|
|
308
|
+
/export\s+(?:interface|type)\s+((?:Ui|Ck)\w+Props)/
|
|
309
|
+
);
|
|
275
310
|
const interfaceName = exactMatch?.[1] || subComponentMatch?.[1] || anyPropsMatch?.[1] || `${componentName}Props`;
|
|
276
|
-
const jsdocData =
|
|
311
|
+
const jsdocData = findBestJSDocSource(
|
|
312
|
+
typesContent,
|
|
313
|
+
componentName,
|
|
314
|
+
interfaceName
|
|
315
|
+
);
|
|
277
316
|
const nameKeywords = extractKeywordsFromName(componentName);
|
|
278
317
|
const keywords = jsdocData.keywords.length > 0 ? jsdocData.keywords : nameKeywords;
|
|
279
318
|
const category = jsdocData.category || "Uncategorized";
|
|
@@ -342,8 +381,12 @@ function scanChatKitComponents() {
|
|
|
342
381
|
}
|
|
343
382
|
function summarize(label, meta) {
|
|
344
383
|
const total = Object.keys(meta).length;
|
|
345
|
-
const withUseCases = Object.values(meta).filter(
|
|
346
|
-
|
|
384
|
+
const withUseCases = Object.values(meta).filter(
|
|
385
|
+
(m) => m.useCases.length > 0
|
|
386
|
+
).length;
|
|
387
|
+
const withKeywords = Object.values(meta).filter(
|
|
388
|
+
(m) => m.keywords.length > 0
|
|
389
|
+
).length;
|
|
347
390
|
console.log(`
|
|
348
391
|
${label} summary:`);
|
|
349
392
|
console.log(` Components with @useCases: ${withUseCases}/${total}`);
|
|
@@ -371,5 +414,7 @@ if (isMain) {
|
|
|
371
414
|
export {
|
|
372
415
|
extractJSDocTags,
|
|
373
416
|
extractKeywordsFromName,
|
|
374
|
-
extractProps
|
|
417
|
+
extractProps,
|
|
418
|
+
findBestJSDocSource,
|
|
419
|
+
parseJSDocBlock
|
|
375
420
|
};
|
package/dist/server.js
CHANGED
|
@@ -21313,11 +21313,15 @@ function detectCategoryDirs() {
|
|
|
21313
21313
|
return [];
|
|
21314
21314
|
}
|
|
21315
21315
|
const entries = fs3.readdirSync(srcPath, { withFileTypes: true });
|
|
21316
|
-
return entries.filter((entry) => entry.isDirectory()).filter(
|
|
21316
|
+
return entries.filter((entry) => entry.isDirectory()).filter(
|
|
21317
|
+
(entry) => !entry.name.startsWith(".") && entry.name !== "node_modules"
|
|
21318
|
+
).filter((entry) => {
|
|
21317
21319
|
try {
|
|
21318
21320
|
const dirPath = path3.join(srcPath, entry.name);
|
|
21319
21321
|
const subEntries = fs3.readdirSync(dirPath, { withFileTypes: true });
|
|
21320
|
-
return subEntries.some(
|
|
21322
|
+
return subEntries.some(
|
|
21323
|
+
(sub) => sub.isDirectory() && sub.name.startsWith(COMPONENT_PREFIX)
|
|
21324
|
+
);
|
|
21321
21325
|
} catch {
|
|
21322
21326
|
return false;
|
|
21323
21327
|
}
|
|
@@ -21858,7 +21862,10 @@ function parseInterface2(content, interfaceName) {
|
|
|
21858
21862
|
const propName = propMatch[2];
|
|
21859
21863
|
const isOptional = !!propMatch[3];
|
|
21860
21864
|
const typeStartIndex = propMatch.index + propMatch[0].length;
|
|
21861
|
-
const { type: propType, endIndex } = extractType2(
|
|
21865
|
+
const { type: propType, endIndex } = extractType2(
|
|
21866
|
+
interfaceBody,
|
|
21867
|
+
typeStartIndex
|
|
21868
|
+
);
|
|
21862
21869
|
propStartRegex.lastIndex = endIndex + 1;
|
|
21863
21870
|
const jsdoc = parseJSDoc2(jsdocComment);
|
|
21864
21871
|
props.push({
|
|
@@ -21875,7 +21882,9 @@ function parseInterface2(content, interfaceName) {
|
|
|
21875
21882
|
function extractComponentDescription2(content, interfaceName) {
|
|
21876
21883
|
const lines = content.split("\n");
|
|
21877
21884
|
const interfaceLineIndex = lines.findIndex(
|
|
21878
|
-
(line) => line.match(
|
|
21885
|
+
(line) => line.match(
|
|
21886
|
+
new RegExp(`export\\s+${TYPE_OR_INTERFACE2}\\s+${interfaceName}`)
|
|
21887
|
+
)
|
|
21879
21888
|
);
|
|
21880
21889
|
if (interfaceLineIndex === -1) {
|
|
21881
21890
|
return "";
|
|
@@ -21901,7 +21910,9 @@ function extractComponentDescription2(content, interfaceName) {
|
|
|
21901
21910
|
return "";
|
|
21902
21911
|
}
|
|
21903
21912
|
function resolveUnionOrIntersectionProps2(content, typeName) {
|
|
21904
|
-
const typeDefRegex = new RegExp(
|
|
21913
|
+
const typeDefRegex = new RegExp(
|
|
21914
|
+
`export\\s+type\\s+${typeName}\\s*=\\s*([^;]+)`
|
|
21915
|
+
);
|
|
21905
21916
|
const match = content.match(typeDefRegex);
|
|
21906
21917
|
if (!match) return [];
|
|
21907
21918
|
const referencedTypes = match[1].split(/[|&]/).map((t) => t.trim()).filter((t) => t.endsWith("Props"));
|
|
@@ -21929,7 +21940,9 @@ function readChatKitTypesFile(filePath, componentName) {
|
|
|
21929
21940
|
return null;
|
|
21930
21941
|
}
|
|
21931
21942
|
const resolvedName = componentName || path8.basename(path8.dirname(filePath));
|
|
21932
|
-
const exactRegex = new RegExp(
|
|
21943
|
+
const exactRegex = new RegExp(
|
|
21944
|
+
`export\\s+${TYPE_OR_INTERFACE2}\\s+(${resolvedName}Props)\\b`
|
|
21945
|
+
);
|
|
21933
21946
|
let propsInterfaceMatch = content.match(exactRegex);
|
|
21934
21947
|
if (!propsInterfaceMatch) {
|
|
21935
21948
|
const prefixRegex = new RegExp(
|
|
@@ -22195,7 +22208,9 @@ async function startServer() {
|
|
|
22195
22208
|
server.tool(
|
|
22196
22209
|
"list_chat_kit_components",
|
|
22197
22210
|
"List all Chat Kit components. Optionally filter by name, category, or description.",
|
|
22198
|
-
{
|
|
22211
|
+
{
|
|
22212
|
+
filter: external_exports.string().optional().describe("Filter by name/category/description")
|
|
22213
|
+
},
|
|
22199
22214
|
async ({ filter }) => {
|
|
22200
22215
|
try {
|
|
22201
22216
|
const components = listChatKitComponents(filter);
|
|
@@ -22210,7 +22225,10 @@ async function startServer() {
|
|
|
22210
22225
|
},
|
|
22211
22226
|
{}
|
|
22212
22227
|
);
|
|
22213
|
-
const sections = [
|
|
22228
|
+
const sections = [
|
|
22229
|
+
`Found ${components.length} chat-kit component(s):`,
|
|
22230
|
+
""
|
|
22231
|
+
];
|
|
22214
22232
|
Object.entries(grouped).forEach(([category, comps]) => {
|
|
22215
22233
|
sections.push(`## ${category}`, "");
|
|
22216
22234
|
comps.forEach((comp) => {
|
|
@@ -22227,11 +22245,14 @@ async function startServer() {
|
|
|
22227
22245
|
server.tool(
|
|
22228
22246
|
"get_chat_kit_docs",
|
|
22229
22247
|
"Get full documentation for a Chat Kit component including props, examples, and usage.",
|
|
22230
|
-
{
|
|
22248
|
+
{
|
|
22249
|
+
componentName: external_exports.string().describe('Component name (e.g., "CkChatBubble" or "ChatBubble")')
|
|
22250
|
+
},
|
|
22231
22251
|
async ({ componentName }) => {
|
|
22232
22252
|
try {
|
|
22233
22253
|
const docs = getChatKitComponentDocs(componentName);
|
|
22234
|
-
if (!docs)
|
|
22254
|
+
if (!docs)
|
|
22255
|
+
return error2(`Chat Kit component "${componentName}" not found.`);
|
|
22235
22256
|
return text(formatComponentDocs(docs));
|
|
22236
22257
|
} catch (e) {
|
|
22237
22258
|
return handleError(e);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aleph-alpha/lib-mcp",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/server.js",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"@aleph-alpha/tsconfig-frontend": "0.6.0"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@aleph-alpha/
|
|
40
|
-
"@aleph-alpha/
|
|
39
|
+
"@aleph-alpha/ui-library": "2.6.2",
|
|
40
|
+
"@aleph-alpha/chat-kit": "1.11.1"
|
|
41
41
|
},
|
|
42
42
|
"homepage": "https://docs.aleph-alpha.com",
|
|
43
43
|
"scripts": {
|