bloby-bot 0.70.8 → 0.70.10

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.
Files changed (38) hide show
  1. package/dist-bloby/assets/{bloby-CXmOcb1r.js → bloby-DSNB0g4w.js} +4 -4
  2. package/dist-bloby/assets/{globals-DpO5tO92.js → globals-B3cTbITX.js} +1 -1
  3. package/dist-bloby/assets/{highlighted-body-OFNGDK62-D7cU1Y-Z.js → highlighted-body-OFNGDK62-BLforpkr.js} +1 -1
  4. package/dist-bloby/assets/mermaid-GHXKKRXX-C1H_fSCU.js +1 -0
  5. package/dist-bloby/assets/{onboard-B96ELhXn.js → onboard-Dn2Ws_G2.js} +1 -1
  6. package/dist-bloby/bloby.html +2 -2
  7. package/dist-bloby/onboard.html +2 -2
  8. package/package.json +1 -1
  9. package/scripts/sync-pi-models.ts +37 -6
  10. package/supervisor/chat/OnboardWizard.tsx +4 -4
  11. package/supervisor/harnesses/pi/async-queue.ts +7 -11
  12. package/supervisor/harnesses/pi/index.ts +475 -73
  13. package/supervisor/harnesses/pi/models-catalog.generated.ts +840 -210
  14. package/supervisor/harnesses/pi/providers/humanize-error.ts +125 -0
  15. package/supervisor/harnesses/pi/providers/retry.ts +87 -0
  16. package/supervisor/harnesses/pi/providers/stream-anthropic.ts +73 -11
  17. package/supervisor/harnesses/pi/providers/stream-google.ts +15 -5
  18. package/supervisor/harnesses/pi/providers/stream-openai-completions.ts +55 -19
  19. package/supervisor/harnesses/pi/providers/types.ts +26 -1
  20. package/supervisor/harnesses/pi/session.ts +179 -73
  21. package/supervisor/harnesses/pi/sub-providers.ts +30 -1
  22. package/supervisor/harnesses/pi/test-completion.ts +8 -2
  23. package/supervisor/harnesses/pi/tools/registry.ts +25 -9
  24. package/supervisor/harnesses/pi/tools/task.ts +108 -0
  25. package/supervisor/harnesses/pi/tools/types.ts +15 -0
  26. package/supervisor/index.ts +11 -10
  27. package/supervisor/public/morphy_sad.mov +0 -0
  28. package/supervisor/public/morphy_sad.webm +0 -0
  29. package/supervisor/shell.ts +1 -1
  30. package/supervisor/workspace-guard.js +1 -1
  31. package/workspace/client/public/morphy_bounce.mov +0 -0
  32. package/workspace/client/public/morphy_bounce.webm +0 -0
  33. package/workspace/client/public/morphy_hi.mov +0 -0
  34. package/workspace/client/public/morphy_hi.webm +0 -0
  35. package/workspace/client/src/App.tsx +5 -3
  36. package/dist-bloby/assets/mermaid-GHXKKRXX-D5YxphBn.js +0 -1
  37. package/supervisor/public/what-happened.mp4 +0 -0
  38. package/supervisor/public/what-happened.webm +0 -0
@@ -22,5 +22,5 @@ own model`,icon:`/pi-logo.svg`,comingSoon:!1,iconHeight:33}],md={anthropic:[{id:
22
22
  [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-white
23
23
  [&::-webkit-slider-thumb]:shadow-[0_0_0_3px_rgba(0,105,254,0.35)] [&::-webkit-slider-thumb]:cursor-pointer
24
24
  [&::-moz-range-thumb]:h-4 [&::-moz-range-thumb]:w-4 [&::-moz-range-thumb]:rounded-full
25
- [&::-moz-range-thumb]:bg-white [&::-moz-range-thumb]:border-0 [&::-moz-range-thumb]:shadow-[0_0_0_3px_rgba(0,105,254,0.35)]`}),(0,G.jsx)(`div`,{className:`flex justify-between mt-2 px-[1px]`,children:bd.map((e,t)=>(0,G.jsx)(`button`,{type:`button`,onClick:()=>x(t),className:`text-[10px] leading-none transition-colors ${t===m?`text-[#0069FE] font-semibold`:`text-white/30 hover:text-white/55`}`,children:e.label},e.label))}),p&&(0,G.jsxs)(`div`,{className:`mt-3 flex items-center gap-2.5`,children:[(0,G.jsx)(`input`,{type:`number`,min:1,max:1440,value:Number.isFinite(e.intervalMinutes)?e.intervalMinutes:``,onChange:e=>{let t=parseInt(e.target.value,10);b({intervalMinutes:Number.isFinite(t)?t:NaN})},placeholder:`45`,className:`w-28 bg-white/[0.03] border border-white/[0.08] text-white rounded-xl px-4 py-2.5 text-[13px] outline-none focus:border-[#0069FE]/30 transition-colors placeholder:text-white/20 font-mono`}),(0,G.jsx)(`span`,{className:`text-[12px] text-white/40`,children:`minutes between pulses`})]}),p&&!g&&(0,G.jsx)(`p`,{className:`text-amber-400/80 text-[11px] mt-1.5`,children:`Enter a whole number of minutes (1–1440).`}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2 mt-6 mb-2.5`,children:[(0,G.jsx)(pe,{className:`h-3.5 w-3.5 text-[#0069FE]/70`}),(0,G.jsx)(`span`,{className:`text-[12px] font-semibold text-white/70 uppercase tracking-wide`,children:`Quiet hours`})]}),(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsxs)(`div`,{className:`flex-1`,children:[(0,G.jsx)(`label`,{className:`text-[11px] text-white/40 mb-1 block`,children:`Start`}),(0,G.jsx)(`input`,{type:`time`,value:e.quietHours.start,onChange:t=>b({quietHours:{...e.quietHours,start:t.target.value}}),className:`w-full bg-white/[0.03] border border-white/[0.08] text-white rounded-xl px-4 py-2.5 text-[13px] outline-none focus:border-[#0069FE]/30 transition-colors [color-scheme:dark]`})]}),(0,G.jsx)(w,{className:`h-4 w-4 text-white/25 mt-5 shrink-0`}),(0,G.jsxs)(`div`,{className:`flex-1`,children:[(0,G.jsx)(`label`,{className:`text-[11px] text-white/40 mb-1 block`,children:`End`}),(0,G.jsx)(`input`,{type:`time`,value:e.quietHours.end,onChange:t=>b({quietHours:{...e.quietHours,end:t.target.value}}),className:`w-full bg-white/[0.03] border border-white/[0.08] text-white rounded-xl px-4 py-2.5 text-[13px] outline-none focus:border-[#0069FE]/30 transition-colors [color-scheme:dark]`})]})]}),(0,G.jsx)(`p`,{className:`text-white/35 text-[12px] mt-2 leading-relaxed`,children:`No pulses fire between these times.`})]}),o&&!_&&(0,G.jsxs)(`div`,{className:`mt-4 flex items-center gap-2.5 bg-emerald-500/[0.06] border border-emerald-500/20 rounded-xl px-4 py-3`,children:[(0,G.jsx)(ne,{className:`h-4 w-4 text-emerald-400 shrink-0`}),(0,G.jsx)(`p`,{className:`text-emerald-300/90 text-[12px]`,children:`Saved — the scheduler picks this up within a minute.`})]}),c&&(0,G.jsxs)(`div`,{className:`mt-3 flex items-center gap-1.5 text-[12px] text-red-400`,children:[(0,G.jsx)(Se,{className:`h-3.5 w-3.5 shrink-0`}),c]}),_&&(0,G.jsx)(`button`,{type:`button`,onClick:S,disabled:!y,className:`w-full mt-4 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40 disabled:cursor-not-allowed`,children:i?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}),`Saving...`]}):(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(_e,{className:`h-4 w-4`}),`Save pulse settings`]})})]})}function Dd({crons:e,onChanged:t,onLocalUpdate:n}){let[r,i]=(0,v.useState)({}),[a,o]=(0,v.useState)(null),[s,c]=(0,v.useState)({}),[l,u]=(0,v.useState)(``),[d,f]=(0,v.useState)(new Set),p=(e,t)=>i(n=>({...n,[e]:t})),m=e=>f(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),h=async e=>{if(!r[e.id]){u(``),p(e.id,`pause`);try{let r=await Ne(`/api/crons/pause`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({id:e.id,paused:!e.paused})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e.error||`Failed to update`)}n(t=>t.map(t=>t.id===e.id?{...t,paused:!e.paused}:t)),t()}catch(e){u(e.message||`Failed to update`)}finally{p(e.id,void 0)}}},g=async e=>{if(!r[e.id]){u(``),p(e.id,`delete`);try{let r=await Ne(`/api/crons/delete`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({id:e.id})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e.error||`Failed to delete`)}o(null),n(t=>t.filter(t=>t.id!==e.id)),t()}catch(e){u(e.message||`Failed to delete`)}finally{p(e.id,void 0)}}},_=async e=>{if(!s[e.id]){u(``),c(t=>({...t,[e.id]:!0}));try{let t=await Ne(`/api/crons/task?id=${encodeURIComponent(e.id)}`);if(!t.ok)throw Error(`Could not download task file`);let n=await t.blob(),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`${e.id}.md`,document.body.appendChild(i),i.click(),i.remove(),URL.revokeObjectURL(r)}catch(e){u(e.message||`Download failed`)}finally{c(t=>({...t,[e.id]:!1}))}}};return(0,G.jsxs)(`div`,{className:`mt-8`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(te,{className:`h-4 w-4 text-[#0069FE]/70 shrink-0`}),(0,G.jsx)(`h2`,{className:`text-[15px] font-bold text-white tracking-tight`,children:`Crons`})]}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:`Crons let your agent schedule tasks inside the main session, running them daily, hourly, or on any schedule you choose. They can also be one-shot tasks that run once at a specific time.`}),(0,G.jsxs)(`div`,{className:`mt-2 flex items-start gap-1.5 text-white/30 text-[12px] leading-relaxed`,children:[(0,G.jsx)(ue,{className:`h-3.5 w-3.5 mt-0.5 shrink-0`}),(0,G.jsx)(`span`,{children:`To change or add a cron, just ask your agent. To delete or pause, use the buttons below.`})]}),l&&(0,G.jsxs)(`div`,{className:`mt-3 flex items-center gap-1.5 text-[12px] text-red-400`,children:[(0,G.jsx)(Se,{className:`h-3.5 w-3.5 shrink-0`}),l]}),(0,G.jsx)(`div`,{className:`mt-4 space-y-2.5`,children:e.length===0?(0,G.jsxs)(`div`,{className:`rounded-xl border border-white/[0.06] bg-white/[0.02] px-4 py-7 text-center`,children:[(0,G.jsx)(te,{className:`h-5 w-5 text-white/25 mx-auto mb-2`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px]`,children:`No scheduled tasks yet.`}),(0,G.jsx)(`p`,{className:`text-white/25 text-[12px] mt-1`,children:`Ask your agent to schedule something.`})]}):e.map(e=>{let t=!!e.paused,n=r[e.id],i=d.has(e.id),c=Td(e.nextRun);return(0,G.jsxs)(`div`,{className:`rounded-xl border transition-colors ${t?`border-white/[0.05] bg-white/[0.015]`:`border-white/[0.06] bg-white/[0.02]`}`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2 p-2.5`,children:[(0,G.jsxs)(`button`,{type:`button`,onClick:()=>m(e.id),className:`flex items-center gap-2.5 flex-1 min-w-0 text-left`,children:[(0,G.jsx)(`div`,{className:`w-8 h-8 rounded-lg flex items-center justify-center shrink-0 ${t?`bg-white/[0.04]`:e.oneShot?`bg-amber-500/10`:`bg-[#0069FE]/10`}`,children:e.oneShot?(0,G.jsx)(Ee,{className:`h-4 w-4 ${t?`text-white/40`:`text-amber-400`}`}):(0,G.jsx)(ie,{className:`h-4 w-4 ${t?`text-white/40`:`text-[#0069FE]`}`})}),(0,G.jsx)(`span`,{className:`flex-1 min-w-0 truncate text-[13px] ${t?`text-white/45`:`text-white`}`,children:e.task||`(untitled task)`}),t&&(0,G.jsx)(`span`,{className:`shrink-0 text-[10px] font-medium text-white/40 bg-white/[0.05] rounded-full px-2 py-0.5`,children:`Paused`})]}),a===e.id?(0,G.jsxs)(`div`,{className:`flex items-center gap-1 shrink-0`,children:[(0,G.jsx)(`span`,{className:`text-[11px] text-white/45 mr-0.5`,children:`Delete?`}),(0,G.jsxs)(`button`,{type:`button`,onClick:()=>g(e),disabled:n===`delete`,className:`inline-flex items-center gap-1 rounded-md bg-red-500/15 hover:bg-red-500/25 border border-red-500/30 text-red-300 text-[11px] font-medium px-2 py-1 transition-colors disabled:opacity-50`,children:[n===`delete`?(0,G.jsx)(O,{className:`h-3 w-3 animate-spin`}):(0,G.jsx)(xe,{className:`h-3 w-3`}),`Delete`]}),(0,G.jsx)(`button`,{type:`button`,onClick:()=>o(null),disabled:n===`delete`,className:`rounded-md text-white/40 hover:text-white/70 text-[11px] px-1.5 py-1 transition-colors`,children:`Cancel`})]}):(0,G.jsxs)(`div`,{className:`flex items-center gap-0.5 shrink-0`,children:[(0,G.jsx)(`button`,{type:`button`,onClick:()=>h(e),disabled:!!n,title:t?`Resume`:`Pause`,"aria-label":t?`Resume`:`Pause`,className:`p-1.5 rounded-lg text-white/40 hover:text-white/80 hover:bg-white/[0.05] transition-colors disabled:opacity-50`,children:n===`pause`?(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}):t?(0,G.jsx)(me,{className:`h-4 w-4`}):(0,G.jsx)(k,{className:`h-4 w-4`})}),(0,G.jsx)(`button`,{type:`button`,onClick:()=>o(e.id),disabled:!!n,title:`Delete`,"aria-label":`Delete`,className:`p-1.5 rounded-lg text-white/30 hover:text-red-400 hover:bg-red-500/[0.06] transition-colors disabled:opacity-50`,children:(0,G.jsx)(xe,{className:`h-4 w-4`})}),(0,G.jsx)(`button`,{type:`button`,onClick:()=>m(e.id),title:i?`Collapse`:`Expand`,"aria-label":i?`Collapse`:`Expand`,className:`p-1.5 rounded-lg text-white/30 hover:text-white/70 hover:bg-white/[0.05] transition-colors`,children:(0,G.jsx)(T,{className:`h-4 w-4 transition-transform ${i?`rotate-180`:``}`})})]})]}),i&&(0,G.jsxs)(`div`,{className:`px-2.5 pb-3 pl-[52px] -mt-0.5`,children:[(0,G.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2 gap-y-1 text-[12px] text-white/45`,children:[(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,G.jsx)(ie,{className:`h-3 w-3 text-white/30 shrink-0`}),e.description]}),e.oneShot&&(0,G.jsx)(`span`,{className:`text-amber-300/70`,children:`· One-time`}),!t&&c&&(0,G.jsxs)(`span`,{className:`text-[#4AA8FF]`,children:[`· Next: `,c]})]}),e.hasTaskFile&&(0,G.jsxs)(`button`,{type:`button`,onClick:()=>_(e),disabled:s[e.id],className:`group mt-2 inline-flex items-center gap-1.5 rounded-md bg-white/[0.04] hover:bg-white/[0.07] border border-white/[0.06] hover:border-white/[0.12] text-white/50 hover:text-white/80 text-[11px] font-mono px-2 py-1 transition-colors disabled:opacity-50`,title:`Download task instructions`,children:[s[e.id]?(0,G.jsx)(O,{className:`h-3 w-3 animate-spin`}):(0,G.jsx)(E,{className:`h-3 w-3 shrink-0`}),e.id,`.md`,(0,G.jsx)(oe,{className:`h-3 w-3 opacity-0 group-hover:opacity-100 transition-opacity`})]})]})]},e.id)})})]})}function Od({cacheRef:e}){let t=(0,v.useRef)(e.current!=null).current,n=e.current,[r,i]=(0,v.useState)(!t),[a,o]=(0,v.useState)(``),[s,c]=(0,v.useState)(n?.pulse??Q),[l,u]=(0,v.useState)(n?.original??null),[d,f]=(0,v.useState)(n?.crons??[]),p=async e=>{let t=await Ne(`/api/schedule`);if(!t.ok)throw Error(`Failed to load schedule`);let n=await t.json();if(f(Array.isArray(n.crons)?n.crons:[]),e){let e={enabled:!!n.pulse?.enabled,intervalMinutes:Number(n.pulse?.intervalMinutes)||60,quietHours:{start:n.pulse?.quietHours?.start??`22:00`,end:n.pulse?.quietHours?.end??`07:00`}};c(e),u(e)}};return(0,v.useEffect)(()=>{if(t)return;let e=!1;return p(!0).then(()=>{e||i(!1)}).catch(t=>{e||(o(t.message||`Failed to load`),i(!1))}),()=>{e=!0}},[t]),(0,v.useEffect)(()=>{r||(e.current={pulse:s,original:l,crons:d})}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`Pulse & Crons`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:`Background wake-ups and scheduled tasks your agent runs on its own.`}),r?(0,G.jsx)(`div`,{className:`flex items-center justify-center py-12 text-white/40`,children:(0,G.jsx)(O,{className:`h-5 w-5 animate-spin`})}):a?(0,G.jsxs)(`div`,{className:`mt-5 flex items-center gap-2 text-[13px] text-red-400`,children:[(0,G.jsx)(Se,{className:`h-4 w-4 shrink-0`}),a]}):(0,G.jsxs)(`div`,{className:`mt-6`,children:[(0,G.jsx)(Ed,{pulse:s,original:l,setPulse:c,onPulseSaved:e=>u(e)}),(0,G.jsx)(Dd,{crons:d,onLocalUpdate:e=>f(e),onChanged:()=>{p(!1).catch(()=>{})}})]})]})}function kd({onComplete:e,isInitialSetup:t=!1,onSave:n,onTunnelSwitch:r}){let[i,a]=(0,v.useState)(0),[o,s]=(0,v.useState)(``),[c,l]=(0,v.useState)(`anthropic`),[u,d]=(0,v.useState)(``),[f,p]=(0,v.useState)(!1),[m,h]=(0,v.useState)({anthropic:`idle`,openai:`idle`,pi:`idle`}),[g,_]=(0,v.useState)([]),[y,b]=(0,v.useState)(``),[x,S]=(0,v.useState)(``),[C,te]=(0,v.useState)(``),[T,ie]=(0,v.useState)(``),[oe,E]=(0,v.useState)(!1),[ue,de]=(0,v.useState)(!1),[pe,k]=(0,v.useState)(),[me,he]=(0,v.useState)(null),[_e,xe]=(0,v.useState)(!1),[Ee,De]=(0,v.useState)(``),[Oe,ke]=(0,v.useState)(!1),[Ae,je]=(0,v.useState)(),[Me,Ne]=(0,v.useState)(!1),[Pe,Fe]=(0,v.useState)(`device`),[Ie,Le]=(0,v.useState)(`idle`),[Re,ze]=(0,v.useState)(``),[Be,Ve]=(0,v.useState)(``),[He,Ue]=(0,v.useState)(!1),[We,Ge]=(0,v.useState)(!1),[A,Ke]=(0,v.useState)(!1),[qe,Je]=(0,v.useState)(``),[Ye,Xe]=(0,v.useState)(!1),[Ze,Qe]=(0,v.useState)(),[$e,et]=(0,v.useState)(!1),[j,tt]=(0,v.useState)(``),[nt,rt]=(0,v.useState)(null),[it,at]=(0,v.useState)(``),[ot,st]=(0,v.useState)({}),[ct,lt]=(0,v.useState)(``),[ut,dt]=(0,v.useState)(!1),[ft,pt]=(0,v.useState)(!1),[mt,ht]=(0,v.useState)(``),gt=(0,v.useRef)(null),[_t,vt]=(0,v.useState)(`quick`),[yt,bt]=(0,v.useState)(``),[xt,St]=(0,v.useState)(``),[Ct,wt]=(0,v.useState)(`relay`),[M,N]=(0,v.useState)(null),[P,Tt]=(0,v.useState)(!1),[Et,Dt]=(0,v.useState)(!1),[Ot,kt]=(0,v.useState)({}),[At,jt]=(0,v.useState)(!1),[Mt,Nt]=(0,v.useState)(``),[Pt,Ft]=(0,v.useState)(``),[It,Lt]=(0,v.useState)(!1),[Rt,zt]=(0,v.useState)(`tunnel`),[Bt,Vt]=(0,v.useState)(!1),[Ht,Ut]=(0,v.useState)(``),[Wt,Gt]=(0,v.useState)(!1),[Kt,qt]=(0,v.useState)(``),[Jt,Yt]=(0,v.useState)(!1),[Xt,Zt]=(0,v.useState)(!1),[Qt,F]=(0,v.useState)(``),[$t,en]=(0,v.useState)(`admin`),[tn,nn]=(0,v.useState)(``),[I,rn]=(0,v.useState)(``),[an,on]=(0,v.useState)(!1),[sn,cn]=(0,v.useState)(!1),[ln,un]=(0,v.useState)(!1),[dn,fn]=(0,v.useState)(!1),[pn,mn]=(0,v.useState)(``),[hn,gn]=(0,v.useState)(``),[_n,vn]=(0,v.useState)(!1),[yn,bn]=(0,v.useState)(!1),[xn,Sn]=(0,v.useState)(!1),[L,Cn]=(0,v.useState)(!1),[wn,Tn]=(0,v.useState)(``),[En,Dn]=(0,v.useState)(!1),[On,kn]=(0,v.useState)(``),[An,jn]=(0,v.useState)(``),[Mn,Nn]=(0,v.useState)(``),[Pn,Fn]=(0,v.useState)(``),[In,Ln]=(0,v.useState)(!1),[Rn,zn]=(0,v.useState)(!1),[Bn,Vn]=(0,v.useState)(``),[R,Hn]=(0,v.useState)([]),[Un,Wn]=(0,v.useState)(!1),[Gn,Kn]=(0,v.useState)(!1),[qn,Jn]=(0,v.useState)(``),[Yn,Xn]=(0,v.useState)(``),[Zn,Qn]=(0,v.useState)(!1),[$n,er]=(0,v.useState)(`password`),[tr,nr]=(0,v.useState)(!1),rr=(0,v.useRef)(!1),ir=(0,v.useRef)(null),ar=(0,v.useRef)(null),or=(0,v.useRef)(null),[sr,cr]=(0,v.useState)({userName:``,botName:``,provider:``,model:``,whisperEnabled:!1,whisperKey:``}),[lr,ur]=(0,v.useState)(!1),[dr,fr]=(0,v.useState)(!1),[pr,mr]=(0,v.useState)(``),hr=m[c]===`connected`,gr=`bloby_totp_setup`;function _r(){try{sessionStorage.setItem(gr,JSON.stringify({secret:On,qrUri:An,otpauthUri:Mn,phase:$n,portalPass:tn,portalPassConfirm:I}))}catch{}}function vr(){try{let e=sessionStorage.getItem(gr);if(!e)return!1;let t=JSON.parse(e);if(t.secret&&t.phase===`totp-setup`)return kn(t.secret),jn(t.qrUri||``),Nn(t.otpauthUri||``),Dn(!0),er(`totp-setup`),a(3),t.portalPass&&(nn(t.portalPass),rn(t.portalPassConfirm||``)),!0}catch{}return!1}function yr(){try{sessionStorage.removeItem(gr)}catch{}}(0,v.useEffect)(()=>{fetch(`/api/onboard/status`).then(e=>e.json()).then(e=>{e.userName&&s(e.userName),e.handle?(tt(e.handle.username),lt(e.handle.tier||`at`),N({username:e.handle.username,tier:e.handle.tier,url:e.handle.url}),pt(!0),ht(e.handle.url)):e.agentName&&tt(e.agentName),e.portalUser&&en(e.portalUser),e.portalConfigured&&cn(!0),e.provider&&l(e.provider),e.model&&d(e.model),e.whisperEnabled&&(Cn(!0),Tn(e.whisperKey||``)),e.totpEnabled&&(Dn(!0),Ln(!0)),e.tunnelMode&&vt(e.tunnelMode),e.tunnelDomain&&bt(e.tunnelDomain),e.tunnelUrl&&St(e.tunnelUrl),e.handle||wt(`tunnel`),cr({userName:e.userName||``,botName:e.handle&&e.handle.username||e.agentName||``,provider:e.provider||``,model:e.model||``,whisperEnabled:!!e.whisperEnabled,whisperKey:e.whisperKey||``}),rr.current=!0,e.totpEnabled||vr()}).catch(()=>{rr.current=!0})},[]),(0,v.useEffect)(()=>{zt(ld(window.location.hostname))},[]),(0,v.useEffect)(()=>{Qn(window.matchMedia(`(max-width: 768px)`).matches||`ontouchstart`in window)},[]),(0,v.useEffect)(()=>{c!==`anthropic`||m.anthropic===`connected`||fetch(`/api/auth/claude/status`).then(e=>e.json()).then(e=>{e.authenticated&&h(e=>({...e,anthropic:`connected`}))}).catch(()=>{})},[c]),(0,v.useEffect)(()=>{c!==`openai`||m.openai===`connected`||fetch(`/api/auth/codex/status`).then(e=>e.json()).then(e=>{e.authenticated&&h(e=>({...e,openai:`connected`}))}).catch(()=>{})},[c]),(0,v.useEffect)(()=>{if(gt.current&&clearTimeout(gt.current),!rr.current||_t===`off`||M&&ft&&j===M.username)return;rt(null),at(``),st({}),kt({}),jt(!1),Nt(``),Ft(``),pt(!1),ht(``);let e=j.trim();if(e){if(e.length<3){rt(`invalid`),at(`At least 3 characters`);return}return rt(`checking`),gt.current=setTimeout(async()=>{try{let t=await(await fetch(`/api/handle/check/${encodeURIComponent(e)}`)).json();if(!t.valid)rt(`invalid`),at(t.error);else{let e={},n={};for(let r of t.handles)e[r.tier]=r.available,r.reserved&&(n[r.tier]=!0);st(e),kt(n),rt(`ready`),lt(``)}}catch{rt(null)}},400),()=>{gt.current&&clearTimeout(gt.current)}}},[j]),(0,v.useEffect)(()=>{if(!j||j.length<3||nt!==`ready`)return;let e=async()=>{try{let e=await(await fetch(`/api/handle/check/${encodeURIComponent(j.trim())}`)).json();if(e.valid){let t={},n={};for(let r of e.handles)t[r.tier]=r.available,r.reserved&&(n[r.tier]=!0);st(t),kt(n)}}catch{}};return window.addEventListener(`focus`,e),()=>window.removeEventListener(`focus`,e)},[j,nt]);let br=e=>{tt(e.toLowerCase().replace(/[^a-z0-9-]/g,``))},xr=async()=>{if(!(!j||nt!==`ready`||!ot[ct])){dt(!0);try{let e=await(await fetch(`/api/handle/register`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({username:j,tier:ct})})).json();e.ok?(pt(!0),ht(e.url)):(at(e.error||`Registration failed`),rt(`invalid`))}catch{at(`Could not reach server`),rt(`invalid`)}finally{dt(!1)}}},Sr=async()=>{if(!(!j||nt!==`ready`||!ot[ct])){Dt(!0);try{let e=await(await fetch(`/api/handle/change`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({username:j,tier:ct})})).json();e.ok?(pt(!0),ht(e.url),N({username:j,tier:ct,url:e.url}),Tt(!1)):(at(e.error||`Handle change failed`),rt(`invalid`))}catch{at(`Could not reach server`),rt(`invalid`)}finally{Dt(!1)}}},Cr=async()=>{if(!(!j||!Mt)){Lt(!0),Ft(``);try{let e=await(await fetch(`/api/handle/claim-reserved`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({handle:j,hash:Mt})})).json();e.ok?(pt(!0),ht(e.url),jt(!1),Nt(``),lt(`premium`),wt(`relay`)):Ft(e.error||`Invalid activation code`)}catch{Ft(`Could not reach server`)}finally{Lt(!1)}}},wr=e=>{c===`openai`&&e!==`openai`&&(A&&fetch(`/api/auth/codex/cancel`,{method:`POST`}),Ie===`pending`&&fetch(`/api/auth/codex/device/cancel`,{method:`POST`})),l(e),d(e===`openai`?`gpt-5.5:high`:``),xe(!1),De(``),je(void 0),Ke(!1),Je(``),Le(`idle`),ze(``),Ve(``),Fe(`device`),Qe(void 0),k(void 0)};(0,v.useEffect)(()=>{if(c!==`pi`)return;let e=!1;return(async()=>{try{let[t,n]=await Promise.all([fetch(`/api/auth/pi/providers`),fetch(`/api/auth/pi/status`)]),r=await t.json(),i=await n.json();if(e)return;let a=r?.providers||[];_(a),i?.configured?(b(i.subProvider||``),ie(i.modelId||``),te(i.baseUrl||``),h(e=>({...e,pi:`connected`})),he({subProvider:i.subProvider,modelId:i.modelId,baseUrl:i.baseUrl}),d(`${i.subProvider}/${i.modelId||``}`)):!y&&a[0]&&(b(a[0].id),te(a[0].baseUrl||``),ie(a[0].defaultModel||``))}catch(t){e||k(t?.message||`Failed to load Bloby providers`)}})(),()=>{e=!0}},[c]);let Tr=g.find(e=>e.id===y),Er=e=>{let t=g.find(t=>t.id===e);b(e),te(t?.baseUrl||``),ie(t?.defaultModel||``),k(void 0),m.pi===`connected`&&(h(e=>({...e,pi:`idle`})),he(null))},Dr=async()=>{if(y){k(void 0),de(!0);try{let e={subProvider:y,apiKey:x.trim()||void 0,baseUrl:C.trim()||void 0,modelId:T.trim()||void 0},t=await(await fetch(`/api/auth/pi/test`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})).json();if(!t?.ok){k(t?.error||`Connection test failed`);return}let n=await(await fetch(`/api/auth/pi/save`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})).json();if(!n?.ok){k(n?.error||`Failed to save credentials`);return}h(e=>({...e,pi:`connected`})),he(n.status||null),d(`${y}/${T||Tr?.defaultModel||``}`),S(``)}catch(e){k(e?.message||`Connection failed`)}finally{de(!1)}}},Or=async()=>{try{await fetch(`/api/auth/pi`,{method:`DELETE`})}catch{}h(e=>({...e,pi:`idle`})),he(null),d(``)},kr=e=>{if(window.matchMedia(`(display-mode: standalone)`).matches||navigator.standalone===!0){let t=document.createElement(`a`);t.href=e,t.target=`_blank`,t.rel=`noopener noreferrer`,document.body.appendChild(t),t.click(),document.body.removeChild(t)}else window.open(e,`_blank`,`noopener,noreferrer`)},Ar=async()=>{je(void 0);try{let e=await(await fetch(`/api/auth/claude/start`,{method:`POST`})).json();e.success&&e.authUrl?(kr(e.authUrl),xe(!0)):je(e.error||`Failed to start authentication`)}catch(e){je(e.message)}},jr=async()=>{if(Ee.trim()){ke(!0),je(void 0);try{let e=await(await fetch(`/api/auth/claude/exchange`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({code:Ee.trim()})})).json();e.success?h(e=>({...e,anthropic:`connected`})):je(e.error||`Code exchange failed`)}catch(e){je(e.message)}finally{ke(!1)}}},Mr=async()=>{try{let e=await navigator.clipboard.readText();e&&De(e.trim())}catch{}},Nr=async()=>{Ne(!0),je(void 0);try{(await(await fetch(`/api/auth/claude/status`)).json()).authenticated?h(e=>({...e,anthropic:`connected`})):je(`No active session found. Please authenticate first.`)}catch{}finally{Ne(!1)}},Pr=async()=>{Qe(void 0),Ue(!0),Le(`pending`);try{let e=await(await fetch(`/api/auth/codex/device/start`,{method:`POST`})).json();e.success?(ze(e.userCode||``),Ve(e.verificationUrl||``),e.verificationUrl&&kr(e.verificationUrl)):(Le(`error`),Qe(e.error||`Failed to start device-code login`))}catch(e){Le(`error`),Qe(e.message)}finally{Ue(!1)}},Fr=async()=>{try{await fetch(`/api/auth/codex/device/cancel`,{method:`POST`})}catch{}Le(`idle`),ze(``),Ve(``)},Ir=async()=>{try{await navigator.clipboard.writeText(Re),Ge(!0),setTimeout(()=>Ge(!1),1500)}catch{}};(0,v.useEffect)(()=>{if(Ie!==`pending`||!Re)return;let e=setInterval(async()=>{try{let e=await(await fetch(`/api/auth/codex/device/status`)).json();e.state===`success`?(Le(`success`),h(e=>({...e,openai:`connected`}))):e.state===`error`&&(Le(`error`),Qe(e.error||`Device-code login failed`))}catch{}},2e3);return()=>clearInterval(e)},[Ie,Re]);let Lr=async()=>{Qe(void 0);try{let e=await(await fetch(`/api/auth/codex/start`,{method:`POST`})).json();e.success&&e.authUrl?(kr(e.authUrl),Ke(!0)):Qe(e.error||`Failed to start authentication`)}catch(e){Qe(e.message)}},Rr=async()=>{if(qe.trim()){Xe(!0),Qe(void 0);try{let e=await(await fetch(`/api/auth/codex/exchange`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({code:qe.trim()})})).json();e.success?(h(e=>({...e,openai:`connected`})),Je(``)):Qe(e.error||`Code exchange failed`)}catch(e){Qe(e.message)}finally{Xe(!1)}}},zr=async()=>{try{let e=await navigator.clipboard.readText();e&&Je(e.trim())}catch{}},Br=async()=>{et(!0),Qe(void 0);try{(await(await fetch(`/api/auth/codex/status`)).json()).authenticated?h(e=>({...e,openai:`connected`})):Qe(`No active session found. Please authenticate first.`)}catch{}finally{et(!1)}},Vr=tn===I,Hr=tn.length>=6&&Vr,Ur=sn?tn.length===0||_n&&Hr:Hr,Wr=(()=>{switch(i){case 0:return!0;case 1:return o.trim().length>0;case 2:return Bt||Jt?!1:_t===`off`||_t===`named`||Ct===`tunnel`?j.trim().length>=3:ft;case 3:return!($n!==`password`||!Ur||En&&!In);case 4:return!!(c&&u&&hr);case 5:return!0;case 6:return!0;case 7:return!0;default:return!1}})(),Gr=()=>{t&&Wr&&i<6&&a(e=>e+1)},Kr=()=>{i>0&&a(e=>e-1)},qr=e=>{e.key===`Enter`&&Wr&&Gr()},Jr=(()=>{if(t)return!1;switch(i){case 1:return o.trim()!==sr.userName;case 2:return j.trim()!==sr.botName;case 3:return $n===`password`&&tn.length>0&&Hr&&(sn?_n:!0);case 4:return(c!==sr.provider||u!==sr.model)&&hr&&!!u;case 5:return(L!==sr.whisperEnabled||L&&wn!==sr.whisperKey)&&!(L&&(!wn.startsWith(`sk-`)||wn.length<20));default:return!1}})();(0,v.useEffect)(()=>{fr(!1),mr(``),or.current?.scrollTo({top:0})},[i]);let Yr=async()=>{if(!Jr||lr)return;ur(!0),mr(``),fr(!1);let e={userName:sr.userName,agentName:sr.botName||`Bloby`,provider:sr.provider,model:sr.model,apiKey:``,whisperEnabled:sr.whisperEnabled,whisperKey:sr.whisperEnabled?sr.whisperKey:``,portalUser:$t.trim(),portalPass:``};switch(i){case 1:e.userName=o.trim();break;case 2:e.agentName=j.trim()||`Bloby`;break;case 3:e.portalPass=tn;break;case 4:e.provider=c,e.model=u;break;case 5:e.whisperEnabled=L,e.whisperKey=L?wn:``;break}try{n?await n(e):await fetch(`/api/onboard`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)}),cr(e=>{switch(i){case 1:return{...e,userName:o.trim()};case 2:return{...e,botName:j.trim()};case 4:return{...e,provider:c,model:u};case 5:return{...e,whisperEnabled:L,whisperKey:wn};default:return e}}),i===3&&(nn(``),rn(``),mn(``),vn(!1),Sn(!1),cn(!0)),fr(!0),ur(!1)}catch(e){mr(e.message||`Save failed`),ur(!1)}},Xr=async()=>{p(!0);let r={userName:o.trim(),agentName:j.trim()||`Bloby`,provider:c,model:u,apiKey:``,whisperEnabled:L,whisperKey:L?wn:``,portalUser:$t.trim(),portalPass:tn};try{n?await n(r):await fetch(`/api/onboard`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(r)}),t?(p(!1),a(6)):e()}catch(e){console.error(`[OnboardWizard] Onboard failed:`,e),p(!1)}},Zr=`w-full bg-white/[0.05] border border-white/[0.08] text-white rounded-xl px-4 py-3 text-base outline-none input-glow placeholder:text-white/20 transition-all`,Qr=`w-full bg-white/[0.03] border border-white/[0.08] text-white rounded-xl px-4 py-2.5 text-[13px] outline-none input-glow placeholder:text-white/20 transition-all`;return(0,G.jsxs)(`div`,{className:`fixed inset-0 z-[200] flex items-center justify-center p-4`,children:[(0,G.jsx)(`div`,{className:`absolute inset-0 bg-black/85 backdrop-blur-md`}),(0,G.jsxs)(sd.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},transition:{duration:.3},className:`relative w-full max-w-[480px] max-h-[calc(100dvh_-_2rem)] flex flex-col bg-[#181818] border border-white/[0.06] rounded-[24px] shadow-2xl overflow-hidden`,children:[t?(0,G.jsx)(`div`,{className:`flex justify-center gap-2 pt-6 shrink-0`,children:Array.from({length:7},(e,t)=>(0,G.jsx)(`div`,{className:`h-1.5 rounded-full transition-all duration-300 ${t===i?`w-7 bg-gradient-brand`:t<i?`w-1.5 bg-gradient-brand opacity-60`:`w-1.5 bg-white/10`}`},t))}):(0,G.jsxs)(`div`,{className:`flex items-center justify-between px-5 pt-4 pb-1 shrink-0`,children:[i===0?(0,G.jsx)(`span`,{className:`text-[13px] font-semibold text-white/80 pl-1`,children:`Settings`}):(0,G.jsxs)(`button`,{onClick:()=>a(0),className:`flex items-center gap-1 text-white/50 hover:text-white/80 text-[13px] font-medium pl-1 pr-2 py-1 rounded-lg hover:bg-white/[0.05] transition-colors`,children:[(0,G.jsx)(ee,{className:`h-3.5 w-3.5`}),` Settings`]}),(0,G.jsxs)(`div`,{className:`flex items-center gap-0.5`,children:[i!==0&&(0,G.jsx)(_d,{onJump:e=>a(e)}),(0,G.jsx)(`button`,{onClick:e,className:`text-white/40 hover:text-white/80 p-1.5 rounded-lg hover:bg-white/[0.05] transition-colors`,"aria-label":`Close settings`,children:(0,G.jsx)(Te,{className:`h-4 w-4`})})]})]}),(0,G.jsx)(`div`,{ref:or,className:`flex-1 min-h-0 overflow-y-auto`,children:(0,G.jsx)(_l,{mode:`wait`,children:(0,G.jsxs)(sd.div,{initial:{opacity:0,x:30},animate:{opacity:1,x:0},exit:{opacity:0,x:-30},transition:{duration:.2,ease:`easeOut`},className:`px-8 pt-6 pb-8`,children:[i===0&&t&&(0,G.jsxs)(`div`,{className:`flex flex-col items-center text-center`,children:[(0,G.jsxs)(`video`,{autoPlay:!0,loop:!0,muted:!0,playsInline:!0,className:`h-[180px] mb-4`,children:[(0,G.jsx)(`source`,{src:`/bloby_say_hi.mov`,type:`video/mp4; codecs="hvc1"`}),(0,G.jsx)(`source`,{src:`/bloby_say_hi.webm`,type:`video/webm`})]}),(0,G.jsx)(`h1`,{className:`text-2xl font-bold text-white tracking-tight`,children:`Welcome to Bloby`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[14px] mt-2 leading-relaxed max-w-[320px]`,children:`Let's set up your AI assistant in just a few steps.`}),(0,G.jsxs)(`button`,{onClick:Gr,className:`mt-6 px-7 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center gap-2`,children:[`Get Started`,(0,G.jsx)(w,{className:`h-4 w-4`})]})]}),i===0&&!t&&(0,G.jsxs)(`div`,{className:`flex flex-col items-center text-center`,children:[(0,G.jsxs)(`video`,{autoPlay:!0,loop:!0,muted:!0,playsInline:!0,className:`h-[150px] mb-4`,children:[(0,G.jsx)(`source`,{src:`/bloby_say_hi.mov`,type:`video/mp4; codecs="hvc1"`}),(0,G.jsx)(`source`,{src:`/bloby_say_hi.webm`,type:`video/webm`})]}),(0,G.jsx)(`h1`,{className:`text-2xl font-bold text-white tracking-tight`,children:`Settings`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[14px] mt-2 leading-relaxed max-w-[320px]`,children:`What would you like to change?`}),(0,G.jsx)(`div`,{className:`w-full mt-5`,children:(0,G.jsx)(hd,{models:gd.map(e=>({id:String(e.step),label:e.label})),value:``,placeholder:`Select a setting…`,menuMaxPx:188,onChange:e=>a(Number(e))})})]}),i===1&&(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`What's your name?`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:`This is how your agent will address you.`}),(0,G.jsxs)(`div`,{className:`mt-5 flex items-center gap-3`,children:[(0,G.jsx)(`input`,{type:`text`,value:o,onChange:e=>s(e.target.value),onKeyDown:qr,placeholder:`Enter your name`,autoFocus:!0,autoComplete:`off`,"data-1p-ignore":!0,"data-lpignore":`true`,className:Zr+` flex-1`}),t&&(0,G.jsx)(`button`,{onClick:Gr,disabled:!Wr,className:`shrink-0 h-12 w-12 flex items-center justify-center rounded-full bg-gradient-brand hover:opacity-90 text-white transition-colors disabled:opacity-30`,children:(0,G.jsx)(w,{className:`h-5 w-5`})})]})]}),i===2&&_t===`off`&&(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`Agent Name & Access`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:`Give your bot a name. This is used throughout the app as your bot's identity.`}),(0,G.jsx)(`div`,{className:`relative mt-5`,children:(0,G.jsx)(`input`,{type:`text`,value:j,onChange:e=>br(e.target.value),maxLength:30,placeholder:`your-bot-name`,spellCheck:!1,autoCapitalize:`none`,autoCorrect:`off`,autoComplete:`off`,"data-1p-ignore":!0,"data-lpignore":`true`,autoFocus:!0,className:Zr+` pr-10 font-mono`})}),(0,G.jsx)(`div`,{className:`mt-4 bg-white/[0.03] border border-white/[0.06] rounded-xl px-4 py-3`,children:(0,G.jsx)(`p`,{className:`text-white/40 text-[12px] leading-relaxed`,children:`Private network mode — your bot is only accessible via your local network or VPN. No public URL will be created.`})}),!t&&(0,G.jsx)(`div`,{className:`mt-3 flex items-center gap-2`,children:(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-medium border ${ud(Rt)?`bg-emerald-500/10 text-emerald-400 border-emerald-500/20`:`bg-blue-500/10 text-blue-400 border-blue-500/20`}`,children:[ud(Rt)?(0,G.jsx)(Ce,{className:`h-3 w-3`}):(0,G.jsx)(D,{className:`h-3 w-3`}),`Accessing via `,dd[Rt]]})}),!t&&!Jt&&(0,G.jsxs)(`button`,{onClick:()=>{Yt(!0),F(``)},className:`w-full mt-4 flex items-center justify-between px-4 py-3 rounded-xl border border-white/[0.06] bg-white/[0.02] hover:border-white/10 hover:bg-white/[0.04] transition-all text-left`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`p`,{className:`text-[13px] text-white/70 font-medium`,children:`Re-enable public tunnel access`}),(0,G.jsx)(`p`,{className:`text-[11px] text-white/30 mt-0.5`,children:`Start a Cloudflare tunnel to make your bot accessible from anywhere`})]}),(0,G.jsx)(D,{className:`h-4 w-4 text-white/30 shrink-0 ml-3`})]}),Jt&&(0,G.jsxs)(`div`,{className:`mt-4 space-y-3`,children:[(0,G.jsx)(`div`,{className:`bg-amber-500/8 border border-amber-500/20 rounded-xl px-4 py-3`,children:(0,G.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,G.jsx)(Se,{className:`h-4 w-4 text-amber-400 shrink-0 mt-0.5`}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`p`,{className:`text-amber-400/90 text-[13px] font-medium`,children:`Enable public access?`}),(0,G.jsxs)(`p`,{className:`text-amber-400/60 text-[12px] mt-1 leading-relaxed`,children:[`This will start a Cloudflare tunnel, making your bot reachable from the internet.`,M&&` Your handle will reconnect automatically.`]})]})]})}),Qt&&(0,G.jsx)(`p`,{className:`text-red-400/70 text-[12px]`,children:Qt}),(0,G.jsxs)(`div`,{className:`flex gap-2`,children:[(0,G.jsx)(`button`,{onClick:async()=>{if(r){Zt(!0),F(``);try{await r(`quick`),vt(`quick`),Yt(!1)}catch(e){F(e.message||`Failed to start tunnel`)}finally{Zt(!1)}}},disabled:Xt||!r,className:`flex-1 py-2.5 bg-gradient-brand hover:opacity-90 text-white text-[13px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40`,children:Xt?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}),`Starting tunnel...`]}):`Enable Tunnel`}),(0,G.jsx)(`button`,{onClick:()=>{Yt(!1),F(``)},disabled:Xt,className:`px-5 py-2.5 bg-white/[0.04] hover:bg-white/[0.08] border border-white/[0.08] text-white/60 text-[13px] font-medium rounded-full transition-colors`,children:`Cancel`})]})]}),t&&(0,G.jsxs)(`button`,{onClick:Gr,disabled:!Wr,className:`w-full mt-5 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40`,children:[`Continue`,(0,G.jsx)(w,{className:`h-4 w-4`})]})]}),i===2&&_t===`named`&&(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`Agent Name & Access`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:`This is your bot's identity. Your named tunnel domain is already configured.`}),(0,G.jsx)(`div`,{className:`relative mt-5`,children:(0,G.jsx)(`input`,{type:`text`,value:j,onChange:e=>br(e.target.value),maxLength:30,placeholder:`your-bot-name`,spellCheck:!1,autoCapitalize:`none`,autoCorrect:`off`,autoComplete:`off`,"data-1p-ignore":!0,"data-lpignore":`true`,autoFocus:!0,className:Zr+` pr-10 font-mono`})}),(0,G.jsxs)(`div`,{className:`mt-4 flex items-center gap-2 bg-white/[0.03] border border-white/[0.06] rounded-xl px-4 py-3`,children:[(0,G.jsxs)(`span`,{className:`font-mono text-[13px] text-white/70 truncate flex-1 text-left`,children:[`https://`,yt]}),(0,G.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(`https://${yt}`),on(!0),setTimeout(()=>on(!1),2e3)},className:`shrink-0 text-white/30 hover:text-white/60 transition-colors`,children:an?(0,G.jsx)(ne,{className:`h-4 w-4 text-emerald-400`}):(0,G.jsx)(re,{className:`h-4 w-4`})})]})]}),i===2&&_t===`quick`&&(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`Agent Name & Access`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:`This is your bot's name and permanent handle — access it from anywhere.`}),M&&ft&&!P&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`div`,{className:`mt-4 bg-emerald-500/8 border border-emerald-500/15 rounded-xl px-4 py-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(ne,{className:`h-4 w-4 text-emerald-400`}),(0,G.jsx)(`p`,{className:`text-emerald-400/90 text-[13px] font-medium`,children:`Current handle`})]}),(0,G.jsx)(`p`,{className:`text-emerald-400/60 text-[12px] mt-1 font-mono`,children:mt})]}),(0,G.jsxs)(`div`,{className:`flex gap-2 mt-4`,children:[t&&(0,G.jsxs)(`button`,{onClick:Gr,className:`flex-1 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2`,children:[`Continue`,(0,G.jsx)(w,{className:`h-4 w-4`})]}),(0,G.jsx)(`button`,{onClick:()=>{Tt(!0),pt(!1),tt(``),rt(null),st({}),wt(`relay`)},className:`px-5 py-3 bg-white/[0.04] hover:bg-white/[0.08] border border-white/[0.08] text-white/60 text-[13px] font-medium rounded-full transition-colors`,children:`Change`})]})]}),P&&!ft&&(0,G.jsxs)(`div`,{className:`mt-4 bg-amber-500/8 border border-amber-500/20 rounded-xl px-4 py-3`,children:[(0,G.jsx)(`p`,{className:`text-amber-400/90 text-[13px] font-medium`,children:`Changing your handle`}),(0,G.jsxs)(`p`,{className:`text-amber-400/60 text-[12px] mt-1`,children:[`Your current handle `,(0,G.jsx)(`span`,{className:`font-mono`,children:M?.url}),` will be released and become available for others.`]})]}),(!M||P||!ft)&&!(M&&ft&&!P)&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`div`,{className:`relative mt-5`,children:[(0,G.jsx)(`input`,{type:`text`,value:j,onChange:e=>br(e.target.value),maxLength:30,placeholder:`your-bot-name`,spellCheck:!1,autoCapitalize:`none`,autoCorrect:`off`,autoComplete:`off`,"data-1p-ignore":!0,"data-lpignore":`true`,autoFocus:!0,disabled:ft,className:Zr+` pr-10 font-mono`+(ft?` opacity-50`:``)}),nt&&j.length>0&&!ft&&(0,G.jsxs)(`div`,{className:`absolute right-4 top-1/2 -translate-y-1/2`,children:[nt===`checking`&&(0,G.jsx)(`div`,{className:`w-5 h-5 border-2 border-white/10 border-t-[#0069FE] rounded-full animate-spin`}),nt===`invalid`&&(0,G.jsx)(`div`,{className:`w-6 h-6 rounded-full bg-amber-500/15 flex items-center justify-center`,children:(0,G.jsx)(`svg`,{className:`w-3.5 h-3.5 text-amber-400`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:3,children:(0,G.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 9v3m0 4h.01`})})})]})]}),nt===`invalid`&&it&&(0,G.jsx)(`p`,{className:`text-amber-400 text-[12px] mt-2`,children:it}),nt===`ready`&&j.length>0&&!ft&&(0,G.jsxs)(`div`,{className:`space-y-3 mt-4`,children:[(()=>{let e=ot.at===!1,t=Ct===`relay`&&ct===`at`;return(0,G.jsxs)(`button`,{onClick:()=>{e||(lt(`at`),wt(`relay`))},disabled:e,className:`w-full rounded-xl border transition-all duration-200 text-left px-4 py-3 ${e?`border-white/[0.04] opacity-50 cursor-not-allowed`:t?`border-[#0069FE]/30 bg-white/[0.04]`:`border-white/[0.06] hover:border-white/10 hover:bg-white/[0.02]`}`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsx)(`span`,{className:`text-[12px] font-semibold text-white/60 uppercase tracking-wider`,children:`Free`}),(0,G.jsx)(`span`,{className:`text-[11px] font-medium px-2.5 py-0.5 rounded-full border ${e?`bg-red-500/10 text-red-400 border-red-500/20`:`bg-emerald-500/10 text-emerald-400 border-emerald-500/20`}`,children:e?`Taken`:`Available`})]}),(0,G.jsxs)(`p`,{className:`font-mono text-[13px] mt-1.5 ${t?`text-white/80`:`text-white/40`}`,children:[`open.bloby.bot/`,j]})]})})(),(()=>{let e=ot.premium,t=e===!1,n=t&&Ot.premium;return(0,G.jsxs)(`div`,{className:`rounded-xl border transition-all duration-200 text-left px-4 py-3 ${n?`border-[#0069FE]/20`:`border-white/[0.06]`}`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`span`,{className:`text-[12px] font-semibold text-white/60 uppercase tracking-wider`,children:`Premium`}),(0,G.jsx)(`span`,{className:`text-[11px] font-medium px-2.5 py-0.5 rounded-full border bg-[#0069FE]/15 text-[#0069FE] border-[#0069FE]/20`,children:`$5`})]}),(0,G.jsx)(`span`,{className:`text-[11px] font-medium px-2.5 py-0.5 rounded-full border ${n?`bg-[#0069FE]/10 text-[#0069FE] border-[#0069FE]/20`:t?`bg-red-500/10 text-red-400 border-red-500/20`:`bg-emerald-500/10 text-emerald-400 border-emerald-500/20`}`,children:n?`Reserved`:t?`Taken`:`Available`})]}),(0,G.jsxs)(`p`,{className:`font-mono text-[13px] mt-1.5 text-white/40`,children:[`bloby.bot/`,j]}),e&&(0,G.jsxs)(`div`,{className:`mt-3 pt-3 border-t border-white/[0.06] flex items-center justify-between`,children:[(0,G.jsx)(`p`,{className:`text-[12px] text-white/40`,children:`Purchase on bloby.bot`}),(0,G.jsx)(`a`,{href:`https://www.bloby.bot/#reserve`,target:`_blank`,rel:`noopener noreferrer`,className:`text-[12px] font-medium text-[#0069FE] hover:text-[#3391FF] transition-colors`,children:`Purchase`})]}),n&&(0,G.jsx)(`div`,{className:`mt-3 pt-3 border-t border-[#0069FE]/10`,children:At?(0,G.jsxs)(`div`,{className:`space-y-2.5`,children:[(0,G.jsxs)(`p`,{className:`text-[12px] text-white/40`,children:[`Enter the 5-character code from your `,(0,G.jsx)(`span`,{className:`text-white/60 font-medium`,children:`bloby.bot`}),` account`]}),(0,G.jsxs)(`div`,{className:`flex gap-2`,children:[(0,G.jsx)(`input`,{type:`text`,value:Mt,onChange:e=>Nt(e.target.value.trim()),maxLength:5,placeholder:`e.g. a3Kx9`,spellCheck:!1,autoComplete:`off`,autoFocus:!0,className:`flex-1 bg-white/[0.05] border border-white/[0.08] text-white rounded-lg px-3 py-2 text-[13px] font-mono outline-none focus:border-[#0069FE]/30 transition-colors placeholder:text-white/20 tracking-widest text-center`}),(0,G.jsx)(`button`,{onClick:Cr,disabled:It||Mt.length<5,className:`px-4 py-2 bg-gradient-brand hover:opacity-90 text-white text-[13px] font-semibold rounded-lg transition-colors flex items-center gap-1.5 disabled:opacity-40`,children:It?(0,G.jsx)(O,{className:`h-3.5 w-3.5 animate-spin`}):`Activate`})]}),Pt&&(0,G.jsx)(`p`,{className:`text-red-400 text-[12px]`,children:Pt}),(0,G.jsx)(`button`,{onClick:()=>{jt(!1),Nt(``),Ft(``)},className:`text-[11px] text-white/25 hover:text-white/40 transition-colors`,children:`Cancel`})]}):(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsx)(`p`,{className:`text-[12px] text-white/40`,children:`Is that yours?`}),(0,G.jsx)(`button`,{onClick:()=>{jt(!0),Nt(``),Ft(``)},className:`text-[12px] font-medium text-[#0069FE] hover:text-[#3391FF] transition-colors`,children:`Activate`})]})})]})})(),(0,G.jsxs)(`button`,{onClick:()=>{wt(`tunnel`),lt(`skip`)},className:`w-full rounded-xl border transition-all duration-200 text-left px-4 py-3 ${ct===`skip`?`border-[#0069FE]/30 bg-white/[0.04]`:`border-white/[0.06] hover:border-white/10 hover:bg-white/[0.02]`}`,children:[(0,G.jsx)(`span`,{className:`text-[12px] font-semibold text-white/60 uppercase tracking-wider`,children:`No handle`}),(0,G.jsx)(`p`,{className:`text-[13px] mt-1.5 ${ct===`skip`?`text-white/60`:`text-white/30`}`,children:`I'll use the random tunnel URL`})]})]}),ft&&(0,G.jsxs)(`div`,{className:`mt-4 bg-emerald-500/8 border border-emerald-500/15 rounded-xl px-4 py-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(ne,{className:`h-4 w-4 text-emerald-400`}),(0,G.jsx)(`p`,{className:`text-emerald-400/90 text-[13px] font-medium`,children:`Handle claimed!`})]}),(0,G.jsx)(`p`,{className:`text-emerald-400/60 text-[12px] mt-1 font-mono`,children:mt})]}),nt===`ready`&&j.length>0&&!ft&&(0,G.jsx)(`button`,{onClick:ct===`skip`?Gr:Ct===`relay`&&ct===`at`?P?Sr:xr:void 0,disabled:!ct||ut||Et||ct===`at`&&!ot.at,className:`w-full mt-4 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40 disabled:cursor-not-allowed`,children:ut||Et?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}),P?`Changing...`:`Claiming...`]}):ct?ct===`skip`?(0,G.jsxs)(G.Fragment,{children:[`Continue`,(0,G.jsx)(w,{className:`h-4 w-4`})]}):(0,G.jsxs)(G.Fragment,{children:[P?`Change Handle`:`Claim & Continue`,(0,G.jsx)(w,{className:`h-4 w-4`})]}):(0,G.jsx)(G.Fragment,{children:`Select an option to continue`})}),t&&ft&&(0,G.jsxs)(`button`,{onClick:Gr,className:`w-full mt-4 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2`,children:[`Continue`,(0,G.jsx)(w,{className:`h-4 w-4`})]}),P&&!ft&&(0,G.jsx)(`button`,{onClick:()=>{Tt(!1),tt(M.username),pt(!0),ht(M.url),lt(M.tier),wt(`relay`),rt(null)},className:`w-full mt-2 py-2 text-white/25 hover:text-white/40 text-[12px] transition-colors`,children:`Cancel — keep current handle`})]}),!t&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`div`,{className:`mt-5 flex items-center gap-2`,children:(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-medium border ${ud(Rt)?`bg-emerald-500/10 text-emerald-400 border-emerald-500/20`:`bg-blue-500/10 text-blue-400 border-blue-500/20`}`,children:[ud(Rt)?(0,G.jsx)(we,{className:`h-3 w-3`}):(0,G.jsx)(D,{className:`h-3 w-3`}),`Accessing via `,dd[Rt]]})}),!Bt&&(0,G.jsxs)(`button`,{onClick:()=>{ud(Rt)&&(Vt(!0),Ut(``),qt(``))},disabled:!ud(Rt),className:`w-full mt-3 flex items-center justify-between px-4 py-3 rounded-xl border transition-all text-left ${ud(Rt)?`border-white/[0.06] bg-white/[0.02] hover:border-white/10 hover:bg-white/[0.04] cursor-pointer`:`border-white/[0.04] bg-transparent opacity-50 cursor-not-allowed`}`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`p`,{className:`text-[13px] text-white/70 font-medium`,children:`Switch to private network only`}),(0,G.jsx)(`p`,{className:`text-[11px] text-white/30 mt-0.5`,children:ud(Rt)?`Stop the tunnel and relay — access only via Tailscale or LAN`:`Connect via Tailscale or private network to unlock`})]}),(0,G.jsx)(Ce,{className:`h-4 w-4 text-white/30 shrink-0 ml-3`})]}),Bt&&(0,G.jsxs)(`div`,{className:`mt-3 space-y-3`,children:[(0,G.jsx)(`div`,{className:`bg-amber-500/8 border border-amber-500/20 rounded-xl px-4 py-3`,children:(0,G.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,G.jsx)(Se,{className:`h-4 w-4 text-amber-400 shrink-0 mt-0.5`}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`p`,{className:`text-amber-400/90 text-[13px] font-medium`,children:`Switch to private network only?`}),(0,G.jsx)(`p`,{className:`text-amber-400/60 text-[12px] mt-1 leading-relaxed`,children:`This will stop the Cloudflare tunnel and relay connection. Your bot will only be accessible via your private network.`}),M&&(0,G.jsx)(`p`,{className:`text-amber-400/50 text-[12px] mt-1.5`,children:`Your handle will be preserved and can be re-activated later.`})]})]})}),(0,G.jsxs)(`div`,{children:[(0,G.jsxs)(`label`,{className:`text-[12px] text-white/40 font-medium mb-1.5 block`,children:[`Type `,(0,G.jsx)(`span`,{className:`font-mono text-white/60`,children:`I confirm`}),` to proceed`]}),(0,G.jsx)(`input`,{type:`text`,value:Ht,onChange:e=>Ut(e.target.value),placeholder:`I confirm`,spellCheck:!1,autoFocus:!0,className:Qr})]}),Kt&&(0,G.jsx)(`p`,{className:`text-red-400/70 text-[12px]`,children:Kt}),(0,G.jsxs)(`div`,{className:`flex gap-2`,children:[(0,G.jsx)(`button`,{onClick:async()=>{if(!(!r||Ht.trim().toLowerCase()!==`i confirm`)){Gt(!0),qt(``);try{await r(`off`),vt(`off`),Vt(!1)}catch(e){qt(e.message||`Failed to switch`)}finally{Gt(!1)}}},disabled:Wt||Ht.trim().toLowerCase()!==`i confirm`||!r,className:`flex-1 py-2.5 bg-amber-600 hover:bg-amber-500 text-white text-[13px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40`,children:Wt?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}),`Switching...`]}):`Confirm Switch`}),(0,G.jsx)(`button`,{onClick:()=>{Vt(!1),Ut(``),qt(``)},disabled:Wt,className:`px-5 py-2.5 bg-white/[0.04] hover:bg-white/[0.08] border border-white/[0.08] text-white/60 text-[13px] font-medium rounded-full transition-colors`,children:`Cancel`})]})]})]})]}),i===3&&(0,G.jsx)(`div`,{children:(0,G.jsxs)(_l,{mode:`wait`,children:[$n===`password`&&(0,G.jsxs)(sd.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},exit:{opacity:0,x:-20},transition:{duration:.15},children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:sn?`Password & 2FA`:`Set a password`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:sn?`Your Bloby Chat password is already set — you can keep it as-is or change it below.`:`You'll need this password to access your Bloby Chat. Keep it safe — anyone with your URL will need it to log in.`}),sn&&!xn&&(0,G.jsxs)(`div`,{className:`mt-5 flex items-center justify-between bg-white/[0.02] border border-white/[0.06] rounded-xl px-4 py-3`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`p`,{className:`text-white/70 text-[13px] font-medium`,children:`Bloby Chat Password`}),(0,G.jsx)(`p`,{className:`text-white/30 text-[11px] mt-0.5`,children:`Already configured.`})]}),(0,G.jsx)(`button`,{type:`button`,onClick:()=>{Sn(!0),mn(``),gn(``),vn(!1),nn(``),rn(``)},className:`shrink-0 px-3.5 py-2 bg-white/[0.04] hover:bg-white/[0.08] text-white/70 hover:text-white text-[12px] font-medium rounded-lg transition-colors`,children:`Change password`})]}),sn&&xn&&(0,G.jsxs)(`div`,{className:`mt-5`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between mb-1.5`,children:[(0,G.jsx)(`label`,{className:`text-[12px] text-white/40 font-medium`,children:`Current password`}),(0,G.jsx)(`button`,{type:`button`,onClick:()=>{Sn(!1),mn(``),gn(``),vn(!1),nn(``),rn(``)},className:`text-white/30 hover:text-white/60 text-[11px] transition-colors`,children:`Cancel`})]}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`input`,{type:`password`,value:pn,onChange:e=>{mn(e.target.value),gn(``),vn(!1)},placeholder:`Enter your current password`,autoComplete:`current-password`,className:Zr+` flex-1`}),pn.length>0&&!_n&&(0,G.jsx)(`button`,{onClick:async()=>{bn(!0),gn(``);try{(await(await fetch(`/api/portal/verify-password`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({password:pn})})).json()).valid?vn(!0):gn(`Incorrect password`)}catch{gn(`Could not verify`)}finally{bn(!1)}},disabled:yn,className:`shrink-0 px-4 py-3 bg-white/[0.06] hover:bg-white/[0.1] text-white/60 text-[13px] font-medium rounded-xl transition-colors disabled:opacity-40`,children:yn?(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}):`Verify`}),_n&&(0,G.jsx)(`div`,{className:`shrink-0 w-10 h-10 flex items-center justify-center`,children:(0,G.jsx)(ne,{className:`h-4 w-4 text-emerald-400`})})]}),hn&&(0,G.jsx)(`p`,{className:`text-red-400/70 text-[11px] mt-1`,children:hn})]}),(!sn||xn&&_n)&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`div`,{className:sn?`mt-3`:`mt-5`,children:[(0,G.jsx)(`label`,{className:`text-[12px] text-white/40 font-medium mb-1.5 block`,children:sn?`New password`:`Password`}),(0,G.jsx)(`input`,{type:`password`,value:tn,onChange:e=>nn(e.target.value),placeholder:`••••••••`,autoComplete:`new-password`,autoFocus:!sn,onKeyDown:qr,className:Zr}),tn.length>0&&tn.length<6&&(0,G.jsx)(`p`,{className:`text-amber-400/70 text-[11px] mt-1`,children:`At least 6 characters`})]}),(0,G.jsxs)(`div`,{className:`mt-3`,children:[(0,G.jsx)(`label`,{className:`text-[12px] text-white/40 font-medium mb-1.5 block`,children:sn?`Confirm new password`:`Confirm password`}),(0,G.jsx)(`input`,{type:`password`,value:I,onChange:e=>rn(e.target.value),placeholder:`••••••••`,autoComplete:`new-password`,onKeyDown:qr,className:Zr}),I.length>0&&!Vr&&(0,G.jsx)(`p`,{className:`text-red-400/70 text-[11px] mt-1`,children:`Passwords don't match`})]})]}),(0,G.jsxs)(`div`,{className:`mt-5 border border-white/[0.06] rounded-xl overflow-hidden`,children:[(0,G.jsxs)(`button`,{onClick:async()=>{if(En&&In){Kn(!0);return}if(En)Dn(!1),jn(``),kn(``),Nn(``);else{if(Dn(!0),Vn(``),Fn(``),sn&&!_n){Sn(!0),Vn(`Enter your current portal password above first, then toggle 2FA again.`),Dn(!1);return}if(An)er(`totp-setup`);else try{let e=await fetch(`/api/portal/totp/setup`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({password:sn?pn:tn})}),t=await e.json();e.ok?(kn(t.secret),jn(t.qrDataUri),Nn(t.otpauthUri),er(`totp-setup`)):(Vn(t.error||`Setup failed`),Dn(!1))}catch{Vn(`Could not reach server`),Dn(!1)}}},type:`button`,className:`w-full flex items-center gap-3 px-4 py-3 text-left`,children:[(0,G.jsx)(`div`,{className:`w-9 h-9 rounded-lg flex items-center justify-center shrink-0 ${En&&In?`bg-emerald-500/10`:`bg-white/[0.04]`}`,children:En&&In?(0,G.jsx)(ve,{className:`h-[18px] w-[18px] text-emerald-400`}):(0,G.jsx)(ye,{className:`h-[18px] w-[18px] text-white/30`})}),(0,G.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,G.jsx)(`span`,{className:`text-[13px] font-medium text-white block`,children:`Two-Factor Auth`}),(0,G.jsx)(`p`,{className:`text-[11px] text-white/30 mt-0.5`,children:En&&In?(0,G.jsx)(`span`,{className:`text-emerald-400/70`,children:`Active — authenticator app required`}):_t===`quick`||_t===`named`?(0,G.jsx)(`span`,{children:`Recommended for public bots`}):(0,G.jsx)(`span`,{children:`Extra security with an authenticator app`})})]}),(0,G.jsx)(`div`,{className:`w-10 h-6 rounded-full transition-colors relative shrink-0 ${En?`bg-emerald-500`:`bg-white/10`}`,children:(0,G.jsx)(`div`,{className:`absolute top-1 w-4 h-4 rounded-full bg-white shadow transition-transform ${En?`translate-x-5`:`translate-x-1`}`})})]}),Gn&&(0,G.jsxs)(`div`,{className:`px-4 pb-3 border-t border-white/[0.06]`,children:[(0,G.jsx)(`p`,{className:`text-[12px] text-white/40 mt-3 mb-2`,children:`Enter your current TOTP code to disable 2FA:`}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`input`,{type:`text`,inputMode:`numeric`,autoComplete:`one-time-code`,maxLength:6,value:qn,onChange:e=>{Jn(e.target.value.replace(/\D/g,``)),Xn(``)},placeholder:`000000`,className:Qr+` flex-1 tracking-[0.3em] text-center font-mono`}),(0,G.jsx)(`button`,{onClick:async()=>{if(qn.length===6)try{let e=await fetch(`/api/portal/totp/disable`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({password:sn?pn:tn,code:qn})}),t=await e.json();e.ok?(Dn(!1),Ln(!1),kn(``),jn(``),Nn(``),Kn(!1),Jn(``),Hn([]),Wn(!1)):Xn(t.error||`Failed to disable`)}catch{Xn(`Could not reach server`)}},disabled:qn.length!==6,className:`shrink-0 px-4 py-2.5 bg-red-500/10 hover:bg-red-500/20 text-red-400 text-[13px] font-medium rounded-xl transition-colors disabled:opacity-40`,children:`Disable`})]}),Yn&&(0,G.jsx)(`p`,{className:`text-red-400/70 text-[11px] mt-1`,children:Yn}),(0,G.jsx)(`button`,{onClick:()=>{Kn(!1),Jn(``),Xn(``)},className:`text-[11px] text-white/30 hover:text-white/50 mt-2`,children:`Cancel`})]}),Bn&&$n===`password`&&(0,G.jsx)(`div`,{className:`mx-4 mb-3 bg-red-500/8 border border-red-500/15 rounded-xl px-3 py-2`,children:(0,G.jsx)(`p`,{className:`text-red-400/90 text-[11px]`,children:Bn})})]}),t&&(0,G.jsxs)(`button`,{onClick:Gr,disabled:!Wr,className:`w-full mt-5 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40`,children:[`Continue`,(0,G.jsx)(w,{className:`h-4 w-4`})]})]},`password`),$n===`totp-setup`&&(0,G.jsxs)(sd.div,{initial:{opacity:0,x:20},animate:{opacity:1,x:0},exit:{opacity:0,x:20},transition:{duration:.15},children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-3 mb-1`,children:[(0,G.jsx)(`button`,{onClick:()=>{Dn(!1),jn(``),kn(``),Nn(``),Fn(``),Vn(``),er(`password`),yr()},className:`w-7 h-7 rounded-full bg-white/[0.04] flex items-center justify-center text-white/40 hover:text-white/70 transition-colors shrink-0`,children:(0,G.jsx)(ee,{className:`h-4 w-4`})}),(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`Set up 2FA`})]}),Bn&&(0,G.jsx)(`div`,{className:`mt-3 bg-red-500/8 border border-red-500/15 rounded-xl px-3 py-2`,children:(0,G.jsx)(`p`,{className:`text-red-400/90 text-[11px]`,children:Bn})}),An&&(0,G.jsxs)(G.Fragment,{children:[Zn?(0,G.jsxs)(`div`,{className:`mt-4`,children:[(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] leading-relaxed mb-4`,children:`Add Bloby to your authenticator app, then enter the 6-digit code below to confirm.`}),(0,G.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(On),nr(!0),setTimeout(()=>nr(!1),3e3)},className:`w-full py-3 text-[14px] font-medium rounded-xl transition-colors flex items-center justify-center gap-2 ${tr?`bg-emerald-500/10 text-emerald-400 border border-emerald-500/20`:`bg-white/[0.05] text-white/70 hover:bg-white/[0.08] border border-white/[0.08]`}`,children:tr?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(ne,{className:`h-4 w-4`}),`Secret key copied`]}):(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(ae,{className:`h-4 w-4`}),`Copy secret key`]})}),(0,G.jsx)(`p`,{className:`text-[11px] text-white/20 text-center mt-2`,children:`Paste it in your authenticator app → Add account → Enter key`}),(0,G.jsxs)(`a`,{href:Mn,onClick:()=>_r(),className:`w-full mt-3 py-2.5 text-[13px] text-white/30 hover:text-white/50 flex items-center justify-center gap-1.5 transition-colors`,children:[(0,G.jsx)(be,{className:`h-3.5 w-3.5`}),`Or open directly in authenticator`]})]}):(0,G.jsxs)(`div`,{className:`mt-4 flex gap-4 items-start`,children:[(0,G.jsx)(`div`,{className:`shrink-0`,children:(0,G.jsx)(`div`,{className:`bg-white rounded-xl p-1.5`,children:(0,G.jsx)(`img`,{src:An,alt:`TOTP QR Code`,className:`w-[140px] h-[140px]`})})}),(0,G.jsxs)(`div`,{className:`flex-1 min-w-0 pt-1`,children:[(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] leading-relaxed`,children:`Scan this QR code with your authenticator app.`}),(0,G.jsx)(`p`,{className:`text-white/25 text-[11px] mt-2 leading-relaxed`,children:`Google Authenticator, Authy, 1Password, or any TOTP app.`}),(0,G.jsxs)(`button`,{onClick:()=>{navigator.clipboard.writeText(On)},className:`mt-3 text-[11px] text-white/25 hover:text-white/40 flex items-center gap-1 transition-colors`,children:[(0,G.jsx)(ae,{className:`h-3 w-3`}),`Copy secret key`]})]})]}),(0,G.jsxs)(`div`,{className:`mt-5`,children:[(0,G.jsx)(`label`,{className:`text-[12px] text-white/40 font-medium mb-1.5 block`,children:`Enter the 6-digit code from your app`}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`input`,{type:`text`,inputMode:`numeric`,autoComplete:`one-time-code`,maxLength:6,value:Pn,onChange:e=>{Fn(e.target.value.replace(/\D/g,``)),Vn(``)},placeholder:`000000`,autoFocus:!0,className:Zr+` tracking-[0.3em] text-center font-mono flex-1`}),(0,G.jsx)(`button`,{onClick:async()=>{if(Pn.length===6){zn(!0),Vn(``);try{let e=await fetch(`/api/portal/totp/verify-setup`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({code:Pn,password:sn?pn:tn})}),t=await e.json();e.ok&&t.success?(Ln(!0),Hn(t.recoveryCodes||[]),er(`recovery`),yr()):Vn(t.error||`Verification failed`)}catch{Vn(`Could not reach server`)}finally{zn(!1)}}},disabled:Pn.length!==6||Rn,className:`shrink-0 px-5 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-xl transition-colors flex items-center gap-2 disabled:opacity-40`,children:Rn?(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}):`Verify`})]})]})]})]},`totp-setup`),$n===`recovery`&&(0,G.jsxs)(sd.div,{initial:{opacity:0,x:20},animate:{opacity:1,x:0},exit:{opacity:0,x:20},transition:{duration:.15},children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-3 mb-1`,children:[(0,G.jsx)(`div`,{className:`w-9 h-9 rounded-xl bg-emerald-500/10 flex items-center justify-center shrink-0`,children:(0,G.jsx)(ve,{className:`h-[18px] w-[18px] text-emerald-400`})}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`2FA enabled`}),(0,G.jsx)(`p`,{className:`text-emerald-400/70 text-[12px]`,children:`Save your recovery codes`})]})]}),(0,G.jsx)(`p`,{className:`text-white/35 text-[13px] mt-3 leading-relaxed`,children:`If you lose your authenticator app, you can use one of these codes to sign in. Each code works once. Store them somewhere safe.`}),(0,G.jsx)(`div`,{className:`mt-4 grid grid-cols-2 gap-1.5`,children:R.map((e,t)=>(0,G.jsx)(`div`,{className:`bg-white/[0.03] border border-white/[0.06] rounded-lg px-3 py-2 text-center`,children:(0,G.jsx)(`code`,{className:`text-[13px] text-white/60 font-mono tracking-wider`,children:e})},t))}),(0,G.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(R.join(`
25
+ [&::-moz-range-thumb]:bg-white [&::-moz-range-thumb]:border-0 [&::-moz-range-thumb]:shadow-[0_0_0_3px_rgba(0,105,254,0.35)]`}),(0,G.jsx)(`div`,{className:`flex justify-between mt-2 px-[1px]`,children:bd.map((e,t)=>(0,G.jsx)(`button`,{type:`button`,onClick:()=>x(t),className:`text-[10px] leading-none transition-colors ${t===m?`text-[#0069FE] font-semibold`:`text-white/30 hover:text-white/55`}`,children:e.label},e.label))}),p&&(0,G.jsxs)(`div`,{className:`mt-3 flex items-center gap-2.5`,children:[(0,G.jsx)(`input`,{type:`number`,min:1,max:1440,value:Number.isFinite(e.intervalMinutes)?e.intervalMinutes:``,onChange:e=>{let t=parseInt(e.target.value,10);b({intervalMinutes:Number.isFinite(t)?t:NaN})},placeholder:`45`,className:`w-28 bg-white/[0.03] border border-white/[0.08] text-white rounded-xl px-4 py-2.5 text-[13px] outline-none focus:border-[#0069FE]/30 transition-colors placeholder:text-white/20 font-mono`}),(0,G.jsx)(`span`,{className:`text-[12px] text-white/40`,children:`minutes between pulses`})]}),p&&!g&&(0,G.jsx)(`p`,{className:`text-amber-400/80 text-[11px] mt-1.5`,children:`Enter a whole number of minutes (1–1440).`}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2 mt-6 mb-2.5`,children:[(0,G.jsx)(pe,{className:`h-3.5 w-3.5 text-[#0069FE]/70`}),(0,G.jsx)(`span`,{className:`text-[12px] font-semibold text-white/70 uppercase tracking-wide`,children:`Quiet hours`})]}),(0,G.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,G.jsxs)(`div`,{className:`flex-1`,children:[(0,G.jsx)(`label`,{className:`text-[11px] text-white/40 mb-1 block`,children:`Start`}),(0,G.jsx)(`input`,{type:`time`,value:e.quietHours.start,onChange:t=>b({quietHours:{...e.quietHours,start:t.target.value}}),className:`w-full bg-white/[0.03] border border-white/[0.08] text-white rounded-xl px-4 py-2.5 text-[13px] outline-none focus:border-[#0069FE]/30 transition-colors [color-scheme:dark]`})]}),(0,G.jsx)(w,{className:`h-4 w-4 text-white/25 mt-5 shrink-0`}),(0,G.jsxs)(`div`,{className:`flex-1`,children:[(0,G.jsx)(`label`,{className:`text-[11px] text-white/40 mb-1 block`,children:`End`}),(0,G.jsx)(`input`,{type:`time`,value:e.quietHours.end,onChange:t=>b({quietHours:{...e.quietHours,end:t.target.value}}),className:`w-full bg-white/[0.03] border border-white/[0.08] text-white rounded-xl px-4 py-2.5 text-[13px] outline-none focus:border-[#0069FE]/30 transition-colors [color-scheme:dark]`})]})]}),(0,G.jsx)(`p`,{className:`text-white/35 text-[12px] mt-2 leading-relaxed`,children:`No pulses fire between these times.`})]}),o&&!_&&(0,G.jsxs)(`div`,{className:`mt-4 flex items-center gap-2.5 bg-emerald-500/[0.06] border border-emerald-500/20 rounded-xl px-4 py-3`,children:[(0,G.jsx)(ne,{className:`h-4 w-4 text-emerald-400 shrink-0`}),(0,G.jsx)(`p`,{className:`text-emerald-300/90 text-[12px]`,children:`Saved — the scheduler picks this up within a minute.`})]}),c&&(0,G.jsxs)(`div`,{className:`mt-3 flex items-center gap-1.5 text-[12px] text-red-400`,children:[(0,G.jsx)(Se,{className:`h-3.5 w-3.5 shrink-0`}),c]}),_&&(0,G.jsx)(`button`,{type:`button`,onClick:S,disabled:!y,className:`w-full mt-4 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40 disabled:cursor-not-allowed`,children:i?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}),`Saving...`]}):(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(_e,{className:`h-4 w-4`}),`Save pulse settings`]})})]})}function Dd({crons:e,onChanged:t,onLocalUpdate:n}){let[r,i]=(0,v.useState)({}),[a,o]=(0,v.useState)(null),[s,c]=(0,v.useState)({}),[l,u]=(0,v.useState)(``),[d,f]=(0,v.useState)(new Set),p=(e,t)=>i(n=>({...n,[e]:t})),m=e=>f(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n}),h=async e=>{if(!r[e.id]){u(``),p(e.id,`pause`);try{let r=await Ne(`/api/crons/pause`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({id:e.id,paused:!e.paused})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e.error||`Failed to update`)}n(t=>t.map(t=>t.id===e.id?{...t,paused:!e.paused}:t)),t()}catch(e){u(e.message||`Failed to update`)}finally{p(e.id,void 0)}}},g=async e=>{if(!r[e.id]){u(``),p(e.id,`delete`);try{let r=await Ne(`/api/crons/delete`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({id:e.id})});if(!r.ok){let e=await r.json().catch(()=>({}));throw Error(e.error||`Failed to delete`)}o(null),n(t=>t.filter(t=>t.id!==e.id)),t()}catch(e){u(e.message||`Failed to delete`)}finally{p(e.id,void 0)}}},_=async e=>{if(!s[e.id]){u(``),c(t=>({...t,[e.id]:!0}));try{let t=await Ne(`/api/crons/task?id=${encodeURIComponent(e.id)}`);if(!t.ok)throw Error(`Could not download task file`);let n=await t.blob(),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=`${e.id}.md`,document.body.appendChild(i),i.click(),i.remove(),URL.revokeObjectURL(r)}catch(e){u(e.message||`Download failed`)}finally{c(t=>({...t,[e.id]:!1}))}}};return(0,G.jsxs)(`div`,{className:`mt-8`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(te,{className:`h-4 w-4 text-[#0069FE]/70 shrink-0`}),(0,G.jsx)(`h2`,{className:`text-[15px] font-bold text-white tracking-tight`,children:`Crons`})]}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:`Crons let your agent schedule tasks inside the main session, running them daily, hourly, or on any schedule you choose. They can also be one-shot tasks that run once at a specific time.`}),(0,G.jsxs)(`div`,{className:`mt-2 flex items-start gap-1.5 text-white/30 text-[12px] leading-relaxed`,children:[(0,G.jsx)(ue,{className:`h-3.5 w-3.5 mt-0.5 shrink-0`}),(0,G.jsx)(`span`,{children:`To change or add a cron, just ask your agent. To delete or pause, use the buttons below.`})]}),l&&(0,G.jsxs)(`div`,{className:`mt-3 flex items-center gap-1.5 text-[12px] text-red-400`,children:[(0,G.jsx)(Se,{className:`h-3.5 w-3.5 shrink-0`}),l]}),(0,G.jsx)(`div`,{className:`mt-4 space-y-2.5`,children:e.length===0?(0,G.jsxs)(`div`,{className:`rounded-xl border border-white/[0.06] bg-white/[0.02] px-4 py-7 text-center`,children:[(0,G.jsx)(te,{className:`h-5 w-5 text-white/25 mx-auto mb-2`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px]`,children:`No scheduled tasks yet.`}),(0,G.jsx)(`p`,{className:`text-white/25 text-[12px] mt-1`,children:`Ask your agent to schedule something.`})]}):e.map(e=>{let t=!!e.paused,n=r[e.id],i=d.has(e.id),c=Td(e.nextRun);return(0,G.jsxs)(`div`,{className:`rounded-xl border transition-colors ${t?`border-white/[0.05] bg-white/[0.015]`:`border-white/[0.06] bg-white/[0.02]`}`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2 p-2.5`,children:[(0,G.jsxs)(`button`,{type:`button`,onClick:()=>m(e.id),className:`flex items-center gap-2.5 flex-1 min-w-0 text-left`,children:[(0,G.jsx)(`div`,{className:`w-8 h-8 rounded-lg flex items-center justify-center shrink-0 ${t?`bg-white/[0.04]`:e.oneShot?`bg-amber-500/10`:`bg-[#0069FE]/10`}`,children:e.oneShot?(0,G.jsx)(Ee,{className:`h-4 w-4 ${t?`text-white/40`:`text-amber-400`}`}):(0,G.jsx)(ie,{className:`h-4 w-4 ${t?`text-white/40`:`text-[#0069FE]`}`})}),(0,G.jsx)(`span`,{className:`flex-1 min-w-0 truncate text-[13px] ${t?`text-white/45`:`text-white`}`,children:e.task||`(untitled task)`}),t&&(0,G.jsx)(`span`,{className:`shrink-0 text-[10px] font-medium text-white/40 bg-white/[0.05] rounded-full px-2 py-0.5`,children:`Paused`})]}),a===e.id?(0,G.jsxs)(`div`,{className:`flex items-center gap-1 shrink-0`,children:[(0,G.jsx)(`span`,{className:`text-[11px] text-white/45 mr-0.5`,children:`Delete?`}),(0,G.jsxs)(`button`,{type:`button`,onClick:()=>g(e),disabled:n===`delete`,className:`inline-flex items-center gap-1 rounded-md bg-red-500/15 hover:bg-red-500/25 border border-red-500/30 text-red-300 text-[11px] font-medium px-2 py-1 transition-colors disabled:opacity-50`,children:[n===`delete`?(0,G.jsx)(O,{className:`h-3 w-3 animate-spin`}):(0,G.jsx)(xe,{className:`h-3 w-3`}),`Delete`]}),(0,G.jsx)(`button`,{type:`button`,onClick:()=>o(null),disabled:n===`delete`,className:`rounded-md text-white/40 hover:text-white/70 text-[11px] px-1.5 py-1 transition-colors`,children:`Cancel`})]}):(0,G.jsxs)(`div`,{className:`flex items-center gap-0.5 shrink-0`,children:[(0,G.jsx)(`button`,{type:`button`,onClick:()=>h(e),disabled:!!n,title:t?`Resume`:`Pause`,"aria-label":t?`Resume`:`Pause`,className:`p-1.5 rounded-lg text-white/40 hover:text-white/80 hover:bg-white/[0.05] transition-colors disabled:opacity-50`,children:n===`pause`?(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}):t?(0,G.jsx)(me,{className:`h-4 w-4`}):(0,G.jsx)(k,{className:`h-4 w-4`})}),(0,G.jsx)(`button`,{type:`button`,onClick:()=>o(e.id),disabled:!!n,title:`Delete`,"aria-label":`Delete`,className:`p-1.5 rounded-lg text-white/30 hover:text-red-400 hover:bg-red-500/[0.06] transition-colors disabled:opacity-50`,children:(0,G.jsx)(xe,{className:`h-4 w-4`})}),(0,G.jsx)(`button`,{type:`button`,onClick:()=>m(e.id),title:i?`Collapse`:`Expand`,"aria-label":i?`Collapse`:`Expand`,className:`p-1.5 rounded-lg text-white/30 hover:text-white/70 hover:bg-white/[0.05] transition-colors`,children:(0,G.jsx)(T,{className:`h-4 w-4 transition-transform ${i?`rotate-180`:``}`})})]})]}),i&&(0,G.jsxs)(`div`,{className:`px-2.5 pb-3 pl-[52px] -mt-0.5`,children:[(0,G.jsxs)(`div`,{className:`flex flex-wrap items-center gap-x-2 gap-y-1 text-[12px] text-white/45`,children:[(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,G.jsx)(ie,{className:`h-3 w-3 text-white/30 shrink-0`}),e.description]}),e.oneShot&&(0,G.jsx)(`span`,{className:`text-amber-300/70`,children:`· One-time`}),!t&&c&&(0,G.jsxs)(`span`,{className:`text-[#4AA8FF]`,children:[`· Next: `,c]})]}),e.hasTaskFile&&(0,G.jsxs)(`button`,{type:`button`,onClick:()=>_(e),disabled:s[e.id],className:`group mt-2 inline-flex items-center gap-1.5 rounded-md bg-white/[0.04] hover:bg-white/[0.07] border border-white/[0.06] hover:border-white/[0.12] text-white/50 hover:text-white/80 text-[11px] font-mono px-2 py-1 transition-colors disabled:opacity-50`,title:`Download task instructions`,children:[s[e.id]?(0,G.jsx)(O,{className:`h-3 w-3 animate-spin`}):(0,G.jsx)(E,{className:`h-3 w-3 shrink-0`}),e.id,`.md`,(0,G.jsx)(oe,{className:`h-3 w-3 opacity-0 group-hover:opacity-100 transition-opacity`})]})]})]},e.id)})})]})}function Od({cacheRef:e}){let t=(0,v.useRef)(e.current!=null).current,n=e.current,[r,i]=(0,v.useState)(!t),[a,o]=(0,v.useState)(``),[s,c]=(0,v.useState)(n?.pulse??Q),[l,u]=(0,v.useState)(n?.original??null),[d,f]=(0,v.useState)(n?.crons??[]),p=async e=>{let t=await Ne(`/api/schedule`);if(!t.ok)throw Error(`Failed to load schedule`);let n=await t.json();if(f(Array.isArray(n.crons)?n.crons:[]),e){let e={enabled:!!n.pulse?.enabled,intervalMinutes:Number(n.pulse?.intervalMinutes)||60,quietHours:{start:n.pulse?.quietHours?.start??`22:00`,end:n.pulse?.quietHours?.end??`07:00`}};c(e),u(e)}};return(0,v.useEffect)(()=>{if(t)return;let e=!1;return p(!0).then(()=>{e||i(!1)}).catch(t=>{e||(o(t.message||`Failed to load`),i(!1))}),()=>{e=!0}},[t]),(0,v.useEffect)(()=>{r||(e.current={pulse:s,original:l,crons:d})}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`Pulse & Crons`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:`Background wake-ups and scheduled tasks your agent runs on its own.`}),r?(0,G.jsx)(`div`,{className:`flex items-center justify-center py-12 text-white/40`,children:(0,G.jsx)(O,{className:`h-5 w-5 animate-spin`})}):a?(0,G.jsxs)(`div`,{className:`mt-5 flex items-center gap-2 text-[13px] text-red-400`,children:[(0,G.jsx)(Se,{className:`h-4 w-4 shrink-0`}),a]}):(0,G.jsxs)(`div`,{className:`mt-6`,children:[(0,G.jsx)(Ed,{pulse:s,original:l,setPulse:c,onPulseSaved:e=>u(e)}),(0,G.jsx)(Dd,{crons:d,onLocalUpdate:e=>f(e),onChanged:()=>{p(!1).catch(()=>{})}})]})]})}function kd({onComplete:e,isInitialSetup:t=!1,onSave:n,onTunnelSwitch:r}){let[i,a]=(0,v.useState)(0),[o,s]=(0,v.useState)(``),[c,l]=(0,v.useState)(`anthropic`),[u,d]=(0,v.useState)(``),[f,p]=(0,v.useState)(!1),[m,h]=(0,v.useState)({anthropic:`idle`,openai:`idle`,pi:`idle`}),[g,_]=(0,v.useState)([]),[y,b]=(0,v.useState)(``),[x,S]=(0,v.useState)(``),[C,te]=(0,v.useState)(``),[T,ie]=(0,v.useState)(``),[oe,E]=(0,v.useState)(!1),[ue,de]=(0,v.useState)(!1),[pe,k]=(0,v.useState)(),[me,he]=(0,v.useState)(null),[_e,xe]=(0,v.useState)(!1),[Ee,De]=(0,v.useState)(``),[Oe,ke]=(0,v.useState)(!1),[Ae,je]=(0,v.useState)(),[Me,Ne]=(0,v.useState)(!1),[Pe,Fe]=(0,v.useState)(`device`),[Ie,Le]=(0,v.useState)(`idle`),[Re,ze]=(0,v.useState)(``),[Be,Ve]=(0,v.useState)(``),[He,Ue]=(0,v.useState)(!1),[We,Ge]=(0,v.useState)(!1),[A,Ke]=(0,v.useState)(!1),[qe,Je]=(0,v.useState)(``),[Ye,Xe]=(0,v.useState)(!1),[Ze,Qe]=(0,v.useState)(),[$e,et]=(0,v.useState)(!1),[j,tt]=(0,v.useState)(``),[nt,rt]=(0,v.useState)(null),[it,at]=(0,v.useState)(``),[ot,st]=(0,v.useState)({}),[ct,lt]=(0,v.useState)(``),[ut,dt]=(0,v.useState)(!1),[ft,pt]=(0,v.useState)(!1),[mt,ht]=(0,v.useState)(``),gt=(0,v.useRef)(null),[_t,vt]=(0,v.useState)(`quick`),[yt,bt]=(0,v.useState)(``),[xt,St]=(0,v.useState)(``),[Ct,wt]=(0,v.useState)(`relay`),[M,N]=(0,v.useState)(null),[P,Tt]=(0,v.useState)(!1),[Et,Dt]=(0,v.useState)(!1),[Ot,kt]=(0,v.useState)({}),[At,jt]=(0,v.useState)(!1),[Mt,Nt]=(0,v.useState)(``),[Pt,Ft]=(0,v.useState)(``),[It,Lt]=(0,v.useState)(!1),[Rt,zt]=(0,v.useState)(`tunnel`),[Bt,Vt]=(0,v.useState)(!1),[Ht,Ut]=(0,v.useState)(``),[Wt,Gt]=(0,v.useState)(!1),[Kt,qt]=(0,v.useState)(``),[Jt,Yt]=(0,v.useState)(!1),[Xt,Zt]=(0,v.useState)(!1),[Qt,F]=(0,v.useState)(``),[$t,en]=(0,v.useState)(`admin`),[tn,nn]=(0,v.useState)(``),[I,rn]=(0,v.useState)(``),[an,on]=(0,v.useState)(!1),[sn,cn]=(0,v.useState)(!1),[ln,un]=(0,v.useState)(!1),[dn,fn]=(0,v.useState)(!1),[pn,mn]=(0,v.useState)(``),[hn,gn]=(0,v.useState)(``),[_n,vn]=(0,v.useState)(!1),[yn,bn]=(0,v.useState)(!1),[xn,Sn]=(0,v.useState)(!1),[L,Cn]=(0,v.useState)(!1),[wn,Tn]=(0,v.useState)(``),[En,Dn]=(0,v.useState)(!1),[On,kn]=(0,v.useState)(``),[An,jn]=(0,v.useState)(``),[Mn,Nn]=(0,v.useState)(``),[Pn,Fn]=(0,v.useState)(``),[In,Ln]=(0,v.useState)(!1),[Rn,zn]=(0,v.useState)(!1),[Bn,Vn]=(0,v.useState)(``),[R,Hn]=(0,v.useState)([]),[Un,Wn]=(0,v.useState)(!1),[Gn,Kn]=(0,v.useState)(!1),[qn,Jn]=(0,v.useState)(``),[Yn,Xn]=(0,v.useState)(``),[Zn,Qn]=(0,v.useState)(!1),[$n,er]=(0,v.useState)(`password`),[tr,nr]=(0,v.useState)(!1),rr=(0,v.useRef)(!1),ir=(0,v.useRef)(null),ar=(0,v.useRef)(null),or=(0,v.useRef)(null),[sr,cr]=(0,v.useState)({userName:``,botName:``,provider:``,model:``,whisperEnabled:!1,whisperKey:``}),[lr,ur]=(0,v.useState)(!1),[dr,fr]=(0,v.useState)(!1),[pr,mr]=(0,v.useState)(``),hr=m[c]===`connected`,gr=`bloby_totp_setup`;function _r(){try{sessionStorage.setItem(gr,JSON.stringify({secret:On,qrUri:An,otpauthUri:Mn,phase:$n,portalPass:tn,portalPassConfirm:I}))}catch{}}function vr(){try{let e=sessionStorage.getItem(gr);if(!e)return!1;let t=JSON.parse(e);if(t.secret&&t.phase===`totp-setup`)return kn(t.secret),jn(t.qrUri||``),Nn(t.otpauthUri||``),Dn(!0),er(`totp-setup`),a(3),t.portalPass&&(nn(t.portalPass),rn(t.portalPassConfirm||``)),!0}catch{}return!1}function yr(){try{sessionStorage.removeItem(gr)}catch{}}(0,v.useEffect)(()=>{fetch(`/api/onboard/status`).then(e=>e.json()).then(e=>{e.userName&&s(e.userName),e.handle?(tt(e.handle.username),lt(e.handle.tier||`at`),N({username:e.handle.username,tier:e.handle.tier,url:e.handle.url}),pt(!0),ht(e.handle.url)):e.agentName&&tt(e.agentName),e.portalUser&&en(e.portalUser),e.portalConfigured&&cn(!0),e.provider&&l(e.provider),e.model&&d(e.model),e.whisperEnabled&&(Cn(!0),Tn(e.whisperKey||``)),e.totpEnabled&&(Dn(!0),Ln(!0)),e.tunnelMode&&vt(e.tunnelMode),e.tunnelDomain&&bt(e.tunnelDomain),e.tunnelUrl&&St(e.tunnelUrl),e.handle||wt(`tunnel`),cr({userName:e.userName||``,botName:e.handle&&e.handle.username||e.agentName||``,provider:e.provider||``,model:e.model||``,whisperEnabled:!!e.whisperEnabled,whisperKey:e.whisperKey||``}),rr.current=!0,e.totpEnabled||vr()}).catch(()=>{rr.current=!0})},[]),(0,v.useEffect)(()=>{zt(ld(window.location.hostname))},[]),(0,v.useEffect)(()=>{Qn(window.matchMedia(`(max-width: 768px)`).matches||`ontouchstart`in window)},[]),(0,v.useEffect)(()=>{c!==`anthropic`||m.anthropic===`connected`||fetch(`/api/auth/claude/status`).then(e=>e.json()).then(e=>{e.authenticated&&h(e=>({...e,anthropic:`connected`}))}).catch(()=>{})},[c]),(0,v.useEffect)(()=>{c!==`openai`||m.openai===`connected`||fetch(`/api/auth/codex/status`).then(e=>e.json()).then(e=>{e.authenticated&&h(e=>({...e,openai:`connected`}))}).catch(()=>{})},[c]),(0,v.useEffect)(()=>{if(gt.current&&clearTimeout(gt.current),!rr.current||_t===`off`||M&&ft&&j===M.username)return;rt(null),at(``),st({}),kt({}),jt(!1),Nt(``),Ft(``),pt(!1),ht(``);let e=j.trim();if(e){if(e.length<3){rt(`invalid`),at(`At least 3 characters`);return}return rt(`checking`),gt.current=setTimeout(async()=>{try{let t=await(await fetch(`/api/handle/check/${encodeURIComponent(e)}`)).json();if(!t.valid)rt(`invalid`),at(t.error);else{let e={},n={};for(let r of t.handles)e[r.tier]=r.available,r.reserved&&(n[r.tier]=!0);st(e),kt(n),rt(`ready`),lt(``)}}catch{rt(null)}},400),()=>{gt.current&&clearTimeout(gt.current)}}},[j]),(0,v.useEffect)(()=>{if(!j||j.length<3||nt!==`ready`)return;let e=async()=>{try{let e=await(await fetch(`/api/handle/check/${encodeURIComponent(j.trim())}`)).json();if(e.valid){let t={},n={};for(let r of e.handles)t[r.tier]=r.available,r.reserved&&(n[r.tier]=!0);st(t),kt(n)}}catch{}};return window.addEventListener(`focus`,e),()=>window.removeEventListener(`focus`,e)},[j,nt]);let br=e=>{tt(e.toLowerCase().replace(/[^a-z0-9-]/g,``))},xr=async()=>{if(!(!j||nt!==`ready`||!ot[ct])){dt(!0);try{let e=await(await fetch(`/api/handle/register`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({username:j,tier:ct})})).json();e.ok?(pt(!0),ht(e.url)):(at(e.error||`Registration failed`),rt(`invalid`))}catch{at(`Could not reach server`),rt(`invalid`)}finally{dt(!1)}}},Sr=async()=>{if(!(!j||nt!==`ready`||!ot[ct])){Dt(!0);try{let e=await(await fetch(`/api/handle/change`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({username:j,tier:ct})})).json();e.ok?(pt(!0),ht(e.url),N({username:j,tier:ct,url:e.url}),Tt(!1)):(at(e.error||`Handle change failed`),rt(`invalid`))}catch{at(`Could not reach server`),rt(`invalid`)}finally{Dt(!1)}}},Cr=async()=>{if(!(!j||!Mt)){Lt(!0),Ft(``);try{let e=await(await fetch(`/api/handle/claim-reserved`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({handle:j,hash:Mt})})).json();e.ok?(pt(!0),ht(e.url),jt(!1),Nt(``),lt(`premium`),wt(`relay`)):Ft(e.error||`Invalid activation code`)}catch{Ft(`Could not reach server`)}finally{Lt(!1)}}},wr=e=>{c===`openai`&&e!==`openai`&&(A&&fetch(`/api/auth/codex/cancel`,{method:`POST`}),Ie===`pending`&&fetch(`/api/auth/codex/device/cancel`,{method:`POST`})),l(e),d(e===`openai`?`gpt-5.5:high`:``),xe(!1),De(``),je(void 0),Ke(!1),Je(``),Le(`idle`),ze(``),Ve(``),Fe(`device`),Qe(void 0),k(void 0)};(0,v.useEffect)(()=>{if(c!==`pi`)return;let e=!1;return(async()=>{try{let[t,n]=await Promise.all([fetch(`/api/auth/pi/providers`),fetch(`/api/auth/pi/status`)]),r=await t.json(),i=await n.json();if(e)return;let a=r?.providers||[];_(a),i?.configured?(b(i.subProvider||``),ie(i.modelId||``),te(i.baseUrl||``),h(e=>({...e,pi:`connected`})),he({subProvider:i.subProvider,modelId:i.modelId,baseUrl:i.baseUrl}),d(`${i.subProvider}/${i.modelId||``}`)):!y&&a[0]&&(b(a[0].id),te(a[0].baseUrl||``),ie(a[0].defaultModel||``))}catch(t){e||k(t?.message||`Failed to load Bloby providers`)}})(),()=>{e=!0}},[c]);let Tr=g.find(e=>e.id===y),Er=e=>{let t=g.find(t=>t.id===e);b(e),te(t?.baseUrl||``),ie(t?.defaultModel||``),k(void 0),m.pi===`connected`&&(h(e=>({...e,pi:`idle`})),he(null))},Dr=async()=>{if(y){k(void 0),de(!0);try{let e={subProvider:y,apiKey:x.trim()||void 0,baseUrl:C.trim()||void 0,modelId:T.trim()||void 0},t=await(await fetch(`/api/auth/pi/test`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})).json();if(!t?.ok){k(t?.error||`Connection test failed`);return}let n=await(await fetch(`/api/auth/pi/save`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)})).json();if(!n?.ok){k(n?.error||`Failed to save credentials`);return}h(e=>({...e,pi:`connected`})),he(n.status||null),d(`${y}/${T||Tr?.defaultModel||``}`),S(``)}catch(e){k(e?.message||`Connection failed`)}finally{de(!1)}}},Or=async()=>{try{await fetch(`/api/auth/pi`,{method:`DELETE`})}catch{}h(e=>({...e,pi:`idle`})),he(null),d(``)},kr=e=>{if(window.matchMedia(`(display-mode: standalone)`).matches||navigator.standalone===!0){let t=document.createElement(`a`);t.href=e,t.target=`_blank`,t.rel=`noopener noreferrer`,document.body.appendChild(t),t.click(),document.body.removeChild(t)}else window.open(e,`_blank`,`noopener,noreferrer`)},Ar=async()=>{je(void 0);try{let e=await(await fetch(`/api/auth/claude/start`,{method:`POST`})).json();e.success&&e.authUrl?(kr(e.authUrl),xe(!0)):je(e.error||`Failed to start authentication`)}catch(e){je(e.message)}},jr=async()=>{if(Ee.trim()){ke(!0),je(void 0);try{let e=await(await fetch(`/api/auth/claude/exchange`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({code:Ee.trim()})})).json();e.success?h(e=>({...e,anthropic:`connected`})):je(e.error||`Code exchange failed`)}catch(e){je(e.message)}finally{ke(!1)}}},Mr=async()=>{try{let e=await navigator.clipboard.readText();e&&De(e.trim())}catch{}},Nr=async()=>{Ne(!0),je(void 0);try{(await(await fetch(`/api/auth/claude/status`)).json()).authenticated?h(e=>({...e,anthropic:`connected`})):je(`No active session found. Please authenticate first.`)}catch{}finally{Ne(!1)}},Pr=async()=>{Qe(void 0),Ue(!0),Le(`pending`);try{let e=await(await fetch(`/api/auth/codex/device/start`,{method:`POST`})).json();e.success?(ze(e.userCode||``),Ve(e.verificationUrl||``),e.verificationUrl&&kr(e.verificationUrl)):(Le(`error`),Qe(e.error||`Failed to start device-code login`))}catch(e){Le(`error`),Qe(e.message)}finally{Ue(!1)}},Fr=async()=>{try{await fetch(`/api/auth/codex/device/cancel`,{method:`POST`})}catch{}Le(`idle`),ze(``),Ve(``)},Ir=async()=>{try{await navigator.clipboard.writeText(Re),Ge(!0),setTimeout(()=>Ge(!1),1500)}catch{}};(0,v.useEffect)(()=>{if(Ie!==`pending`||!Re)return;let e=setInterval(async()=>{try{let e=await(await fetch(`/api/auth/codex/device/status`)).json();e.state===`success`?(Le(`success`),h(e=>({...e,openai:`connected`}))):e.state===`error`&&(Le(`error`),Qe(e.error||`Device-code login failed`))}catch{}},2e3);return()=>clearInterval(e)},[Ie,Re]);let Lr=async()=>{Qe(void 0);try{let e=await(await fetch(`/api/auth/codex/start`,{method:`POST`})).json();e.success&&e.authUrl?(kr(e.authUrl),Ke(!0)):Qe(e.error||`Failed to start authentication`)}catch(e){Qe(e.message)}},Rr=async()=>{if(qe.trim()){Xe(!0),Qe(void 0);try{let e=await(await fetch(`/api/auth/codex/exchange`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({code:qe.trim()})})).json();e.success?(h(e=>({...e,openai:`connected`})),Je(``)):Qe(e.error||`Code exchange failed`)}catch(e){Qe(e.message)}finally{Xe(!1)}}},zr=async()=>{try{let e=await navigator.clipboard.readText();e&&Je(e.trim())}catch{}},Br=async()=>{et(!0),Qe(void 0);try{(await(await fetch(`/api/auth/codex/status`)).json()).authenticated?h(e=>({...e,openai:`connected`})):Qe(`No active session found. Please authenticate first.`)}catch{}finally{et(!1)}},Vr=tn===I,Hr=tn.length>=6&&Vr,Ur=sn?tn.length===0||_n&&Hr:Hr,Wr=(()=>{switch(i){case 0:return!0;case 1:return o.trim().length>0;case 2:return Bt||Jt?!1:_t===`off`||_t===`named`||Ct===`tunnel`?j.trim().length>=3:ft;case 3:return!($n!==`password`||!Ur||En&&!In);case 4:return!!(c&&u&&hr);case 5:return!0;case 6:return!0;case 7:return!0;default:return!1}})(),Gr=()=>{t&&Wr&&i<6&&a(e=>e+1)},Kr=()=>{i>0&&a(e=>e-1)},qr=e=>{e.key===`Enter`&&Wr&&Gr()},Jr=(()=>{if(t)return!1;switch(i){case 1:return o.trim()!==sr.userName;case 2:return j.trim()!==sr.botName;case 3:return $n===`password`&&tn.length>0&&Hr&&(sn?_n:!0);case 4:return(c!==sr.provider||u!==sr.model)&&hr&&!!u;case 5:return(L!==sr.whisperEnabled||L&&wn!==sr.whisperKey)&&!(L&&(!wn.startsWith(`sk-`)||wn.length<20));default:return!1}})();(0,v.useEffect)(()=>{fr(!1),mr(``),or.current?.scrollTo({top:0})},[i]);let Yr=async()=>{if(!Jr||lr)return;ur(!0),mr(``),fr(!1);let e={userName:sr.userName,agentName:sr.botName||`Bloby`,provider:sr.provider,model:sr.model,apiKey:``,whisperEnabled:sr.whisperEnabled,whisperKey:sr.whisperEnabled?sr.whisperKey:``,portalUser:$t.trim(),portalPass:``};switch(i){case 1:e.userName=o.trim();break;case 2:e.agentName=j.trim()||`Bloby`;break;case 3:e.portalPass=tn;break;case 4:e.provider=c,e.model=u;break;case 5:e.whisperEnabled=L,e.whisperKey=L?wn:``;break}try{n?await n(e):await fetch(`/api/onboard`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(e)}),cr(e=>{switch(i){case 1:return{...e,userName:o.trim()};case 2:return{...e,botName:j.trim()};case 4:return{...e,provider:c,model:u};case 5:return{...e,whisperEnabled:L,whisperKey:wn};default:return e}}),i===3&&(nn(``),rn(``),mn(``),vn(!1),Sn(!1),cn(!0)),fr(!0),ur(!1)}catch(e){mr(e.message||`Save failed`),ur(!1)}},Xr=async()=>{p(!0);let r={userName:o.trim(),agentName:j.trim()||`Bloby`,provider:c,model:u,apiKey:``,whisperEnabled:L,whisperKey:L?wn:``,portalUser:$t.trim(),portalPass:tn};try{n?await n(r):await fetch(`/api/onboard`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify(r)}),t?(p(!1),a(6)):e()}catch(e){console.error(`[OnboardWizard] Onboard failed:`,e),p(!1)}},Zr=`w-full bg-white/[0.05] border border-white/[0.08] text-white rounded-xl px-4 py-3 text-base outline-none input-glow placeholder:text-white/20 transition-all`,Qr=`w-full bg-white/[0.03] border border-white/[0.08] text-white rounded-xl px-4 py-2.5 text-[13px] outline-none input-glow placeholder:text-white/20 transition-all`;return(0,G.jsxs)(`div`,{className:`fixed inset-0 z-[200] flex items-center justify-center p-4`,children:[(0,G.jsx)(`div`,{className:`absolute inset-0 bg-black/85 backdrop-blur-md`}),(0,G.jsxs)(sd.div,{initial:{opacity:0,scale:.95},animate:{opacity:1,scale:1},transition:{duration:.3},className:`relative w-full max-w-[480px] max-h-[calc(100dvh_-_2rem)] flex flex-col bg-[#181818] border border-white/[0.06] rounded-[24px] shadow-2xl overflow-hidden`,children:[t?(0,G.jsx)(`div`,{className:`flex justify-center gap-2 pt-6 shrink-0`,children:Array.from({length:7},(e,t)=>(0,G.jsx)(`div`,{className:`h-1.5 rounded-full transition-all duration-300 ${t===i?`w-7 bg-gradient-brand`:t<i?`w-1.5 bg-gradient-brand opacity-60`:`w-1.5 bg-white/10`}`},t))}):(0,G.jsxs)(`div`,{className:`flex items-center justify-between px-5 pt-4 pb-1 shrink-0`,children:[i===0?(0,G.jsx)(`span`,{className:`text-[13px] font-semibold text-white/80 pl-1`,children:`Settings`}):(0,G.jsxs)(`button`,{onClick:()=>a(0),className:`flex items-center gap-1 text-white/50 hover:text-white/80 text-[13px] font-medium pl-1 pr-2 py-1 rounded-lg hover:bg-white/[0.05] transition-colors`,children:[(0,G.jsx)(ee,{className:`h-3.5 w-3.5`}),` Settings`]}),(0,G.jsxs)(`div`,{className:`flex items-center gap-0.5`,children:[i!==0&&(0,G.jsx)(_d,{onJump:e=>a(e)}),(0,G.jsx)(`button`,{onClick:e,className:`text-white/40 hover:text-white/80 p-1.5 rounded-lg hover:bg-white/[0.05] transition-colors`,"aria-label":`Close settings`,children:(0,G.jsx)(Te,{className:`h-4 w-4`})})]})]}),(0,G.jsx)(`div`,{ref:or,className:`flex-1 min-h-0 overflow-y-auto`,children:(0,G.jsx)(_l,{mode:`wait`,children:(0,G.jsxs)(sd.div,{initial:{opacity:0,x:30},animate:{opacity:1,x:0},exit:{opacity:0,x:-30},transition:{duration:.2,ease:`easeOut`},className:`px-8 pt-6 pb-8`,children:[i===0&&t&&(0,G.jsxs)(`div`,{className:`flex flex-col items-center text-center`,children:[(0,G.jsxs)(`video`,{autoPlay:!0,loop:!0,muted:!0,playsInline:!0,className:`h-[180px] mb-4`,children:[(0,G.jsx)(`source`,{src:`/morphy_hi.mov`,type:`video/mp4; codecs="hvc1"`}),(0,G.jsx)(`source`,{src:`/morphy_hi.webm`,type:`video/webm`})]}),(0,G.jsx)(`h1`,{className:`text-2xl font-bold text-white tracking-tight`,children:`Welcome to Bloby`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[14px] mt-2 leading-relaxed max-w-[320px]`,children:`Let's set up your AI assistant in just a few steps.`}),(0,G.jsxs)(`button`,{onClick:Gr,className:`mt-6 px-7 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center gap-2`,children:[`Get Started`,(0,G.jsx)(w,{className:`h-4 w-4`})]})]}),i===0&&!t&&(0,G.jsxs)(`div`,{className:`flex flex-col items-center text-center`,children:[(0,G.jsxs)(`video`,{autoPlay:!0,loop:!0,muted:!0,playsInline:!0,className:`h-[150px] mb-4`,children:[(0,G.jsx)(`source`,{src:`/morphy_hi.mov`,type:`video/mp4; codecs="hvc1"`}),(0,G.jsx)(`source`,{src:`/morphy_hi.webm`,type:`video/webm`})]}),(0,G.jsx)(`h1`,{className:`text-2xl font-bold text-white tracking-tight`,children:`Settings`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[14px] mt-2 leading-relaxed max-w-[320px]`,children:`What would you like to change?`}),(0,G.jsx)(`div`,{className:`w-full mt-5`,children:(0,G.jsx)(hd,{models:gd.map(e=>({id:String(e.step),label:e.label})),value:``,placeholder:`Select a setting…`,menuMaxPx:188,onChange:e=>a(Number(e))})})]}),i===1&&(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`What's your name?`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:`This is how your agent will address you.`}),(0,G.jsxs)(`div`,{className:`mt-5 flex items-center gap-3`,children:[(0,G.jsx)(`input`,{type:`text`,value:o,onChange:e=>s(e.target.value),onKeyDown:qr,placeholder:`Enter your name`,autoFocus:!0,autoComplete:`off`,"data-1p-ignore":!0,"data-lpignore":`true`,className:Zr+` flex-1`}),t&&(0,G.jsx)(`button`,{onClick:Gr,disabled:!Wr,className:`shrink-0 h-12 w-12 flex items-center justify-center rounded-full bg-gradient-brand hover:opacity-90 text-white transition-colors disabled:opacity-30`,children:(0,G.jsx)(w,{className:`h-5 w-5`})})]})]}),i===2&&_t===`off`&&(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`Agent Name & Access`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:`Give your bot a name. This is used throughout the app as your bot's identity.`}),(0,G.jsx)(`div`,{className:`relative mt-5`,children:(0,G.jsx)(`input`,{type:`text`,value:j,onChange:e=>br(e.target.value),maxLength:30,placeholder:`your-bot-name`,spellCheck:!1,autoCapitalize:`none`,autoCorrect:`off`,autoComplete:`off`,"data-1p-ignore":!0,"data-lpignore":`true`,autoFocus:!0,className:Zr+` pr-10 font-mono`})}),(0,G.jsx)(`div`,{className:`mt-4 bg-white/[0.03] border border-white/[0.06] rounded-xl px-4 py-3`,children:(0,G.jsx)(`p`,{className:`text-white/40 text-[12px] leading-relaxed`,children:`Private network mode — your bot is only accessible via your local network or VPN. No public URL will be created.`})}),!t&&(0,G.jsx)(`div`,{className:`mt-3 flex items-center gap-2`,children:(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-medium border ${ud(Rt)?`bg-emerald-500/10 text-emerald-400 border-emerald-500/20`:`bg-blue-500/10 text-blue-400 border-blue-500/20`}`,children:[ud(Rt)?(0,G.jsx)(Ce,{className:`h-3 w-3`}):(0,G.jsx)(D,{className:`h-3 w-3`}),`Accessing via `,dd[Rt]]})}),!t&&!Jt&&(0,G.jsxs)(`button`,{onClick:()=>{Yt(!0),F(``)},className:`w-full mt-4 flex items-center justify-between px-4 py-3 rounded-xl border border-white/[0.06] bg-white/[0.02] hover:border-white/10 hover:bg-white/[0.04] transition-all text-left`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`p`,{className:`text-[13px] text-white/70 font-medium`,children:`Re-enable public tunnel access`}),(0,G.jsx)(`p`,{className:`text-[11px] text-white/30 mt-0.5`,children:`Start a Cloudflare tunnel to make your bot accessible from anywhere`})]}),(0,G.jsx)(D,{className:`h-4 w-4 text-white/30 shrink-0 ml-3`})]}),Jt&&(0,G.jsxs)(`div`,{className:`mt-4 space-y-3`,children:[(0,G.jsx)(`div`,{className:`bg-amber-500/8 border border-amber-500/20 rounded-xl px-4 py-3`,children:(0,G.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,G.jsx)(Se,{className:`h-4 w-4 text-amber-400 shrink-0 mt-0.5`}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`p`,{className:`text-amber-400/90 text-[13px] font-medium`,children:`Enable public access?`}),(0,G.jsxs)(`p`,{className:`text-amber-400/60 text-[12px] mt-1 leading-relaxed`,children:[`This will start a Cloudflare tunnel, making your bot reachable from the internet.`,M&&` Your handle will reconnect automatically.`]})]})]})}),Qt&&(0,G.jsx)(`p`,{className:`text-red-400/70 text-[12px]`,children:Qt}),(0,G.jsxs)(`div`,{className:`flex gap-2`,children:[(0,G.jsx)(`button`,{onClick:async()=>{if(r){Zt(!0),F(``);try{await r(`quick`),vt(`quick`),Yt(!1)}catch(e){F(e.message||`Failed to start tunnel`)}finally{Zt(!1)}}},disabled:Xt||!r,className:`flex-1 py-2.5 bg-gradient-brand hover:opacity-90 text-white text-[13px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40`,children:Xt?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}),`Starting tunnel...`]}):`Enable Tunnel`}),(0,G.jsx)(`button`,{onClick:()=>{Yt(!1),F(``)},disabled:Xt,className:`px-5 py-2.5 bg-white/[0.04] hover:bg-white/[0.08] border border-white/[0.08] text-white/60 text-[13px] font-medium rounded-full transition-colors`,children:`Cancel`})]})]}),t&&(0,G.jsxs)(`button`,{onClick:Gr,disabled:!Wr,className:`w-full mt-5 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40`,children:[`Continue`,(0,G.jsx)(w,{className:`h-4 w-4`})]})]}),i===2&&_t===`named`&&(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`Agent Name & Access`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:`This is your bot's identity. Your named tunnel domain is already configured.`}),(0,G.jsx)(`div`,{className:`relative mt-5`,children:(0,G.jsx)(`input`,{type:`text`,value:j,onChange:e=>br(e.target.value),maxLength:30,placeholder:`your-bot-name`,spellCheck:!1,autoCapitalize:`none`,autoCorrect:`off`,autoComplete:`off`,"data-1p-ignore":!0,"data-lpignore":`true`,autoFocus:!0,className:Zr+` pr-10 font-mono`})}),(0,G.jsxs)(`div`,{className:`mt-4 flex items-center gap-2 bg-white/[0.03] border border-white/[0.06] rounded-xl px-4 py-3`,children:[(0,G.jsxs)(`span`,{className:`font-mono text-[13px] text-white/70 truncate flex-1 text-left`,children:[`https://`,yt]}),(0,G.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(`https://${yt}`),on(!0),setTimeout(()=>on(!1),2e3)},className:`shrink-0 text-white/30 hover:text-white/60 transition-colors`,children:an?(0,G.jsx)(ne,{className:`h-4 w-4 text-emerald-400`}):(0,G.jsx)(re,{className:`h-4 w-4`})})]})]}),i===2&&_t===`quick`&&(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`Agent Name & Access`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:`This is your bot's name and permanent handle — access it from anywhere.`}),M&&ft&&!P&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`div`,{className:`mt-4 bg-emerald-500/8 border border-emerald-500/15 rounded-xl px-4 py-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(ne,{className:`h-4 w-4 text-emerald-400`}),(0,G.jsx)(`p`,{className:`text-emerald-400/90 text-[13px] font-medium`,children:`Current handle`})]}),(0,G.jsx)(`p`,{className:`text-emerald-400/60 text-[12px] mt-1 font-mono`,children:mt})]}),(0,G.jsxs)(`div`,{className:`flex gap-2 mt-4`,children:[t&&(0,G.jsxs)(`button`,{onClick:Gr,className:`flex-1 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2`,children:[`Continue`,(0,G.jsx)(w,{className:`h-4 w-4`})]}),(0,G.jsx)(`button`,{onClick:()=>{Tt(!0),pt(!1),tt(``),rt(null),st({}),wt(`relay`)},className:`px-5 py-3 bg-white/[0.04] hover:bg-white/[0.08] border border-white/[0.08] text-white/60 text-[13px] font-medium rounded-full transition-colors`,children:`Change`})]})]}),P&&!ft&&(0,G.jsxs)(`div`,{className:`mt-4 bg-amber-500/8 border border-amber-500/20 rounded-xl px-4 py-3`,children:[(0,G.jsx)(`p`,{className:`text-amber-400/90 text-[13px] font-medium`,children:`Changing your handle`}),(0,G.jsxs)(`p`,{className:`text-amber-400/60 text-[12px] mt-1`,children:[`Your current handle `,(0,G.jsx)(`span`,{className:`font-mono`,children:M?.url}),` will be released and become available for others.`]})]}),(!M||P||!ft)&&!(M&&ft&&!P)&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`div`,{className:`relative mt-5`,children:[(0,G.jsx)(`input`,{type:`text`,value:j,onChange:e=>br(e.target.value),maxLength:30,placeholder:`your-bot-name`,spellCheck:!1,autoCapitalize:`none`,autoCorrect:`off`,autoComplete:`off`,"data-1p-ignore":!0,"data-lpignore":`true`,autoFocus:!0,disabled:ft,className:Zr+` pr-10 font-mono`+(ft?` opacity-50`:``)}),nt&&j.length>0&&!ft&&(0,G.jsxs)(`div`,{className:`absolute right-4 top-1/2 -translate-y-1/2`,children:[nt===`checking`&&(0,G.jsx)(`div`,{className:`w-5 h-5 border-2 border-white/10 border-t-[#0069FE] rounded-full animate-spin`}),nt===`invalid`&&(0,G.jsx)(`div`,{className:`w-6 h-6 rounded-full bg-amber-500/15 flex items-center justify-center`,children:(0,G.jsx)(`svg`,{className:`w-3.5 h-3.5 text-amber-400`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:3,children:(0,G.jsx)(`path`,{strokeLinecap:`round`,strokeLinejoin:`round`,d:`M12 9v3m0 4h.01`})})})]})]}),nt===`invalid`&&it&&(0,G.jsx)(`p`,{className:`text-amber-400 text-[12px] mt-2`,children:it}),nt===`ready`&&j.length>0&&!ft&&(0,G.jsxs)(`div`,{className:`space-y-3 mt-4`,children:[(()=>{let e=ot.at===!1,t=Ct===`relay`&&ct===`at`;return(0,G.jsxs)(`button`,{onClick:()=>{e||(lt(`at`),wt(`relay`))},disabled:e,className:`w-full rounded-xl border transition-all duration-200 text-left px-4 py-3 ${e?`border-white/[0.04] opacity-50 cursor-not-allowed`:t?`border-[#0069FE]/30 bg-white/[0.04]`:`border-white/[0.06] hover:border-white/10 hover:bg-white/[0.02]`}`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsx)(`span`,{className:`text-[12px] font-semibold text-white/60 uppercase tracking-wider`,children:`Free`}),(0,G.jsx)(`span`,{className:`text-[11px] font-medium px-2.5 py-0.5 rounded-full border ${e?`bg-red-500/10 text-red-400 border-red-500/20`:`bg-emerald-500/10 text-emerald-400 border-emerald-500/20`}`,children:e?`Taken`:`Available`})]}),(0,G.jsxs)(`p`,{className:`font-mono text-[13px] mt-1.5 ${t?`text-white/80`:`text-white/40`}`,children:[`open.bloby.bot/`,j]})]})})(),(()=>{let e=ot.premium,t=e===!1,n=t&&Ot.premium;return(0,G.jsxs)(`div`,{className:`rounded-xl border transition-all duration-200 text-left px-4 py-3 ${n?`border-[#0069FE]/20`:`border-white/[0.06]`}`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`span`,{className:`text-[12px] font-semibold text-white/60 uppercase tracking-wider`,children:`Premium`}),(0,G.jsx)(`span`,{className:`text-[11px] font-medium px-2.5 py-0.5 rounded-full border bg-[#0069FE]/15 text-[#0069FE] border-[#0069FE]/20`,children:`$5`})]}),(0,G.jsx)(`span`,{className:`text-[11px] font-medium px-2.5 py-0.5 rounded-full border ${n?`bg-[#0069FE]/10 text-[#0069FE] border-[#0069FE]/20`:t?`bg-red-500/10 text-red-400 border-red-500/20`:`bg-emerald-500/10 text-emerald-400 border-emerald-500/20`}`,children:n?`Reserved`:t?`Taken`:`Available`})]}),(0,G.jsxs)(`p`,{className:`font-mono text-[13px] mt-1.5 text-white/40`,children:[`bloby.bot/`,j]}),e&&(0,G.jsxs)(`div`,{className:`mt-3 pt-3 border-t border-white/[0.06] flex items-center justify-between`,children:[(0,G.jsx)(`p`,{className:`text-[12px] text-white/40`,children:`Purchase on bloby.bot`}),(0,G.jsx)(`a`,{href:`https://www.bloby.bot/#reserve`,target:`_blank`,rel:`noopener noreferrer`,className:`text-[12px] font-medium text-[#0069FE] hover:text-[#3391FF] transition-colors`,children:`Purchase`})]}),n&&(0,G.jsx)(`div`,{className:`mt-3 pt-3 border-t border-[#0069FE]/10`,children:At?(0,G.jsxs)(`div`,{className:`space-y-2.5`,children:[(0,G.jsxs)(`p`,{className:`text-[12px] text-white/40`,children:[`Enter the 5-character code from your `,(0,G.jsx)(`span`,{className:`text-white/60 font-medium`,children:`bloby.bot`}),` account`]}),(0,G.jsxs)(`div`,{className:`flex gap-2`,children:[(0,G.jsx)(`input`,{type:`text`,value:Mt,onChange:e=>Nt(e.target.value.trim()),maxLength:5,placeholder:`e.g. a3Kx9`,spellCheck:!1,autoComplete:`off`,autoFocus:!0,className:`flex-1 bg-white/[0.05] border border-white/[0.08] text-white rounded-lg px-3 py-2 text-[13px] font-mono outline-none focus:border-[#0069FE]/30 transition-colors placeholder:text-white/20 tracking-widest text-center`}),(0,G.jsx)(`button`,{onClick:Cr,disabled:It||Mt.length<5,className:`px-4 py-2 bg-gradient-brand hover:opacity-90 text-white text-[13px] font-semibold rounded-lg transition-colors flex items-center gap-1.5 disabled:opacity-40`,children:It?(0,G.jsx)(O,{className:`h-3.5 w-3.5 animate-spin`}):`Activate`})]}),Pt&&(0,G.jsx)(`p`,{className:`text-red-400 text-[12px]`,children:Pt}),(0,G.jsx)(`button`,{onClick:()=>{jt(!1),Nt(``),Ft(``)},className:`text-[11px] text-white/25 hover:text-white/40 transition-colors`,children:`Cancel`})]}):(0,G.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,G.jsx)(`p`,{className:`text-[12px] text-white/40`,children:`Is that yours?`}),(0,G.jsx)(`button`,{onClick:()=>{jt(!0),Nt(``),Ft(``)},className:`text-[12px] font-medium text-[#0069FE] hover:text-[#3391FF] transition-colors`,children:`Activate`})]})})]})})(),(0,G.jsxs)(`button`,{onClick:()=>{wt(`tunnel`),lt(`skip`)},className:`w-full rounded-xl border transition-all duration-200 text-left px-4 py-3 ${ct===`skip`?`border-[#0069FE]/30 bg-white/[0.04]`:`border-white/[0.06] hover:border-white/10 hover:bg-white/[0.02]`}`,children:[(0,G.jsx)(`span`,{className:`text-[12px] font-semibold text-white/60 uppercase tracking-wider`,children:`No handle`}),(0,G.jsx)(`p`,{className:`text-[13px] mt-1.5 ${ct===`skip`?`text-white/60`:`text-white/30`}`,children:`I'll use the random tunnel URL`})]})]}),ft&&(0,G.jsxs)(`div`,{className:`mt-4 bg-emerald-500/8 border border-emerald-500/15 rounded-xl px-4 py-3`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(ne,{className:`h-4 w-4 text-emerald-400`}),(0,G.jsx)(`p`,{className:`text-emerald-400/90 text-[13px] font-medium`,children:`Handle claimed!`})]}),(0,G.jsx)(`p`,{className:`text-emerald-400/60 text-[12px] mt-1 font-mono`,children:mt})]}),nt===`ready`&&j.length>0&&!ft&&(0,G.jsx)(`button`,{onClick:ct===`skip`?Gr:Ct===`relay`&&ct===`at`?P?Sr:xr:void 0,disabled:!ct||ut||Et||ct===`at`&&!ot.at,className:`w-full mt-4 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40 disabled:cursor-not-allowed`,children:ut||Et?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}),P?`Changing...`:`Claiming...`]}):ct?ct===`skip`?(0,G.jsxs)(G.Fragment,{children:[`Continue`,(0,G.jsx)(w,{className:`h-4 w-4`})]}):(0,G.jsxs)(G.Fragment,{children:[P?`Change Handle`:`Claim & Continue`,(0,G.jsx)(w,{className:`h-4 w-4`})]}):(0,G.jsx)(G.Fragment,{children:`Select an option to continue`})}),t&&ft&&(0,G.jsxs)(`button`,{onClick:Gr,className:`w-full mt-4 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2`,children:[`Continue`,(0,G.jsx)(w,{className:`h-4 w-4`})]}),P&&!ft&&(0,G.jsx)(`button`,{onClick:()=>{Tt(!1),tt(M.username),pt(!0),ht(M.url),lt(M.tier),wt(`relay`),rt(null)},className:`w-full mt-2 py-2 text-white/25 hover:text-white/40 text-[12px] transition-colors`,children:`Cancel — keep current handle`})]}),!t&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`div`,{className:`mt-5 flex items-center gap-2`,children:(0,G.jsxs)(`span`,{className:`inline-flex items-center gap-1.5 px-2.5 py-1 rounded-full text-[11px] font-medium border ${ud(Rt)?`bg-emerald-500/10 text-emerald-400 border-emerald-500/20`:`bg-blue-500/10 text-blue-400 border-blue-500/20`}`,children:[ud(Rt)?(0,G.jsx)(we,{className:`h-3 w-3`}):(0,G.jsx)(D,{className:`h-3 w-3`}),`Accessing via `,dd[Rt]]})}),!Bt&&(0,G.jsxs)(`button`,{onClick:()=>{ud(Rt)&&(Vt(!0),Ut(``),qt(``))},disabled:!ud(Rt),className:`w-full mt-3 flex items-center justify-between px-4 py-3 rounded-xl border transition-all text-left ${ud(Rt)?`border-white/[0.06] bg-white/[0.02] hover:border-white/10 hover:bg-white/[0.04] cursor-pointer`:`border-white/[0.04] bg-transparent opacity-50 cursor-not-allowed`}`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`p`,{className:`text-[13px] text-white/70 font-medium`,children:`Switch to private network only`}),(0,G.jsx)(`p`,{className:`text-[11px] text-white/30 mt-0.5`,children:ud(Rt)?`Stop the tunnel and relay — access only via Tailscale or LAN`:`Connect via Tailscale or private network to unlock`})]}),(0,G.jsx)(Ce,{className:`h-4 w-4 text-white/30 shrink-0 ml-3`})]}),Bt&&(0,G.jsxs)(`div`,{className:`mt-3 space-y-3`,children:[(0,G.jsx)(`div`,{className:`bg-amber-500/8 border border-amber-500/20 rounded-xl px-4 py-3`,children:(0,G.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,G.jsx)(Se,{className:`h-4 w-4 text-amber-400 shrink-0 mt-0.5`}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`p`,{className:`text-amber-400/90 text-[13px] font-medium`,children:`Switch to private network only?`}),(0,G.jsx)(`p`,{className:`text-amber-400/60 text-[12px] mt-1 leading-relaxed`,children:`This will stop the Cloudflare tunnel and relay connection. Your bot will only be accessible via your private network.`}),M&&(0,G.jsx)(`p`,{className:`text-amber-400/50 text-[12px] mt-1.5`,children:`Your handle will be preserved and can be re-activated later.`})]})]})}),(0,G.jsxs)(`div`,{children:[(0,G.jsxs)(`label`,{className:`text-[12px] text-white/40 font-medium mb-1.5 block`,children:[`Type `,(0,G.jsx)(`span`,{className:`font-mono text-white/60`,children:`I confirm`}),` to proceed`]}),(0,G.jsx)(`input`,{type:`text`,value:Ht,onChange:e=>Ut(e.target.value),placeholder:`I confirm`,spellCheck:!1,autoFocus:!0,className:Qr})]}),Kt&&(0,G.jsx)(`p`,{className:`text-red-400/70 text-[12px]`,children:Kt}),(0,G.jsxs)(`div`,{className:`flex gap-2`,children:[(0,G.jsx)(`button`,{onClick:async()=>{if(!(!r||Ht.trim().toLowerCase()!==`i confirm`)){Gt(!0),qt(``);try{await r(`off`),vt(`off`),Vt(!1)}catch(e){qt(e.message||`Failed to switch`)}finally{Gt(!1)}}},disabled:Wt||Ht.trim().toLowerCase()!==`i confirm`||!r,className:`flex-1 py-2.5 bg-amber-600 hover:bg-amber-500 text-white text-[13px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40`,children:Wt?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}),`Switching...`]}):`Confirm Switch`}),(0,G.jsx)(`button`,{onClick:()=>{Vt(!1),Ut(``),qt(``)},disabled:Wt,className:`px-5 py-2.5 bg-white/[0.04] hover:bg-white/[0.08] border border-white/[0.08] text-white/60 text-[13px] font-medium rounded-full transition-colors`,children:`Cancel`})]})]})]})]}),i===3&&(0,G.jsx)(`div`,{children:(0,G.jsxs)(_l,{mode:`wait`,children:[$n===`password`&&(0,G.jsxs)(sd.div,{initial:{opacity:0,x:-20},animate:{opacity:1,x:0},exit:{opacity:0,x:-20},transition:{duration:.15},children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:sn?`Password & 2FA`:`Set a password`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:sn?`Your Bloby Chat password is already set — you can keep it as-is or change it below.`:`You'll need this password to access your Bloby Chat. Keep it safe — anyone with your URL will need it to log in.`}),sn&&!xn&&(0,G.jsxs)(`div`,{className:`mt-5 flex items-center justify-between bg-white/[0.02] border border-white/[0.06] rounded-xl px-4 py-3`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`p`,{className:`text-white/70 text-[13px] font-medium`,children:`Bloby Chat Password`}),(0,G.jsx)(`p`,{className:`text-white/30 text-[11px] mt-0.5`,children:`Already configured.`})]}),(0,G.jsx)(`button`,{type:`button`,onClick:()=>{Sn(!0),mn(``),gn(``),vn(!1),nn(``),rn(``)},className:`shrink-0 px-3.5 py-2 bg-white/[0.04] hover:bg-white/[0.08] text-white/70 hover:text-white text-[12px] font-medium rounded-lg transition-colors`,children:`Change password`})]}),sn&&xn&&(0,G.jsxs)(`div`,{className:`mt-5`,children:[(0,G.jsxs)(`div`,{className:`flex items-center justify-between mb-1.5`,children:[(0,G.jsx)(`label`,{className:`text-[12px] text-white/40 font-medium`,children:`Current password`}),(0,G.jsx)(`button`,{type:`button`,onClick:()=>{Sn(!1),mn(``),gn(``),vn(!1),nn(``),rn(``)},className:`text-white/30 hover:text-white/60 text-[11px] transition-colors`,children:`Cancel`})]}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`input`,{type:`password`,value:pn,onChange:e=>{mn(e.target.value),gn(``),vn(!1)},placeholder:`Enter your current password`,autoComplete:`current-password`,className:Zr+` flex-1`}),pn.length>0&&!_n&&(0,G.jsx)(`button`,{onClick:async()=>{bn(!0),gn(``);try{(await(await fetch(`/api/portal/verify-password`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({password:pn})})).json()).valid?vn(!0):gn(`Incorrect password`)}catch{gn(`Could not verify`)}finally{bn(!1)}},disabled:yn,className:`shrink-0 px-4 py-3 bg-white/[0.06] hover:bg-white/[0.1] text-white/60 text-[13px] font-medium rounded-xl transition-colors disabled:opacity-40`,children:yn?(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}):`Verify`}),_n&&(0,G.jsx)(`div`,{className:`shrink-0 w-10 h-10 flex items-center justify-center`,children:(0,G.jsx)(ne,{className:`h-4 w-4 text-emerald-400`})})]}),hn&&(0,G.jsx)(`p`,{className:`text-red-400/70 text-[11px] mt-1`,children:hn})]}),(!sn||xn&&_n)&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`div`,{className:sn?`mt-3`:`mt-5`,children:[(0,G.jsx)(`label`,{className:`text-[12px] text-white/40 font-medium mb-1.5 block`,children:sn?`New password`:`Password`}),(0,G.jsx)(`input`,{type:`password`,value:tn,onChange:e=>nn(e.target.value),placeholder:`••••••••`,autoComplete:`new-password`,autoFocus:!sn,onKeyDown:qr,className:Zr}),tn.length>0&&tn.length<6&&(0,G.jsx)(`p`,{className:`text-amber-400/70 text-[11px] mt-1`,children:`At least 6 characters`})]}),(0,G.jsxs)(`div`,{className:`mt-3`,children:[(0,G.jsx)(`label`,{className:`text-[12px] text-white/40 font-medium mb-1.5 block`,children:sn?`Confirm new password`:`Confirm password`}),(0,G.jsx)(`input`,{type:`password`,value:I,onChange:e=>rn(e.target.value),placeholder:`••••••••`,autoComplete:`new-password`,onKeyDown:qr,className:Zr}),I.length>0&&!Vr&&(0,G.jsx)(`p`,{className:`text-red-400/70 text-[11px] mt-1`,children:`Passwords don't match`})]})]}),(0,G.jsxs)(`div`,{className:`mt-5 border border-white/[0.06] rounded-xl overflow-hidden`,children:[(0,G.jsxs)(`button`,{onClick:async()=>{if(En&&In){Kn(!0);return}if(En)Dn(!1),jn(``),kn(``),Nn(``);else{if(Dn(!0),Vn(``),Fn(``),sn&&!_n){Sn(!0),Vn(`Enter your current portal password above first, then toggle 2FA again.`),Dn(!1);return}if(An)er(`totp-setup`);else try{let e=await fetch(`/api/portal/totp/setup`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({password:sn?pn:tn})}),t=await e.json();e.ok?(kn(t.secret),jn(t.qrDataUri),Nn(t.otpauthUri),er(`totp-setup`)):(Vn(t.error||`Setup failed`),Dn(!1))}catch{Vn(`Could not reach server`),Dn(!1)}}},type:`button`,className:`w-full flex items-center gap-3 px-4 py-3 text-left`,children:[(0,G.jsx)(`div`,{className:`w-9 h-9 rounded-lg flex items-center justify-center shrink-0 ${En&&In?`bg-emerald-500/10`:`bg-white/[0.04]`}`,children:En&&In?(0,G.jsx)(ve,{className:`h-[18px] w-[18px] text-emerald-400`}):(0,G.jsx)(ye,{className:`h-[18px] w-[18px] text-white/30`})}),(0,G.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,G.jsx)(`span`,{className:`text-[13px] font-medium text-white block`,children:`Two-Factor Auth`}),(0,G.jsx)(`p`,{className:`text-[11px] text-white/30 mt-0.5`,children:En&&In?(0,G.jsx)(`span`,{className:`text-emerald-400/70`,children:`Active — authenticator app required`}):_t===`quick`||_t===`named`?(0,G.jsx)(`span`,{children:`Recommended for public bots`}):(0,G.jsx)(`span`,{children:`Extra security with an authenticator app`})})]}),(0,G.jsx)(`div`,{className:`w-10 h-6 rounded-full transition-colors relative shrink-0 ${En?`bg-emerald-500`:`bg-white/10`}`,children:(0,G.jsx)(`div`,{className:`absolute top-1 w-4 h-4 rounded-full bg-white shadow transition-transform ${En?`translate-x-5`:`translate-x-1`}`})})]}),Gn&&(0,G.jsxs)(`div`,{className:`px-4 pb-3 border-t border-white/[0.06]`,children:[(0,G.jsx)(`p`,{className:`text-[12px] text-white/40 mt-3 mb-2`,children:`Enter your current TOTP code to disable 2FA:`}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`input`,{type:`text`,inputMode:`numeric`,autoComplete:`one-time-code`,maxLength:6,value:qn,onChange:e=>{Jn(e.target.value.replace(/\D/g,``)),Xn(``)},placeholder:`000000`,className:Qr+` flex-1 tracking-[0.3em] text-center font-mono`}),(0,G.jsx)(`button`,{onClick:async()=>{if(qn.length===6)try{let e=await fetch(`/api/portal/totp/disable`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({password:sn?pn:tn,code:qn})}),t=await e.json();e.ok?(Dn(!1),Ln(!1),kn(``),jn(``),Nn(``),Kn(!1),Jn(``),Hn([]),Wn(!1)):Xn(t.error||`Failed to disable`)}catch{Xn(`Could not reach server`)}},disabled:qn.length!==6,className:`shrink-0 px-4 py-2.5 bg-red-500/10 hover:bg-red-500/20 text-red-400 text-[13px] font-medium rounded-xl transition-colors disabled:opacity-40`,children:`Disable`})]}),Yn&&(0,G.jsx)(`p`,{className:`text-red-400/70 text-[11px] mt-1`,children:Yn}),(0,G.jsx)(`button`,{onClick:()=>{Kn(!1),Jn(``),Xn(``)},className:`text-[11px] text-white/30 hover:text-white/50 mt-2`,children:`Cancel`})]}),Bn&&$n===`password`&&(0,G.jsx)(`div`,{className:`mx-4 mb-3 bg-red-500/8 border border-red-500/15 rounded-xl px-3 py-2`,children:(0,G.jsx)(`p`,{className:`text-red-400/90 text-[11px]`,children:Bn})})]}),t&&(0,G.jsxs)(`button`,{onClick:Gr,disabled:!Wr,className:`w-full mt-5 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40`,children:[`Continue`,(0,G.jsx)(w,{className:`h-4 w-4`})]})]},`password`),$n===`totp-setup`&&(0,G.jsxs)(sd.div,{initial:{opacity:0,x:20},animate:{opacity:1,x:0},exit:{opacity:0,x:20},transition:{duration:.15},children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-3 mb-1`,children:[(0,G.jsx)(`button`,{onClick:()=>{Dn(!1),jn(``),kn(``),Nn(``),Fn(``),Vn(``),er(`password`),yr()},className:`w-7 h-7 rounded-full bg-white/[0.04] flex items-center justify-center text-white/40 hover:text-white/70 transition-colors shrink-0`,children:(0,G.jsx)(ee,{className:`h-4 w-4`})}),(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`Set up 2FA`})]}),Bn&&(0,G.jsx)(`div`,{className:`mt-3 bg-red-500/8 border border-red-500/15 rounded-xl px-3 py-2`,children:(0,G.jsx)(`p`,{className:`text-red-400/90 text-[11px]`,children:Bn})}),An&&(0,G.jsxs)(G.Fragment,{children:[Zn?(0,G.jsxs)(`div`,{className:`mt-4`,children:[(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] leading-relaxed mb-4`,children:`Add Bloby to your authenticator app, then enter the 6-digit code below to confirm.`}),(0,G.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(On),nr(!0),setTimeout(()=>nr(!1),3e3)},className:`w-full py-3 text-[14px] font-medium rounded-xl transition-colors flex items-center justify-center gap-2 ${tr?`bg-emerald-500/10 text-emerald-400 border border-emerald-500/20`:`bg-white/[0.05] text-white/70 hover:bg-white/[0.08] border border-white/[0.08]`}`,children:tr?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(ne,{className:`h-4 w-4`}),`Secret key copied`]}):(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(ae,{className:`h-4 w-4`}),`Copy secret key`]})}),(0,G.jsx)(`p`,{className:`text-[11px] text-white/20 text-center mt-2`,children:`Paste it in your authenticator app → Add account → Enter key`}),(0,G.jsxs)(`a`,{href:Mn,onClick:()=>_r(),className:`w-full mt-3 py-2.5 text-[13px] text-white/30 hover:text-white/50 flex items-center justify-center gap-1.5 transition-colors`,children:[(0,G.jsx)(be,{className:`h-3.5 w-3.5`}),`Or open directly in authenticator`]})]}):(0,G.jsxs)(`div`,{className:`mt-4 flex gap-4 items-start`,children:[(0,G.jsx)(`div`,{className:`shrink-0`,children:(0,G.jsx)(`div`,{className:`bg-white rounded-xl p-1.5`,children:(0,G.jsx)(`img`,{src:An,alt:`TOTP QR Code`,className:`w-[140px] h-[140px]`})})}),(0,G.jsxs)(`div`,{className:`flex-1 min-w-0 pt-1`,children:[(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] leading-relaxed`,children:`Scan this QR code with your authenticator app.`}),(0,G.jsx)(`p`,{className:`text-white/25 text-[11px] mt-2 leading-relaxed`,children:`Google Authenticator, Authy, 1Password, or any TOTP app.`}),(0,G.jsxs)(`button`,{onClick:()=>{navigator.clipboard.writeText(On)},className:`mt-3 text-[11px] text-white/25 hover:text-white/40 flex items-center gap-1 transition-colors`,children:[(0,G.jsx)(ae,{className:`h-3 w-3`}),`Copy secret key`]})]})]}),(0,G.jsxs)(`div`,{className:`mt-5`,children:[(0,G.jsx)(`label`,{className:`text-[12px] text-white/40 font-medium mb-1.5 block`,children:`Enter the 6-digit code from your app`}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,G.jsx)(`input`,{type:`text`,inputMode:`numeric`,autoComplete:`one-time-code`,maxLength:6,value:Pn,onChange:e=>{Fn(e.target.value.replace(/\D/g,``)),Vn(``)},placeholder:`000000`,autoFocus:!0,className:Zr+` tracking-[0.3em] text-center font-mono flex-1`}),(0,G.jsx)(`button`,{onClick:async()=>{if(Pn.length===6){zn(!0),Vn(``);try{let e=await fetch(`/api/portal/totp/verify-setup`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({code:Pn,password:sn?pn:tn})}),t=await e.json();e.ok&&t.success?(Ln(!0),Hn(t.recoveryCodes||[]),er(`recovery`),yr()):Vn(t.error||`Verification failed`)}catch{Vn(`Could not reach server`)}finally{zn(!1)}}},disabled:Pn.length!==6||Rn,className:`shrink-0 px-5 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-xl transition-colors flex items-center gap-2 disabled:opacity-40`,children:Rn?(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}):`Verify`})]})]})]})]},`totp-setup`),$n===`recovery`&&(0,G.jsxs)(sd.div,{initial:{opacity:0,x:20},animate:{opacity:1,x:0},exit:{opacity:0,x:20},transition:{duration:.15},children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-3 mb-1`,children:[(0,G.jsx)(`div`,{className:`w-9 h-9 rounded-xl bg-emerald-500/10 flex items-center justify-center shrink-0`,children:(0,G.jsx)(ve,{className:`h-[18px] w-[18px] text-emerald-400`})}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`2FA enabled`}),(0,G.jsx)(`p`,{className:`text-emerald-400/70 text-[12px]`,children:`Save your recovery codes`})]})]}),(0,G.jsx)(`p`,{className:`text-white/35 text-[13px] mt-3 leading-relaxed`,children:`If you lose your authenticator app, you can use one of these codes to sign in. Each code works once. Store them somewhere safe.`}),(0,G.jsx)(`div`,{className:`mt-4 grid grid-cols-2 gap-1.5`,children:R.map((e,t)=>(0,G.jsx)(`div`,{className:`bg-white/[0.03] border border-white/[0.06] rounded-lg px-3 py-2 text-center`,children:(0,G.jsx)(`code`,{className:`text-[13px] text-white/60 font-mono tracking-wider`,children:e})},t))}),(0,G.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(R.join(`
26
26
  `)),Wn(!0)},className:`w-full mt-4 py-3 text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 ${Un?`bg-emerald-500/10 text-emerald-400 border border-emerald-500/20`:`bg-white/[0.05] text-white/60 hover:bg-white/[0.08] border border-white/[0.08]`}`,children:Un?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(ne,{className:`h-4 w-4`}),`Copied`]}):(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(ae,{className:`h-4 w-4`}),`Copy recovery codes`]})}),(0,G.jsxs)(`button`,{onClick:()=>{Hn([]),er(`password`),yr()},disabled:!Un,className:`w-full mt-3 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40`,children:[`Done`,(0,G.jsx)(w,{className:`h-4 w-4`})]})]},`recovery`)]})}),i===4&&(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight`,children:`Choose your AI provider`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1.5 leading-relaxed`,children:`Pick one provider to power your bot, authenticate, and select a model.`}),(0,G.jsx)(`div`,{className:`flex gap-2.5 mt-4`,children:pd.map(e=>(0,G.jsxs)(`button`,{onClick:()=>wr(e.id),className:`flex-1 relative rounded-xl border transition-all duration-200 p-3 text-left ${c===e.id?`bg-white/[0.04] border-[#0069FE]/40`:`bg-transparent border-white/[0.06] hover:border-white/10 hover:bg-white/[0.02]`}`,children:[(0,G.jsxs)(`div`,{className:`flex flex-col items-center gap-1.5 py-0.5`,children:[(()=>{let t=e.iconHeight??fd;return(0,G.jsx)(`div`,{className:`flex items-center justify-center`,style:{height:`${Math.max(fd,t)}px`},children:e.icon?(0,G.jsx)(`img`,{src:e.icon,alt:e.name,className:`w-auto object-contain`,style:{height:`${t}px`}}):(0,G.jsx)(`div`,{className:`rounded-lg bg-white/[0.06] flex items-center justify-center text-white/50 text-sm font-bold`,style:{height:`${t}px`,width:`${t}px`}})})})(),(0,G.jsxs)(`div`,{className:`text-center`,children:[(0,G.jsx)(`div`,{className:`text-[13px] font-medium text-white`,children:e.name}),(0,G.jsx)(`div`,{className:`text-[10px] text-white/30 whitespace-pre-line leading-tight`,children:e.subtitle})]})]}),m[e.id]===`connected`?(0,G.jsx)(`div`,{className:`absolute top-2 right-2 w-4 h-4 rounded-full bg-emerald-500/15 flex items-center justify-center`,children:(0,G.jsx)(ne,{className:`h-2.5 w-2.5 text-emerald-400`})}):c===e.id?(0,G.jsx)(`div`,{className:`absolute top-2 right-2 w-2 h-2 rounded-full bg-gradient-brand`}):null]},e.id))}),(0,G.jsx)(`div`,{className:`border-t border-white/[0.06] mt-4 mb-3`}),c===`pi`&&(0,G.jsx)(`div`,{className:`space-y-2`,children:m.pi===`connected`&&me?(0,G.jsxs)(`div`,{className:`flex items-center justify-between bg-emerald-500/8 border border-emerald-500/15 rounded-lg px-3 py-2`,children:[(0,G.jsxs)(`p`,{className:`text-emerald-400/90 text-[12px] truncate`,children:[`Connected — `,g.find(e=>e.id===me.subProvider)?.name||me.subProvider,me.modelId?(0,G.jsxs)(G.Fragment,{children:[` · `,(0,G.jsx)(`span`,{className:`font-mono`,children:me.modelId})]}):null]}),(0,G.jsxs)(`button`,{onClick:Or,className:`text-white/30 hover:text-white/60 text-[11px] flex items-center gap-1 shrink-0 ml-2`,children:[(0,G.jsx)(ge,{className:`h-3 w-3`}),`Change`]})]}):(0,G.jsxs)(G.Fragment,{children:[(0,G.jsxs)(`div`,{className:`grid grid-cols-2 gap-2`,children:[(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`label`,{className:`text-[11px] text-white/40 font-medium mb-1 block`,children:`Provider`}),(0,G.jsx)(hd,{models:g.map(e=>({id:e.id,label:e.name})),value:y,onChange:Er})]}),(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`label`,{className:`text-[11px] text-white/40 font-medium mb-1 block`,children:`Model`}),Tr&&Array.isArray(Tr.models)?(0,G.jsx)(hd,{models:Tr.models,value:T,onChange:ie}):(0,G.jsx)(`input`,{type:`text`,value:T,onChange:e=>ie(e.target.value),placeholder:Tr?.defaultModel||`model-id`,className:Qr+` font-mono`})]})]}),Tr?.needsBaseUrl&&(0,G.jsx)(`input`,{type:`text`,value:C,onChange:e=>te(e.target.value),placeholder:Tr.baseUrl||`https://example.com/v1`,className:Qr+` font-mono`}),Tr?.needsApiKey&&(0,G.jsxs)(`div`,{className:`relative`,children:[(0,G.jsx)(`input`,{type:oe?`text`:`password`,value:x,onChange:e=>S(e.target.value),onKeyDown:e=>e.key===`Enter`&&Dr(),placeholder:`API key…`,className:Qr+` pr-16 font-mono`}),(0,G.jsxs)(`div`,{className:`absolute right-2 top-1/2 -translate-y-1/2 flex items-center gap-1.5`,children:[Tr.apiKeyUrl&&(0,G.jsx)(`button`,{type:`button`,onClick:()=>kr(Tr.apiKeyUrl),className:`text-white/25 hover:text-white/55 transition-colors`,title:`Get a key`,children:(0,G.jsx)(se,{className:`h-3.5 w-3.5`})}),(0,G.jsx)(`button`,{type:`button`,onClick:()=>E(e=>!e),className:`text-white/25 hover:text-white/55 transition-colors`,children:oe?(0,G.jsx)(ce,{className:`h-3.5 w-3.5`}):(0,G.jsx)(le,{className:`h-3.5 w-3.5`})})]})]}),pe&&(0,G.jsx)(`div`,{className:`bg-red-500/8 border border-red-500/15 rounded-lg px-3 py-2`,children:(0,G.jsx)(`p`,{className:`text-[12px] text-red-400/90 break-words`,children:pe})}),(0,G.jsx)(`button`,{onClick:Dr,disabled:ue||!y||!!Tr?.needsApiKey&&!x.trim()||!!Tr?.needsBaseUrl&&!C.trim()||!T.trim(),className:`w-full py-2.5 px-4 bg-gradient-brand hover:opacity-90 text-white text-[13px] font-medium rounded-xl transition-colors flex items-center justify-center gap-2 disabled:opacity-40`,children:ue?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(O,{className:`h-3.5 w-3.5 animate-spin`}),`Connecting…`]}):(0,G.jsxs)(G.Fragment,{children:[`Test & connect`,(0,G.jsx)(w,{className:`h-3.5 w-3.5 opacity-60`})]})})]})}),c===`bloby`&&(0,G.jsxs)(`div`,{className:`space-y-3`,children:[(0,G.jsx)(`p`,{className:`text-[12px] text-white/40 leading-relaxed`,children:`Bloby (managed) is on the way. Sign in with Google once it ships and your bot will be hosted, updated, and billed by us — no API keys to manage.`}),(0,G.jsxs)(`button`,{type:`button`,disabled:!0,title:`Coming soon`,className:`w-full py-2.5 px-4 bg-white/[0.04] border border-white/[0.06] text-white/35 text-[13px] font-medium rounded-xl flex items-center justify-center gap-2 cursor-not-allowed`,children:[(0,G.jsx)(`svg`,{viewBox:`0 0 24 24`,className:`h-4 w-4 opacity-50`,fill:`currentColor`,children:(0,G.jsx)(`path`,{d:`M21.35 11.1h-9.17v2.96h5.27c-.23 1.39-1.62 4.08-5.27 4.08-3.17 0-5.76-2.62-5.76-5.85s2.59-5.85 5.76-5.85c1.81 0 3.02.77 3.71 1.43l2.53-2.43C16.85 3.91 14.74 3 12.18 3 7.03 3 2.86 7.17 2.86 12.29s4.17 9.29 9.32 9.29c5.38 0 8.94-3.79 8.94-9.12 0-.61-.07-1.08-.17-1.55Z`})}),`Login with Google`]}),(0,G.jsx)(`p`,{className:`text-[10.5px] text-white/25 text-center`,children:`Not available yet.`})]}),c===`anthropic`&&(0,G.jsxs)(`div`,{className:`space-y-2.5`,children:[(0,G.jsxs)(`div`,{className:`rounded-xl border border-amber-500/20 bg-amber-500/[0.06] px-4 py-3.5`,children:[(0,G.jsxs)(`div`,{className:`flex items-center gap-2 mb-2`,children:[(0,G.jsx)(Se,{className:`h-4 w-4 text-amber-400 shrink-0`}),(0,G.jsx)(`h3`,{className:`text-[12.5px] font-semibold text-amber-200/90`,children:`Anthropic Third-Party App Policy Update`})]}),(0,G.jsxs)(`div`,{className:`space-y-2 text-amber-100/70 text-[12px] leading-relaxed`,children:[(0,G.jsx)(`p`,{children:`Starting June 15, 2026, Anthropic will provide a separate Third-Party App credit equal to the amount you pay for your subscription.`}),(0,G.jsx)(`p`,{children:`For example, if you have the Max 5x plan at $100/month, you will receive $100 in credits to use with third-party tools like Bloby.`}),(0,G.jsx)(`p`,{children:`Unfortunately, this is only a fraction of the usage Bloby users had before. We don't control Anthropic's rules, but we do need to follow them.`}),(0,G.jsxs)(`p`,{children:[`The best alternative right now is a `,(0,G.jsx)(`span`,{className:`font-medium text-amber-100/90`,children:`ChatGPT subscription`}),`, which also offers $100 and $200 plans with much higher usage limits for Bloby.`]}),(0,G.jsx)(`p`,{children:`In the short term, Bloby will be optimized for ChatGPT. In the long term, we are building our own model harness so Bloby has more control, more flexibility, and does not depend too heavily on providers that can change their rules at any moment.`})]})]}),hr&&(0,G.jsxs)(`div`,{className:`space-y-2.5`,children:[(0,G.jsx)(`div`,{className:`bg-emerald-500/8 border border-emerald-500/15 rounded-lg px-3.5 py-2.5`,children:(0,G.jsx)(`p`,{className:`text-emerald-400/90 text-[12px]`,children:`Connected — Anthropic subscription is active.`})}),(0,G.jsxs)(`button`,{onClick:()=>{h(e=>({...e,anthropic:`idle`})),xe(!1),De(``),je(``)},className:`w-full py-1.5 text-white/25 text-[11px] hover:text-white/40 transition-colors flex items-center justify-center gap-1.5`,children:[(0,G.jsx)(ge,{className:`h-3 w-3`}),`Re-authenticate`]})]}),!hr&&(0,G.jsxs)(G.Fragment,{children:[Ae&&(0,G.jsx)(`div`,{className:`bg-red-500/8 border border-red-500/15 rounded-lg px-3.5 py-2.5`,children:(0,G.jsx)(`p`,{className:`text-red-400/90 text-[12px]`,children:Ae})}),(0,G.jsx)(`div`,{className:`space-y-1.5`,children:[`Click the button below to open Anthropic's login page`,`Sign in with your Anthropic account — a code will be generated`,`Copy the code and paste it in the field below`].map((e,t)=>(0,G.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,G.jsx)(`span`,{className:`flex-shrink-0 w-[18px] h-[18px] rounded-full bg-white/[0.06] text-white/30 text-[10px] font-medium flex items-center justify-center mt-px`,children:t+1}),(0,G.jsx)(`p`,{className:`text-white/40 text-[12px] leading-relaxed`,children:e})]},t))}),(0,G.jsx)(`button`,{onClick:Ar,className:`w-full py-2.5 px-4 bg-gradient-brand hover:opacity-90 text-white text-[13px] font-medium rounded-xl transition-colors flex items-center justify-center gap-2`,children:_e?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(se,{className:`h-3.5 w-3.5 opacity-60`}),`Open authentication page again`]}):(0,G.jsxs)(G.Fragment,{children:[`Authenticate with Anthropic`,(0,G.jsx)(w,{className:`h-3.5 w-3.5 opacity-60`})]})}),(0,G.jsxs)(`div`,{className:`relative`,children:[(0,G.jsx)(`input`,{type:`text`,value:Ee,onChange:e=>De(e.target.value),onKeyDown:e=>e.key===`Enter`&&jr(),placeholder:`Paste your code here...`,className:Qr+` pr-10 font-mono`}),(0,G.jsx)(`button`,{onClick:Mr,className:`absolute right-3 top-1/2 -translate-y-1/2 text-white/20 hover:text-white/50 transition-colors`,children:(0,G.jsx)(re,{className:`h-3.5 w-3.5`})})]}),(0,G.jsx)(`button`,{onClick:jr,disabled:!Ee.trim()||Oe,className:`w-full py-2.5 px-4 bg-gradient-brand hover:opacity-90 text-white text-[13px] font-medium rounded-xl transition-colors flex items-center justify-center gap-2 disabled:opacity-40`,children:Oe?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(O,{className:`h-3.5 w-3.5 animate-spin`}),`Verifying...`]}):`Connect`}),(0,G.jsxs)(`button`,{onClick:Nr,disabled:Me,className:`w-full py-1.5 text-white/25 text-[11px] hover:text-white/40 transition-colors flex items-center justify-center gap-1.5 disabled:opacity-50`,children:[Me?(0,G.jsx)(O,{className:`h-3 w-3 animate-spin`}):(0,G.jsx)(ge,{className:`h-3 w-3`}),Me?`Checking...`:`I'm already authenticated`]})]})]}),c===`openai`&&(0,G.jsxs)(`div`,{className:`space-y-2.5`,children:[hr&&(0,G.jsxs)(`div`,{className:`space-y-2.5`,children:[(0,G.jsx)(`div`,{className:`bg-emerald-500/8 border border-emerald-500/15 rounded-lg px-3.5 py-2.5`,children:(0,G.jsx)(`p`,{className:`text-emerald-400/90 text-[12px]`,children:`Connected — ChatGPT subscription is active.`})}),(0,G.jsxs)(`button`,{onClick:()=>{h(e=>({...e,openai:`idle`})),Qe(``)},className:`w-full py-1.5 text-white/25 text-[11px] hover:text-white/40 transition-colors flex items-center justify-center gap-1.5`,children:[(0,G.jsx)(ge,{className:`h-3 w-3`}),`Re-authenticate`]})]}),!hr&&(0,G.jsxs)(G.Fragment,{children:[Ze&&(0,G.jsx)(`div`,{className:`bg-red-500/8 border border-red-500/15 rounded-lg px-3.5 py-2.5`,children:(0,G.jsx)(`p`,{className:`text-red-400/90 text-[12px]`,children:Ze})}),Pe===`device`&&Ie!==`pending`&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`div`,{className:`space-y-1.5`,children:[`Click below — we'll open auth.openai.com/codex/device for you`,`Sign in with your ChatGPT Plus or Pro account`,`Type the one-time code shown here on that page`].map((e,t)=>(0,G.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,G.jsx)(`span`,{className:`flex-shrink-0 w-[18px] h-[18px] rounded-full bg-white/[0.06] text-white/30 text-[10px] font-medium flex items-center justify-center mt-px`,children:t+1}),(0,G.jsx)(`p`,{className:`text-white/40 text-[12px] leading-relaxed`,children:e})]},t))}),(0,G.jsx)(`button`,{onClick:Pr,disabled:He,className:`w-full py-2.5 px-4 bg-gradient-brand hover:opacity-90 text-white text-[13px] font-medium rounded-xl transition-colors flex items-center justify-center gap-2 disabled:opacity-60`,children:He?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(O,{className:`h-3.5 w-3.5 animate-spin`}),`Requesting code...`]}):(0,G.jsxs)(G.Fragment,{children:[`Sign in with ChatGPT`,(0,G.jsx)(w,{className:`h-3.5 w-3.5 opacity-60`})]})})]}),Pe===`device`&&Ie===`pending`&&Re&&(0,G.jsxs)(`div`,{className:`space-y-3`,children:[(0,G.jsxs)(`div`,{className:`bg-white/[0.03] border border-white/[0.06] rounded-xl p-4`,children:[(0,G.jsx)(`p`,{className:`text-[11px] text-white/40 mb-1`,children:`1. Open this URL in any browser`}),(0,G.jsxs)(`button`,{onClick:()=>kr(Be),className:`w-full text-left py-2 px-3 bg-white/[0.04] hover:bg-white/[0.07] rounded-lg text-[12px] font-mono text-white/80 flex items-center justify-between transition-colors`,children:[(0,G.jsx)(`span`,{className:`truncate`,children:Be}),(0,G.jsx)(se,{className:`h-3.5 w-3.5 ml-2 opacity-60 shrink-0`})]}),(0,G.jsx)(`p`,{className:`text-[11px] text-white/40 mt-3 mb-1`,children:`2. Enter this code`}),(0,G.jsxs)(`button`,{onClick:Ir,className:`w-full py-3 px-3 bg-white/[0.04] hover:bg-white/[0.07] rounded-lg text-center transition-colors flex items-center justify-center gap-3 group`,children:[(0,G.jsx)(`span`,{className:`text-[20px] font-mono font-semibold text-white tracking-widest`,children:Re}),We?(0,G.jsx)(ne,{className:`h-4 w-4 text-emerald-400`}):(0,G.jsx)(ae,{className:`h-4 w-4 text-white/30 group-hover:text-white/60`})]}),(0,G.jsxs)(`div`,{className:`flex items-center justify-center gap-2 mt-3 text-[11px] text-white/40`,children:[(0,G.jsx)(O,{className:`h-3 w-3 animate-spin`}),`Waiting for you to approve...`]})]}),(0,G.jsx)(`button`,{onClick:Fr,className:`w-full py-1.5 text-white/25 text-[11px] hover:text-white/40 transition-colors`,children:`Cancel`})]}),Pe===`paste`&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`div`,{className:`space-y-1.5`,children:[`Click below to open ChatGPT sign-in`,`Sign in with your ChatGPT Plus or Pro account`,`Your browser will say "site can't be reached" — that's expected. Copy the FULL URL from the address bar and paste it below.`].map((e,t)=>(0,G.jsxs)(`div`,{className:`flex items-start gap-2`,children:[(0,G.jsx)(`span`,{className:`flex-shrink-0 w-[18px] h-[18px] rounded-full bg-white/[0.06] text-white/30 text-[10px] font-medium flex items-center justify-center mt-px`,children:t+1}),(0,G.jsx)(`p`,{className:`text-white/40 text-[12px] leading-relaxed`,children:e})]},t))}),(0,G.jsx)(`button`,{onClick:Lr,className:`w-full py-2.5 px-4 bg-gradient-brand hover:opacity-90 text-white text-[13px] font-medium rounded-xl transition-colors flex items-center justify-center gap-2`,children:A?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(se,{className:`h-3.5 w-3.5 opacity-60`}),`Open authentication page again`]}):(0,G.jsxs)(G.Fragment,{children:[`Authenticate with ChatGPT`,(0,G.jsx)(w,{className:`h-3.5 w-3.5 opacity-60`})]})}),(0,G.jsxs)(`div`,{className:`relative`,children:[(0,G.jsx)(`input`,{type:`text`,value:qe,onChange:e=>Je(e.target.value),onKeyDown:e=>e.key===`Enter`&&Rr(),placeholder:`Paste callback URL or code here...`,className:Qr+` pr-10 font-mono`}),(0,G.jsx)(`button`,{onClick:zr,className:`absolute right-3 top-1/2 -translate-y-1/2 text-white/20 hover:text-white/50 transition-colors`,children:(0,G.jsx)(re,{className:`h-3.5 w-3.5`})})]}),(0,G.jsx)(`button`,{onClick:Rr,disabled:!qe.trim()||Ye,className:`w-full py-2.5 px-4 bg-gradient-brand hover:opacity-90 text-white text-[13px] font-medium rounded-xl transition-colors flex items-center justify-center gap-2 disabled:opacity-40`,children:Ye?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(O,{className:`h-3.5 w-3.5 animate-spin`}),`Verifying...`]}):`Connect`})]}),Ie!==`pending`&&(0,G.jsxs)(`div`,{className:`flex items-center justify-between pt-1`,children:[(0,G.jsx)(`button`,{onClick:()=>{Qe(void 0),Fe(Pe===`device`?`paste`:`device`)},className:`text-white/25 text-[11px] hover:text-white/40 transition-colors`,children:Pe===`device`?`Use callback URL instead`:`Use device code instead`}),(0,G.jsxs)(`button`,{onClick:Br,disabled:$e,className:`text-white/25 text-[11px] hover:text-white/40 transition-colors flex items-center gap-1.5 disabled:opacity-50`,children:[$e?(0,G.jsx)(O,{className:`h-3 w-3 animate-spin`}):(0,G.jsx)(ge,{className:`h-3 w-3`}),$e?`Checking...`:`I'm already authenticated`]})]})]})]}),hr&&c!==`pi`&&(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(`div`,{className:`border-t border-white/[0.06] mt-4 mb-3`}),(0,G.jsx)(`label`,{className:`text-[12px] text-white/40 font-medium mb-1.5 block`,children:`Select a model`}),(0,G.jsx)(hd,{models:md[c]||[],value:u,onChange:d})]}),t&&hr&&(0,G.jsxs)(`button`,{onClick:Gr,disabled:!Wr,className:`w-full mt-4 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40`,children:[`Continue`,(0,G.jsx)(w,{className:`h-4 w-4`})]})]}),i===5&&(0,G.jsxs)(`div`,{children:[(0,G.jsx)(`h1`,{className:`text-xl font-bold text-white tracking-tight mb-1`,children:`Voice Messages`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-1 leading-relaxed`,children:`Voice input works out of the box using your browser's built-in speech recognition. For better accuracy, you can optionally enable OpenAI Whisper.`}),(0,G.jsx)(`div`,{className:`w-full mt-5 rounded-xl border border-emerald-500/20 bg-emerald-500/[0.04] p-4`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-3.5`,children:[(0,G.jsx)(`div`,{className:`w-10 h-10 rounded-xl bg-emerald-500/10 flex items-center justify-center shrink-0`,children:(0,G.jsx)(fe,{className:`h-5 w-5 text-emerald-400`})}),(0,G.jsxs)(`div`,{className:`flex-1`,children:[(0,G.jsx)(`div`,{className:`text-[14px] font-medium text-white`,children:`Browser Speech Recognition`}),(0,G.jsx)(`div`,{className:`text-[12px] text-white/35 mt-0.5 leading-relaxed`,children:`Built-in voice input — no setup needed. Works in Chrome, Edge, and Safari.`})]}),(0,G.jsx)(`div`,{className:`flex items-center justify-center w-6 h-6 rounded-full bg-emerald-500/20 shrink-0`,children:(0,G.jsx)(ne,{className:`h-3.5 w-3.5 text-emerald-400`})})]})}),(0,G.jsx)(`button`,{onClick:()=>Cn(e=>!e),className:`w-full mt-3 rounded-xl border transition-all duration-200 p-4 text-left ${L?`bg-white/[0.04] border-[#0069FE]/40`:`bg-transparent border-white/[0.06] hover:border-white/10 hover:bg-white/[0.02]`}`,children:(0,G.jsxs)(`div`,{className:`flex items-center gap-3.5`,children:[(0,G.jsx)(`img`,{src:`/icons/openai.svg`,alt:`OpenAI`,className:`w-10 h-10 rounded-xl bg-white/[0.04] p-1.5`}),(0,G.jsxs)(`div`,{className:`flex-1`,children:[(0,G.jsx)(`div`,{className:`text-[14px] font-medium text-white`,children:`OpenAI Whisper`}),(0,G.jsx)(`div`,{className:`text-[12px] text-white/35 mt-0.5 leading-relaxed`,children:`Upgrade to more accurate transcription that works in all browsers including Firefox.`})]}),(0,G.jsx)(`div`,{className:`w-10 h-[22px] rounded-full transition-colors duration-200 flex items-center px-0.5 shrink-0 ${L?`bg-gradient-brand`:`bg-white/[0.08]`}`,children:(0,G.jsx)(`div`,{className:`w-[18px] h-[18px] rounded-full bg-white shadow-sm transition-transform duration-200 ${L?`translate-x-[18px]`:`translate-x-0`}`})})]})}),L&&(0,G.jsxs)(`div`,{className:`mt-3`,children:[(0,G.jsx)(`label`,{className:`text-[12px] text-white/40 font-medium mb-1.5 block`,children:`OpenAI API Key`}),(0,G.jsx)(`input`,{type:`password`,value:wn,onChange:e=>Tn(e.target.value.trim()),placeholder:`sk-...`,autoComplete:`off`,className:Zr+` font-mono text-[13px]`}),wn.length>0&&!wn.startsWith(`sk-`)&&(0,G.jsx)(`p`,{className:`text-amber-400/70 text-[11px] mt-1`,children:`Key should start with sk-`}),wn.length>0&&wn.startsWith(`sk-`)&&wn.length<20&&(0,G.jsx)(`p`,{className:`text-amber-400/70 text-[11px] mt-1`,children:`Key looks too short`}),(0,G.jsxs)(`div`,{className:`flex items-start gap-2.5 mt-3 bg-white/[0.02] border border-white/[0.06] rounded-xl px-4 py-3`,children:[(0,G.jsx)(fe,{className:`h-4 w-4 text-[#0069FE]/60 mt-0.5 shrink-0`}),(0,G.jsx)(`p`,{className:`text-white/35 text-[12px] leading-relaxed`,children:`Whisper provides more accurate transcription and works in all browsers including Firefox.`})]})]}),t&&(0,G.jsx)(`button`,{onClick:Xr,disabled:f||L&&(!wn.startsWith(`sk-`)||wn.length<20),className:`w-full mt-5 py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40`,children:f?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}),`Setting up...`]}):(0,G.jsxs)(G.Fragment,{children:[`Complete Setup`,(0,G.jsx)(w,{className:`h-4 w-4`})]})}),!L&&(0,G.jsx)(`p`,{className:`text-center text-white/20 text-[11px] mt-2.5`,children:`Voice input is active using your browser's built-in speech recognition.`})]}),i===6&&t&&(()=>{let e=_t===`off`,t=e?window.location.origin:_t===`named`?`https://${yt}`:Ct===`relay`&&mt?mt:xt||`http://localhost:3000`,n=t.startsWith(`http`)?t:`https://${t}`;return(0,G.jsxs)(`div`,{className:`flex flex-col items-center text-center`,children:[(0,G.jsx)(`div`,{className:`w-16 h-16 rounded-full bg-emerald-500/10 border border-emerald-500/20 flex items-center justify-center mb-5`,children:(0,G.jsx)(ne,{className:`h-8 w-8 text-emerald-400`})}),(0,G.jsx)(`h1`,{className:`text-2xl font-bold text-white tracking-tight`,children:`All Set!`}),(0,G.jsx)(`p`,{className:`text-white/40 text-[13px] mt-2 leading-relaxed max-w-[340px]`,children:e?`Your agent is running on your private network. Access it from any device on your local network or VPN.`:_t===`named`?`Access your agent at your custom domain.`:Ct===`relay`&&mt?`Your agent is live and ready. From now on, access it using your custom URL below.`:`Your agent is live and ready. Your tunnel URL is shown below. Note: this URL changes on restart.`}),(0,G.jsxs)(`div`,{className:`w-full mt-6 flex items-center gap-2 bg-white/[0.03] border border-white/[0.06] rounded-xl px-4 py-3`,children:[(0,G.jsx)(`span`,{className:`font-mono text-[13px] text-white/70 truncate flex-1 text-left`,children:t}),(0,G.jsx)(`button`,{onClick:()=>{navigator.clipboard.writeText(n),on(!0),setTimeout(()=>on(!1),2e3)},className:`shrink-0 text-white/30 hover:text-white/60 transition-colors`,children:an?(0,G.jsx)(ne,{className:`h-4 w-4 text-emerald-400`}):(0,G.jsxs)(`svg`,{className:`h-4 w-4`,fill:`none`,viewBox:`0 0 24 24`,stroke:`currentColor`,strokeWidth:2,children:[(0,G.jsx)(`rect`,{x:`9`,y:`9`,width:`13`,height:`13`,rx:`2`}),(0,G.jsx)(`path`,{d:`M5 15H4a2 2 0 01-2-2V4a2 2 0 012-2h9a2 2 0 012 2v1`})]})})]}),(0,G.jsxs)(`div`,{className:`w-full mt-3`,children:[(0,G.jsx)(`label`,{className:`text-[12px] text-white/40 font-medium mb-1.5 block text-left`,children:`Your password`}),(0,G.jsxs)(`div`,{className:`flex items-center gap-2 bg-white/[0.03] border border-white/[0.06] rounded-xl px-4 py-3`,children:[(0,G.jsx)(`span`,{className:`font-mono text-[13px] text-white/70 truncate flex-1 text-left`,children:ln?tn:`•`.repeat(Math.max(tn.length,8))}),(0,G.jsx)(`button`,{onClick:()=>un(e=>!e),className:`shrink-0 text-white/30 hover:text-white/60 transition-colors`,children:ln?(0,G.jsx)(ce,{className:`h-4 w-4`}):(0,G.jsx)(le,{className:`h-4 w-4`})})]})]}),(0,G.jsxs)(`label`,{className:`flex items-start gap-2.5 mt-6 cursor-pointer text-left select-none`,children:[(0,G.jsx)(`input`,{type:`checkbox`,checked:dn,onChange:e=>fn(e.target.checked),className:`mt-0.5 h-4 w-4 rounded border-white/20 bg-white/5 accent-emerald-500 shrink-0`}),(0,G.jsxs)(`span`,{className:`text-[12px] text-white/50 leading-relaxed`,children:[`I accept the`,` `,(0,G.jsx)(`a`,{href:`https://www.bloby.bot/terms`,target:`_blank`,rel:`noopener noreferrer`,className:`text-white/70 underline hover:text-white/90`,children:`terms`}),` `,`and`,` `,(0,G.jsx)(`a`,{href:`https://www.bloby.bot/privacy`,target:`_blank`,rel:`noopener noreferrer`,className:`text-white/70 underline hover:text-white/90`,children:`privacy policy`})]})]}),(0,G.jsxs)(`button`,{disabled:!dn,onClick:()=>{e?(window.top||window).location.href=`/`:(window.top||window).location.href=n},className:`w-full mt-4 py-3 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 ${dn?`bg-gradient-brand hover:opacity-90`:`bg-white/10 cursor-not-allowed opacity-50`}`,children:[e?`Go to dashboard`:`Go to your agent`,(0,G.jsx)(se,{className:`h-4 w-4`})]}),(0,G.jsx)(`p`,{className:`text-white/20 text-[11px] mt-3 leading-relaxed`,children:e?`Access from any device on your network using the URL above.`:`You'll be redirected to your ${_t===`named`?`custom domain`:Ct===`relay`?`custom URL`:`tunnel URL`}.`})]})})(),i===6&&!t&&(0,G.jsx)(yd,{cacheRef:ir}),i===7&&!t&&(0,G.jsx)(Od,{cacheRef:ar})]},i)})}),t&&i>0&&i<6&&(0,G.jsx)(`div`,{className:`px-8 pb-5 pt-2 shrink-0`,children:(0,G.jsx)(`button`,{onClick:Kr,className:`text-white/25 hover:text-white/50 text-[12px] transition-colors`,children:`← Back`})}),!t&&i>=1&&i<=5&&(Jr||lr||dr||pr)&&(0,G.jsxs)(`div`,{className:`px-8 pb-6 pt-3 shrink-0 border-t border-white/[0.06] bg-[#181818]`,children:[pr&&(0,G.jsxs)(`p`,{className:`text-red-400 text-[12px] mb-2 flex items-center gap-1.5`,children:[(0,G.jsx)(Se,{className:`h-3.5 w-3.5 shrink-0`}),pr]}),dr&&!Jr?(0,G.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-3 text-emerald-400 text-[13px] font-medium`,children:[(0,G.jsx)(ne,{className:`h-4 w-4`}),` Saved`]}):(0,G.jsx)(`button`,{onClick:Yr,disabled:lr||!Jr,className:`w-full py-3 bg-gradient-brand hover:opacity-90 text-white text-[14px] font-semibold rounded-full transition-colors flex items-center justify-center gap-2 disabled:opacity-40 disabled:cursor-not-allowed`,children:lr?(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(O,{className:`h-4 w-4 animate-spin`}),`Saving...`]}):(0,G.jsxs)(G.Fragment,{children:[(0,G.jsx)(ne,{className:`h-4 w-4`}),`Save changes`]})})]})]})]})}export{w as C,d as E,ne as S,S as T,de as _,je as a,oe as b,Ae as c,be as d,ye as f,O as g,fe as h,Ne as i,Te as l,k as m,sd as n,ke as o,me as p,_l as r,Me as s,kd as t,xe as u,D as v,ee as w,ae as x,se as y};
@@ -1 +1 @@
1
- import{c as e,r as t,t as n}from"./jsx-runtime-C0W9Wf2W.js";import{n as r,r as i,t as a}from"./bloby-CXmOcb1r.js";var o=e(t(),1),s=n(),c=({code:e,language:t,raw:n,className:c,startLine:l,lineNumbers:u,...d})=>{let{shikiTheme:f}=(0,o.useContext)(i),p=r(),[m,h]=(0,o.useState)(n);return(0,o.useEffect)(()=>{if(!p){h(n);return}let r=p.highlight({code:e,language:t,themes:f},e=>{h(e)});r&&h(r)},[e,t,f,p,n]),(0,s.jsx)(a,{className:c,language:t,lineNumbers:u,result:m,startLine:l,...d})};export{c as HighlightedCodeBlockBody};
1
+ import{c as e,r as t,t as n}from"./jsx-runtime-C0W9Wf2W.js";import{n as r,r as i,t as a}from"./bloby-DSNB0g4w.js";var o=e(t(),1),s=n(),c=({code:e,language:t,raw:n,className:c,startLine:l,lineNumbers:u,...d})=>{let{shikiTheme:f}=(0,o.useContext)(i),p=r(),[m,h]=(0,o.useState)(n);return(0,o.useEffect)(()=>{if(!p){h(n);return}let r=p.highlight({code:e,language:t,themes:f},e=>{h(e)});r&&h(r)},[e,t,f,p,n]),(0,s.jsx)(a,{className:c,language:t,lineNumbers:u,result:m,startLine:l,...d})};export{c as HighlightedCodeBlockBody};
@@ -0,0 +1 @@
1
+ import{i as e}from"./bloby-DSNB0g4w.js";export{e as Mermaid};
@@ -1 +1 @@
1
- import{c as e,r as t,t as n}from"./jsx-runtime-C0W9Wf2W.js";import{E as r,t as i}from"./globals-DpO5tO92.js";var a=e(t(),1),o=e(r(),1),s=n();function c(){return(0,s.jsx)(i,{onComplete:()=>{window.parent?.postMessage({type:`bloby:onboard-complete`},`*`)},isInitialSetup:!0})}o.createRoot(document.getElementById(`root`)).render((0,s.jsx)(a.StrictMode,{children:(0,s.jsx)(c,{})}));
1
+ import{c as e,r as t,t as n}from"./jsx-runtime-C0W9Wf2W.js";import{E as r,t as i}from"./globals-B3cTbITX.js";var a=e(t(),1),o=e(r(),1),s=n();function c(){return(0,s.jsx)(i,{onComplete:()=>{window.parent?.postMessage({type:`bloby:onboard-complete`},`*`)},isInitialSetup:!0})}o.createRoot(document.getElementById(`root`)).render((0,s.jsx)(a.StrictMode,{children:(0,s.jsx)(c,{})}));
@@ -4,9 +4,9 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, interactive-widget=resizes-content" />
6
6
  <title>Bloby Chat</title>
7
- <script type="module" crossorigin src="/bloby/assets/bloby-CXmOcb1r.js"></script>
7
+ <script type="module" crossorigin src="/bloby/assets/bloby-DSNB0g4w.js"></script>
8
8
  <link rel="modulepreload" crossorigin href="/bloby/assets/jsx-runtime-C0W9Wf2W.js">
9
- <link rel="modulepreload" crossorigin href="/bloby/assets/globals-DpO5tO92.js">
9
+ <link rel="modulepreload" crossorigin href="/bloby/assets/globals-B3cTbITX.js">
10
10
  <link rel="stylesheet" crossorigin href="/bloby/assets/globals-DyeW509Y.css">
11
11
  <link rel="stylesheet" crossorigin href="/bloby/assets/bloby-DkK0ymA2.css">
12
12
  </head>
@@ -4,9 +4,9 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, interactive-widget=resizes-content" />
6
6
  <title>Bloby Setup</title>
7
- <script type="module" crossorigin src="/bloby/assets/onboard-B96ELhXn.js"></script>
7
+ <script type="module" crossorigin src="/bloby/assets/onboard-Dn2Ws_G2.js"></script>
8
8
  <link rel="modulepreload" crossorigin href="/bloby/assets/jsx-runtime-C0W9Wf2W.js">
9
- <link rel="modulepreload" crossorigin href="/bloby/assets/globals-DpO5tO92.js">
9
+ <link rel="modulepreload" crossorigin href="/bloby/assets/globals-B3cTbITX.js">
10
10
  <link rel="stylesheet" crossorigin href="/bloby/assets/globals-DyeW509Y.css">
11
11
  </head>
12
12
  <body class="bg-background text-foreground">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bloby-bot",
3
- "version": "0.70.8",
3
+ "version": "0.70.10",
4
4
  "releaseNotes": [
5
5
  "1. Fix: agent self-update ",
6
6
  "1",
@@ -17,7 +17,9 @@ import { fileURLToPath, pathToFileURL } from 'url';
17
17
 
18
18
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
19
19
  const REPO_ROOT = path.resolve(__dirname, '..');
20
- const PI_MODELS_PATH = path.join(REPO_ROOT, 'pi-main', 'packages', 'ai', 'src', 'models.generated.ts');
20
+ // Default sibling checkout; override with PI_MAIN_DIR=/path/to/pi-main when it lives elsewhere.
21
+ const PI_MAIN_DIR = process.env.PI_MAIN_DIR || path.join(REPO_ROOT, 'pi-main');
22
+ const PI_MODELS_PATH = path.join(PI_MAIN_DIR, 'packages', 'ai', 'src', 'models.generated.ts');
21
23
  const OUTPUT_PATH = path.join(REPO_ROOT, 'supervisor', 'harnesses', 'pi', 'models-catalog.generated.ts');
22
24
 
23
25
  if (!fs.existsSync(PI_MODELS_PATH)) {
@@ -69,7 +71,13 @@ function isHidden(id: string): boolean {
69
71
  return HIDDEN_PATTERNS.some((re) => re.test(id));
70
72
  }
71
73
 
72
- async function loadPiModels(): Promise<Record<string, Record<string, { id: string; name?: string }>>> {
74
+ async function loadPiModels(): Promise<Record<string, Record<string, {
75
+ id: string;
76
+ name?: string;
77
+ contextWindow?: number;
78
+ maxTokens?: number;
79
+ input?: string[];
80
+ }>>> {
73
81
  // pi's file has `import type { Model } from "./types.js"` — strip that line
74
82
  // so the module loads without needing pi's full types graph at sync time.
75
83
  const raw = fs.readFileSync(PI_MODELS_PATH, 'utf-8');
@@ -101,7 +109,14 @@ function versionScore(id: string): number {
101
109
  async function main() {
102
110
  const MODELS = await loadPiModels();
103
111
 
104
- const out: Record<string, { id: string; label: string }[]> = {};
112
+ interface OutModel {
113
+ id: string;
114
+ label: string;
115
+ contextWindow?: number;
116
+ maxOutputTokens?: number;
117
+ input?: string[];
118
+ }
119
+ const out: Record<string, OutModel[]> = {};
105
120
  let total = 0;
106
121
  for (const [blobyId, piKey] of Object.entries(PROVIDER_MAP)) {
107
122
  const provider = MODELS[piKey];
@@ -109,10 +124,17 @@ async function main() {
109
124
  console.warn(`! no pi provider "${piKey}" (mapped from bloby "${blobyId}")`);
110
125
  continue;
111
126
  }
112
- const entries: { id: string; label: string }[] = [];
127
+ const entries: OutModel[] = [];
113
128
  for (const [id, m] of Object.entries(provider)) {
114
129
  if (isHidden(id)) continue;
115
- entries.push({ id, label: m?.name || id });
130
+ const entry: OutModel = { id, label: m?.name || id };
131
+ // Capacity + modality metadata used by the harness: contextWindow feeds the
132
+ // supervisor's session recycler, maxOutputTokens caps tool-call/output size,
133
+ // input gates image attachments on non-vision models.
134
+ if (typeof m?.contextWindow === 'number' && m.contextWindow > 0) entry.contextWindow = m.contextWindow;
135
+ if (typeof m?.maxTokens === 'number' && m.maxTokens > 0) entry.maxOutputTokens = m.maxTokens;
136
+ if (Array.isArray(m?.input) && m.input.length > 0) entry.input = m.input;
137
+ entries.push(entry);
116
138
  }
117
139
  // Newest version first; alphabetical inside the same version.
118
140
  entries.sort((a, b) => {
@@ -129,7 +151,16 @@ async function main() {
129
151
  `// Last sync: ${new Date().toISOString()}\n` +
130
152
  `\n`;
131
153
  const body =
132
- `export interface PiCatalogModel { id: string; label: string }\n` +
154
+ `export interface PiCatalogModel {\n` +
155
+ ` id: string;\n` +
156
+ ` label: string;\n` +
157
+ ` /** Model context window in tokens — feeds the supervisor's proactive session recycling. */\n` +
158
+ ` contextWindow?: number;\n` +
159
+ ` /** Max output tokens per request — caps tool-call/output size per provider round. */\n` +
160
+ ` maxOutputTokens?: number;\n` +
161
+ ` /** Input modalities (e.g. ["text","image"]) — gates image attachments on non-vision models. */\n` +
162
+ ` input?: string[];\n` +
163
+ `}\n` +
133
164
  `export const PI_MODELS_CATALOG: Record<string, PiCatalogModel[]> = ${JSON.stringify(out, null, 2)};\n`;
134
165
  fs.writeFileSync(OUTPUT_PATH, banner + body);
135
166
 
@@ -2111,8 +2111,8 @@ export default function OnboardWizard({ onComplete, isInitialSetup = false, onSa
2111
2111
  {step === 0 && isInitialSetup && (
2112
2112
  <div className="flex flex-col items-center text-center">
2113
2113
  <video autoPlay loop muted playsInline className="h-[180px] mb-4">
2114
- <source src="/bloby_say_hi.mov" type='video/mp4; codecs="hvc1"' />
2115
- <source src="/bloby_say_hi.webm" type="video/webm" />
2114
+ <source src="/morphy_hi.mov" type='video/mp4; codecs="hvc1"' />
2115
+ <source src="/morphy_hi.webm" type="video/webm" />
2116
2116
  </video>
2117
2117
  <h1 className="text-2xl font-bold text-white tracking-tight">
2118
2118
  Welcome to Bloby
@@ -2134,8 +2134,8 @@ export default function OnboardWizard({ onComplete, isInitialSetup = false, onSa
2134
2134
  {step === 0 && !isInitialSetup && (
2135
2135
  <div className="flex flex-col items-center text-center">
2136
2136
  <video autoPlay loop muted playsInline className="h-[150px] mb-4">
2137
- <source src="/bloby_say_hi.mov" type='video/mp4; codecs="hvc1"' />
2138
- <source src="/bloby_say_hi.webm" type="video/webm" />
2137
+ <source src="/morphy_hi.mov" type='video/mp4; codecs="hvc1"' />
2138
+ <source src="/morphy_hi.webm" type="video/webm" />
2139
2139
  </video>
2140
2140
  <h1 className="text-2xl font-bold text-white tracking-tight">
2141
2141
  Settings
@@ -4,17 +4,17 @@
4
4
  * The Claude harness uses this exact shape as the input prompt to the Claude
5
5
  * Agent SDK's long-lived `query()`. The pi session loop uses the same pattern
6
6
  * so the non-blocking live-conversation behavior matches Claude byte-for-byte
7
- * at the queue level: pushMessage() never awaits the model.
7
+ * at the queue level: pushMessage() never awaits the model, and each queued
8
+ * message is consumed as its own turn.
9
+ *
10
+ * Deliberately NO bulk-drain helper: an earlier `drainPending()` let the
11
+ * session fold mid-turn messages into the in-flight turn, which broke the
12
+ * channel manager's one-routing-target-per-push FIFO (see
13
+ * PI-PARITY-AUDIT-2026-06-11.md D1-1). One message in → one turn out.
8
14
  */
9
15
  export interface AsyncQueue<T> extends AsyncIterable<T> {
10
16
  push(item: T): void;
11
17
  end(): void;
12
- /**
13
- * Non-blocking drain: return every item currently buffered without waiting
14
- * for a new one. Used by the session to fold mid-turn user messages into
15
- * the model's history without breaking the outer `for await` consumer.
16
- */
17
- drainPending(): T[];
18
18
  }
19
19
 
20
20
  export function createAsyncQueue<T>(): AsyncQueue<T> {
@@ -36,10 +36,6 @@ export function createAsyncQueue<T>(): AsyncQueue<T> {
36
36
  done = true;
37
37
  if (resolve) resolve({ value: undefined as any, done: true });
38
38
  },
39
- drainPending() {
40
- if (pending.length === 0) return [];
41
- return pending.splice(0, pending.length);
42
- },
43
39
  [Symbol.asyncIterator]() {
44
40
  return {
45
41
  next(): Promise<IteratorResult<T>> {