@burdenoff/website-sdk 2026.829.2 → 2026.829.4

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.
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { createContext, useMemo, useState, useRef, useCallback, useEffect, useContext } from 'react';
3
- import { Sparkles, RotateCcw, History, Trash2, Mic, Square, ArrowUp, BookOpenText, Layers, Link2, TriangleAlert, ChevronLeft, ChevronRight, ExternalLink } from 'lucide-react';
3
+ import { Sparkles, RotateCcw, Link2, History, Trash2, Mic, Square, ArrowUp, BookOpenText, Layers, TriangleAlert, ChevronLeft, ChevronRight, ExternalLink } from 'lucide-react';
4
4
  import ReactMarkdown from 'react-markdown';
5
5
  import rehypeSanitize from 'rehype-sanitize';
6
6
  import remarkGfm from 'remark-gfm';
@@ -548,6 +548,16 @@ var RECORD_EXPLORE_CLICK_MUTATION = (
548
548
  }
549
549
  `
550
550
  );
551
+ var CREATE_EXPLORE_SHARE_LINK_MUTATION = (
552
+ /* GraphQL */
553
+ `
554
+ mutation CreateExploreShareLink($conversationToken: String!) {
555
+ createExploreShareLink(conversationToken: $conversationToken) {
556
+ shareToken
557
+ }
558
+ }
559
+ `
560
+ );
551
561
 
552
562
  // src/data/products.ts
553
563
  var ECOSYSTEM_PRODUCTS = [
@@ -1480,6 +1490,16 @@ function useExploreChat(options = {}) {
1480
1490
  return null;
1481
1491
  }, [messages]);
1482
1492
  const canSend = (phase === "ready" || phase === "error") && catalog.enabled && turnCount < catalog.limits.maxTurnsPerConversation;
1493
+ const createShareLink = useCallback(async () => {
1494
+ const token = conversationTokenRef.current;
1495
+ if (!token) return null;
1496
+ try {
1497
+ const result = await client.mutate(CREATE_EXPLORE_SHARE_LINK_MUTATION, { conversationToken: token });
1498
+ return result?.data?.createExploreShareLink?.shareToken ?? null;
1499
+ } catch {
1500
+ return null;
1501
+ }
1502
+ }, [client]);
1483
1503
  const recordClick = useCallback(
1484
1504
  (messageId, kind, url) => {
1485
1505
  const token = conversationTokenRef.current;
@@ -1512,7 +1532,8 @@ function useExploreChat(options = {}) {
1512
1532
  openConversation,
1513
1533
  deleteConversation,
1514
1534
  clearHistory,
1515
- recordClick
1535
+ recordClick,
1536
+ createShareLink
1516
1537
  };
1517
1538
  }
1518
1539
  var optimisticCounter = 0;
@@ -2640,7 +2661,8 @@ function ExplorePage({
2640
2661
  openConversation,
2641
2662
  deleteConversation,
2642
2663
  clearHistory,
2643
- recordClick
2664
+ recordClick,
2665
+ createShareLink
2644
2666
  } = useExploreChat({ productSlug, pageUrl, onSend, examplePrompts });
2645
2667
  const [draft, setDraft] = useState("");
2646
2668
  const textareaRef = useRef(null);
@@ -2660,6 +2682,8 @@ function ExplorePage({
2660
2682
  });
2661
2683
  speechStopRef.current = speech.stop;
2662
2684
  const [disclaimerOpen, setDisclaimerOpen] = useState(false);
2685
+ const [shareLabel, setShareLabel] = useState("Share");
2686
+ const [shareUrl, setShareUrl] = useState(null);
2663
2687
  const scrollRef = useRef(null);
2664
2688
  const latestAssistantRef = useRef(null);
2665
2689
  const alignedForRef = useRef(null);
@@ -2714,6 +2738,26 @@ function ExplorePage({
2714
2738
  if (!el) return;
2715
2739
  el.scrollTop = el.scrollHeight;
2716
2740
  }, [activity, latestAssistantId, messages]);
2741
+ const handleShare = useCallback(async () => {
2742
+ setShareLabel("Copying\u2026");
2743
+ setShareUrl(null);
2744
+ const token = await createShareLink();
2745
+ if (!token) {
2746
+ setShareLabel("Unavailable");
2747
+ setTimeout(() => setShareLabel("Share"), 2500);
2748
+ return;
2749
+ }
2750
+ const base = (pageUrl ?? window.location.href).split("?")[0];
2751
+ const url = `${base}?c=${encodeURIComponent(token)}`;
2752
+ try {
2753
+ await navigator.clipboard.writeText(url);
2754
+ setShareLabel("Copied");
2755
+ setTimeout(() => setShareLabel("Share"), 2500);
2756
+ } catch {
2757
+ setShareUrl(url);
2758
+ setShareLabel("Share");
2759
+ }
2760
+ }, [createShareLink, pageUrl]);
2717
2761
  const submitDraft = useCallback(() => {
2718
2762
  const text = draft.trim();
2719
2763
  if (!text || overLimit || busy || !canSend) return;
@@ -2796,6 +2840,24 @@ function ExplorePage({
2796
2840
  ]
2797
2841
  }
2798
2842
  ),
2843
+ messages.length > 0 ? /* @__PURE__ */ jsxs(
2844
+ Button,
2845
+ {
2846
+ "data-boff-explore": "share",
2847
+ type: "button",
2848
+ size: "sm",
2849
+ variant: "ghost",
2850
+ className: "shrink-0 text-muted-foreground",
2851
+ title: "Copy a read-only link to this conversation",
2852
+ onClick: () => {
2853
+ void handleShare();
2854
+ },
2855
+ children: [
2856
+ /* @__PURE__ */ jsx(Link2, { className: "h-3.5 w-3.5" }),
2857
+ /* @__PURE__ */ jsx("span", { className: "hidden sm:inline", children: shareLabel })
2858
+ ]
2859
+ }
2860
+ ) : null,
2799
2861
  history.length > 0 ? /* @__PURE__ */ jsxs(
2800
2862
  Button,
2801
2863
  {
@@ -3058,6 +3120,28 @@ function ExplorePage({
3058
3120
  }
3059
3121
  )
3060
3122
  ] }),
3123
+ shareUrl ? /* @__PURE__ */ jsxs("div", { className: "mt-2 flex items-center gap-2", children: [
3124
+ /* @__PURE__ */ jsx(
3125
+ "input",
3126
+ {
3127
+ "data-boff-explore": "share-url",
3128
+ readOnly: true,
3129
+ value: shareUrl,
3130
+ "aria-label": "Read-only link to this conversation",
3131
+ onFocus: (event) => event.currentTarget.select(),
3132
+ className: "min-w-0 flex-1 rounded-md border border-border bg-muted px-2 py-1 text-xs text-muted-foreground"
3133
+ }
3134
+ ),
3135
+ /* @__PURE__ */ jsx(
3136
+ "button",
3137
+ {
3138
+ type: "button",
3139
+ className: "shrink-0 text-xs underline underline-offset-2",
3140
+ onClick: () => setShareUrl(null),
3141
+ children: "Done"
3142
+ }
3143
+ )
3144
+ ] }) : null,
3061
3145
  /* @__PURE__ */ jsxs("div", { className: "mt-2 flex flex-wrap items-center gap-x-3 gap-y-1 text-xs text-muted-foreground", children: [
3062
3146
  /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate", children: "Grounded in our docs \u2014 check anything important." }),
3063
3147
  /* @__PURE__ */ jsx(