@prodact.ai/sdk 0.0.10 → 0.0.11

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/dist/react.js CHANGED
@@ -1247,7 +1247,7 @@ var UserFlowTracker = class {
1247
1247
  samplingRate: this.config.samplingRate,
1248
1248
  currentState: this.state,
1249
1249
  apiUrl: this.apiUrl,
1250
- hasSessionToken: !!this.sessionToken
1250
+ hasSessionToken: !!this.sdkSessionToken
1251
1251
  });
1252
1252
  if (!this.config.enabled) {
1253
1253
  console.warn("[UserFlow] Tracking disabled by config");
@@ -1373,6 +1373,57 @@ var UserFlowTracker = class {
1373
1373
  isTracking() {
1374
1374
  return this.state === "tracking";
1375
1375
  }
1376
+ /**
1377
+ * Get recent events for context (excludes SDK UI interactions like chat widget)
1378
+ * @param limit - Maximum number of events to return (default: 10)
1379
+ * @param excludeSelectors - CSS selectors to exclude (default: produck SDK elements)
1380
+ */
1381
+ getRecentEvents(limit = 10, excludeSelectors) {
1382
+ const defaultExcludeSelectors = [
1383
+ "[data-produck-chat]",
1384
+ ".produck-chat",
1385
+ ".produck-widget",
1386
+ "#produck-chat",
1387
+ "#produck-widget",
1388
+ '[class*="produck"]',
1389
+ '[id*="produck"]'
1390
+ ];
1391
+ const selectorsToExclude = excludeSelectors || defaultExcludeSelectors;
1392
+ const filteredEvents = this.events.filter((event) => {
1393
+ if (event.eventType === "navigation") return true;
1394
+ if (event.element?.selector) {
1395
+ const selectorLower = event.element.selector.toLowerCase();
1396
+ const matchesExclude = selectorsToExclude.some((excludeSel) => {
1397
+ const excludeLower = excludeSel.toLowerCase();
1398
+ if (excludeLower.includes("produck")) {
1399
+ return selectorLower.includes("produck");
1400
+ }
1401
+ return selectorLower.includes(excludeLower.replace(/[\[\].*#]/g, ""));
1402
+ });
1403
+ if (matchesExclude) return false;
1404
+ }
1405
+ return true;
1406
+ });
1407
+ return filteredEvents.slice(-limit);
1408
+ }
1409
+ /**
1410
+ * Get recent events as a summary string for chat context
1411
+ */
1412
+ getRecentEventsAsSummary(limit = 10) {
1413
+ const events = this.getRecentEvents(limit);
1414
+ if (events.length === 0) return "";
1415
+ return events.map((event) => {
1416
+ if (event.eventType === "navigation") {
1417
+ return `Navigated to: ${event.pageTitle || event.pagePath}`;
1418
+ } else if (event.eventType === "click" && event.element) {
1419
+ const elementDesc = event.element.text || event.element.tag || "element";
1420
+ return `Clicked: ${elementDesc}${event.pageTitle ? ` on ${event.pageTitle}` : ""}`;
1421
+ } else if (event.eventType === "form_submit") {
1422
+ return `Submitted form on: ${event.pageTitle || event.pagePath}`;
1423
+ }
1424
+ return `${event.eventType}: ${event.pageTitle || event.pagePath}`;
1425
+ }).join("\n");
1426
+ }
1376
1427
  /**
1377
1428
  * Add a custom event
1378
1429
  */
@@ -2015,12 +2066,16 @@ Check the Network tab in DevTools for more details.`
2015
2066
  });
2016
2067
  }
2017
2068
  }
2069
+ const userContext = this.getRecentUserFlowSummary(10);
2018
2070
  const sessionResponse = await fetch(
2019
2071
  `${this.config.apiUrl}/chat/sessions/${this.sessionToken}/message`,
2020
2072
  {
2021
2073
  method: "POST",
2022
2074
  headers: { "Content-Type": "application/json" },
2023
- body: JSON.stringify({ message })
2075
+ body: JSON.stringify({
2076
+ message,
2077
+ userContext: userContext || void 0
2078
+ })
2024
2079
  }
2025
2080
  );
2026
2081
  if (!sessionResponse.ok) {
@@ -2711,6 +2766,19 @@ Check the Network tab in DevTools for more details.`
2711
2766
  getUserFlowStats() {
2712
2767
  return this.userFlowTracker?.getStats() ?? null;
2713
2768
  }
2769
+ /**
2770
+ * Get recent user flow events (excluding SDK UI interactions)
2771
+ * Useful for providing context to chat
2772
+ */
2773
+ getRecentUserFlowEvents(limit = 10) {
2774
+ return this.userFlowTracker?.getRecentEvents(limit) ?? [];
2775
+ }
2776
+ /**
2777
+ * Get recent user flow events as a summary string for chat context
2778
+ */
2779
+ getRecentUserFlowSummary(limit = 10) {
2780
+ return this.userFlowTracker?.getRecentEventsAsSummary(limit) ?? "";
2781
+ }
2714
2782
  /**
2715
2783
  * Check if user flow tracking is active
2716
2784
  */
@@ -2881,7 +2949,7 @@ function ProduckProvider({
2881
2949
  }
2882
2950
 
2883
2951
  // src/react/ProduckChat.tsx
2884
- var import_react5 = require("react");
2952
+ var import_react6 = require("react");
2885
2953
 
2886
2954
  // src/react/hooks.ts
2887
2955
  var import_react3 = require("react");
@@ -3171,8 +3239,267 @@ function VisualFlowDisplay({
3171
3239
  ] });
3172
3240
  }
3173
3241
 
3174
- // src/react/ProduckChat.tsx
3242
+ // src/react/StepGuide.tsx
3243
+ var import_react5 = require("react");
3175
3244
  var import_jsx_runtime3 = require("react/jsx-runtime");
3245
+ function StepGuide({
3246
+ title,
3247
+ description,
3248
+ steps,
3249
+ theme = "light",
3250
+ primaryColor = "#f97316",
3251
+ onStepClick,
3252
+ hasReplay,
3253
+ onWatchReplay,
3254
+ compact = false
3255
+ }) {
3256
+ const [expandedStep, setExpandedStep] = (0, import_react5.useState)(null);
3257
+ const isDark = theme === "dark";
3258
+ const bgColor = isDark ? "#1f2937" : "#f9fafb";
3259
+ const borderColor = isDark ? "#374151" : "#e5e7eb";
3260
+ const textColor = isDark ? "#f3f4f6" : "#111827";
3261
+ const mutedColor = isDark ? "#9ca3af" : "#6b7280";
3262
+ const stepBgColor = isDark ? "#374151" : "#ffffff";
3263
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3264
+ "div",
3265
+ {
3266
+ style: {
3267
+ backgroundColor: compact ? "transparent" : bgColor,
3268
+ border: compact ? "none" : `1px solid ${borderColor}`,
3269
+ borderRadius: compact ? "0" : "12px",
3270
+ overflow: "hidden",
3271
+ marginTop: compact ? "0" : "12px"
3272
+ },
3273
+ children: [
3274
+ !compact && title && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3275
+ "div",
3276
+ {
3277
+ style: {
3278
+ padding: "12px 16px",
3279
+ borderBottom: `1px solid ${borderColor}`,
3280
+ backgroundColor: isDark ? "#111827" : "#ffffff"
3281
+ },
3282
+ children: [
3283
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
3284
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { fontSize: "18px" }, children: "\u{1F4CB}" }),
3285
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3286
+ "span",
3287
+ {
3288
+ style: {
3289
+ fontWeight: 600,
3290
+ fontSize: "14px",
3291
+ color: textColor
3292
+ },
3293
+ children: title
3294
+ }
3295
+ )
3296
+ ] }),
3297
+ description && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3298
+ "p",
3299
+ {
3300
+ style: {
3301
+ marginTop: "4px",
3302
+ fontSize: "12px",
3303
+ color: mutedColor,
3304
+ lineHeight: 1.4
3305
+ },
3306
+ children: description
3307
+ }
3308
+ )
3309
+ ]
3310
+ }
3311
+ ),
3312
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { padding: compact ? "0" : "12px" }, children: steps.map((step, index) => {
3313
+ const isLast = index === steps.length - 1;
3314
+ const isExpanded = expandedStep === index;
3315
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3316
+ "div",
3317
+ {
3318
+ style: {
3319
+ display: "flex",
3320
+ gap: "12px",
3321
+ cursor: onStepClick ? "pointer" : "default"
3322
+ },
3323
+ onClick: () => {
3324
+ if (onStepClick) {
3325
+ onStepClick(step, index);
3326
+ }
3327
+ setExpandedStep(isExpanded ? null : index);
3328
+ },
3329
+ children: [
3330
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3331
+ "div",
3332
+ {
3333
+ style: {
3334
+ display: "flex",
3335
+ flexDirection: "column",
3336
+ alignItems: "center",
3337
+ width: "24px"
3338
+ },
3339
+ children: [
3340
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3341
+ "div",
3342
+ {
3343
+ style: {
3344
+ width: "24px",
3345
+ height: "24px",
3346
+ borderRadius: "50%",
3347
+ backgroundColor: primaryColor,
3348
+ color: "#ffffff",
3349
+ display: "flex",
3350
+ alignItems: "center",
3351
+ justifyContent: "center",
3352
+ fontSize: "12px",
3353
+ fontWeight: 600,
3354
+ flexShrink: 0
3355
+ },
3356
+ children: step.stepNumber
3357
+ }
3358
+ ),
3359
+ !isLast && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3360
+ "div",
3361
+ {
3362
+ style: {
3363
+ width: "2px",
3364
+ flexGrow: 1,
3365
+ minHeight: "20px",
3366
+ backgroundColor: isDark ? "#4b5563" : "#d1d5db",
3367
+ marginTop: "4px"
3368
+ }
3369
+ }
3370
+ )
3371
+ ]
3372
+ }
3373
+ ),
3374
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3375
+ "div",
3376
+ {
3377
+ style: {
3378
+ flex: 1,
3379
+ paddingBottom: isLast ? 0 : "16px"
3380
+ },
3381
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3382
+ "div",
3383
+ {
3384
+ style: {
3385
+ backgroundColor: stepBgColor,
3386
+ border: `1px solid ${borderColor}`,
3387
+ borderRadius: "8px",
3388
+ padding: "10px 12px",
3389
+ transition: "all 0.2s ease"
3390
+ },
3391
+ children: [
3392
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3393
+ "div",
3394
+ {
3395
+ style: {
3396
+ fontSize: "13px",
3397
+ fontWeight: 500,
3398
+ color: textColor,
3399
+ lineHeight: 1.4
3400
+ },
3401
+ children: step.action
3402
+ }
3403
+ ),
3404
+ step.page && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3405
+ "div",
3406
+ {
3407
+ style: {
3408
+ marginTop: "4px",
3409
+ fontSize: "11px",
3410
+ color: mutedColor,
3411
+ display: "flex",
3412
+ alignItems: "center",
3413
+ gap: "4px"
3414
+ },
3415
+ children: [
3416
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u{1F4CD}" }),
3417
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: step.page })
3418
+ ]
3419
+ }
3420
+ ),
3421
+ isExpanded && step.details && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3422
+ "div",
3423
+ {
3424
+ style: {
3425
+ marginTop: "8px",
3426
+ paddingTop: "8px",
3427
+ borderTop: `1px solid ${borderColor}`,
3428
+ fontSize: "12px",
3429
+ color: mutedColor,
3430
+ lineHeight: 1.5
3431
+ },
3432
+ children: step.details
3433
+ }
3434
+ )
3435
+ ]
3436
+ }
3437
+ )
3438
+ }
3439
+ )
3440
+ ]
3441
+ },
3442
+ index
3443
+ );
3444
+ }) }),
3445
+ hasReplay && onWatchReplay && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3446
+ "div",
3447
+ {
3448
+ style: {
3449
+ padding: "12px 16px",
3450
+ borderTop: `1px solid ${borderColor}`,
3451
+ backgroundColor: isDark ? "#111827" : "#ffffff"
3452
+ },
3453
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3454
+ "button",
3455
+ {
3456
+ onClick: onWatchReplay,
3457
+ style: {
3458
+ display: "flex",
3459
+ alignItems: "center",
3460
+ justifyContent: "center",
3461
+ gap: "8px",
3462
+ width: "100%",
3463
+ padding: "10px 16px",
3464
+ backgroundColor: primaryColor,
3465
+ color: "#ffffff",
3466
+ border: "none",
3467
+ borderRadius: "8px",
3468
+ fontSize: "13px",
3469
+ fontWeight: 500,
3470
+ cursor: "pointer"
3471
+ },
3472
+ children: [
3473
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u25B6\uFE0F" }),
3474
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Watch Full Session Replay" })
3475
+ ]
3476
+ }
3477
+ )
3478
+ }
3479
+ )
3480
+ ]
3481
+ }
3482
+ );
3483
+ }
3484
+ function parseStepsFromStrings(steps) {
3485
+ return steps.map((stepStr, index) => {
3486
+ const stepMatch = stepStr.match(/^(?:Step\s+)?(\d+)[:.]\s*(.+?)(?:\s*\((?:on\s+)?(.+?)\))?$/i);
3487
+ if (stepMatch) {
3488
+ return {
3489
+ stepNumber: parseInt(stepMatch[1], 10),
3490
+ action: stepMatch[2].trim(),
3491
+ page: stepMatch[3]?.trim()
3492
+ };
3493
+ }
3494
+ return {
3495
+ stepNumber: index + 1,
3496
+ action: stepStr.replace(/^(?:Step\s+)?\d+[:.]\s*/i, "").trim()
3497
+ };
3498
+ });
3499
+ }
3500
+
3501
+ // src/react/ProduckChat.tsx
3502
+ var import_jsx_runtime4 = require("react/jsx-runtime");
3176
3503
  function ProduckChat({
3177
3504
  placeholder = "Ask a question...",
3178
3505
  title = "Chat Assistant",
@@ -3193,15 +3520,15 @@ function ProduckChat({
3193
3520
  }) {
3194
3521
  const { messages, isLoading, sendMessage } = useProduckMessages();
3195
3522
  const isReady = useProduckReady();
3196
- const [input, setInput] = (0, import_react5.useState)("");
3197
- const [isOpen, setIsOpen] = (0, import_react5.useState)(position === "inline" ? true : defaultOpen);
3198
- const [isHovering, setIsHovering] = (0, import_react5.useState)(false);
3199
- const messagesEndRef = (0, import_react5.useRef)(null);
3200
- const inputRef = (0, import_react5.useRef)(null);
3201
- const [streamedMessage, setStreamedMessage] = (0, import_react5.useState)("");
3202
- const [isStreamingInitial, setIsStreamingInitial] = (0, import_react5.useState)(false);
3203
- const [hasShownInitial, setHasShownInitial] = (0, import_react5.useState)(false);
3204
- (0, import_react5.useEffect)(() => {
3523
+ const [input, setInput] = (0, import_react6.useState)("");
3524
+ const [isOpen, setIsOpen] = (0, import_react6.useState)(position === "inline" ? true : defaultOpen);
3525
+ const [isHovering, setIsHovering] = (0, import_react6.useState)(false);
3526
+ const messagesEndRef = (0, import_react6.useRef)(null);
3527
+ const inputRef = (0, import_react6.useRef)(null);
3528
+ const [streamedMessage, setStreamedMessage] = (0, import_react6.useState)("");
3529
+ const [isStreamingInitial, setIsStreamingInitial] = (0, import_react6.useState)(false);
3530
+ const [hasShownInitial, setHasShownInitial] = (0, import_react6.useState)(false);
3531
+ (0, import_react6.useEffect)(() => {
3205
3532
  if (autoOpenDelay && autoOpenDelay > 0 && !isOpen && isReady) {
3206
3533
  const timer = setTimeout(() => {
3207
3534
  setIsOpen(true);
@@ -3209,7 +3536,7 @@ function ProduckChat({
3209
3536
  return () => clearTimeout(timer);
3210
3537
  }
3211
3538
  }, [autoOpenDelay, isReady]);
3212
- (0, import_react5.useEffect)(() => {
3539
+ (0, import_react6.useEffect)(() => {
3213
3540
  if (isOpen && initialMessage && isReady && !hasShownInitial) {
3214
3541
  const timer = setTimeout(() => {
3215
3542
  streamInitialMessage(initialMessage);
@@ -3230,12 +3557,12 @@ function ProduckChat({
3230
3557
  }
3231
3558
  setIsStreamingInitial(false);
3232
3559
  };
3233
- (0, import_react5.useEffect)(() => {
3560
+ (0, import_react6.useEffect)(() => {
3234
3561
  if (messagesEndRef.current) {
3235
3562
  messagesEndRef.current.scrollIntoView({ behavior: "smooth" });
3236
3563
  }
3237
3564
  }, [messages]);
3238
- (0, import_react5.useEffect)(() => {
3565
+ (0, import_react6.useEffect)(() => {
3239
3566
  if (isOpen && inputRef.current) {
3240
3567
  setTimeout(() => inputRef.current?.focus(), 100);
3241
3568
  }
@@ -3329,7 +3656,7 @@ function ProduckChat({
3329
3656
  backgroundColor: isDark ? "#111827" : "#f9fafb",
3330
3657
  flexShrink: 0
3331
3658
  };
3332
- const renderFloatingButton = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: containerStyles, className, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3659
+ const renderFloatingButton = () => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: containerStyles, className, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3333
3660
  "button",
3334
3661
  {
3335
3662
  onClick: () => setIsOpen(true),
@@ -3361,12 +3688,12 @@ function ProduckChat({
3361
3688
  return renderFloatingButton();
3362
3689
  }
3363
3690
  if (position === "inline" && !isReady) {
3364
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: containerStyles, className, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: chatWindowStyles, children: [
3365
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { ...headerStyles, justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
3366
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { animation: "spin 1s linear infinite" }, children: floatingButtonLoadingIcon }),
3691
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: containerStyles, className, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: chatWindowStyles, children: [
3692
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { ...headerStyles, justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
3693
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { animation: "spin 1s linear infinite" }, children: floatingButtonLoadingIcon }),
3367
3694
  "Loading..."
3368
3695
  ] }) }),
3369
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: {
3696
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: {
3370
3697
  flex: 1,
3371
3698
  display: "flex",
3372
3699
  alignItems: "center",
@@ -3375,14 +3702,14 @@ function ProduckChat({
3375
3702
  }, children: "Connecting to chat..." })
3376
3703
  ] }) });
3377
3704
  }
3378
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: containerStyles, className, children: [
3379
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: chatWindowStyles, children: [
3380
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: headerStyles, children: [
3381
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
3382
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: headerIcon }),
3383
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: title })
3705
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: containerStyles, className, children: [
3706
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: chatWindowStyles, children: [
3707
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: headerStyles, children: [
3708
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
3709
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: headerIcon }),
3710
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: title })
3384
3711
  ] }),
3385
- position !== "inline" && showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3712
+ position !== "inline" && showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3386
3713
  "button",
3387
3714
  {
3388
3715
  onClick: () => setIsOpen(false),
@@ -3404,15 +3731,15 @@ function ProduckChat({
3404
3731
  }
3405
3732
  )
3406
3733
  ] }),
3407
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: messagesContainerStyles, children: [
3408
- streamedMessage && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3734
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: messagesContainerStyles, children: [
3735
+ streamedMessage && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3409
3736
  "div",
3410
3737
  {
3411
3738
  style: {
3412
3739
  display: "flex",
3413
3740
  justifyContent: "flex-start"
3414
3741
  },
3415
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3742
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3416
3743
  "div",
3417
3744
  {
3418
3745
  style: {
@@ -3427,7 +3754,7 @@ function ProduckChat({
3427
3754
  },
3428
3755
  children: [
3429
3756
  streamedMessage,
3430
- isStreamingInitial && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3757
+ isStreamingInitial && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3431
3758
  "span",
3432
3759
  {
3433
3760
  style: {
@@ -3445,7 +3772,7 @@ function ProduckChat({
3445
3772
  )
3446
3773
  }
3447
3774
  ),
3448
- messages.length === 0 && !streamedMessage && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3775
+ messages.length === 0 && !streamedMessage && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3449
3776
  "div",
3450
3777
  {
3451
3778
  style: {
@@ -3454,20 +3781,20 @@ function ProduckChat({
3454
3781
  padding: "40px 20px"
3455
3782
  },
3456
3783
  children: [
3457
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: "40px", marginBottom: "16px" }, children: emptyStateIcon }),
3458
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: typeof fontSize === "number" ? `${fontSize + 2}px` : fontSize, fontWeight: 500 }, children: emptyStateTitle }),
3459
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { fontSize: typeof fontSize === "number" ? `${fontSize}px` : fontSize, marginTop: "8px", opacity: 0.8 }, children: emptyStateSubtitle })
3784
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: "40px", marginBottom: "16px" }, children: emptyStateIcon }),
3785
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: typeof fontSize === "number" ? `${fontSize + 2}px` : fontSize, fontWeight: 500 }, children: emptyStateTitle }),
3786
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: typeof fontSize === "number" ? `${fontSize}px` : fontSize, marginTop: "8px", opacity: 0.8 }, children: emptyStateSubtitle })
3460
3787
  ]
3461
3788
  }
3462
3789
  ),
3463
- messages.map((msg, idx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3790
+ messages.map((msg, idx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3464
3791
  "div",
3465
3792
  {
3466
3793
  style: {
3467
3794
  display: "flex",
3468
3795
  justifyContent: msg.role === "user" ? "flex-end" : "flex-start"
3469
3796
  },
3470
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3797
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3471
3798
  "div",
3472
3799
  {
3473
3800
  style: {
@@ -3482,7 +3809,7 @@ function ProduckChat({
3482
3809
  },
3483
3810
  children: [
3484
3811
  msg.content,
3485
- msg.action && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3812
+ msg.action && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3486
3813
  "div",
3487
3814
  {
3488
3815
  style: {
@@ -3496,15 +3823,15 @@ function ProduckChat({
3496
3823
  gap: "6px"
3497
3824
  },
3498
3825
  children: [
3499
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u26A1" }),
3500
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { children: [
3826
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u26A1" }),
3827
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { children: [
3501
3828
  "Action triggered: ",
3502
3829
  msg.action.name
3503
3830
  ] })
3504
3831
  ]
3505
3832
  }
3506
3833
  ),
3507
- msg.visualFlows && msg.visualFlows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { marginTop: "12px" }, children: msg.visualFlows.map((flowRef, flowIdx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3834
+ msg.visualFlows && msg.visualFlows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { marginTop: "12px" }, children: msg.visualFlows.map((flowRef, flowIdx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3508
3835
  VisualFlowDisplay,
3509
3836
  {
3510
3837
  flowRef,
@@ -3513,7 +3840,7 @@ function ProduckChat({
3513
3840
  },
3514
3841
  flowRef.flowId || flowIdx
3515
3842
  )) }),
3516
- msg.images && msg.images.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { marginTop: "12px" }, children: msg.images.map((img, imgIdx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3843
+ msg.images && msg.images.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { marginTop: "12px" }, children: msg.images.map((img, imgIdx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3517
3844
  "div",
3518
3845
  {
3519
3846
  style: {
@@ -3523,7 +3850,7 @@ function ProduckChat({
3523
3850
  border: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`
3524
3851
  },
3525
3852
  children: [
3526
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3853
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3527
3854
  "img",
3528
3855
  {
3529
3856
  src: img.url,
@@ -3535,7 +3862,7 @@ function ProduckChat({
3535
3862
  }
3536
3863
  }
3537
3864
  ),
3538
- img.name && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3865
+ img.name && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3539
3866
  "div",
3540
3867
  {
3541
3868
  style: {
@@ -3551,32 +3878,32 @@ function ProduckChat({
3551
3878
  },
3552
3879
  imgIdx
3553
3880
  )) }),
3554
- msg.userFlows && msg.userFlows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { marginTop: "12px" }, children: msg.userFlows.filter((uf) => uf.hasReplay).slice(0, 2).map((userFlow, ufIdx) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3881
+ msg.userFlows && msg.userFlows.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { marginTop: "12px" }, children: msg.userFlows.slice(0, 3).map((userFlow, ufIdx) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3555
3882
  "div",
3556
3883
  {
3557
3884
  style: {
3558
- marginTop: ufIdx > 0 ? "8px" : 0,
3885
+ marginTop: ufIdx > 0 ? "12px" : 0,
3559
3886
  padding: "12px",
3560
3887
  borderRadius: "8px",
3561
3888
  border: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`,
3562
3889
  backgroundColor: isDark ? "#1f2937" : "#f9fafb"
3563
3890
  },
3564
3891
  children: [
3565
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: {
3892
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: {
3566
3893
  display: "flex",
3567
3894
  alignItems: "center",
3568
3895
  justifyContent: "space-between",
3569
3896
  marginBottom: "8px"
3570
3897
  }, children: [
3571
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
3572
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: { fontSize: "16px" }, children: "\u{1F3AC}" }),
3573
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: {
3898
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
3899
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { fontSize: "16px" }, children: "\u{1F4CB}" }),
3900
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: {
3574
3901
  fontWeight: 600,
3575
- fontSize: "13px",
3902
+ fontSize: "14px",
3576
3903
  color: isDark ? "#f3f4f6" : "#111827"
3577
3904
  }, children: userFlow.title })
3578
3905
  ] }),
3579
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { style: {
3906
+ userFlow.eventCount && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { style: {
3580
3907
  fontSize: "11px",
3581
3908
  padding: "2px 6px",
3582
3909
  backgroundColor: primaryColor + "20",
@@ -3587,13 +3914,22 @@ function ProduckChat({
3587
3914
  " steps"
3588
3915
  ] })
3589
3916
  ] }),
3590
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { style: {
3917
+ userFlow.description && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { style: {
3591
3918
  fontSize: "12px",
3592
3919
  color: isDark ? "#9ca3af" : "#6b7280",
3593
- marginBottom: "10px",
3920
+ marginBottom: "12px",
3594
3921
  lineHeight: 1.4
3595
3922
  }, children: userFlow.description }),
3596
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3923
+ userFlow.steps && userFlow.steps.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3924
+ StepGuide,
3925
+ {
3926
+ steps: parseStepsFromStrings(userFlow.steps),
3927
+ theme,
3928
+ primaryColor,
3929
+ compact: true
3930
+ }
3931
+ ),
3932
+ userFlow.hasReplay && userFlow.recordingId && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3597
3933
  "button",
3598
3934
  {
3599
3935
  onClick: () => {
@@ -3605,6 +3941,7 @@ function ProduckChat({
3605
3941
  alignItems: "center",
3606
3942
  gap: "6px",
3607
3943
  padding: "8px 12px",
3944
+ marginTop: userFlow.steps && userFlow.steps.length > 0 ? "12px" : "8px",
3608
3945
  backgroundColor: primaryColor,
3609
3946
  color: "#fff",
3610
3947
  border: "none",
@@ -3616,8 +3953,8 @@ function ProduckChat({
3616
3953
  justifyContent: "center"
3617
3954
  },
3618
3955
  children: [
3619
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "\u25B6\uFE0F" }),
3620
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: "Watch Session Replay" })
3956
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "\u25B6\uFE0F" }),
3957
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Watch Session Replay" })
3621
3958
  ]
3622
3959
  }
3623
3960
  )
@@ -3631,7 +3968,7 @@ function ProduckChat({
3631
3968
  },
3632
3969
  idx
3633
3970
  )),
3634
- isLoading && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: { display: "flex", justifyContent: "flex-start" }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3971
+ isLoading && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", justifyContent: "flex-start" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3635
3972
  "div",
3636
3973
  {
3637
3974
  style: {
@@ -3641,16 +3978,16 @@ function ProduckChat({
3641
3978
  color: isDark ? "#9ca3af" : "#6b7280",
3642
3979
  fontSize: typeof fontSize === "number" ? `${fontSize}px` : fontSize
3643
3980
  },
3644
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { style: {
3981
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: {
3645
3982
  display: "inline-block",
3646
3983
  animation: "pulse 1.5s ease-in-out infinite"
3647
3984
  }, children: "Thinking..." })
3648
3985
  }
3649
3986
  ) }),
3650
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: messagesEndRef })
3987
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref: messagesEndRef })
3651
3988
  ] }),
3652
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("form", { onSubmit: handleSubmit, style: inputContainerStyles, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { style: { display: "flex", gap: "10px", alignItems: "center" }, children: [
3653
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3989
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("form", { onSubmit: handleSubmit, style: inputContainerStyles, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", gap: "10px", alignItems: "center" }, children: [
3990
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3654
3991
  "input",
3655
3992
  {
3656
3993
  ref: inputRef,
@@ -3681,7 +4018,7 @@ function ProduckChat({
3681
4018
  }
3682
4019
  }
3683
4020
  ),
3684
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
4021
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3685
4022
  "button",
3686
4023
  {
3687
4024
  type: "submit",
@@ -3713,13 +4050,13 @@ function ProduckChat({
3713
4050
  e.currentTarget.style.boxShadow = "none";
3714
4051
  },
3715
4052
  children: [
3716
- sendButtonIcon && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: sendButtonIcon }),
4053
+ sendButtonIcon && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: sendButtonIcon }),
3717
4054
  sendButtonText
3718
4055
  ]
3719
4056
  }
3720
4057
  )
3721
4058
  ] }) }),
3722
- showPoweredBy && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4059
+ showPoweredBy && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3723
4060
  "div",
3724
4061
  {
3725
4062
  style: {
@@ -3727,7 +4064,7 @@ function ProduckChat({
3727
4064
  textAlign: "center",
3728
4065
  borderTop: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`
3729
4066
  },
3730
- children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
4067
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3731
4068
  "a",
3732
4069
  {
3733
4070
  href: poweredByUrl,
@@ -3751,7 +4088,7 @@ function ProduckChat({
3751
4088
  }
3752
4089
  )
3753
4090
  ] }),
3754
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("style", { children: `
4091
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("style", { children: `
3755
4092
  @keyframes pulse {
3756
4093
  0%, 100% { opacity: 1; }
3757
4094
  50% { opacity: 0.5; }
@@ -3765,8 +4102,8 @@ function ProduckChat({
3765
4102
  }
3766
4103
 
3767
4104
  // src/react/ProduckTarget.tsx
3768
- var import_react6 = __toESM(require("react"));
3769
- var import_jsx_runtime4 = require("react/jsx-runtime");
4105
+ var import_react7 = __toESM(require("react"));
4106
+ var import_jsx_runtime5 = require("react/jsx-runtime");
3770
4107
  function ProduckTarget({
3771
4108
  actionKey,
3772
4109
  children,
@@ -3780,8 +4117,8 @@ function ProduckTarget({
3780
4117
  highlightDuration = 3e3,
3781
4118
  scrollIntoView = true
3782
4119
  }) {
3783
- const ref = (0, import_react6.useRef)(null);
3784
- const [isHighlighted, setIsHighlighted] = import_react6.default.useState(false);
4120
+ const ref = (0, import_react7.useRef)(null);
4121
+ const [isHighlighted, setIsHighlighted] = import_react7.default.useState(false);
3785
4122
  useProduckAction(
3786
4123
  actionKey,
3787
4124
  (payload) => {
@@ -3797,7 +4134,7 @@ function ProduckTarget({
3797
4134
  },
3798
4135
  [scrollIntoView, highlightDuration, onTrigger]
3799
4136
  );
3800
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
4137
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3801
4138
  "div",
3802
4139
  {
3803
4140
  ref,