@modelnex/sdk 0.5.36 → 0.5.38

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/index.d.mts CHANGED
@@ -817,9 +817,14 @@ interface SavedDraftPreview {
817
817
  experienceType: ExperienceType;
818
818
  }
819
819
  type PreviewLaunchSource = 'standard' | 'query_param';
820
+ type DraftPreviewModeListener = (enabled: boolean) => void;
820
821
  declare function getPreviewQueryParamName(experienceType: ExperienceType): 'modelnex_test_tour' | 'modelnex_test_workflow';
821
822
  declare function buildDraftPreviewUrl(currentUrl: string, draft: SavedDraftPreview): string;
822
823
  declare function shouldPromptForPreviewStart(notificationType: TourNotificationType | undefined, _source: PreviewLaunchSource): boolean;
824
+ declare function hasDraftPreviewModeSignal(): boolean;
825
+ declare function observeDraftPreviewModeSignal(listener: DraftPreviewModeListener, options?: {
826
+ pollIntervalMs?: number;
827
+ }): () => void;
823
828
  declare function persistActiveDraftPreview(draft: SavedDraftPreview): void;
824
829
  declare function readActiveDraftPreview(): SavedDraftPreview | null;
825
830
  declare function clearActiveDraftPreview(experienceType?: ExperienceType): void;
@@ -847,4 +852,4 @@ interface ModelNexProviderProps {
847
852
  }
848
853
  declare const ModelNexProvider: React$1.FC<ModelNexProviderProps>;
849
854
 
850
- export { type AgentDebug, type AgentTraceLlmInput, type AgentTraceStep, type ChatMessage, DEFAULT_MODELNEX_SERVER_URL, type ExperienceGoal, type ExperiencePlaybackHook, type ExperiencePresentation, type ExperienceType, type ExtractedElement, ModelNexChatBubble, type ModelNexChatBubbleProps, ModelNexOnboardingPanel, type ModelNexOnboardingPanelProps, ModelNexProvider, type ModelNexProviderProps, type OnboardingPlaybackHook, type OnboardingStepMetadata, type PreviewLaunchSource, type RecordingModeHook, RecordingOverlay, type RunCommandResult, type SavedDraftPreview, StudioOverlay, type TagData, type TagStore, type Tour, type TourNotificationType, type TourPlaybackHook, type TourPlaybackState, TourProgressPanel, type TourStartPolicy, type TourStep, type TourStepType, type TourTrigger, UIStateProvider, type UserProfile, type VoiceHook, buildDraftPreviewUrl, buildRecordingCapturePayload, buildRecordingStepGoal, clearActiveDraftPreview, extractInteractiveElements, generateFingerprint, getPreviewQueryParamName, getRecordingDraftActionLabel, getRecordingDraftStatusMessage, inferOnboardingMetadataForStep, isAskDrivenInputStepType, isInteractiveInputStepType, isManualOnboardingStep, isRecordingDraftGenerating, persistActiveDraftPreview, readActiveDraftPreview, shouldPromptForPreviewStart, shouldShowRecordingOverlay, useActionHighlight, useAgentViewport, useAutoExtract, useExperiencePlayback, useOnboardingPlayback, useRecordingMode, useRunCommand, useTagStore, useTourPlayback, useUIState, useViewportTrack, useVisibleIds, useVoice };
855
+ export { type AgentDebug, type AgentTraceLlmInput, type AgentTraceStep, type ChatMessage, DEFAULT_MODELNEX_SERVER_URL, type ExperienceGoal, type ExperiencePlaybackHook, type ExperiencePresentation, type ExperienceType, type ExtractedElement, ModelNexChatBubble, type ModelNexChatBubbleProps, ModelNexOnboardingPanel, type ModelNexOnboardingPanelProps, ModelNexProvider, type ModelNexProviderProps, type OnboardingPlaybackHook, type OnboardingStepMetadata, type PreviewLaunchSource, type RecordingModeHook, RecordingOverlay, type RunCommandResult, type SavedDraftPreview, StudioOverlay, type TagData, type TagStore, type Tour, type TourNotificationType, type TourPlaybackHook, type TourPlaybackState, TourProgressPanel, type TourStartPolicy, type TourStep, type TourStepType, type TourTrigger, UIStateProvider, type UserProfile, type VoiceHook, buildDraftPreviewUrl, buildRecordingCapturePayload, buildRecordingStepGoal, clearActiveDraftPreview, extractInteractiveElements, generateFingerprint, getPreviewQueryParamName, getRecordingDraftActionLabel, getRecordingDraftStatusMessage, hasDraftPreviewModeSignal, inferOnboardingMetadataForStep, isAskDrivenInputStepType, isInteractiveInputStepType, isManualOnboardingStep, isRecordingDraftGenerating, observeDraftPreviewModeSignal, persistActiveDraftPreview, readActiveDraftPreview, shouldPromptForPreviewStart, shouldShowRecordingOverlay, useActionHighlight, useAgentViewport, useAutoExtract, useExperiencePlayback, useOnboardingPlayback, useRecordingMode, useRunCommand, useTagStore, useTourPlayback, useUIState, useViewportTrack, useVisibleIds, useVoice };
package/dist/index.d.ts CHANGED
@@ -817,9 +817,14 @@ interface SavedDraftPreview {
817
817
  experienceType: ExperienceType;
818
818
  }
819
819
  type PreviewLaunchSource = 'standard' | 'query_param';
820
+ type DraftPreviewModeListener = (enabled: boolean) => void;
820
821
  declare function getPreviewQueryParamName(experienceType: ExperienceType): 'modelnex_test_tour' | 'modelnex_test_workflow';
821
822
  declare function buildDraftPreviewUrl(currentUrl: string, draft: SavedDraftPreview): string;
822
823
  declare function shouldPromptForPreviewStart(notificationType: TourNotificationType | undefined, _source: PreviewLaunchSource): boolean;
824
+ declare function hasDraftPreviewModeSignal(): boolean;
825
+ declare function observeDraftPreviewModeSignal(listener: DraftPreviewModeListener, options?: {
826
+ pollIntervalMs?: number;
827
+ }): () => void;
823
828
  declare function persistActiveDraftPreview(draft: SavedDraftPreview): void;
824
829
  declare function readActiveDraftPreview(): SavedDraftPreview | null;
825
830
  declare function clearActiveDraftPreview(experienceType?: ExperienceType): void;
@@ -847,4 +852,4 @@ interface ModelNexProviderProps {
847
852
  }
848
853
  declare const ModelNexProvider: React$1.FC<ModelNexProviderProps>;
849
854
 
850
- export { type AgentDebug, type AgentTraceLlmInput, type AgentTraceStep, type ChatMessage, DEFAULT_MODELNEX_SERVER_URL, type ExperienceGoal, type ExperiencePlaybackHook, type ExperiencePresentation, type ExperienceType, type ExtractedElement, ModelNexChatBubble, type ModelNexChatBubbleProps, ModelNexOnboardingPanel, type ModelNexOnboardingPanelProps, ModelNexProvider, type ModelNexProviderProps, type OnboardingPlaybackHook, type OnboardingStepMetadata, type PreviewLaunchSource, type RecordingModeHook, RecordingOverlay, type RunCommandResult, type SavedDraftPreview, StudioOverlay, type TagData, type TagStore, type Tour, type TourNotificationType, type TourPlaybackHook, type TourPlaybackState, TourProgressPanel, type TourStartPolicy, type TourStep, type TourStepType, type TourTrigger, UIStateProvider, type UserProfile, type VoiceHook, buildDraftPreviewUrl, buildRecordingCapturePayload, buildRecordingStepGoal, clearActiveDraftPreview, extractInteractiveElements, generateFingerprint, getPreviewQueryParamName, getRecordingDraftActionLabel, getRecordingDraftStatusMessage, inferOnboardingMetadataForStep, isAskDrivenInputStepType, isInteractiveInputStepType, isManualOnboardingStep, isRecordingDraftGenerating, persistActiveDraftPreview, readActiveDraftPreview, shouldPromptForPreviewStart, shouldShowRecordingOverlay, useActionHighlight, useAgentViewport, useAutoExtract, useExperiencePlayback, useOnboardingPlayback, useRecordingMode, useRunCommand, useTagStore, useTourPlayback, useUIState, useViewportTrack, useVisibleIds, useVoice };
855
+ export { type AgentDebug, type AgentTraceLlmInput, type AgentTraceStep, type ChatMessage, DEFAULT_MODELNEX_SERVER_URL, type ExperienceGoal, type ExperiencePlaybackHook, type ExperiencePresentation, type ExperienceType, type ExtractedElement, ModelNexChatBubble, type ModelNexChatBubbleProps, ModelNexOnboardingPanel, type ModelNexOnboardingPanelProps, ModelNexProvider, type ModelNexProviderProps, type OnboardingPlaybackHook, type OnboardingStepMetadata, type PreviewLaunchSource, type RecordingModeHook, RecordingOverlay, type RunCommandResult, type SavedDraftPreview, StudioOverlay, type TagData, type TagStore, type Tour, type TourNotificationType, type TourPlaybackHook, type TourPlaybackState, TourProgressPanel, type TourStartPolicy, type TourStep, type TourStepType, type TourTrigger, UIStateProvider, type UserProfile, type VoiceHook, buildDraftPreviewUrl, buildRecordingCapturePayload, buildRecordingStepGoal, clearActiveDraftPreview, extractInteractiveElements, generateFingerprint, getPreviewQueryParamName, getRecordingDraftActionLabel, getRecordingDraftStatusMessage, hasDraftPreviewModeSignal, inferOnboardingMetadataForStep, isAskDrivenInputStepType, isInteractiveInputStepType, isManualOnboardingStep, isRecordingDraftGenerating, observeDraftPreviewModeSignal, persistActiveDraftPreview, readActiveDraftPreview, shouldPromptForPreviewStart, shouldShowRecordingOverlay, useActionHighlight, useAgentViewport, useAutoExtract, useExperiencePlayback, useOnboardingPlayback, useRecordingMode, useRunCommand, useTagStore, useTourPlayback, useUIState, useViewportTrack, useVisibleIds, useVoice };
package/dist/index.js CHANGED
@@ -188,11 +188,13 @@ __export(index_exports, {
188
188
  getPreviewQueryParamName: () => getPreviewQueryParamName,
189
189
  getRecordingDraftActionLabel: () => getRecordingDraftActionLabel,
190
190
  getRecordingDraftStatusMessage: () => getRecordingDraftStatusMessage,
191
+ hasDraftPreviewModeSignal: () => hasDraftPreviewModeSignal,
191
192
  inferOnboardingMetadataForStep: () => inferOnboardingMetadataForStep,
192
193
  isAskDrivenInputStepType: () => isAskDrivenInputStepType,
193
194
  isInteractiveInputStepType: () => isInteractiveInputStepType,
194
195
  isManualOnboardingStep: () => isManualOnboardingStep,
195
196
  isRecordingDraftGenerating: () => isRecordingDraftGenerating,
197
+ observeDraftPreviewModeSignal: () => observeDraftPreviewModeSignal,
196
198
  persistActiveDraftPreview: () => persistActiveDraftPreview,
197
199
  readActiveDraftPreview: () => readActiveDraftPreview,
198
200
  shouldPromptForPreviewStart: () => shouldPromptForPreviewStart,
@@ -918,10 +920,7 @@ function useModelNexSocket({
918
920
  contexts: serializeContexts(contextsRef.current),
919
921
  documentation: documentationRef.current ?? void 0,
920
922
  domSummary: captureDomSummary(tagsRef.current),
921
- websiteId,
922
- // All tagged elements across every page — not just what's visible now.
923
- // The server uses this to pre-search relevant elements for each user query.
924
- allTaggedElements: tagsRef.current ? Array.from(tagsRef.current.values()) : void 0
923
+ websiteId
925
924
  });
926
925
  socket.on("connect", () => {
927
926
  emitSdkDebugLog("[ModelNex SDK] Connected to agent server", {
@@ -2918,6 +2917,159 @@ function clearPersistedRecordingSession() {
2918
2917
  }
2919
2918
  }
2920
2919
 
2920
+ // src/utils/draftPreview.ts
2921
+ var ACTIVE_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:active-draft-preview";
2922
+ var PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY = "modelnex:preview-session-suppressed";
2923
+ var SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:suppressed-draft-preview";
2924
+ function getPreviewQueryParamName(experienceType) {
2925
+ return experienceType === "onboarding" ? "modelnex_test_workflow" : "modelnex_test_tour";
2926
+ }
2927
+ function buildDraftPreviewUrl(currentUrl, draft) {
2928
+ const url = new URL(currentUrl);
2929
+ url.searchParams.delete("modelnex_test_tour");
2930
+ url.searchParams.delete("modelnex_test_onboarding");
2931
+ url.searchParams.delete("modelnex_test_workflow");
2932
+ url.searchParams.set(getPreviewQueryParamName(draft.experienceType), draft.id);
2933
+ return url.toString();
2934
+ }
2935
+ function shouldPromptForPreviewStart(notificationType, _source) {
2936
+ const normalizedNotificationType = notificationType ?? "bubble_card";
2937
+ return normalizedNotificationType === "modal";
2938
+ }
2939
+ function hasDraftPreviewModeSignal() {
2940
+ if (typeof window === "undefined") return false;
2941
+ try {
2942
+ const params = new URLSearchParams(window.location.search);
2943
+ if (params.has("modelnex_test_tour") || params.has("modelnex_test_workflow") || params.has("modelnex_test_onboarding")) {
2944
+ return true;
2945
+ }
2946
+ } catch {
2947
+ }
2948
+ return readActiveDraftPreview() !== null;
2949
+ }
2950
+ function observeDraftPreviewModeSignal(listener, options) {
2951
+ if (typeof window === "undefined") return () => {
2952
+ };
2953
+ let currentValue = hasDraftPreviewModeSignal();
2954
+ const pollIntervalMs = options?.pollIntervalMs ?? 500;
2955
+ const syncPreviewModeSignal = () => {
2956
+ const nextValue = hasDraftPreviewModeSignal();
2957
+ if (nextValue === currentValue) return;
2958
+ currentValue = nextValue;
2959
+ listener(nextValue);
2960
+ };
2961
+ const intervalId = window.setInterval(syncPreviewModeSignal, pollIntervalMs);
2962
+ window.addEventListener("focus", syncPreviewModeSignal);
2963
+ window.addEventListener("pageshow", syncPreviewModeSignal);
2964
+ window.addEventListener("popstate", syncPreviewModeSignal);
2965
+ if (typeof document !== "undefined") {
2966
+ document.addEventListener("visibilitychange", syncPreviewModeSignal);
2967
+ }
2968
+ return () => {
2969
+ window.clearInterval(intervalId);
2970
+ window.removeEventListener("focus", syncPreviewModeSignal);
2971
+ window.removeEventListener("pageshow", syncPreviewModeSignal);
2972
+ window.removeEventListener("popstate", syncPreviewModeSignal);
2973
+ if (typeof document !== "undefined") {
2974
+ document.removeEventListener("visibilitychange", syncPreviewModeSignal);
2975
+ }
2976
+ };
2977
+ }
2978
+ function persistActiveDraftPreview(draft) {
2979
+ if (typeof window === "undefined") return;
2980
+ try {
2981
+ window.sessionStorage.setItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
2982
+ } catch {
2983
+ }
2984
+ }
2985
+ function readActiveDraftPreview() {
2986
+ if (typeof window === "undefined") return null;
2987
+ try {
2988
+ const raw = window.sessionStorage.getItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
2989
+ if (!raw) return null;
2990
+ const parsed = JSON.parse(raw);
2991
+ if (!parsed || typeof parsed.id !== "string") return null;
2992
+ if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
2993
+ return {
2994
+ id: parsed.id,
2995
+ experienceType: parsed.experienceType
2996
+ };
2997
+ } catch {
2998
+ return null;
2999
+ }
3000
+ }
3001
+ function clearActiveDraftPreview(experienceType) {
3002
+ if (typeof window === "undefined") return;
3003
+ try {
3004
+ const activePreview = readActiveDraftPreview();
3005
+ if (experienceType && activePreview && activePreview.experienceType !== experienceType) {
3006
+ return;
3007
+ }
3008
+ window.sessionStorage.removeItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
3009
+ } catch {
3010
+ }
3011
+ }
3012
+ function readSavedDraftPreview(storageKey) {
3013
+ if (typeof window === "undefined") return null;
3014
+ try {
3015
+ const raw = window.sessionStorage.getItem(storageKey);
3016
+ if (!raw) return null;
3017
+ const parsed = JSON.parse(raw);
3018
+ if (!parsed || typeof parsed.id !== "string") return null;
3019
+ if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
3020
+ return {
3021
+ id: parsed.id,
3022
+ experienceType: parsed.experienceType
3023
+ };
3024
+ } catch {
3025
+ return null;
3026
+ }
3027
+ }
3028
+ function readSuppressedDraftPreview() {
3029
+ return readSavedDraftPreview(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
3030
+ }
3031
+ function persistSuppressedDraftPreview(draft) {
3032
+ if (typeof window === "undefined") return;
3033
+ try {
3034
+ window.sessionStorage.setItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
3035
+ } catch {
3036
+ }
3037
+ }
3038
+ function clearSuppressedDraftPreview(draft) {
3039
+ if (typeof window === "undefined") return;
3040
+ try {
3041
+ const suppressedDraft = readSuppressedDraftPreview();
3042
+ if (draft && suppressedDraft) {
3043
+ if (suppressedDraft.id !== draft.id || suppressedDraft.experienceType !== draft.experienceType) {
3044
+ return;
3045
+ }
3046
+ }
3047
+ window.sessionStorage.removeItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
3048
+ } catch {
3049
+ }
3050
+ }
3051
+ function isSuppressedDraftPreview(draft) {
3052
+ const suppressedDraft = readSuppressedDraftPreview();
3053
+ return Boolean(
3054
+ suppressedDraft && suppressedDraft.id === draft.id && suppressedDraft.experienceType === draft.experienceType
3055
+ );
3056
+ }
3057
+ function persistPreviewSessionSuppression() {
3058
+ if (typeof window === "undefined") return;
3059
+ try {
3060
+ window.sessionStorage.setItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY, "true");
3061
+ } catch {
3062
+ }
3063
+ }
3064
+ function readPreviewSessionSuppression() {
3065
+ if (typeof window === "undefined") return false;
3066
+ try {
3067
+ return window.sessionStorage.getItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY) === "true";
3068
+ } catch {
3069
+ return false;
3070
+ }
3071
+ }
3072
+
2921
3073
  // src/hooks/useRunCommand.ts
2922
3074
  var import_react9 = require("react");
2923
3075
  function searchTaggedElementsForQuery(store, query, limit = 8) {
@@ -3053,120 +3205,6 @@ var import_react_dom = require("react-dom");
3053
3205
  // src/hooks/useExperiencePlaybackController.ts
3054
3206
  var import_react13 = require("react");
3055
3207
 
3056
- // src/utils/draftPreview.ts
3057
- var ACTIVE_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:active-draft-preview";
3058
- var PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY = "modelnex:preview-session-suppressed";
3059
- var SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:suppressed-draft-preview";
3060
- function getPreviewQueryParamName(experienceType) {
3061
- return experienceType === "onboarding" ? "modelnex_test_workflow" : "modelnex_test_tour";
3062
- }
3063
- function buildDraftPreviewUrl(currentUrl, draft) {
3064
- const url = new URL(currentUrl);
3065
- url.searchParams.delete("modelnex_test_tour");
3066
- url.searchParams.delete("modelnex_test_onboarding");
3067
- url.searchParams.delete("modelnex_test_workflow");
3068
- url.searchParams.set(getPreviewQueryParamName(draft.experienceType), draft.id);
3069
- return url.toString();
3070
- }
3071
- function shouldPromptForPreviewStart(notificationType, _source) {
3072
- const normalizedNotificationType = notificationType ?? "bubble_card";
3073
- return normalizedNotificationType === "modal";
3074
- }
3075
- function persistActiveDraftPreview(draft) {
3076
- if (typeof window === "undefined") return;
3077
- try {
3078
- window.sessionStorage.setItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
3079
- } catch {
3080
- }
3081
- }
3082
- function readActiveDraftPreview() {
3083
- if (typeof window === "undefined") return null;
3084
- try {
3085
- const raw = window.sessionStorage.getItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
3086
- if (!raw) return null;
3087
- const parsed = JSON.parse(raw);
3088
- if (!parsed || typeof parsed.id !== "string") return null;
3089
- if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
3090
- return {
3091
- id: parsed.id,
3092
- experienceType: parsed.experienceType
3093
- };
3094
- } catch {
3095
- return null;
3096
- }
3097
- }
3098
- function clearActiveDraftPreview(experienceType) {
3099
- if (typeof window === "undefined") return;
3100
- try {
3101
- const activePreview = readActiveDraftPreview();
3102
- if (experienceType && activePreview && activePreview.experienceType !== experienceType) {
3103
- return;
3104
- }
3105
- window.sessionStorage.removeItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
3106
- } catch {
3107
- }
3108
- }
3109
- function readSavedDraftPreview(storageKey) {
3110
- if (typeof window === "undefined") return null;
3111
- try {
3112
- const raw = window.sessionStorage.getItem(storageKey);
3113
- if (!raw) return null;
3114
- const parsed = JSON.parse(raw);
3115
- if (!parsed || typeof parsed.id !== "string") return null;
3116
- if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
3117
- return {
3118
- id: parsed.id,
3119
- experienceType: parsed.experienceType
3120
- };
3121
- } catch {
3122
- return null;
3123
- }
3124
- }
3125
- function readSuppressedDraftPreview() {
3126
- return readSavedDraftPreview(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
3127
- }
3128
- function persistSuppressedDraftPreview(draft) {
3129
- if (typeof window === "undefined") return;
3130
- try {
3131
- window.sessionStorage.setItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
3132
- } catch {
3133
- }
3134
- }
3135
- function clearSuppressedDraftPreview(draft) {
3136
- if (typeof window === "undefined") return;
3137
- try {
3138
- const suppressedDraft = readSuppressedDraftPreview();
3139
- if (draft && suppressedDraft) {
3140
- if (suppressedDraft.id !== draft.id || suppressedDraft.experienceType !== draft.experienceType) {
3141
- return;
3142
- }
3143
- }
3144
- window.sessionStorage.removeItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
3145
- } catch {
3146
- }
3147
- }
3148
- function isSuppressedDraftPreview(draft) {
3149
- const suppressedDraft = readSuppressedDraftPreview();
3150
- return Boolean(
3151
- suppressedDraft && suppressedDraft.id === draft.id && suppressedDraft.experienceType === draft.experienceType
3152
- );
3153
- }
3154
- function persistPreviewSessionSuppression() {
3155
- if (typeof window === "undefined") return;
3156
- try {
3157
- window.sessionStorage.setItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY, "true");
3158
- } catch {
3159
- }
3160
- }
3161
- function readPreviewSessionSuppression() {
3162
- if (typeof window === "undefined") return false;
3163
- try {
3164
- return window.sessionStorage.getItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY) === "true";
3165
- } catch {
3166
- return false;
3167
- }
3168
- }
3169
-
3170
3208
  // src/utils/locationSignature.ts
3171
3209
  function getLocationSignature(locationLike) {
3172
3210
  if (!locationLike) return "";
@@ -3267,6 +3305,43 @@ function createTourSocketPool({
3267
3305
  }
3268
3306
  var tourSocketPool = createTourSocketPool();
3269
3307
 
3308
+ // src/utils/tourTransport.ts
3309
+ function compactCaptureEventForTransport(event) {
3310
+ return {
3311
+ id: event.id,
3312
+ type: event.type,
3313
+ order: event.order,
3314
+ timestamp: event.timestamp,
3315
+ url: event.url,
3316
+ label: event.label,
3317
+ tagName: event.tagName,
3318
+ testId: event.testId,
3319
+ fingerprint: event.fingerprint,
3320
+ textContaining: event.textContaining,
3321
+ fieldType: event.fieldType,
3322
+ valueSample: event.valueSample,
3323
+ note: event.note,
3324
+ stepTypeHint: event.stepTypeHint
3325
+ };
3326
+ }
3327
+ function compactTourForTransport(tour) {
3328
+ const capture = tour.capture;
3329
+ if (!capture || typeof capture !== "object") {
3330
+ return tour;
3331
+ }
3332
+ return {
3333
+ ...tour,
3334
+ capture: {
3335
+ ...capture.experienceType ? { experienceType: capture.experienceType } : {},
3336
+ ...capture.onboardingHints ? { onboardingHints: capture.onboardingHints } : {},
3337
+ ...capture.generation ? { generation: capture.generation } : {},
3338
+ ...Array.isArray(capture.events) ? {
3339
+ events: capture.events.map((event) => compactCaptureEventForTransport(event))
3340
+ } : {}
3341
+ }
3342
+ };
3343
+ }
3344
+
3270
3345
  // src/utils/tour-playback-guards.ts
3271
3346
  var playbackOwners = /* @__PURE__ */ new Map();
3272
3347
  function shouldExecuteTourCommandBatch(isPlaybackActive) {
@@ -4783,7 +4858,7 @@ function useTourPlayback({
4783
4858
  emitSocketEvent(socketRef.current, "tour:request_start", {
4784
4859
  tourId: tour.id,
4785
4860
  previewRunId: previewRunIdRef.current,
4786
- tourContext: tour
4861
+ tourContext: compactTourForTransport(tour)
4787
4862
  });
4788
4863
  }, [serverUrl, websiteId]);
4789
4864
  (0, import_react12.useEffect)(() => {
@@ -9450,6 +9525,7 @@ function ModelNexChatBubble({
9450
9525
  const setRecordingMode = ctx?.setRecordingMode ?? (() => {
9451
9526
  });
9452
9527
  const devMode = ctx?.devMode ?? false;
9528
+ const authoringMode = ctx?.authoringMode ?? devMode;
9453
9529
  const [recordingTourName, setRecordingTourName] = (0, import_react18.useState)("");
9454
9530
  const [recordingTargetTypes, setRecordingTargetTypes] = (0, import_react18.useState)("admin");
9455
9531
  const [showStopModal, setShowStopModal] = (0, import_react18.useState)(false);
@@ -9578,11 +9654,11 @@ function ModelNexChatBubble({
9578
9654
  }
9579
9655
  }, [ctx]);
9580
9656
  (0, import_react18.useEffect)(() => {
9581
- if (devMode && ctx?.extractedElements.length) {
9657
+ if (authoringMode && ctx?.extractedElements.length) {
9582
9658
  const timer = setTimeout(handleAutoTag, 1e3);
9583
9659
  return () => clearTimeout(timer);
9584
9660
  }
9585
- }, [devMode, handleAutoTag, ctx?.extractedElements.length, window.location.pathname]);
9661
+ }, [authoringMode, handleAutoTag, ctx?.extractedElements.length, window.location.pathname]);
9586
9662
  const onboardingReviewToggle = getReviewModeToggleConfig(onboardingPlayback.playbackState);
9587
9663
  const pendingPrompt = playbackController.pendingPrompt;
9588
9664
  const pendingNotificationType = (onboardingPlayback.pendingTour || tourPlayback.pendingTour)?.notificationType ?? "bubble_card";
@@ -9943,7 +10019,7 @@ function ModelNexChatBubble({
9943
10019
  content: summary || fallbackContent,
9944
10020
  summary: summary ?? void 0,
9945
10021
  nextSteps: nextSteps ?? void 0,
9946
- debug: devMode ? data?.debug ?? void 0 : void 0
10022
+ debug: authoringMode ? data?.debug ?? void 0 : void 0
9947
10023
  }
9948
10024
  ]);
9949
10025
  } catch (err) {
@@ -10231,7 +10307,7 @@ function ModelNexChatBubble({
10231
10307
  children: voice.isMuted ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(VolumeMuteIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(VolumeIcon, {})
10232
10308
  }
10233
10309
  ) }),
10234
- devMode && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", background: "var(--modelnex-bg-secondary, #f4f4f5)", borderRadius: "12px", padding: "2px", gap: "2px", marginRight: "4px" }, children: (!recordingMode || activeRecordingExperienceType === "onboarding") && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Tooltip, { title: recordingMode ? "Stop & Save Workflow" : "Record Workflow", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
10310
+ authoringMode && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", background: "var(--modelnex-bg-secondary, #f4f4f5)", borderRadius: "12px", padding: "2px", gap: "2px", marginRight: "4px" }, children: (!recordingMode || activeRecordingExperienceType === "onboarding") && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Tooltip, { title: recordingMode ? "Stop & Save Workflow" : "Record Workflow", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
10235
10311
  "button",
10236
10312
  {
10237
10313
  onClick: () => {
@@ -10987,7 +11063,7 @@ function ModelNexChatBubble({
10987
11063
  )
10988
11064
  }
10989
11065
  ),
10990
- msg.role === "assistant" && devMode && msg.debug && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AgentTraces, { debug: msg.debug, command: messages[i - 1]?.content ?? "" })
11066
+ msg.role === "assistant" && authoringMode && msg.debug && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AgentTraces, { debug: msg.debug, command: messages[i - 1]?.content ?? "" })
10991
11067
  ] }, i)),
10992
11068
  loading && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { display: "flex", justifyContent: "flex-start" }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
10993
11069
  "div",
@@ -11988,7 +12064,9 @@ var ModelNexProvider = ({
11988
12064
  const [actions, setActions] = (0, import_react21.useState)(/* @__PURE__ */ new Map());
11989
12065
  const [validatedBrowserDevMode, setValidatedBrowserDevMode] = (0, import_react21.useState)(false);
11990
12066
  const [resolvedDevModeKey, setResolvedDevModeKey] = (0, import_react21.useState)(() => resolveInjectedDevModeKey());
12067
+ const [previewRuntimeMode, setPreviewRuntimeMode] = (0, import_react21.useState)(() => hasDraftPreviewModeSignal());
11991
12068
  (0, import_react21.useEffect)(() => observeInjectedDevModeKey(setResolvedDevModeKey), []);
12069
+ (0, import_react21.useEffect)(() => observeDraftPreviewModeSignal(setPreviewRuntimeMode), []);
11992
12070
  (0, import_react21.useEffect)(() => {
11993
12071
  let cancelled = false;
11994
12072
  if (!websiteId || !resolvedDevModeKey) {
@@ -12005,7 +12083,7 @@ var ModelNexProvider = ({
12005
12083
  cancelled = true;
12006
12084
  };
12007
12085
  }, [resolvedDevModeKey, serverUrl, websiteId]);
12008
- const effectiveDevMode = validatedBrowserDevMode;
12086
+ const effectiveDevMode = validatedBrowserDevMode || previewRuntimeMode;
12009
12087
  const registerAction = (0, import_react21.useCallback)((action) => {
12010
12088
  setActions((prev) => {
12011
12089
  const next = new Map(prev);
@@ -12102,9 +12180,10 @@ var ModelNexProvider = ({
12102
12180
  voiceMuted,
12103
12181
  setVoiceMuted,
12104
12182
  socketId,
12105
- devMode: effectiveDevMode
12183
+ devMode: effectiveDevMode,
12184
+ authoringMode: validatedBrowserDevMode
12106
12185
  }),
12107
- [serverUrl, commandUrl, registerAction, unregisterAction, activeAgentActions, stagingFields, highlightActions, studioMode, recordingMode, extractedElements, tagStore, chatMessages, websiteId, userProfile?.userId, userProfile?.type, userProfile?.isNewUser, toursApiBase, voiceMuted, socketId, effectiveDevMode]
12186
+ [serverUrl, commandUrl, registerAction, unregisterAction, activeAgentActions, stagingFields, highlightActions, studioMode, recordingMode, extractedElements, tagStore, chatMessages, websiteId, userProfile?.userId, userProfile?.type, userProfile?.isNewUser, toursApiBase, voiceMuted, socketId, effectiveDevMode, validatedBrowserDevMode]
12108
12187
  );
12109
12188
  return import_react21.default.createElement(
12110
12189
  ModelNexContext.Provider,
@@ -12135,11 +12214,13 @@ var ModelNexProvider = ({
12135
12214
  getPreviewQueryParamName,
12136
12215
  getRecordingDraftActionLabel,
12137
12216
  getRecordingDraftStatusMessage,
12217
+ hasDraftPreviewModeSignal,
12138
12218
  inferOnboardingMetadataForStep,
12139
12219
  isAskDrivenInputStepType,
12140
12220
  isInteractiveInputStepType,
12141
12221
  isManualOnboardingStep,
12142
12222
  isRecordingDraftGenerating,
12223
+ observeDraftPreviewModeSignal,
12143
12224
  persistActiveDraftPreview,
12144
12225
  readActiveDraftPreview,
12145
12226
  shouldPromptForPreviewStart,
package/dist/index.mjs CHANGED
@@ -709,10 +709,7 @@ function useModelNexSocket({
709
709
  contexts: serializeContexts(contextsRef.current),
710
710
  documentation: documentationRef.current ?? void 0,
711
711
  domSummary: captureDomSummary(tagsRef.current),
712
- websiteId,
713
- // All tagged elements across every page — not just what's visible now.
714
- // The server uses this to pre-search relevant elements for each user query.
715
- allTaggedElements: tagsRef.current ? Array.from(tagsRef.current.values()) : void 0
712
+ websiteId
716
713
  });
717
714
  socket.on("connect", () => {
718
715
  emitSdkDebugLog("[ModelNex SDK] Connected to agent server", {
@@ -2709,6 +2706,159 @@ function clearPersistedRecordingSession() {
2709
2706
  }
2710
2707
  }
2711
2708
 
2709
+ // src/utils/draftPreview.ts
2710
+ var ACTIVE_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:active-draft-preview";
2711
+ var PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY = "modelnex:preview-session-suppressed";
2712
+ var SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:suppressed-draft-preview";
2713
+ function getPreviewQueryParamName(experienceType) {
2714
+ return experienceType === "onboarding" ? "modelnex_test_workflow" : "modelnex_test_tour";
2715
+ }
2716
+ function buildDraftPreviewUrl(currentUrl, draft) {
2717
+ const url = new URL(currentUrl);
2718
+ url.searchParams.delete("modelnex_test_tour");
2719
+ url.searchParams.delete("modelnex_test_onboarding");
2720
+ url.searchParams.delete("modelnex_test_workflow");
2721
+ url.searchParams.set(getPreviewQueryParamName(draft.experienceType), draft.id);
2722
+ return url.toString();
2723
+ }
2724
+ function shouldPromptForPreviewStart(notificationType, _source) {
2725
+ const normalizedNotificationType = notificationType ?? "bubble_card";
2726
+ return normalizedNotificationType === "modal";
2727
+ }
2728
+ function hasDraftPreviewModeSignal() {
2729
+ if (typeof window === "undefined") return false;
2730
+ try {
2731
+ const params = new URLSearchParams(window.location.search);
2732
+ if (params.has("modelnex_test_tour") || params.has("modelnex_test_workflow") || params.has("modelnex_test_onboarding")) {
2733
+ return true;
2734
+ }
2735
+ } catch {
2736
+ }
2737
+ return readActiveDraftPreview() !== null;
2738
+ }
2739
+ function observeDraftPreviewModeSignal(listener, options) {
2740
+ if (typeof window === "undefined") return () => {
2741
+ };
2742
+ let currentValue = hasDraftPreviewModeSignal();
2743
+ const pollIntervalMs = options?.pollIntervalMs ?? 500;
2744
+ const syncPreviewModeSignal = () => {
2745
+ const nextValue = hasDraftPreviewModeSignal();
2746
+ if (nextValue === currentValue) return;
2747
+ currentValue = nextValue;
2748
+ listener(nextValue);
2749
+ };
2750
+ const intervalId = window.setInterval(syncPreviewModeSignal, pollIntervalMs);
2751
+ window.addEventListener("focus", syncPreviewModeSignal);
2752
+ window.addEventListener("pageshow", syncPreviewModeSignal);
2753
+ window.addEventListener("popstate", syncPreviewModeSignal);
2754
+ if (typeof document !== "undefined") {
2755
+ document.addEventListener("visibilitychange", syncPreviewModeSignal);
2756
+ }
2757
+ return () => {
2758
+ window.clearInterval(intervalId);
2759
+ window.removeEventListener("focus", syncPreviewModeSignal);
2760
+ window.removeEventListener("pageshow", syncPreviewModeSignal);
2761
+ window.removeEventListener("popstate", syncPreviewModeSignal);
2762
+ if (typeof document !== "undefined") {
2763
+ document.removeEventListener("visibilitychange", syncPreviewModeSignal);
2764
+ }
2765
+ };
2766
+ }
2767
+ function persistActiveDraftPreview(draft) {
2768
+ if (typeof window === "undefined") return;
2769
+ try {
2770
+ window.sessionStorage.setItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
2771
+ } catch {
2772
+ }
2773
+ }
2774
+ function readActiveDraftPreview() {
2775
+ if (typeof window === "undefined") return null;
2776
+ try {
2777
+ const raw = window.sessionStorage.getItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
2778
+ if (!raw) return null;
2779
+ const parsed = JSON.parse(raw);
2780
+ if (!parsed || typeof parsed.id !== "string") return null;
2781
+ if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
2782
+ return {
2783
+ id: parsed.id,
2784
+ experienceType: parsed.experienceType
2785
+ };
2786
+ } catch {
2787
+ return null;
2788
+ }
2789
+ }
2790
+ function clearActiveDraftPreview(experienceType) {
2791
+ if (typeof window === "undefined") return;
2792
+ try {
2793
+ const activePreview = readActiveDraftPreview();
2794
+ if (experienceType && activePreview && activePreview.experienceType !== experienceType) {
2795
+ return;
2796
+ }
2797
+ window.sessionStorage.removeItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
2798
+ } catch {
2799
+ }
2800
+ }
2801
+ function readSavedDraftPreview(storageKey) {
2802
+ if (typeof window === "undefined") return null;
2803
+ try {
2804
+ const raw = window.sessionStorage.getItem(storageKey);
2805
+ if (!raw) return null;
2806
+ const parsed = JSON.parse(raw);
2807
+ if (!parsed || typeof parsed.id !== "string") return null;
2808
+ if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
2809
+ return {
2810
+ id: parsed.id,
2811
+ experienceType: parsed.experienceType
2812
+ };
2813
+ } catch {
2814
+ return null;
2815
+ }
2816
+ }
2817
+ function readSuppressedDraftPreview() {
2818
+ return readSavedDraftPreview(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
2819
+ }
2820
+ function persistSuppressedDraftPreview(draft) {
2821
+ if (typeof window === "undefined") return;
2822
+ try {
2823
+ window.sessionStorage.setItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
2824
+ } catch {
2825
+ }
2826
+ }
2827
+ function clearSuppressedDraftPreview(draft) {
2828
+ if (typeof window === "undefined") return;
2829
+ try {
2830
+ const suppressedDraft = readSuppressedDraftPreview();
2831
+ if (draft && suppressedDraft) {
2832
+ if (suppressedDraft.id !== draft.id || suppressedDraft.experienceType !== draft.experienceType) {
2833
+ return;
2834
+ }
2835
+ }
2836
+ window.sessionStorage.removeItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
2837
+ } catch {
2838
+ }
2839
+ }
2840
+ function isSuppressedDraftPreview(draft) {
2841
+ const suppressedDraft = readSuppressedDraftPreview();
2842
+ return Boolean(
2843
+ suppressedDraft && suppressedDraft.id === draft.id && suppressedDraft.experienceType === draft.experienceType
2844
+ );
2845
+ }
2846
+ function persistPreviewSessionSuppression() {
2847
+ if (typeof window === "undefined") return;
2848
+ try {
2849
+ window.sessionStorage.setItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY, "true");
2850
+ } catch {
2851
+ }
2852
+ }
2853
+ function readPreviewSessionSuppression() {
2854
+ if (typeof window === "undefined") return false;
2855
+ try {
2856
+ return window.sessionStorage.getItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY) === "true";
2857
+ } catch {
2858
+ return false;
2859
+ }
2860
+ }
2861
+
2712
2862
  // src/hooks/useRunCommand.ts
2713
2863
  import { useCallback as useCallback5, useContext as useContext2 } from "react";
2714
2864
  function searchTaggedElementsForQuery(store, query, limit = 8) {
@@ -2844,120 +2994,6 @@ import { createPortal, flushSync } from "react-dom";
2844
2994
  // src/hooks/useExperiencePlaybackController.ts
2845
2995
  import { useCallback as useCallback8, useEffect as useEffect12, useRef as useRef9, useState as useState8 } from "react";
2846
2996
 
2847
- // src/utils/draftPreview.ts
2848
- var ACTIVE_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:active-draft-preview";
2849
- var PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY = "modelnex:preview-session-suppressed";
2850
- var SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY = "modelnex:suppressed-draft-preview";
2851
- function getPreviewQueryParamName(experienceType) {
2852
- return experienceType === "onboarding" ? "modelnex_test_workflow" : "modelnex_test_tour";
2853
- }
2854
- function buildDraftPreviewUrl(currentUrl, draft) {
2855
- const url = new URL(currentUrl);
2856
- url.searchParams.delete("modelnex_test_tour");
2857
- url.searchParams.delete("modelnex_test_onboarding");
2858
- url.searchParams.delete("modelnex_test_workflow");
2859
- url.searchParams.set(getPreviewQueryParamName(draft.experienceType), draft.id);
2860
- return url.toString();
2861
- }
2862
- function shouldPromptForPreviewStart(notificationType, _source) {
2863
- const normalizedNotificationType = notificationType ?? "bubble_card";
2864
- return normalizedNotificationType === "modal";
2865
- }
2866
- function persistActiveDraftPreview(draft) {
2867
- if (typeof window === "undefined") return;
2868
- try {
2869
- window.sessionStorage.setItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
2870
- } catch {
2871
- }
2872
- }
2873
- function readActiveDraftPreview() {
2874
- if (typeof window === "undefined") return null;
2875
- try {
2876
- const raw = window.sessionStorage.getItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
2877
- if (!raw) return null;
2878
- const parsed = JSON.parse(raw);
2879
- if (!parsed || typeof parsed.id !== "string") return null;
2880
- if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
2881
- return {
2882
- id: parsed.id,
2883
- experienceType: parsed.experienceType
2884
- };
2885
- } catch {
2886
- return null;
2887
- }
2888
- }
2889
- function clearActiveDraftPreview(experienceType) {
2890
- if (typeof window === "undefined") return;
2891
- try {
2892
- const activePreview = readActiveDraftPreview();
2893
- if (experienceType && activePreview && activePreview.experienceType !== experienceType) {
2894
- return;
2895
- }
2896
- window.sessionStorage.removeItem(ACTIVE_DRAFT_PREVIEW_STORAGE_KEY);
2897
- } catch {
2898
- }
2899
- }
2900
- function readSavedDraftPreview(storageKey) {
2901
- if (typeof window === "undefined") return null;
2902
- try {
2903
- const raw = window.sessionStorage.getItem(storageKey);
2904
- if (!raw) return null;
2905
- const parsed = JSON.parse(raw);
2906
- if (!parsed || typeof parsed.id !== "string") return null;
2907
- if (parsed.experienceType !== "tour" && parsed.experienceType !== "onboarding") return null;
2908
- return {
2909
- id: parsed.id,
2910
- experienceType: parsed.experienceType
2911
- };
2912
- } catch {
2913
- return null;
2914
- }
2915
- }
2916
- function readSuppressedDraftPreview() {
2917
- return readSavedDraftPreview(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
2918
- }
2919
- function persistSuppressedDraftPreview(draft) {
2920
- if (typeof window === "undefined") return;
2921
- try {
2922
- window.sessionStorage.setItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY, JSON.stringify(draft));
2923
- } catch {
2924
- }
2925
- }
2926
- function clearSuppressedDraftPreview(draft) {
2927
- if (typeof window === "undefined") return;
2928
- try {
2929
- const suppressedDraft = readSuppressedDraftPreview();
2930
- if (draft && suppressedDraft) {
2931
- if (suppressedDraft.id !== draft.id || suppressedDraft.experienceType !== draft.experienceType) {
2932
- return;
2933
- }
2934
- }
2935
- window.sessionStorage.removeItem(SUPPRESSED_DRAFT_PREVIEW_STORAGE_KEY);
2936
- } catch {
2937
- }
2938
- }
2939
- function isSuppressedDraftPreview(draft) {
2940
- const suppressedDraft = readSuppressedDraftPreview();
2941
- return Boolean(
2942
- suppressedDraft && suppressedDraft.id === draft.id && suppressedDraft.experienceType === draft.experienceType
2943
- );
2944
- }
2945
- function persistPreviewSessionSuppression() {
2946
- if (typeof window === "undefined") return;
2947
- try {
2948
- window.sessionStorage.setItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY, "true");
2949
- } catch {
2950
- }
2951
- }
2952
- function readPreviewSessionSuppression() {
2953
- if (typeof window === "undefined") return false;
2954
- try {
2955
- return window.sessionStorage.getItem(PREVIEW_SESSION_SUPPRESSION_STORAGE_KEY) === "true";
2956
- } catch {
2957
- return false;
2958
- }
2959
- }
2960
-
2961
2997
  // src/utils/locationSignature.ts
2962
2998
  function getLocationSignature(locationLike) {
2963
2999
  if (!locationLike) return "";
@@ -3058,6 +3094,43 @@ function createTourSocketPool({
3058
3094
  }
3059
3095
  var tourSocketPool = createTourSocketPool();
3060
3096
 
3097
+ // src/utils/tourTransport.ts
3098
+ function compactCaptureEventForTransport(event) {
3099
+ return {
3100
+ id: event.id,
3101
+ type: event.type,
3102
+ order: event.order,
3103
+ timestamp: event.timestamp,
3104
+ url: event.url,
3105
+ label: event.label,
3106
+ tagName: event.tagName,
3107
+ testId: event.testId,
3108
+ fingerprint: event.fingerprint,
3109
+ textContaining: event.textContaining,
3110
+ fieldType: event.fieldType,
3111
+ valueSample: event.valueSample,
3112
+ note: event.note,
3113
+ stepTypeHint: event.stepTypeHint
3114
+ };
3115
+ }
3116
+ function compactTourForTransport(tour) {
3117
+ const capture = tour.capture;
3118
+ if (!capture || typeof capture !== "object") {
3119
+ return tour;
3120
+ }
3121
+ return {
3122
+ ...tour,
3123
+ capture: {
3124
+ ...capture.experienceType ? { experienceType: capture.experienceType } : {},
3125
+ ...capture.onboardingHints ? { onboardingHints: capture.onboardingHints } : {},
3126
+ ...capture.generation ? { generation: capture.generation } : {},
3127
+ ...Array.isArray(capture.events) ? {
3128
+ events: capture.events.map((event) => compactCaptureEventForTransport(event))
3129
+ } : {}
3130
+ }
3131
+ };
3132
+ }
3133
+
3061
3134
  // src/utils/tour-playback-guards.ts
3062
3135
  var playbackOwners = /* @__PURE__ */ new Map();
3063
3136
  function shouldExecuteTourCommandBatch(isPlaybackActive) {
@@ -4574,7 +4647,7 @@ function useTourPlayback({
4574
4647
  emitSocketEvent(socketRef.current, "tour:request_start", {
4575
4648
  tourId: tour.id,
4576
4649
  previewRunId: previewRunIdRef.current,
4577
- tourContext: tour
4650
+ tourContext: compactTourForTransport(tour)
4578
4651
  });
4579
4652
  }, [serverUrl, websiteId]);
4580
4653
  useEffect11(() => {
@@ -9240,6 +9313,7 @@ function ModelNexChatBubble({
9240
9313
  const setRecordingMode = ctx?.setRecordingMode ?? (() => {
9241
9314
  });
9242
9315
  const devMode = ctx?.devMode ?? false;
9316
+ const authoringMode = ctx?.authoringMode ?? devMode;
9243
9317
  const [recordingTourName, setRecordingTourName] = useState13("");
9244
9318
  const [recordingTargetTypes, setRecordingTargetTypes] = useState13("admin");
9245
9319
  const [showStopModal, setShowStopModal] = useState13(false);
@@ -9368,11 +9442,11 @@ function ModelNexChatBubble({
9368
9442
  }
9369
9443
  }, [ctx]);
9370
9444
  useEffect17(() => {
9371
- if (devMode && ctx?.extractedElements.length) {
9445
+ if (authoringMode && ctx?.extractedElements.length) {
9372
9446
  const timer = setTimeout(handleAutoTag, 1e3);
9373
9447
  return () => clearTimeout(timer);
9374
9448
  }
9375
- }, [devMode, handleAutoTag, ctx?.extractedElements.length, window.location.pathname]);
9449
+ }, [authoringMode, handleAutoTag, ctx?.extractedElements.length, window.location.pathname]);
9376
9450
  const onboardingReviewToggle = getReviewModeToggleConfig(onboardingPlayback.playbackState);
9377
9451
  const pendingPrompt = playbackController.pendingPrompt;
9378
9452
  const pendingNotificationType = (onboardingPlayback.pendingTour || tourPlayback.pendingTour)?.notificationType ?? "bubble_card";
@@ -9733,7 +9807,7 @@ function ModelNexChatBubble({
9733
9807
  content: summary || fallbackContent,
9734
9808
  summary: summary ?? void 0,
9735
9809
  nextSteps: nextSteps ?? void 0,
9736
- debug: devMode ? data?.debug ?? void 0 : void 0
9810
+ debug: authoringMode ? data?.debug ?? void 0 : void 0
9737
9811
  }
9738
9812
  ]);
9739
9813
  } catch (err) {
@@ -10021,7 +10095,7 @@ function ModelNexChatBubble({
10021
10095
  children: voice.isMuted ? /* @__PURE__ */ jsx4(VolumeMuteIcon, {}) : /* @__PURE__ */ jsx4(VolumeIcon, {})
10022
10096
  }
10023
10097
  ) }),
10024
- devMode && /* @__PURE__ */ jsx4("div", { style: { display: "flex", background: "var(--modelnex-bg-secondary, #f4f4f5)", borderRadius: "12px", padding: "2px", gap: "2px", marginRight: "4px" }, children: (!recordingMode || activeRecordingExperienceType === "onboarding") && /* @__PURE__ */ jsx4(Tooltip, { title: recordingMode ? "Stop & Save Workflow" : "Record Workflow", children: /* @__PURE__ */ jsx4(
10098
+ authoringMode && /* @__PURE__ */ jsx4("div", { style: { display: "flex", background: "var(--modelnex-bg-secondary, #f4f4f5)", borderRadius: "12px", padding: "2px", gap: "2px", marginRight: "4px" }, children: (!recordingMode || activeRecordingExperienceType === "onboarding") && /* @__PURE__ */ jsx4(Tooltip, { title: recordingMode ? "Stop & Save Workflow" : "Record Workflow", children: /* @__PURE__ */ jsx4(
10025
10099
  "button",
10026
10100
  {
10027
10101
  onClick: () => {
@@ -10777,7 +10851,7 @@ function ModelNexChatBubble({
10777
10851
  )
10778
10852
  }
10779
10853
  ),
10780
- msg.role === "assistant" && devMode && msg.debug && /* @__PURE__ */ jsx4(AgentTraces, { debug: msg.debug, command: messages[i - 1]?.content ?? "" })
10854
+ msg.role === "assistant" && authoringMode && msg.debug && /* @__PURE__ */ jsx4(AgentTraces, { debug: msg.debug, command: messages[i - 1]?.content ?? "" })
10781
10855
  ] }, i)),
10782
10856
  loading && /* @__PURE__ */ jsx4("div", { style: { display: "flex", justifyContent: "flex-start" }, children: /* @__PURE__ */ jsxs3(
10783
10857
  "div",
@@ -11778,7 +11852,9 @@ var ModelNexProvider = ({
11778
11852
  const [actions, setActions] = useState15(/* @__PURE__ */ new Map());
11779
11853
  const [validatedBrowserDevMode, setValidatedBrowserDevMode] = useState15(false);
11780
11854
  const [resolvedDevModeKey, setResolvedDevModeKey] = useState15(() => resolveInjectedDevModeKey());
11855
+ const [previewRuntimeMode, setPreviewRuntimeMode] = useState15(() => hasDraftPreviewModeSignal());
11781
11856
  useEffect19(() => observeInjectedDevModeKey(setResolvedDevModeKey), []);
11857
+ useEffect19(() => observeDraftPreviewModeSignal(setPreviewRuntimeMode), []);
11782
11858
  useEffect19(() => {
11783
11859
  let cancelled = false;
11784
11860
  if (!websiteId || !resolvedDevModeKey) {
@@ -11795,7 +11871,7 @@ var ModelNexProvider = ({
11795
11871
  cancelled = true;
11796
11872
  };
11797
11873
  }, [resolvedDevModeKey, serverUrl, websiteId]);
11798
- const effectiveDevMode = validatedBrowserDevMode;
11874
+ const effectiveDevMode = validatedBrowserDevMode || previewRuntimeMode;
11799
11875
  const registerAction = useCallback14((action) => {
11800
11876
  setActions((prev) => {
11801
11877
  const next = new Map(prev);
@@ -11892,9 +11968,10 @@ var ModelNexProvider = ({
11892
11968
  voiceMuted,
11893
11969
  setVoiceMuted,
11894
11970
  socketId,
11895
- devMode: effectiveDevMode
11971
+ devMode: effectiveDevMode,
11972
+ authoringMode: validatedBrowserDevMode
11896
11973
  }),
11897
- [serverUrl, commandUrl, registerAction, unregisterAction, activeAgentActions, stagingFields, highlightActions, studioMode, recordingMode, extractedElements, tagStore, chatMessages, websiteId, userProfile?.userId, userProfile?.type, userProfile?.isNewUser, toursApiBase, voiceMuted, socketId, effectiveDevMode]
11974
+ [serverUrl, commandUrl, registerAction, unregisterAction, activeAgentActions, stagingFields, highlightActions, studioMode, recordingMode, extractedElements, tagStore, chatMessages, websiteId, userProfile?.userId, userProfile?.type, userProfile?.isNewUser, toursApiBase, voiceMuted, socketId, effectiveDevMode, validatedBrowserDevMode]
11898
11975
  );
11899
11976
  return React8.createElement(
11900
11977
  ModelNexContext.Provider,
@@ -11924,11 +12001,13 @@ export {
11924
12001
  getPreviewQueryParamName,
11925
12002
  getRecordingDraftActionLabel,
11926
12003
  getRecordingDraftStatusMessage,
12004
+ hasDraftPreviewModeSignal,
11927
12005
  inferOnboardingMetadataForStep,
11928
12006
  isAskDrivenInputStepType,
11929
12007
  isInteractiveInputStepType,
11930
12008
  isManualOnboardingStep,
11931
12009
  isRecordingDraftGenerating,
12010
+ observeDraftPreviewModeSignal,
11932
12011
  persistActiveDraftPreview,
11933
12012
  readActiveDraftPreview,
11934
12013
  shouldPromptForPreviewStart,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelnex/sdk",
3
- "version": "0.5.36",
3
+ "version": "0.5.38",
4
4
  "description": "React SDK for natural language control of web apps via AI agents",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",