@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.mjs CHANGED
@@ -1203,7 +1203,7 @@ var UserFlowTracker = class {
1203
1203
  samplingRate: this.config.samplingRate,
1204
1204
  currentState: this.state,
1205
1205
  apiUrl: this.apiUrl,
1206
- hasSessionToken: !!this.sessionToken
1206
+ hasSessionToken: !!this.sdkSessionToken
1207
1207
  });
1208
1208
  if (!this.config.enabled) {
1209
1209
  console.warn("[UserFlow] Tracking disabled by config");
@@ -1329,6 +1329,57 @@ var UserFlowTracker = class {
1329
1329
  isTracking() {
1330
1330
  return this.state === "tracking";
1331
1331
  }
1332
+ /**
1333
+ * Get recent events for context (excludes SDK UI interactions like chat widget)
1334
+ * @param limit - Maximum number of events to return (default: 10)
1335
+ * @param excludeSelectors - CSS selectors to exclude (default: produck SDK elements)
1336
+ */
1337
+ getRecentEvents(limit = 10, excludeSelectors) {
1338
+ const defaultExcludeSelectors = [
1339
+ "[data-produck-chat]",
1340
+ ".produck-chat",
1341
+ ".produck-widget",
1342
+ "#produck-chat",
1343
+ "#produck-widget",
1344
+ '[class*="produck"]',
1345
+ '[id*="produck"]'
1346
+ ];
1347
+ const selectorsToExclude = excludeSelectors || defaultExcludeSelectors;
1348
+ const filteredEvents = this.events.filter((event) => {
1349
+ if (event.eventType === "navigation") return true;
1350
+ if (event.element?.selector) {
1351
+ const selectorLower = event.element.selector.toLowerCase();
1352
+ const matchesExclude = selectorsToExclude.some((excludeSel) => {
1353
+ const excludeLower = excludeSel.toLowerCase();
1354
+ if (excludeLower.includes("produck")) {
1355
+ return selectorLower.includes("produck");
1356
+ }
1357
+ return selectorLower.includes(excludeLower.replace(/[\[\].*#]/g, ""));
1358
+ });
1359
+ if (matchesExclude) return false;
1360
+ }
1361
+ return true;
1362
+ });
1363
+ return filteredEvents.slice(-limit);
1364
+ }
1365
+ /**
1366
+ * Get recent events as a summary string for chat context
1367
+ */
1368
+ getRecentEventsAsSummary(limit = 10) {
1369
+ const events = this.getRecentEvents(limit);
1370
+ if (events.length === 0) return "";
1371
+ return events.map((event) => {
1372
+ if (event.eventType === "navigation") {
1373
+ return `Navigated to: ${event.pageTitle || event.pagePath}`;
1374
+ } else if (event.eventType === "click" && event.element) {
1375
+ const elementDesc = event.element.text || event.element.tag || "element";
1376
+ return `Clicked: ${elementDesc}${event.pageTitle ? ` on ${event.pageTitle}` : ""}`;
1377
+ } else if (event.eventType === "form_submit") {
1378
+ return `Submitted form on: ${event.pageTitle || event.pagePath}`;
1379
+ }
1380
+ return `${event.eventType}: ${event.pageTitle || event.pagePath}`;
1381
+ }).join("\n");
1382
+ }
1332
1383
  /**
1333
1384
  * Add a custom event
1334
1385
  */
@@ -1971,12 +2022,16 @@ Check the Network tab in DevTools for more details.`
1971
2022
  });
1972
2023
  }
1973
2024
  }
2025
+ const userContext = this.getRecentUserFlowSummary(10);
1974
2026
  const sessionResponse = await fetch(
1975
2027
  `${this.config.apiUrl}/chat/sessions/${this.sessionToken}/message`,
1976
2028
  {
1977
2029
  method: "POST",
1978
2030
  headers: { "Content-Type": "application/json" },
1979
- body: JSON.stringify({ message })
2031
+ body: JSON.stringify({
2032
+ message,
2033
+ userContext: userContext || void 0
2034
+ })
1980
2035
  }
1981
2036
  );
1982
2037
  if (!sessionResponse.ok) {
@@ -2667,6 +2722,19 @@ Check the Network tab in DevTools for more details.`
2667
2722
  getUserFlowStats() {
2668
2723
  return this.userFlowTracker?.getStats() ?? null;
2669
2724
  }
2725
+ /**
2726
+ * Get recent user flow events (excluding SDK UI interactions)
2727
+ * Useful for providing context to chat
2728
+ */
2729
+ getRecentUserFlowEvents(limit = 10) {
2730
+ return this.userFlowTracker?.getRecentEvents(limit) ?? [];
2731
+ }
2732
+ /**
2733
+ * Get recent user flow events as a summary string for chat context
2734
+ */
2735
+ getRecentUserFlowSummary(limit = 10) {
2736
+ return this.userFlowTracker?.getRecentEventsAsSummary(limit) ?? "";
2737
+ }
2670
2738
  /**
2671
2739
  * Check if user flow tracking is active
2672
2740
  */
@@ -2837,7 +2905,7 @@ function ProduckProvider({
2837
2905
  }
2838
2906
 
2839
2907
  // src/react/ProduckChat.tsx
2840
- import { useState as useState3, useRef as useRef2, useEffect as useEffect4 } from "react";
2908
+ import { useState as useState4, useRef as useRef2, useEffect as useEffect4 } from "react";
2841
2909
 
2842
2910
  // src/react/hooks.ts
2843
2911
  import { useEffect as useEffect2, useCallback as useCallback2 } from "react";
@@ -3127,8 +3195,267 @@ function VisualFlowDisplay({
3127
3195
  ] });
3128
3196
  }
3129
3197
 
3130
- // src/react/ProduckChat.tsx
3198
+ // src/react/StepGuide.tsx
3199
+ import { useState as useState3 } from "react";
3131
3200
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
3201
+ function StepGuide({
3202
+ title,
3203
+ description,
3204
+ steps,
3205
+ theme = "light",
3206
+ primaryColor = "#f97316",
3207
+ onStepClick,
3208
+ hasReplay,
3209
+ onWatchReplay,
3210
+ compact = false
3211
+ }) {
3212
+ const [expandedStep, setExpandedStep] = useState3(null);
3213
+ const isDark = theme === "dark";
3214
+ const bgColor = isDark ? "#1f2937" : "#f9fafb";
3215
+ const borderColor = isDark ? "#374151" : "#e5e7eb";
3216
+ const textColor = isDark ? "#f3f4f6" : "#111827";
3217
+ const mutedColor = isDark ? "#9ca3af" : "#6b7280";
3218
+ const stepBgColor = isDark ? "#374151" : "#ffffff";
3219
+ return /* @__PURE__ */ jsxs2(
3220
+ "div",
3221
+ {
3222
+ style: {
3223
+ backgroundColor: compact ? "transparent" : bgColor,
3224
+ border: compact ? "none" : `1px solid ${borderColor}`,
3225
+ borderRadius: compact ? "0" : "12px",
3226
+ overflow: "hidden",
3227
+ marginTop: compact ? "0" : "12px"
3228
+ },
3229
+ children: [
3230
+ !compact && title && /* @__PURE__ */ jsxs2(
3231
+ "div",
3232
+ {
3233
+ style: {
3234
+ padding: "12px 16px",
3235
+ borderBottom: `1px solid ${borderColor}`,
3236
+ backgroundColor: isDark ? "#111827" : "#ffffff"
3237
+ },
3238
+ children: [
3239
+ /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
3240
+ /* @__PURE__ */ jsx3("span", { style: { fontSize: "18px" }, children: "\u{1F4CB}" }),
3241
+ /* @__PURE__ */ jsx3(
3242
+ "span",
3243
+ {
3244
+ style: {
3245
+ fontWeight: 600,
3246
+ fontSize: "14px",
3247
+ color: textColor
3248
+ },
3249
+ children: title
3250
+ }
3251
+ )
3252
+ ] }),
3253
+ description && /* @__PURE__ */ jsx3(
3254
+ "p",
3255
+ {
3256
+ style: {
3257
+ marginTop: "4px",
3258
+ fontSize: "12px",
3259
+ color: mutedColor,
3260
+ lineHeight: 1.4
3261
+ },
3262
+ children: description
3263
+ }
3264
+ )
3265
+ ]
3266
+ }
3267
+ ),
3268
+ /* @__PURE__ */ jsx3("div", { style: { padding: compact ? "0" : "12px" }, children: steps.map((step, index) => {
3269
+ const isLast = index === steps.length - 1;
3270
+ const isExpanded = expandedStep === index;
3271
+ return /* @__PURE__ */ jsxs2(
3272
+ "div",
3273
+ {
3274
+ style: {
3275
+ display: "flex",
3276
+ gap: "12px",
3277
+ cursor: onStepClick ? "pointer" : "default"
3278
+ },
3279
+ onClick: () => {
3280
+ if (onStepClick) {
3281
+ onStepClick(step, index);
3282
+ }
3283
+ setExpandedStep(isExpanded ? null : index);
3284
+ },
3285
+ children: [
3286
+ /* @__PURE__ */ jsxs2(
3287
+ "div",
3288
+ {
3289
+ style: {
3290
+ display: "flex",
3291
+ flexDirection: "column",
3292
+ alignItems: "center",
3293
+ width: "24px"
3294
+ },
3295
+ children: [
3296
+ /* @__PURE__ */ jsx3(
3297
+ "div",
3298
+ {
3299
+ style: {
3300
+ width: "24px",
3301
+ height: "24px",
3302
+ borderRadius: "50%",
3303
+ backgroundColor: primaryColor,
3304
+ color: "#ffffff",
3305
+ display: "flex",
3306
+ alignItems: "center",
3307
+ justifyContent: "center",
3308
+ fontSize: "12px",
3309
+ fontWeight: 600,
3310
+ flexShrink: 0
3311
+ },
3312
+ children: step.stepNumber
3313
+ }
3314
+ ),
3315
+ !isLast && /* @__PURE__ */ jsx3(
3316
+ "div",
3317
+ {
3318
+ style: {
3319
+ width: "2px",
3320
+ flexGrow: 1,
3321
+ minHeight: "20px",
3322
+ backgroundColor: isDark ? "#4b5563" : "#d1d5db",
3323
+ marginTop: "4px"
3324
+ }
3325
+ }
3326
+ )
3327
+ ]
3328
+ }
3329
+ ),
3330
+ /* @__PURE__ */ jsx3(
3331
+ "div",
3332
+ {
3333
+ style: {
3334
+ flex: 1,
3335
+ paddingBottom: isLast ? 0 : "16px"
3336
+ },
3337
+ children: /* @__PURE__ */ jsxs2(
3338
+ "div",
3339
+ {
3340
+ style: {
3341
+ backgroundColor: stepBgColor,
3342
+ border: `1px solid ${borderColor}`,
3343
+ borderRadius: "8px",
3344
+ padding: "10px 12px",
3345
+ transition: "all 0.2s ease"
3346
+ },
3347
+ children: [
3348
+ /* @__PURE__ */ jsx3(
3349
+ "div",
3350
+ {
3351
+ style: {
3352
+ fontSize: "13px",
3353
+ fontWeight: 500,
3354
+ color: textColor,
3355
+ lineHeight: 1.4
3356
+ },
3357
+ children: step.action
3358
+ }
3359
+ ),
3360
+ step.page && /* @__PURE__ */ jsxs2(
3361
+ "div",
3362
+ {
3363
+ style: {
3364
+ marginTop: "4px",
3365
+ fontSize: "11px",
3366
+ color: mutedColor,
3367
+ display: "flex",
3368
+ alignItems: "center",
3369
+ gap: "4px"
3370
+ },
3371
+ children: [
3372
+ /* @__PURE__ */ jsx3("span", { children: "\u{1F4CD}" }),
3373
+ /* @__PURE__ */ jsx3("span", { children: step.page })
3374
+ ]
3375
+ }
3376
+ ),
3377
+ isExpanded && step.details && /* @__PURE__ */ jsx3(
3378
+ "div",
3379
+ {
3380
+ style: {
3381
+ marginTop: "8px",
3382
+ paddingTop: "8px",
3383
+ borderTop: `1px solid ${borderColor}`,
3384
+ fontSize: "12px",
3385
+ color: mutedColor,
3386
+ lineHeight: 1.5
3387
+ },
3388
+ children: step.details
3389
+ }
3390
+ )
3391
+ ]
3392
+ }
3393
+ )
3394
+ }
3395
+ )
3396
+ ]
3397
+ },
3398
+ index
3399
+ );
3400
+ }) }),
3401
+ hasReplay && onWatchReplay && /* @__PURE__ */ jsx3(
3402
+ "div",
3403
+ {
3404
+ style: {
3405
+ padding: "12px 16px",
3406
+ borderTop: `1px solid ${borderColor}`,
3407
+ backgroundColor: isDark ? "#111827" : "#ffffff"
3408
+ },
3409
+ children: /* @__PURE__ */ jsxs2(
3410
+ "button",
3411
+ {
3412
+ onClick: onWatchReplay,
3413
+ style: {
3414
+ display: "flex",
3415
+ alignItems: "center",
3416
+ justifyContent: "center",
3417
+ gap: "8px",
3418
+ width: "100%",
3419
+ padding: "10px 16px",
3420
+ backgroundColor: primaryColor,
3421
+ color: "#ffffff",
3422
+ border: "none",
3423
+ borderRadius: "8px",
3424
+ fontSize: "13px",
3425
+ fontWeight: 500,
3426
+ cursor: "pointer"
3427
+ },
3428
+ children: [
3429
+ /* @__PURE__ */ jsx3("span", { children: "\u25B6\uFE0F" }),
3430
+ /* @__PURE__ */ jsx3("span", { children: "Watch Full Session Replay" })
3431
+ ]
3432
+ }
3433
+ )
3434
+ }
3435
+ )
3436
+ ]
3437
+ }
3438
+ );
3439
+ }
3440
+ function parseStepsFromStrings(steps) {
3441
+ return steps.map((stepStr, index) => {
3442
+ const stepMatch = stepStr.match(/^(?:Step\s+)?(\d+)[:.]\s*(.+?)(?:\s*\((?:on\s+)?(.+?)\))?$/i);
3443
+ if (stepMatch) {
3444
+ return {
3445
+ stepNumber: parseInt(stepMatch[1], 10),
3446
+ action: stepMatch[2].trim(),
3447
+ page: stepMatch[3]?.trim()
3448
+ };
3449
+ }
3450
+ return {
3451
+ stepNumber: index + 1,
3452
+ action: stepStr.replace(/^(?:Step\s+)?\d+[:.]\s*/i, "").trim()
3453
+ };
3454
+ });
3455
+ }
3456
+
3457
+ // src/react/ProduckChat.tsx
3458
+ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
3132
3459
  function ProduckChat({
3133
3460
  placeholder = "Ask a question...",
3134
3461
  title = "Chat Assistant",
@@ -3149,14 +3476,14 @@ function ProduckChat({
3149
3476
  }) {
3150
3477
  const { messages, isLoading, sendMessage } = useProduckMessages();
3151
3478
  const isReady = useProduckReady();
3152
- const [input, setInput] = useState3("");
3153
- const [isOpen, setIsOpen] = useState3(position === "inline" ? true : defaultOpen);
3154
- const [isHovering, setIsHovering] = useState3(false);
3479
+ const [input, setInput] = useState4("");
3480
+ const [isOpen, setIsOpen] = useState4(position === "inline" ? true : defaultOpen);
3481
+ const [isHovering, setIsHovering] = useState4(false);
3155
3482
  const messagesEndRef = useRef2(null);
3156
3483
  const inputRef = useRef2(null);
3157
- const [streamedMessage, setStreamedMessage] = useState3("");
3158
- const [isStreamingInitial, setIsStreamingInitial] = useState3(false);
3159
- const [hasShownInitial, setHasShownInitial] = useState3(false);
3484
+ const [streamedMessage, setStreamedMessage] = useState4("");
3485
+ const [isStreamingInitial, setIsStreamingInitial] = useState4(false);
3486
+ const [hasShownInitial, setHasShownInitial] = useState4(false);
3160
3487
  useEffect4(() => {
3161
3488
  if (autoOpenDelay && autoOpenDelay > 0 && !isOpen && isReady) {
3162
3489
  const timer = setTimeout(() => {
@@ -3285,7 +3612,7 @@ function ProduckChat({
3285
3612
  backgroundColor: isDark ? "#111827" : "#f9fafb",
3286
3613
  flexShrink: 0
3287
3614
  };
3288
- const renderFloatingButton = () => /* @__PURE__ */ jsx3("div", { style: containerStyles, className, children: /* @__PURE__ */ jsx3(
3615
+ const renderFloatingButton = () => /* @__PURE__ */ jsx4("div", { style: containerStyles, className, children: /* @__PURE__ */ jsx4(
3289
3616
  "button",
3290
3617
  {
3291
3618
  onClick: () => setIsOpen(true),
@@ -3317,12 +3644,12 @@ function ProduckChat({
3317
3644
  return renderFloatingButton();
3318
3645
  }
3319
3646
  if (position === "inline" && !isReady) {
3320
- return /* @__PURE__ */ jsx3("div", { style: containerStyles, className, children: /* @__PURE__ */ jsxs2("div", { style: chatWindowStyles, children: [
3321
- /* @__PURE__ */ jsx3("div", { style: { ...headerStyles, justifyContent: "center" }, children: /* @__PURE__ */ jsxs2("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
3322
- /* @__PURE__ */ jsx3("span", { style: { animation: "spin 1s linear infinite" }, children: floatingButtonLoadingIcon }),
3647
+ return /* @__PURE__ */ jsx4("div", { style: containerStyles, className, children: /* @__PURE__ */ jsxs3("div", { style: chatWindowStyles, children: [
3648
+ /* @__PURE__ */ jsx4("div", { style: { ...headerStyles, justifyContent: "center" }, children: /* @__PURE__ */ jsxs3("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
3649
+ /* @__PURE__ */ jsx4("span", { style: { animation: "spin 1s linear infinite" }, children: floatingButtonLoadingIcon }),
3323
3650
  "Loading..."
3324
3651
  ] }) }),
3325
- /* @__PURE__ */ jsx3("div", { style: {
3652
+ /* @__PURE__ */ jsx4("div", { style: {
3326
3653
  flex: 1,
3327
3654
  display: "flex",
3328
3655
  alignItems: "center",
@@ -3331,14 +3658,14 @@ function ProduckChat({
3331
3658
  }, children: "Connecting to chat..." })
3332
3659
  ] }) });
3333
3660
  }
3334
- return /* @__PURE__ */ jsxs2("div", { style: containerStyles, className, children: [
3335
- /* @__PURE__ */ jsxs2("div", { style: chatWindowStyles, children: [
3336
- /* @__PURE__ */ jsxs2("div", { style: headerStyles, children: [
3337
- /* @__PURE__ */ jsxs2("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
3338
- /* @__PURE__ */ jsx3("span", { children: headerIcon }),
3339
- /* @__PURE__ */ jsx3("span", { children: title })
3661
+ return /* @__PURE__ */ jsxs3("div", { style: containerStyles, className, children: [
3662
+ /* @__PURE__ */ jsxs3("div", { style: chatWindowStyles, children: [
3663
+ /* @__PURE__ */ jsxs3("div", { style: headerStyles, children: [
3664
+ /* @__PURE__ */ jsxs3("span", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
3665
+ /* @__PURE__ */ jsx4("span", { children: headerIcon }),
3666
+ /* @__PURE__ */ jsx4("span", { children: title })
3340
3667
  ] }),
3341
- position !== "inline" && showCloseButton && /* @__PURE__ */ jsx3(
3668
+ position !== "inline" && showCloseButton && /* @__PURE__ */ jsx4(
3342
3669
  "button",
3343
3670
  {
3344
3671
  onClick: () => setIsOpen(false),
@@ -3360,15 +3687,15 @@ function ProduckChat({
3360
3687
  }
3361
3688
  )
3362
3689
  ] }),
3363
- /* @__PURE__ */ jsxs2("div", { style: messagesContainerStyles, children: [
3364
- streamedMessage && /* @__PURE__ */ jsx3(
3690
+ /* @__PURE__ */ jsxs3("div", { style: messagesContainerStyles, children: [
3691
+ streamedMessage && /* @__PURE__ */ jsx4(
3365
3692
  "div",
3366
3693
  {
3367
3694
  style: {
3368
3695
  display: "flex",
3369
3696
  justifyContent: "flex-start"
3370
3697
  },
3371
- children: /* @__PURE__ */ jsxs2(
3698
+ children: /* @__PURE__ */ jsxs3(
3372
3699
  "div",
3373
3700
  {
3374
3701
  style: {
@@ -3383,7 +3710,7 @@ function ProduckChat({
3383
3710
  },
3384
3711
  children: [
3385
3712
  streamedMessage,
3386
- isStreamingInitial && /* @__PURE__ */ jsx3(
3713
+ isStreamingInitial && /* @__PURE__ */ jsx4(
3387
3714
  "span",
3388
3715
  {
3389
3716
  style: {
@@ -3401,7 +3728,7 @@ function ProduckChat({
3401
3728
  )
3402
3729
  }
3403
3730
  ),
3404
- messages.length === 0 && !streamedMessage && /* @__PURE__ */ jsxs2(
3731
+ messages.length === 0 && !streamedMessage && /* @__PURE__ */ jsxs3(
3405
3732
  "div",
3406
3733
  {
3407
3734
  style: {
@@ -3410,20 +3737,20 @@ function ProduckChat({
3410
3737
  padding: "40px 20px"
3411
3738
  },
3412
3739
  children: [
3413
- /* @__PURE__ */ jsx3("div", { style: { fontSize: "40px", marginBottom: "16px" }, children: emptyStateIcon }),
3414
- /* @__PURE__ */ jsx3("div", { style: { fontSize: typeof fontSize === "number" ? `${fontSize + 2}px` : fontSize, fontWeight: 500 }, children: emptyStateTitle }),
3415
- /* @__PURE__ */ jsx3("div", { style: { fontSize: typeof fontSize === "number" ? `${fontSize}px` : fontSize, marginTop: "8px", opacity: 0.8 }, children: emptyStateSubtitle })
3740
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: "40px", marginBottom: "16px" }, children: emptyStateIcon }),
3741
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: typeof fontSize === "number" ? `${fontSize + 2}px` : fontSize, fontWeight: 500 }, children: emptyStateTitle }),
3742
+ /* @__PURE__ */ jsx4("div", { style: { fontSize: typeof fontSize === "number" ? `${fontSize}px` : fontSize, marginTop: "8px", opacity: 0.8 }, children: emptyStateSubtitle })
3416
3743
  ]
3417
3744
  }
3418
3745
  ),
3419
- messages.map((msg, idx) => /* @__PURE__ */ jsx3(
3746
+ messages.map((msg, idx) => /* @__PURE__ */ jsx4(
3420
3747
  "div",
3421
3748
  {
3422
3749
  style: {
3423
3750
  display: "flex",
3424
3751
  justifyContent: msg.role === "user" ? "flex-end" : "flex-start"
3425
3752
  },
3426
- children: /* @__PURE__ */ jsxs2(
3753
+ children: /* @__PURE__ */ jsxs3(
3427
3754
  "div",
3428
3755
  {
3429
3756
  style: {
@@ -3438,7 +3765,7 @@ function ProduckChat({
3438
3765
  },
3439
3766
  children: [
3440
3767
  msg.content,
3441
- msg.action && /* @__PURE__ */ jsxs2(
3768
+ msg.action && /* @__PURE__ */ jsxs3(
3442
3769
  "div",
3443
3770
  {
3444
3771
  style: {
@@ -3452,15 +3779,15 @@ function ProduckChat({
3452
3779
  gap: "6px"
3453
3780
  },
3454
3781
  children: [
3455
- /* @__PURE__ */ jsx3("span", { children: "\u26A1" }),
3456
- /* @__PURE__ */ jsxs2("span", { children: [
3782
+ /* @__PURE__ */ jsx4("span", { children: "\u26A1" }),
3783
+ /* @__PURE__ */ jsxs3("span", { children: [
3457
3784
  "Action triggered: ",
3458
3785
  msg.action.name
3459
3786
  ] })
3460
3787
  ]
3461
3788
  }
3462
3789
  ),
3463
- msg.visualFlows && msg.visualFlows.length > 0 && /* @__PURE__ */ jsx3("div", { style: { marginTop: "12px" }, children: msg.visualFlows.map((flowRef, flowIdx) => /* @__PURE__ */ jsx3(
3790
+ msg.visualFlows && msg.visualFlows.length > 0 && /* @__PURE__ */ jsx4("div", { style: { marginTop: "12px" }, children: msg.visualFlows.map((flowRef, flowIdx) => /* @__PURE__ */ jsx4(
3464
3791
  VisualFlowDisplay,
3465
3792
  {
3466
3793
  flowRef,
@@ -3469,7 +3796,7 @@ function ProduckChat({
3469
3796
  },
3470
3797
  flowRef.flowId || flowIdx
3471
3798
  )) }),
3472
- msg.images && msg.images.length > 0 && /* @__PURE__ */ jsx3("div", { style: { marginTop: "12px" }, children: msg.images.map((img, imgIdx) => /* @__PURE__ */ jsxs2(
3799
+ msg.images && msg.images.length > 0 && /* @__PURE__ */ jsx4("div", { style: { marginTop: "12px" }, children: msg.images.map((img, imgIdx) => /* @__PURE__ */ jsxs3(
3473
3800
  "div",
3474
3801
  {
3475
3802
  style: {
@@ -3479,7 +3806,7 @@ function ProduckChat({
3479
3806
  border: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`
3480
3807
  },
3481
3808
  children: [
3482
- /* @__PURE__ */ jsx3(
3809
+ /* @__PURE__ */ jsx4(
3483
3810
  "img",
3484
3811
  {
3485
3812
  src: img.url,
@@ -3491,7 +3818,7 @@ function ProduckChat({
3491
3818
  }
3492
3819
  }
3493
3820
  ),
3494
- img.name && /* @__PURE__ */ jsx3(
3821
+ img.name && /* @__PURE__ */ jsx4(
3495
3822
  "div",
3496
3823
  {
3497
3824
  style: {
@@ -3507,32 +3834,32 @@ function ProduckChat({
3507
3834
  },
3508
3835
  imgIdx
3509
3836
  )) }),
3510
- msg.userFlows && msg.userFlows.length > 0 && /* @__PURE__ */ jsx3("div", { style: { marginTop: "12px" }, children: msg.userFlows.filter((uf) => uf.hasReplay).slice(0, 2).map((userFlow, ufIdx) => /* @__PURE__ */ jsxs2(
3837
+ msg.userFlows && msg.userFlows.length > 0 && /* @__PURE__ */ jsx4("div", { style: { marginTop: "12px" }, children: msg.userFlows.slice(0, 3).map((userFlow, ufIdx) => /* @__PURE__ */ jsxs3(
3511
3838
  "div",
3512
3839
  {
3513
3840
  style: {
3514
- marginTop: ufIdx > 0 ? "8px" : 0,
3841
+ marginTop: ufIdx > 0 ? "12px" : 0,
3515
3842
  padding: "12px",
3516
3843
  borderRadius: "8px",
3517
3844
  border: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`,
3518
3845
  backgroundColor: isDark ? "#1f2937" : "#f9fafb"
3519
3846
  },
3520
3847
  children: [
3521
- /* @__PURE__ */ jsxs2("div", { style: {
3848
+ /* @__PURE__ */ jsxs3("div", { style: {
3522
3849
  display: "flex",
3523
3850
  alignItems: "center",
3524
3851
  justifyContent: "space-between",
3525
3852
  marginBottom: "8px"
3526
3853
  }, children: [
3527
- /* @__PURE__ */ jsxs2("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
3528
- /* @__PURE__ */ jsx3("span", { style: { fontSize: "16px" }, children: "\u{1F3AC}" }),
3529
- /* @__PURE__ */ jsx3("span", { style: {
3854
+ /* @__PURE__ */ jsxs3("div", { style: { display: "flex", alignItems: "center", gap: "8px" }, children: [
3855
+ /* @__PURE__ */ jsx4("span", { style: { fontSize: "16px" }, children: "\u{1F4CB}" }),
3856
+ /* @__PURE__ */ jsx4("span", { style: {
3530
3857
  fontWeight: 600,
3531
- fontSize: "13px",
3858
+ fontSize: "14px",
3532
3859
  color: isDark ? "#f3f4f6" : "#111827"
3533
3860
  }, children: userFlow.title })
3534
3861
  ] }),
3535
- /* @__PURE__ */ jsxs2("span", { style: {
3862
+ userFlow.eventCount && /* @__PURE__ */ jsxs3("span", { style: {
3536
3863
  fontSize: "11px",
3537
3864
  padding: "2px 6px",
3538
3865
  backgroundColor: primaryColor + "20",
@@ -3543,13 +3870,22 @@ function ProduckChat({
3543
3870
  " steps"
3544
3871
  ] })
3545
3872
  ] }),
3546
- /* @__PURE__ */ jsx3("p", { style: {
3873
+ userFlow.description && /* @__PURE__ */ jsx4("p", { style: {
3547
3874
  fontSize: "12px",
3548
3875
  color: isDark ? "#9ca3af" : "#6b7280",
3549
- marginBottom: "10px",
3876
+ marginBottom: "12px",
3550
3877
  lineHeight: 1.4
3551
3878
  }, children: userFlow.description }),
3552
- /* @__PURE__ */ jsxs2(
3879
+ userFlow.steps && userFlow.steps.length > 0 && /* @__PURE__ */ jsx4(
3880
+ StepGuide,
3881
+ {
3882
+ steps: parseStepsFromStrings(userFlow.steps),
3883
+ theme,
3884
+ primaryColor,
3885
+ compact: true
3886
+ }
3887
+ ),
3888
+ userFlow.hasReplay && userFlow.recordingId && /* @__PURE__ */ jsxs3(
3553
3889
  "button",
3554
3890
  {
3555
3891
  onClick: () => {
@@ -3561,6 +3897,7 @@ function ProduckChat({
3561
3897
  alignItems: "center",
3562
3898
  gap: "6px",
3563
3899
  padding: "8px 12px",
3900
+ marginTop: userFlow.steps && userFlow.steps.length > 0 ? "12px" : "8px",
3564
3901
  backgroundColor: primaryColor,
3565
3902
  color: "#fff",
3566
3903
  border: "none",
@@ -3572,8 +3909,8 @@ function ProduckChat({
3572
3909
  justifyContent: "center"
3573
3910
  },
3574
3911
  children: [
3575
- /* @__PURE__ */ jsx3("span", { children: "\u25B6\uFE0F" }),
3576
- /* @__PURE__ */ jsx3("span", { children: "Watch Session Replay" })
3912
+ /* @__PURE__ */ jsx4("span", { children: "\u25B6\uFE0F" }),
3913
+ /* @__PURE__ */ jsx4("span", { children: "Watch Session Replay" })
3577
3914
  ]
3578
3915
  }
3579
3916
  )
@@ -3587,7 +3924,7 @@ function ProduckChat({
3587
3924
  },
3588
3925
  idx
3589
3926
  )),
3590
- isLoading && /* @__PURE__ */ jsx3("div", { style: { display: "flex", justifyContent: "flex-start" }, children: /* @__PURE__ */ jsx3(
3927
+ isLoading && /* @__PURE__ */ jsx4("div", { style: { display: "flex", justifyContent: "flex-start" }, children: /* @__PURE__ */ jsx4(
3591
3928
  "div",
3592
3929
  {
3593
3930
  style: {
@@ -3597,16 +3934,16 @@ function ProduckChat({
3597
3934
  color: isDark ? "#9ca3af" : "#6b7280",
3598
3935
  fontSize: typeof fontSize === "number" ? `${fontSize}px` : fontSize
3599
3936
  },
3600
- children: /* @__PURE__ */ jsx3("span", { style: {
3937
+ children: /* @__PURE__ */ jsx4("span", { style: {
3601
3938
  display: "inline-block",
3602
3939
  animation: "pulse 1.5s ease-in-out infinite"
3603
3940
  }, children: "Thinking..." })
3604
3941
  }
3605
3942
  ) }),
3606
- /* @__PURE__ */ jsx3("div", { ref: messagesEndRef })
3943
+ /* @__PURE__ */ jsx4("div", { ref: messagesEndRef })
3607
3944
  ] }),
3608
- /* @__PURE__ */ jsx3("form", { onSubmit: handleSubmit, style: inputContainerStyles, children: /* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "10px", alignItems: "center" }, children: [
3609
- /* @__PURE__ */ jsx3(
3945
+ /* @__PURE__ */ jsx4("form", { onSubmit: handleSubmit, style: inputContainerStyles, children: /* @__PURE__ */ jsxs3("div", { style: { display: "flex", gap: "10px", alignItems: "center" }, children: [
3946
+ /* @__PURE__ */ jsx4(
3610
3947
  "input",
3611
3948
  {
3612
3949
  ref: inputRef,
@@ -3637,7 +3974,7 @@ function ProduckChat({
3637
3974
  }
3638
3975
  }
3639
3976
  ),
3640
- /* @__PURE__ */ jsxs2(
3977
+ /* @__PURE__ */ jsxs3(
3641
3978
  "button",
3642
3979
  {
3643
3980
  type: "submit",
@@ -3669,13 +4006,13 @@ function ProduckChat({
3669
4006
  e.currentTarget.style.boxShadow = "none";
3670
4007
  },
3671
4008
  children: [
3672
- sendButtonIcon && /* @__PURE__ */ jsx3("span", { children: sendButtonIcon }),
4009
+ sendButtonIcon && /* @__PURE__ */ jsx4("span", { children: sendButtonIcon }),
3673
4010
  sendButtonText
3674
4011
  ]
3675
4012
  }
3676
4013
  )
3677
4014
  ] }) }),
3678
- showPoweredBy && /* @__PURE__ */ jsx3(
4015
+ showPoweredBy && /* @__PURE__ */ jsx4(
3679
4016
  "div",
3680
4017
  {
3681
4018
  style: {
@@ -3683,7 +4020,7 @@ function ProduckChat({
3683
4020
  textAlign: "center",
3684
4021
  borderTop: `1px solid ${isDark ? "#374151" : "#e5e7eb"}`
3685
4022
  },
3686
- children: /* @__PURE__ */ jsx3(
4023
+ children: /* @__PURE__ */ jsx4(
3687
4024
  "a",
3688
4025
  {
3689
4026
  href: poweredByUrl,
@@ -3707,7 +4044,7 @@ function ProduckChat({
3707
4044
  }
3708
4045
  )
3709
4046
  ] }),
3710
- /* @__PURE__ */ jsx3("style", { children: `
4047
+ /* @__PURE__ */ jsx4("style", { children: `
3711
4048
  @keyframes pulse {
3712
4049
  0%, 100% { opacity: 1; }
3713
4050
  50% { opacity: 0.5; }
@@ -3721,8 +4058,8 @@ function ProduckChat({
3721
4058
  }
3722
4059
 
3723
4060
  // src/react/ProduckTarget.tsx
3724
- import React4, { useRef as useRef3 } from "react";
3725
- import { jsx as jsx4 } from "react/jsx-runtime";
4061
+ import React5, { useRef as useRef3 } from "react";
4062
+ import { jsx as jsx5 } from "react/jsx-runtime";
3726
4063
  function ProduckTarget({
3727
4064
  actionKey,
3728
4065
  children,
@@ -3737,7 +4074,7 @@ function ProduckTarget({
3737
4074
  scrollIntoView = true
3738
4075
  }) {
3739
4076
  const ref = useRef3(null);
3740
- const [isHighlighted, setIsHighlighted] = React4.useState(false);
4077
+ const [isHighlighted, setIsHighlighted] = React5.useState(false);
3741
4078
  useProduckAction(
3742
4079
  actionKey,
3743
4080
  (payload) => {
@@ -3753,7 +4090,7 @@ function ProduckTarget({
3753
4090
  },
3754
4091
  [scrollIntoView, highlightDuration, onTrigger]
3755
4092
  );
3756
- return /* @__PURE__ */ jsx4(
4093
+ return /* @__PURE__ */ jsx5(
3757
4094
  "div",
3758
4095
  {
3759
4096
  ref,