@helpai/elements 0.30.1 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, H as HandshakeResponse, L as Link, S as ServerConfig, b as SiteConfig, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial } from './deployment-rva7dkso.js';
1
+ export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, H as HandshakeResponse, L as Link, S as ServerConfig, b as SiteConfig, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial } from './deployment-DRGLrW2j.js';
2
2
  import 'zod';
3
3
 
4
4
  /**
@@ -505,6 +505,46 @@ interface FormDef {
505
505
  * `/activity` records for such forms).
506
506
  */
507
507
  reviewable?: boolean;
508
+ /** BCP-47 locale the top-level strings (title / fields copy) are authored in. */
509
+ defaultLocale?: string;
510
+ /**
511
+ * Per-locale string overrides. The data module trims this to the requested
512
+ * `?locale=` (≤1 entry); the widget overlays it onto the default copy at
513
+ * resolve time (`overlayFormDef`). Absent strings fall back to the default.
514
+ */
515
+ translations?: FormTranslation[];
516
+ }
517
+ /**
518
+ * Per-locale overrides of a form's HUMAN-FACING strings only. Structure (field
519
+ * `name` / `type` / `validation`, option `value`) is shared across locales and
520
+ * stays canonical, so submissions + validation are locale-independent — a
521
+ * translation matches the canonical form by the stable `name` (field) / `value`
522
+ * (option) keys. Absent strings fall back to the top-level (defaultLocale) copy.
523
+ *
524
+ * The data module trims `FormDef.translations` to the requested `?locale=` (≤1
525
+ * entry) on read; the widget overlays that entry onto the default fields. Mirror
526
+ * of `module-help-ai-data-api` `DynamicFormTranslation`.
527
+ */
528
+ interface FieldOptionTranslation {
529
+ /** The canonical option `value` this localizes. */
530
+ value: string;
531
+ label?: string;
532
+ description?: string;
533
+ }
534
+ interface FormFieldTranslation {
535
+ /** The canonical field `name` this localizes. */
536
+ name: string;
537
+ label?: string;
538
+ placeholder?: string;
539
+ validationHint?: string;
540
+ options?: FieldOptionTranslation[];
541
+ }
542
+ interface FormTranslation {
543
+ locale: string;
544
+ title?: string;
545
+ description?: string;
546
+ submitLabel?: string;
547
+ fields?: FormFieldTranslation[];
508
548
  }
509
549
  /** The `forms` block is an ordered list (max 20); order = priority. */
510
550
  type FormsOptions = FormDef[];
package/index.mjs CHANGED
@@ -275,8 +275,8 @@ function resolveStrings(locale, override) {
275
275
  function primaryTag(locale) {
276
276
  return (locale.split("-")[0] ?? "en").toLowerCase();
277
277
  }
278
- function moduleLabel(strings, label) {
279
- return strings[label] ?? label;
278
+ function localizeText(strings, value) {
279
+ return strings[value] ?? value;
280
280
  }
281
281
  function isNestedShape(override) {
282
282
  if (!override) return false;
@@ -286,6 +286,51 @@ function isNestedShape(override) {
286
286
  return false;
287
287
  }
288
288
 
289
+ // src/i18n/overlay.ts
290
+ function pickTranslation(translations, locale) {
291
+ if (!translations?.length || !locale) return void 0;
292
+ return translations.find((t) => t.locale === locale);
293
+ }
294
+ function overlayContent(item, locale) {
295
+ const { translations, defaultLocale: _defaultLocale, ...base } = item;
296
+ const tr = pickTranslation(translations, locale);
297
+ if (!tr) return base;
298
+ return {
299
+ ...base,
300
+ title: tr.title ?? base.title,
301
+ description: tr.description ?? base.description,
302
+ content: tr.content ?? base.content
303
+ };
304
+ }
305
+ function overlayFormDef(def, locale) {
306
+ const { translations, defaultLocale: _defaultLocale, ...base } = def;
307
+ const tr = pickTranslation(translations, locale);
308
+ if (!tr) return base;
309
+ const fieldTrByName = new Map((tr.fields ?? []).map((f) => [f.name, f]));
310
+ const fields = base.fields.map((field) => {
311
+ const ftr = fieldTrByName.get(field.name);
312
+ if (!ftr) return field;
313
+ const optionTrByValue = new Map((ftr.options ?? []).map((o) => [o.value, o]));
314
+ return {
315
+ ...field,
316
+ label: ftr.label ?? field.label,
317
+ placeholder: ftr.placeholder ?? field.placeholder,
318
+ validationHint: ftr.validationHint ?? field.validationHint,
319
+ options: field.options?.map((option) => {
320
+ const otr = optionTrByValue.get(option.value);
321
+ return otr ? { ...option, label: otr.label ?? option.label, description: otr.description ?? option.description } : option;
322
+ })
323
+ };
324
+ });
325
+ return {
326
+ ...base,
327
+ title: tr.title ?? base.title,
328
+ description: tr.description ?? base.description,
329
+ submitLabel: tr.submitLabel ?? base.submitLabel,
330
+ fields
331
+ };
332
+ }
333
+
289
334
  // src/core/storage.ts
290
335
  var LocalStorageAdapter = class {
291
336
  get(key) {
@@ -552,7 +597,7 @@ function resolveOptions(rawOpts) {
552
597
  humanInLoop: opts.features?.humanInLoop ?? DEFAULT_FEATURES.humanInLoop,
553
598
  tools: opts.features?.tools
554
599
  },
555
- forms: resolveForms(opts.forms),
600
+ forms: resolveForms(opts.forms, locale),
556
601
  endpoints: {
557
602
  upload: opts.endpoints?.upload ?? DEFAULT_ENDPOINTS.upload,
558
603
  transcribe: opts.endpoints?.transcribe ?? DEFAULT_ENDPOINTS.transcribe,
@@ -675,13 +720,14 @@ function resolveModules(overrides) {
675
720
  const byId = Object.fromEntries(list.map((m) => [m.id, m]));
676
721
  return { list, byId };
677
722
  }
678
- function resolveForms(overrides) {
723
+ function resolveForms(overrides, locale) {
679
724
  var _a;
680
725
  if (!overrides?.length) return DEFAULT_FORMS;
681
726
  const list = [];
682
727
  const seen = /* @__PURE__ */ new Set();
683
- for (const def of overrides) {
684
- if (!def?.id || seen.has(def.id)) continue;
728
+ for (const raw of overrides) {
729
+ if (!raw?.id || seen.has(raw.id)) continue;
730
+ const def = overlayFormDef(raw, locale);
685
731
  const fields = (def.fields ?? []).filter((f) => Boolean(f && f.name && f.label && f.type));
686
732
  const triggers = (Array.isArray(def.on) ? def.on : [def.on]).map(parseTrigger).filter((t) => t !== null);
687
733
  if (fields.length === 0 || triggers.length === 0) continue;
@@ -1844,7 +1890,7 @@ var AgentTransport = class {
1844
1890
  }
1845
1891
  /** Fetch content rows by filter. `GET /pai/content` (data-API), TTL-cached. */
1846
1892
  listContent(query = {}) {
1847
- const key = JSON.stringify(query, Object.keys(query).toSorted());
1893
+ const key = `${this.locale ?? ""}|${JSON.stringify(query, Object.keys(query).toSorted())}`;
1848
1894
  const cached = this.contentCache.get(key);
1849
1895
  if (cached && Date.now() - cached.at < CONTENT_CACHE_TTL_MS) {
1850
1896
  log6.debug("listContent \u2192 cache", query);
@@ -1865,7 +1911,7 @@ var AgentTransport = class {
1865
1911
  }
1866
1912
  log6.debug("listContent \u2192", query);
1867
1913
  const res = await this.getJson(url.toString(), "listContent");
1868
- const items = res.items ?? [];
1914
+ const items = (res.items ?? []).map((item) => overlayContent(item, this.locale));
1869
1915
  log6.debug("listContent \u2190", { count: items.length, total: res.pagination?.total });
1870
1916
  return { ...res, items };
1871
1917
  }
@@ -3125,7 +3171,7 @@ function mountRawSvg(host, source) {
3125
3171
  } catch {
3126
3172
  }
3127
3173
  }
3128
- function LauncherCallout({ callout, launcherPosition, closeLabel, onDismiss }) {
3174
+ function LauncherCallout({ callout, launcherPosition, strings, closeLabel, onDismiss }) {
3129
3175
  const [visible, setVisible] = useState(false);
3130
3176
  useEffect(() => {
3131
3177
  const id = setTimeout(() => setVisible(true), callout.delayMs);
@@ -3147,7 +3193,7 @@ function LauncherCallout({ callout, launcherPosition, closeLabel, onDismiss }) {
3147
3193
  "data-animated": callout.animated ? "true" : void 0,
3148
3194
  "data-testid": TID.callout,
3149
3195
  children: [
3150
- /* @__PURE__ */ jsx2("span", { children: callout.text }),
3196
+ /* @__PURE__ */ jsx2("span", { children: localizeText(strings, callout.text) }),
3151
3197
  /* @__PURE__ */ jsx2(
3152
3198
  "button",
3153
3199
  {
@@ -5707,9 +5753,16 @@ function createController(depsRef) {
5707
5753
  else if (form.frequency !== "always") depsRef.current.persistence.saveFormDone(form.id);
5708
5754
  depsRef.current.onComplete(form, trigger, values, skipped);
5709
5755
  };
5756
+ const refresh = () => {
5757
+ const active = activeForm.value;
5758
+ if (!active) return;
5759
+ const next = depsRef.current.forms.list.find((f) => f.id === active.form.id);
5760
+ if (next && next !== active.form) activeForm.value = { form: next, trigger: active.trigger };
5761
+ };
5710
5762
  return {
5711
5763
  activeForm,
5712
5764
  fire,
5765
+ refresh,
5713
5766
  complete: (values) => finish(values, false),
5714
5767
  skip: () => finish({}, true)
5715
5768
  };
@@ -6121,7 +6174,7 @@ function HomeRoot(props2) {
6121
6174
  const greeting = resolveGreeting(props2);
6122
6175
  const avatars = config.userAvatars ?? [];
6123
6176
  const status = config.status;
6124
- const contentTitle = config.contentBlockTitle ? moduleLabel(strings, config.contentBlockTitle) : strings.homeContentTitle;
6177
+ const contentTitle = config.contentBlockTitle ? localizeText(strings, config.contentBlockTitle) : strings.homeContentTitle;
6125
6178
  return /* @__PURE__ */ jsx29("div", { class: `${p25}-module ${p25}-home`, "data-testid": TID.homeView, children: /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-scroll`, children: [
6126
6179
  /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-hero`, children: [
6127
6180
  /* @__PURE__ */ jsxs24("div", { class: `${p25}-home-hero-top`, children: [
@@ -6276,7 +6329,7 @@ function HomeTabBar({ modules, activeTab, strings, unreadCount, onSelect }) {
6276
6329
  /* @__PURE__ */ jsx31(Icon, {}),
6277
6330
  badge ? /* @__PURE__ */ jsx31("span", { class: `${p27}-tab-badge`, "data-testid": TID.tabBadge, children: badge }) : null
6278
6331
  ] }),
6279
- /* @__PURE__ */ jsx31("span", { class: `${p27}-tab-label`, children: moduleLabel(strings, m.label) })
6332
+ /* @__PURE__ */ jsx31("span", { class: `${p27}-tab-label`, children: localizeText(strings, m.label) })
6280
6333
  ]
6281
6334
  },
6282
6335
  m.id
@@ -6947,7 +7000,7 @@ function App({ options, hostElement, bus }) {
6947
7000
  void (async () => {
6948
7001
  try {
6949
7002
  const res = await dataBootRef.current;
6950
- setRemoteForms(resolveForms((res ?? { forms: [] }).forms));
7003
+ setRemoteForms(resolveForms((res ?? { forms: [] }).forms, effectiveLocale));
6951
7004
  } catch (err) {
6952
7005
  log17.debug("bootstrap failed \u2014 treating as no forms", { err });
6953
7006
  } finally {
@@ -6965,6 +7018,23 @@ function App({ options, hostElement, bus }) {
6965
7018
  void runResume(handle);
6966
7019
  }
6967
7020
  }, [activated]);
7021
+ const formsLocaleRef = useRef9(null);
7022
+ useEffect17(() => {
7023
+ if (!activated) return;
7024
+ if (formsLocaleRef.current === null) {
7025
+ formsLocaleRef.current = effectiveLocale;
7026
+ return;
7027
+ }
7028
+ if (formsLocaleRef.current === effectiveLocale) return;
7029
+ formsLocaleRef.current = effectiveLocale;
7030
+ let cancelled = false;
7031
+ void transport.bootstrap().then((res) => {
7032
+ if (!cancelled) setRemoteForms(resolveForms((res ?? { forms: [] }).forms, effectiveLocale));
7033
+ }).catch((err) => log17.debug("forms re-localize failed \u2014 keeping current copy", { err }));
7034
+ return () => {
7035
+ cancelled = true;
7036
+ };
7037
+ }, [activated, effectiveLocale, transport]);
6968
7038
  const lastUserSig = useRef9(userSig);
6969
7039
  useEffect17(() => {
6970
7040
  if (!conversationReady || lastUserSig.current === userSig) return;
@@ -7121,6 +7191,9 @@ function App({ options, hostElement, bus }) {
7121
7191
  }
7122
7192
  });
7123
7193
  const activeForm = useComputed7(() => forms.activeForm.value);
7194
+ useEffect17(() => {
7195
+ forms.refresh();
7196
+ }, [effectiveForms, forms]);
7124
7197
  const pageArea = options.pageContext?.area ? String(options.pageContext.area) : void 0;
7125
7198
  const msgCount = useComputed7(() => messagesSig.value.length);
7126
7199
  useEffect17(() => {
@@ -7507,6 +7580,7 @@ function App({ options, hostElement, bus }) {
7507
7580
  {
7508
7581
  callout: calloutToRender,
7509
7582
  launcherPosition: effectiveOptions.position,
7583
+ strings: effectiveOptions.strings,
7510
7584
  closeLabel: effectiveOptions.strings.close,
7511
7585
  onDismiss: dismissCallout
7512
7586
  }
package/package.json CHANGED
@@ -80,5 +80,5 @@
80
80
  ],
81
81
  "type": "module",
82
82
  "types": "./index.d.ts",
83
- "version": "0.30.1"
83
+ "version": "0.31.0"
84
84
  }
package/schema.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, E as Endpoints, H as HandshakeResponse, L as Link, P as PAGE_AREA_SUGGESTIONS, f as PageContext, S as ServerConfig, b as SiteConfig, U as UserContext, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial, g as assetSchema, h as blocksConfigSchema, i as connectionConfigPartialSchema, j as connectionConfigSchema, k as cssColorSchema, l as cssLengthSchema, m as endpointsSchema, n as handshakeResponseSchema, o as linkSchema, p as localeSchema, q as pageContextSchema, s as serverConfigSchema, r as siteConfigSchema, u as userContextSchema, t as uuid7Schema, w as widgetConfigPartialSchema, v as widgetConfigSchema, x as widgetSettingsPartialSchema, y as widgetSettingsSchema } from './deployment-rva7dkso.js';
1
+ export { A as Asset, B as BlocksConfig, C as ConnectionConfig, a as ConnectionConfigPartial, E as Endpoints, H as HandshakeResponse, L as Link, P as PAGE_AREA_SUGGESTIONS, f as PageContext, S as ServerConfig, b as SiteConfig, U as UserContext, W as WidgetConfig, c as WidgetConfigPartial, d as WidgetSettings, e as WidgetSettingsPartial, g as assetSchema, h as blocksConfigSchema, i as connectionConfigPartialSchema, j as connectionConfigSchema, k as cssColorSchema, l as cssLengthSchema, m as endpointsSchema, n as handshakeResponseSchema, o as linkSchema, p as localeSchema, q as pageContextSchema, s as serverConfigSchema, r as siteConfigSchema, u as userContextSchema, t as uuid7Schema, w as widgetConfigPartialSchema, v as widgetConfigSchema, x as widgetSettingsPartialSchema, y as widgetSettingsSchema } from './deployment-DRGLrW2j.js';
2
2
  import { z } from 'zod';
3
3
 
4
4
  /**
@@ -56,9 +56,9 @@ declare const presentationSchema: z.ZodObject<{
56
56
  inset: z.ZodOptional<z.ZodString>;
57
57
  initialSize: z.ZodDefault<z.ZodEnum<{
58
58
  fullscreen: "fullscreen";
59
- normal: "normal";
60
59
  expanded: "expanded";
61
60
  auto: "auto";
61
+ normal: "normal";
62
62
  }>>;
63
63
  autoSizeBreakpoint: z.ZodDefault<z.ZodNumber>;
64
64
  }, z.core.$loose>>;
@@ -240,9 +240,9 @@ type LauncherOptions = z.infer<typeof launcherOptionsSchema>;
240
240
 
241
241
  declare const initialSizeSchema: z.ZodEnum<{
242
242
  fullscreen: "fullscreen";
243
- normal: "normal";
244
243
  expanded: "expanded";
245
244
  auto: "auto";
245
+ normal: "normal";
246
246
  }>;
247
247
  declare const resizeOptionsSchema: z.ZodObject<{
248
248
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -269,9 +269,9 @@ declare const sizeOptionsSchema: z.ZodObject<{
269
269
  inset: z.ZodOptional<z.ZodString>;
270
270
  initialSize: z.ZodDefault<z.ZodEnum<{
271
271
  fullscreen: "fullscreen";
272
- normal: "normal";
273
272
  expanded: "expanded";
274
273
  auto: "auto";
274
+ normal: "normal";
275
275
  }>>;
276
276
  autoSizeBreakpoint: z.ZodDefault<z.ZodNumber>;
277
277
  }, z.core.$loose>;
@@ -323,43 +323,43 @@ type FeatureFlags = z.infer<typeof featureFlagsSchema>;
323
323
  */
324
324
 
325
325
  declare const actionNameSchema: z.ZodEnum<{
326
+ close: "close";
326
327
  expand: "expand";
327
328
  fullscreen: "fullscreen";
328
329
  popOut: "popOut";
329
- close: "close";
330
- language: "language";
330
+ clear: "clear";
331
331
  theme: "theme";
332
+ language: "language";
332
333
  textSize: "textSize";
333
334
  history: "history";
334
- clear: "clear";
335
335
  sound: "sound";
336
336
  }>;
337
337
  type ActionName = z.infer<typeof actionNameSchema>;
338
338
  declare const headerActionsSchema: z.ZodArray<z.ZodEnum<{
339
+ close: "close";
339
340
  expand: "expand";
340
341
  fullscreen: "fullscreen";
341
342
  popOut: "popOut";
342
- close: "close";
343
- language: "language";
343
+ clear: "clear";
344
344
  theme: "theme";
345
+ language: "language";
345
346
  textSize: "textSize";
346
347
  history: "history";
347
- clear: "clear";
348
348
  sound: "sound";
349
349
  }>>;
350
350
  type HeaderActions = z.infer<typeof headerActionsSchema>;
351
351
  /** Section wrapper — `actions` list wrapped under `header` in the dashboard form. */
352
352
  declare const headerSchema: z.ZodObject<{
353
353
  actions: z.ZodOptional<z.ZodArray<z.ZodEnum<{
354
+ close: "close";
354
355
  expand: "expand";
355
356
  fullscreen: "fullscreen";
356
357
  popOut: "popOut";
357
- close: "close";
358
- language: "language";
358
+ clear: "clear";
359
359
  theme: "theme";
360
+ language: "language";
360
361
  textSize: "textSize";
361
362
  history: "history";
362
- clear: "clear";
363
363
  sound: "sound";
364
364
  }>>>;
365
365
  }, z.core.$loose>;
@@ -375,33 +375,33 @@ type HeaderOptions = z.infer<typeof headerSchema>;
375
375
  */
376
376
 
377
377
  declare const feedbackEventSchema: z.ZodEnum<{
378
+ voiceStart: "voiceStart";
379
+ voiceStop: "voiceStop";
378
380
  error: "error";
379
381
  messageReceived: "messageReceived";
380
382
  messageSent: "messageSent";
381
- voiceStart: "voiceStart";
382
- voiceStop: "voiceStop";
383
383
  }>;
384
384
  type FeedbackEvent = z.infer<typeof feedbackEventSchema>;
385
385
  declare const soundOptionsSchema: z.ZodObject<{
386
386
  enabled: z.ZodDefault<z.ZodBoolean>;
387
387
  volume: z.ZodDefault<z.ZodNumber>;
388
388
  events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
389
+ voiceStart: "voiceStart";
390
+ voiceStop: "voiceStop";
389
391
  error: "error";
390
392
  messageReceived: "messageReceived";
391
393
  messageSent: "messageSent";
392
- voiceStart: "voiceStart";
393
- voiceStop: "voiceStop";
394
394
  }> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
395
395
  }, z.core.$loose>;
396
396
  type SoundOptions = z.infer<typeof soundOptionsSchema>;
397
397
  declare const hapticsOptionsSchema: z.ZodObject<{
398
398
  enabled: z.ZodDefault<z.ZodBoolean>;
399
399
  events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
400
+ voiceStart: "voiceStart";
401
+ voiceStop: "voiceStop";
400
402
  error: "error";
401
403
  messageReceived: "messageReceived";
402
404
  messageSent: "messageSent";
403
- voiceStart: "voiceStart";
404
- voiceStop: "voiceStop";
405
405
  }> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodNumber>]>>>;
406
406
  }, z.core.$loose>;
407
407
  type HapticsOptions = z.infer<typeof hapticsOptionsSchema>;
@@ -410,21 +410,21 @@ declare const feedbackSchema: z.ZodObject<{
410
410
  enabled: z.ZodDefault<z.ZodBoolean>;
411
411
  volume: z.ZodDefault<z.ZodNumber>;
412
412
  events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
413
+ voiceStart: "voiceStart";
414
+ voiceStop: "voiceStop";
413
415
  error: "error";
414
416
  messageReceived: "messageReceived";
415
417
  messageSent: "messageSent";
416
- voiceStart: "voiceStart";
417
- voiceStop: "voiceStop";
418
418
  }> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>;
419
419
  }, z.core.$loose>>;
420
420
  haptics: z.ZodOptional<z.ZodObject<{
421
421
  enabled: z.ZodDefault<z.ZodBoolean>;
422
422
  events: z.ZodOptional<z.ZodRecord<z.ZodEnum<{
423
+ voiceStart: "voiceStart";
424
+ voiceStop: "voiceStop";
423
425
  error: "error";
424
426
  messageReceived: "messageReceived";
425
427
  messageSent: "messageSent";
426
- voiceStart: "voiceStart";
427
- voiceStop: "voiceStop";
428
428
  }> & z.core.$partial, z.ZodUnion<readonly [z.ZodBoolean, z.ZodNumber, z.ZodArray<z.ZodNumber>]>>>;
429
429
  }, z.core.$loose>>;
430
430
  }, z.core.$loose>;
@@ -624,6 +624,48 @@ declare const formConditionSchema: z.ZodObject<{
624
624
  maxMessages: z.ZodOptional<z.ZodNumber>;
625
625
  }, z.core.$loose>;
626
626
  type FormCondition = z.infer<typeof formConditionSchema>;
627
+ /**
628
+ * Per-locale overrides of a form's HUMAN-FACING strings only. Structure (field
629
+ * `name` / `type` / `validation`, option `value`) is shared across locales and
630
+ * stays canonical — a translation matches the canonical form by the stable
631
+ * `name` (field) / `value` (option) keys; absent strings fall back to the
632
+ * top-level (defaultLocale) copy. The data module trims `translations` to the
633
+ * requested `?locale=` (≤1 entry); the widget overlays it (`overlayFormDef`).
634
+ */
635
+ declare const fieldOptionTranslationSchema: z.ZodObject<{
636
+ value: z.ZodString;
637
+ label: z.ZodOptional<z.ZodString>;
638
+ description: z.ZodOptional<z.ZodString>;
639
+ }, z.core.$loose>;
640
+ declare const formFieldTranslationSchema: z.ZodObject<{
641
+ name: z.ZodString;
642
+ label: z.ZodOptional<z.ZodString>;
643
+ placeholder: z.ZodOptional<z.ZodString>;
644
+ validationHint: z.ZodOptional<z.ZodString>;
645
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
646
+ value: z.ZodString;
647
+ label: z.ZodOptional<z.ZodString>;
648
+ description: z.ZodOptional<z.ZodString>;
649
+ }, z.core.$loose>>>;
650
+ }, z.core.$loose>;
651
+ declare const formTranslationSchema: z.ZodObject<{
652
+ locale: z.ZodString;
653
+ title: z.ZodOptional<z.ZodString>;
654
+ description: z.ZodOptional<z.ZodString>;
655
+ submitLabel: z.ZodOptional<z.ZodString>;
656
+ fields: z.ZodOptional<z.ZodArray<z.ZodObject<{
657
+ name: z.ZodString;
658
+ label: z.ZodOptional<z.ZodString>;
659
+ placeholder: z.ZodOptional<z.ZodString>;
660
+ validationHint: z.ZodOptional<z.ZodString>;
661
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
662
+ value: z.ZodString;
663
+ label: z.ZodOptional<z.ZodString>;
664
+ description: z.ZodOptional<z.ZodString>;
665
+ }, z.core.$loose>>>;
666
+ }, z.core.$loose>>>;
667
+ }, z.core.$loose>;
668
+ type FormTranslation = z.infer<typeof formTranslationSchema>;
627
669
  declare const formDefSchema: z.ZodObject<{
628
670
  id: z.ZodString;
629
671
  on: z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>;
@@ -682,6 +724,24 @@ declare const formDefSchema: z.ZodObject<{
682
724
  mirrorToContext: z.ZodDefault<z.ZodBoolean>;
683
725
  reopenable: z.ZodDefault<z.ZodBoolean>;
684
726
  reviewable: z.ZodDefault<z.ZodBoolean>;
727
+ defaultLocale: z.ZodOptional<z.ZodString>;
728
+ translations: z.ZodOptional<z.ZodArray<z.ZodObject<{
729
+ locale: z.ZodString;
730
+ title: z.ZodOptional<z.ZodString>;
731
+ description: z.ZodOptional<z.ZodString>;
732
+ submitLabel: z.ZodOptional<z.ZodString>;
733
+ fields: z.ZodOptional<z.ZodArray<z.ZodObject<{
734
+ name: z.ZodString;
735
+ label: z.ZodOptional<z.ZodString>;
736
+ placeholder: z.ZodOptional<z.ZodString>;
737
+ validationHint: z.ZodOptional<z.ZodString>;
738
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
739
+ value: z.ZodString;
740
+ label: z.ZodOptional<z.ZodString>;
741
+ description: z.ZodOptional<z.ZodString>;
742
+ }, z.core.$loose>>>;
743
+ }, z.core.$loose>>>;
744
+ }, z.core.$loose>>>;
685
745
  }, z.core.$loose>;
686
746
  type FormDef = z.infer<typeof formDefSchema>;
687
747
  declare const formsSchema: z.ZodArray<z.ZodObject<{
@@ -742,6 +802,24 @@ declare const formsSchema: z.ZodArray<z.ZodObject<{
742
802
  mirrorToContext: z.ZodDefault<z.ZodBoolean>;
743
803
  reopenable: z.ZodDefault<z.ZodBoolean>;
744
804
  reviewable: z.ZodDefault<z.ZodBoolean>;
805
+ defaultLocale: z.ZodOptional<z.ZodString>;
806
+ translations: z.ZodOptional<z.ZodArray<z.ZodObject<{
807
+ locale: z.ZodString;
808
+ title: z.ZodOptional<z.ZodString>;
809
+ description: z.ZodOptional<z.ZodString>;
810
+ submitLabel: z.ZodOptional<z.ZodString>;
811
+ fields: z.ZodOptional<z.ZodArray<z.ZodObject<{
812
+ name: z.ZodString;
813
+ label: z.ZodOptional<z.ZodString>;
814
+ placeholder: z.ZodOptional<z.ZodString>;
815
+ validationHint: z.ZodOptional<z.ZodString>;
816
+ options: z.ZodOptional<z.ZodArray<z.ZodObject<{
817
+ value: z.ZodString;
818
+ label: z.ZodOptional<z.ZodString>;
819
+ description: z.ZodOptional<z.ZodString>;
820
+ }, z.core.$loose>>>;
821
+ }, z.core.$loose>>>;
822
+ }, z.core.$loose>>>;
745
823
  }, z.core.$loose>>;
746
824
  type Forms = z.infer<typeof formsSchema>;
747
825
 
@@ -781,18 +859,18 @@ type I18nOptions = z.infer<typeof i18nSchema>;
781
859
  */
782
860
 
783
861
  declare const moduleLayoutSchema: z.ZodEnum<{
862
+ home: "home";
784
863
  chat: "chat";
785
864
  help: "help";
786
- home: "home";
787
865
  news: "news";
788
866
  }>;
789
867
  type ModuleLayout = z.infer<typeof moduleLayoutSchema>;
790
868
  declare const moduleSchema: z.ZodObject<{
791
869
  label: z.ZodString;
792
870
  layout: z.ZodEnum<{
871
+ home: "home";
793
872
  chat: "chat";
794
873
  help: "help";
795
- home: "home";
796
874
  news: "news";
797
875
  }>;
798
876
  contentTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -818,9 +896,9 @@ type ModuleOptions = z.infer<typeof moduleSchema>;
818
896
  declare const modulesSchema: z.ZodArray<z.ZodObject<{
819
897
  label: z.ZodString;
820
898
  layout: z.ZodEnum<{
899
+ home: "home";
821
900
  chat: "chat";
822
901
  help: "help";
823
- home: "home";
824
902
  news: "news";
825
903
  }>;
826
904
  contentTags: z.ZodOptional<z.ZodArray<z.ZodString>>;
@@ -902,4 +980,4 @@ declare const ALL_MODES: readonly Mode[];
902
980
  */
903
981
  declare function emitJsonSchema(): unknown;
904
982
 
905
- export { ALL_MODES, type ActionName, type AttachmentLimits, type Behavior, type CalloutPosition, type CalloutShape, type ComposerOptions, type FeatureFlags, type FeedbackEvent, type FeedbackOptions, type FieldOption, type FieldType, type FieldValidation, type FooterOptions, type FormCondition, type FormDef, type FormField, type Forms, type HapticsOptions, type HeaderActions, type HeaderOptions, type I18nOptions, type LauncherCallout, type LauncherOptions, type LauncherSize, type LauncherVariant, type Mode, type ModuleLayout, type ModuleOptions, type ModulesOptions, type Position, type PoweredBy, type Presentation, type ResizeOptions, type ResponseMode, type SendButtonOptions, type SizeOptions, type SoundOptions, type StringsOverride, type ThemeOverrides, type ThemePreference, type TrackingSettings, type VoiceMode, actionNameSchema, attachmentLimitsSchema, behaviorSchema, calloutPositionSchema, calloutShapeSchema, composerOptionsSchema, emitJsonSchema, featureFlagsSchema, feedbackEventSchema, feedbackSchema, fieldOptionSchema, fieldTypeSchema, fieldValidationSchema, footerSchema, formConditionSchema, formDefSchema, formFieldSchema, formTriggerSchema, formsSchema, hapticsOptionsSchema, headerActionsSchema, headerSchema, i18nSchema, initialSizeSchema, launcherCalloutSchema, launcherOptionsSchema, launcherSizeSchema, launcherVariantSchema, modeSchema, moduleLayoutSchema, moduleSchema, modulesSchema, positionSchema, poweredBySchema, presentationSchema, resizeOptionsSchema, responseModeSchema, sendButtonIconSchema, sendButtonOptionsSchema, sendButtonShapeSchema, sendButtonVariantSchema, sizeOptionsSchema, soundOptionsSchema, stringsOverrideSchema, themeFieldSchema, themeOverridesSchema, themePreferenceSchema, toolRefSchema, trackingSchema, voiceModeSchema, widgetSettingsSchemaForMode };
983
+ export { ALL_MODES, type ActionName, type AttachmentLimits, type Behavior, type CalloutPosition, type CalloutShape, type ComposerOptions, type FeatureFlags, type FeedbackEvent, type FeedbackOptions, type FieldOption, type FieldType, type FieldValidation, type FooterOptions, type FormCondition, type FormDef, type FormField, type FormTranslation, type Forms, type HapticsOptions, type HeaderActions, type HeaderOptions, type I18nOptions, type LauncherCallout, type LauncherOptions, type LauncherSize, type LauncherVariant, type Mode, type ModuleLayout, type ModuleOptions, type ModulesOptions, type Position, type PoweredBy, type Presentation, type ResizeOptions, type ResponseMode, type SendButtonOptions, type SizeOptions, type SoundOptions, type StringsOverride, type ThemeOverrides, type ThemePreference, type TrackingSettings, type VoiceMode, actionNameSchema, attachmentLimitsSchema, behaviorSchema, calloutPositionSchema, calloutShapeSchema, composerOptionsSchema, emitJsonSchema, featureFlagsSchema, feedbackEventSchema, feedbackSchema, fieldOptionSchema, fieldOptionTranslationSchema, fieldTypeSchema, fieldValidationSchema, footerSchema, formConditionSchema, formDefSchema, formFieldSchema, formFieldTranslationSchema, formTranslationSchema, formTriggerSchema, formsSchema, hapticsOptionsSchema, headerActionsSchema, headerSchema, i18nSchema, initialSizeSchema, launcherCalloutSchema, launcherOptionsSchema, launcherSizeSchema, launcherVariantSchema, modeSchema, moduleLayoutSchema, moduleSchema, modulesSchema, positionSchema, poweredBySchema, presentationSchema, resizeOptionsSchema, responseModeSchema, sendButtonIconSchema, sendButtonOptionsSchema, sendButtonShapeSchema, sendButtonVariantSchema, sizeOptionsSchema, soundOptionsSchema, stringsOverrideSchema, themeFieldSchema, themeOverridesSchema, themePreferenceSchema, toolRefSchema, trackingSchema, voiceModeSchema, widgetSettingsSchemaForMode };