@rubytech/create-realagent 1.0.444 → 1.0.446

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.
@@ -0,0 +1,5 @@
1
+ import{C as e,D as t,S as n,T as r,_ as i,a,b as o,d as s,f as c,h as l,i as u,j as d,k as f,m as p,n as m,p as h,r as g,s as _,t as v,u as y,v as b,w as x,x as S,y as C}from"./ChatInput-CIVDMwyt.js";var w=t(),T=d(f(),1),E=`image/jpeg,image/png,image/gif,image/webp,application/pdf,text/plain,text/markdown,text/csv`,D=new Set(E.split(`,`)),O=20*1024*1024,k=typeof window<`u`&&/^(localhost|127\.0\.0\.1|[a-z0-9-]+\.local)(:|$)/.test(window.location.hostname);function A(){let e=crypto.getRandomValues(new Uint8Array(16));e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=[...e].map(e=>e.toString(16).padStart(2,`0`)).join(``);return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}function j(){let e=window.location.pathname.match(/^\/([a-z][a-z0-9-]{2,49})$/);return e?e[1]:void 0}function M(e){return[{key:`length`,label:`At least 8 characters`,met:e.length>=8},{key:`number`,label:`Contains a number`,met:/\d/.test(e)},{key:`special`,label:`Contains a special character`,met:/[^A-Za-z0-9]/.test(e)},{key:`whitespace`,label:`No leading or trailing spaces`,met:e.length>0&&e===e.trim()}]}function N(e,t){if(t===`phone`)return e.length>4?e.slice(0,e.length-4).replace(/\d/g,`•`)+` `+e.slice(-4):e;let n=e.indexOf(`@`);return n<=2?e:e.slice(0,2)+`•••`+e.slice(n)}function P(e){let[t,n]=(0,T.useState)(null),[r,i]=(0,T.useState)(null),[a,o]=(0,T.useState)(`loading`),[s,c]=(0,T.useState)(``),[l,u]=(0,T.useState)(null),d=(0,T.useMemo)(()=>j(),[]),f=(0,T.useRef)(d||``),p=(0,T.useRef)(null),m=(0,T.useRef)(null),h=(0,T.useRef)(!1),g=(0,T.useRef)(null),[_,v]=(0,T.useState)(`sign-in`),[y,b]=(0,T.useState)(null),x=(0,T.useRef)(null),S=(0,T.useRef)(null);(0,T.useEffect)(()=>{try{let e=sessionStorage.getItem(`maxy_session`);e&&(S.current=e)}catch{}},[]);let C=(0,T.useCallback)(t=>{p.current=t,n(t);try{sessionStorage.setItem(`maxy_session`,t)}catch{}o(`chat`),e(t)},[e]),w=(0,T.useCallback)(()=>{p.current=null;try{sessionStorage.removeItem(`maxy_session`)}catch{}n(null),o(`auth-required`),v(`sign-in`)},[]),E=(0,T.useCallback)(async e=>{try{let t=f.current,n=await fetch(`/api/access/verify-token`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({token:e,agentSlug:t})}),r=await n.json();n.ok?(x.current=r.session_key,b(r.grant),v(`set-password`),window.history.replaceState({},``,window.location.pathname)):v(`link-expired`)}catch{v(`sign-in`)}},[]);return{sessionId:t,sessionKeyRef:p,sessionError:r,pageState:a,setPageState:o,agentDisplayName:s,agentSlug:d,branding:l,resolvedSlugRef:f,ensureSession:(0,T.useCallback)(async()=>{if(p.current)return p.current;if(m.current)return m.current;let e=(async()=>{try{let e=S.current,t=await fetch(`/api/session`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({session_id:A(),...d?{agent:d}:{},...e?{session_key:e}:{}})});if(!t.ok){let e=await t.json().catch(()=>({error:``}));return k&&console.error(`[session] POST /api/session failed: ${t.status} ${t.statusText}`,e),t.status===404?i(e.error||`Agent not found`):t.status===503&&i(e.error||`Service unavailable`),null}let r=await t.json();if(r.auth_required){r.agent_id&&(f.current=r.agent_id),c(r.displayName||``),r.branding&&u(r.branding),o(`auth-required`);let e=new URLSearchParams(window.location.search).get(`token`);return e?E(e):v(`sign-in`),null}p.current=r.session_key,n(r.session_key),r.branding&&u(r.branding),o(`chat`),r.resumed&&r.messages&&(h.current=!0,g.current=r.messages);try{sessionStorage.setItem(`maxy_session`,r.session_key)}catch{}return r.session_key}catch(e){return k&&console.error(`[session] fetch /api/session threw:`,e),i(`Unable to connect. Please check your connection and try again.`),null}finally{m.current=null}})();return m.current=e,e},[d,E]),enterChat:C,enterGate:w,resumedRef:h,resumeMessagesRef:g,gateState:_,setGateState:v,grantInfo:y,setGrantInfo:b,gateSessionKeyRef:x}}function F({sessionKeyRef:e,ensureSession:t,sessionError:n,pageState:r,inputRef:a}){let[o,s]=(0,T.useState)([]),[c,l]=(0,T.useState)(!1),u=(0,T.useRef)(!1),d=e=>{u.current=e,l(e)},f=(0,T.useCallback)(async o=>{if(!u.current){d(!0),s([{role:`maxy`,content:``,timestamp:Date.now()}]);try{let n=await fetch(`/api/chat`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({greeting:!0,session_key:o})});if(n.status===401){e.current=null;try{sessionStorage.removeItem(`maxy_session`)}catch{}k&&console.warn(`[greeting] stale session, retrying with fresh session`);let r=await t();if(!r)return;n=await fetch(`/api/chat`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({greeting:!0,session_key:r})})}if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error||`Something went wrong`)}let r=``,a=``,c=()=>{a&&(r+=a,a=``,s(e=>{let t=[...e];return t[0]={...t[0],content:r},t}))},l=setInterval(c,60);try{for await(let e of i(n)){if(e.error)throw Object.assign(Error(e.error),{fromSSE:!0});e.text&&(a+=e.text),e.type===`component`&&(c(),s(t=>{let n=[...t],r={...n[0]},i=[...r.components||[]];return i.push({name:e.name,data:e.data,submitted:!1}),n[0]={...r,components:i},n}))}}finally{clearInterval(l),c()}}catch(e){if(k&&console.error(`[chat] greeting failed:`,e),r===`auth-required`)return;let t=e instanceof Error?e.message:String(e);s([{role:`maxy`,content:e instanceof Error&&e.fromSSE?t:n??`I'm having trouble connecting right now. Try refreshing the page.`,timestamp:Date.now()}])}finally{d(!1),r===`chat`&&a.current?.focus()}}},[e,t,n,r,a]),p=(0,T.useCallback)(async(o,c)=>{let l=c?.hidden??!1,f=c?.files??[];if(!o&&f.length===0||u.current)return;d(!0);let p=f.map(e=>({filename:e.name,mimeType:e.type})),m={role:`visitor`,content:o,attachments:p.length>0?p:void 0,timestamp:Date.now(),hidden:l},h;s(e=>{let t=[...e,m,{role:`maxy`,content:``,timestamp:Date.now()}];return h=t.length-1,t});try{let n=await t();if(!n)throw Error(`session`);let r=e=>{if(f.length>0){let t=new FormData;t.append(`message`,o),t.append(`session_key`,e);for(let e of f)t.append(`attachments`,e);return{body:t,headers:{}}}return{body:JSON.stringify({message:o,session_key:e}),headers:{"Content-Type":`application/json`}}},{body:a,headers:c}=r(n),l=await fetch(`/api/chat`,{method:`POST`,headers:c,body:a});if(l.status===401){e.current=null;try{sessionStorage.removeItem(`maxy_session`)}catch{}k&&console.warn(`[session-expired] stale key cleared, retrying with fresh session`);let n=await t();if(!n)throw Error(`session`);({body:a,headers:c}=r(n)),l=await fetch(`/api/chat`,{method:`POST`,headers:c,body:a})}if(!l.ok){let e=await l.json().catch(()=>({}));throw Error(e.error||`Something went wrong`)}let u=``,d=``,p=()=>{d&&(u+=d,d=``,s(e=>{let t=[...e];return t[h]={...t[h],content:u},t}))},m=setInterval(p,60);try{for await(let e of i(l)){if(e.error)throw Object.assign(Error(e.error),{fromSSE:!0});e.text&&(d+=e.text),e.type===`component`&&(p(),s(t=>{let n=[...t],r={...n[h]},i=[...r.components||[]];return i.push({name:e.name,data:e.data,submitted:!1}),n[h]={...r,components:i},n}))}}finally{clearInterval(m),p()}}catch(e){if(k&&console.error(`[chat] sendMessage failed:`,e),r===`auth-required`)return;let t=e instanceof Error?e.message:String(e),i=e instanceof Error&&e.fromSSE;s(e=>{let r=[...e];return r[h]={...r[h],content:i?t:t===`session`?n??`I'm having trouble connecting right now. Try refreshing the page.`:`Sorry, I hit a snag. Try again in a moment.`},r})}finally{d(!1),r===`chat`&&a.current?.focus()}},[e,t,n,r,a]);return{messages:o,setMessages:s,isStreaming:c,sendMessage:p,sendGreeting:f,handleComponentSubmit:(0,T.useCallback)((e,t,n)=>{s(n=>{let r=[...n],i={...r[e]},a=[...i.components||[]];return a[t]={...a[t],submitted:!0},r[e]={...i,components:a},r}),p(n,{hidden:!0})},[p])}}var I=c();function L({value:e,onChange:t,onComplete:n,disabled:r}){let i=(0,T.useRef)([]);function a(n,r){r.key===`Backspace`?(r.preventDefault(),e[n]?t(e.slice(0,n)+e.slice(n+1)):n>0&&(t(e.slice(0,n-1)+e.slice(n)),i.current[n-1]?.focus())):r.key===`ArrowLeft`&&n>0?i.current[n-1]?.focus():r.key===`ArrowRight`&&n<5&&i.current[n+1]?.focus()}function o(r,a){let o=a.nativeEvent.data;if(!o||!/^\d$/.test(o))return;let s=e.split(``);for(s[r]=o;s.length<r;)s.push(``);let c=s.join(``).replace(/\D/g,``).slice(0,6);t(c),c.length===6?n(c):r<5&&i.current[r+1]?.focus()}function s(e){e.preventDefault();let r=e.clipboardData.getData(`text`).replace(/\D/g,``).slice(0,6);r&&(t(r),r.length===6?n(r):i.current[r.length]?.focus())}return(0,I.jsx)(`div`,{className:`gate-otp-field`,children:Array.from({length:6}).map((t,n)=>(0,I.jsx)(`input`,{ref:e=>{i.current[n]=e},type:`text`,inputMode:`numeric`,className:`pin-box${e[n]?` pin-box-filled`:``}`,value:e[n]||``,onKeyDown:e=>a(n,e),onInput:e=>o(n,e),onPaste:s,onFocus:e=>e.target.select(),autoFocus:n===0,autoComplete:`off`,maxLength:1,disabled:r,"aria-label":`Code digit ${n+1}`},n))})}function R({gateState:e,setGateState:t,grantInfo:n,setGrantInfo:r,gateSessionKeyRef:i,resolvedSlugRef:a,onAuthenticated:o}){let[c,l]=(0,T.useState)(``),[u,d]=(0,T.useState)(``),[f,p]=(0,T.useState)(``),[m,h]=(0,T.useState)(!1),[g,_]=(0,T.useState)(``),[v,b]=(0,T.useState)(``),[x,S]=(0,T.useState)(!1),[C,w]=(0,T.useState)(null),[E,D]=(0,T.useState)(null),[O,k]=(0,T.useState)(!1);async function A(e){if(e.preventDefault(),!O){w(null),k(!0);try{let e=a.current,n=await fetch(`/api/access/login`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({contact:c,password:u,agentSlug:e})}),i=await n.json();n.ok?o(i.session_key):n.status===401?i.error?.includes(`setup not complete`)||i.error?.includes(`invitation link`)?(t(`private-agent`),w(null)):w(i.error||`Invalid credentials`):n.status===403?(t(`access-expired`),i.expiresAt&&r(e=>e?{...e,expiresAt:i.expiresAt}:{displayName:null,contactValue:c,contactMethod:`email`,expiresAt:i.expiresAt,status:`expired`})):n.status===429?w(i.error||`Too many attempts. Please try again later.`):w(i.error||`Something went wrong`)}catch{w(`Unable to connect. Please try again.`)}finally{k(!1)}}}async function j(e){if(!O){w(null),k(!0);try{let n=a.current,o=await fetch(`/api/access/verify-otp`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({phone:v,code:e,agentSlug:n})}),s=await o.json();o.ok?(i.current=s.session_key,r(s.grant),t(`set-password`)):o.status===429?t(`otp-failed`):(w(s.error||`Invalid code`),_(``))}catch{w(`Unable to connect. Please try again.`)}finally{k(!1)}}}async function P(e){if(e.preventDefault(),!O){if(w(null),u!==f){w(`Passwords do not match`);return}if(!M(u).every(e=>e.met)){w(`Password does not meet requirements`);return}k(!0);try{let e=i.current;if(!e){w(`Session expired. Please use your invitation link again.`);return}let t=await fetch(`/api/access/create-credentials`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({session_key:e,password:u})}),n=await t.json();t.ok?o(n.session_key):t.status===400&&n.requirements?w(n.requirements.filter(e=>!e.met).map(e=>e.label).join(`, `)):w(n.error||`Something went wrong`)}catch{w(`Unable to connect. Please try again.`)}finally{k(!1)}}}async function F(e){if(e.preventDefault(),!(O||!c)){w(null),k(!0);try{let e=a.current,t=await fetch(`/api/access/forgot-password`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({contact:c,agentSlug:e})});t.status===429?w((await t.json()).error||`Too many attempts. Please try again later.`):(D(`If an account exists, a reset link has been sent.`),setTimeout(()=>{S(!1),D(null)},4e3))}catch{w(`Unable to connect. Please try again.`)}finally{k(!1)}}}switch(e){case`set-password`:{let e=M(u),t=e.every(e=>e.met),r=u===f,i=t&&r&&f.length>0;return(0,I.jsx)(`div`,{className:`gate-wrap`,children:(0,I.jsxs)(`div`,{className:`gate-card`,children:[n?.expiresAt&&(0,I.jsxs)(`div`,{className:`gate-expiry-badge`,children:[`Access until `,new Date(n.expiresAt).toLocaleDateString(`en-GB`,{day:`numeric`,month:`short`,year:`numeric`})]}),(0,I.jsxs)(`h2`,{className:`gate-title`,children:[`Welcome, `,n?.displayName||`there`]}),(0,I.jsx)(`p`,{className:`gate-subtitle`,children:`Create a password to access this agent in the future.`}),(0,I.jsxs)(`form`,{className:`gate-form`,onSubmit:P,children:[(0,I.jsxs)(`div`,{className:`gate-field`,children:[(0,I.jsx)(`label`,{htmlFor:`gate-display-name`,children:`Display name`}),(0,I.jsx)(`input`,{id:`gate-display-name`,type:`text`,value:n?.displayName||``,disabled:!0})]}),(0,I.jsxs)(`div`,{className:`gate-field gate-pw-row`,children:[(0,I.jsx)(`label`,{htmlFor:`gate-pw`,children:`Password`}),(0,I.jsx)(`div`,{className:`gate-pw-toggle`,children:(0,I.jsx)(s,{checked:m,onChange:h,label:`Show`})}),(0,I.jsx)(`input`,{id:`gate-pw`,type:m?`text`:`password`,value:u,onChange:e=>d(e.target.value),placeholder:`Your password`,autoFocus:!0,autoComplete:`new-password`}),u.length>0&&(0,I.jsx)(`div`,{className:`gate-strength`,children:e.map(e=>(0,I.jsxs)(`span`,{className:`gate-strength-item${e.met?` met`:``}`,children:[e.met?`✓`:`○`,` `,e.label]},e.key))})]}),(0,I.jsxs)(`div`,{className:`gate-field`,children:[(0,I.jsx)(`label`,{htmlFor:`gate-pw-confirm`,children:`Confirm password`}),(0,I.jsx)(`input`,{id:`gate-pw-confirm`,type:m?`text`:`password`,value:f,onChange:e=>p(e.target.value),placeholder:`Confirm your password`,autoComplete:`new-password`}),f.length>0&&!r&&(0,I.jsx)(`div`,{className:`gate-error`,children:`Passwords do not match`})]}),C&&(0,I.jsx)(`div`,{className:`gate-error`,children:C}),(0,I.jsx)(`div`,{className:`gate-submit`,children:(0,I.jsx)(y,{variant:`primary`,type:`submit`,fullWidth:!0,disabled:!i||O,loading:O,children:`Create account & enter chat`})})]})]})})}case`enter-otp`:return(0,I.jsx)(`div`,{className:`gate-wrap`,children:(0,I.jsxs)(`div`,{className:`gate-card`,children:[(0,I.jsx)(`h2`,{className:`gate-title`,children:`Enter your code`}),(0,I.jsxs)(`p`,{className:`gate-subtitle`,children:[`Enter the 6-digit code sent to `,N(v,`phone`)]}),(0,I.jsx)(L,{value:g,onChange:_,onComplete:j,disabled:O}),C&&(0,I.jsx)(`div`,{className:`gate-error`,children:C}),O&&(0,I.jsxs)(`div`,{className:`gate-loading`,children:[(0,I.jsx)(`span`,{className:`spinner`}),`Verifying...`]}),(0,I.jsx)(`div`,{className:`gate-resend`,children:(0,I.jsx)(`button`,{type:`button`,className:`gate-link`,onClick:()=>{t(`sign-in`),_(``),w(null)},children:`Use a different number`})})]})});case`sign-in`:case`private-agent`:return(0,I.jsx)(`div`,{className:`gate-wrap`,children:(0,I.jsxs)(`div`,{className:`gate-card`,children:[(0,I.jsx)(`h2`,{className:`gate-title`,children:e===`private-agent`?`Private Agent`:`Welcome back`}),(0,I.jsx)(`p`,{className:`gate-subtitle`,children:e===`private-agent`?`This agent is invitation-only. If you have an account, sign in below.`:`Sign in to continue your conversation.`}),x?(0,I.jsxs)(`form`,{className:`gate-form`,onSubmit:F,children:[(0,I.jsxs)(`div`,{className:`gate-field`,children:[(0,I.jsx)(`label`,{htmlFor:`gate-forgot-contact`,children:`Email or phone`}),(0,I.jsx)(`input`,{id:`gate-forgot-contact`,type:`text`,value:c,onChange:e=>l(e.target.value),placeholder:`you@example.com`,autoFocus:!0,autoComplete:`email`})]}),C&&(0,I.jsx)(`div`,{className:`gate-error`,children:C}),E&&(0,I.jsx)(`div`,{className:`gate-success`,children:E}),(0,I.jsx)(`div`,{className:`gate-submit`,children:(0,I.jsx)(y,{variant:`primary`,type:`submit`,fullWidth:!0,disabled:!c.trim()||O,loading:O,children:`Send reset link`})}),(0,I.jsx)(`div`,{className:`gate-actions`,children:(0,I.jsx)(`button`,{type:`button`,className:`gate-link`,onClick:()=>{S(!1),w(null),D(null)},children:`Back to sign in`})})]}):(0,I.jsxs)(`form`,{className:`gate-form`,onSubmit:A,children:[(0,I.jsxs)(`div`,{className:`gate-field`,children:[(0,I.jsx)(`label`,{htmlFor:`gate-contact`,children:`Email or phone`}),(0,I.jsx)(`input`,{id:`gate-contact`,type:`text`,value:c,onChange:e=>l(e.target.value),placeholder:`you@example.com`,autoFocus:!0,autoComplete:`email`})]}),(0,I.jsxs)(`div`,{className:`gate-field gate-pw-row`,children:[(0,I.jsx)(`label`,{htmlFor:`gate-login-pw`,children:`Password`}),(0,I.jsx)(`div`,{className:`gate-pw-toggle`,children:(0,I.jsx)(s,{checked:m,onChange:h,label:`Show`})}),(0,I.jsx)(`input`,{id:`gate-login-pw`,type:m?`text`:`password`,value:u,onChange:e=>d(e.target.value),placeholder:`Your password`,autoComplete:`current-password`})]}),C&&(0,I.jsx)(`div`,{className:`gate-error`,children:C}),(0,I.jsx)(`div`,{className:`gate-submit`,children:(0,I.jsx)(y,{variant:`primary`,type:`submit`,fullWidth:!0,disabled:!c.trim()||!u||O,loading:O,children:`Sign in`})}),(0,I.jsx)(`div`,{className:`gate-actions`,children:(0,I.jsx)(`button`,{type:`button`,className:`gate-link`,onClick:()=>{S(!0),w(null)},children:`Forgot password?`})})]}),e===`private-agent`&&(0,I.jsx)(`p`,{className:`gate-hint`,children:`No account? You need an invitation from the agent owner.`})]})});case`access-expired`:return(0,I.jsx)(`div`,{className:`gate-wrap`,children:(0,I.jsxs)(`div`,{className:`gate-card`,children:[(0,I.jsx)(`div`,{className:`gate-icon`,children:`⏰`}),(0,I.jsx)(`h2`,{className:`gate-title`,children:`Access expired`}),(0,I.jsxs)(`p`,{className:`gate-subtitle`,children:[n?.expiresAt?`Your access expired on ${new Date(n.expiresAt).toLocaleDateString(`en-GB`,{day:`numeric`,month:`long`,year:`numeric`})}.`:`Your access to this agent has expired.`,` `,`Contact the agent owner to renew.`]}),(0,I.jsx)(`div`,{className:`gate-actions`,children:(0,I.jsx)(y,{variant:`secondary`,onClick:()=>{t(`sign-in`),w(null),d(``)},children:`Sign in with a different account`})})]})});case`link-expired`:return(0,I.jsx)(`div`,{className:`gate-wrap`,children:(0,I.jsxs)(`div`,{className:`gate-card`,children:[(0,I.jsx)(`div`,{className:`gate-icon`,children:`⚠️`}),(0,I.jsx)(`h2`,{className:`gate-title`,children:`Link expired`}),(0,I.jsx)(`p`,{className:`gate-subtitle`,children:`This invitation link has expired or has already been used. If you already set your password, sign in below. Otherwise, ask the agent owner to send a new invitation.`}),(0,I.jsx)(`div`,{className:`gate-actions`,children:(0,I.jsx)(y,{variant:`primary`,onClick:()=>{t(`sign-in`),w(null)},children:`Go to sign in`})})]})});case`otp-failed`:return(0,I.jsx)(`div`,{className:`gate-wrap`,children:(0,I.jsxs)(`div`,{className:`gate-card`,children:[(0,I.jsx)(`div`,{className:`gate-icon`,children:`⛔`}),(0,I.jsx)(`h2`,{className:`gate-title`,children:`Too many attempts`}),(0,I.jsx)(`p`,{className:`gate-subtitle`,children:`You've entered the wrong code too many times. Ask the agent owner to send a new code.`}),(0,I.jsx)(`div`,{className:`gate-actions`,children:(0,I.jsx)(y,{variant:`secondary`,onClick:()=>{t(`sign-in`),w(null),_(``)},children:`Back to sign in`})})]})})}}var z={"single-select":a,"multi-select":u};function B({name:e,data:t,onSubmit:n,submitted:r}){let i=z[e];return i?(0,I.jsx)(i,{data:t,onSubmit:n,submitted:r}):(console.warn(`[PublicComponentRenderer] Unknown component: "${e}". Registered: ${Object.keys(z).join(`, `)}`),(0,I.jsx)(`div`,{className:`component-card component-card--error`,children:(0,I.jsxs)(`p`,{style:{fontFamily:`var(--font-body)`,fontSize:12,color:`var(--text-secondary)`},children:[`Component “`,e,`” is not available. This may require a platform update.`]})}))}function V({messages:t,isStreaming:i,sessionError:a,selectionMode:o,selectedItems:c,toggleSelectItem:l,onComponentSubmit:u,remainingSuggestions:d,onSuggestionClick:f,isAtBottom:p,setIsAtBottom:m}){let[h,v]=(0,T.useState)(new Set),[b,x]=(0,T.useState)(new Set),S=(0,T.useRef)(null),C=(0,T.useRef)(null),w=(0,T.useRef)(null),E=(0,T.useRef)(!1),D=(0,T.useRef)(!1),O=(0,T.useRef)(0),k=(0,T.useRef)(!1),A=(0,T.useRef)(new Map);k.current=i,(0,T.useEffect)(()=>{i&&!E.current&&p&&(D.current=!0)},[i,p]),(0,T.useEffect)(()=>{if(!D.current&&!p){E.current=i;return}if(E.current&&!i&&w.current&&C.current){let e=w.current;if(e.offsetHeight>C.current.clientHeight){e.scrollIntoView({behavior:`smooth`,block:`start`}),E.current=i;return}}(p||D.current)&&S.current?.scrollIntoView({behavior:`smooth`}),E.current=i},[t,p,i]),(0,T.useEffect)(()=>{let e=C.current;if(!e)return;let t=()=>{let t=e.scrollTop;k.current&&t<O.current&&(D.current=!1),O.current=t,m(e.scrollHeight-e.scrollTop-e.clientHeight<80)};return e.addEventListener(`scroll`,t,{passive:!0}),t(),()=>e.removeEventListener(`scroll`,t)},[m]),(0,T.useEffect)(()=>{function e(){x(e=>{let t=new Set;return A.current.forEach((n,r)=>{n.isConnected&&(h.has(r)?e.has(r)&&t.add(r):n.scrollHeight>n.clientHeight+2&&t.add(r))}),e.size===t.size&&[...e].every(e=>t.has(e))?e:t})}e();let t=new ResizeObserver(e);return A.current.forEach(e=>t.observe(e)),()=>t.disconnect()},[t.length,h]);let j=t.reduce((e,t,n)=>t.role===`maxy`&&!t.hidden?n:e,-1);return(0,I.jsxs)(`div`,{className:`chat-messages-wrap`,children:[o&&(0,I.jsx)(`div`,{className:`selection-overlay-band`}),(0,I.jsxs)(`div`,{className:`chat-messages`,ref:C,children:[a&&t.length===0&&(0,I.jsx)(`div`,{className:`session-error`,children:(0,I.jsx)(`p`,{children:a})}),t.map((a,d)=>{if(a.hidden)return null;let f=i&&d===t.length-1,p=`${a.timestamp}_${a.role}`,m=c.has(p);return(0,I.jsxs)(`div`,{ref:d===j?w:void 0,className:`message ${a.role}${m?` selected`:``}`,children:[o&&!f&&(0,I.jsx)(`div`,{className:`message-select-check`,children:(0,I.jsx)(s,{checked:m,onChange:()=>l(p)})}),(0,I.jsxs)(`div`,{className:`bubble`,children:[a.role===`visitor`&&a.content?(()=>{let e=h.has(d),t=b.has(d);return(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(`div`,{ref:e=>{e?A.current.set(d,e):A.current.delete(d)},className:e?`bubble-content`:`bubble-content clamped${t?` overflowing`:``}`,children:a.content}),t&&(0,I.jsx)(`div`,{className:`bubble-expand`,children:(0,I.jsx)(y,{variant:`icon`,className:e?`expanded`:``,onClick:()=>v(e=>{let t=new Set(e);return t.has(d)?t.delete(d):t.add(d),t}),"aria-label":e?`Collapse message`:`Expand message`,children:(0,I.jsx)(r,{size:14})})})]})})():a.content?(0,I.jsx)(_,{content:a.content,timestamp:g(a.timestamp)}):(0,I.jsxs)(`span`,{className:`typing-indicator`,children:[(0,I.jsx)(`span`,{className:`typing-dot`}),(0,I.jsx)(`span`,{className:`typing-dot`}),(0,I.jsx)(`span`,{className:`typing-dot`})]}),a.attachments&&a.attachments.length>0&&(0,I.jsx)(`div`,{className:`message-attachments`,children:a.attachments.map((t,r)=>(0,I.jsxs)(`span`,{className:`message-attachment-chip no-action`,children:[t.mimeType===`application/pdf`?(0,I.jsx)(n,{size:12}):t.mimeType.startsWith(`text/`)?(0,I.jsx)(e,{size:12}):null,(0,I.jsx)(`span`,{children:t.filename})]},r))}),a.role===`visitor`&&(0,I.jsx)(`span`,{className:`message-timestamp`,children:g(a.timestamp)})]}),a.role===`maxy`&&a.components&&a.components.length>0&&(0,I.jsx)(`div`,{className:`public-components`,children:a.components.map((e,t)=>(0,I.jsx)(`div`,{className:`public-component-enter`,children:(0,I.jsx)(B,{name:e.name,data:e.data,onSubmit:e=>u(d,t,e),submitted:e.submitted})},t))})]},d)}),!i&&d.length>0&&(0,I.jsx)(`div`,{className:`chat-suggestions`,children:d.map(e=>(0,I.jsx)(y,{variant:`suggestion`,onClick:()=>f(e),children:e},e))}),(0,I.jsx)(`div`,{ref:S})]}),!p&&(0,I.jsx)(`button`,{className:`scroll-to-bottom`,onClick:()=>S.current?.scrollIntoView({behavior:`smooth`}),"aria-label":`Scroll to bottom`})]})}function H({selectedItems:e,messages:t,copySelected:n,exitSelection:r,showCopyToast:i}){let[a,o]=(0,T.useState)(!1),s=(0,T.useRef)(null),c=(0,T.useRef)(!1);function l(e){let n=e.lastIndexOf(`_`),r=e.slice(0,n),i=e.slice(n+1),a=parseInt(r,10);return t.find(e=>e.timestamp===a&&e.role===i)?.content??``}function u(e,t){return parseInt(e.slice(0,e.lastIndexOf(`_`)),10)-parseInt(t.slice(0,t.lastIndexOf(`_`)),10)}function d(){let e=[...t].sort((e,t)=>e.timestamp-t.timestamp),n=[];for(let t of e){if(t.hidden||!t.content)continue;let e=t.role===`visitor`?`Visitor`:`Maxy`;n.push(`${e}:\n${t.content}`)}return n.join(`
2
+
3
+ ---
4
+
5
+ `)}T.useEffect(()=>{if(!a)return;let e=e=>{e.target.closest(`.selection-copy-wrap`)||o(!1)};return document.addEventListener(`pointerdown`,e),()=>document.removeEventListener(`pointerdown`,e)},[a]);function f(){s.current!==null&&(clearTimeout(s.current),s.current=null)}return(0,I.jsx)(`div`,{className:`chat-input-area`,children:(0,I.jsxs)(`div`,{className:`selection-bar`,children:[(0,I.jsxs)(`span`,{className:`selection-count`,children:[e.size,` Selected`]}),(0,I.jsxs)(`div`,{className:`selection-copy-wrap`,children:[(0,I.jsxs)(`button`,{type:`button`,className:`selection-copy`,onPointerDown:()=>{if(a){o(!1);return}c.current=!1,s.current=setTimeout(()=>{c.current=!0,o(!0),s.current=null},500)},onPointerUp:f,onPointerLeave:f,onPointerCancel:f,onClick:async()=>{c.current||await n(l,u)},children:[(0,I.jsx)(x,{size:18}),(0,I.jsx)(`span`,{children:`Copy`})]}),a&&(0,I.jsx)(`div`,{className:`copy-menu`,children:(0,I.jsx)(`button`,{type:`button`,className:`copy-menu-item`,onClick:async()=>{let e=d();e&&i(await b(e)),r()},children:`Copy all`})})]}),(0,I.jsx)(`button`,{type:`button`,className:`selection-cancel`,onClick:r,children:`Cancel`})]})})}function U({input:t,setInput:r,isStreaming:i,pendingFiles:a,setPendingFiles:o,attachError:s,setAttachError:c,isDragOver:l,setIsDragOver:u,inputRef:d,onSubmit:f}){let p=(0,T.useRef)(null);function h(e){c(null);let t=e.find(e=>!D.has(e.type));if(t){c(`Unsupported file type: "${t.type}". Supported: images, PDF, plain text, markdown, CSV.`);return}let n=e.find(e=>e.size>O);if(n){c(`"${n.name}" exceeds the 20 MB limit.`);return}o(t=>[...t,...e].slice(0,5))}function g(e){e.preventDefault(),u(!0)}function _(){u(!1)}function b(e){e.preventDefault(),u(!1),h([...e.dataTransfer.files])}return(0,I.jsxs)(`div`,{className:`chat-input-area`,children:[(0,I.jsx)(`input`,{ref:p,type:`file`,multiple:!0,accept:E,style:{display:`none`},onChange:e=>{e.target.files&&h([...e.target.files]),e.target.value=``}}),a.length>0&&(0,I.jsx)(`div`,{className:`attachment-strip`,children:a.map((t,r)=>(0,I.jsxs)(`div`,{className:`attachment-chip`,children:[t.type.startsWith(`image/`)?(0,I.jsx)(`img`,{src:URL.createObjectURL(t),alt:t.name,className:`attachment-chip-thumb`}):t.type===`application/pdf`?(0,I.jsx)(n,{size:14}):(0,I.jsx)(e,{size:14}),(0,I.jsx)(`span`,{className:`attachment-chip-name`,children:t.name}),(0,I.jsx)(`button`,{type:`button`,className:`attachment-chip-remove`,onClick:()=>o(e=>e.filter((e,t)=>t!==r)),"aria-label":`Remove ${t.name}`,children:`×`})]},r))}),s&&(0,I.jsx)(`p`,{className:`attach-error`,children:s}),(0,I.jsx)(m,{inputRef:d}),(0,I.jsxs)(`form`,{className:`chat-form${l?` drag-over`:``}`,onSubmit:f,onDragOver:g,onDragLeave:_,onDrop:b,onPaste:e=>{let t=e.clipboardData?.items;if(!t)return;let n=[];for(let e of t){if(e.kind!==`file`)continue;let t=e.getAsFile();if(!t)continue;let r=t.type.split(`/`)[1]?.replace(`jpeg`,`jpg`)||`png`;n.push(new File([t],`pasted-image-${Date.now()}.${r}`,{type:t.type}))}n.length>0&&h(n)},children:[(0,I.jsx)(y,{variant:`icon`,type:`button`,onClick:()=>p.current?.click(),disabled:i,"aria-label":`Attach file`,children:(0,I.jsx)(S,{size:14})}),(0,I.jsx)(v,{ref:d,value:t,onChange:r,placeholder:`Type a message...`}),(0,I.jsx)(y,{variant:`send`,type:`submit`,disabled:i||!t.trim()&&a.length===0,"aria-label":`Send message`,children:(0,I.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,I.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,I.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]})]})}var W=[];function G(){let[e,t]=(0,T.useState)(``),[n,r]=(0,T.useState)([]),[i,a]=(0,T.useState)(!1),[s,c]=(0,T.useState)(null),[u,d]=(0,T.useState)(W),[f,m]=(0,T.useState)(!0),g=(0,T.useRef)(null),{selectionMode:_,selectedItems:v,copyToast:y,exitSelection:b,enterSelection:x,toggleSelectItem:S,copySelected:w,showCopyToast:E}=C(),D=(0,T.useRef)(()=>{}),O=P((0,T.useCallback)(e=>{D.current(e)},[])),{sessionId:k,sessionKeyRef:A,sessionError:j,pageState:M,agentDisplayName:N,branding:L,ensureSession:z,resumedRef:B,resumeMessagesRef:G}=O,{messages:K,setMessages:q,isStreaming:J,sendMessage:Y,sendGreeting:X,handleComponentSubmit:Z}=F({sessionKeyRef:A,ensureSession:z,sessionError:j,pageState:M,inputRef:g});(0,T.useEffect)(()=>{D.current=X},[X]),(0,T.useEffect)(()=>{let e=!1;return(async()=>{let t=await z();if(!e&&t){if(B.current&&G.current&&G.current.length>0){q(G.current.map(e=>({role:e.role,content:e.content,timestamp:e.timestamp}))),G.current=null;return}X(t)}})(),()=>{e=!0}},[]),(0,T.useEffect)(()=>{M===`chat`&&g.current?.focus()},[M]),(0,T.useEffect)(()=>{if(!L)return;let e=document.documentElement;if(L.primaryColor&&(e.style.setProperty(`--sage`,L.primaryColor),e.style.setProperty(`--sage-hover`,L.primaryColor),e.style.setProperty(`--sage-subtle`,L.primaryColor+`14`),e.style.setProperty(`--sage-glow`,L.primaryColor+`26`)),L.accentColor&&e.style.setProperty(`--visitor-bubble`,L.accentColor),L.backgroundColor&&e.style.setProperty(`--bg`,L.backgroundColor),document.title=L.name,L.primaryColor){let e=document.querySelector(`meta[name="theme-color"]`);e||(e=document.createElement(`meta`),e.name=`theme-color`,document.head.appendChild(e)),e.content=L.primaryColor}if(L.faviconUrl){let e=document.querySelector(`link[rel="icon"]`);e||(e=document.createElement(`link`),e.rel=`icon`,document.head.appendChild(e)),e.href=L.faviconUrl}},[L]),(0,T.useEffect)(()=>{function e(e){e.key===`Escape`&&_&&b()}return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[_,b]);function Q(e){if(!e&&n.length===0||J)return;q(e=>e.map(e=>e.components?.some(e=>!e.submitted)?{...e,components:e.components.map(e=>e.submitted?e:{...e,submitted:!0})}:e)),d(t=>t.filter(t=>t!==e)),m(!0);let i=[...n];t(``),r([]),c(null),Y(e,{files:i})}function $(t){t.preventDefault(),Q(e.trim()),g.current?.resetHeight()}return(0,I.jsxs)(`div`,{className:`chat-page`,children:[(0,I.jsxs)(`header`,{className:`chat-header`,children:[(0,I.jsx)(`img`,{src:L?.logoUrl||l,alt:L?.name||h.productName,className:`chat-logo`,onError:e=>{e.target.src=l}}),(0,I.jsx)(`h1`,{className:`chat-tagline`,children:N||L?.name||h.productName}),(0,I.jsx)(`p`,{className:`chat-intro`,children:L?.tagline||``}),M===`chat`&&!_&&(0,I.jsx)(`button`,{className:`chat-header-select`,onClick:x,title:`Select messages`,"aria-label":`Select messages`,children:(0,I.jsx)(o,{size:16})})]}),M===`loading`&&(0,I.jsx)(`div`,{className:`gate-wrap`,children:(0,I.jsx)(`div`,{className:`gate-loading`,children:(0,I.jsx)(`span`,{className:`spinner`})})}),M===`auth-required`&&(0,I.jsx)(R,{gateState:O.gateState,setGateState:O.setGateState,grantInfo:O.grantInfo,setGrantInfo:O.setGrantInfo,gateSessionKeyRef:O.gateSessionKeyRef,resolvedSlugRef:O.resolvedSlugRef,onAuthenticated:O.enterChat}),M===`chat`&&(0,I.jsxs)(I.Fragment,{children:[(0,I.jsx)(V,{messages:K,isStreaming:J,sessionError:j,selectionMode:_,selectedItems:v,toggleSelectItem:S,onComponentSubmit:Z,remainingSuggestions:u,onSuggestionClick:Q,isAtBottom:f,setIsAtBottom:m}),_?(0,I.jsx)(H,{selectedItems:v,messages:K,copySelected:w,exitSelection:b,showCopyToast:E}):(0,I.jsx)(U,{input:e,setInput:t,isStreaming:J,pendingFiles:n,setPendingFiles:r,attachError:s,setAttachError:c,isDragOver:i,setIsDragOver:a,inputRef:g,onSubmit:$})]}),y&&(0,I.jsx)(`span`,{className:`copy-toast${y===`failed`?` copy-toast-failed`:``}`,children:y===`copied`?`Copied`:`Copy failed`}),(0,I.jsxs)(`footer`,{className:`chat-footer`,children:[(0,I.jsxs)(`a`,{href:p,children:[h.domain,` `,`↗`]}),k&&(0,I.jsxs)(`span`,{style:{opacity:.35,fontSize:`10px`,fontFamily:`monospace`,marginLeft:`1rem`},children:[`Session · `,k.slice(0,8)]})]})]})}(0,w.createRoot)(document.getElementById(`root`)).render((0,I.jsx)(G,{}));
@@ -3,6 +3,6 @@
3
3
  "tagline": "Built for agents. By agents.",
4
4
  "domain": "realagency.network",
5
5
  "hostname": "realagent",
6
- "logo": "/brand/realagent-icon-web.png",
6
+ "logo": "/brand/realagent-logo-black.png",
7
7
  "favicon": "/brand/realagent-favicon-dark-32.png"
8
8
  }
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Real Agent</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/admin-CisU37jg.js"></script>
9
- <link rel="modulepreload" crossorigin href="/assets/ChatInput--kmj83_w.js">
8
+ <script type="module" crossorigin src="/assets/admin-BuKpzjOb.js"></script>
9
+ <link rel="modulepreload" crossorigin href="/assets/ChatInput-CIVDMwyt.js">
10
10
  <link rel="stylesheet" crossorigin href="/assets/ChatInput-rWA47V05.css">
11
11
  <link rel="stylesheet" href="/brand-defaults.css">
12
12
  </head>
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Real Agent</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/public-ClFTMlS3.js"></script>
9
- <link rel="modulepreload" crossorigin href="/assets/ChatInput--kmj83_w.js">
8
+ <script type="module" crossorigin src="/assets/public-B-3jg3R-.js"></script>
9
+ <link rel="modulepreload" crossorigin href="/assets/ChatInput-CIVDMwyt.js">
10
10
  <link rel="stylesheet" crossorigin href="/assets/ChatInput-rWA47V05.css">
11
11
  <link rel="stylesheet" href="/brand-defaults.css">
12
12
  </head>
@@ -9501,8 +9501,12 @@ function isLoginFresh(login) {
9501
9501
  }
9502
9502
  async function startLogin(opts) {
9503
9503
  const { accountId, authDir, force, timeoutMs = 3e4 } = opts;
9504
+ const existing0 = activeLogins.get(accountId);
9504
9505
  const hasAuth = await authExists(authDir);
9505
9506
  const selfId = readSelfId(authDir);
9507
+ console.error(
9508
+ `${TAG3} startLogin account=${accountId} force=${!!force} hasAuth=${hasAuth}` + (existing0 ? ` activeLogin={id=${existing0.id.slice(0, 8)},age=${Math.round((Date.now() - existing0.startedAt) / 1e3)}s,hasQr=${!!existing0.qr}}` : " activeLogin=none")
9509
+ );
9506
9510
  if (hasAuth && !force) {
9507
9511
  const who = selfId.e164 ?? selfId.jid ?? "unknown";
9508
9512
  return {
@@ -9512,12 +9516,17 @@ async function startLogin(opts) {
9512
9516
  }
9513
9517
  await clearAuth(authDir);
9514
9518
  const existing = activeLogins.get(accountId);
9515
- if (existing && isLoginFresh(existing) && existing.qrDataUrl) {
9519
+ if (existing && isLoginFresh(existing) && existing.qrDataUrl && !force) {
9520
+ console.error(`${TAG3} startLogin account=${accountId} guard: returning existing QR (age=${Math.round((Date.now() - existing.startedAt) / 1e3)}s)`);
9516
9521
  return {
9517
9522
  qrDataUrl: existing.qrDataUrl,
9523
+ qrRaw: existing.qr,
9518
9524
  message: "QR already active. Scan it in WhatsApp \u2192 Linked Devices."
9519
9525
  };
9520
9526
  }
9527
+ if (existing) {
9528
+ console.error(`${TAG3} startLogin account=${accountId} ${force ? "force override" : "stale/no-QR"}, resetting active login`);
9529
+ }
9521
9530
  resetActiveLogin(accountId);
9522
9531
  let resolveQr = null;
9523
9532
  let rejectQr = null;
@@ -9586,6 +9595,9 @@ async function startLogin(opts) {
9586
9595
  async function waitForLogin(opts) {
9587
9596
  const { accountId, timeoutMs = 6e4 } = opts;
9588
9597
  const login = activeLogins.get(accountId);
9598
+ console.error(
9599
+ `${TAG3} waitForLogin account=${accountId} timeout=${timeoutMs}ms` + (login ? ` login={id=${login.id.slice(0, 8)},age=${Math.round((Date.now() - login.startedAt) / 1e3)}s,connected=${login.connected},hasQr=${!!login.qr}}` : " login=none")
9600
+ );
9589
9601
  if (!login) {
9590
9602
  return { connected: false, message: "No active WhatsApp login in progress." };
9591
9603
  }
@@ -9616,6 +9628,9 @@ async function waitForLogin(opts) {
9616
9628
  }
9617
9629
  await new Promise((r) => setTimeout(r, 1e3));
9618
9630
  }
9631
+ const elapsed = Math.round((Date.now() - (deadline - timeoutMs)) / 1e3);
9632
+ console.error(`${TAG3} waitForLogin timeout account=${accountId} elapsed=${elapsed}s \u2014 cleaning up active login`);
9633
+ resetActiveLogin(accountId);
9619
9634
  return { connected: false, message: "Login timed out. Try generating a new QR." };
9620
9635
  }
9621
9636
 
@@ -25517,10 +25532,12 @@ app.get(
25517
25532
  );
25518
25533
  var htmlCache = /* @__PURE__ */ new Map();
25519
25534
  var brandLogoPath = "/brand/maxy-monochrome.png";
25535
+ var brandIconPath = "/brand/maxy-monochrome.png";
25520
25536
  if (BRAND_JSON_PATH && existsSync18(BRAND_JSON_PATH)) {
25521
25537
  try {
25522
25538
  const fullBrand = JSON.parse(readFileSync18(BRAND_JSON_PATH, "utf-8"));
25523
25539
  if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
25540
+ brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
25524
25541
  } catch {
25525
25542
  }
25526
25543
  }
@@ -25528,7 +25545,8 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
25528
25545
  productName: BRAND.productName,
25529
25546
  hostname: BRAND.hostname,
25530
25547
  domain: BRAND.domain,
25531
- logo: brandLogoPath
25548
+ logo: brandLogoPath,
25549
+ icon: brandIconPath
25532
25550
  })}</script>`;
25533
25551
  function cachedHtml(file2) {
25534
25552
  let html = htmlCache.get(file2);
@@ -24,7 +24,8 @@
24
24
  },
25
25
 
26
26
  "assets": {
27
- "logo": "realagent-icon-web.png",
27
+ "logo": "realagent-logo-black.png",
28
+ "icon": "realagent-icon-web.png",
28
29
  "logoMonochrome": "realagent-icon-web.png",
29
30
  "logoRound": "realagent-icon-dark-round-web.png",
30
31
  "favicon": "realagent-favicon-dark-32.png"