@seed-ship/mcp-ui-solid 6.5.0 → 6.6.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/CHANGELOG.md +161 -0
- package/README.md +37 -0
- package/dist/adapters/connector.cjs +112 -0
- package/dist/adapters/connector.cjs.map +1 -0
- package/dist/adapters/connector.d.ts +71 -0
- package/dist/adapters/connector.d.ts.map +1 -0
- package/dist/adapters/connector.js +112 -0
- package/dist/adapters/connector.js.map +1 -0
- package/dist/adapters/index.d.ts +18 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters.cjs +6 -0
- package/dist/adapters.cjs.map +1 -0
- package/dist/adapters.d.cts +18 -0
- package/dist/adapters.d.ts +18 -0
- package/dist/adapters.js +6 -0
- package/dist/adapters.js.map +1 -0
- package/dist/components/ActionGroupRenderer.cjs +12 -3
- package/dist/components/ActionGroupRenderer.cjs.map +1 -1
- package/dist/components/ActionGroupRenderer.d.ts.map +1 -1
- package/dist/components/ActionGroupRenderer.js +12 -3
- package/dist/components/ActionGroupRenderer.js.map +1 -1
- package/dist/components/ExpandableWrapper.cjs +24 -6
- package/dist/components/ExpandableWrapper.cjs.map +1 -1
- package/dist/components/ExpandableWrapper.d.ts.map +1 -1
- package/dist/components/ExpandableWrapper.js +24 -6
- package/dist/components/ExpandableWrapper.js.map +1 -1
- package/dist/components/FeedbackInline.cjs +6 -2
- package/dist/components/FeedbackInline.cjs.map +1 -1
- package/dist/components/FeedbackInline.d.ts +2 -2
- package/dist/components/FeedbackInline.d.ts.map +1 -1
- package/dist/components/FeedbackInline.js +7 -3
- package/dist/components/FeedbackInline.js.map +1 -1
- package/dist/components/PresentationFeedback.cjs +207 -0
- package/dist/components/PresentationFeedback.cjs.map +1 -0
- package/dist/components/PresentationFeedback.d.ts +113 -0
- package/dist/components/PresentationFeedback.d.ts.map +1 -0
- package/dist/components/PresentationFeedback.js +207 -0
- package/dist/components/PresentationFeedback.js.map +1 -0
- package/dist/components/StreamingUIRenderer.cjs +82 -195
- package/dist/components/StreamingUIRenderer.cjs.map +1 -1
- package/dist/components/StreamingUIRenderer.d.ts +25 -5
- package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
- package/dist/components/StreamingUIRenderer.js +84 -197
- package/dist/components/StreamingUIRenderer.js.map +1 -1
- package/dist/components/UIResourceRenderer.cjs +22 -15
- package/dist/components/UIResourceRenderer.cjs.map +1 -1
- package/dist/components/UIResourceRenderer.d.ts.map +1 -1
- package/dist/components/UIResourceRenderer.js +22 -15
- package/dist/components/UIResourceRenderer.js.map +1 -1
- package/dist/components/index.d.ts +2 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components.cjs +3 -0
- package/dist/components.cjs.map +1 -1
- package/dist/components.d.cts +2 -0
- package/dist/components.d.ts +2 -0
- package/dist/components.js +3 -0
- package/dist/components.js.map +1 -1
- package/dist/context/MCPActionContext.cjs +4 -1
- package/dist/context/MCPActionContext.cjs.map +1 -1
- package/dist/context/MCPActionContext.d.ts +13 -1
- package/dist/context/MCPActionContext.d.ts.map +1 -1
- package/dist/context/MCPActionContext.js +4 -1
- package/dist/context/MCPActionContext.js.map +1 -1
- package/dist/context/MCPUIStringsContext.cjs +38 -0
- package/dist/context/MCPUIStringsContext.cjs.map +1 -0
- package/dist/context/MCPUIStringsContext.d.ts +95 -0
- package/dist/context/MCPUIStringsContext.d.ts.map +1 -0
- package/dist/context/MCPUIStringsContext.js +38 -0
- package/dist/context/MCPUIStringsContext.js.map +1 -0
- package/dist/index.cjs +8 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp-ui-spec/dist/schemas.cjs +103 -0
- package/dist/mcp-ui-spec/dist/schemas.cjs.map +1 -1
- package/dist/mcp-ui-spec/dist/schemas.js +103 -0
- package/dist/mcp-ui-spec/dist/schemas.js.map +1 -1
- package/docs/briefs/ROADMAP-opendata-macro-mcpui.md +912 -0
- package/package.json +17 -5
- package/src/adapters/connector.test.ts +165 -0
- package/src/adapters/connector.ts +234 -0
- package/src/adapters/index.ts +24 -0
- package/src/components/ActionGroupRenderer.test.tsx +1 -0
- package/src/components/ActionGroupRenderer.tsx +19 -4
- package/src/components/ActionSubmit.test.tsx +188 -0
- package/src/components/ExpandableWrapper.test.tsx +5 -2
- package/src/components/ExpandableWrapper.tsx +8 -6
- package/src/components/FeedbackInline.test.tsx +6 -3
- package/src/components/FeedbackInline.tsx +8 -6
- package/src/components/PresentationFeedback.test.tsx +163 -0
- package/src/components/PresentationFeedback.tsx +326 -0
- package/src/components/StreamingUIRenderer.parity.test.tsx +158 -0
- package/src/components/StreamingUIRenderer.tsx +42 -166
- package/src/components/UIResourceRenderer.tsx +19 -6
- package/src/components/index.ts +10 -0
- package/src/context/MCPActionContext.tsx +17 -1
- package/src/context/MCPUIStringsContext.test.tsx +116 -0
- package/src/context/MCPUIStringsContext.tsx +128 -0
- package/src/index.ts +27 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/vite.config.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,167 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [6.6.1] - 2026-05-22
|
|
9
|
+
|
|
10
|
+
### Fixed — `action: 'submit'` is no longer inert outside a `<form>`
|
|
11
|
+
|
|
12
|
+
`ActionParamsSchema.action` allows `'tool-call' | 'link' | 'submit'`, but
|
|
13
|
+
at runtime `submit` did nothing : `ActionGroupRenderer` only branched on
|
|
14
|
+
`tool-call` / `link`, and the standalone `action` renderer emitted a
|
|
15
|
+
native `type="submit"` button — which only fires inside a real `<form>`.
|
|
16
|
+
Standalone resources rendered by `<UIResourceRenderer>` have no
|
|
17
|
+
surrounding form, so the click was inert.
|
|
18
|
+
|
|
19
|
+
`submit` actions now route through the host executor — like `tool-call`,
|
|
20
|
+
but **not treated as a tool call** :
|
|
21
|
+
|
|
22
|
+
- `<ActionGroupRenderer>` and the standalone `action` renderer both call
|
|
23
|
+
`executeAction({ action: 'submit', toolName, params })` on click.
|
|
24
|
+
- The action **kind** is preserved : `ActionRequest` gains an optional
|
|
25
|
+
`action?: 'tool-call' | 'submit' | 'link'` field so a host `executor`
|
|
26
|
+
can tell a submit apart from a tool call (e.g. POST to
|
|
27
|
+
`params.submit_url`). The full `params` payload (`submit_url`,
|
|
28
|
+
`connector_id`, `feedback_value`, `preferred_layout`, …) is passed
|
|
29
|
+
through intact.
|
|
30
|
+
- The submit button is now `type="button"` (JS-handled) — it works with
|
|
31
|
+
no surrounding `<form>`, and shows the same loading / disabled state as
|
|
32
|
+
a `tool-call` button.
|
|
33
|
+
- The `defaultExecutor` `mcp-action` `CustomEvent` detail now carries
|
|
34
|
+
`action`, so a window-level listener can route submits too.
|
|
35
|
+
|
|
36
|
+
Backward compatible : `action` is optional everywhere and absent on every
|
|
37
|
+
pre-6.6.1 request — a request without it is still treated as `tool-call`.
|
|
38
|
+
|
|
39
|
+
## [6.6.0] - 2026-05-21
|
|
40
|
+
|
|
41
|
+
Sprint OpenData / macros — cf. `docs/briefs/ROADMAP-opendata-macro-mcpui.md`
|
|
42
|
+
(decisions D1-D10 + R1-R4). Ships steps 1-5 of the execution order :
|
|
43
|
+
`StreamingUIRenderer` parity, `MCPUIStringsProvider`, the
|
|
44
|
+
`ConnectorDynamicResultV1` contract consumption, `PresentationFeedback`,
|
|
45
|
+
and the opt-in connector adapters. The macro adapters are deferred to a
|
|
46
|
+
later phase (they need a macro-run contract). Pairs with
|
|
47
|
+
`@seed-ship/mcp-ui-spec@5.1.0`.
|
|
48
|
+
|
|
49
|
+
### Added — opt-in connector adapters (`@seed-ship/mcp-ui-solid/adapters`) (D5 / D6)
|
|
50
|
+
|
|
51
|
+
New dedicated subpath export — **never** imported by the core renderer
|
|
52
|
+
path, so consumers that don't emit connector results pay nothing for it:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { connectorResultToUILayout } from '@seed-ship/mcp-ui-solid/adapters'
|
|
56
|
+
|
|
57
|
+
const layout = connectorResultToUILayout(connectorResult)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
- `connectorResultToUILayout(result)` — assembles a `ConnectorDynamicResultV1`
|
|
61
|
+
(`primary` + `supplemental[]` + `actions`) into one `UILayout`. **Pure**
|
|
62
|
+
(D5) — deterministic, no side effects, safe to re-run after feedback.
|
|
63
|
+
- `connectorActionsToActionGroup(actions)` — wraps connector actions into
|
|
64
|
+
an `action-group` `UIComponent`.
|
|
65
|
+
- **Unknown `schemaVersion` never throws** (R2) : a usable-but-unversioned
|
|
66
|
+
envelope still renders, prefixed with a visible warning notice ; a truly
|
|
67
|
+
unreadable payload becomes an explicit degraded `UILayout` (a `text`
|
|
68
|
+
notice with id `connector-degraded`). Never a silent disappearance.
|
|
69
|
+
|
|
70
|
+
**Scope note** : this ships the *connector* adapters. The *macro* adapters
|
|
71
|
+
(`macroRunToScratchpadState`, `macroInterrogationToChatPromptConfig`) are
|
|
72
|
+
deferred — they need a macro-run contract that the roadmap leaves to
|
|
73
|
+
Phase 2.
|
|
74
|
+
|
|
75
|
+
### Added — `PresentationFeedback` component (R3 / D9 / Phase 4)
|
|
76
|
+
|
|
77
|
+
A new opt-in feedback widget — **distinct** from `FeedbackInline` :
|
|
78
|
+
|
|
79
|
+
- `FeedbackInline` — was the *answer* good? (response quality)
|
|
80
|
+
- `PresentationFeedback` — was the answer *shown well*? (layout / readability)
|
|
81
|
+
|
|
82
|
+
They are separate components, separate exports, separate payloads — the
|
|
83
|
+
two axes never collapse (cf. R3). `PresentationFeedback` collects a
|
|
84
|
+
`verdict` (`readable` / `not_readable`) and, when not readable, problem
|
|
85
|
+
tags + an optional preferred layout + a free-text comment, then emits a
|
|
86
|
+
`ConnectorRenderFeedback` payload via `onSubmit`.
|
|
87
|
+
|
|
88
|
+
- Stateless : the host persists the feedback and owns any re-render
|
|
89
|
+
(cf. D1 — adapter pure + host state). The component never mutates the
|
|
90
|
+
rendered result.
|
|
91
|
+
- Best-effort : a rejected `onSubmit` promise is swallowed, the UI flips.
|
|
92
|
+
- Localizable : all labels ship in English, overridable via the `labels`
|
|
93
|
+
prop (`DEFAULT_PRESENTATION_FEEDBACK_LABELS` exported).
|
|
94
|
+
- `ConnectorRenderFeedback` / `ConnectorRenderProblem` /
|
|
95
|
+
`ConnectorPreferredLayout` types are re-exported from the package root
|
|
96
|
+
for convenience (defined in `@seed-ship/mcp-ui-spec`).
|
|
97
|
+
|
|
98
|
+
### Added — `MCPUIStringsProvider` : i18n for the library's chrome (D2 / R4)
|
|
99
|
+
|
|
100
|
+
MCP-UI hardcoded a handful of its own UI strings (the expand-button
|
|
101
|
+
tooltip, the feedback acknowledgements…) — and they were an inconsistent
|
|
102
|
+
FR/EN mix. New opt-in context to localize them :
|
|
103
|
+
|
|
104
|
+
```tsx
|
|
105
|
+
import { MCPUIStringsProvider } from '@seed-ship/mcp-ui-solid'
|
|
106
|
+
|
|
107
|
+
<MCPUIStringsProvider strings={{ expand: 'Agrandir', feedbackUseful: 'Utile' }}>
|
|
108
|
+
<App />
|
|
109
|
+
</MCPUIStringsProvider>
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
- `MCPUIStrings` — flat string map of the library's own "chrome" strings.
|
|
113
|
+
**Content** (table headers, chart titles, action labels) is NOT covered:
|
|
114
|
+
it comes from the payload, already localized by the producer.
|
|
115
|
+
- `DEFAULT_MCPUI_STRINGS` — English defaults. A published library ships no
|
|
116
|
+
hardcoded non-English chrome.
|
|
117
|
+
- `<MCPUIStringsProvider strings={...}>` — partial override; unset keys fall
|
|
118
|
+
back to the EN defaults.
|
|
119
|
+
- `useMCPUIStrings()` — reads the active strings; returns the EN defaults
|
|
120
|
+
when no provider is mounted (every renderer works standalone).
|
|
121
|
+
|
|
122
|
+
Wired consumers : `FeedbackInline` (button tooltips + acks),
|
|
123
|
+
`ExpandableWrapper` (expand / copy / close chrome), `StreamingUIRenderer`
|
|
124
|
+
(retry button). Component props that already carry a label
|
|
125
|
+
(`FeedbackInline.positiveAck`, `ExpandableWrapper.copyLabel`) keep priority
|
|
126
|
+
over the provider.
|
|
127
|
+
|
|
128
|
+
**Behavior change** : `FeedbackInline`'s ack defaults were French
|
|
129
|
+
(`'Merci !'`, `"Noté, on s'améliore"`) — they are now English
|
|
130
|
+
(`'Thanks!'`, `"Noted — we'll improve"`). Consumers relying on the FR
|
|
131
|
+
defaults pass a `<MCPUIStringsProvider>` with FR strings, or the
|
|
132
|
+
`positiveAck` / `negativeAck` props. `ExpandableWrapper`'s default heading
|
|
133
|
+
casing was also unified to `'Expanded view'` (it was inconsistently
|
|
134
|
+
`'Expanded View'` for the heading vs `'Expanded view'` for the aria-label).
|
|
135
|
+
|
|
136
|
+
### Changed — `StreamingUIRenderer` renders with full fidelity (Gap 1 / D3)
|
|
137
|
+
|
|
138
|
+
`StreamingUIRenderer` previously rendered each streamed component through an
|
|
139
|
+
inline simplified renderer (`StreamingComponentRenderer`) that only showed a
|
|
140
|
+
type label, the title, and — for metrics — the value. A streamed `table` /
|
|
141
|
+
`chart` / `map` did NOT render the real component.
|
|
142
|
+
|
|
143
|
+
Each streamed `UIComponent` is now delegated to the real
|
|
144
|
+
`<UIResourceRenderer>`. Streaming and static paths use the literal same
|
|
145
|
+
renderer, so they cannot drift. Validation, telemetry, the error boundary
|
|
146
|
+
and `errorMode` all come from `<UIResourceRenderer>` — the duplicated copies
|
|
147
|
+
in the streaming path are deleted.
|
|
148
|
+
|
|
149
|
+
- New `toolbarVariant` prop on `<StreamingUIRenderer>`, forwarded to streamed
|
|
150
|
+
components (parity with the static `<UIResourceRenderer toolbarVariant>`).
|
|
151
|
+
- Delegation is a one-way value import — `UIResourceRenderer` never imports
|
|
152
|
+
`StreamingUIRenderer`, no cycle.
|
|
153
|
+
- Progress bar, skeletons, arrival animation and metadata display unchanged.
|
|
154
|
+
- The streamed component's grid `position` is normalized to full-width
|
|
155
|
+
before delegation: `StreamingUIRenderer` owns the 12-column layout,
|
|
156
|
+
`<UIResourceRenderer>` only renders the component.
|
|
157
|
+
|
|
158
|
+
### Changed — `size-limit` budgets
|
|
159
|
+
|
|
160
|
+
The "Streaming renderer" `size-limit` budget was raised from 30 KB to 1 MB.
|
|
161
|
+
Post-D3 that entry's reachable graph equals the full renderer set, and
|
|
162
|
+
`size-limit` measures the pre-built `dist/` including lazy `import()` chunks
|
|
163
|
+
(leaflet, `@antv/g6`, chart.js) that are fetched on demand, not at import.
|
|
164
|
+
The figure is a worst-case total, not eager load cost — the budget is
|
|
165
|
+
generous headroom, since `size-limit` here is a regression guardrail and
|
|
166
|
+
does not gate CI. The "Hooks only" and "Full bundle" entries are unchanged —
|
|
167
|
+
their pre-existing overages predate this sprint.
|
|
168
|
+
|
|
8
169
|
## [6.5.0] - 2026-05-05
|
|
9
170
|
|
|
10
171
|
Closes Demande 1 + Demande 2 of `deposium_solid`'s
|
package/README.md
CHANGED
|
@@ -5,6 +5,43 @@ SolidJS components + chat toolkit for MCP-generated UI. Part of the [MCP UI ecos
|
|
|
5
5
|
[](https://www.npmjs.com/package/@seed-ship/mcp-ui-solid)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
|
+
## What's New in v6.6.0
|
|
9
|
+
|
|
10
|
+
Sprint OpenData / macros — `docs/briefs/ROADMAP-opendata-macro-mcpui.md`.
|
|
11
|
+
|
|
12
|
+
- **`StreamingUIRenderer` renders with full fidelity** — each streamed
|
|
13
|
+
component is now delegated to the real `<UIResourceRenderer>`. A streamed
|
|
14
|
+
`table` / `chart` / `map` renders exactly like a static one (no more
|
|
15
|
+
simplified type-label placeholder). New `toolbarVariant` prop forwarded
|
|
16
|
+
to streamed components.
|
|
17
|
+
- **`<MCPUIStringsProvider>`** — opt-in i18n for the library's own *chrome*
|
|
18
|
+
strings (expand tooltip, feedback acks…). English defaults; override
|
|
19
|
+
partially. Payload *content* is untouched — it stays the producer's job.
|
|
20
|
+
|
|
21
|
+
```tsx
|
|
22
|
+
import { MCPUIStringsProvider } from '@seed-ship/mcp-ui-solid'
|
|
23
|
+
<MCPUIStringsProvider strings={{ expand: 'Agrandir' }}><App /></MCPUIStringsProvider>
|
|
24
|
+
```
|
|
25
|
+
- **`<PresentationFeedback>`** — a feedback widget for how a result was
|
|
26
|
+
*presented* (layout / readability), distinct from `FeedbackInline`
|
|
27
|
+
(response quality). Emits a `ConnectorRenderFeedback` payload; stateless
|
|
28
|
+
(the host persists + re-renders).
|
|
29
|
+
- **`@seed-ship/mcp-ui-solid/adapters`** — new opt-in subpath.
|
|
30
|
+
`connectorResultToUILayout()` assembles a `ConnectorDynamicResultV1` into
|
|
31
|
+
a `UILayout`; `connectorActionsToActionGroup()` wraps connector actions.
|
|
32
|
+
Pure functions; an unknown `schemaVersion` degrades gracefully, never
|
|
33
|
+
throws.
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
import { connectorResultToUILayout } from '@seed-ship/mcp-ui-solid/adapters'
|
|
37
|
+
const layout = connectorResultToUILayout(connectorResult)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
> **Note** — `FeedbackInline`'s acknowledgement defaults changed from
|
|
41
|
+
> French to English (`'Thanks!'`, `"Noted — we'll improve"`). Wrap your app
|
|
42
|
+
> in `<MCPUIStringsProvider>` with French strings, or pass `positiveAck` /
|
|
43
|
+
> `negativeAck`, to restore French.
|
|
44
|
+
|
|
8
45
|
## What's New in v5.2.0 (`mcp-ui-solid` only)
|
|
9
46
|
|
|
10
47
|
- **`createChatPromptController()`** primitive — closes the v5.1.0 boilerplate. Owns resolver closure + `AbortSignal` wiring + re-entrance. Consumers write `bus.commands.handle('showChatPrompt', ctrl.handle)` + `<Show when={ctrl.activePrompt()}>{cfg => <ChatPrompt ... />}</Show>`. `PromptReplacedError` exported for `instanceof` checks.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const schemas = require("../mcp-ui-spec/dist/schemas.cjs");
|
|
4
|
+
const types = require("../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.cjs");
|
|
5
|
+
function connectorActionsToActionGroup(actions, options = {}) {
|
|
6
|
+
return {
|
|
7
|
+
id: options.id ?? "connector-actions",
|
|
8
|
+
type: "action-group",
|
|
9
|
+
position: options.position ?? { colStart: 1, colSpan: 12 },
|
|
10
|
+
params: {
|
|
11
|
+
actions,
|
|
12
|
+
...options.title ? { title: options.title } : {},
|
|
13
|
+
layout: options.layout ?? "horizontal",
|
|
14
|
+
gap: options.gap ?? "md"
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
const LenientResultSchema = types.object({
|
|
19
|
+
schemaVersion: types.string(),
|
|
20
|
+
connectorId: types.string().min(1),
|
|
21
|
+
toolName: types.string().min(1),
|
|
22
|
+
query: types.string(),
|
|
23
|
+
queryHash: types.string().optional(),
|
|
24
|
+
intent: types.string().optional(),
|
|
25
|
+
primary: types.record(types.unknown()),
|
|
26
|
+
supplemental: types.array(types.record(types.unknown())).optional(),
|
|
27
|
+
actions: types.array(types.record(types.unknown())).optional()
|
|
28
|
+
});
|
|
29
|
+
const DEFAULT_GRID = { columns: 12, gap: "1rem" };
|
|
30
|
+
function withPosition(component) {
|
|
31
|
+
if (component && component.position) return component;
|
|
32
|
+
return { ...component, position: { colStart: 1, colSpan: 12 } };
|
|
33
|
+
}
|
|
34
|
+
function isLayoutShape(value) {
|
|
35
|
+
return Array.isArray(value.components);
|
|
36
|
+
}
|
|
37
|
+
function degradedTextComponent(id, message) {
|
|
38
|
+
return {
|
|
39
|
+
id,
|
|
40
|
+
type: "text",
|
|
41
|
+
position: { colStart: 1, colSpan: 12 },
|
|
42
|
+
params: { markdown: true, content: message }
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function connectorResultToUILayout(result, options = {}) {
|
|
46
|
+
const strict = schemas.ConnectorDynamicResultV1Schema.safeParse(result);
|
|
47
|
+
if (!strict.success) {
|
|
48
|
+
const lenient = LenientResultSchema.safeParse(result);
|
|
49
|
+
if (!lenient.success) {
|
|
50
|
+
const version = result && typeof result === "object" ? result.schemaVersion : void 0;
|
|
51
|
+
return {
|
|
52
|
+
id: "connector-degraded",
|
|
53
|
+
components: [
|
|
54
|
+
degradedTextComponent(
|
|
55
|
+
"connector-degraded-notice",
|
|
56
|
+
`### Résultat non rendu
|
|
57
|
+
|
|
58
|
+
Le résultat du connecteur n'a pas pu être interprété${typeof version === "string" ? ` (schéma : \`${version}\`)` : ""}. Cet état explicite remplace une disparition silencieuse du rendu.`
|
|
59
|
+
)
|
|
60
|
+
],
|
|
61
|
+
grid: { ...DEFAULT_GRID }
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const r2 = lenient.data;
|
|
65
|
+
const components2 = [
|
|
66
|
+
degradedTextComponent(
|
|
67
|
+
"connector-version-warning",
|
|
68
|
+
`> ⚠ Schéma connecteur non reconnu (\`${r2.schemaVersion}\`, attendu \`${schemas.CONNECTOR_DYNAMIC_RESULT_V1}\`). Le rendu ci-dessous est en mode dégradé.`
|
|
69
|
+
),
|
|
70
|
+
...collectComponents(r2)
|
|
71
|
+
];
|
|
72
|
+
return {
|
|
73
|
+
id: options.id ?? `connector-degraded-${r2.connectorId}`,
|
|
74
|
+
components: components2.map(withPosition),
|
|
75
|
+
grid: { ...DEFAULT_GRID }
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const r = strict.data;
|
|
79
|
+
const components = collectComponents(r, options.actionsTitle).map(withPosition);
|
|
80
|
+
return {
|
|
81
|
+
id: options.id ?? layoutId(r.connectorId, r.queryHash ?? r.toolName),
|
|
82
|
+
components,
|
|
83
|
+
grid: { ...DEFAULT_GRID }
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function collectComponents(r, actionsTitle) {
|
|
87
|
+
const components = [];
|
|
88
|
+
if (isLayoutShape(r.primary)) {
|
|
89
|
+
const inner = r.primary.components ?? [];
|
|
90
|
+
components.push(...inner);
|
|
91
|
+
} else {
|
|
92
|
+
components.push(r.primary);
|
|
93
|
+
}
|
|
94
|
+
if (r.supplemental) {
|
|
95
|
+
components.push(...r.supplemental);
|
|
96
|
+
}
|
|
97
|
+
if (Array.isArray(r.actions) && r.actions.length > 0) {
|
|
98
|
+
components.push(
|
|
99
|
+
connectorActionsToActionGroup(r.actions, {
|
|
100
|
+
id: "connector-actions",
|
|
101
|
+
title: actionsTitle
|
|
102
|
+
})
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
return components;
|
|
106
|
+
}
|
|
107
|
+
function layoutId(connectorId, suffix) {
|
|
108
|
+
return `connector-${connectorId}-${suffix}`;
|
|
109
|
+
}
|
|
110
|
+
exports.connectorActionsToActionGroup = connectorActionsToActionGroup;
|
|
111
|
+
exports.connectorResultToUILayout = connectorResultToUILayout;
|
|
112
|
+
//# sourceMappingURL=connector.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector.cjs","sources":["../../src/adapters/connector.ts"],"sourcesContent":["/**\n * Connector adapters — `ConnectorDynamicResultV1` → MCP-UI render structures.\n *\n * @since v6.6.0 (D5 / D6 of ROADMAP-opendata-macro-mcpui)\n *\n * ## Opt-in, pure\n *\n * These adapters are published under the dedicated subpath\n * `@seed-ship/mcp-ui-solid/adapters` — they are NEVER imported by the core\n * renderer path, so a consumer that does not emit connector results pays\n * nothing for them.\n *\n * Every adapter here is a **pure function** (D5) : same input → same\n * output, no `fetch`, no `localStorage`, no global state, no clock, no\n * randomness. This is what lets a host re-run an adapter deterministically\n * after presentation feedback (D1) and replay fixtures in tests.\n *\n * ## Unknown schema version — never throw (R2)\n *\n * `connectorResultToUILayout()` never throws on the runtime render path.\n * A payload it cannot read becomes an explicit degraded `UILayout` (a\n * visible notice), never a silent disappearance and never an exception.\n */\n\nimport type { UIComponent, UILayout, GridPosition } from '../types'\nimport {\n ConnectorDynamicResultV1Schema,\n CONNECTOR_DYNAMIC_RESULT_V1,\n type ConnectorAction,\n} from '@seed-ship/mcp-ui-spec'\nimport { z } from 'zod'\n\n// ─────────────────────────────────────────────────────────────\n// connectorActionsToActionGroup\n// ─────────────────────────────────────────────────────────────\n\nexport interface ConnectorActionsToActionGroupOptions {\n /** Component id. Default `'connector-actions'`. */\n id?: string\n /** Optional heading shown above the buttons. */\n title?: string\n /** Button row layout. Default `'horizontal'`. */\n layout?: 'horizontal' | 'vertical' | 'space-between' | 'end' | 'center'\n /** Gap between buttons. Default `'md'`. */\n gap?: 'none' | 'sm' | 'md' | 'lg'\n /** Grid position. Default full-width. */\n position?: GridPosition\n}\n\n/**\n * Wraps a connector's `actions` into an `action-group` `UIComponent`.\n *\n * `ConnectorAction` is the exact `action-group` action shape, so this is a\n * thin, pure envelope — no transformation of the actions themselves.\n */\nexport function connectorActionsToActionGroup(\n actions: ConnectorAction[],\n options: ConnectorActionsToActionGroupOptions = {}\n): UIComponent {\n return {\n id: options.id ?? 'connector-actions',\n type: 'action-group',\n position: options.position ?? { colStart: 1, colSpan: 12 },\n params: {\n actions,\n ...(options.title ? { title: options.title } : {}),\n layout: options.layout ?? 'horizontal',\n gap: options.gap ?? 'md',\n },\n } as UIComponent\n}\n\n// ─────────────────────────────────────────────────────────────\n// connectorResultToUILayout\n// ─────────────────────────────────────────────────────────────\n\nexport interface ConnectorResultToUILayoutOptions {\n /** Layout id. Default derived from `connectorId` + `queryHash` / `toolName`. */\n id?: string\n /** Heading for the actions `action-group`. */\n actionsTitle?: string\n}\n\n/**\n * Lenient mirror of `ConnectorDynamicResultV1Schema` — `schemaVersion`\n * relaxed to any string. Used to tell apart \"unknown version but otherwise\n * a usable envelope\" (→ render with a warning, R2) from \"truly unreadable\"\n * (→ explicit error state).\n */\nconst LenientResultSchema = z.object({\n schemaVersion: z.string(),\n connectorId: z.string().min(1),\n toolName: z.string().min(1),\n query: z.string(),\n queryHash: z.string().optional(),\n intent: z.string().optional(),\n primary: z.record(z.unknown()),\n supplemental: z.array(z.record(z.unknown())).optional(),\n actions: z.array(z.record(z.unknown())).optional(),\n})\n\nconst DEFAULT_GRID = { columns: 12, gap: '1rem' } as const\n\nfunction withPosition(component: UIComponent): UIComponent {\n if (component && component.position) return component\n return { ...component, position: { colStart: 1, colSpan: 12 } }\n}\n\n/** A component is a UILayout when it carries a `components` array. */\nfunction isLayoutShape(value: Record<string, unknown>): boolean {\n return Array.isArray((value as { components?: unknown }).components)\n}\n\nfunction degradedTextComponent(id: string, message: string): UIComponent {\n return {\n id,\n type: 'text',\n position: { colStart: 1, colSpan: 12 },\n params: { markdown: true, content: message },\n } as UIComponent\n}\n\n/**\n * Assembles a `ConnectorDynamicResultV1` into a single `UILayout` :\n * `primary` + `supplemental[]` + (`actions` → an `action-group`).\n *\n * - When `primary` is itself a layout, its components are spread in.\n * - Raw data is never sacrificed — every supplied component is kept.\n * - Pure : no side effects, deterministic.\n *\n * ### Degraded behavior (R2)\n *\n * - Valid v1 payload → normal assembled layout.\n * - Unknown `schemaVersion` but an otherwise-usable envelope → the\n * components are still rendered, prefixed with a visible warning notice.\n * - Unreadable payload → an explicit error `UILayout` (a single `text`\n * notice). Never throws, never returns an empty layout silently.\n *\n * A degraded layout always has an `id` starting with `connector-degraded`,\n * so a host can detect it (e.g. for telemetry) without inspecting content.\n */\nexport function connectorResultToUILayout(\n result: unknown,\n options: ConnectorResultToUILayoutOptions = {}\n): UILayout {\n const strict = ConnectorDynamicResultV1Schema.safeParse(result)\n\n // ── Tier 3 : unreadable ───────────────────────────────────\n if (!strict.success) {\n const lenient = LenientResultSchema.safeParse(result)\n if (!lenient.success) {\n const version =\n result && typeof result === 'object'\n ? (result as { schemaVersion?: unknown }).schemaVersion\n : undefined\n return {\n id: 'connector-degraded',\n components: [\n degradedTextComponent(\n 'connector-degraded-notice',\n `### Résultat non rendu\\n\\nLe résultat du connecteur n'a pas pu être interprété${\n typeof version === 'string' ? ` (schéma : \\`${version}\\`)` : ''\n }. Cet état explicite remplace une disparition silencieuse du rendu.`\n ),\n ],\n grid: { ...DEFAULT_GRID },\n }\n }\n // ── Tier 2 : usable envelope, unknown version ───────────\n const r = lenient.data\n const components: UIComponent[] = [\n degradedTextComponent(\n 'connector-version-warning',\n `> ⚠ Schéma connecteur non reconnu (\\`${r.schemaVersion}\\`, attendu \\`${CONNECTOR_DYNAMIC_RESULT_V1}\\`). Le rendu ci-dessous est en mode dégradé.`\n ),\n ...collectComponents(r),\n ]\n return {\n id: options.id ?? `connector-degraded-${r.connectorId}`,\n components: components.map(withPosition),\n grid: { ...DEFAULT_GRID },\n }\n }\n\n // ── Tier 1 : valid v1 ─────────────────────────────────────\n const r = strict.data\n const components = collectComponents(r, options.actionsTitle).map(withPosition)\n return {\n id: options.id ?? layoutId(r.connectorId, r.queryHash ?? r.toolName),\n components,\n grid: { ...DEFAULT_GRID },\n }\n}\n\n/**\n * Flattens `primary` + `supplemental` + `actions` into a component list.\n * Shared by the valid and degraded-but-usable paths.\n */\nfunction collectComponents(\n r: {\n primary: Record<string, unknown>\n supplemental?: Record<string, unknown>[]\n actions?: unknown[]\n },\n actionsTitle?: string\n): UIComponent[] {\n const components: UIComponent[] = []\n\n if (isLayoutShape(r.primary)) {\n const inner = (r.primary as { components?: UIComponent[] }).components ?? []\n components.push(...inner)\n } else {\n components.push(r.primary as unknown as UIComponent)\n }\n\n if (r.supplemental) {\n components.push(...(r.supplemental as unknown as UIComponent[]))\n }\n\n if (Array.isArray(r.actions) && r.actions.length > 0) {\n components.push(\n connectorActionsToActionGroup(r.actions as ConnectorAction[], {\n id: 'connector-actions',\n title: actionsTitle,\n })\n )\n }\n\n return components\n}\n\nfunction layoutId(connectorId: string, suffix: string): string {\n return `connector-${connectorId}-${suffix}`\n}\n"],"names":["z.object","z.string","z.record","z.unknown","z.array","ConnectorDynamicResultV1Schema","r","components","CONNECTOR_DYNAMIC_RESULT_V1"],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Connector adapters — `ConnectorDynamicResultV1` → MCP-UI render structures.
|
|
3
|
+
*
|
|
4
|
+
* @since v6.6.0 (D5 / D6 of ROADMAP-opendata-macro-mcpui)
|
|
5
|
+
*
|
|
6
|
+
* ## Opt-in, pure
|
|
7
|
+
*
|
|
8
|
+
* These adapters are published under the dedicated subpath
|
|
9
|
+
* `@seed-ship/mcp-ui-solid/adapters` — they are NEVER imported by the core
|
|
10
|
+
* renderer path, so a consumer that does not emit connector results pays
|
|
11
|
+
* nothing for them.
|
|
12
|
+
*
|
|
13
|
+
* Every adapter here is a **pure function** (D5) : same input → same
|
|
14
|
+
* output, no `fetch`, no `localStorage`, no global state, no clock, no
|
|
15
|
+
* randomness. This is what lets a host re-run an adapter deterministically
|
|
16
|
+
* after presentation feedback (D1) and replay fixtures in tests.
|
|
17
|
+
*
|
|
18
|
+
* ## Unknown schema version — never throw (R2)
|
|
19
|
+
*
|
|
20
|
+
* `connectorResultToUILayout()` never throws on the runtime render path.
|
|
21
|
+
* A payload it cannot read becomes an explicit degraded `UILayout` (a
|
|
22
|
+
* visible notice), never a silent disappearance and never an exception.
|
|
23
|
+
*/
|
|
24
|
+
import type { UIComponent, UILayout, GridPosition } from '../types';
|
|
25
|
+
import { type ConnectorAction } from '@seed-ship/mcp-ui-spec';
|
|
26
|
+
export interface ConnectorActionsToActionGroupOptions {
|
|
27
|
+
/** Component id. Default `'connector-actions'`. */
|
|
28
|
+
id?: string;
|
|
29
|
+
/** Optional heading shown above the buttons. */
|
|
30
|
+
title?: string;
|
|
31
|
+
/** Button row layout. Default `'horizontal'`. */
|
|
32
|
+
layout?: 'horizontal' | 'vertical' | 'space-between' | 'end' | 'center';
|
|
33
|
+
/** Gap between buttons. Default `'md'`. */
|
|
34
|
+
gap?: 'none' | 'sm' | 'md' | 'lg';
|
|
35
|
+
/** Grid position. Default full-width. */
|
|
36
|
+
position?: GridPosition;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Wraps a connector's `actions` into an `action-group` `UIComponent`.
|
|
40
|
+
*
|
|
41
|
+
* `ConnectorAction` is the exact `action-group` action shape, so this is a
|
|
42
|
+
* thin, pure envelope — no transformation of the actions themselves.
|
|
43
|
+
*/
|
|
44
|
+
export declare function connectorActionsToActionGroup(actions: ConnectorAction[], options?: ConnectorActionsToActionGroupOptions): UIComponent;
|
|
45
|
+
export interface ConnectorResultToUILayoutOptions {
|
|
46
|
+
/** Layout id. Default derived from `connectorId` + `queryHash` / `toolName`. */
|
|
47
|
+
id?: string;
|
|
48
|
+
/** Heading for the actions `action-group`. */
|
|
49
|
+
actionsTitle?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Assembles a `ConnectorDynamicResultV1` into a single `UILayout` :
|
|
53
|
+
* `primary` + `supplemental[]` + (`actions` → an `action-group`).
|
|
54
|
+
*
|
|
55
|
+
* - When `primary` is itself a layout, its components are spread in.
|
|
56
|
+
* - Raw data is never sacrificed — every supplied component is kept.
|
|
57
|
+
* - Pure : no side effects, deterministic.
|
|
58
|
+
*
|
|
59
|
+
* ### Degraded behavior (R2)
|
|
60
|
+
*
|
|
61
|
+
* - Valid v1 payload → normal assembled layout.
|
|
62
|
+
* - Unknown `schemaVersion` but an otherwise-usable envelope → the
|
|
63
|
+
* components are still rendered, prefixed with a visible warning notice.
|
|
64
|
+
* - Unreadable payload → an explicit error `UILayout` (a single `text`
|
|
65
|
+
* notice). Never throws, never returns an empty layout silently.
|
|
66
|
+
*
|
|
67
|
+
* A degraded layout always has an `id` starting with `connector-degraded`,
|
|
68
|
+
* so a host can detect it (e.g. for telemetry) without inspecting content.
|
|
69
|
+
*/
|
|
70
|
+
export declare function connectorResultToUILayout(result: unknown, options?: ConnectorResultToUILayoutOptions): UILayout;
|
|
71
|
+
//# sourceMappingURL=connector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../src/adapters/connector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AACnE,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,wBAAwB,CAAA;AAO/B,MAAM,WAAW,oCAAoC;IACnD,mDAAmD;IACnD,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iDAAiD;IACjD,MAAM,CAAC,EAAE,YAAY,GAAG,UAAU,GAAG,eAAe,GAAG,KAAK,GAAG,QAAQ,CAAA;IACvE,2CAA2C;IAC3C,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;IACjC,yCAAyC;IACzC,QAAQ,CAAC,EAAE,YAAY,CAAA;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,eAAe,EAAE,EAC1B,OAAO,GAAE,oCAAyC,GACjD,WAAW,CAYb;AAMD,MAAM,WAAW,gCAAgC;IAC/C,gFAAgF;IAChF,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,8CAA8C;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAyCD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,gCAAqC,GAC7C,QAAQ,CAgDV"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { ConnectorDynamicResultV1Schema, CONNECTOR_DYNAMIC_RESULT_V1 } from "../mcp-ui-spec/dist/schemas.js";
|
|
2
|
+
import { object as objectType, array as arrayType, record as recordType, string as stringType, unknown as unknownType } from "../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js";
|
|
3
|
+
function connectorActionsToActionGroup(actions, options = {}) {
|
|
4
|
+
return {
|
|
5
|
+
id: options.id ?? "connector-actions",
|
|
6
|
+
type: "action-group",
|
|
7
|
+
position: options.position ?? { colStart: 1, colSpan: 12 },
|
|
8
|
+
params: {
|
|
9
|
+
actions,
|
|
10
|
+
...options.title ? { title: options.title } : {},
|
|
11
|
+
layout: options.layout ?? "horizontal",
|
|
12
|
+
gap: options.gap ?? "md"
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const LenientResultSchema = objectType({
|
|
17
|
+
schemaVersion: stringType(),
|
|
18
|
+
connectorId: stringType().min(1),
|
|
19
|
+
toolName: stringType().min(1),
|
|
20
|
+
query: stringType(),
|
|
21
|
+
queryHash: stringType().optional(),
|
|
22
|
+
intent: stringType().optional(),
|
|
23
|
+
primary: recordType(unknownType()),
|
|
24
|
+
supplemental: arrayType(recordType(unknownType())).optional(),
|
|
25
|
+
actions: arrayType(recordType(unknownType())).optional()
|
|
26
|
+
});
|
|
27
|
+
const DEFAULT_GRID = { columns: 12, gap: "1rem" };
|
|
28
|
+
function withPosition(component) {
|
|
29
|
+
if (component && component.position) return component;
|
|
30
|
+
return { ...component, position: { colStart: 1, colSpan: 12 } };
|
|
31
|
+
}
|
|
32
|
+
function isLayoutShape(value) {
|
|
33
|
+
return Array.isArray(value.components);
|
|
34
|
+
}
|
|
35
|
+
function degradedTextComponent(id, message) {
|
|
36
|
+
return {
|
|
37
|
+
id,
|
|
38
|
+
type: "text",
|
|
39
|
+
position: { colStart: 1, colSpan: 12 },
|
|
40
|
+
params: { markdown: true, content: message }
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function connectorResultToUILayout(result, options = {}) {
|
|
44
|
+
const strict = ConnectorDynamicResultV1Schema.safeParse(result);
|
|
45
|
+
if (!strict.success) {
|
|
46
|
+
const lenient = LenientResultSchema.safeParse(result);
|
|
47
|
+
if (!lenient.success) {
|
|
48
|
+
const version = result && typeof result === "object" ? result.schemaVersion : void 0;
|
|
49
|
+
return {
|
|
50
|
+
id: "connector-degraded",
|
|
51
|
+
components: [
|
|
52
|
+
degradedTextComponent(
|
|
53
|
+
"connector-degraded-notice",
|
|
54
|
+
`### Résultat non rendu
|
|
55
|
+
|
|
56
|
+
Le résultat du connecteur n'a pas pu être interprété${typeof version === "string" ? ` (schéma : \`${version}\`)` : ""}. Cet état explicite remplace une disparition silencieuse du rendu.`
|
|
57
|
+
)
|
|
58
|
+
],
|
|
59
|
+
grid: { ...DEFAULT_GRID }
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
const r2 = lenient.data;
|
|
63
|
+
const components2 = [
|
|
64
|
+
degradedTextComponent(
|
|
65
|
+
"connector-version-warning",
|
|
66
|
+
`> ⚠ Schéma connecteur non reconnu (\`${r2.schemaVersion}\`, attendu \`${CONNECTOR_DYNAMIC_RESULT_V1}\`). Le rendu ci-dessous est en mode dégradé.`
|
|
67
|
+
),
|
|
68
|
+
...collectComponents(r2)
|
|
69
|
+
];
|
|
70
|
+
return {
|
|
71
|
+
id: options.id ?? `connector-degraded-${r2.connectorId}`,
|
|
72
|
+
components: components2.map(withPosition),
|
|
73
|
+
grid: { ...DEFAULT_GRID }
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const r = strict.data;
|
|
77
|
+
const components = collectComponents(r, options.actionsTitle).map(withPosition);
|
|
78
|
+
return {
|
|
79
|
+
id: options.id ?? layoutId(r.connectorId, r.queryHash ?? r.toolName),
|
|
80
|
+
components,
|
|
81
|
+
grid: { ...DEFAULT_GRID }
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function collectComponents(r, actionsTitle) {
|
|
85
|
+
const components = [];
|
|
86
|
+
if (isLayoutShape(r.primary)) {
|
|
87
|
+
const inner = r.primary.components ?? [];
|
|
88
|
+
components.push(...inner);
|
|
89
|
+
} else {
|
|
90
|
+
components.push(r.primary);
|
|
91
|
+
}
|
|
92
|
+
if (r.supplemental) {
|
|
93
|
+
components.push(...r.supplemental);
|
|
94
|
+
}
|
|
95
|
+
if (Array.isArray(r.actions) && r.actions.length > 0) {
|
|
96
|
+
components.push(
|
|
97
|
+
connectorActionsToActionGroup(r.actions, {
|
|
98
|
+
id: "connector-actions",
|
|
99
|
+
title: actionsTitle
|
|
100
|
+
})
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
return components;
|
|
104
|
+
}
|
|
105
|
+
function layoutId(connectorId, suffix) {
|
|
106
|
+
return `connector-${connectorId}-${suffix}`;
|
|
107
|
+
}
|
|
108
|
+
export {
|
|
109
|
+
connectorActionsToActionGroup,
|
|
110
|
+
connectorResultToUILayout
|
|
111
|
+
};
|
|
112
|
+
//# sourceMappingURL=connector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connector.js","sources":["../../src/adapters/connector.ts"],"sourcesContent":["/**\n * Connector adapters — `ConnectorDynamicResultV1` → MCP-UI render structures.\n *\n * @since v6.6.0 (D5 / D6 of ROADMAP-opendata-macro-mcpui)\n *\n * ## Opt-in, pure\n *\n * These adapters are published under the dedicated subpath\n * `@seed-ship/mcp-ui-solid/adapters` — they are NEVER imported by the core\n * renderer path, so a consumer that does not emit connector results pays\n * nothing for them.\n *\n * Every adapter here is a **pure function** (D5) : same input → same\n * output, no `fetch`, no `localStorage`, no global state, no clock, no\n * randomness. This is what lets a host re-run an adapter deterministically\n * after presentation feedback (D1) and replay fixtures in tests.\n *\n * ## Unknown schema version — never throw (R2)\n *\n * `connectorResultToUILayout()` never throws on the runtime render path.\n * A payload it cannot read becomes an explicit degraded `UILayout` (a\n * visible notice), never a silent disappearance and never an exception.\n */\n\nimport type { UIComponent, UILayout, GridPosition } from '../types'\nimport {\n ConnectorDynamicResultV1Schema,\n CONNECTOR_DYNAMIC_RESULT_V1,\n type ConnectorAction,\n} from '@seed-ship/mcp-ui-spec'\nimport { z } from 'zod'\n\n// ─────────────────────────────────────────────────────────────\n// connectorActionsToActionGroup\n// ─────────────────────────────────────────────────────────────\n\nexport interface ConnectorActionsToActionGroupOptions {\n /** Component id. Default `'connector-actions'`. */\n id?: string\n /** Optional heading shown above the buttons. */\n title?: string\n /** Button row layout. Default `'horizontal'`. */\n layout?: 'horizontal' | 'vertical' | 'space-between' | 'end' | 'center'\n /** Gap between buttons. Default `'md'`. */\n gap?: 'none' | 'sm' | 'md' | 'lg'\n /** Grid position. Default full-width. */\n position?: GridPosition\n}\n\n/**\n * Wraps a connector's `actions` into an `action-group` `UIComponent`.\n *\n * `ConnectorAction` is the exact `action-group` action shape, so this is a\n * thin, pure envelope — no transformation of the actions themselves.\n */\nexport function connectorActionsToActionGroup(\n actions: ConnectorAction[],\n options: ConnectorActionsToActionGroupOptions = {}\n): UIComponent {\n return {\n id: options.id ?? 'connector-actions',\n type: 'action-group',\n position: options.position ?? { colStart: 1, colSpan: 12 },\n params: {\n actions,\n ...(options.title ? { title: options.title } : {}),\n layout: options.layout ?? 'horizontal',\n gap: options.gap ?? 'md',\n },\n } as UIComponent\n}\n\n// ─────────────────────────────────────────────────────────────\n// connectorResultToUILayout\n// ─────────────────────────────────────────────────────────────\n\nexport interface ConnectorResultToUILayoutOptions {\n /** Layout id. Default derived from `connectorId` + `queryHash` / `toolName`. */\n id?: string\n /** Heading for the actions `action-group`. */\n actionsTitle?: string\n}\n\n/**\n * Lenient mirror of `ConnectorDynamicResultV1Schema` — `schemaVersion`\n * relaxed to any string. Used to tell apart \"unknown version but otherwise\n * a usable envelope\" (→ render with a warning, R2) from \"truly unreadable\"\n * (→ explicit error state).\n */\nconst LenientResultSchema = z.object({\n schemaVersion: z.string(),\n connectorId: z.string().min(1),\n toolName: z.string().min(1),\n query: z.string(),\n queryHash: z.string().optional(),\n intent: z.string().optional(),\n primary: z.record(z.unknown()),\n supplemental: z.array(z.record(z.unknown())).optional(),\n actions: z.array(z.record(z.unknown())).optional(),\n})\n\nconst DEFAULT_GRID = { columns: 12, gap: '1rem' } as const\n\nfunction withPosition(component: UIComponent): UIComponent {\n if (component && component.position) return component\n return { ...component, position: { colStart: 1, colSpan: 12 } }\n}\n\n/** A component is a UILayout when it carries a `components` array. */\nfunction isLayoutShape(value: Record<string, unknown>): boolean {\n return Array.isArray((value as { components?: unknown }).components)\n}\n\nfunction degradedTextComponent(id: string, message: string): UIComponent {\n return {\n id,\n type: 'text',\n position: { colStart: 1, colSpan: 12 },\n params: { markdown: true, content: message },\n } as UIComponent\n}\n\n/**\n * Assembles a `ConnectorDynamicResultV1` into a single `UILayout` :\n * `primary` + `supplemental[]` + (`actions` → an `action-group`).\n *\n * - When `primary` is itself a layout, its components are spread in.\n * - Raw data is never sacrificed — every supplied component is kept.\n * - Pure : no side effects, deterministic.\n *\n * ### Degraded behavior (R2)\n *\n * - Valid v1 payload → normal assembled layout.\n * - Unknown `schemaVersion` but an otherwise-usable envelope → the\n * components are still rendered, prefixed with a visible warning notice.\n * - Unreadable payload → an explicit error `UILayout` (a single `text`\n * notice). Never throws, never returns an empty layout silently.\n *\n * A degraded layout always has an `id` starting with `connector-degraded`,\n * so a host can detect it (e.g. for telemetry) without inspecting content.\n */\nexport function connectorResultToUILayout(\n result: unknown,\n options: ConnectorResultToUILayoutOptions = {}\n): UILayout {\n const strict = ConnectorDynamicResultV1Schema.safeParse(result)\n\n // ── Tier 3 : unreadable ───────────────────────────────────\n if (!strict.success) {\n const lenient = LenientResultSchema.safeParse(result)\n if (!lenient.success) {\n const version =\n result && typeof result === 'object'\n ? (result as { schemaVersion?: unknown }).schemaVersion\n : undefined\n return {\n id: 'connector-degraded',\n components: [\n degradedTextComponent(\n 'connector-degraded-notice',\n `### Résultat non rendu\\n\\nLe résultat du connecteur n'a pas pu être interprété${\n typeof version === 'string' ? ` (schéma : \\`${version}\\`)` : ''\n }. Cet état explicite remplace une disparition silencieuse du rendu.`\n ),\n ],\n grid: { ...DEFAULT_GRID },\n }\n }\n // ── Tier 2 : usable envelope, unknown version ───────────\n const r = lenient.data\n const components: UIComponent[] = [\n degradedTextComponent(\n 'connector-version-warning',\n `> ⚠ Schéma connecteur non reconnu (\\`${r.schemaVersion}\\`, attendu \\`${CONNECTOR_DYNAMIC_RESULT_V1}\\`). Le rendu ci-dessous est en mode dégradé.`\n ),\n ...collectComponents(r),\n ]\n return {\n id: options.id ?? `connector-degraded-${r.connectorId}`,\n components: components.map(withPosition),\n grid: { ...DEFAULT_GRID },\n }\n }\n\n // ── Tier 1 : valid v1 ─────────────────────────────────────\n const r = strict.data\n const components = collectComponents(r, options.actionsTitle).map(withPosition)\n return {\n id: options.id ?? layoutId(r.connectorId, r.queryHash ?? r.toolName),\n components,\n grid: { ...DEFAULT_GRID },\n }\n}\n\n/**\n * Flattens `primary` + `supplemental` + `actions` into a component list.\n * Shared by the valid and degraded-but-usable paths.\n */\nfunction collectComponents(\n r: {\n primary: Record<string, unknown>\n supplemental?: Record<string, unknown>[]\n actions?: unknown[]\n },\n actionsTitle?: string\n): UIComponent[] {\n const components: UIComponent[] = []\n\n if (isLayoutShape(r.primary)) {\n const inner = (r.primary as { components?: UIComponent[] }).components ?? []\n components.push(...inner)\n } else {\n components.push(r.primary as unknown as UIComponent)\n }\n\n if (r.supplemental) {\n components.push(...(r.supplemental as unknown as UIComponent[]))\n }\n\n if (Array.isArray(r.actions) && r.actions.length > 0) {\n components.push(\n connectorActionsToActionGroup(r.actions as ConnectorAction[], {\n id: 'connector-actions',\n title: actionsTitle,\n })\n )\n }\n\n return components\n}\n\nfunction layoutId(connectorId: string, suffix: string): string {\n return `connector-${connectorId}-${suffix}`\n}\n"],"names":["z.object","z.string","z.record","z.unknown","z.array","r","components"],"mappings":";;AAuDO,SAAS,8BACd,SACA,UAAgD,IACnC;AACb,SAAO;AAAA,IACL,IAAI,QAAQ,MAAM;AAAA,IAClB,MAAM;AAAA,IACN,UAAU,QAAQ,YAAY,EAAE,UAAU,GAAG,SAAS,GAAA;AAAA,IACtD,QAAQ;AAAA,MACN;AAAA,MACA,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,MAAA,IAAU,CAAA;AAAA,MAC/C,QAAQ,QAAQ,UAAU;AAAA,MAC1B,KAAK,QAAQ,OAAO;AAAA,IAAA;AAAA,EACtB;AAEJ;AAmBA,MAAM,sBAAsBA,WAAS;AAAA,EACnC,eAAeC,WAAE;AAAA,EACjB,aAAaA,WAAE,EAAS,IAAI,CAAC;AAAA,EAC7B,UAAUA,WAAE,EAAS,IAAI,CAAC;AAAA,EAC1B,OAAOA,WAAE;AAAA,EACT,WAAWA,WAAE,EAAS,SAAA;AAAA,EACtB,QAAQA,WAAE,EAAS,SAAA;AAAA,EACnB,SAASC,WAASC,aAAW;AAAA,EAC7B,cAAcC,UAAQF,WAASC,YAAE,CAAS,CAAC,EAAE,SAAA;AAAA,EAC7C,SAASC,UAAQF,WAASC,YAAE,CAAS,CAAC,EAAE,SAAA;AAC1C,CAAC;AAED,MAAM,eAAe,EAAE,SAAS,IAAI,KAAK,OAAA;AAEzC,SAAS,aAAa,WAAqC;AACzD,MAAI,aAAa,UAAU,SAAU,QAAO;AAC5C,SAAO,EAAE,GAAG,WAAW,UAAU,EAAE,UAAU,GAAG,SAAS,KAAG;AAC9D;AAGA,SAAS,cAAc,OAAyC;AAC9D,SAAO,MAAM,QAAS,MAAmC,UAAU;AACrE;AAEA,SAAS,sBAAsB,IAAY,SAA8B;AACvE,SAAO;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,UAAU,EAAE,UAAU,GAAG,SAAS,GAAA;AAAA,IAClC,QAAQ,EAAE,UAAU,MAAM,SAAS,QAAA;AAAA,EAAQ;AAE/C;AAqBO,SAAS,0BACd,QACA,UAA4C,IAClC;AACV,QAAM,SAAS,+BAA+B,UAAU,MAAM;AAG9D,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,UAAU,oBAAoB,UAAU,MAAM;AACpD,QAAI,CAAC,QAAQ,SAAS;AACpB,YAAM,UACJ,UAAU,OAAO,WAAW,WACvB,OAAuC,gBACxC;AACN,aAAO;AAAA,QACL,IAAI;AAAA,QACJ,YAAY;AAAA,UACV;AAAA,YACE;AAAA,YACA;AAAA;AAAA,sDACE,OAAO,YAAY,WAAW,gBAAgB,OAAO,QAAQ,EAC/D;AAAA,UAAA;AAAA,QACF;AAAA,QAEF,MAAM,EAAE,GAAG,aAAA;AAAA,MAAa;AAAA,IAE5B;AAEA,UAAME,KAAI,QAAQ;AAClB,UAAMC,cAA4B;AAAA,MAChC;AAAA,QACE;AAAA,QACA,wCAAwCD,GAAE,aAAa,iBAAiB,2BAA2B;AAAA,MAAA;AAAA,MAErG,GAAG,kBAAkBA,EAAC;AAAA,IAAA;AAExB,WAAO;AAAA,MACL,IAAI,QAAQ,MAAM,sBAAsBA,GAAE,WAAW;AAAA,MACrD,YAAYC,YAAW,IAAI,YAAY;AAAA,MACvC,MAAM,EAAE,GAAG,aAAA;AAAA,IAAa;AAAA,EAE5B;AAGA,QAAM,IAAI,OAAO;AACjB,QAAM,aAAa,kBAAkB,GAAG,QAAQ,YAAY,EAAE,IAAI,YAAY;AAC9E,SAAO;AAAA,IACL,IAAI,QAAQ,MAAM,SAAS,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ;AAAA,IACnE;AAAA,IACA,MAAM,EAAE,GAAG,aAAA;AAAA,EAAa;AAE5B;AAMA,SAAS,kBACP,GAKA,cACe;AACf,QAAM,aAA4B,CAAA;AAElC,MAAI,cAAc,EAAE,OAAO,GAAG;AAC5B,UAAM,QAAS,EAAE,QAA2C,cAAc,CAAA;AAC1E,eAAW,KAAK,GAAG,KAAK;AAAA,EAC1B,OAAO;AACL,eAAW,KAAK,EAAE,OAAiC;AAAA,EACrD;AAEA,MAAI,EAAE,cAAc;AAClB,eAAW,KAAK,GAAI,EAAE,YAAyC;AAAA,EACjE;AAEA,MAAI,MAAM,QAAQ,EAAE,OAAO,KAAK,EAAE,QAAQ,SAAS,GAAG;AACpD,eAAW;AAAA,MACT,8BAA8B,EAAE,SAA8B;AAAA,QAC5D,IAAI;AAAA,QACJ,OAAO;AAAA,MAAA,CACR;AAAA,IAAA;AAAA,EAEL;AAEA,SAAO;AACT;AAEA,SAAS,SAAS,aAAqB,QAAwB;AAC7D,SAAO,aAAa,WAAW,IAAI,MAAM;AAC3C;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @seed-ship/mcp-ui-solid/adapters
|
|
3
|
+
*
|
|
4
|
+
* Opt-in, pure adapters that turn connector / macro contracts into MCP-UI
|
|
5
|
+
* render structures. Published as a dedicated subpath so the core renderer
|
|
6
|
+
* path never depends on them.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { connectorResultToUILayout } from '@seed-ship/mcp-ui-solid/adapters'
|
|
11
|
+
*
|
|
12
|
+
* const layout = connectorResultToUILayout(connectorResult)
|
|
13
|
+
* // → <UIResourceRenderer content={layout} />
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export { connectorResultToUILayout, connectorActionsToActionGroup, } from './connector';
|
|
17
|
+
export type { ConnectorResultToUILayoutOptions, ConnectorActionsToActionGroupOptions, } from './connector';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,yBAAyB,EACzB,6BAA6B,GAC9B,MAAM,aAAa,CAAA;AACpB,YAAY,EACV,gCAAgC,EAChC,oCAAoC,GACrC,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const connector = require("./adapters/connector.cjs");
|
|
4
|
+
exports.connectorActionsToActionGroup = connector.connectorActionsToActionGroup;
|
|
5
|
+
exports.connectorResultToUILayout = connector.connectorResultToUILayout;
|
|
6
|
+
//# sourceMappingURL=adapters.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @seed-ship/mcp-ui-solid/adapters
|
|
3
|
+
*
|
|
4
|
+
* Opt-in, pure adapters that turn connector / macro contracts into MCP-UI
|
|
5
|
+
* render structures. Published as a dedicated subpath so the core renderer
|
|
6
|
+
* path never depends on them.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { connectorResultToUILayout } from '@seed-ship/mcp-ui-solid/adapters'
|
|
11
|
+
*
|
|
12
|
+
* const layout = connectorResultToUILayout(connectorResult)
|
|
13
|
+
* // → <UIResourceRenderer content={layout} />
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export { connectorResultToUILayout, connectorActionsToActionGroup, } from './connector';
|
|
17
|
+
export type { ConnectorResultToUILayoutOptions, ConnectorActionsToActionGroupOptions, } from './connector';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @seed-ship/mcp-ui-solid/adapters
|
|
3
|
+
*
|
|
4
|
+
* Opt-in, pure adapters that turn connector / macro contracts into MCP-UI
|
|
5
|
+
* render structures. Published as a dedicated subpath so the core renderer
|
|
6
|
+
* path never depends on them.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import { connectorResultToUILayout } from '@seed-ship/mcp-ui-solid/adapters'
|
|
11
|
+
*
|
|
12
|
+
* const layout = connectorResultToUILayout(connectorResult)
|
|
13
|
+
* // → <UIResourceRenderer content={layout} />
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export { connectorResultToUILayout, connectorActionsToActionGroup, } from './connector';
|
|
17
|
+
export type { ConnectorResultToUILayoutOptions, ConnectorActionsToActionGroupOptions, } from './connector';
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/adapters.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapters.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|