@burdenoff/website-sdk 2026.1101.3 → 2026.1102.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.
Files changed (40) hide show
  1. package/README.md +234 -14
  2. package/dist/avatar-live-view/index.d.mts +1 -1
  3. package/dist/avatar-live-view/index.d.ts +1 -1
  4. package/dist/avatar-live-view/index.js +71 -24
  5. package/dist/avatar-live-view/index.js.map +1 -1
  6. package/dist/avatar-live-view/index.mjs +69 -22
  7. package/dist/avatar-live-view/index.mjs.map +1 -1
  8. package/dist/{chunk-Y4V5CEWD.mjs → chunk-2LPDCXQH.mjs} +7 -4
  9. package/dist/chunk-2LPDCXQH.mjs.map +1 -0
  10. package/dist/{chunk-FFADMVIK.mjs → chunk-ETI2HQEC.mjs} +7 -5
  11. package/dist/chunk-ETI2HQEC.mjs.map +1 -0
  12. package/dist/{chunk-23H4JUL4.js → chunk-OIQHIGGU.js} +20 -3
  13. package/dist/chunk-OIQHIGGU.js.map +1 -0
  14. package/dist/{chunk-OYEUNZJY.js → chunk-PIXTBL63.js} +7 -3
  15. package/dist/chunk-PIXTBL63.js.map +1 -0
  16. package/dist/{chunk-BX2USEWF.mjs → chunk-QOHPLTGT.mjs} +19 -4
  17. package/dist/chunk-QOHPLTGT.mjs.map +1 -0
  18. package/dist/{chunk-O76QDGRM.js → chunk-R742FS5E.js} +8 -4
  19. package/dist/chunk-R742FS5E.js.map +1 -0
  20. package/dist/components/explore-cta.d.mts +7 -0
  21. package/dist/components/explore-cta.d.ts +7 -0
  22. package/dist/components/explore-cta.js +2 -2
  23. package/dist/components/explore-cta.mjs +1 -1
  24. package/dist/components/explore.js +13 -13
  25. package/dist/components/explore.mjs +1 -1
  26. package/dist/{explore-avatar-live-config-B171o1Yo.d.ts → explore-avatar-live-config-C1ILEcY8.d.ts} +16 -4
  27. package/dist/{explore-avatar-live-config-BGsGwbcq.d.mts → explore-avatar-live-config-D-hO90-A.d.mts} +16 -4
  28. package/dist/index.d.mts +107 -4
  29. package/dist/index.d.ts +107 -4
  30. package/dist/index.js +209 -43
  31. package/dist/index.js.map +1 -1
  32. package/dist/index.mjs +173 -7
  33. package/dist/index.mjs.map +1 -1
  34. package/package.json +1 -1
  35. package/dist/chunk-23H4JUL4.js.map +0 -1
  36. package/dist/chunk-BX2USEWF.mjs.map +0 -1
  37. package/dist/chunk-FFADMVIK.mjs.map +0 -1
  38. package/dist/chunk-O76QDGRM.js.map +0 -1
  39. package/dist/chunk-OYEUNZJY.js.map +0 -1
  40. package/dist/chunk-Y4V5CEWD.mjs.map +0 -1
@@ -28,6 +28,13 @@ interface ExploreCtaProps {
28
28
  expanded?: boolean;
29
29
  /** BOFF-9697. The id of the panel the button opens; used only together with `expanded`. */
30
30
  controls?: string;
31
+ /**
32
+ * BOFF-9797. `floating` only: a CSS length to lift the bubble by, the site's cookie banner's height (say
33
+ * `var(--hb-cookie-banner-height, 0px)`), so a banner on screen does not cover it. The bubble then sits at
34
+ * `calc(1.25rem + bottomOffset)` from the bottom, set inline, so it wins over a `bottom-*` class in `className`.
35
+ * Unset: the bubble's usual place (`bottom-5`), exactly as before.
36
+ */
37
+ bottomOffset?: string;
31
38
  }
32
39
  /** The rendered `<a>` is forwarded, so a panel can return focus to the button that opened it (BOFF-9697). */
33
40
  declare const ExploreCta: react.ForwardRefExoticComponent<ExploreCtaProps & react.RefAttributes<HTMLAnchorElement>>;
@@ -28,6 +28,13 @@ interface ExploreCtaProps {
28
28
  expanded?: boolean;
29
29
  /** BOFF-9697. The id of the panel the button opens; used only together with `expanded`. */
30
30
  controls?: string;
31
+ /**
32
+ * BOFF-9797. `floating` only: a CSS length to lift the bubble by, the site's cookie banner's height (say
33
+ * `var(--hb-cookie-banner-height, 0px)`), so a banner on screen does not cover it. The bubble then sits at
34
+ * `calc(1.25rem + bottomOffset)` from the bottom, set inline, so it wins over a `bottom-*` class in `className`.
35
+ * Unset: the bubble's usual place (`bottom-5`), exactly as before.
36
+ */
37
+ bottomOffset?: string;
31
38
  }
32
39
  /** The rendered `<a>` is forwarded, so a panel can return focus to the button that opened it (BOFF-9697). */
33
40
  declare const ExploreCta: react.ForwardRefExoticComponent<ExploreCtaProps & react.RefAttributes<HTMLAnchorElement>>;
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkOYEUNZJY_js = require('../chunk-OYEUNZJY.js');
3
+ var chunkPIXTBL63_js = require('../chunk-PIXTBL63.js');
4
4
  require('../chunk-C6OJIHNO.js');
5
5
  require('../chunk-ZSTFX7FV.js');
6
6
 
@@ -8,7 +8,7 @@ require('../chunk-ZSTFX7FV.js');
8
8
 
9
9
  Object.defineProperty(exports, "ExploreCta", {
10
10
  enumerable: true,
11
- get: function () { return chunkOYEUNZJY_js.ExploreCta; }
11
+ get: function () { return chunkPIXTBL63_js.ExploreCta; }
12
12
  });
13
13
  //# sourceMappingURL=explore-cta.js.map
14
14
  //# sourceMappingURL=explore-cta.js.map
@@ -1,4 +1,4 @@
1
- export { ExploreCta } from '../chunk-Y4V5CEWD.mjs';
1
+ export { ExploreCta } from '../chunk-2LPDCXQH.mjs';
2
2
  import '../chunk-R7G6TWIS.mjs';
3
3
  import '../chunk-VNS5WDWO.mjs';
4
4
  //# sourceMappingURL=explore-cta.mjs.map
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkO76QDGRM_js = require('../chunk-O76QDGRM.js');
3
+ var chunkR742FS5E_js = require('../chunk-R742FS5E.js');
4
4
  require('../chunk-O4GS3XPZ.js');
5
5
  require('../chunk-SK5UGG6A.js');
6
6
  require('../chunk-PHXAGQNB.js');
@@ -18,51 +18,51 @@ require('../chunk-ZSTFX7FV.js');
18
18
 
19
19
  Object.defineProperty(exports, "EXPLORE_PREFILL_MAX_LENGTH", {
20
20
  enumerable: true,
21
- get: function () { return chunkO76QDGRM_js.EXPLORE_PREFILL_MAX_LENGTH; }
21
+ get: function () { return chunkR742FS5E_js.EXPLORE_PREFILL_MAX_LENGTH; }
22
22
  });
23
23
  Object.defineProperty(exports, "ExplorePage", {
24
24
  enumerable: true,
25
- get: function () { return chunkO76QDGRM_js.ExplorePage; }
25
+ get: function () { return chunkR742FS5E_js.ExplorePage; }
26
26
  });
27
27
  Object.defineProperty(exports, "answerPlainText", {
28
28
  enumerable: true,
29
- get: function () { return chunkO76QDGRM_js.answerPlainText; }
29
+ get: function () { return chunkR742FS5E_js.answerPlainText; }
30
30
  });
31
31
  Object.defineProperty(exports, "answerSpeechText", {
32
32
  enumerable: true,
33
- get: function () { return chunkO76QDGRM_js.answerSpeechText; }
33
+ get: function () { return chunkR742FS5E_js.answerSpeechText; }
34
34
  });
35
35
  Object.defineProperty(exports, "exploreQuestionHref", {
36
36
  enumerable: true,
37
- get: function () { return chunkO76QDGRM_js.exploreQuestionHref; }
37
+ get: function () { return chunkR742FS5E_js.exploreQuestionHref; }
38
38
  });
39
39
  Object.defineProperty(exports, "inlineImageOrigins", {
40
40
  enumerable: true,
41
- get: function () { return chunkO76QDGRM_js.inlineImageOrigins; }
41
+ get: function () { return chunkR742FS5E_js.inlineImageOrigins; }
42
42
  });
43
43
  Object.defineProperty(exports, "isInlineImageAllowed", {
44
44
  enumerable: true,
45
- get: function () { return chunkO76QDGRM_js.isInlineImageAllowed; }
45
+ get: function () { return chunkR742FS5E_js.isInlineImageAllowed; }
46
46
  });
47
47
  Object.defineProperty(exports, "isInlineVideoAllowed", {
48
48
  enumerable: true,
49
- get: function () { return chunkO76QDGRM_js.isInlineVideoAllowed; }
49
+ get: function () { return chunkR742FS5E_js.isInlineVideoAllowed; }
50
50
  });
51
51
  Object.defineProperty(exports, "logoUrlOf", {
52
52
  enumerable: true,
53
- get: function () { return chunkO76QDGRM_js.logoUrlOf; }
53
+ get: function () { return chunkR742FS5E_js.logoUrlOf; }
54
54
  });
55
55
  Object.defineProperty(exports, "productNamesByOrigin", {
56
56
  enumerable: true,
57
- get: function () { return chunkO76QDGRM_js.productNamesByOrigin; }
57
+ get: function () { return chunkR742FS5E_js.productNamesByOrigin; }
58
58
  });
59
59
  Object.defineProperty(exports, "referenceKindOf", {
60
60
  enumerable: true,
61
- get: function () { return chunkO76QDGRM_js.referenceKindOf; }
61
+ get: function () { return chunkR742FS5E_js.referenceKindOf; }
62
62
  });
63
63
  Object.defineProperty(exports, "summariseReferences", {
64
64
  enumerable: true,
65
- get: function () { return chunkO76QDGRM_js.summariseReferences; }
65
+ get: function () { return chunkR742FS5E_js.summariseReferences; }
66
66
  });
67
67
  //# sourceMappingURL=explore.js.map
68
68
  //# sourceMappingURL=explore.js.map
@@ -1,4 +1,4 @@
1
- export { EXPLORE_PREFILL_MAX_LENGTH, ExplorePage, answerPlainText, answerSpeechText, exploreQuestionHref, inlineImageOrigins, isInlineImageAllowed, isInlineVideoAllowed, logoUrlOf, productNamesByOrigin, referenceKindOf, summariseReferences } from '../chunk-FFADMVIK.mjs';
1
+ export { EXPLORE_PREFILL_MAX_LENGTH, ExplorePage, answerPlainText, answerSpeechText, exploreQuestionHref, inlineImageOrigins, isInlineImageAllowed, isInlineVideoAllowed, logoUrlOf, productNamesByOrigin, referenceKindOf, summariseReferences } from '../chunk-ETI2HQEC.mjs';
2
2
  import '../chunk-TT3MHN42.mjs';
3
3
  import '../chunk-EUPFS6MZ.mjs';
4
4
  import '../chunk-SKIYDKIS.mjs';
@@ -260,8 +260,9 @@ declare function speechLocaleOf(locale: ExploreLocale): string;
260
260
  */
261
261
 
262
262
  /**
263
- * BOFF-9797. A host's opt-in to the live avatar on its panel's Avatar tab. Every field is required; a config that is
264
- * incomplete leaves the tab as it was (and a warning in the console).
263
+ * BOFF-9797. A host's opt-in to the live avatar on its panel's Avatar tab. `site`, `load` and `manifestVersion` are
264
+ * required; a config that is incomplete, or has an optional field of the wrong shape, leaves the tab as it was (and a
265
+ * warning in the console).
265
266
  */
266
267
  interface ExplorePanelAvatarLive {
267
268
  /** The site, as the live avatar service knows it: `healthybowl`. */
@@ -272,8 +273,19 @@ interface ExplorePanelAvatarLive {
272
273
  * package's optional peer dependency for media rooms (see the README).
273
274
  */
274
275
  load: () => Promise<AvatarLiveModule>;
275
- /** The site's Cloudflare Turnstile site key, for the bot check that runs when the visitor presses Start. */
276
- turnstileSiteKey: string;
276
+ /**
277
+ * The site's Cloudflare Turnstile site key, for the bot check that runs when the visitor presses Start. Used only when
278
+ * the server says it checks for bots (its availability's `botCheck`, contract v1.2), or says nothing of it (a server
279
+ * older than v1.2, which always checks): such a server's live avatar then needs a key, and without one the tab stays
280
+ * as it was. A server that runs no bot check needs none, and no Cloudflare script is loaded for it, key or not.
281
+ */
282
+ turnstileSiteKey?: string;
283
+ /**
284
+ * Whether `turnstileSiteKey` may be one of Cloudflare's test keys (`1x00000000000000000000AA` and keys of their
285
+ * shape). `websiteAvatarLive` sets it: true on alpha only, false everywhere else, so a production page never runs a
286
+ * test widget. Unset (a config made by hand): any key of a valid shape, as before.
287
+ */
288
+ allowTestSiteKey?: boolean;
277
289
  /** The version of the suggested-question list the panel shows (its `examplePrompts`), such as `hb-en-1`. */
278
290
  manifestVersion: string;
279
291
  }
@@ -260,8 +260,9 @@ declare function speechLocaleOf(locale: ExploreLocale): string;
260
260
  */
261
261
 
262
262
  /**
263
- * BOFF-9797. A host's opt-in to the live avatar on its panel's Avatar tab. Every field is required; a config that is
264
- * incomplete leaves the tab as it was (and a warning in the console).
263
+ * BOFF-9797. A host's opt-in to the live avatar on its panel's Avatar tab. `site`, `load` and `manifestVersion` are
264
+ * required; a config that is incomplete, or has an optional field of the wrong shape, leaves the tab as it was (and a
265
+ * warning in the console).
265
266
  */
266
267
  interface ExplorePanelAvatarLive {
267
268
  /** The site, as the live avatar service knows it: `healthybowl`. */
@@ -272,8 +273,19 @@ interface ExplorePanelAvatarLive {
272
273
  * package's optional peer dependency for media rooms (see the README).
273
274
  */
274
275
  load: () => Promise<AvatarLiveModule>;
275
- /** The site's Cloudflare Turnstile site key, for the bot check that runs when the visitor presses Start. */
276
- turnstileSiteKey: string;
276
+ /**
277
+ * The site's Cloudflare Turnstile site key, for the bot check that runs when the visitor presses Start. Used only when
278
+ * the server says it checks for bots (its availability's `botCheck`, contract v1.2), or says nothing of it (a server
279
+ * older than v1.2, which always checks): such a server's live avatar then needs a key, and without one the tab stays
280
+ * as it was. A server that runs no bot check needs none, and no Cloudflare script is loaded for it, key or not.
281
+ */
282
+ turnstileSiteKey?: string;
283
+ /**
284
+ * Whether `turnstileSiteKey` may be one of Cloudflare's test keys (`1x00000000000000000000AA` and keys of their
285
+ * shape). `websiteAvatarLive` sets it: true on alpha only, false everywhere else, so a production page never runs a
286
+ * test widget. Unset (a config made by hand): any key of a valid shape, as before.
287
+ */
288
+ allowTestSiteKey?: boolean;
277
289
  /** The version of the suggested-question list the panel shows (its `examplePrompts`), such as `hb-en-1`. */
278
290
  manifestVersion: string;
279
291
  }
package/dist/index.d.mts CHANGED
@@ -18,8 +18,8 @@ export { LaunchCountdown, LaunchCountdownProps } from './components/launch-count
18
18
  export { ProblemSolved, ProblemsSolvedSection, ProblemsSolvedSectionProps } from './components/problems-solved.mjs';
19
19
  export { DetectedPlatform, ElectronDownloadLink, ElectronDownloadLinkProps, detectElectronPlatform } from './components/electron-download.mjs';
20
20
  import { Components } from 'react-markdown';
21
- import { a as ExploreLocale, E as ExplorePanelAvatarLive } from './explore-avatar-live-config-BGsGwbcq.mjs';
22
- export { b as EXPLORE_LOCALES, c as ExploreStrings, s as speechLocaleOf } from './explore-avatar-live-config-BGsGwbcq.mjs';
21
+ import { a as ExploreLocale, E as ExplorePanelAvatarLive } from './explore-avatar-live-config-D-hO90-A.mjs';
22
+ export { b as EXPLORE_LOCALES, c as ExploreStrings, s as speechLocaleOf } from './explore-avatar-live-config-D-hO90-A.mjs';
23
23
  import { A as AnswerRendererStrings, E as ExploreScope } from './explore-DUTNYUOm.mjs';
24
24
  export { a as EXPLORE_PREFILL_MAX_LENGTH, b as ExploreAnswerBody, c as ExploreAnswerBodyProps, d as ExploreAnswerStyles, e as ExplorePage, f as ExplorePageProps, g as answerPlainText, h as answerSpeechText, i as exploreQuestionHref, j as inlineImageOrigins, k as isInlineImageAllowed, l as isInlineVideoAllowed, p as productSlugsByOrigin } from './explore-DUTNYUOm.mjs';
25
25
  export { ExploreCta, ExploreCtaProps } from './components/explore-cta.mjs';
@@ -658,7 +658,8 @@ interface ExploreChatProviderProps extends Omit<ExploreConversationOptions, "ena
658
658
  /**
659
659
  * Start the conversation. Pass `true` from the visitor's first opening of the assistant, or while the `/explore`
660
660
  * route is shown; until then the provider asks nothing (no catalog request, no restore). Latched: once it has been
661
- * `true` the conversation stays live, so a running answer is never cut by the host flipping it back.
661
+ * `true` the conversation stays live, so a running answer is never cut by the host flipping it back. Under a
662
+ * `SiteAssistantDock` the dock starts it on its first opening (BOFF-9797): pass `true` on the `/explore` route only.
662
663
  */
663
664
  enabled: boolean;
664
665
  /**
@@ -743,6 +744,108 @@ interface ExplorePanelProps {
743
744
  }
744
745
  declare function ExplorePanel({ open, onOpenChange, id, productSlug, locale, scope, productName, examplePrompts, onNavigate, welcomeTitle, welcomeBody, explorePath, avatar, bottomOffset, zIndex, returnFocusRef, className, }: ExplorePanelProps): react.JSX.Element | null;
745
746
 
747
+ interface SiteAssistantDockProps {
748
+ /** The site's product, as the platform knows it (`healthybowl`). Passed to the panel's chat. */
749
+ productSlug?: string;
750
+ /** `product` (with `productSlug`) makes the panel this product's own assistant. See `ExplorePanelProps.scope`. */
751
+ scope?: ExploreScope;
752
+ /** The product's display name in the `product` scope ("Healthy Bowl"). See `ExplorePanelProps.productName`. */
753
+ productName?: string;
754
+ /** The panel's example prompts; in the `product` scope the only ones it shows. See `ExplorePanelProps`. */
755
+ examplePrompts?: string[];
756
+ /** The assistant's locale. Default: the SDK's own resolution, as on `ExplorePanel`. */
757
+ locale?: string;
758
+ /**
759
+ * The Avatar view: the approved still picture, plus `live` to opt in to the live avatar (see `websiteAvatarLive`).
760
+ * Absent: the panel has no Avatar view and no tabs.
761
+ */
762
+ avatar?: ExplorePanelAvatar;
763
+ /**
764
+ * The host router's navigate, for links in the conversation (and, without a provider in production, for the
765
+ * button's link to `/explore`). Absent: links load the page normally.
766
+ */
767
+ onNavigate?: (path: string) => void;
768
+ /**
769
+ * A CSS length kept clear at the bottom of the window: the site's own cookie banner's height, from the CSS variable
770
+ * that banner publishes (HealthyBowl's is `var(--hb-cookie-banner-height, 0px)`; there is no SDK-wide variable). The
771
+ * panel keeps it clear and the floating button sits that much higher, so a banner still on screen covers neither.
772
+ * Default `0px`: the button at its usual place.
773
+ */
774
+ bottomOffset?: string;
775
+ /** Extra classes for the floating button (the launcher). */
776
+ className?: string;
777
+ /** Extra classes for the panel. */
778
+ panelClassName?: string;
779
+ /**
780
+ * The current route, from the host's router (`useLocation().pathname`). Falls back to `window.location.pathname`,
781
+ * which cannot see a router's `pushState` navigations: pass it.
782
+ */
783
+ currentPath?: string;
784
+ /**
785
+ * The site's Explore route. Default `/explore`. The button links there, the dock hides on it (matched as the router
786
+ * does: ignoring case and a trailing slash), and the panel makes its share links to it.
787
+ */
788
+ explorePath?: string;
789
+ /** The button's visible label and accessible name. Default `Ask AI`. */
790
+ label?: string;
791
+ /** The panel's id, for the button's `aria-controls`. Default `boff-explore-panel`. */
792
+ id?: string;
793
+ /** The panel's `z-index`. Default 50 (see `ExplorePanelProps.zIndex`). */
794
+ zIndex?: number;
795
+ }
796
+ declare function SiteAssistantDock(props: SiteAssistantDockProps): react.JSX.Element | null;
797
+
798
+ /**
799
+ * BOFF-9797. A product website's live-avatar opt-in (`avatar.live` on `ExplorePanel` / `SiteAssistantDock`), decided
800
+ * from its build: which environment it is built for, and the Cloudflare Turnstile site key it was given.
801
+ *
802
+ * Pure: no React, no network, no globals. A site calls it once, at module scope, with its build's values:
803
+ *
804
+ * ```ts
805
+ * export const AVATAR_LIVE = websiteAvatarLive({
806
+ * deployEnv: import.meta.env.VITE_DEPLOY_ENV,
807
+ * siteKey: import.meta.env.VITE_AVATAR_TURNSTILE_SITE_KEY,
808
+ * site: 'healthybowl',
809
+ * manifestVersion: manifest.version,
810
+ * load: () => import('@burdenoff/website-sdk/avatar-live'),
811
+ * })
812
+ * ```
813
+ *
814
+ * The server decides whether the live avatar is offered on the site (its reviewed site list, its pause and its caps),
815
+ * and whether it checks for bots (its availability's `botCheck`, contract v1.2). The key matters only when it does. The
816
+ * rule, so that a misconfigured build shows the still picture instead of a live avatar whose bot check can never pass,
817
+ * or always passes:
818
+ *
819
+ * - `enabled: false`: `undefined` (the still picture, "Live avatar coming soon"), whatever else is set.
820
+ * - No key, or an empty one: the live config without a key. The server decides: a server that runs no bot check offers
821
+ * the live avatar, one that checks for bots (or a site it does not list) leaves the still picture.
822
+ * - Alpha (`deployEnv` `alpha`): Cloudflare's always-pass test key `1x00000000000000000000AA` (the alpha gateway runs
823
+ * Turnstile in dummy mode with the matching test secret), or a real-looking key.
824
+ * - Every other environment, production included, and an unset one: a real-looking key only. Cloudflare's test keys
825
+ * (`1x…AA`, `2x…AB`, `1x…BB`, `2x…BB`, `3x…FF`, and anything of their shape) are refused.
826
+ * - A key that is set but refused: `undefined`, the still picture, never a live avatar without the key it was given.
827
+ */
828
+
829
+ interface WebsiteAvatarLiveOptions {
830
+ /** The environment the site is built for: `import.meta.env.VITE_DEPLOY_ENV` (`alpha`, `production`, …). */
831
+ deployEnv: string | null | undefined;
832
+ /**
833
+ * The site's Turnstile site key: `import.meta.env.VITE_AVATAR_TURNSTILE_SITE_KEY`. Unset or empty: no key, and the
834
+ * live avatar runs only where the server runs no bot check.
835
+ */
836
+ siteKey: string | null | undefined;
837
+ /** The site, as the live avatar service knows it (`healthybowl`). */
838
+ site: string;
839
+ /** The version of the suggested-question list the panel shows (its `examplePrompts`), such as `hb-en-1`. */
840
+ manifestVersion: string;
841
+ /** Loads the live avatar's room module: `() => import('@burdenoff/website-sdk/avatar-live')`. */
842
+ load: ExplorePanelAvatarLive["load"];
843
+ /** False keeps the still picture on this build, whatever the server offers. Default true. */
844
+ enabled?: boolean;
845
+ }
846
+ /** The `avatar.live` prop for this build, or `undefined` for the still picture only. */
847
+ declare function websiteAvatarLive({ deployEnv, siteKey, site, manifestVersion, load, enabled, }: WebsiteAvatarLiveOptions): ExplorePanelAvatarLive | undefined;
848
+
746
849
  declare const buttonVariants: (props?: ({
747
850
  variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
748
851
  size?: "icon" | "default" | "sm" | "lg" | null | undefined;
@@ -769,4 +872,4 @@ declare const Textarea: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLP
769
872
  */
770
873
  declare const ECOSYSTEM_PRODUCTS: WebsiteSwitcherProduct[];
771
874
 
772
- export { ANSWERS_PATH, ANSWER_HEADING_SHIFT, ANSWER_PATH_PREFIX, AnswerDetailPage, type AnswerDetailPageProps, type AnswerLinkComponent, type AnswerLinkProps, AnswerRendererStrings, type AnswerStrings, AnswersPage, type AnswersPageProps, Button, type ButtonProps, CONCEPTS_PATH, CONCEPT_ILLUSTRATION_NOTICE, CONCEPT_PATH_PREFIX, CONCEPT_WORKFLOW_NOTICE, CareersPostingOption, CareersSubmissionForm, type CareersSubmissionFormProps, type Concept, type ConceptCategory, ConceptDetailPage, type ConceptDetailPageProps, type ConceptDevice, type ConceptImage, type ConceptLinkComponent, type ConceptLinkProps, type ConceptSolution, ConceptsPage, type ConceptsPageProps, DOMAINS_URL, ECOSYSTEM_PRODUCTS, ExploreChatProvider, type ExploreChatProviderProps, type ExploreConversationOptions, type ExploreConversationState, ExploreLocale, ExplorePanel, type ExplorePanelAvatar, ExplorePanelAvatarLive, type ExplorePanelProps, ExploreScope, Input, Label, PUBLISHED_ANSWER_FIELDS, type PublishedAnswer, type PublishedAnswerSource, type PublishedAnswerTopic, Select, Textarea, UseExploreChatResult, WebsiteSwitcherProduct, answerPath, answerSourceHost, answerStrings, buttonVariants, conceptPath, formatAnswerDate, getAnswerBySlug, getConceptBySlug, isPublishedSourceUrl, isValidUrl, useExploreConversation };
875
+ export { ANSWERS_PATH, ANSWER_HEADING_SHIFT, ANSWER_PATH_PREFIX, AnswerDetailPage, type AnswerDetailPageProps, type AnswerLinkComponent, type AnswerLinkProps, AnswerRendererStrings, type AnswerStrings, AnswersPage, type AnswersPageProps, Button, type ButtonProps, CONCEPTS_PATH, CONCEPT_ILLUSTRATION_NOTICE, CONCEPT_PATH_PREFIX, CONCEPT_WORKFLOW_NOTICE, CareersPostingOption, CareersSubmissionForm, type CareersSubmissionFormProps, type Concept, type ConceptCategory, ConceptDetailPage, type ConceptDetailPageProps, type ConceptDevice, type ConceptImage, type ConceptLinkComponent, type ConceptLinkProps, type ConceptSolution, ConceptsPage, type ConceptsPageProps, DOMAINS_URL, ECOSYSTEM_PRODUCTS, ExploreChatProvider, type ExploreChatProviderProps, type ExploreConversationOptions, type ExploreConversationState, ExploreLocale, ExplorePanel, type ExplorePanelAvatar, ExplorePanelAvatarLive, type ExplorePanelProps, ExploreScope, Input, Label, PUBLISHED_ANSWER_FIELDS, type PublishedAnswer, type PublishedAnswerSource, type PublishedAnswerTopic, Select, SiteAssistantDock, type SiteAssistantDockProps, Textarea, UseExploreChatResult, type WebsiteAvatarLiveOptions, WebsiteSwitcherProduct, answerPath, answerSourceHost, answerStrings, buttonVariants, conceptPath, formatAnswerDate, getAnswerBySlug, getConceptBySlug, isPublishedSourceUrl, isValidUrl, useExploreConversation, websiteAvatarLive };
package/dist/index.d.ts CHANGED
@@ -18,8 +18,8 @@ export { LaunchCountdown, LaunchCountdownProps } from './components/launch-count
18
18
  export { ProblemSolved, ProblemsSolvedSection, ProblemsSolvedSectionProps } from './components/problems-solved.js';
19
19
  export { DetectedPlatform, ElectronDownloadLink, ElectronDownloadLinkProps, detectElectronPlatform } from './components/electron-download.js';
20
20
  import { Components } from 'react-markdown';
21
- import { a as ExploreLocale, E as ExplorePanelAvatarLive } from './explore-avatar-live-config-B171o1Yo.js';
22
- export { b as EXPLORE_LOCALES, c as ExploreStrings, s as speechLocaleOf } from './explore-avatar-live-config-B171o1Yo.js';
21
+ import { a as ExploreLocale, E as ExplorePanelAvatarLive } from './explore-avatar-live-config-C1ILEcY8.js';
22
+ export { b as EXPLORE_LOCALES, c as ExploreStrings, s as speechLocaleOf } from './explore-avatar-live-config-C1ILEcY8.js';
23
23
  import { A as AnswerRendererStrings, E as ExploreScope } from './explore-DjQE7Xia.js';
24
24
  export { a as EXPLORE_PREFILL_MAX_LENGTH, b as ExploreAnswerBody, c as ExploreAnswerBodyProps, d as ExploreAnswerStyles, e as ExplorePage, f as ExplorePageProps, g as answerPlainText, h as answerSpeechText, i as exploreQuestionHref, j as inlineImageOrigins, k as isInlineImageAllowed, l as isInlineVideoAllowed, p as productSlugsByOrigin } from './explore-DjQE7Xia.js';
25
25
  export { ExploreCta, ExploreCtaProps } from './components/explore-cta.js';
@@ -658,7 +658,8 @@ interface ExploreChatProviderProps extends Omit<ExploreConversationOptions, "ena
658
658
  /**
659
659
  * Start the conversation. Pass `true` from the visitor's first opening of the assistant, or while the `/explore`
660
660
  * route is shown; until then the provider asks nothing (no catalog request, no restore). Latched: once it has been
661
- * `true` the conversation stays live, so a running answer is never cut by the host flipping it back.
661
+ * `true` the conversation stays live, so a running answer is never cut by the host flipping it back. Under a
662
+ * `SiteAssistantDock` the dock starts it on its first opening (BOFF-9797): pass `true` on the `/explore` route only.
662
663
  */
663
664
  enabled: boolean;
664
665
  /**
@@ -743,6 +744,108 @@ interface ExplorePanelProps {
743
744
  }
744
745
  declare function ExplorePanel({ open, onOpenChange, id, productSlug, locale, scope, productName, examplePrompts, onNavigate, welcomeTitle, welcomeBody, explorePath, avatar, bottomOffset, zIndex, returnFocusRef, className, }: ExplorePanelProps): react.JSX.Element | null;
745
746
 
747
+ interface SiteAssistantDockProps {
748
+ /** The site's product, as the platform knows it (`healthybowl`). Passed to the panel's chat. */
749
+ productSlug?: string;
750
+ /** `product` (with `productSlug`) makes the panel this product's own assistant. See `ExplorePanelProps.scope`. */
751
+ scope?: ExploreScope;
752
+ /** The product's display name in the `product` scope ("Healthy Bowl"). See `ExplorePanelProps.productName`. */
753
+ productName?: string;
754
+ /** The panel's example prompts; in the `product` scope the only ones it shows. See `ExplorePanelProps`. */
755
+ examplePrompts?: string[];
756
+ /** The assistant's locale. Default: the SDK's own resolution, as on `ExplorePanel`. */
757
+ locale?: string;
758
+ /**
759
+ * The Avatar view: the approved still picture, plus `live` to opt in to the live avatar (see `websiteAvatarLive`).
760
+ * Absent: the panel has no Avatar view and no tabs.
761
+ */
762
+ avatar?: ExplorePanelAvatar;
763
+ /**
764
+ * The host router's navigate, for links in the conversation (and, without a provider in production, for the
765
+ * button's link to `/explore`). Absent: links load the page normally.
766
+ */
767
+ onNavigate?: (path: string) => void;
768
+ /**
769
+ * A CSS length kept clear at the bottom of the window: the site's own cookie banner's height, from the CSS variable
770
+ * that banner publishes (HealthyBowl's is `var(--hb-cookie-banner-height, 0px)`; there is no SDK-wide variable). The
771
+ * panel keeps it clear and the floating button sits that much higher, so a banner still on screen covers neither.
772
+ * Default `0px`: the button at its usual place.
773
+ */
774
+ bottomOffset?: string;
775
+ /** Extra classes for the floating button (the launcher). */
776
+ className?: string;
777
+ /** Extra classes for the panel. */
778
+ panelClassName?: string;
779
+ /**
780
+ * The current route, from the host's router (`useLocation().pathname`). Falls back to `window.location.pathname`,
781
+ * which cannot see a router's `pushState` navigations: pass it.
782
+ */
783
+ currentPath?: string;
784
+ /**
785
+ * The site's Explore route. Default `/explore`. The button links there, the dock hides on it (matched as the router
786
+ * does: ignoring case and a trailing slash), and the panel makes its share links to it.
787
+ */
788
+ explorePath?: string;
789
+ /** The button's visible label and accessible name. Default `Ask AI`. */
790
+ label?: string;
791
+ /** The panel's id, for the button's `aria-controls`. Default `boff-explore-panel`. */
792
+ id?: string;
793
+ /** The panel's `z-index`. Default 50 (see `ExplorePanelProps.zIndex`). */
794
+ zIndex?: number;
795
+ }
796
+ declare function SiteAssistantDock(props: SiteAssistantDockProps): react.JSX.Element | null;
797
+
798
+ /**
799
+ * BOFF-9797. A product website's live-avatar opt-in (`avatar.live` on `ExplorePanel` / `SiteAssistantDock`), decided
800
+ * from its build: which environment it is built for, and the Cloudflare Turnstile site key it was given.
801
+ *
802
+ * Pure: no React, no network, no globals. A site calls it once, at module scope, with its build's values:
803
+ *
804
+ * ```ts
805
+ * export const AVATAR_LIVE = websiteAvatarLive({
806
+ * deployEnv: import.meta.env.VITE_DEPLOY_ENV,
807
+ * siteKey: import.meta.env.VITE_AVATAR_TURNSTILE_SITE_KEY,
808
+ * site: 'healthybowl',
809
+ * manifestVersion: manifest.version,
810
+ * load: () => import('@burdenoff/website-sdk/avatar-live'),
811
+ * })
812
+ * ```
813
+ *
814
+ * The server decides whether the live avatar is offered on the site (its reviewed site list, its pause and its caps),
815
+ * and whether it checks for bots (its availability's `botCheck`, contract v1.2). The key matters only when it does. The
816
+ * rule, so that a misconfigured build shows the still picture instead of a live avatar whose bot check can never pass,
817
+ * or always passes:
818
+ *
819
+ * - `enabled: false`: `undefined` (the still picture, "Live avatar coming soon"), whatever else is set.
820
+ * - No key, or an empty one: the live config without a key. The server decides: a server that runs no bot check offers
821
+ * the live avatar, one that checks for bots (or a site it does not list) leaves the still picture.
822
+ * - Alpha (`deployEnv` `alpha`): Cloudflare's always-pass test key `1x00000000000000000000AA` (the alpha gateway runs
823
+ * Turnstile in dummy mode with the matching test secret), or a real-looking key.
824
+ * - Every other environment, production included, and an unset one: a real-looking key only. Cloudflare's test keys
825
+ * (`1x…AA`, `2x…AB`, `1x…BB`, `2x…BB`, `3x…FF`, and anything of their shape) are refused.
826
+ * - A key that is set but refused: `undefined`, the still picture, never a live avatar without the key it was given.
827
+ */
828
+
829
+ interface WebsiteAvatarLiveOptions {
830
+ /** The environment the site is built for: `import.meta.env.VITE_DEPLOY_ENV` (`alpha`, `production`, …). */
831
+ deployEnv: string | null | undefined;
832
+ /**
833
+ * The site's Turnstile site key: `import.meta.env.VITE_AVATAR_TURNSTILE_SITE_KEY`. Unset or empty: no key, and the
834
+ * live avatar runs only where the server runs no bot check.
835
+ */
836
+ siteKey: string | null | undefined;
837
+ /** The site, as the live avatar service knows it (`healthybowl`). */
838
+ site: string;
839
+ /** The version of the suggested-question list the panel shows (its `examplePrompts`), such as `hb-en-1`. */
840
+ manifestVersion: string;
841
+ /** Loads the live avatar's room module: `() => import('@burdenoff/website-sdk/avatar-live')`. */
842
+ load: ExplorePanelAvatarLive["load"];
843
+ /** False keeps the still picture on this build, whatever the server offers. Default true. */
844
+ enabled?: boolean;
845
+ }
846
+ /** The `avatar.live` prop for this build, or `undefined` for the still picture only. */
847
+ declare function websiteAvatarLive({ deployEnv, siteKey, site, manifestVersion, load, enabled, }: WebsiteAvatarLiveOptions): ExplorePanelAvatarLive | undefined;
848
+
746
849
  declare const buttonVariants: (props?: ({
747
850
  variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
748
851
  size?: "icon" | "default" | "sm" | "lg" | null | undefined;
@@ -769,4 +872,4 @@ declare const Textarea: react.ForwardRefExoticComponent<Omit<react.DetailedHTMLP
769
872
  */
770
873
  declare const ECOSYSTEM_PRODUCTS: WebsiteSwitcherProduct[];
771
874
 
772
- export { ANSWERS_PATH, ANSWER_HEADING_SHIFT, ANSWER_PATH_PREFIX, AnswerDetailPage, type AnswerDetailPageProps, type AnswerLinkComponent, type AnswerLinkProps, AnswerRendererStrings, type AnswerStrings, AnswersPage, type AnswersPageProps, Button, type ButtonProps, CONCEPTS_PATH, CONCEPT_ILLUSTRATION_NOTICE, CONCEPT_PATH_PREFIX, CONCEPT_WORKFLOW_NOTICE, CareersPostingOption, CareersSubmissionForm, type CareersSubmissionFormProps, type Concept, type ConceptCategory, ConceptDetailPage, type ConceptDetailPageProps, type ConceptDevice, type ConceptImage, type ConceptLinkComponent, type ConceptLinkProps, type ConceptSolution, ConceptsPage, type ConceptsPageProps, DOMAINS_URL, ECOSYSTEM_PRODUCTS, ExploreChatProvider, type ExploreChatProviderProps, type ExploreConversationOptions, type ExploreConversationState, ExploreLocale, ExplorePanel, type ExplorePanelAvatar, ExplorePanelAvatarLive, type ExplorePanelProps, ExploreScope, Input, Label, PUBLISHED_ANSWER_FIELDS, type PublishedAnswer, type PublishedAnswerSource, type PublishedAnswerTopic, Select, Textarea, UseExploreChatResult, WebsiteSwitcherProduct, answerPath, answerSourceHost, answerStrings, buttonVariants, conceptPath, formatAnswerDate, getAnswerBySlug, getConceptBySlug, isPublishedSourceUrl, isValidUrl, useExploreConversation };
875
+ export { ANSWERS_PATH, ANSWER_HEADING_SHIFT, ANSWER_PATH_PREFIX, AnswerDetailPage, type AnswerDetailPageProps, type AnswerLinkComponent, type AnswerLinkProps, AnswerRendererStrings, type AnswerStrings, AnswersPage, type AnswersPageProps, Button, type ButtonProps, CONCEPTS_PATH, CONCEPT_ILLUSTRATION_NOTICE, CONCEPT_PATH_PREFIX, CONCEPT_WORKFLOW_NOTICE, CareersPostingOption, CareersSubmissionForm, type CareersSubmissionFormProps, type Concept, type ConceptCategory, ConceptDetailPage, type ConceptDetailPageProps, type ConceptDevice, type ConceptImage, type ConceptLinkComponent, type ConceptLinkProps, type ConceptSolution, ConceptsPage, type ConceptsPageProps, DOMAINS_URL, ECOSYSTEM_PRODUCTS, ExploreChatProvider, type ExploreChatProviderProps, type ExploreConversationOptions, type ExploreConversationState, ExploreLocale, ExplorePanel, type ExplorePanelAvatar, ExplorePanelAvatarLive, type ExplorePanelProps, ExploreScope, Input, Label, PUBLISHED_ANSWER_FIELDS, type PublishedAnswer, type PublishedAnswerSource, type PublishedAnswerTopic, Select, SiteAssistantDock, type SiteAssistantDockProps, Textarea, UseExploreChatResult, type WebsiteAvatarLiveOptions, WebsiteSwitcherProduct, answerPath, answerSourceHost, answerStrings, buttonVariants, conceptPath, formatAnswerDate, getAnswerBySlug, getConceptBySlug, isPublishedSourceUrl, isValidUrl, useExploreConversation, websiteAvatarLive };