@gamaro.io/widget 0.6.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,9 +5,10 @@
5
5
  [![types](https://img.shields.io/npm/types/@gamaro.io/widget.svg)](#typescript)
6
6
  [![license](https://img.shields.io/badge/license-Commercial%20Source--available-blue.svg)](./LICENSE)
7
7
 
8
- Versiq Widget SDK — embed a conversational conversion agent that answers
9
- visitors using **your** site's data (catalogue, inventory, CRM, knowledge base),
10
- not the public-web average a generic LLM assistant returns.
8
+ Gamaro Widget SDK — embed a conversational conversion agent that grounds every
9
+ response in **your** site's own data (catalogue, inventory, CRM, knowledge base)
10
+ instead of the undifferentiated public training data a generic LLM assistant
11
+ would otherwise draw on.
11
12
 
12
13
  ## Table of Contents
13
14
 
@@ -71,7 +72,7 @@ the cost of having to bump it manually on every release.
71
72
  ### Programmatic API
72
73
 
73
74
  The minimal integration is one line — every visual and behavioural aspect
74
- (theme, position, language, open-state, branding) is configured in the **Versiq
75
+ (theme, position, language, open-state, branding) is configured in the **Gamaro
75
76
  admin portal** for your Agent and resolved server-side from the API key.
76
77
 
77
78
  ```typescript
@@ -93,16 +94,16 @@ widget.destroy();
93
94
  Two reasons most platforms fail to convert mobile visitors, and two reasons this
94
95
  widget does:
95
96
 
96
- 1. **It speaks with your data, not the public-web average.** The agent answers
97
- from your catalogue, your stock, your CRM, your knowledge base — what your
98
- competitors and generic AI assistants don't have.
97
+ 1. **It grounds every answer in your own data, not generic AI training data.**
98
+ The agent answers from your catalogue, your stock, your CRM, your knowledge
99
+ base — what your competitors and generic AI assistants don't have.
99
100
  2. **It is driven by your thumb, not your keyboard.** The LLM dynamically picks
100
101
  the right component at every turn — quick replies, sliders, product cards —
101
102
  instead of forcing a form. Visitors qualify their need in a few taps on
102
103
  mobile, where 3+ field forms lose 50%+ of users (HubSpot).
103
104
 
104
105
  The widget rendering layer (`QuickReplies`, `PropertyCard`, `ActionButtons`) is
105
- the runtime that materialises this. Schemas live in the Versiq backend
106
+ the runtime that materialises this. Schemas live in the Gamaro backend
106
107
  repository and are out of scope for the SDK consumer.
107
108
 
108
109
  ## Configuration
@@ -125,22 +126,22 @@ context (DOM, identity, environment).
125
126
  | `userId` | `string` | - | Host-side stable user identifier — must be paired with `userHash`. |
126
127
  | `userHash` | `string` | - | HMAC-SHA256 of `email` (or `userId`), signed with the Agent identity secret. See _Identity_. |
127
128
 
128
- ### 2. Server-resolved (configured in the Versiq admin portal)
129
+ ### 2. Server-resolved (configured in the Gamaro admin portal)
129
130
 
130
131
  These are **not** passed by the integration — they are stored in the Agent's
131
132
  `widget_config` JSONB row and fetched at bootstrap from the API key. To change
132
133
  any of them, edit the Agent in the portal.
133
134
 
134
- | Field | Configured in admin | Notes |
135
- | ----------------- | -------------------------- | ----------------------------------------------------------------------------------------------------------- |
136
- | `theme` | Apparence → palette | Full palette (`primaryColor`, `backgroundColor`, `textColor`, `borderRadius`, `fontFamily`, `colorScheme`). |
137
- | `position` | Apparence → position | `"bottom-right"`, `"bottom-left"`, or `"inline"`. |
138
- | `language` | Apparence → langue | ISO 639-1 (e.g. `fr`, `en`). Falls back to browser language when unset. |
139
- | `showProfile` | Apparence → panneau profil | Toggles the profile panel in the widget header. |
140
- | `open` | Apparence → état initial | Default open state on page load. Host can still call `widget.open()` programmatically. |
141
- | `brand.title` | Branding → titre | Custom header title (falls back to a vertical-specific default). |
142
- | `brand.avatarUrl` | Branding → avatar | Custom avatar URL (must originate from the portal upload — arbitrary URLs are rejected). |
143
- | `vertical` | Agent creation | `real-estate`, `b2b-qualification`, … Bound to the API key. |
135
+ | Field | Configured in admin | Notes |
136
+ | ----------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
137
+ | `theme` | Apparence → palette | Full palette (`primaryColor`, `backgroundColor`, `textColor`, `borderRadius`, `fontFamily`, `colorScheme`). |
138
+ | `position` | Apparence → position | `"bottom-right"`, `"bottom-left"`, or `"inline"`. |
139
+ | `language` | Apparence → langue | ISO 639-1 (e.g. `fr`, `en`). Falls back to browser language when unset. |
140
+ | `showProfile` | Apparence → panneau profil | Forces the profile panel visible from the start of the conversation. The panel already shows on its own once the visitor's profile has data, regardless of this flag. |
141
+ | `open` | Apparence → état initial | Default open state on page load. Host can still call `widget.open()` programmatically. |
142
+ | `brand.title` | Branding → titre | Custom header title (falls back to a vertical-specific default). |
143
+ | `brand.avatarUrl` | Branding → avatar | Custom avatar URL (must originate from the portal upload — arbitrary URLs are rejected). |
144
+ | `vertical` | Agent creation | `real-estate`, `b2b-qualification`, … Bound to the API key. |
144
145
 
145
146
  ### 3. Client overrides (advanced — rarely needed in production)
146
147
 
@@ -199,7 +200,7 @@ const widget = createWidget({
199
200
  });
200
201
  ```
201
202
 
202
- ### VersiqWidget Methods
203
+ ### GamaroWidget Methods
203
204
 
204
205
  | Method | Description |
205
206
  | ----------------------------------------------------- | -------------------------------------------------------- |
@@ -215,15 +216,15 @@ const widget = createWidget({
215
216
 
216
217
  ### Window API (Script Tag)
217
218
 
218
- When using the script tag, the API is available on `window.Versiq`:
219
+ When using the script tag, the API is available on `window.Gamaro`:
219
220
 
220
221
  ```javascript
221
- window.Versiq.open();
222
- window.Versiq.close();
223
- window.Versiq.setTheme({ primaryColor: "#10B981" });
222
+ window.Gamaro.open();
223
+ window.Gamaro.close();
224
+ window.Gamaro.setTheme({ primaryColor: "#10B981" });
224
225
 
225
226
  // Wire your own dark-mode toggle to the widget:
226
- window.Versiq.setColorScheme("dark"); // or "light", or "auto"
227
+ window.Gamaro.setColorScheme("dark"); // or "light", or "auto"
227
228
  ```
228
229
 
229
230
  ## Events
@@ -281,7 +282,7 @@ The package includes full TypeScript support with exported types:
281
282
  import type {
282
283
  WidgetConfig,
283
284
  ThemeConfig,
284
- VersiqWidget,
285
+ GamaroWidget,
285
286
  WidgetEventType,
286
287
  WidgetProfile,
287
288
  WidgetMessage,
@@ -307,7 +308,7 @@ vertical = creating a new Agent + new key.
307
308
  ### Real-Estate flow
308
309
 
309
310
  When the resolved vertical is `real-estate`, the widget runs in qualification
310
- mode: Versiq qualifies the buyer through conversation and emits the profile — no
311
+ mode: Gamaro qualifies the buyer through conversation and emits the profile — no
311
312
  property data is needed from the integrator (data-dependent tools like
312
313
  `searchProperties`, `getCityStats`, `estimateProperty` are automatically
313
314
  excluded).
@@ -381,10 +382,10 @@ createWidget({
381
382
  "use client";
382
383
 
383
384
  import { useEffect, useRef } from "react";
384
- import { createWidget, type VersiqWidget } from "@gamaro.io/widget";
385
+ import { createWidget, type GamaroWidget } from "@gamaro.io/widget";
385
386
 
386
387
  export function ContactWidget() {
387
- const widgetRef = useRef<VersiqWidget | null>(null);
388
+ const widgetRef = useRef<GamaroWidget | null>(null);
388
389
  const containerRef = useRef<HTMLDivElement>(null);
389
390
 
390
391
  useEffect(() => {
@@ -448,7 +449,7 @@ attestation, the host `Permissions-Policy`, and your `Content-Security-Policy`.
448
449
  ### Identity verification (HMAC)
449
450
 
450
451
  By default a visitor is anonymous. If your page already knows who the visitor is
451
- (a logged-in user), you can attest that identity to Versiq so leads are attached
452
+ (a logged-in user), you can attest that identity to Gamaro so leads are attached
452
453
  to the right account — without trusting a client-supplied email blindly.
453
454
 
454
455
  Pass `email` (or `userId`) **together with** a `userHash`: an HMAC-SHA256 of the
@@ -507,7 +508,7 @@ conversation still works; the visitor just types the city manually.
507
508
  Permissions-Policy controls **what the iframe is allowed to do**;
508
509
  Content-Security-Policy controls **where scripts / iframes / styles can come
509
510
  from**. Both are independent and both are needed in production. The CSP
510
- directives required for the Versiq widget are documented in the Versiq backend
511
+ directives required for the Gamaro widget are documented in the Gamaro backend
511
512
  repo at `docs/B2B_INTEGRATION.md` § "Content-Security-Policy pour intégrateurs".
512
513
 
513
514
  ## E2E Test Selectors (data-testid)
@@ -516,21 +517,22 @@ For a smoke test that the widget mounted and works on your page, a small core of
516
517
  `data-testid` selectors is exposed. These are guaranteed not to change without a
517
518
  major version bump.
518
519
 
519
- | Selector | Element | Additional attributes |
520
- | ----------------------- | ----------------------------------------------------------------------------- | ---------------------------------- |
521
- | `widget-root` | Chat container (open) | — |
522
- | `widget-input` | Message input field | — |
523
- | `widget-send` | Send button | — |
524
- | `widget-message` | Message bubble | `data-role="user" \| "assistant"` |
525
- | `widget-loading-status` | Running-tool status label beside the typing dots (e.g. "Recherche de biens…") | — (absent until a tool runs) |
526
- | `widget-suggestion` | Quick reply chip | `data-index="<N>"` (position) |
527
- | `widget-cta-button` | Call-to-action button | `data-objective="<objectiveType>"` |
528
- | `widget-avatar` | Header avatar | — |
520
+ | Selector | Element | Additional attributes |
521
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
522
+ | `widget-root` | Chat container (open) | — |
523
+ | `widget-input` | Message input field | — |
524
+ | `widget-send` | Send button | — |
525
+ | `widget-message` | Message bubble | `data-role="user" \| "assistant"` |
526
+ | `widget-loading-status` | Running-tool status label beside the typing dots (e.g. "Recherche de biens…") | — (absent until a tool runs) |
527
+ | `widget-suggestion` | Quick reply chip | `data-index="<N>"` (position) |
528
+ | `widget-cta-summary-continue` | Pre-CTA recap card "Continue" button (#3028) — precedes `widget-cta-button` when the visitor's profile has display config for the active vertical | — (absent otherwise, `widget-cta-button` mounts directly) |
529
+ | `widget-cta-button` | Call-to-action button | `data-objective="<objectiveType>"` |
530
+ | `widget-avatar` | Header avatar | — |
529
531
 
530
532
  > The widget also exposes a large set of vertical-specific selectors
531
533
  > (real-estate map, areas-overview, exploration mode, criteria popup, range
532
- > slider, contact form). They are internal to the Versiq UI and out of scope for
533
- > SDK consumers — the full contract lives in the Versiq backend repository under
534
+ > slider, contact form). They are internal to the Gamaro UI and out of scope for
535
+ > SDK consumers — the full contract lives in the Gamaro backend repository under
534
536
  > `apps/app/src/app/widget/embed/components/`.
535
537
 
536
538
  ### Example (Playwright)
@@ -612,7 +614,7 @@ Lighthouse manually:
612
614
  analytics pipeline (Google Analytics 4, Sentry, etc.) to track field LCP per
613
615
  real visitor — Lighthouse alone only measures synthetic loads.
614
616
 
615
- The Versiq widget itself does not emit web-vitals events (out of scope — the SDK
617
+ The Gamaro widget itself does not emit web-vitals events (out of scope — the SDK
616
618
  should not impose an analytics dependency on the host). Integrators own the
617
619
  measurement pipeline for their own page.
618
620
 
@@ -656,7 +658,7 @@ Commercial Source-available — see [LICENSE](./LICENSE).
656
658
  This is **not** an open-source release: the source is published so integrators
657
659
  can audit what runs in their visitors' browsers, but fork / redistribution /
658
660
  competing-SDK use are prohibited without a written agreement. Production use
659
- against the Versiq backend is governed by the Versiq Commercial Terms of
661
+ against the Gamaro backend is governed by the Gamaro Commercial Terms of
660
662
  Service.
661
663
 
662
664
  For commercial licensing inquiries: admin@dolard.eu
@@ -3,10 +3,10 @@
3
3
  *
4
4
  * Promotes a skeleton placeholder into an operational iframe with a per-attempt
5
5
  * timeout and a configurable backoff between retries. Single responsibility —
6
- * the host (`VersiqWidget`) keeps the application FSM, this module owns the
6
+ * the host (`GamaroWidget`) keeps the application FSM, this module owns the
7
7
  * mechanics of getting the iframe up.
8
8
  *
9
- * Success criterion: iframe `load` event AND a `versiq:ready` postMessage from
9
+ * Success criterion: iframe `load` event AND a `gamaro:ready` postMessage from
10
10
  * the embed React app. The AND is mandatory — a 5xx Next page rendered inside
11
11
  * the iframe still fires `load`; relying on that alone would mask deployment
12
12
  * failures as silent successes.
@@ -48,7 +48,7 @@ export interface IframeLoaderOptions {
48
48
  buildIframe: () => HTMLIFrameElement;
49
49
  /** DOM node the iframe will be appended to. */
50
50
  container: HTMLElement;
51
- /** Allowed origins for the `versiq:ready` ack (passed to `isValidOrigin`). */
51
+ /** Allowed origins for the `gamaro:ready` ack (passed to `isValidOrigin`). */
52
52
  allowedOrigins: string[];
53
53
  /** Per-attempt timeout in ms. Defaults to `IFRAME_LOAD_TIMEOUT_MS`. */
54
54
  timeoutMs?: number;
@@ -69,10 +69,10 @@ export declare class IframeLoadError extends Error {
69
69
  * success; throws `IframeLoadError` (reason + final attempt count) on final
70
70
  * failure, or `DOMException("AbortError")` when `opts.signal` aborts.
71
71
  *
72
- * The `versiq:ready` message is observed via a LOCAL listener that is detached
72
+ * The `gamaro:ready` message is observed via a LOCAL listener that is detached
73
73
  * the moment the handshake completes — the caller is expected to attach its
74
74
  * own applicative listener AFTER this resolves, and to manually set
75
75
  * `isReady = true` + send any post-ready commands, since the embed React app
76
- * only emits `versiq:ready` once on mount.
76
+ * only emits `gamaro:ready` once on mount.
77
77
  */
78
78
  export declare function loadIframeWithRetry(opts: IframeLoaderOptions): Promise<HTMLIFrameElement>;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Versiq Widget SDK
2
+ * Gamaro Widget SDK
3
3
  *
4
4
  * Entry point for the widget SDK. Supports both auto-initialization from
5
5
  * script tags and programmatic usage.
@@ -34,14 +34,14 @@
34
34
  * admin sandbox's live-preview use case (client-wins merge). Partner
35
35
  * integrators should configure those fields from the admin portal.
36
36
  */
37
- import { VersiqWidget, createWidget } from "./loader";
37
+ import { GamaroWidget, createWidget } from "./loader";
38
38
  import type { WidgetConfig } from "./types";
39
- export { createWidget, VersiqWidget };
39
+ export { createWidget, GamaroWidget };
40
40
  export { parseScriptAttributes as __parseScriptAttributes };
41
41
  export { getCurrentScript as __getCurrentScript };
42
42
  export { autoInit as __autoInit };
43
43
  export { themeConfigSchema, widgetPositionSchema, widgetConfigSchema, b2bProfileSchema, widgetMessageSchema, applicationConfigResponseSchema, } from "./types";
44
- export type { WidgetConfig, WidgetPosition, ColorScheme, ThemeConfig, B2BProfile, WidgetProfile, WidgetMessage, WidgetEvent, WidgetEventType, WidgetEventHandler, VersiqAPI, ApplicationConfigResponse, } from "./types";
44
+ export type { WidgetConfig, WidgetPosition, ColorScheme, ThemeConfig, B2BProfile, WidgetProfile, WidgetMessage, WidgetEvent, WidgetEventType, WidgetEventHandler, GamaroAPI, ApplicationConfigResponse, } from "./types";
45
45
  export { fetchApplicationConfig, ConfigFetchError } from "./config";
46
46
  /**
47
47
  * Parse script tag data attributes to extract widget config (#726).
package/dist/loader.d.ts CHANGED
@@ -6,9 +6,9 @@
6
6
  * - postMessage communication
7
7
  * - Public API exposure
8
8
  */
9
- import type { WidgetConfig, WidgetEventType, WidgetEventHandler, VersiqAPI, ColorScheme, ThemeConfig } from "./types";
9
+ import type { WidgetConfig, WidgetEventType, WidgetEventHandler, GamaroAPI, ColorScheme, ThemeConfig } from "./types";
10
10
  export declare function __resetInstanceCounter(): void;
11
- export declare class VersiqWidget implements VersiqAPI {
11
+ export declare class GamaroWidget implements GamaroAPI {
12
12
  readonly version = "0.1.0";
13
13
  /**
14
14
  * Original config as passed by the caller — preserved separately from
@@ -100,7 +100,7 @@ export declare class VersiqWidget implements VersiqAPI {
100
100
  private init;
101
101
  /**
102
102
  * Strip any path from `baseUrl` so the resulting string matches the
103
- * `event.origin` field of a `versiq:ready` postMessage (which is always
103
+ * `event.origin` field of a `gamaro:ready` postMessage (which is always
104
104
  * scheme + host + port, no path). Falls back to the raw value if parsing
105
105
  * fails so a malformed config does not silently break the loader gate.
106
106
  */
@@ -143,4 +143,4 @@ export declare class VersiqWidget implements VersiqAPI {
143
143
  /**
144
144
  * Create a new widget instance.
145
145
  */
146
- export declare function createWidget(config: WidgetConfig): VersiqWidget;
146
+ export declare function createWidget(config: WidgetConfig): GamaroWidget;
@@ -15,9 +15,9 @@ import type { WidgetCommand, WidgetEvent } from "./types";
15
15
  */
16
16
  export declare function isValidOrigin(origin: string, allowedOrigins: string[]): boolean;
17
17
  /**
18
- * Check if an event contains a valid Versiq message.
18
+ * Check if an event contains a valid Gamaro message.
19
19
  */
20
- export declare function isVersiqMessage(event: MessageEvent): event is MessageEvent<WidgetCommand | WidgetEvent>;
20
+ export declare function isGamaroMessage(event: MessageEvent): event is MessageEvent<WidgetCommand | WidgetEvent>;
21
21
  /**
22
22
  * Send a command to the widget iframe.
23
23
  */
package/dist/types.d.ts CHANGED
@@ -6,7 +6,7 @@
6
6
  * re-exports them so existing consumers (`apps/marketing`,
7
7
  * `apps/app/src/components/portal/sandbox`) keep working unchanged. The only
8
8
  * types still defined locally are widget-specific SDK surfaces (B2B profile
9
- * schemas, `VersiqAPI`, `window` augmentation).
9
+ * schemas, `GamaroAPI`, `window` augmentation).
10
10
  */
11
11
  import { z } from "zod";
12
12
  import type { ColorScheme, ThemeConfig, WidgetEventHandler, WidgetEventType } from "@gamaro.io/core-types";
@@ -145,9 +145,9 @@ export declare const b2bProfileSchema: z.ZodObject<{
145
145
  }, z.core.$strip>;
146
146
  export type B2BProfile = z.infer<typeof b2bProfileSchema>;
147
147
  /**
148
- * Public API exposed on window.Versiq.
148
+ * Public API exposed on window.Gamaro.
149
149
  */
150
- export interface VersiqAPI {
150
+ export interface GamaroAPI {
151
151
  /** Application ID (available after config resolution) */
152
152
  readonly applicationId: string;
153
153
  /** Open the widget */
@@ -161,7 +161,7 @@ export interface VersiqAPI {
161
161
  /**
162
162
  * Update only the color scheme. Sugar over `setTheme({ colorScheme })` so
163
163
  * integrators can wire their own dark-mode toggle without rebuilding the
164
- * full theme object: `window.Versiq.setColorScheme("dark")`.
164
+ * full theme object: `window.Gamaro.setColorScheme("dark")`.
165
165
  */
166
166
  setColorScheme(scheme: ColorScheme): void;
167
167
  /** Identify the current user with host-attested HMAC verification */
@@ -179,7 +179,7 @@ export interface VersiqAPI {
179
179
  }
180
180
  declare global {
181
181
  interface Window {
182
- Versiq?: VersiqAPI;
183
- VersiqApps?: Map<string, VersiqAPI>;
182
+ Gamaro?: GamaroAPI;
183
+ GamaroApps?: Map<string, GamaroAPI>;
184
184
  }
185
185
  }