sv5ui-plus 5.0.4 → 5.0.6
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 +6 -6
- package/dist/adapters/notify.d.ts +1 -1
- package/dist/adapters/notify.js +18 -18
- package/dist/compat.d.ts +2 -2
- package/dist/compat.js +2 -2
- package/dist/components/BentoGrid/BentoCard.svelte +33 -33
- package/dist/components/BentoGrid/BentoCard.svelte.d.ts +1 -1
- package/dist/components/BentoGrid/BentoGrid.svelte +1 -1
- package/dist/components/BentoGrid/BentoGrid.svelte.d.ts +1 -1
- package/dist/components/BentoGrid/bento-grid.types.d.ts +2 -2
- package/dist/components/BentoGrid/bento-grid.variants.d.ts +1 -1
- package/dist/components/BentoGrid/bento-grid.variants.js +10 -10
- package/dist/components/BentoGrid/index.d.ts +4 -4
- package/dist/components/BentoGrid/index.js +4 -4
- package/dist/components/Chart/Chart.svelte +1 -1
- package/dist/components/Chart/Chart.svelte.d.ts +1 -1
- package/dist/components/Chart/chart.types.d.ts +3 -3
- package/dist/components/Chart/index.d.ts +2 -2
- package/dist/components/Chart/index.js +2 -2
- package/dist/components/Chat/ChatBubble.svelte +19 -19
- package/dist/components/Chat/ChatBubble.svelte.d.ts +1 -1
- package/dist/components/Chat/ChatInput.svelte +26 -27
- package/dist/components/Chat/ChatInput.svelte.d.ts +1 -1
- package/dist/components/Chat/ChatMessage.svelte +1 -1
- package/dist/components/Chat/ChatMessage.svelte.d.ts +1 -1
- package/dist/components/Chat/chat.types.d.ts +6 -6
- package/dist/components/Chat/chat.variants.d.ts +1 -1
- package/dist/components/Chat/chat.variants.js +29 -29
- package/dist/components/Chat/index.d.ts +5 -5
- package/dist/components/Chat/index.js +5 -5
- package/dist/components/CodeBlock/CodeBlock.svelte +15 -15
- package/dist/components/CodeBlock/CodeBlock.svelte.d.ts +1 -1
- package/dist/components/CodeBlock/code-block.types.d.ts +5 -5
- package/dist/components/CodeBlock/code-block.variants.d.ts +1 -1
- package/dist/components/CodeBlock/code-block.variants.js +40 -40
- package/dist/components/CodeBlock/index.d.ts +2 -2
- package/dist/components/CodeBlock/index.js +1 -1
- package/dist/components/ConfirmDialog/ConfirmDialog.svelte +93 -97
- package/dist/components/ConfirmDialog/ConfirmDialog.svelte.d.ts +1 -1
- package/dist/components/ConfirmDialog/confirm.d.ts +1 -1
- package/dist/components/ConfirmDialog/confirm.js +9 -9
- package/dist/components/ConfirmDialog/confirm.types.d.ts +4 -4
- package/dist/components/ConfirmDialog/index.d.ts +4 -4
- package/dist/components/ConfirmDialog/index.js +2 -2
- package/dist/components/DatePickerField/DatePickerField.svelte +11 -11
- package/dist/components/DatePickerField/DatePickerField.svelte.d.ts +2 -2
- package/dist/components/DatePickerField/date-picker-field.types.d.ts +1 -1
- package/dist/components/DatePickerField/index.d.ts +2 -2
- package/dist/components/DatePickerField/index.js +1 -1
- package/dist/components/DateRangePickerField/DateRangePickerField.svelte +26 -26
- package/dist/components/DateRangePickerField/DateRangePickerField.svelte.d.ts +2 -2
- package/dist/components/DateRangePickerField/date-range-picker-field.types.d.ts +1 -1
- package/dist/components/DateRangePickerField/index.d.ts +2 -2
- package/dist/components/DateRangePickerField/index.js +1 -1
- package/dist/components/Fonts/Fonts.svelte +12 -12
- package/dist/components/Fonts/Fonts.svelte.d.ts +1 -1
- package/dist/components/Fonts/fonts.d.ts +1 -1
- package/dist/components/Fonts/fonts.js +42 -42
- package/dist/components/Fonts/fonts.types.d.ts +6 -6
- package/dist/components/Fonts/index.d.ts +3 -3
- package/dist/components/Fonts/index.js +2 -2
- package/dist/components/FormSelect/FormSelect.svelte +4 -4
- package/dist/components/FormSelect/FormSelect.svelte.d.ts +2 -2
- package/dist/components/FormSelect/form-select.types.d.ts +3 -3
- package/dist/components/FormSelect/index.d.ts +2 -2
- package/dist/components/FormSelect/index.js +1 -1
- package/dist/components/List/List.svelte +1 -1
- package/dist/components/List/List.svelte.d.ts +1 -1
- package/dist/components/List/ListItem.svelte +31 -39
- package/dist/components/List/ListItem.svelte.d.ts +1 -1
- package/dist/components/List/index.d.ts +4 -4
- package/dist/components/List/index.js +4 -4
- package/dist/components/List/list.types.d.ts +4 -4
- package/dist/components/List/list.variants.d.ts +1 -1
- package/dist/components/List/list.variants.js +22 -22
- package/dist/components/LocaleButton/LocaleButton.svelte +104 -108
- package/dist/components/LocaleButton/LocaleButton.svelte.d.ts +1 -1
- package/dist/components/LocaleButton/index.d.ts +2 -2
- package/dist/components/LocaleButton/index.js +1 -1
- package/dist/components/LocaleButton/locale-button.types.d.ts +12 -12
- package/dist/components/LocaleButton/locale-button.variants.d.ts +2 -2
- package/dist/components/LocaleButton/locale-button.variants.js +68 -68
- package/dist/components/Marquee/Marquee.svelte +34 -34
- package/dist/components/Marquee/Marquee.svelte.d.ts +1 -1
- package/dist/components/Marquee/index.d.ts +3 -3
- package/dist/components/Marquee/index.js +3 -3
- package/dist/components/Marquee/marquee.types.d.ts +4 -4
- package/dist/components/Marquee/marquee.variants.d.ts +1 -1
- package/dist/components/Marquee/marquee.variants.js +15 -15
- package/dist/components/NavigationMenu/NavigationMenu.svelte +366 -379
- package/dist/components/NavigationMenu/NavigationMenu.svelte.d.ts +1 -1
- package/dist/components/NavigationMenu/index.d.ts +2 -2
- package/dist/components/NavigationMenu/index.js +1 -1
- package/dist/components/NavigationMenu/navigation-menu.types.d.ts +17 -17
- package/dist/components/NavigationMenu/navigation-menu.variants.d.ts +1 -1
- package/dist/components/NavigationMenu/navigation-menu.variants.js +177 -177
- package/dist/components/NumberTicker/NumberTicker.svelte +1 -5
- package/dist/components/NumberTicker/NumberTicker.svelte.d.ts +1 -1
- package/dist/components/NumberTicker/index.d.ts +3 -3
- package/dist/components/NumberTicker/index.js +3 -3
- package/dist/components/NumberTicker/number-ticker.types.d.ts +1 -1
- package/dist/components/NumberTicker/number-ticker.variants.d.ts +1 -1
- package/dist/components/NumberTicker/number-ticker.variants.js +3 -3
- package/dist/components/PasswordInput/PasswordInput.svelte +58 -58
- package/dist/components/PasswordInput/PasswordInput.svelte.d.ts +1 -1
- package/dist/components/PasswordInput/index.d.ts +2 -2
- package/dist/components/PasswordInput/index.js +1 -1
- package/dist/components/PasswordInput/password-input.types.d.ts +9 -9
- package/dist/components/PasswordInput/password-input.variants.d.ts +2 -2
- package/dist/components/PasswordInput/password-input.variants.js +62 -62
- package/dist/components/Prose/Prose.svelte +5 -5
- package/dist/components/Prose/Prose.svelte.d.ts +1 -1
- package/dist/components/Prose/index.d.ts +3 -3
- package/dist/components/Prose/index.js +3 -3
- package/dist/components/Prose/prose.types.d.ts +4 -4
- package/dist/components/Prose/prose.variants.d.ts +1 -1
- package/dist/components/Prose/prose.variants.js +27 -27
- package/dist/components/{Resizable/Resizable.svelte → ResizeContainer/ResizeContainer.svelte} +3 -3
- package/dist/components/ResizeContainer/ResizeContainer.svelte.d.ts +4 -0
- package/dist/components/ResizeContainer/index.d.ts +4 -0
- package/dist/components/ResizeContainer/index.js +4 -0
- package/dist/components/ResizeContainer/resize-container.types.d.ts +18 -0
- package/dist/components/ResizeContainer/resize-container.variants.d.ts +30 -0
- package/dist/components/ResizeContainer/resize-container.variants.js +17 -0
- package/dist/components/SafeTable/SafeTable.svelte +74 -74
- package/dist/components/SafeTable/SafeTable.svelte.d.ts +2 -2
- package/dist/components/SafeTable/index.d.ts +2 -2
- package/dist/components/SafeTable/index.js +1 -1
- package/dist/components/SafeTable/safe-table.types.d.ts +1 -1
- package/dist/components/Search/Search.svelte +63 -63
- package/dist/components/Search/Search.svelte.d.ts +1 -1
- package/dist/components/Search/index.d.ts +2 -2
- package/dist/components/Search/index.js +1 -1
- package/dist/components/Search/search.types.d.ts +5 -5
- package/dist/components/SortableGroup/SortableGroup.svelte +16 -10
- package/dist/components/SortableGroup/SortableGroup.svelte.d.ts +3 -3
- package/dist/components/SortableGroup/index.d.ts +1 -1
- package/dist/components/SortableGroup/index.js +1 -1
- package/dist/components/SortableList/SortableList.svelte +49 -46
- package/dist/components/SortableList/SortableList.svelte.d.ts +2 -2
- package/dist/components/SortableList/index.d.ts +2 -2
- package/dist/components/SortableList/index.js +1 -1
- package/dist/components/SortableList/sortable-list.types.d.ts +3 -3
- package/dist/components/Spotlight/Spotlight.svelte +13 -13
- package/dist/components/Spotlight/Spotlight.svelte.d.ts +1 -1
- package/dist/components/Spotlight/index.d.ts +3 -3
- package/dist/components/Spotlight/index.js +3 -3
- package/dist/components/Spotlight/spotlight.types.d.ts +2 -2
- package/dist/components/Spotlight/spotlight.variants.d.ts +1 -1
- package/dist/components/Spotlight/spotlight.variants.js +5 -5
- package/dist/components/TableBulkActionBar/TableBulkActionBar.svelte +23 -23
- package/dist/components/TableBulkActionBar/TableBulkActionBar.svelte.d.ts +1 -1
- package/dist/components/TableBulkActionBar/index.d.ts +2 -2
- package/dist/components/TableBulkActionBar/index.js +1 -1
- package/dist/components/TableBulkActionBar/table-bulk-action-bar.types.d.ts +3 -3
- package/dist/components/TableBulkActionBar/table-bulk-action-bar.variants.d.ts +1 -1
- package/dist/components/TableBulkActionBar/table-bulk-action-bar.variants.js +7 -7
- package/dist/components/TreeView/TreeView.svelte +59 -59
- package/dist/components/TreeView/TreeView.svelte.d.ts +1 -1
- package/dist/components/TreeView/index.d.ts +3 -3
- package/dist/components/TreeView/index.js +2 -2
- package/dist/components/TreeView/tree-view.types.d.ts +4 -4
- package/dist/components/TreeView/tree-view.variants.d.ts +1 -1
- package/dist/components/TreeView/tree-view.variants.js +19 -19
- package/dist/config.d.ts +1 -1
- package/dist/config.js +28 -28
- package/dist/editor.d.ts +1 -1
- package/dist/editor.js +1 -1
- package/dist/form/resolve-form-field-name.js +1 -1
- package/dist/hooks/internal/DragDropProviderScope.svelte +1 -1
- package/dist/hooks/internal/DragDropProviderScope.svelte.d.ts +1 -1
- package/dist/hooks/internal/SortableProvider.svelte +16 -11
- package/dist/hooks/internal/SortableProvider.svelte.d.ts +1 -1
- package/dist/hooks/internal/drag-drop-context.d.ts +1 -1
- package/dist/hooks/internal/drag-drop-context.js +1 -1
- package/dist/hooks/internal/sortable-context.d.ts +6 -6
- package/dist/hooks/internal/sortable-context.js +2 -2
- package/dist/hooks/useDragDrop/index.d.ts +1 -1
- package/dist/hooks/useDragDrop/index.js +1 -1
- package/dist/hooks/useDragDrop/useDragDrop.svelte.d.ts +3 -3
- package/dist/hooks/useDragDrop/useDragDrop.svelte.js +15 -15
- package/dist/hooks/useSortable/index.d.ts +2 -2
- package/dist/hooks/useSortable/index.js +2 -2
- package/dist/hooks/useSortable/useSortable.svelte.d.ts +4 -4
- package/dist/hooks/useSortable/useSortable.svelte.js +23 -23
- package/dist/hooks/utils.js +1 -1
- package/dist/index.d.ts +29 -31
- package/dist/index.js +28 -30
- package/dist/mcp/install-template.mjs +44 -44
- package/dist/mcp/server.mjs +262 -263
- package/dist/mcp/sv5ui-plus-docs.data.json +4 -10
- package/package.json +17 -14
- package/dist/components/ColorPicker/ColorPicker.svelte +0 -109
- package/dist/components/ColorPicker/ColorPicker.svelte.d.ts +0 -4
- package/dist/components/ColorPicker/color-picker.types.d.ts +0 -26
- package/dist/components/ColorPicker/color-picker.variants.d.ts +0 -69
- package/dist/components/ColorPicker/color-picker.variants.js +0 -13
- package/dist/components/ColorPicker/index.d.ts +0 -4
- package/dist/components/ColorPicker/index.js +0 -4
- package/dist/components/Resizable/Resizable.svelte.d.ts +0 -4
- package/dist/components/Resizable/index.d.ts +0 -4
- package/dist/components/Resizable/index.js +0 -4
- package/dist/components/Resizable/resizable.types.d.ts +0 -18
- package/dist/components/Resizable/resizable.types.js +0 -1
- package/dist/components/Resizable/resizable.variants.d.ts +0 -48
- package/dist/components/Resizable/resizable.variants.js +0 -17
- package/dist/components/ScrollArea/ScrollArea.svelte +0 -54
- package/dist/components/ScrollArea/ScrollArea.svelte.d.ts +0 -4
- package/dist/components/ScrollArea/index.d.ts +0 -4
- package/dist/components/ScrollArea/index.js +0 -4
- package/dist/components/ScrollArea/scroll-area.types.d.ts +0 -27
- package/dist/components/ScrollArea/scroll-area.types.js +0 -1
- package/dist/components/ScrollArea/scroll-area.variants.d.ts +0 -45
- package/dist/components/ScrollArea/scroll-area.variants.js +0 -27
- /package/dist/components/{ColorPicker/color-picker.types.js → ResizeContainer/resize-container.types.js} +0 -0
package/dist/mcp/server.mjs
CHANGED
|
@@ -1,338 +1,337 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { readFile } from
|
|
4
|
-
import path from
|
|
5
|
-
import { fileURLToPath } from
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
6
|
|
|
7
|
-
import { McpServer } from
|
|
8
|
-
import { StdioServerTransport } from
|
|
9
|
-
import { codeToHtml } from
|
|
10
|
-
import { z } from
|
|
7
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
9
|
+
import { codeToHtml } from "shiki";
|
|
10
|
+
import { z } from "zod";
|
|
11
11
|
|
|
12
|
-
const __filename = fileURLToPath(import.meta.url)
|
|
13
|
-
const __dirname = path.dirname(__filename)
|
|
14
|
-
const repoRoot = path.resolve(__dirname,
|
|
15
|
-
const packagedDataPath = path.resolve(__dirname,
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = path.dirname(__filename);
|
|
14
|
+
const repoRoot = path.resolve(__dirname, "../../");
|
|
15
|
+
const packagedDataPath = path.resolve(__dirname, "./sv5ui-plus-docs.data.json");
|
|
16
16
|
|
|
17
|
-
let packagedDataPromise
|
|
17
|
+
let packagedDataPromise;
|
|
18
18
|
|
|
19
19
|
function resolveRepoPath(relativePath) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
const fullPath = path.resolve(repoRoot, relativePath);
|
|
21
|
+
if (!fullPath.startsWith(repoRoot)) {
|
|
22
|
+
throw new Error("Invalid path");
|
|
23
|
+
}
|
|
24
|
+
return fullPath;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
async function readJsonIfExists(filePath) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
try {
|
|
29
|
+
const source = await readFile(filePath, "utf8");
|
|
30
|
+
return JSON.parse(source);
|
|
31
|
+
} catch (error) {
|
|
32
|
+
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
async function getPackagedData() {
|
|
40
|
-
|
|
41
|
-
|
|
40
|
+
packagedDataPromise ??= readJsonIfExists(packagedDataPath);
|
|
41
|
+
return await packagedDataPromise;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
function normalizeCode(code) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
45
|
+
const lines = code.replaceAll("\r\n", "\n").split("\n");
|
|
46
|
+
const firstNonEmpty = lines.findIndex((line) => line.trim().length > 0);
|
|
47
|
+
if (firstNonEmpty === -1) return "";
|
|
48
|
+
|
|
49
|
+
let lastNonEmptyFromEnd = 0;
|
|
50
|
+
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
51
|
+
if (lines[index].trim().length > 0) break;
|
|
52
|
+
lastNonEmptyFromEnd += 1;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const trimmed = lines.slice(firstNonEmpty, lines.length - lastNonEmptyFromEnd);
|
|
56
|
+
const indents = trimmed
|
|
57
|
+
.filter((line) => line.trim().length > 0)
|
|
58
|
+
.map((line) => line.match(/^(\s*)/)?.[1].length ?? 0);
|
|
59
|
+
|
|
60
|
+
const minIndent = indents.length > 0 ? Math.min(...indents) : 0;
|
|
61
|
+
return trimmed
|
|
62
|
+
.map((line) => line.slice(minIndent))
|
|
63
|
+
.join("\n")
|
|
64
|
+
.trim();
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
function unwrapPreviewWrappers(source) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
return current
|
|
68
|
+
let current = source.trim();
|
|
69
|
+
|
|
70
|
+
const stripPrefix = (token) => token.split(":").at(-1) ?? token;
|
|
71
|
+
const isPresentationToken = (token) => {
|
|
72
|
+
const t = stripPrefix(token);
|
|
73
|
+
if (t.length === 0) return false;
|
|
74
|
+
|
|
75
|
+
if (t.startsWith("max-w-") || t.startsWith("min-w-") || t.startsWith("w-")) return true;
|
|
76
|
+
if (t.startsWith("max-h-") || t.startsWith("min-h-") || t.startsWith("h-")) return true;
|
|
77
|
+
if (/^(m|p)[trblxyse]?-\d+$/.test(t)) return true;
|
|
78
|
+
if (t.startsWith("gap-") || t.startsWith("space-")) return true;
|
|
79
|
+
if (t.startsWith("overflow-")) return true;
|
|
80
|
+
if (t === "grid" || t.startsWith("grid-")) return true;
|
|
81
|
+
if (t === "flex" || t === "inline-flex" || t.startsWith("flex-")) return true;
|
|
82
|
+
if (t.startsWith("items-") || t.startsWith("justify-") || t.startsWith("content-")) return true;
|
|
83
|
+
if (t.startsWith("self-") || t.startsWith("place-")) return true;
|
|
84
|
+
if (t.startsWith("rounded")) return true;
|
|
85
|
+
if (t.startsWith("border") || t.startsWith("ring") || t.startsWith("shadow")) return true;
|
|
86
|
+
if (t === "bg-transparent") return true;
|
|
87
|
+
if (t.startsWith("bg-surface")) return true;
|
|
88
|
+
if (t.startsWith("bg-[")) return true;
|
|
89
|
+
if (t.startsWith("text-") || t.startsWith("font-") || t.startsWith("leading-")) return true;
|
|
90
|
+
if (t.startsWith("tracking-")) return true;
|
|
91
|
+
if (t === "uppercase" || t === "lowercase" || t === "capitalize") return true;
|
|
92
|
+
if (t.startsWith("opacity-")) return true;
|
|
93
|
+
if (t.startsWith("backdrop-blur") || t.startsWith("blur")) return true;
|
|
94
|
+
if (t.startsWith("aspect-") || t.startsWith("object-")) return true;
|
|
95
|
+
if (t.startsWith("size-")) return true;
|
|
96
|
+
if (t.startsWith("[") && t.includes("]:")) return true;
|
|
97
|
+
|
|
98
|
+
return false;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
for (let pass = 0; pass < 3; pass += 1) {
|
|
102
|
+
const match = current.match(/^<div\b([^>]*)>([\s\S]*)<\/div>$/);
|
|
103
|
+
if (!match) break;
|
|
104
|
+
|
|
105
|
+
const attrs = match[1];
|
|
106
|
+
const attrsWithoutClass = attrs
|
|
107
|
+
.replace(/\s*\bclass=(?:"[^"]*"|'[^']*')/, "")
|
|
108
|
+
.replace(/\s+/g, " ")
|
|
109
|
+
.trim();
|
|
110
|
+
if (attrsWithoutClass.length > 0) break;
|
|
111
|
+
|
|
112
|
+
const classMatch = attrs.match(/\bclass=(?:"([^"]*)"|'([^']*)')/);
|
|
113
|
+
const classValue = (classMatch?.[1] ?? classMatch?.[2] ?? "").trim();
|
|
114
|
+
const tokens = classValue.length > 0 ? classValue.split(/\s+/) : [];
|
|
115
|
+
|
|
116
|
+
const isPreviewBg = tokens.some((token) => token.startsWith("bg-surface-container"));
|
|
117
|
+
const isBordered = tokens.some((token) => token.startsWith("border-outline-variant"));
|
|
118
|
+
const isRounded = tokens.some((token) => token.startsWith("rounded"));
|
|
119
|
+
const hasPadding = tokens.some((token) => /^p[trblxy]?-\d+$/.test(token));
|
|
120
|
+
const isMaxWidth = tokens.some((token) => token.startsWith("max-w-"));
|
|
121
|
+
const isOverflow = tokens.some((token) => token.startsWith("overflow-"));
|
|
122
|
+
const isPresentationOnly = tokens.length > 0 && tokens.every(isPresentationToken);
|
|
123
|
+
|
|
124
|
+
const shouldUnwrap = ((isPreviewBg || isBordered || isRounded) && hasPadding) || isOverflow;
|
|
125
|
+
const shouldUnwrapMaxWidth = isMaxWidth && isPresentationOnly;
|
|
126
|
+
|
|
127
|
+
if (!shouldUnwrap && !shouldUnwrapMaxWidth) break;
|
|
128
|
+
|
|
129
|
+
current = match[2].trim();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return current;
|
|
134
133
|
}
|
|
135
134
|
|
|
136
135
|
function decodeHeading(value) {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
136
|
+
return value
|
|
137
|
+
.replaceAll("&", "&")
|
|
138
|
+
.replaceAll("×", "×")
|
|
139
|
+
.replaceAll("'", "'")
|
|
140
|
+
.replaceAll(""", '"')
|
|
141
|
+
.trim();
|
|
143
142
|
}
|
|
144
143
|
|
|
145
144
|
function extractSectionHeading(sectionSource) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
const match = sectionSource.match(/<h2\b[^>]*>([\s\S]*?)<\/h2>/);
|
|
146
|
+
if (!match) return "";
|
|
147
|
+
return decodeHeading(match[1].replace(/<[^>]+>/g, " "));
|
|
149
148
|
}
|
|
150
149
|
|
|
151
150
|
function extractSectionSnippet(sectionSource) {
|
|
152
|
-
|
|
153
|
-
|
|
151
|
+
const openTagEnd = sectionSource.indexOf(">");
|
|
152
|
+
const closeTagStart = sectionSource.lastIndexOf("</section>");
|
|
154
153
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
154
|
+
if (openTagEnd < 0 || closeTagStart < 0) {
|
|
155
|
+
return normalizeCode(sectionSource);
|
|
156
|
+
}
|
|
158
157
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
158
|
+
let inner = sectionSource.slice(openTagEnd + 1, closeTagStart);
|
|
159
|
+
inner = inner.replace(/^\s*<h2\b[\s\S]*?<\/h2>\s*/, "");
|
|
160
|
+
inner = inner.replace(/^\s*<!--[\s\S]*?-->\s*/g, "");
|
|
162
161
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
162
|
+
while (/^\s*<p\b[\s\S]*?<\/p>\s*/.test(inner)) {
|
|
163
|
+
inner = inner.replace(/^\s*<p\b[\s\S]*?<\/p>\s*/, "");
|
|
164
|
+
}
|
|
166
165
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
166
|
+
inner = inner.replace(/\s*<!--[\s\S]*?-->\s*$/g, "");
|
|
167
|
+
inner = unwrapPreviewWrappers(inner);
|
|
168
|
+
return normalizeCode(inner);
|
|
170
169
|
}
|
|
171
170
|
|
|
172
171
|
function getSectionSnippets(source) {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
172
|
+
return [...source.matchAll(/<section\b[\s\S]*?<\/section>/g)].map((match) => {
|
|
173
|
+
const sectionSource = match[0];
|
|
174
|
+
return {
|
|
175
|
+
heading: extractSectionHeading(sectionSource),
|
|
176
|
+
snippet: extractSectionSnippet(sectionSource),
|
|
177
|
+
};
|
|
178
|
+
});
|
|
180
179
|
}
|
|
181
180
|
|
|
182
181
|
function detectLanguage(code) {
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
182
|
+
const source = code.trim();
|
|
183
|
+
|
|
184
|
+
if (
|
|
185
|
+
source.includes('<script lang="ts">') ||
|
|
186
|
+
source.includes("$state(") ||
|
|
187
|
+
source.includes("{#each") ||
|
|
188
|
+
source.includes("<Button") ||
|
|
189
|
+
source.includes("<FormField")
|
|
190
|
+
) {
|
|
191
|
+
return "svelte";
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
if (source.startsWith("{") || source.startsWith("[")) {
|
|
195
|
+
return "json";
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if (
|
|
199
|
+
source.startsWith("@import") ||
|
|
200
|
+
(source.includes("{") && source.includes(":") && source.includes(";"))
|
|
201
|
+
) {
|
|
202
|
+
return "css";
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
if (source.startsWith("#") || source.startsWith("bun ") || source.startsWith("npm ")) {
|
|
206
|
+
return "bash";
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (source.includes("export ") || source.includes("import ") || source.includes("interface ")) {
|
|
210
|
+
return "ts";
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return "html";
|
|
215
214
|
}
|
|
216
215
|
|
|
217
216
|
function decorateHighlightedHtml(html) {
|
|
218
|
-
|
|
217
|
+
return html.replace(/<pre class="shiki[\s\S]*?"[^>]*>/, '<pre class="shiki">');
|
|
219
218
|
}
|
|
220
219
|
|
|
221
220
|
async function renderHighlightedCode(code, isDarkMode = true) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
221
|
+
const html = await codeToHtml(code, {
|
|
222
|
+
lang: detectLanguage(code),
|
|
223
|
+
theme: isDarkMode ? "github-dark" : "github-light",
|
|
224
|
+
});
|
|
225
|
+
return decorateHighlightedHtml(html);
|
|
227
226
|
}
|
|
228
227
|
|
|
229
228
|
function getPagePathFromSlug(slug) {
|
|
230
|
-
|
|
229
|
+
return `src/routes/${slug}/+page.svelte`;
|
|
231
230
|
}
|
|
232
231
|
|
|
233
232
|
async function readRouteSource(slug) {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
233
|
+
const packagedData = await getPackagedData();
|
|
234
|
+
if (packagedData?.pages?.[slug]) {
|
|
235
|
+
return packagedData.pages[slug];
|
|
236
|
+
}
|
|
238
237
|
|
|
239
|
-
|
|
240
|
-
|
|
238
|
+
const filePath = resolveRepoPath(getPagePathFromSlug(slug));
|
|
239
|
+
return await readFile(filePath, "utf8");
|
|
241
240
|
}
|
|
242
241
|
|
|
243
242
|
async function readDocsNavigationSource() {
|
|
244
|
-
|
|
245
|
-
|
|
243
|
+
const filePath = resolveRepoPath("src/internal/docs/navigation.ts");
|
|
244
|
+
return await readFile(filePath, "utf8");
|
|
246
245
|
}
|
|
247
246
|
|
|
248
247
|
async function listDocSlugs() {
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
248
|
+
const packagedData = await getPackagedData();
|
|
249
|
+
if (packagedData?.slugs) {
|
|
250
|
+
return packagedData.slugs;
|
|
251
|
+
}
|
|
253
252
|
|
|
254
|
-
|
|
255
|
-
|
|
253
|
+
const navigationSource = await readDocsNavigationSource();
|
|
254
|
+
return extractDocSlugs(navigationSource);
|
|
256
255
|
}
|
|
257
256
|
|
|
258
257
|
function extractDocSlugs(navigationSource) {
|
|
259
|
-
|
|
260
|
-
|
|
258
|
+
const componentSlugs = [];
|
|
259
|
+
const hookSlugs = [];
|
|
261
260
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
261
|
+
for (const match of navigationSource.matchAll(/href:\s*'\/docs\/components\/([^']+)'/g)) {
|
|
262
|
+
componentSlugs.push(match[1]);
|
|
263
|
+
}
|
|
265
264
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
265
|
+
for (const match of navigationSource.matchAll(/href:\s*'\/docs\/hooks\/([^']+)'/g)) {
|
|
266
|
+
hookSlugs.push(match[1]);
|
|
267
|
+
}
|
|
269
268
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
269
|
+
return {
|
|
270
|
+
components: Array.from(new Set(componentSlugs)),
|
|
271
|
+
hooks: Array.from(new Set(hookSlugs)),
|
|
272
|
+
};
|
|
274
273
|
}
|
|
275
274
|
|
|
276
275
|
const server = new McpServer({
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
})
|
|
276
|
+
name: "sv5ui-plus-docs",
|
|
277
|
+
version: "0.1.0",
|
|
278
|
+
});
|
|
280
279
|
|
|
281
280
|
server.tool(
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
)
|
|
281
|
+
"sv5ui_plus_docs_list_slugs",
|
|
282
|
+
"List docs slugs from src/internal/docs/navigation.ts (components + hooks)",
|
|
283
|
+
{},
|
|
284
|
+
async () => {
|
|
285
|
+
const slugs = await listDocSlugs();
|
|
286
|
+
|
|
287
|
+
return {
|
|
288
|
+
content: [
|
|
289
|
+
{
|
|
290
|
+
type: "text",
|
|
291
|
+
text: JSON.stringify(slugs, null, 2),
|
|
292
|
+
},
|
|
293
|
+
],
|
|
294
|
+
};
|
|
295
|
+
},
|
|
296
|
+
);
|
|
298
297
|
|
|
299
298
|
server.tool(
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
)
|
|
299
|
+
"sv5ui_plus_docs_get_page_source",
|
|
300
|
+
"Read src/routes/[slug]/+page.svelte and return as text",
|
|
301
|
+
{
|
|
302
|
+
slug: z.string().min(1).describe("Route slug, e.g. button, select-menu, use-form-field"),
|
|
303
|
+
},
|
|
304
|
+
async ({ slug }) => {
|
|
305
|
+
const source = await readRouteSource(slug);
|
|
306
|
+
return { content: [{ type: "text", text: source }] };
|
|
307
|
+
},
|
|
308
|
+
);
|
|
310
309
|
|
|
311
310
|
server.tool(
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
)
|
|
311
|
+
"sv5ui_plus_docs_get_section_snippets",
|
|
312
|
+
"Extract all <section> headings and code snippets from a route page source",
|
|
313
|
+
{
|
|
314
|
+
slug: z.string().min(1).describe("Route slug, e.g. button, select-menu, use-form-field"),
|
|
315
|
+
},
|
|
316
|
+
async ({ slug }) => {
|
|
317
|
+
const source = await readRouteSource(slug);
|
|
318
|
+
const sections = getSectionSnippets(source);
|
|
319
|
+
return { content: [{ type: "text", text: JSON.stringify(sections, null, 2) }] };
|
|
320
|
+
},
|
|
321
|
+
);
|
|
323
322
|
|
|
324
323
|
server.tool(
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
)
|
|
336
|
-
|
|
337
|
-
const transport = new StdioServerTransport()
|
|
338
|
-
await server.connect(transport)
|
|
324
|
+
"sv5ui_plus_docs_render_shiki",
|
|
325
|
+
'Render highlighted HTML (Shiki) for a code snippet. Returns <pre class="shiki">...</pre> HTML',
|
|
326
|
+
{
|
|
327
|
+
code: z.string().min(1).describe("Code string"),
|
|
328
|
+
isDarkMode: z.boolean().optional().describe("Use dark theme when true"),
|
|
329
|
+
},
|
|
330
|
+
async ({ code, isDarkMode }) => {
|
|
331
|
+
const html = await renderHighlightedCode(code, isDarkMode ?? true);
|
|
332
|
+
return { content: [{ type: "text", text: html }] };
|
|
333
|
+
},
|
|
334
|
+
);
|
|
335
|
+
|
|
336
|
+
const transport = new StdioServerTransport();
|
|
337
|
+
await server.connect(transport);
|