@seed-ship/mcp-ui-solid 6.19.1 → 6.20.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/CHANGELOG.md +519 -0
- package/README.md +791 -1
- package/dist/adapters/connector.cjs +15 -4
- package/dist/adapters/connector.cjs.map +1 -1
- package/dist/adapters/connector.d.ts +38 -0
- package/dist/adapters/connector.d.ts.map +1 -1
- package/dist/adapters/connector.js +15 -4
- package/dist/adapters/connector.js.map +1 -1
- package/dist/adapters/index.d.ts +4 -3
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/macro-run.cjs +25 -13
- package/dist/adapters/macro-run.cjs.map +1 -1
- package/dist/adapters/macro-run.d.ts +37 -2
- package/dist/adapters/macro-run.d.ts.map +1 -1
- package/dist/adapters/macro-run.js +25 -13
- package/dist/adapters/macro-run.js.map +1 -1
- package/dist/adapters.cjs +2 -0
- package/dist/adapters.cjs.map +1 -1
- package/dist/adapters.js +4 -2
- package/dist/components/ActionGroupRenderer.cjs +3 -1
- package/dist/components/ActionGroupRenderer.cjs.map +1 -1
- package/dist/components/ActionGroupRenderer.d.ts.map +1 -1
- package/dist/components/ActionGroupRenderer.js +3 -1
- package/dist/components/ActionGroupRenderer.js.map +1 -1
- package/dist/components/AgentCard.cjs +11 -8
- package/dist/components/AgentCard.cjs.map +1 -1
- package/dist/components/AgentCard.d.ts.map +1 -1
- package/dist/components/AgentCard.js +11 -8
- package/dist/components/AgentCard.js.map +1 -1
- package/dist/components/AgentHandoff.cjs +6 -1
- package/dist/components/AgentHandoff.cjs.map +1 -1
- package/dist/components/AgentHandoff.d.ts.map +1 -1
- package/dist/components/AgentHandoff.js +6 -1
- package/dist/components/AgentHandoff.js.map +1 -1
- package/dist/components/ArtifactRenderer.cjs +25 -6
- package/dist/components/ArtifactRenderer.cjs.map +1 -1
- package/dist/components/ArtifactRenderer.d.ts.map +1 -1
- package/dist/components/ArtifactRenderer.js +25 -6
- package/dist/components/ArtifactRenderer.js.map +1 -1
- package/dist/components/AutocompleteDropdown.cjs +30 -24
- package/dist/components/AutocompleteDropdown.cjs.map +1 -1
- package/dist/components/AutocompleteDropdown.d.ts.map +1 -1
- package/dist/components/AutocompleteDropdown.js +30 -24
- package/dist/components/AutocompleteDropdown.js.map +1 -1
- package/dist/components/AutocompleteFormField.cjs +3 -1
- package/dist/components/AutocompleteFormField.cjs.map +1 -1
- package/dist/components/AutocompleteFormField.d.ts.map +1 -1
- package/dist/components/AutocompleteFormField.js +4 -2
- package/dist/components/AutocompleteFormField.js.map +1 -1
- package/dist/components/BriefingDiff.cjs +45 -39
- package/dist/components/BriefingDiff.cjs.map +1 -1
- package/dist/components/BriefingDiff.d.ts.map +1 -1
- package/dist/components/BriefingDiff.js +45 -39
- package/dist/components/BriefingDiff.js.map +1 -1
- package/dist/components/CarouselRenderer.cjs +8 -2
- package/dist/components/CarouselRenderer.cjs.map +1 -1
- package/dist/components/CarouselRenderer.d.ts.map +1 -1
- package/dist/components/CarouselRenderer.js +8 -2
- package/dist/components/CarouselRenderer.js.map +1 -1
- package/dist/components/ChartJSRenderer.cjs +60 -36
- package/dist/components/ChartJSRenderer.cjs.map +1 -1
- package/dist/components/ChartJSRenderer.d.ts.map +1 -1
- package/dist/components/ChartJSRenderer.js +61 -37
- package/dist/components/ChartJSRenderer.js.map +1 -1
- package/dist/components/ChatPrompt.cjs +15 -9
- package/dist/components/ChatPrompt.cjs.map +1 -1
- package/dist/components/ChatPrompt.d.ts.map +1 -1
- package/dist/components/ChatPrompt.js +15 -9
- package/dist/components/ChatPrompt.js.map +1 -1
- package/dist/components/CodeBlockRenderer.cjs +34 -16
- package/dist/components/CodeBlockRenderer.cjs.map +1 -1
- package/dist/components/CodeBlockRenderer.d.ts.map +1 -1
- package/dist/components/CodeBlockRenderer.js +34 -16
- package/dist/components/CodeBlockRenderer.js.map +1 -1
- package/dist/components/DataPreviewSection.cjs +91 -44
- package/dist/components/DataPreviewSection.cjs.map +1 -1
- package/dist/components/DataPreviewSection.d.ts.map +1 -1
- package/dist/components/DataPreviewSection.js +92 -45
- package/dist/components/DataPreviewSection.js.map +1 -1
- package/dist/components/DegradedFallback.cjs +20 -16
- package/dist/components/DegradedFallback.cjs.map +1 -1
- package/dist/components/DegradedFallback.d.ts.map +1 -1
- package/dist/components/DegradedFallback.js +20 -16
- package/dist/components/DegradedFallback.js.map +1 -1
- package/dist/components/FooterRenderer.cjs +21 -17
- package/dist/components/FooterRenderer.cjs.map +1 -1
- package/dist/components/FooterRenderer.d.ts.map +1 -1
- package/dist/components/FooterRenderer.js +21 -17
- package/dist/components/FooterRenderer.js.map +1 -1
- package/dist/components/FormFieldRenderer.cjs +116 -93
- package/dist/components/FormFieldRenderer.cjs.map +1 -1
- package/dist/components/FormFieldRenderer.d.ts.map +1 -1
- package/dist/components/FormFieldRenderer.js +116 -93
- package/dist/components/FormFieldRenderer.js.map +1 -1
- package/dist/components/FormRenderer.cjs +55 -31
- package/dist/components/FormRenderer.cjs.map +1 -1
- package/dist/components/FormRenderer.d.ts.map +1 -1
- package/dist/components/FormRenderer.js +55 -31
- package/dist/components/FormRenderer.js.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.cjs +20 -15
- package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.d.ts.map +1 -1
- package/dist/components/GenerativeUIErrorBoundary.js +20 -15
- package/dist/components/GenerativeUIErrorBoundary.js.map +1 -1
- package/dist/components/GraphRenderer.cjs +56 -33
- package/dist/components/GraphRenderer.cjs.map +1 -1
- package/dist/components/GraphRenderer.d.ts.map +1 -1
- package/dist/components/GraphRenderer.js +56 -33
- package/dist/components/GraphRenderer.js.map +1 -1
- package/dist/components/ImageGalleryRenderer.cjs +13 -4
- package/dist/components/ImageGalleryRenderer.cjs.map +1 -1
- package/dist/components/ImageGalleryRenderer.d.ts.map +1 -1
- package/dist/components/ImageGalleryRenderer.js +13 -4
- package/dist/components/ImageGalleryRenderer.js.map +1 -1
- package/dist/components/LightboxOverlay.cjs +16 -8
- package/dist/components/LightboxOverlay.cjs.map +1 -1
- package/dist/components/LightboxOverlay.d.ts.map +1 -1
- package/dist/components/LightboxOverlay.js +17 -9
- package/dist/components/LightboxOverlay.js.map +1 -1
- package/dist/components/MapRenderer.cjs +59 -29
- package/dist/components/MapRenderer.cjs.map +1 -1
- package/dist/components/MapRenderer.d.ts +10 -2
- package/dist/components/MapRenderer.d.ts.map +1 -1
- package/dist/components/MapRenderer.js +60 -30
- package/dist/components/MapRenderer.js.map +1 -1
- package/dist/components/ModalRenderer.cjs +4 -1
- package/dist/components/ModalRenderer.cjs.map +1 -1
- package/dist/components/ModalRenderer.d.ts.map +1 -1
- package/dist/components/ModalRenderer.js +5 -2
- package/dist/components/ModalRenderer.js.map +1 -1
- package/dist/components/ScratchpadPanel.cjs +578 -535
- package/dist/components/ScratchpadPanel.cjs.map +1 -1
- package/dist/components/ScratchpadPanel.d.ts.map +1 -1
- package/dist/components/ScratchpadPanel.js +578 -535
- package/dist/components/ScratchpadPanel.js.map +1 -1
- package/dist/components/StreamingUIRenderer.cjs +92 -28
- package/dist/components/StreamingUIRenderer.cjs.map +1 -1
- package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
- package/dist/components/StreamingUIRenderer.js +92 -28
- package/dist/components/StreamingUIRenderer.js.map +1 -1
- package/dist/components/UIResourceRenderer.cjs +456 -363
- package/dist/components/UIResourceRenderer.cjs.map +1 -1
- package/dist/components/UIResourceRenderer.d.ts +21 -0
- package/dist/components/UIResourceRenderer.d.ts.map +1 -1
- package/dist/components/UIResourceRenderer.js +458 -365
- package/dist/components/UIResourceRenderer.js.map +1 -1
- package/dist/components/VerifiedText.cjs +39 -20
- package/dist/components/VerifiedText.cjs.map +1 -1
- package/dist/components/VerifiedText.d.ts +2 -1
- package/dist/components/VerifiedText.d.ts.map +1 -1
- package/dist/components/VerifiedText.js +39 -20
- package/dist/components/VerifiedText.js.map +1 -1
- package/dist/components/VideoRenderer.cjs +10 -5
- package/dist/components/VideoRenderer.cjs.map +1 -1
- package/dist/components/VideoRenderer.d.ts.map +1 -1
- package/dist/components/VideoRenderer.js +10 -5
- package/dist/components/VideoRenderer.js.map +1 -1
- package/dist/components/chart-data-table.cjs +38 -17
- package/dist/components/chart-data-table.cjs.map +1 -1
- package/dist/components/chart-data-table.d.ts +30 -1
- package/dist/components/chart-data-table.d.ts.map +1 -1
- package/dist/components/chart-data-table.js +38 -17
- package/dist/components/chart-data-table.js.map +1 -1
- package/dist/context/MCPActionContext.cjs +3 -1
- package/dist/context/MCPActionContext.cjs.map +1 -1
- package/dist/context/MCPActionContext.d.ts.map +1 -1
- package/dist/context/MCPActionContext.js +3 -1
- package/dist/context/MCPActionContext.js.map +1 -1
- package/dist/context/MCPUIStringsContext.cjs +285 -2
- package/dist/context/MCPUIStringsContext.cjs.map +1 -1
- package/dist/context/MCPUIStringsContext.d.ts +600 -3
- package/dist/context/MCPUIStringsContext.d.ts.map +1 -1
- package/dist/context/MCPUIStringsContext.js +285 -2
- package/dist/context/MCPUIStringsContext.js.map +1 -1
- package/dist/hooks/index.d.ts +2 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useStreamingUI.cjs +28 -10
- package/dist/hooks/useStreamingUI.cjs.map +1 -1
- package/dist/hooks/useStreamingUI.d.ts +37 -0
- package/dist/hooks/useStreamingUI.d.ts.map +1 -1
- package/dist/hooks/useStreamingUI.js +28 -10
- package/dist/hooks/useStreamingUI.js.map +1 -1
- package/dist/hooks.cjs +1 -0
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.js +2 -1
- package/dist/index.cjs +23 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -3
- package/dist/index.js.map +1 -1
- package/dist/services/validation.cjs +41 -16
- package/dist/services/validation.cjs.map +1 -1
- package/dist/services/validation.d.ts +47 -2
- package/dist/services/validation.d.ts.map +1 -1
- package/dist/services/validation.js +41 -16
- package/dist/services/validation.js.map +1 -1
- package/dist/utils/degraded-projections.cjs +37 -12
- package/dist/utils/degraded-projections.cjs.map +1 -1
- package/dist/utils/degraded-projections.d.ts +39 -3
- package/dist/utils/degraded-projections.d.ts.map +1 -1
- package/dist/utils/degraded-projections.js +37 -12
- package/dist/utils/degraded-projections.js.map +1 -1
- package/dist/utils/format-string.cjs +10 -0
- package/dist/utils/format-string.cjs.map +1 -0
- package/dist/utils/format-string.d.ts +26 -0
- package/dist/utils/format-string.d.ts.map +1 -0
- package/dist/utils/format-string.js +10 -0
- package/dist/utils/format-string.js.map +1 -0
- package/dist/validation.cjs +3 -0
- package/dist/validation.cjs.map +1 -1
- package/dist/validation.d.cts +2 -1
- package/dist/validation.d.ts +2 -1
- package/dist/validation.d.ts.map +1 -1
- package/dist/validation.js +4 -1
- package/package.json +1 -1
- package/src/adapters/connector.ts +58 -4
- package/src/adapters/index.ts +12 -2
- package/src/adapters/macro-run.ts +71 -11
- package/src/components/ActionGroupRenderer.tsx +3 -1
- package/src/components/AgentCard.tsx +27 -9
- package/src/components/AgentHandoff.tsx +4 -1
- package/src/components/ArtifactRenderer.tsx +17 -5
- package/src/components/AutocompleteDropdown.tsx +8 -6
- package/src/components/AutocompleteFormField.tsx +5 -1
- package/src/components/BriefingDiff.tsx +11 -3
- package/src/components/CarouselRenderer.tsx +4 -2
- package/src/components/ChartJSRenderer.tsx +18 -9
- package/src/components/ChatPrompt.tsx +13 -8
- package/src/components/CodeBlockRenderer.tsx +12 -10
- package/src/components/DataPreviewSection.tsx +92 -26
- package/src/components/DegradedFallback.tsx +4 -2
- package/src/components/FooterRenderer.tsx +3 -1
- package/src/components/FormFieldRenderer.tsx +34 -19
- package/src/components/FormRenderer.tsx +38 -10
- package/src/components/GenerativeUIErrorBoundary.tsx +8 -3
- package/src/components/GraphRenderer.tsx +31 -16
- package/src/components/ImageGalleryRenderer.tsx +8 -4
- package/src/components/LightboxOverlay.tsx +6 -4
- package/src/components/MapRenderer.tsx +57 -20
- package/src/components/ModalRenderer.tsx +3 -1
- package/src/components/ScratchpadPanel.tsx +95 -44
- package/src/components/StreamingUIRenderer.tsx +41 -11
- package/src/components/UIResourceRenderer.tsx +145 -63
- package/src/components/VerifiedText.tsx +19 -9
- package/src/components/VideoRenderer.tsx +6 -4
- package/src/components/chart-data-table.ts +68 -14
- package/src/context/MCPActionContext.tsx +4 -1
- package/src/context/MCPUIStringsContext.tsx +1004 -1
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useStreamingUI.ts +64 -10
- package/src/index.ts +23 -0
- package/src/services/validation.ts +93 -16
- package/src/utils/degraded-projections.ts +75 -12
- package/src/utils/format-string.ts +33 -0
- package/src/validation.ts +5 -0
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
import { formatMCPUIString } from "./format-string.js";
|
|
2
|
+
const DEGRADED_PROJECTION_LABELS = {
|
|
3
|
+
source: "Source",
|
|
4
|
+
target: "Target",
|
|
5
|
+
label: "Label",
|
|
6
|
+
node: "Node",
|
|
7
|
+
type: "Type",
|
|
8
|
+
lat: "Lat",
|
|
9
|
+
lng: "Lng",
|
|
10
|
+
info: "Info",
|
|
11
|
+
marker: "marker",
|
|
12
|
+
feature: "feature",
|
|
13
|
+
series: "Series {n}"
|
|
14
|
+
};
|
|
15
|
+
const withLabels = (labels) => ({
|
|
16
|
+
...DEGRADED_PROJECTION_LABELS,
|
|
17
|
+
...labels
|
|
18
|
+
});
|
|
1
19
|
const MAX_PROJECTED_ROWS = 200;
|
|
2
20
|
function cell(value) {
|
|
3
21
|
if (value == null) return "";
|
|
@@ -10,11 +28,12 @@ function cell(value) {
|
|
|
10
28
|
}
|
|
11
29
|
return String(value);
|
|
12
30
|
}
|
|
13
|
-
function graphToDegradedTable(params) {
|
|
31
|
+
function graphToDegradedTable(params, labels) {
|
|
32
|
+
const l = withLabels(labels);
|
|
14
33
|
const edges = params.edges ?? [];
|
|
15
34
|
if (edges.length > 0) {
|
|
16
35
|
return {
|
|
17
|
-
columns: [
|
|
36
|
+
columns: [l.source, l.target, l.label],
|
|
18
37
|
rows: edges.slice(0, MAX_PROJECTED_ROWS).map((e) => {
|
|
19
38
|
const label = [e.weight != null ? String(e.weight) : "", e.label ?? ""].filter(Boolean).join(" · ");
|
|
20
39
|
return [cell(e.source), cell(e.target), label];
|
|
@@ -23,7 +42,7 @@ function graphToDegradedTable(params) {
|
|
|
23
42
|
}
|
|
24
43
|
const nodes = params.nodes ?? [];
|
|
25
44
|
return {
|
|
26
|
-
columns: [
|
|
45
|
+
columns: [l.node, l.label],
|
|
27
46
|
rows: nodes.slice(0, MAX_PROJECTED_ROWS).map((n) => [cell(n.id), cell(n.label ?? n.id)])
|
|
28
47
|
};
|
|
29
48
|
}
|
|
@@ -35,13 +54,14 @@ function firstLngLat(coords) {
|
|
|
35
54
|
}
|
|
36
55
|
return null;
|
|
37
56
|
}
|
|
38
|
-
function mapToDegradedTable(params) {
|
|
57
|
+
function mapToDegradedTable(params, labels) {
|
|
39
58
|
var _a, _b, _c, _d;
|
|
59
|
+
const l = withLabels(labels);
|
|
40
60
|
const rows = [];
|
|
41
61
|
for (const m of params.markers ?? []) {
|
|
42
62
|
const lat = Array.isArray(m.position) ? m.position[0] : (_a = m.position) == null ? void 0 : _a.lat;
|
|
43
63
|
const lng = Array.isArray(m.position) ? m.position[1] : (_b = m.position) == null ? void 0 : _b.lng;
|
|
44
|
-
rows.push([
|
|
64
|
+
rows.push([l.marker, cell(lat), cell(lng), cell(m.tooltip ?? m.popup ?? "")]);
|
|
45
65
|
}
|
|
46
66
|
const fc = params.geojson;
|
|
47
67
|
const features = Array.isArray(fc == null ? void 0 : fc.features) ? fc.features : [];
|
|
@@ -50,29 +70,33 @@ function mapToDegradedTable(params) {
|
|
|
50
70
|
const props = f.properties ?? {};
|
|
51
71
|
const propSummary = Object.keys(props).slice(0, 3).map((k) => `${k}=${cell(props[k])}`).join(", ");
|
|
52
72
|
rows.push([
|
|
53
|
-
cell(((_d = f.geometry) == null ? void 0 : _d.type) ??
|
|
73
|
+
cell(((_d = f.geometry) == null ? void 0 : _d.type) ?? l.feature),
|
|
54
74
|
ll ? cell(ll[1]) : "",
|
|
55
75
|
ll ? cell(ll[0]) : "",
|
|
56
76
|
propSummary
|
|
57
77
|
]);
|
|
58
78
|
}
|
|
59
79
|
return {
|
|
60
|
-
columns: [
|
|
80
|
+
columns: [l.type, l.lat, l.lng, l.info],
|
|
61
81
|
rows: rows.slice(0, MAX_PROJECTED_ROWS)
|
|
62
82
|
};
|
|
63
83
|
}
|
|
64
|
-
function chartToDegradedTable(params) {
|
|
84
|
+
function chartToDegradedTable(params, labels) {
|
|
65
85
|
var _a, _b;
|
|
86
|
+
const l = withLabels(labels);
|
|
66
87
|
const datasets = ((_a = params.data) == null ? void 0 : _a.datasets) ?? [];
|
|
67
|
-
const
|
|
68
|
-
const rowCount = Math.max(
|
|
88
|
+
const dataLabels = ((_b = params.data) == null ? void 0 : _b.labels) ?? [];
|
|
89
|
+
const rowCount = Math.max(dataLabels.length, ...datasets.map((d) => {
|
|
69
90
|
var _a2;
|
|
70
91
|
return ((_a2 = d.data) == null ? void 0 : _a2.length) ?? 0;
|
|
71
92
|
}), 0);
|
|
72
|
-
const columns = [
|
|
93
|
+
const columns = [
|
|
94
|
+
"",
|
|
95
|
+
...datasets.map((d, i) => d.label ?? formatMCPUIString(l.series, { n: i + 1 }))
|
|
96
|
+
];
|
|
73
97
|
const rows = [];
|
|
74
98
|
for (let r = 0; r < Math.min(rowCount, MAX_PROJECTED_ROWS); r++) {
|
|
75
|
-
rows.push([cell(
|
|
99
|
+
rows.push([cell(dataLabels[r] ?? r + 1), ...datasets.map((d) => {
|
|
76
100
|
var _a2;
|
|
77
101
|
return cell((_a2 = d.data) == null ? void 0 : _a2[r]);
|
|
78
102
|
})]);
|
|
@@ -80,6 +104,7 @@ function chartToDegradedTable(params) {
|
|
|
80
104
|
return { columns, rows };
|
|
81
105
|
}
|
|
82
106
|
export {
|
|
107
|
+
DEGRADED_PROJECTION_LABELS,
|
|
83
108
|
chartToDegradedTable,
|
|
84
109
|
graphToDegradedTable,
|
|
85
110
|
mapToDegradedTable
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"degraded-projections.js","sources":["../../src/utils/degraded-projections.ts"],"sourcesContent":["/**\n * Degraded-fallback projections (audit 2026-05-30, P2.5).\n *\n * Pure functions that turn a heavy renderer's params into a flat\n * `{ columns, rows }` table for `<DegradedFallback>` — the middle rung of\n * the fallback ladder shown when the native render (G6 / Leaflet / Chart.js)\n * is unavailable or throws. No peer deps, no side effects, fully testable.\n *\n * These are best-effort views: they surface the underlying data so the user\n * isn't left with a blank space, not faithful reproductions of the chart/\n * map/graph.\n */\n\nexport interface DegradedTable {\n columns: string[];\n rows: Array<Array<string | number>>;\n}\n\nconst MAX_PROJECTED_ROWS = 200;\n\n/** Compact a value to a single table cell string. */\nfunction cell(value: unknown): string {\n if (value == null) return '';\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return String(value);\n}\n\n// ─── Graph ───────────────────────────────────────────────────────────────\n\n/**\n * Graph → edge table when edges exist (Source / Target / Label), else a\n * node list (Node / Label). The graph renderer can therefore degrade to a\n * readable relationship listing instead of a blank canvas.\n */\nexport function graphToDegradedTable(params: {\n nodes?: Array<{ id: string; label?: string }>;\n edges?: Array<{ source: string; target: string; label?: string; weight?: number }>;\n}): DegradedTable {\n const edges = params.edges ?? [];\n if (edges.length > 0) {\n return {\n columns: ['Source', 'Target', 'Label'],\n rows: edges.slice(0, MAX_PROJECTED_ROWS).map((e) => {\n const label = [e.weight != null ? String(e.weight) : '', e.label ?? '']\n .filter(Boolean)\n .join(' · ');\n return [cell(e.source), cell(e.target), label];\n }),\n };\n }\n const nodes = params.nodes ?? [];\n return {\n columns: ['Node', 'Label'],\n rows: nodes.slice(0, MAX_PROJECTED_ROWS).map((n) => [cell(n.id), cell(n.label ?? n.id)]),\n };\n}\n\n// ─── Map ───────────────────────────────────────────────────────────────────\n\ninterface GeoJSONLikeFeature {\n geometry?: { type?: string; coordinates?: unknown } | null;\n properties?: Record<string, unknown> | null;\n}\n\n/** Pull a representative `[lng, lat]` pair out of a geometry's coordinates. */\nfunction firstLngLat(coords: unknown): [number, number] | null {\n let c: unknown = coords;\n // Descend nested arrays until we reach a [number, number, ...] position.\n while (Array.isArray(c) && Array.isArray(c[0])) c = c[0];\n if (Array.isArray(c) && typeof c[0] === 'number' && typeof c[1] === 'number') {\n return [c[0], c[1]];\n }\n return null;\n}\n\n/**\n * Map → a coordinate table. Markers become Lat/Lng/Label rows; GeoJSON\n * features become Type / Lat / Lng (+ a compact properties summary). So a\n * map that can't paint still lists where its points are.\n */\nexport function mapToDegradedTable(params: {\n markers?: Array<{\n position: [number, number] | { lat: number; lng: number };\n tooltip?: string;\n popup?: string;\n }>;\n geojson?: unknown;\n}): DegradedTable {\n const rows: Array<Array<string | number>> = [];\n\n for (const m of params.markers ?? []) {\n const lat = Array.isArray(m.position) ? m.position[0] : m.position?.lat;\n const lng = Array.isArray(m.position) ? m.position[1] : m.position?.lng;\n rows.push(['marker', cell(lat), cell(lng), cell(m.tooltip ?? m.popup ?? '')]);\n }\n\n const fc = params.geojson as { features?: GeoJSONLikeFeature[] } | undefined;\n const features = Array.isArray(fc?.features) ? fc!.features : [];\n for (const f of features) {\n const ll = firstLngLat(f.geometry?.coordinates);\n const props = f.properties ?? {};\n const propSummary = Object.keys(props)\n .slice(0, 3)\n .map((k) => `${k}=${cell(props[k])}`)\n .join(', ');\n rows.push([\n cell(f.geometry?.type ?? 'feature'),\n ll ? cell(ll[1]) : '',\n ll ? cell(ll[0]) : '',\n propSummary,\n ]);\n }\n\n return {\n columns: ['Type', 'Lat', 'Lng', 'Info'],\n rows: rows.slice(0, MAX_PROJECTED_ROWS),\n };\n}\n\n// ─── Chart ───────────────────────────────────────────────────────────────\n\n/**\n * Chart → a series table: one row per label, one column per dataset. So a\n * chart that can't draw still shows its numbers. Point/object data (scatter,\n * bubble, time series) is stringified per cell.\n */\nexport function chartToDegradedTable(params: {\n data?: {\n labels?: Array<string | number>;\n datasets?: Array<{ label?: string; data?: unknown[] }>;\n };\n}): DegradedTable {\n const datasets = params.data?.datasets ?? [];\n const labels = params.data?.labels ?? [];\n const rowCount = Math.max(labels.length, ...datasets.map((d) => d.data?.length ?? 0), 0);\n\n const columns = ['', ...datasets.map((d, i) => d.label ?? `Series ${i + 1}`)];\n const rows: Array<Array<string | number>> = [];\n for (let r = 0; r < Math.min(rowCount, MAX_PROJECTED_ROWS); r++) {\n rows.push([cell(labels[r] ?? r + 1), ...datasets.map((d) => cell(d.data?.[r]))]);\n }\n return { columns, rows };\n}\n"],"names":["_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"degraded-projections.js","sources":["../../src/utils/degraded-projections.ts"],"sourcesContent":["/**\n * Degraded-fallback projections (audit 2026-05-30, P2.5).\n *\n * Pure functions that turn a heavy renderer's params into a flat\n * `{ columns, rows }` table for `<DegradedFallback>` — the middle rung of\n * the fallback ladder shown when the native render (G6 / Leaflet / Chart.js)\n * is unavailable or throws. No peer deps, no side effects, fully testable.\n *\n * These are best-effort views: they surface the underlying data so the user\n * isn't left with a blank space, not faithful reproductions of the chart/\n * map/graph.\n */\n\nimport { formatMCPUIString } from './format-string';\n\n/**\n * Column headers and series names of the degraded tables.\n *\n * The projections are pure helpers with no access to `MCPUIStrings`, so the\n * wording is injected: each function takes an optional trailing `labels`\n * partial, and the renderers feed it from `useMCPUIStrings()`. Left out, the\n * English defaults below apply — the pre-v6.20.0 behaviour.\n *\n * @since v6.20.0\n */\nexport interface DegradedProjectionLabels {\n /** Graph edge table — source column. */\n source: string;\n /** Graph edge table — target column. */\n target: string;\n /** Graph edge / node table — label column. */\n label: string;\n /** Graph node table — node id column. */\n node: string;\n /** Map table — feature type column. */\n type: string;\n /** Map table — latitude column. */\n lat: string;\n /** Map table — longitude column. */\n lng: string;\n /** Map table — property summary column. */\n info: string;\n /** Map table — `Type` cell of a marker row (v6.20.0, 6th pass). */\n marker: string;\n /** Map table — `Type` cell of a GeoJSON feature without a geometry type (v6.20.0). */\n feature: string;\n /** Chart table — fallback dataset name. Template — `{n}`. */\n series: string;\n}\n\n/** English defaults for {@link DegradedProjectionLabels}. */\nexport const DEGRADED_PROJECTION_LABELS: DegradedProjectionLabels = {\n source: 'Source',\n target: 'Target',\n label: 'Label',\n node: 'Node',\n type: 'Type',\n lat: 'Lat',\n lng: 'Lng',\n info: 'Info',\n marker: 'marker',\n feature: 'feature',\n series: 'Series {n}',\n};\n\nconst withLabels = (labels?: Partial<DegradedProjectionLabels>): DegradedProjectionLabels => ({\n ...DEGRADED_PROJECTION_LABELS,\n ...labels,\n});\n\nexport interface DegradedTable {\n columns: string[];\n rows: Array<Array<string | number>>;\n}\n\nconst MAX_PROJECTED_ROWS = 200;\n\n/** Compact a value to a single table cell string. */\nfunction cell(value: unknown): string {\n if (value == null) return '';\n if (typeof value === 'object') {\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n }\n return String(value);\n}\n\n// ─── Graph ───────────────────────────────────────────────────────────────\n\n/**\n * Graph → edge table when edges exist (Source / Target / Label), else a\n * node list (Node / Label). The graph renderer can therefore degrade to a\n * readable relationship listing instead of a blank canvas.\n */\nexport function graphToDegradedTable(params: {\n nodes?: Array<{ id: string; label?: string }>;\n edges?: Array<{ source: string; target: string; label?: string; weight?: number }>;\n}, labels?: Partial<DegradedProjectionLabels>): DegradedTable {\n const l = withLabels(labels);\n const edges = params.edges ?? [];\n if (edges.length > 0) {\n return {\n columns: [l.source, l.target, l.label],\n rows: edges.slice(0, MAX_PROJECTED_ROWS).map((e) => {\n const label = [e.weight != null ? String(e.weight) : '', e.label ?? '']\n .filter(Boolean)\n .join(' · ');\n return [cell(e.source), cell(e.target), label];\n }),\n };\n }\n const nodes = params.nodes ?? [];\n return {\n columns: [l.node, l.label],\n rows: nodes.slice(0, MAX_PROJECTED_ROWS).map((n) => [cell(n.id), cell(n.label ?? n.id)]),\n };\n}\n\n// ─── Map ───────────────────────────────────────────────────────────────────\n\ninterface GeoJSONLikeFeature {\n geometry?: { type?: string; coordinates?: unknown } | null;\n properties?: Record<string, unknown> | null;\n}\n\n/** Pull a representative `[lng, lat]` pair out of a geometry's coordinates. */\nfunction firstLngLat(coords: unknown): [number, number] | null {\n let c: unknown = coords;\n // Descend nested arrays until we reach a [number, number, ...] position.\n while (Array.isArray(c) && Array.isArray(c[0])) c = c[0];\n if (Array.isArray(c) && typeof c[0] === 'number' && typeof c[1] === 'number') {\n return [c[0], c[1]];\n }\n return null;\n}\n\n/**\n * Map → a coordinate table. Markers become Lat/Lng/Label rows; GeoJSON\n * features become Type / Lat / Lng (+ a compact properties summary). So a\n * map that can't paint still lists where its points are.\n */\nexport function mapToDegradedTable(params: {\n markers?: Array<{\n position: [number, number] | { lat: number; lng: number };\n tooltip?: string;\n popup?: string;\n }>;\n geojson?: unknown;\n}, labels?: Partial<DegradedProjectionLabels>): DegradedTable {\n const l = withLabels(labels);\n const rows: Array<Array<string | number>> = [];\n\n for (const m of params.markers ?? []) {\n const lat = Array.isArray(m.position) ? m.position[0] : m.position?.lat;\n const lng = Array.isArray(m.position) ? m.position[1] : m.position?.lng;\n rows.push([l.marker, cell(lat), cell(lng), cell(m.tooltip ?? m.popup ?? '')]);\n }\n\n const fc = params.geojson as { features?: GeoJSONLikeFeature[] } | undefined;\n const features = Array.isArray(fc?.features) ? fc!.features : [];\n for (const f of features) {\n const ll = firstLngLat(f.geometry?.coordinates);\n const props = f.properties ?? {};\n const propSummary = Object.keys(props)\n .slice(0, 3)\n .map((k) => `${k}=${cell(props[k])}`)\n .join(', ');\n rows.push([\n cell(f.geometry?.type ?? l.feature),\n ll ? cell(ll[1]) : '',\n ll ? cell(ll[0]) : '',\n propSummary,\n ]);\n }\n\n return {\n columns: [l.type, l.lat, l.lng, l.info],\n rows: rows.slice(0, MAX_PROJECTED_ROWS),\n };\n}\n\n// ─── Chart ───────────────────────────────────────────────────────────────\n\n/**\n * Chart → a series table: one row per label, one column per dataset. So a\n * chart that can't draw still shows its numbers. Point/object data (scatter,\n * bubble, time series) is stringified per cell.\n */\nexport function chartToDegradedTable(params: {\n data?: {\n labels?: Array<string | number>;\n datasets?: Array<{ label?: string; data?: unknown[] }>;\n };\n}, labels?: Partial<DegradedProjectionLabels>): DegradedTable {\n const l = withLabels(labels);\n const datasets = params.data?.datasets ?? [];\n const dataLabels = params.data?.labels ?? [];\n const rowCount = Math.max(dataLabels.length, ...datasets.map((d) => d.data?.length ?? 0), 0);\n\n const columns = [\n '',\n ...datasets.map((d, i) => d.label ?? formatMCPUIString(l.series, { n: i + 1 })),\n ];\n const rows: Array<Array<string | number>> = [];\n for (let r = 0; r < Math.min(rowCount, MAX_PROJECTED_ROWS); r++) {\n rows.push([cell(dataLabels[r] ?? r + 1), ...datasets.map((d) => cell(d.data?.[r]))]);\n }\n return { columns, rows };\n}\n"],"names":["_a"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
function formatMCPUIString(template, vars) {
|
|
4
|
+
return template.replace(
|
|
5
|
+
/\{(\w+)\}/g,
|
|
6
|
+
(match, name) => Object.prototype.hasOwnProperty.call(vars, name) ? String(vars[name]) : match
|
|
7
|
+
);
|
|
8
|
+
}
|
|
9
|
+
exports.formatMCPUIString = formatMCPUIString;
|
|
10
|
+
//# sourceMappingURL=format-string.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-string.cjs","sources":["../../src/utils/format-string.ts"],"sourcesContent":["/**\n * `formatMCPUIString` — the chrome-string template helper, runtime-free.\n *\n * @since v6.20.0 (extracted from `MCPUIStringsContext` so the pure adapters\n * under `src/adapters` can interpolate their own message templates without\n * importing `solid-js`). `MCPUIStringsContext` re-exports it, so every\n * existing import path — including the root barrel — keeps working.\n *\n * This module imports nothing. It must stay that way: `src/adapters/*` is\n * published as a dedicated subpath that never pulls in the renderer.\n */\n\n/**\n * Substitutes `{name}` placeholders in a chrome string template.\n *\n * Only the keys present in `vars` are replaced; an unknown placeholder is\n * left verbatim so a mistyped or locale-specific template degrades to\n * visible text rather than to `undefined`.\n *\n * @example\n * ```ts\n * formatMCPUIString('Sort by {column}', { column: 'Revenue' }) // 'Sort by Revenue'\n * formatMCPUIString('Export CSV ({count} rows)', { count: 42 }) // 'Export CSV (42 rows)'\n * ```\n */\nexport function formatMCPUIString(\n template: string,\n vars: Record<string, string | number>\n): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, name: string) =>\n Object.prototype.hasOwnProperty.call(vars, name) ? String(vars[name]) : match\n )\n}\n"],"names":[],"mappings":";;AAyBO,SAAS,kBACd,UACA,MACQ;AACR,SAAO,SAAS;AAAA,IAAQ;AAAA,IAAc,CAAC,OAAO,SAC5C,OAAO,UAAU,eAAe,KAAK,MAAM,IAAI,IAAI,OAAO,KAAK,IAAI,CAAC,IAAI;AAAA,EAAA;AAE5E;;"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `formatMCPUIString` — the chrome-string template helper, runtime-free.
|
|
3
|
+
*
|
|
4
|
+
* @since v6.20.0 (extracted from `MCPUIStringsContext` so the pure adapters
|
|
5
|
+
* under `src/adapters` can interpolate their own message templates without
|
|
6
|
+
* importing `solid-js`). `MCPUIStringsContext` re-exports it, so every
|
|
7
|
+
* existing import path — including the root barrel — keeps working.
|
|
8
|
+
*
|
|
9
|
+
* This module imports nothing. It must stay that way: `src/adapters/*` is
|
|
10
|
+
* published as a dedicated subpath that never pulls in the renderer.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Substitutes `{name}` placeholders in a chrome string template.
|
|
14
|
+
*
|
|
15
|
+
* Only the keys present in `vars` are replaced; an unknown placeholder is
|
|
16
|
+
* left verbatim so a mistyped or locale-specific template degrades to
|
|
17
|
+
* visible text rather than to `undefined`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* formatMCPUIString('Sort by {column}', { column: 'Revenue' }) // 'Sort by Revenue'
|
|
22
|
+
* formatMCPUIString('Export CSV ({count} rows)', { count: 42 }) // 'Export CSV (42 rows)'
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare function formatMCPUIString(template: string, vars: Record<string, string | number>): string;
|
|
26
|
+
//# sourceMappingURL=format-string.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-string.d.ts","sourceRoot":"","sources":["../../src/utils/format-string.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GACpC,MAAM,CAIR"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
function formatMCPUIString(template, vars) {
|
|
2
|
+
return template.replace(
|
|
3
|
+
/\{(\w+)\}/g,
|
|
4
|
+
(match, name) => Object.prototype.hasOwnProperty.call(vars, name) ? String(vars[name]) : match
|
|
5
|
+
);
|
|
6
|
+
}
|
|
7
|
+
export {
|
|
8
|
+
formatMCPUIString
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=format-string.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-string.js","sources":["../../src/utils/format-string.ts"],"sourcesContent":["/**\n * `formatMCPUIString` — the chrome-string template helper, runtime-free.\n *\n * @since v6.20.0 (extracted from `MCPUIStringsContext` so the pure adapters\n * under `src/adapters` can interpolate their own message templates without\n * importing `solid-js`). `MCPUIStringsContext` re-exports it, so every\n * existing import path — including the root barrel — keeps working.\n *\n * This module imports nothing. It must stay that way: `src/adapters/*` is\n * published as a dedicated subpath that never pulls in the renderer.\n */\n\n/**\n * Substitutes `{name}` placeholders in a chrome string template.\n *\n * Only the keys present in `vars` are replaced; an unknown placeholder is\n * left verbatim so a mistyped or locale-specific template degrades to\n * visible text rather than to `undefined`.\n *\n * @example\n * ```ts\n * formatMCPUIString('Sort by {column}', { column: 'Revenue' }) // 'Sort by Revenue'\n * formatMCPUIString('Export CSV ({count} rows)', { count: 42 }) // 'Export CSV (42 rows)'\n * ```\n */\nexport function formatMCPUIString(\n template: string,\n vars: Record<string, string | number>\n): string {\n return template.replace(/\\{(\\w+)\\}/g, (match, name: string) =>\n Object.prototype.hasOwnProperty.call(vars, name) ? String(vars[name]) : match\n )\n}\n"],"names":[],"mappings":"AAyBO,SAAS,kBACd,UACA,MACQ;AACR,SAAO,SAAS;AAAA,IAAQ;AAAA,IAAc,CAAC,OAAO,SAC5C,OAAO,UAAU,eAAe,KAAK,MAAM,IAAI,IAAI,OAAO,KAAK,IAAI,CAAC,IAAI;AAAA,EAAA;AAE5E;"}
|
package/dist/validation.cjs
CHANGED
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const validation = require("./services/validation.cjs");
|
|
4
4
|
exports.DEFAULT_RESOURCE_LIMITS = validation.DEFAULT_RESOURCE_LIMITS;
|
|
5
|
+
exports.DEFAULT_VALIDATION_MESSAGES = validation.DEFAULT_VALIDATION_MESSAGES;
|
|
5
6
|
exports.sanitizeString = validation.sanitizeString;
|
|
6
7
|
exports.validateChartComponent = validation.validateChartComponent;
|
|
7
8
|
exports.validateComponent = validation.validateComponent;
|
|
9
|
+
exports.validateFieldValue = validation.validateFieldValue;
|
|
10
|
+
exports.validateFormData = validation.validateFormData;
|
|
8
11
|
exports.validateGridPosition = validation.validateGridPosition;
|
|
9
12
|
exports.validateIframeDomain = validation.validateIframeDomain;
|
|
10
13
|
exports.validateLayout = validation.validateLayout;
|
package/dist/validation.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validation.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;"}
|
package/dist/validation.d.cts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* import { validateLayout } from '@seed-ship/mcp-ui-solid/validation'
|
|
10
10
|
* ```
|
|
11
11
|
*/
|
|
12
|
-
export { validateComponent, validateLayout, validateGridPosition, validateChartComponent, validateTableComponent, validatePayloadSize, validateIframeDomain, sanitizeString, DEFAULT_RESOURCE_LIMITS, } from './services/validation';
|
|
12
|
+
export { validateComponent, validateLayout, validateGridPosition, validateChartComponent, validateTableComponent, validatePayloadSize, validateIframeDomain, sanitizeString, DEFAULT_RESOURCE_LIMITS, validateFieldValue, validateFormData, DEFAULT_VALIDATION_MESSAGES, } from './services/validation';
|
|
13
|
+
export type { FormValidationMessages } from './services/validation';
|
|
13
14
|
export type { UIComponent, UILayout, GridPosition, ComponentType, ChartComponentParams, TableComponentParams, MetricComponentParams, TextComponentParams, ValidationResult, ResourceLimits, } from './types';
|
|
14
15
|
//# sourceMappingURL=validation.d.ts.map
|
package/dist/validation.d.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* import { validateLayout } from '@seed-ship/mcp-ui-solid/validation'
|
|
10
10
|
* ```
|
|
11
11
|
*/
|
|
12
|
-
export { validateComponent, validateLayout, validateGridPosition, validateChartComponent, validateTableComponent, validatePayloadSize, validateIframeDomain, sanitizeString, DEFAULT_RESOURCE_LIMITS, } from './services/validation';
|
|
12
|
+
export { validateComponent, validateLayout, validateGridPosition, validateChartComponent, validateTableComponent, validatePayloadSize, validateIframeDomain, sanitizeString, DEFAULT_RESOURCE_LIMITS, validateFieldValue, validateFormData, DEFAULT_VALIDATION_MESSAGES, } from './services/validation';
|
|
13
|
+
export type { FormValidationMessages } from './services/validation';
|
|
13
14
|
export type { UIComponent, UILayout, GridPosition, ComponentType, ChartComponentParams, TableComponentParams, MetricComponentParams, TextComponentParams, ValidationResult, ResourceLimits, } from './types';
|
|
14
15
|
//# sourceMappingURL=validation.d.ts.map
|
package/dist/validation.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,uBAAuB,
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../src/validation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,sBAAsB,EACtB,sBAAsB,EACtB,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,uBAAuB,EAEvB,kBAAkB,EAClB,gBAAgB,EAChB,2BAA2B,GAC5B,MAAM,uBAAuB,CAAA;AAC9B,YAAY,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAGnE,YAAY,EACV,WAAW,EACX,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,gBAAgB,EAChB,cAAc,GACf,MAAM,SAAS,CAAA"}
|
package/dist/validation.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { DEFAULT_RESOURCE_LIMITS, sanitizeString, validateChartComponent, validateComponent, validateGridPosition, validateIframeDomain, validateLayout, validatePayloadSize, validateTableComponent } from "./services/validation.js";
|
|
1
|
+
import { DEFAULT_RESOURCE_LIMITS, DEFAULT_VALIDATION_MESSAGES, sanitizeString, validateChartComponent, validateComponent, validateFieldValue, validateFormData, validateGridPosition, validateIframeDomain, validateLayout, validatePayloadSize, validateTableComponent } from "./services/validation.js";
|
|
2
2
|
export {
|
|
3
3
|
DEFAULT_RESOURCE_LIMITS,
|
|
4
|
+
DEFAULT_VALIDATION_MESSAGES,
|
|
4
5
|
sanitizeString,
|
|
5
6
|
validateChartComponent,
|
|
6
7
|
validateComponent,
|
|
8
|
+
validateFieldValue,
|
|
9
|
+
validateFormData,
|
|
7
10
|
validateGridPosition,
|
|
8
11
|
validateIframeDomain,
|
|
9
12
|
validateLayout,
|
package/package.json
CHANGED
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
type ConnectorAction,
|
|
30
30
|
} from '@seed-ship/mcp-ui-spec'
|
|
31
31
|
import { z } from 'zod'
|
|
32
|
+
import { formatMCPUIString } from '../utils/format-string'
|
|
32
33
|
|
|
33
34
|
// ─────────────────────────────────────────────────────────────
|
|
34
35
|
// connectorActionsToActionGroup
|
|
@@ -74,11 +75,57 @@ export function connectorActionsToActionGroup(
|
|
|
74
75
|
// connectorResultToUILayout
|
|
75
76
|
// ─────────────────────────────────────────────────────────────
|
|
76
77
|
|
|
78
|
+
/**
|
|
79
|
+
* The visible wording of the two degraded states (R2).
|
|
80
|
+
*
|
|
81
|
+
* These paragraphs are rendered as `text` components, so unlike the payload
|
|
82
|
+
* they are the LIBRARY's own chrome. They cannot go through
|
|
83
|
+
* `MCPUIStrings` — the adapters are runtime-free and never import
|
|
84
|
+
* `solid-js` — so a host localizes them through
|
|
85
|
+
* `ConnectorResultToUILayoutOptions.messages` instead.
|
|
86
|
+
*
|
|
87
|
+
* Every field is a template resolved with `formatMCPUIString`.
|
|
88
|
+
*
|
|
89
|
+
* @since v6.20.0 — the defaults used to be hardcoded French.
|
|
90
|
+
*/
|
|
91
|
+
export interface ConnectorAdapterMessages {
|
|
92
|
+
/**
|
|
93
|
+
* Unreadable payload (tier 3). Template — `{versionSuffix}` is
|
|
94
|
+
* `degradedVersionSuffix` when the payload carried a string
|
|
95
|
+
* `schemaVersion`, and `''` otherwise.
|
|
96
|
+
*/
|
|
97
|
+
degradedNotice: string
|
|
98
|
+
/** Inserted into `degradedNotice`. Template — `{version}`. */
|
|
99
|
+
degradedVersionSuffix: string
|
|
100
|
+
/**
|
|
101
|
+
* Usable envelope, unknown version (tier 2). Template — `{version}` = the
|
|
102
|
+
* version read, `{expected}` = `CONNECTOR_DYNAMIC_RESULT_V1`.
|
|
103
|
+
*/
|
|
104
|
+
versionWarning: string
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/** English defaults for {@link ConnectorAdapterMessages}. */
|
|
108
|
+
export const DEFAULT_CONNECTOR_MESSAGES: ConnectorAdapterMessages = {
|
|
109
|
+
degradedNotice:
|
|
110
|
+
'### Result not rendered\n\nThe connector result could not be interpreted{versionSuffix}. This explicit state replaces a silent disappearance of the rendering.',
|
|
111
|
+
degradedVersionSuffix: ' (schema: `{version}`)',
|
|
112
|
+
versionWarning:
|
|
113
|
+
'> \u26A0 Unrecognized connector schema (`{version}`, expected `{expected}`). The rendering below is in degraded mode.',
|
|
114
|
+
}
|
|
115
|
+
|
|
77
116
|
export interface ConnectorResultToUILayoutOptions {
|
|
78
117
|
/** Layout id. Default derived from `connectorId` + `queryHash` / `toolName`. */
|
|
79
118
|
id?: string
|
|
80
119
|
/** Heading for the actions `action-group`. */
|
|
81
120
|
actionsTitle?: string
|
|
121
|
+
/**
|
|
122
|
+
* Partial override of the degraded-state wording, merged over
|
|
123
|
+
* {@link DEFAULT_CONNECTOR_MESSAGES}. Hosts that render in another
|
|
124
|
+
* language pass their own paragraphs here.
|
|
125
|
+
*
|
|
126
|
+
* @since v6.20.0
|
|
127
|
+
*/
|
|
128
|
+
messages?: Partial<ConnectorAdapterMessages>
|
|
82
129
|
}
|
|
83
130
|
|
|
84
131
|
/**
|
|
@@ -144,6 +191,7 @@ export function connectorResultToUILayout(
|
|
|
144
191
|
options: ConnectorResultToUILayoutOptions = {}
|
|
145
192
|
): UILayout {
|
|
146
193
|
const strict = ConnectorDynamicResultV1Schema.safeParse(result)
|
|
194
|
+
const messages: ConnectorAdapterMessages = { ...DEFAULT_CONNECTOR_MESSAGES, ...options.messages }
|
|
147
195
|
|
|
148
196
|
// ── Tier 3 : unreadable ───────────────────────────────────
|
|
149
197
|
if (!strict.success) {
|
|
@@ -158,9 +206,12 @@ export function connectorResultToUILayout(
|
|
|
158
206
|
components: [
|
|
159
207
|
degradedTextComponent(
|
|
160
208
|
'connector-degraded-notice',
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
209
|
+
formatMCPUIString(messages.degradedNotice, {
|
|
210
|
+
versionSuffix:
|
|
211
|
+
typeof version === 'string'
|
|
212
|
+
? formatMCPUIString(messages.degradedVersionSuffix, { version })
|
|
213
|
+
: '',
|
|
214
|
+
})
|
|
164
215
|
),
|
|
165
216
|
],
|
|
166
217
|
grid: { ...DEFAULT_GRID },
|
|
@@ -171,7 +222,10 @@ export function connectorResultToUILayout(
|
|
|
171
222
|
const components: UIComponent[] = [
|
|
172
223
|
degradedTextComponent(
|
|
173
224
|
'connector-version-warning',
|
|
174
|
-
|
|
225
|
+
formatMCPUIString(messages.versionWarning, {
|
|
226
|
+
version: r.schemaVersion,
|
|
227
|
+
expected: CONNECTOR_DYNAMIC_RESULT_V1,
|
|
228
|
+
})
|
|
175
229
|
),
|
|
176
230
|
...collectComponents(r),
|
|
177
231
|
]
|
package/src/adapters/index.ts
CHANGED
|
@@ -14,13 +14,23 @@
|
|
|
14
14
|
* ```
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
export {
|
|
17
|
+
export {
|
|
18
|
+
connectorResultToUILayout,
|
|
19
|
+
connectorActionsToActionGroup,
|
|
20
|
+
DEFAULT_CONNECTOR_MESSAGES,
|
|
21
|
+
} from './connector';
|
|
18
22
|
export type {
|
|
19
23
|
ConnectorResultToUILayoutOptions,
|
|
20
24
|
ConnectorActionsToActionGroupOptions,
|
|
25
|
+
ConnectorAdapterMessages,
|
|
21
26
|
} from './connector';
|
|
22
27
|
|
|
23
|
-
export {
|
|
28
|
+
export {
|
|
29
|
+
macroRunToScratchpadState,
|
|
30
|
+
macroInterrogationToChatPromptConfig,
|
|
31
|
+
DEFAULT_MACRO_RUN_MESSAGES,
|
|
32
|
+
} from './macro-run';
|
|
33
|
+
export type { MacroRunAdapterMessages, MacroRunAdapterOptions } from './macro-run';
|
|
24
34
|
|
|
25
35
|
export {
|
|
26
36
|
createComparisonLayout,
|
|
@@ -174,7 +174,59 @@ function resultSectionType(componentType: unknown): ScratchpadSection['type'] {
|
|
|
174
174
|
}
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
-
|
|
177
|
+
/**
|
|
178
|
+
* The English wording this adapter produces on its own — section titles and
|
|
179
|
+
* the fallbacks used when the run (or the interrogation) carries none.
|
|
180
|
+
*
|
|
181
|
+
* The adapter is runtime-free by contract: no `solid-js`, no
|
|
182
|
+
* `MCPUIStringsContext`. Hosts that render in another language pass a
|
|
183
|
+
* partial override through `MacroRunAdapterOptions.messages`, exactly like
|
|
184
|
+
* `ConnectorResultToUILayoutOptions.messages`.
|
|
185
|
+
*
|
|
186
|
+
* @since v6.20.0
|
|
187
|
+
*/
|
|
188
|
+
export interface MacroRunAdapterMessages {
|
|
189
|
+
/** Title of the always-present `agent_card` section. */
|
|
190
|
+
agentSectionTitle: string;
|
|
191
|
+
/** Title of the `stepper` / `split_stepper` section. */
|
|
192
|
+
progressSectionTitle: string;
|
|
193
|
+
/** Title of each result section. */
|
|
194
|
+
resultSectionTitle: string;
|
|
195
|
+
/** Error message of an aborted run that carries no `error`. */
|
|
196
|
+
runAborted: string;
|
|
197
|
+
/** Error message of a failed run that carries no `error`. */
|
|
198
|
+
runFailed: string;
|
|
199
|
+
/** Prompt body of an elicitation with no usable schema and no message. */
|
|
200
|
+
confirmDefault: string;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/** English defaults for {@link MacroRunAdapterMessages}. */
|
|
204
|
+
export const DEFAULT_MACRO_RUN_MESSAGES: MacroRunAdapterMessages = {
|
|
205
|
+
agentSectionTitle: 'Agent',
|
|
206
|
+
progressSectionTitle: 'Progress',
|
|
207
|
+
resultSectionTitle: 'Result',
|
|
208
|
+
runAborted: 'Macro run aborted.',
|
|
209
|
+
runFailed: 'Macro run failed.',
|
|
210
|
+
confirmDefault: 'Please confirm to continue.',
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
/** Options shared by the MacroRun adapters. @since v6.20.0 */
|
|
214
|
+
export interface MacroRunAdapterOptions {
|
|
215
|
+
/**
|
|
216
|
+
* Partial override of the adapter's own wording, merged over
|
|
217
|
+
* {@link DEFAULT_MACRO_RUN_MESSAGES}.
|
|
218
|
+
*/
|
|
219
|
+
messages?: Partial<MacroRunAdapterMessages>;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const withMessages = (
|
|
223
|
+
options: MacroRunAdapterOptions = {}
|
|
224
|
+
): MacroRunAdapterMessages => ({ ...DEFAULT_MACRO_RUN_MESSAGES, ...options.messages });
|
|
225
|
+
|
|
226
|
+
function buildError(
|
|
227
|
+
run: MacroRunV1,
|
|
228
|
+
messages: MacroRunAdapterMessages
|
|
229
|
+
): ScratchpadState['error'] | undefined {
|
|
178
230
|
if (run.status !== 'failed' && run.status !== 'aborted') return undefined;
|
|
179
231
|
const aborted = run.status === 'aborted';
|
|
180
232
|
if (run.error) {
|
|
@@ -187,7 +239,7 @@ function buildError(run: MacroRunV1): ScratchpadState['error'] | undefined {
|
|
|
187
239
|
return err;
|
|
188
240
|
}
|
|
189
241
|
return {
|
|
190
|
-
message: aborted ?
|
|
242
|
+
message: aborted ? messages.runAborted : messages.runFailed,
|
|
191
243
|
retryable: false,
|
|
192
244
|
};
|
|
193
245
|
}
|
|
@@ -209,13 +261,17 @@ function buildError(run: MacroRunV1): ScratchpadState['error'] | undefined {
|
|
|
209
261
|
*
|
|
210
262
|
* Pure: no fetch, no SSE, no persistence. The host owns all wiring.
|
|
211
263
|
*/
|
|
212
|
-
export function macroRunToScratchpadState(
|
|
264
|
+
export function macroRunToScratchpadState(
|
|
265
|
+
run: MacroRunV1,
|
|
266
|
+
options: MacroRunAdapterOptions = {}
|
|
267
|
+
): ScratchpadState {
|
|
268
|
+
const messages = withMessages(options);
|
|
213
269
|
const sections: ScratchpadSection[] = [];
|
|
214
270
|
|
|
215
271
|
// 1. Agent card — always present.
|
|
216
272
|
sections.push({
|
|
217
273
|
id: 'macro-agent',
|
|
218
|
-
title:
|
|
274
|
+
title: messages.agentSectionTitle,
|
|
219
275
|
type: 'agent_card',
|
|
220
276
|
content: buildAgentCard(run),
|
|
221
277
|
editable: false,
|
|
@@ -229,7 +285,7 @@ export function macroRunToScratchpadState(run: MacroRunV1): ScratchpadState {
|
|
|
229
285
|
hasParallel
|
|
230
286
|
? {
|
|
231
287
|
id: 'macro-split-stepper',
|
|
232
|
-
title:
|
|
288
|
+
title: messages.progressSectionTitle,
|
|
233
289
|
type: 'split_stepper',
|
|
234
290
|
content: buildSplitStepperContent(run.steps),
|
|
235
291
|
editable: false,
|
|
@@ -237,7 +293,7 @@ export function macroRunToScratchpadState(run: MacroRunV1): ScratchpadState {
|
|
|
237
293
|
}
|
|
238
294
|
: {
|
|
239
295
|
id: 'macro-stepper',
|
|
240
|
-
title:
|
|
296
|
+
title: messages.progressSectionTitle,
|
|
241
297
|
type: 'stepper',
|
|
242
298
|
content: buildStepperContent(run.steps),
|
|
243
299
|
editable: false,
|
|
@@ -252,7 +308,7 @@ export function macroRunToScratchpadState(run: MacroRunV1): ScratchpadState {
|
|
|
252
308
|
id: 'macro-prompt',
|
|
253
309
|
title: run.pendingInterrogation.title,
|
|
254
310
|
type: 'prompt',
|
|
255
|
-
content: macroInterrogationToChatPromptConfig(run.pendingInterrogation),
|
|
311
|
+
content: macroInterrogationToChatPromptConfig(run.pendingInterrogation, options),
|
|
256
312
|
editable: false,
|
|
257
313
|
source: 'agent',
|
|
258
314
|
});
|
|
@@ -265,7 +321,7 @@ export function macroRunToScratchpadState(run: MacroRunV1): ScratchpadState {
|
|
|
265
321
|
results.forEach((component, index) => {
|
|
266
322
|
sections.push({
|
|
267
323
|
id: `macro-result-${String(component?.id ?? index)}`,
|
|
268
|
-
title:
|
|
324
|
+
title: messages.resultSectionTitle,
|
|
269
325
|
type: resultSectionType(component?.type),
|
|
270
326
|
content: component,
|
|
271
327
|
editable: false,
|
|
@@ -282,7 +338,7 @@ export function macroRunToScratchpadState(run: MacroRunV1): ScratchpadState {
|
|
|
282
338
|
status: RUN_STATUS_TO_SCRATCHPAD[run.status],
|
|
283
339
|
};
|
|
284
340
|
|
|
285
|
-
const error = buildError(run);
|
|
341
|
+
const error = buildError(run, messages);
|
|
286
342
|
if (error) state.error = error;
|
|
287
343
|
|
|
288
344
|
return state;
|
|
@@ -311,7 +367,11 @@ function isElicitationSchema(value: unknown): value is ElicitationRequestedSchem
|
|
|
311
367
|
* {@link macroRunToScratchpadState} (which calls it for an embedded
|
|
312
368
|
* `pendingInterrogation`).
|
|
313
369
|
*/
|
|
314
|
-
export function macroInterrogationToChatPromptConfig(
|
|
370
|
+
export function macroInterrogationToChatPromptConfig(
|
|
371
|
+
q: MacroInterrogationV1,
|
|
372
|
+
options: MacroRunAdapterOptions = {}
|
|
373
|
+
): ChatPromptConfig {
|
|
374
|
+
const messages = withMessages(options);
|
|
315
375
|
switch (q.kind) {
|
|
316
376
|
case 'choice': {
|
|
317
377
|
const options: ChoiceOption[] = (q.options ?? []).map((o) => {
|
|
@@ -355,7 +415,7 @@ export function macroInterrogationToChatPromptConfig(q: MacroInterrogationV1): C
|
|
|
355
415
|
return {
|
|
356
416
|
type: 'confirm',
|
|
357
417
|
title: q.title,
|
|
358
|
-
config: { message: q.message ??
|
|
418
|
+
config: { message: q.message ?? messages.confirmDefault },
|
|
359
419
|
};
|
|
360
420
|
}
|
|
361
421
|
}
|
|
@@ -7,6 +7,7 @@ import { Component, For, Show } from 'solid-js'
|
|
|
7
7
|
import type { UIComponent, ActionGroupParams, ActionComponentParams } from '../types'
|
|
8
8
|
import { useAction } from '../hooks/useAction'
|
|
9
9
|
import { safeUrl } from '../utils/safe-url'
|
|
10
|
+
import { useMCPUIStrings } from '../context/MCPUIStringsContext'
|
|
10
11
|
|
|
11
12
|
export interface ActionGroupRendererProps {
|
|
12
13
|
/**
|
|
@@ -147,6 +148,7 @@ const ActionButton: Component<{
|
|
|
147
148
|
* ```
|
|
148
149
|
*/
|
|
149
150
|
export const ActionGroupRenderer: Component<ActionGroupRendererProps> = (props) => {
|
|
151
|
+
const strings = useMCPUIStrings()
|
|
150
152
|
const params = () => props.params || (props.component?.params as ActionGroupParams) || { actions: [] }
|
|
151
153
|
|
|
152
154
|
const layoutClass = () => {
|
|
@@ -181,7 +183,7 @@ export const ActionGroupRenderer: Component<ActionGroupRendererProps> = (props)
|
|
|
181
183
|
<div
|
|
182
184
|
class={`${layoutClass()} ${gapClass()} ${params()?.fullWidth ? 'w-full' : ''}`}
|
|
183
185
|
role="group"
|
|
184
|
-
aria-label={params()?.label ||
|
|
186
|
+
aria-label={params()?.label || strings.actionGroupLabel}
|
|
185
187
|
>
|
|
186
188
|
<For each={params()?.actions || []}>
|
|
187
189
|
{(action, index) => <ActionButton action={action} index={index()} />}
|