@floe-ai/sdk 0.1.0-dev.12 → 0.1.0-dev.14

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.
@@ -839,80 +839,130 @@ ${e.description||""}`;return confirm(r)}async execute(e){if(e.type==="click"){co
839
839
  }
840
840
  </style>
841
841
 
842
- <!-- Icon -->
842
+ <!-- Icon with live indicator -->
843
843
  <div style="display: flex; justify-content: center; margin-bottom: 24px;">
844
- <div style="
845
- width: 64px;
846
- height: 64px;
847
- border-radius: 16px;
848
- background: linear-gradient(135deg, rgba(99, 102, 241, 0.2) 0%, rgba(139, 92, 246, 0.2) 100%);
849
- border: 1px solid rgba(139, 92, 246, 0.3);
850
- display: flex;
851
- align-items: center;
852
- justify-content: center;
853
- box-shadow: 0 8px 24px rgba(139, 92, 246, 0.15);
854
- ">
855
- <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="#a78bfa" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
856
- <path d="M12 2L2 7l10 5 10-5-10-5z"/>
857
- <path d="M2 17l10 5 10-5"/>
858
- <path d="M2 12l10 5 10-5"/>
859
- </svg>
844
+ <div style="position: relative;">
845
+ <div style="
846
+ width: 64px;
847
+ height: 64px;
848
+ border-radius: 16px;
849
+ background: linear-gradient(135deg, rgba(99, 102, 241, 0.2) 0%, rgba(139, 92, 246, 0.2) 100%);
850
+ border: 1px solid rgba(139, 92, 246, 0.3);
851
+ display: flex;
852
+ align-items: center;
853
+ justify-content: center;
854
+ box-shadow: 0 8px 24px rgba(139, 92, 246, 0.15);
855
+ ">
856
+ <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="url(#welcomeIconGradient)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
857
+ <defs>
858
+ <linearGradient id="welcomeIconGradient" x1="0%" y1="0%" x2="100%" y2="100%">
859
+ <stop offset="0%" stop-color="#818cf8" />
860
+ <stop offset="100%" stop-color="#a78bfa" />
861
+ </linearGradient>
862
+ </defs>
863
+ <!-- Headset/support icon -->
864
+ <path d="M3 18v-6a9 9 0 0 1 18 0v6"/>
865
+ <path d="M21 19a2 2 0 0 1-2 2h-1a2 2 0 0 1-2-2v-3a2 2 0 0 1 2-2h3v5z"/>
866
+ <path d="M3 19a2 2 0 0 0 2 2h1a2 2 0 0 0 2-2v-3a2 2 0 0 0-2-2H3v5z"/>
867
+ </svg>
868
+ </div>
869
+ <!-- Live pulse indicator -->
870
+ <div style="
871
+ position: absolute;
872
+ top: -2px;
873
+ right: -2px;
874
+ width: 14px;
875
+ height: 14px;
876
+ background: #10b981;
877
+ border-radius: 50%;
878
+ border: 2px solid rgba(24, 24, 28, 0.99);
879
+ animation: livePulse 2s ease-in-out infinite;
880
+ "></div>
860
881
  </div>
861
882
  </div>
862
883
 
884
+ <style>
885
+ @keyframes livePulse {
886
+ 0%, 100% { box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.4); }
887
+ 50% { box-shadow: 0 0 0 6px rgba(16, 185, 129, 0); }
888
+ }
889
+ #floe-start-guided, #floe-skip-guided {
890
+ cursor: pointer !important;
891
+ }
892
+ #floe-start-guided:hover, #floe-skip-guided:hover {
893
+ cursor: pointer !important;
894
+ }
895
+ </style>
896
+
863
897
  <!-- Title -->
864
898
  <h2 style="margin: 0 0 12px 0; font-size: 20px; font-weight: 600; color: rgba(255, 255, 255, 0.95); text-align: center; letter-spacing: -0.02em;">
865
- Let's personalize your setup
899
+ Your AI guide is ready
866
900
  </h2>
867
901
 
868
902
  <!-- Description -->
869
- <p style="margin: 0 0 20px 0; color: rgba(255, 255, 255, 0.6); font-size: 14px; line-height: 1.6; text-align: center;">
870
- I'll ask a few quick questions to understand your needs, then guide you through the perfect setup for your use case.
903
+ <p style="margin: 0 0 8px 0; color: rgba(255, 255, 255, 0.6); font-size: 14px; line-height: 1.6; text-align: center;">
904
+ Start a live voice conversation to get personalized help setting up your account.
871
905
  </p>
872
906
 
873
- <!-- Benefits -->
874
- <div style="background: rgba(255, 255, 255, 0.03); border-radius: 10px; padding: 14px; margin-bottom: 24px; border: 1px solid rgba(255, 255, 255, 0.05);">
875
- <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;">
876
- <span style="font-size: 14px;">⚡</span>
877
- <span style="font-size: 13px; color: rgba(255, 255, 255, 0.7);">Takes less than a minute</span>
878
- </div>
879
- <div style="display: flex; align-items: center; gap: 10px;">
880
- <span style="font-size: 14px;">🎯</span>
881
- <span style="font-size: 13px; color: rgba(255, 255, 255, 0.7);">Get a customized walkthrough</span>
907
+ <!-- Live badge -->
908
+ <div style="display: flex; justify-content: center; margin-bottom: 28px;">
909
+ <div style="
910
+ display: inline-flex;
911
+ align-items: center;
912
+ gap: 6px;
913
+ padding: 6px 12px;
914
+ background: rgba(16, 185, 129, 0.1);
915
+ border: 1px solid rgba(16, 185, 129, 0.2);
916
+ border-radius: 20px;
917
+ ">
918
+ <div style="width: 6px; height: 6px; background: #10b981; border-radius: 50%;"></div>
919
+ <span style="font-size: 12px; font-weight: 500; color: #10b981;">Live voice assistant</span>
882
920
  </div>
883
921
  </div>
884
922
 
885
923
  <!-- Buttons -->
886
- <div style="display: flex; flex-direction: column; gap: 12px;">
924
+ <div style="display: flex; gap: 12px;">
887
925
  <button id="floe-start-guided" style="
888
- width: 100%;
926
+ flex: 1;
889
927
  padding: 14px 20px;
890
928
  border-radius: 12px;
891
929
  font-size: 14px;
892
930
  font-weight: 600;
893
- cursor: pointer;
931
+ cursor: pointer !important;
894
932
  border: none;
895
- background: linear-gradient(135deg, rgba(99, 102, 241, 0.9) 0%, rgba(139, 92, 246, 0.9) 100%);
933
+ background: linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%);
896
934
  color: white;
897
935
  transition: all 0.2s ease;
898
- box-shadow: 0 4px 12px rgba(99, 102, 241, 0.3);
899
- ">
900
- 🚀 Let's Get Started
901
- </button>
902
- <button id="floe-skip-guided" style="
903
- width: 100%;
904
- padding: 14px 20px;
905
- border-radius: 12px;
906
- font-size: 14px;
907
- font-weight: 500;
908
- cursor: pointer;
909
- border: 1px solid rgba(255, 255, 255, 0.1);
910
- background: rgba(255, 255, 255, 0.05);
911
- color: rgba(255, 255, 255, 0.7);
912
- transition: all 0.2s ease;
936
+ box-shadow: 0 4px 12px rgba(99, 102, 241, 0.25);
937
+ display: flex;
938
+ align-items: center;
939
+ justify-content: center;
940
+ gap: 8px;
913
941
  ">
914
- Skip I'll explore on my own
942
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
943
+ <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
944
+ <path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
945
+ <line x1="12" y1="19" x2="12" y2="23"/>
946
+ <line x1="8" y1="23" x2="16" y2="23"/>
947
+ </svg>
948
+ Start Conversation
915
949
  </button>
916
950
  </div>
917
- `,r.appendChild(i),document.body.appendChild(r);const o=r.querySelector("#floe-start-guided"),s=r.querySelector("#floe-skip-guided");o&&(o.onmouseenter=()=>{o.style.transform="translateY(-2px)",o.style.boxShadow="0 8px 20px rgba(99, 102, 241, 0.4)"},o.onmouseleave=()=>{o.style.transform="translateY(0)",o.style.boxShadow="0 4px 12px rgba(99, 102, 241, 0.3)"},o.onclick=()=>{r.style.animation="welcomeFadeOut 0.2s ease",setTimeout(()=>{r.remove(),n(!0)},200)}),s&&(s.onmouseenter=()=>{s.style.background="rgba(255, 255, 255, 0.1)",s.style.color="rgba(255, 255, 255, 0.9)"},s.onmouseleave=()=>{s.style.background="rgba(255, 255, 255, 0.05)",s.style.color="rgba(255, 255, 255, 0.7)"},s.onclick=()=>{r.style.animation="welcomeFadeOut 0.2s ease",setTimeout(()=>{r.remove(),n(!1)},200)}),console.log("[OnboardingSDK] Welcome popup shown (async)")})}showWelcomePopup(){this.showWelcomePopupAsync().then(n=>{n?this.startGuidedDiscovery():this.skipDiscovery()})}hideWelcomePopup(){const n=document.getElementById("floe-welcome-popup");n&&(n.style.animation="welcomeFadeOut 0.2s ease",setTimeout(()=>n.remove(),200)),console.log("[OnboardingSDK] Welcome popup hidden")}shouldShowDiscoveryPrompt(){const n=localStorage.getItem("floe_has_visited"),r=localStorage.getItem("floe_onboarding_complete");return!n||!r}async checkEndUserStatus(){var n,r,i,o,s;try{const a=`${this.config.apiUrl}/end-users/check-status`,l={clientKey:this.config.clientKey,origin:window.location.origin};(n=this.config.userInfo)!=null&&n.externalId&&(l.externalId=this.config.userInfo.externalId),(r=this.config.userInfo)!=null&&r.email&&(l.email=this.config.userInfo.email),this.config.debug&&console.log("[OnboardingSDK] Checking EndUser status...",{externalId:l.externalId?"***":void 0,email:l.email?"***":void 0});const c=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)});if(!c.ok){console.warn(`[OnboardingSDK] EndUser status check failed: ${c.status}`);return}this.endUserStatus=await c.json(),console.log(`[OnboardingSDK] EndUser status: found=${(i=this.endUserStatus)==null?void 0:i.found}, isNewUser=${(o=this.endUserStatus)==null?void 0:o.isNewUser}, hasPreferences=${(s=this.endUserStatus)==null?void 0:s.hasPreferences}`)}catch(a){console.warn("[OnboardingSDK] Error checking EndUser status:",a)}}getEndUserPreferences(){var n;return((n=this.endUserStatus)==null?void 0:n.preferences)||null}shouldSkipOnboardingModal(){var o,s;if(typeof this.config.skipOnboardingModal=="boolean")return console.log(`[OnboardingSDK] skipOnboardingModal explicitly set to: ${this.config.skipOnboardingModal}`),this.config.skipOnboardingModal;if((o=this.endUserStatus)!=null&&o.found&&!this.endUserStatus.isNewUser)return console.log("[OnboardingSDK] Skipping modal: existing EndUser (isNewUser=false)"),!0;const n=localStorage.getItem("floe_has_visited")==="true",r=!!((s=this.config.userInfo)!=null&&s.externalId),i=n||r;return console.log(`[OnboardingSDK] Auto-detect skip modal: ${i} (hasVisited: ${n}, hasUserIdentity: ${r})`),i}markUserVisited(){localStorage.setItem("floe_has_visited","true")}markOnboardingComplete(){localStorage.setItem("floe_onboarding_complete","true")}async disconnect(){this.pageTracker.stop(),this.domIntrospector.stopCapturing(),this.navigationCompleteDetector&&this.navigationCompleteDetector.stop(),this.overlay.clearHighlight(),this.pipecatClient&&(await this.pipecatClient.disconnect(),this.pipecatClient=null),this.transport&&(this.transport=null),this.audioElements&&(this.audioElements.forEach(n=>{n.pause(),n.remove()}),this.audioElements=[]),this.botAudioAnalyzer&&(this.botAudioAnalyzer.destroy(),this.botAudioAnalyzer=null),this.userAudioAnalyzer&&(this.userAudioAnalyzer.destroy(),this.userAudioAnalyzer=null),this.userMicStreamRequestId++,this.userMicStream&&(this.userMicStream.getTracks().forEach(n=>n.stop()),this.userMicStream=null),this.audioLevels=[],this.reactRoot&&(this.reactRoot.unmount(),this.reactRoot=null),this.reactContainer&&(this.reactContainer.remove(),this.reactContainer=null),this.overlay.remove(),this.isInitialized=!1,this.isConnected=!1,this.agentState="idle",console.log("[OnboardingSDK] Disconnected"),this.emit("disconnected")}}typeof window<"u"&&(window.OnboardingSDK=sy);function Ox(t){return{clientKey:t.clientKey,...t.apiUrl!==void 0&&{apiUrl:t.apiUrl},enableVideo:!1,enableAudio:t.enableAudio??!0,enableScreenCapture:t.enableScreenCapture??!0,debug:t.debug??!1,industry:t.industry,useCase:t.useCase,companyName:t.companyName,companySize:t.companySize,role:t.role,userInfo:t.userInfo,skipOnboardingModal:t.skipOnboardingModal,enableDiscoveryPopup:!0}}function ay(t){if(!t.clientKey)throw new Error("[Floe] clientKey is required");const e=Ox(t),n=new sy(e);return n.ready=n.init().catch(r=>{throw console.error("[Floe] Initialization failed:",r),r}),n}typeof window<"u"&&(window.Floe=ay),_t.Floe=ay,Object.defineProperty(_t,Symbol.toStringTag,{value:"Module"})});
951
+
952
+ <button id="floe-skip-guided" style="
953
+ width: 100%;
954
+ margin-top: 12px;
955
+ padding: 12px 20px;
956
+ border-radius: 12px;
957
+ font-size: 14px;
958
+ font-weight: 500;
959
+ cursor: pointer !important;
960
+ border: none;
961
+ background: transparent;
962
+ color: rgba(255, 255, 255, 0.4);
963
+ transition: all 0.2s ease;
964
+ ">
965
+ I'll explore on my own
966
+ </button>
967
+ `,r.appendChild(i),document.body.appendChild(r);const o=r.querySelector("#floe-start-guided"),s=r.querySelector("#floe-skip-guided");o&&(o.onmouseenter=()=>{o.style.background="linear-gradient(135deg, #818cf8 0%, #a78bfa 100%)",o.style.transform="translateY(-1px)",o.style.boxShadow="0 8px 24px rgba(99, 102, 241, 0.4)"},o.onmouseleave=()=>{o.style.background="linear-gradient(135deg, #6366f1 0%, #8b5cf6 100%)",o.style.transform="translateY(0)",o.style.boxShadow="0 4px 12px rgba(99, 102, 241, 0.25)"},o.onclick=()=>{r.style.animation="welcomeFadeOut 0.2s ease",setTimeout(()=>{r.remove(),n(!0)},200)}),s&&(s.onmouseenter=()=>{s.style.color="rgba(255, 255, 255, 0.8)"},s.onmouseleave=()=>{s.style.color="rgba(255, 255, 255, 0.4)"},s.onclick=()=>{r.style.animation="welcomeFadeOut 0.2s ease",setTimeout(()=>{r.remove(),n(!1)},200)}),console.log("[OnboardingSDK] Welcome popup shown (async)")})}showWelcomePopup(){this.showWelcomePopupAsync().then(n=>{n?this.startGuidedDiscovery():this.skipDiscovery()})}hideWelcomePopup(){const n=document.getElementById("floe-welcome-popup");n&&(n.style.animation="welcomeFadeOut 0.2s ease",setTimeout(()=>n.remove(),200)),console.log("[OnboardingSDK] Welcome popup hidden")}shouldShowDiscoveryPrompt(){const n=localStorage.getItem("floe_has_visited"),r=localStorage.getItem("floe_onboarding_complete");return!n||!r}async checkEndUserStatus(){var n,r,i,o,s;try{const a=`${this.config.apiUrl}/end-users/check-status`,l={clientKey:this.config.clientKey,origin:window.location.origin};(n=this.config.userInfo)!=null&&n.externalId&&(l.externalId=this.config.userInfo.externalId),(r=this.config.userInfo)!=null&&r.email&&(l.email=this.config.userInfo.email),this.config.debug&&console.log("[OnboardingSDK] Checking EndUser status...",{externalId:l.externalId?"***":void 0,email:l.email?"***":void 0});const c=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(l)});if(!c.ok){console.warn(`[OnboardingSDK] EndUser status check failed: ${c.status}`);return}this.endUserStatus=await c.json(),console.log(`[OnboardingSDK] EndUser status: found=${(i=this.endUserStatus)==null?void 0:i.found}, isNewUser=${(o=this.endUserStatus)==null?void 0:o.isNewUser}, hasPreferences=${(s=this.endUserStatus)==null?void 0:s.hasPreferences}`)}catch(a){console.warn("[OnboardingSDK] Error checking EndUser status:",a)}}getEndUserPreferences(){var n;return((n=this.endUserStatus)==null?void 0:n.preferences)||null}shouldSkipOnboardingModal(){var o,s;if(typeof this.config.skipOnboardingModal=="boolean")return console.log(`[OnboardingSDK] skipOnboardingModal explicitly set to: ${this.config.skipOnboardingModal}`),this.config.skipOnboardingModal;if((o=this.endUserStatus)!=null&&o.found&&!this.endUserStatus.isNewUser)return console.log("[OnboardingSDK] Skipping modal: existing EndUser (isNewUser=false)"),!0;const n=localStorage.getItem("floe_has_visited")==="true",r=!!((s=this.config.userInfo)!=null&&s.externalId),i=n||r;return console.log(`[OnboardingSDK] Auto-detect skip modal: ${i} (hasVisited: ${n}, hasUserIdentity: ${r})`),i}markUserVisited(){localStorage.setItem("floe_has_visited","true")}markOnboardingComplete(){localStorage.setItem("floe_onboarding_complete","true")}async disconnect(){this.pageTracker.stop(),this.domIntrospector.stopCapturing(),this.navigationCompleteDetector&&this.navigationCompleteDetector.stop(),this.overlay.clearHighlight(),this.pipecatClient&&(await this.pipecatClient.disconnect(),this.pipecatClient=null),this.transport&&(this.transport=null),this.audioElements&&(this.audioElements.forEach(n=>{n.pause(),n.remove()}),this.audioElements=[]),this.botAudioAnalyzer&&(this.botAudioAnalyzer.destroy(),this.botAudioAnalyzer=null),this.userAudioAnalyzer&&(this.userAudioAnalyzer.destroy(),this.userAudioAnalyzer=null),this.userMicStreamRequestId++,this.userMicStream&&(this.userMicStream.getTracks().forEach(n=>n.stop()),this.userMicStream=null),this.audioLevels=[],this.reactRoot&&(this.reactRoot.unmount(),this.reactRoot=null),this.reactContainer&&(this.reactContainer.remove(),this.reactContainer=null),this.overlay.remove(),this.isInitialized=!1,this.isConnected=!1,this.agentState="idle",console.log("[OnboardingSDK] Disconnected"),this.emit("disconnected")}}typeof window<"u"&&(window.OnboardingSDK=sy);function Ox(t){return{clientKey:t.clientKey,...t.apiUrl!==void 0&&{apiUrl:t.apiUrl},enableVideo:!1,enableAudio:t.enableAudio??!0,enableScreenCapture:t.enableScreenCapture??!0,debug:t.debug??!1,industry:t.industry,useCase:t.useCase,companyName:t.companyName,companySize:t.companySize,role:t.role,userInfo:t.userInfo,skipOnboardingModal:t.skipOnboardingModal,enableDiscoveryPopup:!0}}function ay(t){if(!t.clientKey)throw new Error("[Floe] clientKey is required");const e=Ox(t),n=new sy(e);return n.ready=n.init().catch(r=>{throw console.error("[Floe] Initialization failed:",r),r}),n}typeof window<"u"&&(window.Floe=ay),_t.Floe=ay,Object.defineProperty(_t,Symbol.toStringTag,{value:"Module"})});
918
968
  //# sourceMappingURL=floe-sdk.umd.js.map