@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.
Files changed (257) hide show
  1. package/CHANGELOG.md +519 -0
  2. package/README.md +791 -1
  3. package/dist/adapters/connector.cjs +15 -4
  4. package/dist/adapters/connector.cjs.map +1 -1
  5. package/dist/adapters/connector.d.ts +38 -0
  6. package/dist/adapters/connector.d.ts.map +1 -1
  7. package/dist/adapters/connector.js +15 -4
  8. package/dist/adapters/connector.js.map +1 -1
  9. package/dist/adapters/index.d.ts +4 -3
  10. package/dist/adapters/index.d.ts.map +1 -1
  11. package/dist/adapters/macro-run.cjs +25 -13
  12. package/dist/adapters/macro-run.cjs.map +1 -1
  13. package/dist/adapters/macro-run.d.ts +37 -2
  14. package/dist/adapters/macro-run.d.ts.map +1 -1
  15. package/dist/adapters/macro-run.js +25 -13
  16. package/dist/adapters/macro-run.js.map +1 -1
  17. package/dist/adapters.cjs +2 -0
  18. package/dist/adapters.cjs.map +1 -1
  19. package/dist/adapters.js +4 -2
  20. package/dist/components/ActionGroupRenderer.cjs +3 -1
  21. package/dist/components/ActionGroupRenderer.cjs.map +1 -1
  22. package/dist/components/ActionGroupRenderer.d.ts.map +1 -1
  23. package/dist/components/ActionGroupRenderer.js +3 -1
  24. package/dist/components/ActionGroupRenderer.js.map +1 -1
  25. package/dist/components/AgentCard.cjs +11 -8
  26. package/dist/components/AgentCard.cjs.map +1 -1
  27. package/dist/components/AgentCard.d.ts.map +1 -1
  28. package/dist/components/AgentCard.js +11 -8
  29. package/dist/components/AgentCard.js.map +1 -1
  30. package/dist/components/AgentHandoff.cjs +6 -1
  31. package/dist/components/AgentHandoff.cjs.map +1 -1
  32. package/dist/components/AgentHandoff.d.ts.map +1 -1
  33. package/dist/components/AgentHandoff.js +6 -1
  34. package/dist/components/AgentHandoff.js.map +1 -1
  35. package/dist/components/ArtifactRenderer.cjs +25 -6
  36. package/dist/components/ArtifactRenderer.cjs.map +1 -1
  37. package/dist/components/ArtifactRenderer.d.ts.map +1 -1
  38. package/dist/components/ArtifactRenderer.js +25 -6
  39. package/dist/components/ArtifactRenderer.js.map +1 -1
  40. package/dist/components/AutocompleteDropdown.cjs +30 -24
  41. package/dist/components/AutocompleteDropdown.cjs.map +1 -1
  42. package/dist/components/AutocompleteDropdown.d.ts.map +1 -1
  43. package/dist/components/AutocompleteDropdown.js +30 -24
  44. package/dist/components/AutocompleteDropdown.js.map +1 -1
  45. package/dist/components/AutocompleteFormField.cjs +3 -1
  46. package/dist/components/AutocompleteFormField.cjs.map +1 -1
  47. package/dist/components/AutocompleteFormField.d.ts.map +1 -1
  48. package/dist/components/AutocompleteFormField.js +4 -2
  49. package/dist/components/AutocompleteFormField.js.map +1 -1
  50. package/dist/components/BriefingDiff.cjs +45 -39
  51. package/dist/components/BriefingDiff.cjs.map +1 -1
  52. package/dist/components/BriefingDiff.d.ts.map +1 -1
  53. package/dist/components/BriefingDiff.js +45 -39
  54. package/dist/components/BriefingDiff.js.map +1 -1
  55. package/dist/components/CarouselRenderer.cjs +8 -2
  56. package/dist/components/CarouselRenderer.cjs.map +1 -1
  57. package/dist/components/CarouselRenderer.d.ts.map +1 -1
  58. package/dist/components/CarouselRenderer.js +8 -2
  59. package/dist/components/CarouselRenderer.js.map +1 -1
  60. package/dist/components/ChartJSRenderer.cjs +60 -36
  61. package/dist/components/ChartJSRenderer.cjs.map +1 -1
  62. package/dist/components/ChartJSRenderer.d.ts.map +1 -1
  63. package/dist/components/ChartJSRenderer.js +61 -37
  64. package/dist/components/ChartJSRenderer.js.map +1 -1
  65. package/dist/components/ChatPrompt.cjs +15 -9
  66. package/dist/components/ChatPrompt.cjs.map +1 -1
  67. package/dist/components/ChatPrompt.d.ts.map +1 -1
  68. package/dist/components/ChatPrompt.js +15 -9
  69. package/dist/components/ChatPrompt.js.map +1 -1
  70. package/dist/components/CodeBlockRenderer.cjs +34 -16
  71. package/dist/components/CodeBlockRenderer.cjs.map +1 -1
  72. package/dist/components/CodeBlockRenderer.d.ts.map +1 -1
  73. package/dist/components/CodeBlockRenderer.js +34 -16
  74. package/dist/components/CodeBlockRenderer.js.map +1 -1
  75. package/dist/components/DataPreviewSection.cjs +91 -44
  76. package/dist/components/DataPreviewSection.cjs.map +1 -1
  77. package/dist/components/DataPreviewSection.d.ts.map +1 -1
  78. package/dist/components/DataPreviewSection.js +92 -45
  79. package/dist/components/DataPreviewSection.js.map +1 -1
  80. package/dist/components/DegradedFallback.cjs +20 -16
  81. package/dist/components/DegradedFallback.cjs.map +1 -1
  82. package/dist/components/DegradedFallback.d.ts.map +1 -1
  83. package/dist/components/DegradedFallback.js +20 -16
  84. package/dist/components/DegradedFallback.js.map +1 -1
  85. package/dist/components/FooterRenderer.cjs +21 -17
  86. package/dist/components/FooterRenderer.cjs.map +1 -1
  87. package/dist/components/FooterRenderer.d.ts.map +1 -1
  88. package/dist/components/FooterRenderer.js +21 -17
  89. package/dist/components/FooterRenderer.js.map +1 -1
  90. package/dist/components/FormFieldRenderer.cjs +116 -93
  91. package/dist/components/FormFieldRenderer.cjs.map +1 -1
  92. package/dist/components/FormFieldRenderer.d.ts.map +1 -1
  93. package/dist/components/FormFieldRenderer.js +116 -93
  94. package/dist/components/FormFieldRenderer.js.map +1 -1
  95. package/dist/components/FormRenderer.cjs +55 -31
  96. package/dist/components/FormRenderer.cjs.map +1 -1
  97. package/dist/components/FormRenderer.d.ts.map +1 -1
  98. package/dist/components/FormRenderer.js +55 -31
  99. package/dist/components/FormRenderer.js.map +1 -1
  100. package/dist/components/GenerativeUIErrorBoundary.cjs +20 -15
  101. package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -1
  102. package/dist/components/GenerativeUIErrorBoundary.d.ts.map +1 -1
  103. package/dist/components/GenerativeUIErrorBoundary.js +20 -15
  104. package/dist/components/GenerativeUIErrorBoundary.js.map +1 -1
  105. package/dist/components/GraphRenderer.cjs +56 -33
  106. package/dist/components/GraphRenderer.cjs.map +1 -1
  107. package/dist/components/GraphRenderer.d.ts.map +1 -1
  108. package/dist/components/GraphRenderer.js +56 -33
  109. package/dist/components/GraphRenderer.js.map +1 -1
  110. package/dist/components/ImageGalleryRenderer.cjs +13 -4
  111. package/dist/components/ImageGalleryRenderer.cjs.map +1 -1
  112. package/dist/components/ImageGalleryRenderer.d.ts.map +1 -1
  113. package/dist/components/ImageGalleryRenderer.js +13 -4
  114. package/dist/components/ImageGalleryRenderer.js.map +1 -1
  115. package/dist/components/LightboxOverlay.cjs +16 -8
  116. package/dist/components/LightboxOverlay.cjs.map +1 -1
  117. package/dist/components/LightboxOverlay.d.ts.map +1 -1
  118. package/dist/components/LightboxOverlay.js +17 -9
  119. package/dist/components/LightboxOverlay.js.map +1 -1
  120. package/dist/components/MapRenderer.cjs +59 -29
  121. package/dist/components/MapRenderer.cjs.map +1 -1
  122. package/dist/components/MapRenderer.d.ts +10 -2
  123. package/dist/components/MapRenderer.d.ts.map +1 -1
  124. package/dist/components/MapRenderer.js +60 -30
  125. package/dist/components/MapRenderer.js.map +1 -1
  126. package/dist/components/ModalRenderer.cjs +4 -1
  127. package/dist/components/ModalRenderer.cjs.map +1 -1
  128. package/dist/components/ModalRenderer.d.ts.map +1 -1
  129. package/dist/components/ModalRenderer.js +5 -2
  130. package/dist/components/ModalRenderer.js.map +1 -1
  131. package/dist/components/ScratchpadPanel.cjs +578 -535
  132. package/dist/components/ScratchpadPanel.cjs.map +1 -1
  133. package/dist/components/ScratchpadPanel.d.ts.map +1 -1
  134. package/dist/components/ScratchpadPanel.js +578 -535
  135. package/dist/components/ScratchpadPanel.js.map +1 -1
  136. package/dist/components/StreamingUIRenderer.cjs +92 -28
  137. package/dist/components/StreamingUIRenderer.cjs.map +1 -1
  138. package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
  139. package/dist/components/StreamingUIRenderer.js +92 -28
  140. package/dist/components/StreamingUIRenderer.js.map +1 -1
  141. package/dist/components/UIResourceRenderer.cjs +456 -363
  142. package/dist/components/UIResourceRenderer.cjs.map +1 -1
  143. package/dist/components/UIResourceRenderer.d.ts +21 -0
  144. package/dist/components/UIResourceRenderer.d.ts.map +1 -1
  145. package/dist/components/UIResourceRenderer.js +458 -365
  146. package/dist/components/UIResourceRenderer.js.map +1 -1
  147. package/dist/components/VerifiedText.cjs +39 -20
  148. package/dist/components/VerifiedText.cjs.map +1 -1
  149. package/dist/components/VerifiedText.d.ts +2 -1
  150. package/dist/components/VerifiedText.d.ts.map +1 -1
  151. package/dist/components/VerifiedText.js +39 -20
  152. package/dist/components/VerifiedText.js.map +1 -1
  153. package/dist/components/VideoRenderer.cjs +10 -5
  154. package/dist/components/VideoRenderer.cjs.map +1 -1
  155. package/dist/components/VideoRenderer.d.ts.map +1 -1
  156. package/dist/components/VideoRenderer.js +10 -5
  157. package/dist/components/VideoRenderer.js.map +1 -1
  158. package/dist/components/chart-data-table.cjs +38 -17
  159. package/dist/components/chart-data-table.cjs.map +1 -1
  160. package/dist/components/chart-data-table.d.ts +30 -1
  161. package/dist/components/chart-data-table.d.ts.map +1 -1
  162. package/dist/components/chart-data-table.js +38 -17
  163. package/dist/components/chart-data-table.js.map +1 -1
  164. package/dist/context/MCPActionContext.cjs +3 -1
  165. package/dist/context/MCPActionContext.cjs.map +1 -1
  166. package/dist/context/MCPActionContext.d.ts.map +1 -1
  167. package/dist/context/MCPActionContext.js +3 -1
  168. package/dist/context/MCPActionContext.js.map +1 -1
  169. package/dist/context/MCPUIStringsContext.cjs +285 -2
  170. package/dist/context/MCPUIStringsContext.cjs.map +1 -1
  171. package/dist/context/MCPUIStringsContext.d.ts +600 -3
  172. package/dist/context/MCPUIStringsContext.d.ts.map +1 -1
  173. package/dist/context/MCPUIStringsContext.js +285 -2
  174. package/dist/context/MCPUIStringsContext.js.map +1 -1
  175. package/dist/hooks/index.d.ts +2 -2
  176. package/dist/hooks/index.d.ts.map +1 -1
  177. package/dist/hooks/useStreamingUI.cjs +28 -10
  178. package/dist/hooks/useStreamingUI.cjs.map +1 -1
  179. package/dist/hooks/useStreamingUI.d.ts +37 -0
  180. package/dist/hooks/useStreamingUI.d.ts.map +1 -1
  181. package/dist/hooks/useStreamingUI.js +28 -10
  182. package/dist/hooks/useStreamingUI.js.map +1 -1
  183. package/dist/hooks.cjs +1 -0
  184. package/dist/hooks.cjs.map +1 -1
  185. package/dist/hooks.js +2 -1
  186. package/dist/index.cjs +23 -8
  187. package/dist/index.cjs.map +1 -1
  188. package/dist/index.d.cts +9 -3
  189. package/dist/index.d.ts +9 -3
  190. package/dist/index.d.ts.map +1 -1
  191. package/dist/index.js +18 -3
  192. package/dist/index.js.map +1 -1
  193. package/dist/services/validation.cjs +41 -16
  194. package/dist/services/validation.cjs.map +1 -1
  195. package/dist/services/validation.d.ts +47 -2
  196. package/dist/services/validation.d.ts.map +1 -1
  197. package/dist/services/validation.js +41 -16
  198. package/dist/services/validation.js.map +1 -1
  199. package/dist/utils/degraded-projections.cjs +37 -12
  200. package/dist/utils/degraded-projections.cjs.map +1 -1
  201. package/dist/utils/degraded-projections.d.ts +39 -3
  202. package/dist/utils/degraded-projections.d.ts.map +1 -1
  203. package/dist/utils/degraded-projections.js +37 -12
  204. package/dist/utils/degraded-projections.js.map +1 -1
  205. package/dist/utils/format-string.cjs +10 -0
  206. package/dist/utils/format-string.cjs.map +1 -0
  207. package/dist/utils/format-string.d.ts +26 -0
  208. package/dist/utils/format-string.d.ts.map +1 -0
  209. package/dist/utils/format-string.js +10 -0
  210. package/dist/utils/format-string.js.map +1 -0
  211. package/dist/validation.cjs +3 -0
  212. package/dist/validation.cjs.map +1 -1
  213. package/dist/validation.d.cts +2 -1
  214. package/dist/validation.d.ts +2 -1
  215. package/dist/validation.d.ts.map +1 -1
  216. package/dist/validation.js +4 -1
  217. package/package.json +1 -1
  218. package/src/adapters/connector.ts +58 -4
  219. package/src/adapters/index.ts +12 -2
  220. package/src/adapters/macro-run.ts +71 -11
  221. package/src/components/ActionGroupRenderer.tsx +3 -1
  222. package/src/components/AgentCard.tsx +27 -9
  223. package/src/components/AgentHandoff.tsx +4 -1
  224. package/src/components/ArtifactRenderer.tsx +17 -5
  225. package/src/components/AutocompleteDropdown.tsx +8 -6
  226. package/src/components/AutocompleteFormField.tsx +5 -1
  227. package/src/components/BriefingDiff.tsx +11 -3
  228. package/src/components/CarouselRenderer.tsx +4 -2
  229. package/src/components/ChartJSRenderer.tsx +18 -9
  230. package/src/components/ChatPrompt.tsx +13 -8
  231. package/src/components/CodeBlockRenderer.tsx +12 -10
  232. package/src/components/DataPreviewSection.tsx +92 -26
  233. package/src/components/DegradedFallback.tsx +4 -2
  234. package/src/components/FooterRenderer.tsx +3 -1
  235. package/src/components/FormFieldRenderer.tsx +34 -19
  236. package/src/components/FormRenderer.tsx +38 -10
  237. package/src/components/GenerativeUIErrorBoundary.tsx +8 -3
  238. package/src/components/GraphRenderer.tsx +31 -16
  239. package/src/components/ImageGalleryRenderer.tsx +8 -4
  240. package/src/components/LightboxOverlay.tsx +6 -4
  241. package/src/components/MapRenderer.tsx +57 -20
  242. package/src/components/ModalRenderer.tsx +3 -1
  243. package/src/components/ScratchpadPanel.tsx +95 -44
  244. package/src/components/StreamingUIRenderer.tsx +41 -11
  245. package/src/components/UIResourceRenderer.tsx +145 -63
  246. package/src/components/VerifiedText.tsx +19 -9
  247. package/src/components/VideoRenderer.tsx +6 -4
  248. package/src/components/chart-data-table.ts +68 -14
  249. package/src/context/MCPActionContext.tsx +4 -1
  250. package/src/context/MCPUIStringsContext.tsx +1004 -1
  251. package/src/hooks/index.ts +2 -1
  252. package/src/hooks/useStreamingUI.ts +64 -10
  253. package/src/index.ts +23 -0
  254. package/src/services/validation.ts +93 -16
  255. package/src/utils/degraded-projections.ts +75 -12
  256. package/src/utils/format-string.ts +33 -0
  257. package/src/validation.ts +5 -0
package/README.md CHANGED
@@ -5,6 +5,91 @@ SolidJS components + chat toolkit for MCP-generated UI. Part of the [MCP UI ecos
5
5
  [![npm version](https://img.shields.io/npm/v/@seed-ship/mcp-ui-solid.svg)](https://www.npmjs.com/package/@seed-ship/mcp-ui-solid)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
 
8
+ ## What's New in v6.20.0
9
+
10
+ - **Complete i18n of the library chrome.** Every user-visible chrome string —
11
+ copy/export/download button titles, the code toolbar, prefill source
12
+ badges, the lightbox, the modal close button, `VerifiedText`'s tooltips,
13
+ degraded-fallback captions, status badges, form-validation messages, and
14
+ more — now reads from `MCPUIStrings` (components, via `useMCPUIStrings()`)
15
+ or an exported `messages`/`labels` option (runtime-free adapters, services,
16
+ helpers), except the exclusion policy P1–P8 in
17
+ [`CHANGELOG.md`](./CHANGELOG.md) (keyboard key caps, the OpenStreetMap
18
+ attribution, developer/peer-dependency diagnostics, file-format acronyms
19
+ and HTTP verbs, components with their own `labels`/`messages` prop, hook-level errors and `console.*`, and
20
+ LLM-facing registry examples). See **Internationalization** below for the
21
+ full key table and a French example dictionary.
22
+ - **New exported `formatMCPUIString(template, vars)` helper** for hosts that
23
+ render their own chrome and want the same `{placeholder}` substitution
24
+ `mcp-ui-solid` uses internally. It lives in the dependency-free
25
+ `src/utils/format-string.ts`, so the runtime-free adapters use it too.
26
+ - **New `messages` option on `connectorResultToUILayout()`** — the connector
27
+ adapter's own degraded-state paragraphs (unreadable payload, unrecognized
28
+ schema version) are no longer hardcoded French; they default to English
29
+ `DEFAULT_CONNECTOR_MESSAGES` and accept a partial override for hosts that
30
+ render in another language. See **Server-side producers** below. The macro
31
+ adapter gets the same treatment: `macroRunToScratchpadState()` /
32
+ `macroInterrogationToChatPromptConfig()` take a `messages` option backed by
33
+ `DEFAULT_MACRO_RUN_MESSAGES` (`"Agent"` / `"Progress"` / `"Result"` section
34
+ titles, abort/failure/confirm copy) — see the injectable-wording bullet
35
+ below.
36
+ - **Five chrome defaults changed from French to English** —
37
+ `tableSearchPlaceholder` (`"Rechercher dans le tableau..."` →
38
+ `"Search the table..."`), `verifiedStripLabel` (`"[non vérifié]"` →
39
+ `"[unverified]"`), `scratchpadEdit` (`"Modifier"` → `"Edit"`),
40
+ `citationUnresolved` (`"[réf. {id}]"` → `"[ref. {id}]"`, via the new
41
+ `CitationCtx.unresolvedLabel`), and `formPrefilledOne` / `formPrefilledMany`
42
+ (`"{count} champ(s) pré-rempli(s) sur {total}"` → `"{count} field(s)
43
+ pre-filled out of {total}"`). A connector's own
44
+ `tableParams.searchPlaceholder` still wins; otherwise restore the French
45
+ text via `<MCPUIStringsProvider>`. See [`CHANGELOG.md`](./CHANGELOG.md) for
46
+ the complete key list.
47
+ - **`StreamingUIRenderer` no longer shows the machine code `ssr` as its error
48
+ heading** during server rendering; it shows `streamServerSideTitle`
49
+ (`"Streaming unavailable"`). The hook's `StreamError.error` keeps `'ssr'`.
50
+ - **Injectable wording for the runtime-free helpers.** Modules that cannot
51
+ read the context (they must stay free of `solid-js`) now take their English
52
+ as a TRAILING OPTIONAL parameter with an exported default table, so every
53
+ existing call is unchanged:
54
+ `macroRunToScratchpadState(run, { messages })` /
55
+ `macroInterrogationToChatPromptConfig(q, { messages })`
56
+ (`DEFAULT_MACRO_RUN_MESSAGES`),
57
+ `validateFieldValue(value, field, messages)` /
58
+ `validateFormData(data, fields, messages)` (`DEFAULT_VALIDATION_MESSAGES` —
59
+ `FormRenderer` feeds it from `MCPUIStrings`),
60
+ `graphToDegradedTable` / `mapToDegradedTable` / `chartToDegradedTable`
61
+ (`DEGRADED_PROJECTION_LABELS`) and `chartToDataTable`
62
+ (`CHART_DATA_TABLE_LABELS`).
63
+ - **The chrome-strings guard is now a TypeScript-AST scanner over all of
64
+ `src`** (`scripts/chrome-scan.ts`, not published) — it follows literals
65
+ through `||` / `??` / ternary branches / template spans / helper returns /
66
+ signal setters into visible attributes, JSX children and the clipboard,
67
+ and flags French and hardcoded locales anywhere. Each exemption names an
68
+ exclusion-policy item and is kept live by a test; a runtime
69
+ pseudo-localization test renders the renderers with marker strings and CJK
70
+ payloads and fails on any Latin text left in the DOM.
71
+ - **New `locale` key (default `'en-US'`)** drives every number / date
72
+ formatting and collation call — a **default change**: these sites used
73
+ `'fr-FR'` / `'fr'` or the runtime locale before. See
74
+ [`locale`](#locale--number-date-and-sort-formatting-default-change-in-v6200).
75
+ - **`useStreamingUI({ messages })`** — the hook's progress and error messages
76
+ are injectable (`DEFAULT_STREAMING_UI_MESSAGES`); `StreamingUIRenderer`
77
+ feeds them from `MCPUIStrings` (`stream*` keys).
78
+ - `MCPUIStrings` now covers **270 keys** in total, all grouped by the
79
+ component they belong to. See the full key reference below.
80
+
81
+ > **Not covered by `MCPUIStringsProvider`:** `PresentationFeedback` documents
82
+ > its own `labels` prop (`DEFAULT_PRESENTATION_FEEDBACK_LABELS`) and is
83
+ > localized through that prop, not through the chrome-strings context.
84
+
85
+ The handful of strings that stay hardcoded fall under an explicit exclusion
86
+ policy (P1–P8: keyboard key caps, the OpenStreetMap/ODbL attribution,
87
+ developer diagnostics naming an npm/peer dependency or a config flag,
88
+ file-format acronyms and HTTP verbs, components with their own documented `labels`/`messages` prop, hook-level
89
+ errors consumers handle, and LLM-facing example payloads) — see
90
+ [`CHANGELOG.md`](./CHANGELOG.md)'s `## [6.20.0]` entry for the full policy
91
+ text and every concrete occurrence.
92
+
8
93
  ## What's New in v6.19.1
9
94
 
10
95
  - `FeedbackInline`'s thumb buttons now take their `aria-label` from
@@ -182,6 +267,24 @@ Sprint OpenData / macros — `docs/briefs/ROADMAP-opendata-macro-mcpui.md`.
182
267
  const layout = connectorResultToUILayout(connectorResult)
183
268
  ```
184
269
 
270
+ **Since v6.20.0** — `connectorResultToUILayout`'s two degraded-state
271
+ paragraphs (unreadable payload, unrecognized schema version) used to be
272
+ hardcoded French. They now default to English `ConnectorAdapterMessages`
273
+ (`DEFAULT_CONNECTOR_MESSAGES`) and accept a partial override via the
274
+ `messages` option, since these adapters are dependency-free and cannot
275
+ read `<MCPUIStringsProvider>`:
276
+
277
+ ```ts
278
+ import { connectorResultToUILayout } from '@seed-ship/mcp-ui-solid/adapters'
279
+
280
+ const layout = connectorResultToUILayout(connectorResult, {
281
+ messages: {
282
+ versionWarning:
283
+ '> ⚠ Schéma connecteur non reconnu (`{version}`, attendu `{expected}`). Le rendu ci-dessous est en mode dégradé.',
284
+ },
285
+ })
286
+ ```
287
+
185
288
  > **Note** — `FeedbackInline`'s acknowledgement defaults changed from
186
289
  > French to English (`'Thanks!'`, `"Noted — we'll improve"`). Wrap your app
187
290
  > in `<MCPUIStringsProvider>` with French strings, or pass `positiveAck` /
@@ -265,7 +368,7 @@ Everything rolled up from the 4.x series is documented in the previous section b
265
368
 
266
369
  - **Data Verification Layer** - Anti-hallucination: `validateAgainstSource()` detects ~90% of numerical hallucinations, zero LLM cost, <1ms
267
370
  - **VerifiedText component** - Inline badges (verified/hallucinated) with highlight, strip, annotate modes
268
- - **DataPreviewSection** - Paginated data table with CSV/JSON export, source attribution, FR locale formatting
371
+ - **DataPreviewSection** - Paginated data table with CSV/JSON export, source attribution, locale formatting (`MCPUIStrings.locale`)
269
372
  - **GeoJSON maps** - Polygon/line/point rendering, choropleth coloring, feature popups, multi-layer support
270
373
  - **PMTiles** - Vector tiles for large datasets (>5000 features) via optional `protomaps-leaflet`
271
374
  - **Time-series charts** - `timeAxis` config for date-based x-axis in ChartJSRenderer
@@ -907,6 +1010,693 @@ to load or throws.
907
1010
  Net effect: an SSR pass never leaks or executes untrusted markup, and the
908
1011
  client upgrades to the rich version — with a visible reflow — once mounted.
909
1012
 
1013
+ ## Internationalization (i18n) — `MCPUIStrings`
1014
+
1015
+ `<MCPUIStringsProvider>` localizes the library's own **chrome** — button
1016
+ titles, `aria-label`s, placeholders, empty states. It never touches
1017
+ **content** (`params.title`, table data, action labels, chat prompt copy):
1018
+ that comes from the payload and is already localized by whoever produced
1019
+ it. Every key is optional; an omitted key falls back to its English
1020
+ `DEFAULT_MCPUI_STRINGS` value, so mounting the provider is entirely opt-in
1021
+ and partial overrides are the normal case.
1022
+
1023
+ ```tsx
1024
+ import { MCPUIStringsProvider } from '@seed-ship/mcp-ui-solid'
1025
+
1026
+ <MCPUIStringsProvider strings={{ expand: 'Agrandir', feedbackUseful: 'Utile' }}>
1027
+ <App />
1028
+ </MCPUIStringsProvider>
1029
+ ```
1030
+
1031
+ A handful of keys are templates: they carry a `{placeholder}` the renderer
1032
+ fills in at call time via the exported `formatMCPUIString(template, vars)`
1033
+ helper. Hosts that render their own equivalent chrome (e.g. a custom sort
1034
+ header) can call the same helper to get the same substitution behavior —
1035
+ an unrecognized `{placeholder}` is left verbatim rather than becoming
1036
+ `undefined`:
1037
+
1038
+ ```ts
1039
+ import { formatMCPUIString } from '@seed-ship/mcp-ui-solid'
1040
+
1041
+ formatMCPUIString('Sort by {column}', { column: 'Revenue' }) // 'Sort by Revenue'
1042
+ formatMCPUIString('Export CSV ({count} rows)', { count: 42 }) // 'Export CSV (42 rows)'
1043
+ ```
1044
+
1045
+ ### Full key reference
1046
+
1047
+ | Key | English default | Where it appears |
1048
+ |-----|------------------|-------------------|
1049
+ | `expand` | `Expand` | `ExpandableWrapper` toolbar — expand-to-fullscreen button `title` |
1050
+ | `expandedView` | `Expanded view` | `ExpandableWrapper` — fullscreen modal heading/`aria-label` when untitled |
1051
+ | `copyToClipboard` | `Copy to clipboard` | `ExpandableWrapper` — default copy-button tooltip (overridden by a `copyLabel` prop) |
1052
+ | `closeExpandedView` | `Close expanded view` | `ExpandableWrapper` — fullscreen modal close button `aria-label` |
1053
+ | `feedbackUseful` | `Useful` | `FeedbackInline` — thumb-up button `title`/`aria-label` |
1054
+ | `feedbackNotUseful` | `Not useful` | `FeedbackInline` — thumb-down button `title`/`aria-label` |
1055
+ | `feedbackPositiveAck` | `Thanks!` | `FeedbackInline` — acknowledgement after a positive rating |
1056
+ | `feedbackNegativeAck` | `Noted — we'll improve` | `FeedbackInline` — acknowledgement after a negative rating |
1057
+ | `retry` | `Retry` | `StreamingUIRenderer` — retry button label |
1058
+ | `ok` | `OK` | `ScratchpadPanel` — inline filter editor confirm button |
1059
+ | `cancel` | `Cancel` | `ScratchpadPanel` (inline filter editor), `ChatPrompt` (`ConfirmBody`, payload `cancelLabel` still wins) — generic cancel button |
1060
+ | `confirm` | `Confirm` | `ChatPrompt` (`ConfirmBody`) — generic confirm button |
1061
+ | `submit` | `Submit` | `ChatPrompt` (`FormBody`), `FormRenderer`, `ScratchpadPanel` (`EmbeddedFormSection`) — generic submit button |
1062
+ | `dismiss` | `Dismiss` | `ChatPrompt` — `aria-label` of the dismiss button |
1063
+ | `yes` | `Yes` | `StreamingUIRenderer` (cached cell), `ScratchpadPanel` (`FeedbackSection` approve label) |
1064
+ | `no` | `No` | `ScratchpadPanel` — `FeedbackSection` reject label |
1065
+ | `chartView` | `Chart` | `ChartJSRenderer` — chart/data view switch, "chart" side |
1066
+ | `chartDataView` | `Data` | `ChartJSRenderer` — chart/data view switch, "data" side |
1067
+ | `chartViewSelector` | `Chart or data view` | `ChartJSRenderer` — view switch accessible name |
1068
+ | `chartDataTable` | `Chart data` | `ChartJSRenderer` — data-table caption/accessible name |
1069
+ | `chartDataSummary` | `Exact values are available in the data view.` | `ChartJSRenderer` — screen-reader description of the chart canvas |
1070
+ | `chartNoData` | `No chart data` | `ChartJSRenderer` — empty state |
1071
+ | `paginationPrevious` | `Previous page` | `UIResourceRenderer` (table) — pagination "previous" button accessible name |
1072
+ | `paginationNext` | `Next page` | `UIResourceRenderer` (table) — pagination "next" button accessible name |
1073
+ | `paginationPageSize` | `Rows per page` | `UIResourceRenderer` (table) — page-size `<select>` accessible name |
1074
+ | `gridRegion` | `Layout grid` | `GridRenderer` — fallback `aria-label` for an untitled grid region |
1075
+ | `autocompleteSuggestions` | `Suggestions` | `AutocompleteDropdown` — suggestions listbox `aria-label` |
1076
+ | `autocompleteLoading` | `Loading...` | `AutocompleteDropdown` — fallback loading message |
1077
+ | `autocompleteEmpty` | `No suggestions found` | `AutocompleteDropdown` — fallback empty state |
1078
+ | `carouselTitle` | `Carousel` | `CarouselRenderer` — expandable-wrapper toolbar title |
1079
+ | `carouselCopy` | `Copy items (JSON)` | `CarouselRenderer` — copy button `copyLabel` |
1080
+ | `mapTitle` | `Map` | `MapRenderer` — expandable-wrapper toolbar title |
1081
+ | `mapCopy` | `Copy markers as GeoJSON` | `MapRenderer` — copy button `copyLabel` |
1082
+ | `chartDownloadPng` | `Download PNG` | `ChartJSRenderer` — PNG export button `title` |
1083
+ | `chartDownloadPngAria` | `Download chart as PNG` | `ChartJSRenderer` — PNG export button `aria-label` |
1084
+ | `chartCopy` | `Copy chart data (JSON)` | `ChartJSRenderer` — copy button `copyLabel` |
1085
+ | `chartLoading` | `Loading chart...` | `ChartJSRenderer` — overlay shown while the chart library and data are loading |
1086
+ | `codeSearchPlaceholder` | `Search…` | `CodeBlockRenderer` — in-code search input `placeholder` |
1087
+ | `codeSearchAria` | `Search in code` | `CodeBlockRenderer` — in-code search input `aria-label` |
1088
+ | `codeDownloadAria` | `Download code as file` | `CodeBlockRenderer` — download button `aria-label` |
1089
+ | `codeDownload` | `Download code` | `CodeBlockRenderer` — download button `title` |
1090
+ | `codeToggleWordWrap` | `Toggle word wrap` | `CodeBlockRenderer` — word-wrap toggle `aria-label` |
1091
+ | `codeCopy` | `Copy code` | `CodeBlockRenderer` — copy button `title`/`aria-label` |
1092
+ | `codeTitle` | `Code` | `CodeBlockRenderer` — heading and toolbar title when no filename/language is given |
1093
+ | `codeWordWrapEnable` | `Enable word wrap` | `CodeBlockRenderer` — word-wrap toggle `title` while word wrap is OFF |
1094
+ | `codeWordWrapDisable` | `Disable word wrap` | `CodeBlockRenderer` — word-wrap toggle `title` while word wrap is ON |
1095
+ | `exportCsvRows` | `Export CSV ({count} rows)` | `DataPreviewSection` — CSV export button `title`. Template: `{count}` |
1096
+ | `exportJsonRows` | `Export JSON ({count} rows)` | `DataPreviewSection` — JSON export button `title`. Template: `{count}` |
1097
+ | `sortBy` | `Sort by {column}` | `DataPreviewSection` / tables — sortable column header `title`. Template: `{column}` |
1098
+ | `removeItem` | `Remove {name}` | Form fields (chips/tags/filters) — removal button `aria-label`. Template: `{name}` |
1099
+ | `filterPlaceholder` | `Filter...` | Form fields — multi-select options filter input `placeholder` |
1100
+ | `fieldNotSupported` | `Not supported` | `FormFieldRenderer` — badge shown next to a field whose type the renderer does not support |
1101
+ | `fieldNoMatches` | `No matches` | `FormFieldRenderer` (`MultiSelectField`) — empty state of the option list |
1102
+ | `fieldGroupContainer` | `Group container` | `FormFieldRenderer` — fallback help text of a `fieldset` field with none |
1103
+ | `fieldSelectPlaceholder` | `Select...` | `FormFieldRenderer` — fallback `placeholder` of the multi-select trigger |
1104
+ | `fieldTagsPlaceholder` | `Type and press Enter...` | `FormFieldRenderer` (`TagsField`) — fallback `placeholder` of the tags input |
1105
+ | `scratchpadClose` | `Close` | `ScratchpadPanel` — close button `aria-label` |
1106
+ | `scratchpadPreview` | `Preview` | `ScratchpadPanel` — heading of the filter preview block |
1107
+ | `scratchpadNoResults` | `No results for these filters` | `ScratchpadPanel` — empty state of the filter preview block |
1108
+ | `scratchpadModifyFilters` | `Modify filters` | `ScratchpadPanel` — "refine the filters" button in the empty preview |
1109
+ | `scratchpadNoFilters` | `No filters` | `ScratchpadPanel` — empty state of the active-filter chip row |
1110
+ | `scratchpadEdit` | `Edit` | `ScratchpadPanel` — collapsed embedded form's "edit" button |
1111
+ | `scratchpadSend` | `Send` | `ScratchpadPanel` (`FeedbackSection`) — free-text feedback "send" button |
1112
+ | `scratchpadShowRaw` | `Show raw SSE payload` | `ScratchpadPanel` (`FormDebugTrace`) — debug toggle while the raw payload is hidden |
1113
+ | `scratchpadHideRaw` | `Hide raw SSE payload` | `ScratchpadPanel` (`FormDebugTrace`) — debug toggle while the raw payload is shown |
1114
+ | `scratchpadCommentPlaceholder` | `Add a comment...` | `ScratchpadPanel` (`FeedbackSection`) — fallback `placeholder` of the free-text feedback input |
1115
+ | `scratchpadError` | `Error` | `ScratchpadPanel` (`ErrorSectionRenderer`) — fallback message of an error section with none |
1116
+ | `scratchpadSource` | `Source` | `ScratchpadPanel` (`SourceCardSection`) — fallback name of a source card with none |
1117
+ | `graphExport` | `Export graph` | `GraphRenderer` — export-menu trigger `title`/`aria-label` |
1118
+ | `graphCopy` | `Copy graph (JSON)` | `GraphRenderer` — copy button `copyLabel` |
1119
+ | `graphTitle` | `Graph` | `GraphRenderer` — expandable-wrapper toolbar title when untitled |
1120
+ | `graphExportMenu` | `Export ▾` | `GraphRenderer` — visible label of the export-menu trigger button |
1121
+ | `graphDownloadPng` | `Download PNG` | `GraphRenderer` — "download PNG" export-menu item label |
1122
+ | `graphDownloadPngHint` | `visual snapshot` | `GraphRenderer` — hint under the "download PNG" item |
1123
+ | `graphDownloadMermaid` | `Download Mermaid` | `GraphRenderer` — "download Mermaid" export-menu item label |
1124
+ | `graphDownloadMermaidHint` | `markdown / GitHub` | `GraphRenderer` — hint under the "download Mermaid" item |
1125
+ | `graphDownloadJson` | `Download JSON` | `GraphRenderer` — "download JSON" export-menu item label |
1126
+ | `graphDownloadJsonHint` | `raw data` | `GraphRenderer` — hint under the "download JSON" item |
1127
+ | `galleryCopy` | `Copy image URLs` | `ImageGalleryRenderer` — copy button `copyLabel` |
1128
+ | `galleryTitle` | `Gallery` | `ImageGalleryRenderer` — expandable-wrapper toolbar title when untitled |
1129
+ | `videoCopy` | `Copy video URL` | `VideoRenderer` — copy button `copyLabel` |
1130
+ | `videoTitle` | `Video` | `VideoRenderer` — toolbar title and iframe `title` when untitled |
1131
+ | `sourceDetected` | `Detected from message` | `FormFieldRenderer` — "detected" prefill-source badge `title` |
1132
+ | `sourceInferred` | `Inferred from context` | `FormFieldRenderer` — "inferred" prefill-source badge `title` |
1133
+ | `sourcePrevious` | `Previously provided` | `FormFieldRenderer` — "user"/previous prefill-source badge `title` |
1134
+ | `lightboxLabel` | `Image lightbox` | `LightboxOverlay` — dialog `aria-label` |
1135
+ | `lightboxClose` | `Close lightbox` | `LightboxOverlay` — close button `aria-label` |
1136
+ | `lightboxPrevious` | `Previous image` | `LightboxOverlay` — previous-image button `aria-label` |
1137
+ | `lightboxNext` | `Next image` | `LightboxOverlay` — next-image button `aria-label` |
1138
+ | `modalClose` | `Close modal` | `ModalRenderer` — close button `aria-label` |
1139
+ | `copy` | `Copy` | `UIResourceRenderer` — default generic copy-button `title`/`aria-label` |
1140
+ | `copyMetric` | `Copy metric` | `UIResourceRenderer` (metric) — copy button `title` |
1141
+ | `copyText` | `Copy text` | `UIResourceRenderer` (text) — copy button `title` |
1142
+ | `copyErrorDetails` | `Copy error details` | `UIResourceRenderer` (error) — copy button `title` |
1143
+ | `tableTitle` | `Table` | `UIResourceRenderer` (table) — expandable-wrapper toolbar title when untitled |
1144
+ | `tableCopyCsv` | `Copy table (CSV)` | `UIResourceRenderer` (table) — CSV copy button `title`/`copyLabel` |
1145
+ | `tableExport` | `Export table` | `UIResourceRenderer` (table) — export-menu trigger `title`/`aria-label` |
1146
+ | `tableClearSearch` | `Clear search` | `UIResourceRenderer` (table) — search reset button `aria-label` |
1147
+ | `tableAriaLabel` | `Data table` | `UIResourceRenderer` (table) — scroll-region fallback `aria-label` when untitled |
1148
+ | `tableSearchPlaceholder` | `Search the table...` | `UIResourceRenderer` (table) — search input `placeholder`. A connector's own `tableParams.searchPlaceholder` still wins when set |
1149
+ | `tableCopyTsv` | `Copy TSV` | `UIResourceRenderer` (table) — "copy as TSV" export-menu item |
1150
+ | `tableDownloadCsv` | `Download CSV` | `UIResourceRenderer` (table) — "download CSV" export-menu item |
1151
+ | `tableDownloadJson` | `Download JSON` | `UIResourceRenderer` (table) — "download JSON" export-menu item |
1152
+ | `perPageSuffix` | `/ page` | `UIResourceRenderer` (table) — suffix after the pagination page-size selector |
1153
+ | `imageAlt` | `Image` | `UIResourceRenderer` (image) — fallback `alt` text |
1154
+ | `imageViewFullSize` | `View full size: {alt}` | `UIResourceRenderer` (image) — zoom-link `aria-label`. Template: `{alt}` |
1155
+ | `iframeTitle` | `Embedded content` | `UIResourceRenderer` (iframe) — fallback `title` |
1156
+ | `linkLabel` | `Link` | `UIResourceRenderer` (link) — fallback visible label |
1157
+ | `linkOpensInNewTab` | `{label}: {description} (opens in new tab)` | `UIResourceRenderer` (link) — `aria-label`. Template: `{label}`, `{description}` |
1158
+ | `validationWarning` | `Component validation warning` | `UIResourceRenderer` — inline component-validation warning chip `aria-label` |
1159
+ | `resourceTitle` | `Resource` | `UIResourceRenderer` — fallback heading for an HTML resource with no title or URI |
1160
+ | `chartError` | `Chart Error` | `UIResourceRenderer` (`ChartRenderer`) — heading of the chart renderer's error overlay |
1161
+ | `validationError` | `Validation Error` | `UIResourceRenderer` — heading of the blocking component-validation error card |
1162
+ | `validationUnknownError` | `Unknown validation error` | `UIResourceRenderer` — fallback detail of a validation error carrying no message |
1163
+ | `errorUnknown` | `Unknown error` | `UIResourceRenderer` (`ErrorCardRenderer`) — fallback message inside the error card's copyable text |
1164
+ | `errorUnknownToolName` | `Unknown` | `UIResourceRenderer` (`ErrorCardRenderer`) — fallback tool name in the error card heading |
1165
+ | `errorToolExecution` | `An error occurred during tool execution` | `UIResourceRenderer` (`ErrorCardRenderer`) — fallback body of an error card carrying no message |
1166
+ | `verifiedTitle` | `Verified against source data` | `VerifiedText` — `title` of a verified segment |
1167
+ | `verifiedAria` | `verified` | `VerifiedText` — verified marker glyph `aria-label` |
1168
+ | `unverifiedAria` | `unverified` | `VerifiedText` — unverified marker glyph `aria-label` |
1169
+ | `verifiedNotFound` | `Not found in source data` | `VerifiedText` — `title` when there is no closest match |
1170
+ | `verifiedNotFoundClosest` | `Not found in source data. Closest: {closest} ({pct}% off)` | `VerifiedText` — `title` when there is a closest match. Template: `{closest}`, `{pct}` |
1171
+ | `verifiedStripLabel` | `[unverified]` | `VerifiedText` — placeholder shown in `mode="strip"` |
1172
+ | `verifiedConfidence` | `{pct}% verified` | `ScratchpadPanel` (`ActionSection`), `VerifiedText` — confidence summary of a validated answer. Template: `{pct}` |
1173
+ | `verifiedUnverifiedCount` | `({count} unverified)` | `ScratchpadPanel` (`ActionSection`), `VerifiedText` — count of unverified numbers next to the confidence summary. Template: `{count}` |
1174
+ | `promptLoadingPreview` | `Loading preview...` | `ChatPrompt` (`FormBody`) — placeholder shown while the form's live preview is loading |
1175
+ | `promptConfirmed` | `Confirmed` | `ChatPrompt` — submitted label of a confirmed `confirm` prompt (no `confirmLabel`) |
1176
+ | `promptCancelled` | `Cancelled` | `ChatPrompt` — submitted label of a cancelled `confirm` prompt (no `cancelLabel`) |
1177
+ | `promptFormSubmitted` | `Form submitted` | `ChatPrompt` — submitted label of a `form` prompt whose fields are all empty |
1178
+ | `formSubmissionFailed` | `Submission failed` | `FormRenderer` — fallback error when the submit action fails without a message |
1179
+ | `formSubmitCountdown` | `{label} in {seconds}s...` | `FormRenderer` — auto-submit countdown notice. Template: `{label}`, `{seconds}` |
1180
+ | `actionGroupLabel` | `Action group` | `ActionGroupRenderer` — fallback `aria-label` of an action group without one |
1181
+ | `artifactDescription` | `Generated artifact` | `ArtifactRenderer` — fallback description of an artifact card without one |
1182
+ | `degradedCaption` | `Showing the underlying data — the interactive view is unavailable.` | `DegradedFallback` — fallback caption of the degraded-renderer notice |
1183
+ | `metaProvider` | `Provider` | `StreamingUIRenderer` — metadata panel provider cell label |
1184
+ | `metaModel` | `Model` | `StreamingUIRenderer` — metadata panel model cell label |
1185
+ | `metaExecutionTime` | `Execution Time` | `StreamingUIRenderer` — metadata panel execution-time cell label |
1186
+ | `metaCost` | `Cost` | `StreamingUIRenderer` — metadata panel cost cell label |
1187
+ | `metaTtfb` | `TTFB` | `StreamingUIRenderer` — metadata panel time-to-first-byte cell label |
1188
+ | `metaCached` | `Cached` | `StreamingUIRenderer` — metadata panel cache-hit cell label |
1189
+ | `download` | `Download` | `ArtifactRenderer` — download link label |
1190
+ | `unknown` | `unknown` | `GenerativeUIErrorBoundary` — fallback for a missing component type/id |
1191
+ | `citationUnresolved` | `[ref. {id}]` | `UIResourceRenderer` (table) — placeholder kept for a citation marker no `citationMap` resolves (empty map only). Template: `{id}` |
1192
+ | `invalidComponent` | `Invalid {type}` | `UIResourceRenderer` — `errorMode: 'inline-warn'` validation chip text. Template: `{type}` |
1193
+ | `toolErrorTitle` | `Tool Error: {tool}` | `UIResourceRenderer` — tool-error card heading. Template: `{tool}` (falls back to `errorUnknownToolName`) |
1194
+ | `errorTypeLabel` | `Type: {type}` | `UIResourceRenderer` — tool-error card error-type line. Template: `{type}` |
1195
+ | `errorSuggestions` | `Suggestions:` | `UIResourceRenderer` — heading above the tool-error suggestion list |
1196
+ | `chartInvalidData` | `Invalid chart data: missing data.datasets` | `UIResourceRenderer` (`ChartRenderer`) — shown when the payload has no `data.datasets` |
1197
+ | `unsupportedComponentType` | `Unsupported component type:` | `UIResourceRenderer` — prefix of the unsupported-component notice (the type follows in a `<code>`) |
1198
+ | `previewPrev` | `Prev` | `DataPreviewSection` — previous-page button visible label |
1199
+ | `previewNext` | `Next` | `DataPreviewSection` — next-page button visible label |
1200
+ | `previewPageIndicator` | `Page {page} / {total}` | `DataPreviewSection` — page indicator between the two buttons. Template: `{page}`, `{total}` |
1201
+ | `fieldResolving` | `Resolving...` | `FormFieldRenderer` — inline notice while an entity reference is being resolved |
1202
+ | `formPrefilledOne` | `{count} field pre-filled out of {total}` | `FormRenderer`, `ScratchpadPanel` — prefill summary, single field. Template: `{count}` (always 1), `{total}` |
1203
+ | `formPrefilledMany` | `{count} fields pre-filled out of {total}` | `FormRenderer`, `ScratchpadPanel` — prefill summary, several fields. Template: `{count}`, `{total}` |
1204
+ | `formSubmitting` | `Submitting...` | `FormRenderer` — busy label of the submit button while submitting |
1205
+ | `formReset` | `Reset` | `FormRenderer` — reset button label |
1206
+ | `errorBoundaryTitle` | `Component Failed to Render` | `GenerativeUIErrorBoundary` — default fallback heading |
1207
+ | `errorBoundaryMeta` | `Type: {type} \| ID: {id}...` | `GenerativeUIErrorBoundary` — default fallback metadata line. Template: `{type}`, `{id}` (both fall back to `unknown`) |
1208
+ | `errorBoundaryRetry` | `Retry Rendering` | `GenerativeUIErrorBoundary` — default fallback retry button label |
1209
+ | `scratchpadSearch` | `Search` | `ScratchpadPanel` — `waiting_human` search button label |
1210
+ | `scratchpadNextStep` | `Next` | `ScratchpadPanel` (`EnrichedStepsSection`) — advance-to-next-step button label |
1211
+ | `scratchpadPlan` | `Plan:` | `ScratchpadPanel` (`PromptSection`) — label preceding the interrogation plan summary |
1212
+ | `scratchpadModify` | `Modify` | `ScratchpadPanel` (`PromptSection`) — "modify this prompt" button label |
1213
+ | `scratchpadDetails` | `Details` | `ScratchpadPanel` (`ErrorSectionRenderer`) — "show details" toggle label |
1214
+ | `scratchpadItems` | `items` | `ScratchpadPanel` (`ActionSection`) — unit suffix after the item count |
1215
+ | `videoUnsupported` | `Your browser does not support the video tag.` | `VideoRenderer` — fallback text of a `<video>` element the browser cannot play |
1216
+ | `previewShowingRange` | `Showing {start}–{end} of {total}` | `DataPreviewSection` — paginated page-info line (template) |
1217
+ | `previewRowsOne` | `{count} row` | `DataPreviewSection` — unpaginated row count, singular (template) |
1218
+ | `previewRowsMany` | `{count} rows` | `DataPreviewSection` — unpaginated row count, plural (template) |
1219
+ | `previewTotalSuffix` | ` ({total} total)` | `DataPreviewSection` — suffix when the payload declares more rows than sent (template) |
1220
+ | `statusLoading` | `Loading...` | `ScratchpadPanel` — status badge, `loading` |
1221
+ | `statusActionAvailable` | `Action available` | `ScratchpadPanel` — status badge, `ready` |
1222
+ | `statusYourTurn` | `Your turn` | `ScratchpadPanel` — status badge, `waiting_human` |
1223
+ | `statusProcessing` | `Processing...` | `ScratchpadPanel` — status badge, `processing` |
1224
+ | `statusComplete` | `Complete` | `ScratchpadPanel` — status badge, `complete` (the `error` badge reuses `scratchpadError`) |
1225
+ | `agentStatusIdle` | `Idle` | `AgentCard` / `AgentStatusBadge` — status label |
1226
+ | `agentStatusRunning` | `Running` | `AgentCard` / `AgentStatusBadge` — status label |
1227
+ | `agentStatusWaiting` | `Waiting` | `AgentCard` / `AgentStatusBadge` — status label |
1228
+ | `agentStatusDone` | `Done` | `AgentCard` / `AgentStatusBadge` — status label |
1229
+ | `agentStatusError` | `Error` | `AgentCard` / `AgentStatusBadge` — status label |
1230
+ | `handoffItems` | `{count} items` | `AgentHandoff` — fallback summary (template); `content.summary` wins |
1231
+ | `degradedMoreRows` | `+{count} more rows not shown.` | `DegradedFallback` — truncation notice (template) |
1232
+ | `chartDegradedCaption` | `Showing the chart data as a table — the interactive chart is unavailable.` | `ChartJSRenderer` — degraded table caption |
1233
+ | `chartRenderFailed` | `Chart rendering failed: {error}` | `ChartJSRenderer` — degraded table notice (template) |
1234
+ | `chartRenderError` | `Chart rendering failed` | `ChartJSRenderer` — fallback reason when the render throws without a message |
1235
+ | `chartQuickchartCaption` | `Showing the chart data as a table.` | `UIResourceRenderer` — degraded table caption when chart.js is missing |
1236
+ | `graphDegradedCaption` | `Showing the graph data as a table — the interactive view is unavailable.` | `GraphRenderer` — degraded table caption |
1237
+ | `graphRenderFailed` | `Graph rendering failed: {error}` | `GraphRenderer` — degraded table notice (template) |
1238
+ | `graphRenderError` | `Failed to render graph` | `GraphRenderer` — fallback reason when the G6 render throws without a message |
1239
+ | `graphPngUnsupported` | `PNG export not supported in current renderer mode` | `GraphRenderer` — PNG export error |
1240
+ | `graphPngExportFailed` | `PNG export failed` | `GraphRenderer` — PNG export error without a message |
1241
+ | `mapDegradedCaption` | `Showing the map data as a coordinate table — the interactive map is unavailable.` | `MapRenderer` — degraded table caption |
1242
+ | `mapRenderFailed` | `Map rendering failed: {error}` | `MapRenderer` — degraded table notice (template) |
1243
+ | `mapRenderError` | `Failed to render map` | `MapRenderer` — fallback reason when the Leaflet render throws without a message |
1244
+ | `mapLibraryUnavailable` | `Map library could not be loaded.` | `MapRenderer` — the Leaflet bundle failed to load |
1245
+ | `degradedColType` | `Type` | Degraded map table — feature type column |
1246
+ | `degradedColLat` | `Lat` | Degraded map table — latitude column |
1247
+ | `degradedColLng` | `Lng` | Degraded map table — longitude column |
1248
+ | `degradedColInfo` | `Info` | Degraded map table — property summary column |
1249
+ | `degradedColSource` | `Source` | Degraded graph table — edge source column |
1250
+ | `degradedColTarget` | `Target` | Degraded graph table — edge target column |
1251
+ | `degradedColNode` | `Node` | Degraded graph table — node id column |
1252
+ | `degradedColLabel` | `Label` | Degraded graph / chart tables — label column |
1253
+ | `degradedSeries` | `Series {n}` | Degraded chart table — unlabelled dataset name (template) |
1254
+ | `chartTableSeries` | `Series` | `ChartJSRenderer` accessible data table — series column |
1255
+ | `chartTablePoint` | `Point` | `ChartJSRenderer` accessible data table — point-index column |
1256
+ | `autocompleteHintNavigate` | ` to navigate, ` | `AutocompleteDropdown` — hint prose between the arrow and Enter key caps |
1257
+ | `autocompleteHintSelect` | ` to select, ` | `AutocompleteDropdown` — hint prose between the Enter and Esc key caps |
1258
+ | `autocompleteHintDismiss` | ` to dismiss` | `AutocompleteDropdown` — hint prose after the Esc key cap |
1259
+ | `autocompleteTabToAccept` | `Tab to accept` | `AutocompleteFormField` — ghost-text hint |
1260
+ | `fieldAddMorePlaceholder` | `Add more...` | `FormFieldRenderer` — multi-value entity picker placeholder |
1261
+ | `galleryViewImage` | `View image {index}` | `ImageGalleryRenderer` — thumbnail button `aria-label` (template); `image.alt` wins |
1262
+ | `galleryImageAlt` | `Image {index}` | `ImageGalleryRenderer` — image `alt` (template); `image.alt` wins |
1263
+ | `imageAltFallback` | `image` | `UIResourceRenderer` — noun substituted into `imageViewFullSize` when the image has no `alt` |
1264
+ | `chartVisualizationAlt` | `Chart visualization` | `UIResourceRenderer` — chart image `alt`/`aria-label` with no payload title |
1265
+ | `chartWithTitleAlt` | `Chart: {title}` | `UIResourceRenderer` — chart image `alt`/`aria-label` with a title (template) |
1266
+ | `chartLoadFailed` | `Failed to load chart` | `UIResourceRenderer` — the chart image failed to load |
1267
+ | `paginationAllRows` | `All` | `UIResourceRenderer` — page-size option that disables pagination |
1268
+ | `fieldRequired` | `{field} is required` | Form validation (template) |
1269
+ | `fieldMustBeChecked` | `{field} must be checked` | Form validation (template) |
1270
+ | `fieldMinLength` | `Minimum {min} characters required` | Form validation (template) |
1271
+ | `fieldMaxLength` | `Maximum {max} characters allowed` | Form validation (template) |
1272
+ | `fieldInvalidPattern` | `Invalid format` | Form validation — value does not match `field.pattern` |
1273
+ | `fieldInvalidEmail` | `Invalid email address` | Form validation |
1274
+ | `fieldInvalidNumber` | `Must be a valid number` | Form validation |
1275
+ | `fieldMinValue` | `Minimum value is {min}` | Form validation (template) |
1276
+ | `fieldMaxValue` | `Maximum value is {max}` | Form validation (template) |
1277
+ | `fieldMinDate` | `Date must be after {min}` | Form validation (template) |
1278
+ | `fieldMaxDate` | `Date must be before {max}` | Form validation (template) |
1279
+ | `fieldInvalidOption` | `Please select a valid option` | Form validation |
1280
+ | `fieldInvalidFormat` | `Invalid format (expected: {format})` | Form validation (template); `field.valueFormatHint` wins |
1281
+ | `locale` | `en-US` | BCP-47 tag for number / date formatting and collation in chrome and table cells (see below) |
1282
+ | `briefingAdded` | `+{count} added` | `BriefingDiff` — stats summary (template) |
1283
+ | `briefingRemoved` | `{count} removed` | `BriefingDiff` — stats summary (template) |
1284
+ | `briefingChanged` | `{count} changed` | `BriefingDiff` — stats summary (template) |
1285
+ | `footerSources` | `{count} sources` | `FooterRenderer` — source count (template) |
1286
+ | `degradedMarker` | `marker` | Degraded map table — `Type` cell of a marker row |
1287
+ | `degradedFeature` | `feature` | Degraded map table — `Type` cell of a GeoJSON feature without a geometry type |
1288
+ | `fieldUnknownType` | `Unknown field type: {type}` | `FormFieldRenderer` — warning under a field of unknown type (template) |
1289
+ | `fieldSelectedCount` | `{count} selected` | `FormFieldRenderer` — multiselect trigger with selections (template) |
1290
+ | `scratchpadErrorCode` | `Code: {code}` | `ScratchpadPanel` — error state code line (template) |
1291
+ | `scratchpadResultCount` | `{count} results` | `ScratchpadPanel` — data-source card row count (template) |
1292
+ | `tableVirtualizedRows` | `(virtualized: {count} rows)` | `UIResourceRenderer` — table title suffix while virtualized (template) |
1293
+ | `tableSearchResultsOne` | `{count} result on {total}` | `UIResourceRenderer` — search result count, singular (template) |
1294
+ | `tableSearchResultsMany` | `{count} results on {total}` | `UIResourceRenderer` — search result count, plural (template) |
1295
+ | `tableServerPageRange` | `Showing {start} - {end} of {total}` | `UIResourceRenderer` — server-side pagination range (template) |
1296
+ | `errorCopyText` | `Error in {tool}: {message}` | `UIResourceRenderer` — text the tool-error card's Copy button puts on the clipboard (template) |
1297
+ | `errorUnknownTool` | `unknown tool` | `UIResourceRenderer` — tool name in `errorCopyText` when the error has none |
1298
+ | `streamInitializing` | `Initializing...` | `StreamingUIRenderer` — progress message before the stream starts |
1299
+ | `streamConnecting` | `Connecting to server...` | `StreamingUIRenderer` — progress message while connecting |
1300
+ | `streamLoadingComponent` | `Loading {type} component...` | `StreamingUIRenderer` — progress message per streamed component (template) |
1301
+ | `streamDashboardLoaded` | `Dashboard loaded` | `StreamingUIRenderer` — progress message on completion |
1302
+ | `streamErrorProgress` | `Error: {message}` | `StreamingUIRenderer` — progress message after an error (template) |
1303
+ | `streamConnectionFailed` | `Stream connection failed` | `StreamingUIRenderer` — error title when the connection fails |
1304
+ | `streamRequestFailed` | `Stream request failed` | `StreamingUIRenderer` — error message for a non-OK response without a message |
1305
+ | `streamEmptyResponse` | `Response body is null` | `StreamingUIRenderer` — error message for a response without a body |
1306
+ | `streamServerSide` | `Streaming UI cannot start on server-side` | `StreamingUIRenderer` — error message when started during SSR |
1307
+ | `streamUnknownError` | `Unknown error` | `StreamingUIRenderer` — error message when the failure has none |
1308
+ | `streamServerSideTitle` | `Streaming unavailable` | `StreamingUIRenderer` — error heading when streaming was started during SSR (replaces the machine code `ssr`) |
1309
+ | `graphUnavailable` | `Graph rendering unavailable` | `GraphRenderer` — heading when the `@antv/g6` peer is missing |
1310
+ | `mapPmtilesUnavailable` | `PMTiles layer unavailable — the optional "protomaps-leaflet" peer dependency failed to load or render.` | `MapRenderer` — banner when the PMTiles overlay fails |
1311
+ | `mapBaseMapStillShown` | `The base map is still shown.` | `MapRenderer` — sentence after the PMTiles banner |
1312
+ | `chartJsUnavailable` | `Chart.js is not available. Install chart.js peer dependency.` | `UIResourceRenderer` chart — error when `renderer: 'native'` is forced without chart.js |
1313
+ | `chartIframeUnavailable` | `Interactive chart unavailable — install the chart.js peer dependency, or set allowQuickchartFallback to use the external quickchart.io renderer.` | `UIResourceRenderer` chart — degraded-table message when chart.js is missing and quickchart is not allowed |
1314
+ | `previewInvalidContent` | `[DataPreviewSection] Invalid content format` | `DataPreviewSection` — fallback when the content is not `{ columns, rows }` |
1315
+ | `citationViewSource` | `View source - {label}` | `UIResourceRenderer` table — default citation chip tooltip (template; via `CitationCtx.viewSourceLabel`) |
1316
+ | `sizeBytes` | `{size} B` | `ArtifactRenderer` — file size below 1 KB (template) |
1317
+ | `sizeKilobytes` | `{size} KB` | `ArtifactRenderer` — file size in kilobytes (template) |
1318
+ | `sizeMegabytes` | `{size} MB` | `ArtifactRenderer` — file size in megabytes (template) |
1319
+
1320
+ ### `locale` — number, date and sort formatting (default change in v6.20.0)
1321
+
1322
+ `strings.locale` (default `'en-US'`) is passed to every `toLocaleString` /
1323
+ `toLocaleDateString` / `localeCompare` the library calls itself: table sorting
1324
+ and the client-side range count in `UIResourceRenderer`, the tool-error card
1325
+ timestamp, `DataPreviewSection` number / currency / date cells, sorting and
1326
+ page-info counts, `ScratchpadPanel` preview / data-source counts, and
1327
+ `MapRenderer` auto-generated popups. Before v6.20.0 these sites hardcoded
1328
+ `'fr-FR'` / `'fr'` or used the runtime's implicit locale (which could differ
1329
+ between SSR and hydration). To keep French formatting:
1330
+ `<MCPUIStringsProvider strings={{ locale: 'fr-FR' }}>`.
1331
+
1332
+ **SSR determinism.** `strings.locale` always resolves to an explicit BCP-47
1333
+ tag — `'en-US'` unless a provider overrides it — never to the server's or the
1334
+ browser's ambient locale. That is what makes it safe to call in SSR
1335
+ components: the same tag renders the same formatted string on the server and
1336
+ after hydration, so there is no server/client markup mismatch. Relying on the
1337
+ runtime's implicit locale (an argument-less `toLocaleString()`) is exactly
1338
+ the pre-v6.20.0 behavior this key replaces, and it did not have that
1339
+ guarantee. An invalid tag in the provider resolves to `'en-US'` instead of
1340
+ making `Intl` throw (`resolveMCPUILocale()` exposes the same check).
1341
+
1342
+ The locale does not fix the time zone. Date-only `DataPreviewSection` cells
1343
+ are formatted in UTC so every viewer sees the same calendar date. Date-time
1344
+ cells and the tool-error card timestamp are formatted only after mount, in the
1345
+ viewer's time zone: server markup shows the raw date-time value.
1346
+
1347
+ `useStreamingUI()` called directly (without `StreamingUIRenderer`) takes the
1348
+ same messages as a `messages` option (`DEFAULT_STREAMING_UI_MESSAGES`).
1349
+
1350
+ ### `tableSearchPlaceholder`, `verifiedStripLabel`, `scratchpadEdit`, `citationUnresolved` and `formPrefilledOne`/`formPrefilledMany` changed from French to English
1351
+
1352
+ As of v6.20.0 these five defaults are English, matching every other key. If
1353
+ you relied on the previous French defaults with no provider mounted,
1354
+ restore them explicitly:
1355
+
1356
+ ```tsx
1357
+ <MCPUIStringsProvider
1358
+ strings={{
1359
+ tableSearchPlaceholder: 'Rechercher dans le tableau...',
1360
+ verifiedStripLabel: '[non vérifié]',
1361
+ scratchpadEdit: 'Modifier',
1362
+ citationUnresolved: '[réf. {id}]',
1363
+ formPrefilledOne: '{count} champ pré-rempli sur {total}',
1364
+ formPrefilledMany: '{count} champs pré-remplis sur {total}',
1365
+ }}
1366
+ >
1367
+ <App />
1368
+ </MCPUIStringsProvider>
1369
+ ```
1370
+
1371
+ ### French example dictionary
1372
+
1373
+ A complete override covering every key above:
1374
+
1375
+ ```tsx
1376
+ import { MCPUIStringsProvider } from '@seed-ship/mcp-ui-solid'
1377
+ import type { MCPUIStrings } from '@seed-ship/mcp-ui-solid'
1378
+
1379
+ const fr: MCPUIStrings = {
1380
+ expand: 'Agrandir',
1381
+ expandedView: 'Vue agrandie',
1382
+ copyToClipboard: 'Copier dans le presse-papiers',
1383
+ closeExpandedView: 'Fermer la vue agrandie',
1384
+ feedbackUseful: 'Utile',
1385
+ feedbackNotUseful: 'Pas utile',
1386
+ feedbackPositiveAck: 'Merci !',
1387
+ feedbackNegativeAck: "Noté — on va s'améliorer",
1388
+ retry: 'Réessayer',
1389
+ ok: 'OK',
1390
+ cancel: 'Annuler',
1391
+ confirm: 'Confirmer',
1392
+ submit: 'Envoyer',
1393
+ dismiss: 'Fermer',
1394
+ yes: 'Oui',
1395
+ no: 'Non',
1396
+ chartView: 'Graphique',
1397
+ chartDataView: 'Données',
1398
+ chartViewSelector: 'Vue graphique ou données',
1399
+ chartDataTable: 'Données du graphique',
1400
+ chartDataSummary: 'Les valeurs exactes sont disponibles dans la vue données.',
1401
+ chartNoData: 'Aucune donnée de graphique',
1402
+ paginationPrevious: 'Page précédente',
1403
+ paginationNext: 'Page suivante',
1404
+ paginationPageSize: 'Lignes par page',
1405
+ gridRegion: 'Grille de mise en page',
1406
+ autocompleteSuggestions: 'Suggestions',
1407
+ autocompleteLoading: 'Chargement...',
1408
+ autocompleteEmpty: 'Aucune suggestion trouvée',
1409
+ carouselTitle: 'Carrousel',
1410
+ carouselCopy: 'Copier les éléments (JSON)',
1411
+ mapTitle: 'Carte',
1412
+ mapCopy: 'Copier les repères en GeoJSON',
1413
+ chartDownloadPng: 'Télécharger en PNG',
1414
+ chartDownloadPngAria: 'Télécharger le graphique en PNG',
1415
+ chartCopy: 'Copier les données du graphique (JSON)',
1416
+ chartLoading: 'Chargement du graphique...',
1417
+ codeSearchPlaceholder: 'Rechercher…',
1418
+ codeSearchAria: 'Rechercher dans le code',
1419
+ codeDownloadAria: 'Télécharger le code en fichier',
1420
+ codeDownload: 'Télécharger le code',
1421
+ codeToggleWordWrap: 'Activer/désactiver le retour à la ligne',
1422
+ codeCopy: 'Copier le code',
1423
+ codeTitle: 'Code',
1424
+ codeWordWrapEnable: 'Activer le retour à la ligne',
1425
+ codeWordWrapDisable: 'Désactiver le retour à la ligne',
1426
+ exportCsvRows: 'Exporter en CSV ({count} lignes)',
1427
+ exportJsonRows: 'Exporter en JSON ({count} lignes)',
1428
+ sortBy: 'Trier par {column}',
1429
+ removeItem: 'Supprimer {name}',
1430
+ filterPlaceholder: 'Filtrer...',
1431
+ fieldNotSupported: 'Non pris en charge',
1432
+ fieldNoMatches: 'Aucun résultat',
1433
+ fieldGroupContainer: 'Conteneur de groupe',
1434
+ fieldSelectPlaceholder: 'Sélectionner...',
1435
+ fieldTagsPlaceholder: 'Saisir puis appuyer sur Entrée...',
1436
+ scratchpadClose: 'Fermer',
1437
+ scratchpadPreview: 'Aperçu',
1438
+ scratchpadNoResults: 'Aucun résultat pour ces filtres',
1439
+ scratchpadModifyFilters: 'Modifier les filtres',
1440
+ scratchpadNoFilters: 'Aucun filtre',
1441
+ scratchpadEdit: 'Modifier',
1442
+ scratchpadSend: 'Envoyer',
1443
+ scratchpadShowRaw: 'Afficher la charge SSE brute',
1444
+ scratchpadHideRaw: 'Masquer la charge SSE brute',
1445
+ scratchpadCommentPlaceholder: 'Ajouter un commentaire...',
1446
+ scratchpadError: 'Erreur',
1447
+ scratchpadSource: 'Source',
1448
+ graphExport: 'Exporter le graphe',
1449
+ graphCopy: 'Copier le graphe (JSON)',
1450
+ graphTitle: 'Graphe',
1451
+ graphExportMenu: 'Exporter ▾',
1452
+ graphDownloadPng: 'Télécharger en PNG',
1453
+ graphDownloadPngHint: 'instantané visuel',
1454
+ graphDownloadMermaid: 'Télécharger en Mermaid',
1455
+ graphDownloadMermaidHint: 'markdown / GitHub',
1456
+ graphDownloadJson: 'Télécharger en JSON',
1457
+ graphDownloadJsonHint: 'données brutes',
1458
+ galleryCopy: 'Copier les URL des images',
1459
+ galleryTitle: 'Galerie',
1460
+ videoCopy: "Copier l'URL de la vidéo",
1461
+ videoTitle: 'Vidéo',
1462
+ sourceDetected: 'Détecté depuis le message',
1463
+ sourceInferred: 'Déduit du contexte',
1464
+ sourcePrevious: 'Fourni précédemment',
1465
+ lightboxLabel: "Visionneuse d'image",
1466
+ lightboxClose: 'Fermer la visionneuse',
1467
+ lightboxPrevious: 'Image précédente',
1468
+ lightboxNext: 'Image suivante',
1469
+ modalClose: 'Fermer la fenêtre modale',
1470
+ copy: 'Copier',
1471
+ copyMetric: 'Copier la métrique',
1472
+ copyText: 'Copier le texte',
1473
+ copyErrorDetails: "Copier les détails de l'erreur",
1474
+ tableTitle: 'Tableau',
1475
+ tableCopyCsv: 'Copier le tableau (CSV)',
1476
+ tableExport: 'Exporter le tableau',
1477
+ tableClearSearch: 'Effacer la recherche',
1478
+ tableAriaLabel: 'Tableau de données',
1479
+ tableSearchPlaceholder: 'Rechercher dans le tableau...',
1480
+ tableCopyTsv: 'Copier en TSV',
1481
+ tableDownloadCsv: 'Télécharger en CSV',
1482
+ tableDownloadJson: 'Télécharger en JSON',
1483
+ perPageSuffix: '/ page',
1484
+ imageAlt: 'Image',
1485
+ imageViewFullSize: 'Voir en taille réelle : {alt}',
1486
+ iframeTitle: 'Contenu intégré',
1487
+ linkLabel: 'Lien',
1488
+ linkOpensInNewTab: '{label} : {description} (ouvre un nouvel onglet)',
1489
+ validationWarning: 'Avertissement de validation du composant',
1490
+ resourceTitle: 'Ressource',
1491
+ chartError: 'Erreur du graphique',
1492
+ validationError: 'Erreur de validation',
1493
+ validationUnknownError: 'Erreur de validation inconnue',
1494
+ errorUnknown: 'Erreur inconnue',
1495
+ errorUnknownToolName: 'Inconnu',
1496
+ errorToolExecution: "Une erreur s'est produite lors de l'exécution de l'outil",
1497
+ verifiedTitle: 'Vérifié par rapport aux données source',
1498
+ verifiedAria: 'vérifié',
1499
+ unverifiedAria: 'non vérifié',
1500
+ verifiedNotFound: 'Introuvable dans les données source',
1501
+ verifiedNotFoundClosest: "Introuvable dans les données source. Le plus proche : {closest} ({pct} % d'écart)",
1502
+ verifiedStripLabel: '[non vérifié]',
1503
+ verifiedConfidence: '{pct}% vérifié',
1504
+ verifiedUnverifiedCount: '({count} non vérifié)',
1505
+ promptLoadingPreview: "Chargement de l'aperçu...",
1506
+ promptConfirmed: 'Confirmé',
1507
+ promptCancelled: 'Annulé',
1508
+ promptFormSubmitted: 'Formulaire envoyé',
1509
+ formSubmissionFailed: 'Envoi échoué',
1510
+ formSubmitCountdown: '{label} dans {seconds}s...',
1511
+ actionGroupLabel: "Groupe d'actions",
1512
+ artifactDescription: 'Artefact généré',
1513
+ degradedCaption: "Affichage des données sous-jacentes — la vue interactive n'est pas disponible.",
1514
+ metaProvider: 'Fournisseur',
1515
+ metaModel: 'Modèle',
1516
+ metaExecutionTime: "Temps d'exécution",
1517
+ metaCost: 'Coût',
1518
+ metaTtfb: 'TTFB',
1519
+ metaCached: 'En cache',
1520
+ download: 'Télécharger',
1521
+ unknown: 'inconnu',
1522
+ citationUnresolved: '[réf. {id}]',
1523
+ invalidComponent: '{type} invalide',
1524
+ toolErrorTitle: 'Erreur outil : {tool}',
1525
+ errorTypeLabel: 'Type : {type}',
1526
+ errorSuggestions: 'Suggestions :',
1527
+ chartInvalidData: 'Données de graphique invalides : data.datasets manquant',
1528
+ unsupportedComponentType: 'Type de composant non pris en charge :',
1529
+ previewPrev: 'Préc.',
1530
+ previewNext: 'Suiv.',
1531
+ previewPageIndicator: 'Page {page} / {total}',
1532
+ fieldResolving: 'Résolution...',
1533
+ formPrefilledOne: '{count} champ pré-rempli sur {total}',
1534
+ formPrefilledMany: '{count} champs pré-remplis sur {total}',
1535
+ formSubmitting: 'Envoi...',
1536
+ formReset: 'Réinitialiser',
1537
+ errorBoundaryTitle: "Le composant n'a pas pu être rendu",
1538
+ errorBoundaryMeta: 'Type : {type} | ID : {id}...',
1539
+ errorBoundaryRetry: 'Réessayer le rendu',
1540
+ scratchpadSearch: 'Rechercher',
1541
+ scratchpadNextStep: 'Suivant',
1542
+ scratchpadPlan: 'Plan :',
1543
+ scratchpadModify: 'Modifier',
1544
+ scratchpadDetails: 'Détails',
1545
+ scratchpadItems: 'éléments',
1546
+ videoUnsupported: 'Votre navigateur ne prend pas en charge la balise vidéo.',
1547
+ previewShowingRange: 'Affichage de {start}–{end} sur {total}',
1548
+ previewRowsOne: '{count} ligne',
1549
+ previewRowsMany: '{count} lignes',
1550
+ previewTotalSuffix: ' ({total} au total)',
1551
+ statusLoading: 'Chargement...',
1552
+ statusActionAvailable: 'Action disponible',
1553
+ statusYourTurn: 'À vous',
1554
+ statusProcessing: 'Traitement...',
1555
+ statusComplete: 'Terminé',
1556
+ agentStatusIdle: 'Inactif',
1557
+ agentStatusRunning: 'En cours',
1558
+ agentStatusWaiting: 'En attente',
1559
+ agentStatusDone: 'Terminé',
1560
+ agentStatusError: 'Erreur',
1561
+ handoffItems: '{count} éléments',
1562
+ degradedMoreRows: '+{count} lignes supplémentaires non affichées.',
1563
+ chartDegradedCaption:
1564
+ "Affichage des données du graphique sous forme de tableau — le graphique interactif n'est pas disponible.",
1565
+ chartRenderFailed: 'Échec du rendu du graphique : {error}',
1566
+ chartRenderError: 'Échec du rendu du graphique',
1567
+ chartQuickchartCaption: 'Affichage des données du graphique sous forme de tableau.',
1568
+ graphDegradedCaption:
1569
+ "Affichage des données du graphe sous forme de tableau — la vue interactive n'est pas disponible.",
1570
+ graphRenderFailed: 'Échec du rendu du graphe : {error}',
1571
+ graphRenderError: 'Échec du rendu du graphe',
1572
+ graphPngUnsupported: "Export PNG non pris en charge dans ce mode de rendu",
1573
+ graphPngExportFailed: 'Échec de l’export PNG',
1574
+ mapDegradedCaption:
1575
+ "Affichage des données de la carte sous forme de tableau de coordonnées — la carte interactive n'est pas disponible.",
1576
+ mapRenderFailed: 'Échec du rendu de la carte : {error}',
1577
+ mapRenderError: 'Échec du rendu de la carte',
1578
+ mapLibraryUnavailable: 'Impossible de charger la bibliothèque de cartographie.',
1579
+ degradedColType: 'Type',
1580
+ degradedColLat: 'Lat',
1581
+ degradedColLng: 'Long',
1582
+ degradedColInfo: 'Infos',
1583
+ degradedColSource: 'Source',
1584
+ degradedColTarget: 'Cible',
1585
+ degradedColNode: 'Nœud',
1586
+ degradedColLabel: 'Libellé',
1587
+ degradedSeries: 'Série {n}',
1588
+ chartTableSeries: 'Série',
1589
+ chartTablePoint: 'Point',
1590
+ autocompleteHintNavigate: ' pour naviguer, ',
1591
+ autocompleteHintSelect: ' pour sélectionner, ',
1592
+ autocompleteHintDismiss: ' pour fermer',
1593
+ autocompleteTabToAccept: 'Tab pour accepter',
1594
+ fieldAddMorePlaceholder: 'Ajouter...',
1595
+ galleryViewImage: "Voir l'image {index}",
1596
+ galleryImageAlt: 'Image {index}',
1597
+ imageAltFallback: 'image',
1598
+ chartVisualizationAlt: 'Visualisation du graphique',
1599
+ chartWithTitleAlt: 'Graphique : {title}',
1600
+ chartLoadFailed: 'Échec du chargement du graphique',
1601
+ paginationAllRows: 'Toutes',
1602
+ fieldRequired: '{field} est requis',
1603
+ fieldMustBeChecked: '{field} doit être coché',
1604
+ fieldMinLength: '{min} caractères minimum requis',
1605
+ fieldMaxLength: '{max} caractères maximum autorisés',
1606
+ fieldInvalidPattern: 'Format invalide',
1607
+ fieldInvalidEmail: 'Adresse e-mail invalide',
1608
+ fieldInvalidNumber: 'Doit être un nombre valide',
1609
+ fieldMinValue: 'La valeur minimale est {min}',
1610
+ fieldMaxValue: 'La valeur maximale est {max}',
1611
+ fieldMinDate: 'La date doit être postérieure au {min}',
1612
+ fieldMaxDate: 'La date doit être antérieure au {max}',
1613
+ fieldInvalidOption: 'Veuillez sélectionner une option valide',
1614
+ fieldInvalidFormat: 'Format invalide (attendu : {format})',
1615
+ locale: 'fr-FR',
1616
+ briefingAdded: '+{count} ajouté(s)',
1617
+ briefingRemoved: '{count} supprimé(s)',
1618
+ briefingChanged: '{count} modifié(s)',
1619
+ footerSources: '{count} sources',
1620
+ degradedMarker: 'repère',
1621
+ degradedFeature: 'entité',
1622
+ fieldUnknownType: 'Type de champ inconnu : {type}',
1623
+ fieldSelectedCount: '{count} sélectionné(s)',
1624
+ scratchpadErrorCode: 'Code : {code}',
1625
+ scratchpadResultCount: '{count} résultats',
1626
+ tableVirtualizedRows: '(virtualisé : {count} lignes)',
1627
+ tableSearchResultsOne: '{count} résultat sur {total}',
1628
+ tableSearchResultsMany: '{count} résultats sur {total}',
1629
+ tableServerPageRange: 'Lignes {start} à {end} sur {total}',
1630
+ errorCopyText: 'Erreur dans {tool} : {message}',
1631
+ errorUnknownTool: 'outil inconnu',
1632
+ streamInitializing: 'Initialisation...',
1633
+ streamConnecting: 'Connexion au serveur...',
1634
+ streamLoadingComponent: 'Chargement du composant {type}...',
1635
+ streamDashboardLoaded: 'Tableau de bord chargé',
1636
+ streamErrorProgress: 'Erreur : {message}',
1637
+ streamConnectionFailed: 'Échec de la connexion au flux',
1638
+ streamRequestFailed: 'Échec de la requête de flux',
1639
+ streamEmptyResponse: 'Réponse vide',
1640
+ streamServerSide: 'Le streaming ne peut pas démarrer côté serveur',
1641
+ streamUnknownError: 'Erreur inconnue',
1642
+ streamServerSideTitle: 'Streaming indisponible',
1643
+ graphUnavailable: 'Rendu du graphe indisponible',
1644
+ mapPmtilesUnavailable:
1645
+ "Couche PMTiles indisponible — la dépendance optionnelle « protomaps-leaflet » n'a pas pu être chargée ou rendue.",
1646
+ mapBaseMapStillShown: 'Le fond de carte reste affiché.',
1647
+ chartJsUnavailable: "Chart.js n'est pas disponible. Installez la dépendance chart.js.",
1648
+ chartIframeUnavailable:
1649
+ 'Graphique interactif indisponible — installez la dépendance chart.js, ou activez allowQuickchartFallback pour utiliser le rendu externe quickchart.io.',
1650
+ previewInvalidContent: 'Format de contenu invalide',
1651
+ citationViewSource: 'Voir la source - {label}',
1652
+ sizeBytes: '{size} o',
1653
+ sizeKilobytes: '{size} Ko',
1654
+ sizeMegabytes: '{size} Mo',
1655
+ }
1656
+
1657
+ <MCPUIStringsProvider strings={fr}><App /></MCPUIStringsProvider>
1658
+ ```
1659
+
1660
+ ### Exclusion policy
1661
+
1662
+ A handful of strings stay hardcoded on purpose — P1–P8, with every concrete
1663
+ occurrence, live in [`CHANGELOG.md`](./CHANGELOG.md)'s `## [6.20.0]` entry.
1664
+ In short:
1665
+
1666
+ | # | What stays hardcoded | Why |
1667
+ |---|---|---|
1668
+ | P1 | Keyboard key caps inside `<kbd>` (`Enter`, `Esc`) | The physical key reads the same in any language |
1669
+ | P2 | The OpenStreetMap / ODbL tile attribution | Exact wording required by the license; override via `params.attribution` |
1670
+ | P3 | Developer diagnostics naming an npm/peer package or a config flag, bracketed `[Component] …` messages, debug-only panels, developer-misuse errors, and the structural `ValidationError.message` of `services/validation.ts` | Addressed to a developer or to the payload producer, not to the end user |
1671
+ | P4 | Machine tokens: file-format acronyms, HTTP verbs, unit symbols, ISO currency codes, chart point property names (`x`/`y`/`r`) | Not prose — still overridable where a `labels` parameter exists |
1672
+ | P5 | Pure module functions with a documented render override | No occurrence remains — the citation chip tooltip is now `citationViewSource` |
1673
+ | P6 | `PresentationFeedback`'s labels | The component documents its own `labels` prop instead |
1674
+ | P7 | Hook-level errors returned to the consumer, `onError` payloads, `console`/logger/telemetry strings | The library itself never renders these |
1675
+ | P8 | `services/component-registry.ts` and `plugins/` system prompts | LLM-facing schema/example text — translating it would teach the model non-English payloads |
1676
+
1677
+ ### Options — runtime-free adapters, services and hooks
1678
+
1679
+ These modules cannot rely on `MCPUIStringsProvider`: the adapters, services
1680
+ and helpers are runtime-free (no `solid-js` import), and `useStreamingUI` is a
1681
+ hook a host may call outside any provider. So each takes its own English wording as a trailing optional parameter with an
1682
+ exported default table:
1683
+
1684
+ | Module | Function(s) | Option | Default table | Keys |
1685
+ |---|---|---|---|---|
1686
+ | `adapters/connector.ts` (`/adapters`) | `connectorResultToUILayout` | `options.messages?: Partial<ConnectorAdapterMessages>` | `DEFAULT_CONNECTOR_MESSAGES` | `degradedNotice`, `degradedVersionSuffix`, `versionWarning` |
1687
+ | `adapters/macro-run.ts` (`/adapters`) | `macroRunToScratchpadState`, `macroInterrogationToChatPromptConfig` | `options.messages?: Partial<MacroRunAdapterMessages>` | `DEFAULT_MACRO_RUN_MESSAGES` | `agentSectionTitle`, `progressSectionTitle`, `resultSectionTitle`, `runAborted`, `runFailed`, `confirmDefault` |
1688
+ | `services/validation.ts` (root, `/validation`) | `validateFieldValue`, `validateFormData` | `messages?: Partial<FormValidationMessages>` | `DEFAULT_VALIDATION_MESSAGES` | `required`, `mustBeChecked`, `minLength`, `maxLength`, `invalidPattern`, `invalidEmail`, `invalidNumber`, `minValue`, `maxValue`, `minDate`, `maxDate`, `invalidOption`, `invalidFormat` |
1689
+ | `utils/degraded-projections.ts` (root) | `graphToDegradedTable`, `mapToDegradedTable`, `chartToDegradedTable` | `labels?: Partial<DegradedProjectionLabels>` | `DEGRADED_PROJECTION_LABELS` | `source`, `target`, `label`, `node`, `type`, `lat`, `lng`, `info`, `marker`, `feature`, `series` |
1690
+ | `components/chart-data-table.ts` (root) | `chartToDataTable` | `labels?: Partial<ChartDataTableLabels>` | `CHART_DATA_TABLE_LABELS` | `series`, `point`, `label`, `seriesName`, `x`, `y`, `r` |
1691
+ | `hooks/useStreamingUI.ts` (root, `/hooks`) | `useStreamingUI` | `options.messages?: Partial<StreamingUIMessages>` | `DEFAULT_STREAMING_UI_MESSAGES` | `initializing`, `connecting`, `loadingComponent`, `dashboardLoaded`, `errorProgress`, `connectionFailed`, `requestFailed`, `emptyResponse`, `serverSide`, `unknownError` |
1692
+
1693
+ Every option is a trailing OPTIONAL parameter, so existing calls keep
1694
+ type-checking and behaving identically. `StreamingUIRenderer` and
1695
+ `FormRenderer` feed their module's table from `useMCPUIStrings()`
1696
+ automatically — a host only calls these functions with an explicit
1697
+ `messages`/`labels` override when it uses the adapter or helper directly,
1698
+ outside a component that already wires it up.
1699
+
910
1700
  ## Telemetry
911
1701
 
912
1702
  Optional, fail-open event sink for component lifecycle, validation and action