heyhank 0.2.0 → 0.3.0

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 (37) hide show
  1. package/dist/assets/{AgentsPage-B-AAmsMK.js → AgentsPage-DqjDAcIw.js} +1 -1
  2. package/dist/assets/{AssistantPage-BV1Mfwdt.js → AssistantPage-C50CQFSB.js} +1 -1
  3. package/dist/assets/{BusinessPage-tLpNEz19.js → BusinessPage-AY70tf1k.js} +1 -1
  4. package/dist/assets/{CronManager-B-K_n3Jg.js → CronManager-Dt7LLuRr.js} +1 -1
  5. package/dist/assets/{HelpPage-Bhf_j6Xr.js → HelpPage-tlGx7fQF.js} +1 -1
  6. package/dist/assets/{IntegrationsPage-DAMjs9tM.js → IntegrationsPage-B4XOuHXu.js} +1 -1
  7. package/dist/assets/{JarvisHUD-C_TGXCCn.js → JarvisHUD-BDvuRd0I.js} +1 -1
  8. package/dist/assets/{MediaPage-C48HTTrt.js → MediaPage-CofV9Rd-.js} +1 -1
  9. package/dist/assets/{MemoryPage-JkC-qtgp.js → MemoryPage-Cj7FeqmJ.js} +1 -1
  10. package/dist/assets/{PlatformDashboard-AUo7tNnE.js → PlatformDashboard-B9kXAlH1.js} +1 -1
  11. package/dist/assets/{Playground-AzNMsRBL.js → Playground-Cka-pRkP.js} +1 -1
  12. package/dist/assets/{ProcessPanel-DpE_2sX3.js → ProcessPanel-BqhQgfYj.js} +1 -1
  13. package/dist/assets/{PromptsPage-C2RQOs6p.js → PromptsPage-VveKc9uX.js} +1 -1
  14. package/dist/assets/RunsPage-DXVEk0AZ.js +1 -0
  15. package/dist/assets/{SandboxManager-jHvYjwfh.js → SandboxManager-DACcwfDF.js} +1 -1
  16. package/dist/assets/{SettingsPage-BBJax6gt.js → SettingsPage-jfuQh8Tu.js} +1 -1
  17. package/dist/assets/{SkillsMarketplace-IjmjfdjD.js → SkillsMarketplace-DrigiApe.js} +1 -1
  18. package/dist/assets/{SocialMediaPage-DoPZHhr2.js → SocialMediaPage-DOh3IPe8.js} +1 -1
  19. package/dist/assets/{TailscalePage-DDEY7ckO.js → TailscalePage-DLhJWATT.js} +1 -1
  20. package/dist/assets/{TelephonyPage-OPNBZYKt.js → TelephonyPage-9C4C3_ot.js} +1 -1
  21. package/dist/assets/{TerminalPage-BjMbHHW3.js → TerminalPage-ChX-8Wu7.js} +1 -1
  22. package/dist/assets/index-C6Q5UQHD.js +229 -0
  23. package/dist/assets/index-ZxGXgiV3.css +32 -0
  24. package/dist/assets/sw-register-BBYuk-kw.js +1 -0
  25. package/dist/assets/workbox-window.prod.es5-BBnX5xw4.js +2 -0
  26. package/dist/index.html +2 -2
  27. package/dist/sw.js +1 -1
  28. package/dist/{workbox-d2a0910a.js → workbox-080c8b91.js} +1 -1
  29. package/package.json +1 -1
  30. package/server/agent-executor.ts +65 -0
  31. package/server/execution-store.ts +54 -1
  32. package/server/routes/agent-routes.ts +42 -0
  33. package/dist/assets/RunsPage-B9UOyO79.js +0 -1
  34. package/dist/assets/index-BgYM4wXw.js +0 -205
  35. package/dist/assets/index-BkjSoVgn.css +0 -32
  36. package/dist/assets/sw-register-C7NOHtIu.js +0 -1
  37. package/dist/assets/workbox-window.prod.es5-BIl4cyR9.js +0 -2
@@ -1,4 +1,4 @@
1
- import{r as s,b as o,j as e,u as k,n as Is,a as Ts}from"./index-BgYM4wXw.js";import{unsubscribeFromPush as Os,subscribeToPush as Ls}from"./sw-register-C7NOHtIu.js";function Rs(){const[a,f]=s.useState(null),[C,v]=s.useState(""),[m,x]=s.useState([]),[p,b]=s.useState([]),[g,A]=s.useState(!0),[j,d]=s.useState(!1),[y,T]=s.useState(""),[M,R]=s.useState(""),[F,i]=s.useState(""),[E,V]=s.useState(""),[$,z]=s.useState(""),G=s.useCallback(async()=>{try{const[r,h,se]=await Promise.all([o.getFederationIdentity(),o.getFederationNodes(),o.getFederationRemoteSessions()]);f(r),v(r.name),x(h.nodes),b(se.sessions)}catch{}A(!1)},[]);s.useEffect(()=>{G()},[G]),s.useEffect(()=>{const r=setInterval(G,1e4);return()=>clearInterval(r)},[G]);const L=(r,h=!1)=>{h?(T(r),R("")):(R(r),T("")),setTimeout(()=>{T(""),R("")},4e3)},le=async()=>{if(C.trim()){d(!0);try{await o.updateFederationIdentity(C.trim()),L("Node name saved")}catch(r){L(r instanceof Error?r.message:"Failed to save",!0)}d(!1)}},de=async()=>{if(!F.trim()||!E.trim()){L("URL and shared secret are required",!0);return}d(!0);try{await o.addFederationNode({url:F.trim(),secret:E.trim(),name:$.trim()}),i(""),V(""),z(""),L("Node added, connecting..."),setTimeout(G,2e3)}catch(r){L(r instanceof Error?r.message:"Failed to add node",!0)}d(!1)},ye=async r=>{try{await o.removeFederationNode(r),L("Node removed"),G()}catch(h){L(h instanceof Error?h.message:"Failed to remove",!0)}},ue=async r=>{try{const h=await o.testFederationNode(r);L(h.connected?"Connection OK":"Not connected")}catch(h){L(h instanceof Error?h.message:"Test failed",!0)}};return g?e.jsx("div",{className:"text-sm text-cc-muted",children:"Loading federation..."}):e.jsxs("div",{className:"space-y-5",children:[y&&e.jsx("div",{className:"text-sm text-cc-error bg-cc-error/5 border border-cc-error/20 rounded-lg px-3 py-2",children:y}),M&&e.jsx("div",{className:"text-sm text-cc-success bg-cc-success/5 border border-cc-success/20 rounded-lg px-3 py-2",children:M}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider mb-2",children:"This Node"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{type:"text",value:C,onChange:r=>v(r.target.value),onKeyDown:r=>r.key==="Enter"&&le(),placeholder:"Node name",className:"flex-1 px-3 py-2 text-sm rounded-lg bg-cc-hover border border-cc-border text-cc-fg outline-none focus:border-cc-primary/50"}),e.jsx("button",{onClick:le,disabled:j,className:"px-3 py-2 text-sm rounded-lg bg-cc-hover border border-cc-border text-cc-fg hover:bg-cc-active transition-colors cursor-pointer disabled:opacity-50",children:"Save"})]}),a&&e.jsxs("p",{className:"text-[10px] text-cc-muted/60 font-mono mt-1 break-all",children:["ID: ",a.nodeId]})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider mb-2",children:"Add Node"}),e.jsx("p",{className:"text-xs text-cc-muted mb-2",children:"Enter the URL and shared secret of a remote HeyHank instance."}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("input",{type:"url",value:F,onChange:r=>i(r.target.value),placeholder:"https://other-hank.example.com",className:"w-full px-3 py-2 text-sm rounded-lg bg-cc-hover border border-cc-border text-cc-fg outline-none focus:border-cc-primary/50"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{type:"password",value:E,onChange:r=>V(r.target.value),placeholder:"Shared secret",className:"flex-1 px-3 py-2 text-sm rounded-lg bg-cc-hover border border-cc-border text-cc-fg outline-none focus:border-cc-primary/50"}),e.jsx("input",{type:"text",value:$,onChange:r=>z(r.target.value),placeholder:"Name (optional)",className:"flex-1 px-3 py-2 text-sm rounded-lg bg-cc-hover border border-cc-border text-cc-fg outline-none focus:border-cc-primary/50"})]}),e.jsx("button",{onClick:de,disabled:j,className:"w-full px-3 py-2.5 text-sm font-medium rounded-lg bg-cc-primary/10 border border-cc-primary/30 text-cc-primary hover:bg-cc-primary/15 transition-colors cursor-pointer disabled:opacity-50",children:"Connect Node"})]})]}),e.jsxs("div",{children:[e.jsxs("h4",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider mb-2",children:["Connected Nodes (",m.length,")"]}),m.length===0?e.jsx("p",{className:"text-xs text-cc-muted/50",children:"No nodes configured."}):e.jsx("div",{className:"space-y-2",children:m.map(r=>e.jsxs("div",{className:"border border-cc-border/60 rounded-lg p-3 bg-cc-card/50",children:[e.jsxs("div",{className:"flex items-center justify-between mb-1",children:[e.jsxs("span",{className:"text-sm font-medium text-cc-fg flex items-center gap-1.5",children:[e.jsx("span",{className:`w-2 h-2 rounded-full shrink-0 ${r.connected?"bg-cc-success shadow-[0_0_6px_rgba(74,222,128,0.4)]":"bg-cc-error/60"}`}),r.remoteName||r.name||"Unknown"]}),e.jsxs("span",{className:"text-[10px] text-cc-muted",children:[r.connected?"Connected":"Offline"," · ",r.sessionCount," sessions"]})]}),e.jsx("p",{className:"text-[10px] text-cc-muted/60 break-all mb-2",children:r.url}),e.jsxs("div",{className:"flex gap-1.5",children:[e.jsx("button",{onClick:()=>ue(r.id),className:"px-2 py-1 text-[11px] rounded bg-cc-hover border border-cc-border text-cc-fg hover:bg-cc-active transition-colors cursor-pointer",children:"Test"}),e.jsx("button",{onClick:()=>ye(r.id),className:"px-2 py-1 text-[11px] rounded bg-cc-hover border border-cc-error/20 text-cc-error hover:bg-cc-error/5 transition-colors cursor-pointer",children:"Remove"})]})]},r.id))})]}),p.length>0&&e.jsxs("div",{children:[e.jsxs("h4",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider mb-2",children:["Remote Sessions (",p.length,")"]}),e.jsx("div",{className:"space-y-1.5",children:p.map(r=>e.jsxs("div",{className:"border border-cc-border/40 rounded-lg px-3 py-2 bg-cc-card/30",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-xs font-medium text-cc-fg truncate",children:r.name||r.sessionId.slice(0,8)}),e.jsx("span",{className:"text-[9px] font-semibold px-1.5 py-0.5 rounded bg-cc-primary/15 text-cc-primary leading-none shrink-0",children:r.nodeName})]}),e.jsxs("p",{className:"text-[10px] text-cc-muted/60 truncate mt-0.5",children:[r.model||""," · ",r.cwd||r.sessionId]})]},`${r.nodeId}:${r.sessionId}`))})]})]})}const Fs={cloud:"Cloud Providers",gateway:"Gateways & Proxies",local:"Local / Self-Hosted",custom:"Custom"},Vs=["cloud","gateway","local","custom"];function $s(){const[a,f]=s.useState([]),[C,v]=s.useState(!0),[m,x]=s.useState(null),[p,b]=s.useState(""),g=s.useCallback(()=>{o.getProviders().then(f).catch(()=>{}).finally(()=>v(!1))},[]);if(s.useEffect(()=>{g()},[g]),C)return e.jsx("p",{className:"text-xs text-cc-muted",children:"Loading providers..."});const A=p?a.filter(d=>d.name.toLowerCase().includes(p.toLowerCase())||d.description.toLowerCase().includes(p.toLowerCase())):a,j=Vs.map(d=>({category:d,label:Fs[d]||d,items:A.filter(y=>y.category===d)})).filter(d=>d.items.length>0);return e.jsxs("div",{className:"space-y-4",children:[a.length>10&&e.jsx("input",{type:"text",value:p,onChange:d=>b(d.target.value),placeholder:"Search providers...",className:"w-full px-3 py-2 text-sm bg-cc-input-bg rounded-lg text-cc-fg placeholder:text-cc-muted focus:outline-none focus:ring-1 focus:ring-cc-primary/40 transition-shadow"}),j.map(d=>e.jsxs("div",{children:[e.jsx("h4",{className:"text-xs font-medium text-cc-muted uppercase tracking-wide mb-2",children:d.label}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-2",children:d.items.map(y=>e.jsx(Ks,{provider:y,expanded:m===y.id,onToggle:()=>x(m===y.id?null:y.id),onUpdate:g},y.id))})]},d.category))]})}function Ks({provider:a,expanded:f,onToggle:C,onUpdate:v}){const[m,x]=s.useState({}),[p,b]=s.useState(!1),[g,A]=s.useState(!1),[j,d]=s.useState(""),[y,T]=s.useState(!1);s.useEffect(()=>{f&&!y&&o.getProvider(a.id).then(i=>{var V;const E={};for(const $ of a.envFields)!$.secret&&((V=i.envValues)!=null&&V[$.key])&&(E[$.key]=i.envValues[$.key]);x(E),T(!0)}).catch(()=>{})},[f,y,a.id,a.envFields]);const M=async()=>{b(!0),d(""),A(!1);try{const i={};for(const[E,V]of Object.entries(m))V.trim()&&(i[E]=V.trim());await o.updateProvider(a.id,{enabled:!0,envValues:i}),A(!0),setTimeout(()=>A(!1),2e3),x({}),T(!1),v()}catch(i){d(i instanceof Error?i.message:String(i))}finally{b(!1)}},R=async()=>{try{await o.deleteProvider(a.id),x({}),T(!1),v()}catch{}},F=async()=>{try{await o.updateProvider(a.id,{enabled:!a.enabled}),v()}catch{}};return e.jsxs("div",{className:`rounded-lg border transition-colors ${a.configured&&a.enabled?"border-cc-success/30 bg-cc-success/5":a.configured?"border-cc-warning/30 bg-cc-warning/5":"border-cc-border bg-cc-bg"}`,children:[e.jsxs("button",{type:"button",onClick:C,className:"w-full flex items-center justify-between px-3 py-2.5 cursor-pointer text-left",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm font-medium text-cc-fg truncate",children:a.name}),a.configured&&a.enabled&&e.jsx("span",{className:"shrink-0 w-1.5 h-1.5 rounded-full bg-cc-success"}),a.configured&&!a.enabled&&e.jsx("span",{className:"shrink-0 w-1.5 h-1.5 rounded-full bg-cc-warning"})]}),e.jsx("p",{className:"text-[11px] text-cc-muted truncate",children:a.description})]}),e.jsx("svg",{viewBox:"0 0 16 16",fill:"currentColor",className:`shrink-0 w-3.5 h-3.5 text-cc-muted transition-transform ${f?"rotate-180":""}`,children:e.jsx("path",{fillRule:"evenodd",d:"M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z"})})]}),f&&e.jsxs("div",{className:"px-3 pb-3 space-y-3 border-t border-cc-border/50 pt-3",children:[a.envFields.map(i=>e.jsxs("div",{className:"space-y-1",children:[e.jsxs("label",{className:"block text-xs text-cc-muted",htmlFor:`prov-${a.id}-${i.key}`,children:[i.label,i.required&&e.jsx("span",{className:"text-cc-error ml-0.5",children:"*"}),a.envConfigured[i.key]&&i.secret&&e.jsx("span",{className:"ml-1 text-cc-success",children:"(configured)"})]}),e.jsx("input",{id:`prov-${a.id}-${i.key}`,type:i.secret?"password":"text",value:m[i.key]??"",onChange:E=>x({...m,[i.key]:E.target.value}),placeholder:a.envConfigured[i.key]&&i.secret?"Enter new value to replace":i.placeholder||"",className:"w-full px-2.5 py-1.5 text-sm bg-cc-input-bg rounded-md text-cc-fg placeholder:text-cc-muted/50 focus:outline-none focus:ring-1 focus:ring-cc-primary/40"})]},i.key)),a.docsUrl&&e.jsxs("a",{href:a.docsUrl,target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1 text-[11px] text-cc-primary hover:underline",children:["Documentation",e.jsx("svg",{viewBox:"0 0 16 16",fill:"currentColor",className:"w-3 h-3",children:e.jsx("path",{d:"M3.75 2a.75.75 0 0 0 0 1.5h5.69L2.22 10.72a.75.75 0 1 0 1.06 1.06L10.5 4.56v5.69a.75.75 0 0 0 1.5 0V2.75a.75.75 0 0 0-.75-.75H3.75Z"})})]}),j&&e.jsx("p",{className:"text-xs text-cc-error",children:j}),g&&e.jsx("p",{className:"text-xs text-cc-success",children:"Saved!"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{type:"button",onClick:M,disabled:p||Object.values(m).every(i=>!i.trim()),className:`px-3 py-1.5 rounded-md text-xs font-medium transition-colors ${p||Object.values(m).every(i=>!i.trim())?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-primary-btn hover:bg-cc-primary-btn-hover text-white cursor-pointer"}`,children:p?"Saving...":"Save"}),a.configured&&e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",onClick:F,className:"px-3 py-1.5 rounded-md text-xs font-medium bg-cc-hover text-cc-fg hover:bg-cc-active transition-colors cursor-pointer",children:a.enabled?"Disable":"Enable"}),e.jsx("button",{type:"button",onClick:R,className:"px-3 py-1.5 rounded-md text-xs font-medium text-cc-error hover:bg-cc-error/10 transition-colors cursor-pointer",children:"Remove"})]})]})]})]})}const ct=[{id:"general",label:"General"},{id:"connectivity",label:"Connectivity"},{id:"authentication",label:"Authentication"},{id:"notifications",label:"Notifications"},{id:"providers",label:"Providers"},{id:"gemini",label:"Gemini"},{id:"hank-chat",label:"Hank Chat"},{id:"email",label:"Email"},{id:"calendar",label:"Calendar"},{id:"updates",label:"Updates"},{id:"appearance",label:"Appearance"},{id:"environments",label:"Environments"},{id:"federation",label:"Federation"},{id:"backup",label:"Backup"}];function Ds(){const[a,f]=s.useState(!1),[C,v]=s.useState(!0);s.useEffect(()=>{(async()=>{var x;try{const p=await((x=navigator.serviceWorker)==null?void 0:x.ready);if(p){const b=await p.pushManager.getSubscription();f(!!b)}}catch{}v(!1)})()},[]);const m=async()=>{v(!0);try{if(a)await Os(),f(!1);else{if(Notification.permission!=="granted"&&await Notification.requestPermission()!=="granted"){v(!1);return}const x=await Ls();f(!!x)}}catch(x){console.error("[push] Toggle failed:",x)}v(!1)};return typeof Notification>"u"||!("serviceWorker"in navigator)?null:e.jsxs("button",{type:"button",onClick:m,disabled:C,className:"w-full flex items-center justify-between px-3 py-3 min-h-[44px] rounded-lg text-sm bg-cc-hover text-cc-fg hover:bg-cc-active transition-colors cursor-pointer disabled:opacity-50",children:[e.jsx("span",{children:"Push Notifications (Agent Alerts)"}),e.jsx("span",{className:"text-xs text-cc-muted",children:C?"...":a?"On":"Off"})]})}function I({id:a,title:f,status:C,defaultOpen:v=!1,forceOpen:m,sectionRef:x,children:p}){const[b,g]=s.useState(()=>{const j=localStorage.getItem(`settings-section-${a}`);return j!==null?j==="true":v});s.useEffect(()=>{m&&(g(!0),localStorage.setItem(`settings-section-${a}`,"true"))},[m,a]);const A=()=>{const j=!b;g(j),localStorage.setItem(`settings-section-${a}`,String(j))};return e.jsxs("section",{id:a,ref:x,children:[e.jsxs("button",{type:"button",onClick:A,className:"w-full flex items-center gap-2 group cursor-pointer mb-2 py-1 -mx-1 px-1 rounded-lg hover:bg-cc-hover/50 transition-colors","aria-expanded":b,children:[e.jsx("svg",{viewBox:"0 0 16 16",fill:"currentColor",className:`w-3 h-3 text-cc-muted transition-transform duration-150 ${b?"rotate-90":""}`,children:e.jsx("path",{d:"M6 4l4 4-4 4"})}),e.jsx("h2",{className:"text-sm font-semibold text-cc-fg",children:f}),!b&&C&&e.jsx("span",{className:"text-[11px] text-cc-muted ml-auto",children:C})]}),b&&e.jsx("div",{className:"space-y-3 ml-0.5",children:p})]})}function Js({embedded:a=!1}){const[f,C]=s.useState(""),[v,m]=s.useState("claude-sonnet-4-6"),[x,p]=s.useState(!1),[b,g]=s.useState(!1),[A,j]=s.useState(!1),[d,y]=s.useState(!1),[T,M]=s.useState(!0),[R,F]=s.useState(!1),[i,E]=s.useState(""),[V,$]=s.useState(!1),z=k(t=>t.darkMode),G=k(t=>t.toggleDarkMode),L=k(t=>t.diffBase),le=k(t=>t.setDiffBase),de=k(t=>t.notificationSound),ye=k(t=>t.toggleNotificationSound),ue=k(t=>t.notificationDesktop),r=k(t=>t.setNotificationDesktop),h=k(t=>t.updateInfo),se=k(t=>t.setUpdateInfo),ss=k(t=>t.setUpdateOverlayActive),cs=k(t=>t.setEditorTabEnabled),as=typeof Notification<"u",[W,ce]=s.useState("stable"),[me,je]=s.useState(!1),[Ne,at]=s.useState(!1),[ke,rt]=s.useState(!1),[nt,ae]=s.useState(""),[ot,xe]=s.useState(""),[_,we]=s.useState("gemini-live"),[it,lt]=s.useState(""),[Se,Ce]=s.useState(!0),[pe,Ae]=s.useState(!1),[Ee,Pe]=s.useState(!0),[Ue,Ie]=s.useState(!1),[J,Te]=s.useState(""),[dt,ut]=s.useState("general"),[P,mt]=s.useState(null),[Gs,_s]=s.useState(!1),[Bs,zs]=s.useState(!1),[Ws,Ys]=s.useState(null),[Z,xt]=s.useState(""),[he,pt]=s.useState(!1),[X,ht]=s.useState(""),[re,gt]=s.useState(!1),[Oe,ft]=s.useState(!1),[rs,Le]=s.useState(!1),[bt,vt]=s.useState(""),[ns,yt]=s.useState(!1),[os,jt]=s.useState(!1),[l,Nt]=s.useState(null),[u,kt]=s.useState(null),[ne,wt]=s.useState(""),[ee,St]=s.useState(!1),[Re,Fe]=s.useState("Kore"),[is,Ct]=s.useState("Kore"),[Ve,$e]=s.useState(""),[ls,At]=s.useState(""),[Ke,De]=s.useState(""),[ds,Et]=s.useState(""),[us,Pt]=s.useState(!1),[He,Ut]=s.useState(!1),[ms,Me]=s.useState(!1),[It,Tt]=s.useState(""),[ge,xs]=s.useState([]),[ps,Ot]=s.useState(!1),[Lt,Ge]=s.useState(""),[Rt,Ft]=s.useState(""),[K,Vt]=s.useState(null),[hs,_e]=s.useState(!1),[N,O]=s.useState({name:"",email:"",imapHost:"",imapPort:"993",imapSecure:!0,smtpHost:"",smtpPort:"465",smtpSecure:!0,authUser:"",authPass:""}),[$t,Kt]=s.useState(null),[oe,Be]=s.useState(null),[fe,gs]=s.useState([]),[fs,Dt]=s.useState(!1),[Ht,be]=s.useState(""),[Mt,Gt]=s.useState(""),[Y,_t]=s.useState(null),[Bt,ze]=s.useState(!1),[w,q]=s.useState({name:"",provider:"google",serverUrl:"",authUser:"",authPass:""}),[zt,Wt]=s.useState(null),[Q,We]=s.useState(null),[te,Yt]=s.useState(null),[Ye,qt]=s.useState(!1),[H,Qt]=s.useState(null),[ve,bs]=s.useState(0),[qe,Jt]=s.useState(!1),[Qe,Zt]=s.useState(!1),[vs,Xt]=s.useState(!1),es=s.useRef(null),Je=s.useRef({});s.useEffect(()=>{const t=es.current;if(!t)return;const c=new IntersectionObserver(n=>{var D;let S=null;for(const ie of n)ie.isIntersecting&&(!S||ie.boundingClientRect.top<S.boundingClientRect.top)&&(S=ie);(D=S==null?void 0:S.target)!=null&&D.id&&ut(S.target.id)},{root:t,rootMargin:"-10% 0px -70% 0px",threshold:0});for(const n of ct){const S=Je.current[n.id];S&&c.observe(S)}return()=>c.disconnect()},[T]);const ts=s.useCallback(t=>{ut(t),mt(t),setTimeout(()=>mt(null),100),requestAnimationFrame(()=>{const c=Je.current[t];c&&c.scrollIntoView({behavior:"smooth",block:"start"})})},[]);s.useEffect(()=>{o.getSettings().then(t=>{g(t.anthropicApiKeyConfigured),j(t.anthropicApiKeyConfigured),typeof t.openrouterApiKeyConfigured=="boolean"&&y(t.openrouterApiKeyConfigured),o.getProviders().then(c=>{c.some(n=>n.configured&&n.enabled)&&g(!0)}).catch(()=>{}),pt(t.claudeCodeOAuthTokenConfigured),gt(t.openaiApiKeyConfigured),t.claudeCliAuth&&Nt(t.claudeCliAuth),t.codexCliAuth&&kt(t.codexCliAuth),St(t.geminiApiKeyConfigured),t.geminiVoice&&(Fe(t.geminiVoice),Ct(t.geminiVoice)),typeof t.assistantName=="string"&&($e(t.assistantName),At(t.assistantName)),typeof t.userName=="string"&&(De(t.userName),Et(t.userName)),m(t.anthropicModel||"claude-sonnet-4-6"),p(t.editorTabEnabled),cs(t.editorTabEnabled),typeof t.aiValidationEnabled=="boolean"&&Ae(t.aiValidationEnabled),typeof t.aiValidationAutoApprove=="boolean"&&Pe(t.aiValidationAutoApprove),typeof t.aiValidationAutoDeny=="boolean"&&Ie(t.aiValidationAutoDeny),typeof t.hankChatProvider=="string"&&we(t.hankChatProvider),typeof t.hankChatModel=="string"&&lt(t.hankChatModel),typeof t.hankChatAvatarEnabled=="boolean"&&Ce(t.hankChatAvatarEnabled),(t.updateChannel==="stable"||t.updateChannel==="prerelease")&&ce(t.updateChannel),typeof t.dockerAutoUpdate=="boolean"&&je(t.dockerAutoUpdate),typeof t.publicUrl=="string"&&(Te(t.publicUrl),k.getState().setPublicUrl(t.publicUrl))}).catch(t=>E(t instanceof Error?t.message:String(t))).finally(()=>M(!1)),o.getAuthToken().then(t=>Yt(t.token)).catch(()=>{}),Ze(),et()},[]);function Ze(){Ot(!0),fetch("/api/email-accounts",{headers:{...B()}}).then(t=>t.json()).then(t=>xs(t)).catch(()=>{}).finally(()=>Ot(!1))}function B(){const t=localStorage.getItem("auth_token")||sessionStorage.getItem("auth_token");return t?{Authorization:`Bearer ${t}`}:{}}function Xe(){O({name:"",email:"",imapHost:"",imapPort:"993",imapSecure:!0,smtpHost:"",smtpPort:"465",smtpSecure:!0,authUser:"",authPass:""}),Vt(null),_e(!1)}async function ys(){Ge("");const t={name:N.name.trim(),email:N.email.trim(),imap:{host:N.imapHost.trim(),port:parseInt(N.imapPort)||993,secure:N.imapSecure},smtp:{host:N.smtpHost.trim(),port:parseInt(N.smtpPort)||465,secure:N.smtpSecure},auth:{user:N.authUser.trim(),pass:N.authPass}};if(!t.name||!t.email||!t.imap.host||!t.smtp.host||!t.auth.user||!t.auth.pass){Ge("All fields are required.");return}try{const c=K?`/api/email-accounts/${K.id}`:"/api/email-accounts",S=await fetch(c,{method:K?"PUT":"POST",headers:{"Content-Type":"application/json",...B()},body:JSON.stringify(t)});if(!S.ok){const D=await S.json().catch(()=>({}));throw new Error(D.error||"Failed")}Ft(K?"Account updated.":"Account added."),setTimeout(()=>Ft(""),2e3),Xe(),Ze()}catch(c){Ge(c instanceof Error?c.message:String(c))}}async function js(t){if(confirm("Delete this email account?"))try{await fetch(`/api/email-accounts/${t}`,{method:"DELETE",headers:B()}),Ze()}catch{}}async function Ns(t){Kt(t),Be(null);try{const n=await(await fetch(`/api/email-accounts/${t}/test`,{method:"POST",headers:B()})).json();Be({id:t,ok:n.ok,message:n.ok?n.message:n.error})}catch(c){Be({id:t,ok:!1,message:c instanceof Error?c.message:"Connection failed"})}finally{Kt(null)}}function ks(t){Vt(t),O({name:t.name,email:t.email,imapHost:t.imap.host,imapPort:String(t.imap.port),imapSecure:t.imap.secure,smtpHost:t.smtp.host,smtpPort:String(t.smtp.port),smtpSecure:t.smtp.secure,authUser:t.auth.user,authPass:""}),_e(!0)}function et(){Dt(!0),fetch("/api/calendar-accounts",{headers:{...B()}}).then(t=>t.json()).then(t=>gs(t)).catch(()=>{}).finally(()=>Dt(!1))}function tt(){q({name:"",provider:"google",serverUrl:"",authUser:"",authPass:""}),_t(null),ze(!1)}function ws(t){const c={google:{serverUrl:"https://apidata.googleusercontent.com/caldav/v2/"},icloud:{serverUrl:"https://caldav.icloud.com/"},outlook:{serverUrl:"https://outlook.office365.com/caldav/"},caldav:{serverUrl:""}};q(n=>{var S;return{...n,provider:t,serverUrl:((S=c[t])==null?void 0:S.serverUrl)||""}})}async function Ss(){be("");const t=w.provider==="outlook"?"caldav":w.provider,c={name:w.name.trim(),provider:t,serverUrl:w.serverUrl.trim(),auth:{user:w.authUser.trim(),pass:w.authPass}};if(!c.name||!c.auth.user||!c.auth.pass){be("Name, user and password are required.");return}if((w.provider==="caldav"||w.provider==="outlook")&&!c.serverUrl){be("Server URL is required for custom CalDAV.");return}try{const n=Y?`/api/calendar-accounts/${Y.id}`:"/api/calendar-accounts",D=await fetch(n,{method:Y?"PUT":"POST",headers:{"Content-Type":"application/json",...B()},body:JSON.stringify(c)});if(!D.ok){const ie=await D.json().catch(()=>({}));throw new Error(ie.error||"Failed")}Gt(Y?"Account updated.":"Account added."),setTimeout(()=>Gt(""),2e3),tt(),et()}catch(n){be(n instanceof Error?n.message:String(n))}}async function Cs(t){if(confirm("Delete this calendar account?"))try{await fetch(`/api/calendar-accounts/${t}`,{method:"DELETE",headers:B()}),et()}catch{}}async function As(t){Wt(t),We(null);try{const n=await(await fetch(`/api/calendar-accounts/${t}/test`,{method:"POST",headers:B()})).json();We({id:t,ok:n.ok,message:n.ok?n.message:n.error,calendars:n.calendars})}catch(c){We({id:t,ok:!1,message:c instanceof Error?c.message:"Connection failed"})}finally{Wt(null)}}function Es(t){_t(t),q({name:t.name,provider:t.provider,serverUrl:t.serverUrl,authUser:t.auth.user,authPass:""}),ze(!0)}async function st(t){const c=t==="aiValidationEnabled"?pe:t==="aiValidationAutoApprove"?Ee:Ue,n=!c;t==="aiValidationEnabled"?Ae(n):t==="aiValidationAutoApprove"?Pe(n):Ie(n);try{await o.updateSettings({[t]:n})}catch{t==="aiValidationEnabled"?Ae(c):t==="aiValidationAutoApprove"?Pe(c):Ie(c)}}async function Ps(){at(!0),ae(""),xe("");try{const t=await o.forceCheckForUpdate();se(t),t.updateAvailable&&t.latestVersion?ae(`Update v${t.latestVersion} is available.`):ae("You are up to date.")}catch(t){xe(t instanceof Error?t.message:String(t))}finally{at(!1)}}async function Us(){rt(!0),ae(""),xe("");try{localStorage.setItem("heyhank_docker_prompt_pending","1");const t=await o.triggerUpdate();ae(t.message),ss(!0)}catch(t){localStorage.removeItem("heyhank_docker_prompt_pending"),xe(t instanceof Error?t.message:String(t)),rt(!1)}}const U=s.useCallback(t=>c=>{Je.current[t]=c},[]);return e.jsxs("div",{className:`${a?"h-full":"h-[100dvh]"} bg-cc-bg text-cc-fg font-sans-ui antialiased flex flex-col`,children:[e.jsx("div",{className:"shrink-0 max-w-5xl w-full mx-auto px-4 sm:px-8 pt-6 sm:pt-10",children:e.jsxs("div",{className:"flex items-start justify-between gap-3 mb-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-semibold text-cc-fg",children:"Settings"}),e.jsx("p",{className:"mt-1 text-sm text-cc-muted",children:"Configure API access, notifications, appearance, and workspace defaults."})]}),!a&&e.jsx("button",{onClick:()=>{const t=k.getState().currentSessionId;t?Is(t):Ts()},className:"px-3 py-2.5 min-h-[44px] rounded-lg text-sm text-cc-muted hover:text-cc-fg hover:bg-cc-hover transition-colors cursor-pointer",children:"Back"})]})}),e.jsx("div",{className:"sm:hidden shrink-0 border-b border-cc-border",children:e.jsx("nav",{className:"flex gap-1 px-4 py-2 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden","aria-label":"Settings categories",children:ct.map(t=>e.jsx("button",{type:"button",onClick:()=>ts(t.id),className:`shrink-0 px-3 py-2 min-h-[44px] rounded-lg text-sm font-medium transition-colors cursor-pointer ${dt===t.id?"text-cc-primary bg-cc-primary/8":"text-cc-muted hover:text-cc-fg hover:bg-cc-hover"}`,children:t.label},t.id))})}),e.jsxs("div",{className:"flex-1 min-h-0 flex max-w-5xl w-full mx-auto",children:[e.jsx("nav",{className:"hidden sm:flex flex-col gap-0.5 w-44 shrink-0 pt-2 pr-6 pl-8 sticky top-0 self-start max-h-[calc(100vh-3rem)] overflow-y-auto","aria-label":"Settings categories",children:ct.map(t=>e.jsx("button",{type:"button",onClick:()=>ts(t.id),className:`text-left px-3 py-2 min-h-[44px] rounded-lg text-sm font-medium transition-colors cursor-pointer ${dt===t.id?"text-cc-primary bg-cc-primary/8":"text-cc-muted hover:text-cc-fg hover:bg-cc-hover"}`,children:t.label},t.id))}),e.jsx("div",{ref:es,className:"flex-1 min-w-0 overflow-y-auto px-4 sm:px-8 sm:pl-0 pb-safe",children:e.jsxs("div",{className:"space-y-10 py-4 sm:py-2",children:[e.jsxs(I,{id:"general",title:"General",defaultOpen:!0,forceOpen:P==="general",sectionRef:U("general"),children:[e.jsxs("button",{type:"button",onClick:G,className:"w-full flex items-center justify-between px-3 py-3 min-h-[44px] rounded-lg text-sm bg-cc-hover text-cc-fg hover:bg-cc-active transition-colors cursor-pointer",children:[e.jsx("span",{children:"Theme"}),e.jsx("span",{className:"text-xs text-cc-muted",children:z?"Dark":"Light"})]}),e.jsxs("button",{type:"button",onClick:()=>p(t=>!t),className:"w-full flex items-center justify-between px-3 py-3 min-h-[44px] rounded-lg text-sm bg-cc-hover text-cc-fg hover:bg-cc-active transition-colors cursor-pointer",children:[e.jsx("span",{children:"Enable Editor tab (CodeMirror)"}),e.jsx("span",{className:"text-xs text-cc-muted",children:x?"On":"Off"})]}),e.jsx("p",{className:"text-xs text-cc-muted px-1",children:"Shows a simple in-app file editor in the session tabs."}),e.jsxs("button",{type:"button",onClick:()=>le(L==="last-commit"?"default-branch":"last-commit"),className:"w-full flex items-center justify-between px-3 py-3 min-h-[44px] rounded-lg text-sm bg-cc-hover text-cc-fg hover:bg-cc-active transition-colors cursor-pointer",children:[e.jsx("span",{children:"Diff compare against"}),e.jsx("span",{className:"text-xs text-cc-muted",children:L==="last-commit"?"Last commit (HEAD)":"Default branch"})]}),e.jsx("p",{className:"text-xs text-cc-muted px-1",children:"Last commit shows only uncommitted changes. Default branch shows all changes since diverging from main."})]}),e.jsxs(I,{id:"connectivity",title:"Connectivity",status:J||"Not configured",forceOpen:P==="connectivity",sectionRef:U("connectivity"),children:[e.jsx("p",{className:"text-xs text-cc-muted",children:"HeyHank needs an externally-reachable HTTPS URL for mobile access (PWA), webhooks (GitHub), and OAuth callbacks."}),e.jsxs("div",{className:"bg-cc-hover/50 rounded-lg p-3 space-y-3",children:[e.jsx("h3",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider",children:"Public URL"}),e.jsx("p",{className:"text-[11px] text-cc-muted",children:"If you have your own domain with a reverse proxy (nginx, Caddy), enter the URL here."}),e.jsx("input",{id:"public-url",type:"url","aria-label":"Public URL",value:J,onChange:t=>Te(t.target.value),placeholder:"https://your-domain.example.com",className:"w-full px-3 py-2.5 min-h-[44px] text-sm bg-cc-bg rounded-lg border border-cc-border text-cc-fg placeholder:text-cc-muted focus:outline-none focus:ring-1 focus:ring-cc-primary font-mono-code"}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("button",{type:"button",onClick:async()=>{F(!0),E("");try{const t=await o.updateSettings({publicUrl:J.trim()});Te(t.publicUrl),k.getState().setPublicUrl(t.publicUrl),$(!0),setTimeout(()=>$(!1),1800)}catch(t){E(t instanceof Error?t.message:String(t))}finally{F(!1)}},disabled:R,className:"px-3 py-1.5 rounded-lg text-xs font-medium bg-cc-primary text-white hover:opacity-90 transition-opacity disabled:opacity-50 cursor-pointer",children:R?"Saving...":V?"Saved!":"Save"}),J&&e.jsxs("span",{className:"text-[11px] text-green-500 font-medium",children:["Active: ",J]}),!J&&e.jsxs("span",{className:"text-[11px] text-cc-muted",children:["Not set — using ",typeof window<"u"?window.location.origin:"http://localhost:3456"]})]})]}),e.jsxs("div",{className:"bg-cc-hover/50 rounded-lg p-3 space-y-3",children:[e.jsx("h3",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider",children:"Tailscale (no domain needed)"}),e.jsx("p",{className:"text-[11px] text-cc-muted",children:"No domain? Tailscale Funnel gives you a free HTTPS URL automatically. Install Tailscale on your server, then enable Funnel here."}),e.jsx(Hs,{})]}),e.jsxs("div",{className:"bg-cc-hover/50 rounded-lg p-3 space-y-2",children:[e.jsx("h3",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider",children:"What the Public URL enables"}),e.jsxs("ul",{className:"text-[11px] text-cc-muted space-y-1 list-disc pl-4",children:[e.jsx("li",{children:"Mobile access — install HeyHank as PWA on your phone"}),e.jsx("li",{children:"Webhooks — receive events from GitHub and other services"}),e.jsx("li",{children:"OAuth callbacks — authenticate with external services"}),e.jsx("li",{children:"Federation — connect multiple HeyHank instances"})]})]})]}),e.jsxs(I,{id:"authentication",title:"Authentication",status:te?"Token set":"No token",forceOpen:P==="authentication",sectionRef:U("authentication"),children:[e.jsx("p",{className:"text-xs text-cc-muted",children:"Use the auth token or QR code to connect additional devices (e.g. mobile over Tailscale)."}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1.5",children:"Auth Token"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"flex-1 px-3 py-2.5 min-h-[44px] text-sm bg-cc-bg rounded-lg text-cc-fg font-mono-code select-all break-all flex items-center",children:te?Ye?te:"••••••••••••••••":e.jsx("span",{className:"text-cc-muted",children:"Loading..."})}),e.jsx("button",{type:"button",onClick:()=>qt(t=>!t),className:"px-3 py-2.5 min-h-[44px] rounded-lg text-sm bg-cc-hover hover:bg-cc-active text-cc-fg transition-colors cursor-pointer",title:Ye?"Hide token":"Show token",children:Ye?"Hide":"Show"}),e.jsx("button",{type:"button",onClick:()=>{te&&navigator.clipboard.writeText(te).then(()=>{Xt(!0),setTimeout(()=>Xt(!1),1500)})},disabled:!te,className:"px-3 py-2.5 min-h-[44px] rounded-lg text-sm bg-cc-hover hover:bg-cc-active text-cc-fg transition-colors cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed",title:"Copy token to clipboard",children:vs?"Copied":"Copy"})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1.5",children:"Mobile Login QR"}),H&&H.length>0?e.jsxs("div",{className:"space-y-3",children:[H.length>1&&e.jsx("div",{className:"flex gap-1",children:H.map((t,c)=>e.jsx("button",{type:"button",onClick:()=>bs(c),className:`px-3 py-1.5 rounded-md text-xs font-medium transition-colors cursor-pointer ${c===ve?"bg-cc-primary text-white":"bg-cc-hover text-cc-muted hover:text-cc-fg"}`,children:t.label},t.label))}),e.jsx("div",{className:"inline-block rounded-lg bg-white p-2",children:e.jsx("img",{src:H[ve].qrDataUrl,alt:`QR code for ${H[ve].label} login`,className:"w-48 h-48"})}),e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-bg text-sm font-mono-code text-cc-fg break-all select-all",children:H[ve].url}),e.jsx("p",{className:"text-xs text-cc-muted",children:"Scan with your phone's camera app — it will open the URL and auto-authenticate."})]}):H&&H.length===0?e.jsx("p",{className:"text-xs text-cc-muted",children:"No remote addresses detected (LAN or Tailscale). Connect to a network to generate a QR code."}):e.jsx("button",{type:"button",onClick:async()=>{Jt(!0);try{const t=await o.getAuthQr();Qt(t.qrCodes)}catch{}finally{Jt(!1)}},disabled:qe,className:`px-3 py-2 min-h-[44px] rounded-lg text-sm font-medium transition-colors ${qe?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-hover hover:bg-cc-active text-cc-fg cursor-pointer"}`,children:qe?"Generating...":"Show QR Code"})]}),e.jsxs("div",{className:"pt-2",children:[e.jsx("button",{type:"button",onClick:async()=>{if(confirm("Regenerate auth token? All existing sessions on other devices will be signed out.")){Zt(!0);try{const t=await o.regenerateAuthToken();Yt(t.token),qt(!0),Qt(null)}catch{}finally{Zt(!1)}}},disabled:Qe,className:`px-3 py-2 min-h-[44px] rounded-lg text-sm font-medium transition-colors ${Qe?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-error/10 hover:bg-cc-error/20 text-cc-error cursor-pointer"}`,children:Qe?"Regenerating...":"Regenerate Token"}),e.jsx("p",{className:"mt-1.5 text-xs text-cc-muted",children:"Creates a new token. All other signed-in devices will need to re-authenticate."})]})]}),e.jsxs(I,{id:"notifications",title:"Notifications",status:de?"Sound on":"Sound off",forceOpen:P==="notifications",sectionRef:U("notifications"),children:[e.jsxs("button",{type:"button",onClick:ye,className:"w-full flex items-center justify-between px-3 py-3 min-h-[44px] rounded-lg text-sm bg-cc-hover text-cc-fg hover:bg-cc-active transition-colors cursor-pointer",children:[e.jsx("span",{children:"Sound"}),e.jsx("span",{className:"text-xs text-cc-muted",children:de?"On":"Off"})]}),as&&e.jsxs("button",{type:"button",onClick:async()=>{if(ue)r(!1);else{if(Notification.permission!=="granted"&&await Notification.requestPermission()!=="granted")return;r(!0)}},className:"w-full flex items-center justify-between px-3 py-3 min-h-[44px] rounded-lg text-sm bg-cc-hover text-cc-fg hover:bg-cc-active transition-colors cursor-pointer",children:[e.jsx("span",{children:"Desktop Alerts"}),e.jsx("span",{className:"text-xs text-cc-muted",children:ue?"On":"Off"})]}),e.jsx(Ds,{})]}),e.jsxs(I,{id:"providers",title:"Providers",defaultOpen:!0,forceOpen:P==="providers",status:b?"Configured":"Not configured",sectionRef:U("providers"),children:[e.jsxs("p",{className:"text-xs text-cc-muted",children:["Connect AI backends to power your agent sessions. Configure CLI backends (Claude Code, Codex) and additional model providers for Claude Code's ",e.jsx("code",{className:"font-mono-code bg-cc-code-bg px-1 py-0.5 rounded text-cc-code-fg",children:"--provider"})," flag."]}),e.jsxs("div",{className:"space-y-3 p-4 bg-cc-bg rounded-lg border border-cc-border",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-medium text-cc-fg",children:"Claude Code"}),(l==null?void 0:l.cliVersion)&&e.jsx("p",{className:"text-xs text-cc-muted mt-0.5",children:l.cliVersion})]}),((l==null?void 0:l.authenticated)??(l==null?void 0:l.loggedIn))||he?e.jsx("span",{className:"px-2 py-0.5 text-xs rounded-full bg-cc-success/15 text-cc-success border border-cc-success/20",children:"Authenticated"}):e.jsx("span",{className:"px-2 py-0.5 text-xs rounded-full bg-cc-error/15 text-cc-error border border-cc-error/20",children:"Not configured"})]}),((l==null?void 0:l.authenticated)??(l==null?void 0:l.loggedIn))&&e.jsxs("div",{className:"px-3 py-2 rounded-lg bg-cc-success/5 border border-cc-success/10 text-xs text-cc-muted",children:[l.method==="cli_login"&&e.jsxs(e.Fragment,{children:["Authenticated via ",e.jsx("strong",{className:"text-cc-fg",children:"CLI login"}),". Sessions authenticate automatically."]}),l.method==="env_api_key"&&e.jsxs(e.Fragment,{children:["Authenticated via ",e.jsx("strong",{className:"text-cc-fg",children:"ANTHROPIC_API_KEY"})," env var."]}),l.method==="env_oauth"&&e.jsxs(e.Fragment,{children:["Authenticated via ",e.jsx("strong",{className:"text-cc-fg",children:"CLAUDE_CODE_OAUTH_TOKEN"})," env var."]}),l.method==="env_auth_token"&&e.jsxs(e.Fragment,{children:["Authenticated via ",e.jsx("strong",{className:"text-cc-fg",children:"ANTHROPIC_AUTH_TOKEN"})," env var."]})]}),!((l==null?void 0:l.authenticated)??(l==null?void 0:l.loggedIn))&&!he&&e.jsxs("div",{className:"px-3 py-2.5 rounded-lg bg-cc-primary/5 border border-cc-primary/15 text-xs text-cc-muted space-y-1.5",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"CLI Login:"})," Run ",e.jsx("code",{className:"font-mono-code bg-cc-code-bg px-1 py-0.5 rounded text-cc-code-fg",children:"claude login"})," on the server."]}),e.jsxs("p",{children:[e.jsx("strong",{children:"OAuth Token:"})," Paste a token from ",e.jsx("code",{className:"font-mono-code bg-cc-code-bg px-1 py-0.5 rounded text-cc-code-fg",children:"claude setup-token"})," below."]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("label",{className:"block text-xs text-cc-muted",htmlFor:"claude-code-token",children:["OAuth Token ",(l==null?void 0:l.authenticated)??(l==null?void 0:l.loggedIn)?"(optional)":""]}),e.jsx("input",{id:"claude-code-token",type:"password",value:he&&!ns&&!Z?"••••••••••••••••":Z,onChange:t=>xt(t.target.value),onFocus:()=>yt(!0),onBlur:()=>yt(!1),placeholder:he?"Enter a new token to replace":"Paste token from claude setup-token",className:"w-full px-3 py-2 text-sm bg-cc-input-bg rounded-lg text-cc-fg placeholder:text-cc-muted focus:outline-none focus:ring-1 focus:ring-cc-primary/40 transition-shadow"})]})]}),e.jsxs("div",{className:"space-y-3 p-4 bg-cc-bg rounded-lg border border-cc-border",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-medium text-cc-fg",children:"OpenAI Codex"}),(u==null?void 0:u.cliVersion)&&e.jsx("p",{className:"text-xs text-cc-muted mt-0.5",children:u.cliVersion})]}),((u==null?void 0:u.authenticated)??(u==null?void 0:u.loggedIn))||re?e.jsx("span",{className:"px-2 py-0.5 text-xs rounded-full bg-cc-success/15 text-cc-success border border-cc-success/20",children:"Authenticated"}):e.jsx("span",{className:"px-2 py-0.5 text-xs rounded-full bg-cc-error/15 text-cc-error border border-cc-error/20",children:"Not configured"})]}),((u==null?void 0:u.authenticated)??(u==null?void 0:u.loggedIn))&&e.jsxs("div",{className:"px-3 py-2 rounded-lg bg-cc-success/5 border border-cc-success/10 text-xs text-cc-muted",children:[u.method==="cli_login"&&e.jsxs(e.Fragment,{children:["Authenticated via ",e.jsx("strong",{className:"text-cc-fg",children:"device login"}),"."]}),u.method==="env_api_key"&&e.jsxs(e.Fragment,{children:["Authenticated via ",e.jsx("strong",{className:"text-cc-fg",children:"OPENAI_API_KEY"})," env var."]})]}),!((u==null?void 0:u.authenticated)??(u==null?void 0:u.loggedIn))&&!re&&e.jsxs("div",{className:"px-3 py-2.5 rounded-lg bg-cc-primary/5 border border-cc-primary/15 text-xs text-cc-muted space-y-1.5",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Device Login:"})," Run ",e.jsx("code",{className:"font-mono-code bg-cc-code-bg px-1 py-0.5 rounded text-cc-code-fg",children:"codex --login"})," on the server."]}),e.jsxs("p",{children:[e.jsx("strong",{children:"API Key:"})," Enter your key below from ",e.jsx("a",{href:"https://platform.openai.com/api-keys",target:"_blank",rel:"noopener noreferrer",className:"text-cc-primary hover:underline",children:"platform.openai.com"}),"."]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("label",{className:"block text-xs text-cc-muted",htmlFor:"openai-api-key",children:["API Key ",(u==null?void 0:u.authenticated)??(u==null?void 0:u.loggedIn)?"(optional)":""]}),e.jsx("input",{id:"openai-api-key",type:"password",value:re&&!os&&!X?"••••••••••••••••":X,onChange:t=>ht(t.target.value),onFocus:()=>jt(!0),onBlur:()=>jt(!1),placeholder:re?"Enter a new key to replace":"sk-...",className:"w-full px-3 py-2 text-sm bg-cc-input-bg rounded-lg text-cc-fg placeholder:text-cc-muted focus:outline-none focus:ring-1 focus:ring-cc-primary/40 transition-shadow"})]})]}),bt&&e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-error/10 border border-cc-error/20 text-xs text-cc-error",children:bt}),rs&&e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-success/10 border border-cc-success/20 text-xs text-cc-success",children:"Provider settings saved."}),e.jsx("button",{type:"button",disabled:Oe||!Z.trim()&&!X.trim(),onClick:async()=>{ft(!0),vt(""),Le(!1);try{const t={};Z.trim()&&(t.claudeCodeOAuthToken=Z.trim()),X.trim()&&(t.openaiApiKey=X.trim());const c=await o.updateSettings(t);pt(c.claudeCodeOAuthTokenConfigured),gt(c.openaiApiKeyConfigured),c.claudeCliAuth&&Nt(c.claudeCliAuth),c.codexCliAuth&&kt(c.codexCliAuth),xt(""),ht(""),Le(!0),setTimeout(()=>Le(!1),1800)}catch(t){vt(t instanceof Error?t.message:String(t))}finally{ft(!1)}},className:`px-4 py-2 min-h-[44px] rounded-lg text-sm font-medium transition-colors ${Oe||!Z.trim()&&!X.trim()?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-primary-btn hover:bg-cc-primary-btn-hover text-white cursor-pointer"}`,children:Oe?"Saving...":"Save CLI Backend Settings"}),e.jsxs("details",{className:"border-t border-cc-border pt-4 group",children:[e.jsxs("summary",{className:"flex items-center justify-between cursor-pointer list-none",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-medium text-cc-fg",children:"Additional Providers"}),e.jsxs("p",{className:"text-xs text-cc-muted mt-0.5",children:["Configure model providers for Claude Code's ",e.jsx("code",{className:"font-mono-code bg-cc-code-bg px-1 py-0.5 rounded text-cc-code-fg text-[10px]",children:"--provider"})," flag."]})]}),e.jsx("svg",{viewBox:"0 0 16 16",fill:"currentColor",className:"w-4 h-4 text-cc-muted transition-transform group-open:rotate-180",children:e.jsx("path",{fillRule:"evenodd",d:"M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z"})})]}),e.jsx("div",{className:"mt-4",children:e.jsx($s,{})})]})]}),e.jsxs(I,{id:"gemini",title:"Gemini",status:ee?"Key set":"Not configured",forceOpen:P==="gemini",sectionRef:U("gemini"),children:[e.jsxs("p",{className:"text-xs text-cc-muted",children:["Configure Gemini Live for voice chat. Get an API key from"," ",e.jsx("a",{href:"https://aistudio.google.com/apikey",target:"_blank",rel:"noopener noreferrer",className:"text-cc-primary hover:underline",children:"Google AI Studio"}),"."]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"gemini-api-key",children:"Gemini API Key"}),e.jsx("input",{id:"gemini-api-key",type:"password",value:ee&&!us&&!ne?"••••••••••••••••":ne,onChange:t=>wt(t.target.value),onFocus:()=>Pt(!0),onBlur:()=>Pt(!1),placeholder:ee?"Enter a new key to replace":"AIza...",className:"w-full px-3 py-2.5 min-h-[44px] text-sm bg-cc-bg rounded-lg text-cc-fg placeholder:text-cc-muted focus:outline-none focus:ring-1 focus:ring-cc-primary/40 transition-shadow"}),e.jsx("p",{className:"text-xs text-cc-muted",children:ee?"Gemini API key configured":"Gemini API key not configured"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"assistant-name",children:"Assistant Name"}),e.jsx("input",{id:"assistant-name",type:"text",value:Ve,onChange:t=>$e(t.target.value),placeholder:"e.g. Jarvis, Friday, Max",className:"w-full px-3 py-2.5 min-h-[44px] text-sm bg-cc-bg rounded-lg text-cc-fg placeholder:text-cc-muted focus:outline-none focus:ring-1 focus:ring-cc-primary/40 transition-shadow"}),e.jsx("p",{className:"text-xs text-cc-muted",children:"Give your voice assistant a custom name. Leave empty for default."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"user-name",children:"Your Name"}),e.jsx("input",{id:"user-name",type:"text",value:Ke,onChange:t=>De(t.target.value),placeholder:"e.g. Markus",className:"w-full px-3 py-2.5 min-h-[44px] text-sm bg-cc-bg rounded-lg text-cc-fg placeholder:text-cc-muted focus:outline-none focus:ring-1 focus:ring-cc-primary/40 transition-shadow"}),e.jsx("p",{className:"text-xs text-cc-muted",children:"Your name so Gemini knows who it's talking to."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"gemini-voice",children:"Voice"}),e.jsxs("select",{id:"gemini-voice",value:Re,onChange:t=>Fe(t.target.value),className:"w-full px-3 py-2.5 min-h-[44px] text-sm bg-cc-bg rounded-lg text-cc-fg focus:outline-none focus:ring-1 focus:ring-cc-primary/40 transition-shadow",children:[e.jsx("option",{value:"Kore",children:"Kore (female, firm)"}),e.jsx("option",{value:"Puck",children:"Puck (male, playful)"}),e.jsx("option",{value:"Charon",children:"Charon (male, deep)"}),e.jsx("option",{value:"Fenrir",children:"Fenrir (male, bold)"}),e.jsx("option",{value:"Aoede",children:"Aoede (female, bright)"}),e.jsx("option",{value:"Leda",children:"Leda (female, gentle)"}),e.jsx("option",{value:"Orus",children:"Orus (male, clear)"}),e.jsx("option",{value:"Zephyr",children:"Zephyr (neutral, calm)"})]})]}),It&&e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-error/10 border border-cc-error/20 text-xs text-cc-error",children:It}),ms&&e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-success/10 border border-cc-success/20 text-xs text-cc-success",children:"Gemini settings saved."}),e.jsx("button",{type:"button",disabled:He||!ne.trim()&&Re===is&&Ve===ls&&Ke===ds,onClick:async()=>{Ut(!0),Tt(""),Me(!1);try{const t={};ne.trim()&&(t.geminiApiKey=ne.trim()),t.assistantName=Ve,t.userName=Ke,t.geminiVoice=Re;const c=await o.updateSettings(t);St(c.geminiApiKeyConfigured),c.geminiVoice&&(Fe(c.geminiVoice),Ct(c.geminiVoice)),typeof c.assistantName=="string"&&($e(c.assistantName),At(c.assistantName)),typeof c.userName=="string"&&(De(c.userName),Et(c.userName)),wt(""),Me(!0),setTimeout(()=>Me(!1),1800)}catch(t){Tt(t instanceof Error?t.message:String(t))}finally{Ut(!1)}},className:`px-4 py-2 min-h-[44px] rounded-lg text-sm font-medium transition-colors ${He?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-primary-btn hover:bg-cc-primary-btn-hover text-white cursor-pointer"}`,children:He?"Saving...":"Save Gemini Settings"})]}),e.jsxs(I,{id:"email",title:"Email Accounts",status:`${ge.length} account${ge.length!==1?"s":""}`,forceOpen:P==="email",sectionRef:U("email"),children:[e.jsx("p",{className:"text-xs text-cc-muted",children:"Configure IMAP/SMTP email accounts for the voice assistant. Gemini can read, search, and send emails on your behalf."}),ps?e.jsx("p",{className:"text-xs text-cc-muted",children:"Loading accounts..."}):ge.length===0?e.jsx("p",{className:"text-xs text-cc-muted",children:"No email accounts configured."}):e.jsx("div",{className:"space-y-2",children:ge.map(t=>e.jsxs("div",{className:"flex items-center justify-between px-3 py-2.5 bg-cc-bg rounded-lg",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"text-sm font-medium text-cc-fg truncate",children:t.name}),e.jsx("div",{className:"text-xs text-cc-muted truncate",children:t.email}),e.jsxs("div",{className:"text-xs text-cc-muted",children:["IMAP: ",t.imap.host,":",t.imap.port," | SMTP: ",t.smtp.host,":",t.smtp.port]}),(oe==null?void 0:oe.id)===t.id&&e.jsx("div",{className:`text-xs mt-1 ${oe.ok?"text-cc-success":"text-cc-error"}`,children:oe.message})]}),e.jsxs("div",{className:"flex gap-1.5 ml-2 shrink-0",children:[e.jsx("button",{type:"button",onClick:()=>Ns(t.id),disabled:$t===t.id,className:"px-2 py-1 text-xs rounded bg-cc-hover text-cc-fg hover:bg-cc-border transition-colors",children:$t===t.id?"...":"Test"}),e.jsx("button",{type:"button",onClick:()=>ks(t),className:"px-2 py-1 text-xs rounded bg-cc-hover text-cc-fg hover:bg-cc-border transition-colors",children:"Edit"}),e.jsx("button",{type:"button",onClick:()=>js(t.id),className:"px-2 py-1 text-xs rounded bg-cc-error/10 text-cc-error hover:bg-cc-error/20 transition-colors",children:"Delete"})]})]},t.id))}),hs?e.jsxs("div",{className:"space-y-3 p-4 bg-cc-bg rounded-lg border border-cc-border",children:[e.jsx("h3",{className:"text-sm font-medium text-cc-fg",children:K?`Edit: ${K.name}`:"Add Email Account"}),!K&&e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-xs text-cc-muted font-medium",children:"Quick presets:"}),e.jsx("div",{className:"flex gap-2 flex-wrap",children:[{label:"Gmail",imap:"imap.gmail.com",smtp:"smtp.gmail.com",imapPort:"993",smtpPort:"465",info:`1. Go to myaccount.google.com
1
+ import{r as s,b as o,j as e,u as k,n as Is,a as Ts}from"./index-C6Q5UQHD.js";import{unsubscribeFromPush as Os,subscribeToPush as Ls}from"./sw-register-BBYuk-kw.js";function Rs(){const[a,f]=s.useState(null),[C,v]=s.useState(""),[m,x]=s.useState([]),[p,b]=s.useState([]),[g,A]=s.useState(!0),[j,d]=s.useState(!1),[y,T]=s.useState(""),[M,R]=s.useState(""),[F,i]=s.useState(""),[E,V]=s.useState(""),[$,z]=s.useState(""),G=s.useCallback(async()=>{try{const[r,h,se]=await Promise.all([o.getFederationIdentity(),o.getFederationNodes(),o.getFederationRemoteSessions()]);f(r),v(r.name),x(h.nodes),b(se.sessions)}catch{}A(!1)},[]);s.useEffect(()=>{G()},[G]),s.useEffect(()=>{const r=setInterval(G,1e4);return()=>clearInterval(r)},[G]);const L=(r,h=!1)=>{h?(T(r),R("")):(R(r),T("")),setTimeout(()=>{T(""),R("")},4e3)},le=async()=>{if(C.trim()){d(!0);try{await o.updateFederationIdentity(C.trim()),L("Node name saved")}catch(r){L(r instanceof Error?r.message:"Failed to save",!0)}d(!1)}},de=async()=>{if(!F.trim()||!E.trim()){L("URL and shared secret are required",!0);return}d(!0);try{await o.addFederationNode({url:F.trim(),secret:E.trim(),name:$.trim()}),i(""),V(""),z(""),L("Node added, connecting..."),setTimeout(G,2e3)}catch(r){L(r instanceof Error?r.message:"Failed to add node",!0)}d(!1)},ye=async r=>{try{await o.removeFederationNode(r),L("Node removed"),G()}catch(h){L(h instanceof Error?h.message:"Failed to remove",!0)}},ue=async r=>{try{const h=await o.testFederationNode(r);L(h.connected?"Connection OK":"Not connected")}catch(h){L(h instanceof Error?h.message:"Test failed",!0)}};return g?e.jsx("div",{className:"text-sm text-cc-muted",children:"Loading federation..."}):e.jsxs("div",{className:"space-y-5",children:[y&&e.jsx("div",{className:"text-sm text-cc-error bg-cc-error/5 border border-cc-error/20 rounded-lg px-3 py-2",children:y}),M&&e.jsx("div",{className:"text-sm text-cc-success bg-cc-success/5 border border-cc-success/20 rounded-lg px-3 py-2",children:M}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider mb-2",children:"This Node"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{type:"text",value:C,onChange:r=>v(r.target.value),onKeyDown:r=>r.key==="Enter"&&le(),placeholder:"Node name",className:"flex-1 px-3 py-2 text-sm rounded-lg bg-cc-hover border border-cc-border text-cc-fg outline-none focus:border-cc-primary/50"}),e.jsx("button",{onClick:le,disabled:j,className:"px-3 py-2 text-sm rounded-lg bg-cc-hover border border-cc-border text-cc-fg hover:bg-cc-active transition-colors cursor-pointer disabled:opacity-50",children:"Save"})]}),a&&e.jsxs("p",{className:"text-[10px] text-cc-muted/60 font-mono mt-1 break-all",children:["ID: ",a.nodeId]})]}),e.jsxs("div",{children:[e.jsx("h4",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider mb-2",children:"Add Node"}),e.jsx("p",{className:"text-xs text-cc-muted mb-2",children:"Enter the URL and shared secret of a remote HeyHank instance."}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("input",{type:"url",value:F,onChange:r=>i(r.target.value),placeholder:"https://other-hank.example.com",className:"w-full px-3 py-2 text-sm rounded-lg bg-cc-hover border border-cc-border text-cc-fg outline-none focus:border-cc-primary/50"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("input",{type:"password",value:E,onChange:r=>V(r.target.value),placeholder:"Shared secret",className:"flex-1 px-3 py-2 text-sm rounded-lg bg-cc-hover border border-cc-border text-cc-fg outline-none focus:border-cc-primary/50"}),e.jsx("input",{type:"text",value:$,onChange:r=>z(r.target.value),placeholder:"Name (optional)",className:"flex-1 px-3 py-2 text-sm rounded-lg bg-cc-hover border border-cc-border text-cc-fg outline-none focus:border-cc-primary/50"})]}),e.jsx("button",{onClick:de,disabled:j,className:"w-full px-3 py-2.5 text-sm font-medium rounded-lg bg-cc-primary/10 border border-cc-primary/30 text-cc-primary hover:bg-cc-primary/15 transition-colors cursor-pointer disabled:opacity-50",children:"Connect Node"})]})]}),e.jsxs("div",{children:[e.jsxs("h4",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider mb-2",children:["Connected Nodes (",m.length,")"]}),m.length===0?e.jsx("p",{className:"text-xs text-cc-muted/50",children:"No nodes configured."}):e.jsx("div",{className:"space-y-2",children:m.map(r=>e.jsxs("div",{className:"border border-cc-border/60 rounded-lg p-3 bg-cc-card/50",children:[e.jsxs("div",{className:"flex items-center justify-between mb-1",children:[e.jsxs("span",{className:"text-sm font-medium text-cc-fg flex items-center gap-1.5",children:[e.jsx("span",{className:`w-2 h-2 rounded-full shrink-0 ${r.connected?"bg-cc-success shadow-[0_0_6px_rgba(74,222,128,0.4)]":"bg-cc-error/60"}`}),r.remoteName||r.name||"Unknown"]}),e.jsxs("span",{className:"text-[10px] text-cc-muted",children:[r.connected?"Connected":"Offline"," · ",r.sessionCount," sessions"]})]}),e.jsx("p",{className:"text-[10px] text-cc-muted/60 break-all mb-2",children:r.url}),e.jsxs("div",{className:"flex gap-1.5",children:[e.jsx("button",{onClick:()=>ue(r.id),className:"px-2 py-1 text-[11px] rounded bg-cc-hover border border-cc-border text-cc-fg hover:bg-cc-active transition-colors cursor-pointer",children:"Test"}),e.jsx("button",{onClick:()=>ye(r.id),className:"px-2 py-1 text-[11px] rounded bg-cc-hover border border-cc-error/20 text-cc-error hover:bg-cc-error/5 transition-colors cursor-pointer",children:"Remove"})]})]},r.id))})]}),p.length>0&&e.jsxs("div",{children:[e.jsxs("h4",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider mb-2",children:["Remote Sessions (",p.length,")"]}),e.jsx("div",{className:"space-y-1.5",children:p.map(r=>e.jsxs("div",{className:"border border-cc-border/40 rounded-lg px-3 py-2 bg-cc-card/30",children:[e.jsxs("div",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"text-xs font-medium text-cc-fg truncate",children:r.name||r.sessionId.slice(0,8)}),e.jsx("span",{className:"text-[9px] font-semibold px-1.5 py-0.5 rounded bg-cc-primary/15 text-cc-primary leading-none shrink-0",children:r.nodeName})]}),e.jsxs("p",{className:"text-[10px] text-cc-muted/60 truncate mt-0.5",children:[r.model||""," · ",r.cwd||r.sessionId]})]},`${r.nodeId}:${r.sessionId}`))})]})]})}const Fs={cloud:"Cloud Providers",gateway:"Gateways & Proxies",local:"Local / Self-Hosted",custom:"Custom"},Vs=["cloud","gateway","local","custom"];function $s(){const[a,f]=s.useState([]),[C,v]=s.useState(!0),[m,x]=s.useState(null),[p,b]=s.useState(""),g=s.useCallback(()=>{o.getProviders().then(f).catch(()=>{}).finally(()=>v(!1))},[]);if(s.useEffect(()=>{g()},[g]),C)return e.jsx("p",{className:"text-xs text-cc-muted",children:"Loading providers..."});const A=p?a.filter(d=>d.name.toLowerCase().includes(p.toLowerCase())||d.description.toLowerCase().includes(p.toLowerCase())):a,j=Vs.map(d=>({category:d,label:Fs[d]||d,items:A.filter(y=>y.category===d)})).filter(d=>d.items.length>0);return e.jsxs("div",{className:"space-y-4",children:[a.length>10&&e.jsx("input",{type:"text",value:p,onChange:d=>b(d.target.value),placeholder:"Search providers...",className:"w-full px-3 py-2 text-sm bg-cc-input-bg rounded-lg text-cc-fg placeholder:text-cc-muted focus:outline-none focus:ring-1 focus:ring-cc-primary/40 transition-shadow"}),j.map(d=>e.jsxs("div",{children:[e.jsx("h4",{className:"text-xs font-medium text-cc-muted uppercase tracking-wide mb-2",children:d.label}),e.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 gap-2",children:d.items.map(y=>e.jsx(Ks,{provider:y,expanded:m===y.id,onToggle:()=>x(m===y.id?null:y.id),onUpdate:g},y.id))})]},d.category))]})}function Ks({provider:a,expanded:f,onToggle:C,onUpdate:v}){const[m,x]=s.useState({}),[p,b]=s.useState(!1),[g,A]=s.useState(!1),[j,d]=s.useState(""),[y,T]=s.useState(!1);s.useEffect(()=>{f&&!y&&o.getProvider(a.id).then(i=>{var V;const E={};for(const $ of a.envFields)!$.secret&&((V=i.envValues)!=null&&V[$.key])&&(E[$.key]=i.envValues[$.key]);x(E),T(!0)}).catch(()=>{})},[f,y,a.id,a.envFields]);const M=async()=>{b(!0),d(""),A(!1);try{const i={};for(const[E,V]of Object.entries(m))V.trim()&&(i[E]=V.trim());await o.updateProvider(a.id,{enabled:!0,envValues:i}),A(!0),setTimeout(()=>A(!1),2e3),x({}),T(!1),v()}catch(i){d(i instanceof Error?i.message:String(i))}finally{b(!1)}},R=async()=>{try{await o.deleteProvider(a.id),x({}),T(!1),v()}catch{}},F=async()=>{try{await o.updateProvider(a.id,{enabled:!a.enabled}),v()}catch{}};return e.jsxs("div",{className:`rounded-lg border transition-colors ${a.configured&&a.enabled?"border-cc-success/30 bg-cc-success/5":a.configured?"border-cc-warning/30 bg-cc-warning/5":"border-cc-border bg-cc-bg"}`,children:[e.jsxs("button",{type:"button",onClick:C,className:"w-full flex items-center justify-between px-3 py-2.5 cursor-pointer text-left",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm font-medium text-cc-fg truncate",children:a.name}),a.configured&&a.enabled&&e.jsx("span",{className:"shrink-0 w-1.5 h-1.5 rounded-full bg-cc-success"}),a.configured&&!a.enabled&&e.jsx("span",{className:"shrink-0 w-1.5 h-1.5 rounded-full bg-cc-warning"})]}),e.jsx("p",{className:"text-[11px] text-cc-muted truncate",children:a.description})]}),e.jsx("svg",{viewBox:"0 0 16 16",fill:"currentColor",className:`shrink-0 w-3.5 h-3.5 text-cc-muted transition-transform ${f?"rotate-180":""}`,children:e.jsx("path",{fillRule:"evenodd",d:"M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z"})})]}),f&&e.jsxs("div",{className:"px-3 pb-3 space-y-3 border-t border-cc-border/50 pt-3",children:[a.envFields.map(i=>e.jsxs("div",{className:"space-y-1",children:[e.jsxs("label",{className:"block text-xs text-cc-muted",htmlFor:`prov-${a.id}-${i.key}`,children:[i.label,i.required&&e.jsx("span",{className:"text-cc-error ml-0.5",children:"*"}),a.envConfigured[i.key]&&i.secret&&e.jsx("span",{className:"ml-1 text-cc-success",children:"(configured)"})]}),e.jsx("input",{id:`prov-${a.id}-${i.key}`,type:i.secret?"password":"text",value:m[i.key]??"",onChange:E=>x({...m,[i.key]:E.target.value}),placeholder:a.envConfigured[i.key]&&i.secret?"Enter new value to replace":i.placeholder||"",className:"w-full px-2.5 py-1.5 text-sm bg-cc-input-bg rounded-md text-cc-fg placeholder:text-cc-muted/50 focus:outline-none focus:ring-1 focus:ring-cc-primary/40"})]},i.key)),a.docsUrl&&e.jsxs("a",{href:a.docsUrl,target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1 text-[11px] text-cc-primary hover:underline",children:["Documentation",e.jsx("svg",{viewBox:"0 0 16 16",fill:"currentColor",className:"w-3 h-3",children:e.jsx("path",{d:"M3.75 2a.75.75 0 0 0 0 1.5h5.69L2.22 10.72a.75.75 0 1 0 1.06 1.06L10.5 4.56v5.69a.75.75 0 0 0 1.5 0V2.75a.75.75 0 0 0-.75-.75H3.75Z"})})]}),j&&e.jsx("p",{className:"text-xs text-cc-error",children:j}),g&&e.jsx("p",{className:"text-xs text-cc-success",children:"Saved!"}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{type:"button",onClick:M,disabled:p||Object.values(m).every(i=>!i.trim()),className:`px-3 py-1.5 rounded-md text-xs font-medium transition-colors ${p||Object.values(m).every(i=>!i.trim())?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-primary-btn hover:bg-cc-primary-btn-hover text-white cursor-pointer"}`,children:p?"Saving...":"Save"}),a.configured&&e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",onClick:F,className:"px-3 py-1.5 rounded-md text-xs font-medium bg-cc-hover text-cc-fg hover:bg-cc-active transition-colors cursor-pointer",children:a.enabled?"Disable":"Enable"}),e.jsx("button",{type:"button",onClick:R,className:"px-3 py-1.5 rounded-md text-xs font-medium text-cc-error hover:bg-cc-error/10 transition-colors cursor-pointer",children:"Remove"})]})]})]})]})}const ct=[{id:"general",label:"General"},{id:"connectivity",label:"Connectivity"},{id:"authentication",label:"Authentication"},{id:"notifications",label:"Notifications"},{id:"providers",label:"Providers"},{id:"gemini",label:"Gemini"},{id:"hank-chat",label:"Hank Chat"},{id:"email",label:"Email"},{id:"calendar",label:"Calendar"},{id:"updates",label:"Updates"},{id:"appearance",label:"Appearance"},{id:"environments",label:"Environments"},{id:"federation",label:"Federation"},{id:"backup",label:"Backup"}];function Ds(){const[a,f]=s.useState(!1),[C,v]=s.useState(!0);s.useEffect(()=>{(async()=>{var x;try{const p=await((x=navigator.serviceWorker)==null?void 0:x.ready);if(p){const b=await p.pushManager.getSubscription();f(!!b)}}catch{}v(!1)})()},[]);const m=async()=>{v(!0);try{if(a)await Os(),f(!1);else{if(Notification.permission!=="granted"&&await Notification.requestPermission()!=="granted"){v(!1);return}const x=await Ls();f(!!x)}}catch(x){console.error("[push] Toggle failed:",x)}v(!1)};return typeof Notification>"u"||!("serviceWorker"in navigator)?null:e.jsxs("button",{type:"button",onClick:m,disabled:C,className:"w-full flex items-center justify-between px-3 py-3 min-h-[44px] rounded-lg text-sm bg-cc-hover text-cc-fg hover:bg-cc-active transition-colors cursor-pointer disabled:opacity-50",children:[e.jsx("span",{children:"Push Notifications (Agent Alerts)"}),e.jsx("span",{className:"text-xs text-cc-muted",children:C?"...":a?"On":"Off"})]})}function I({id:a,title:f,status:C,defaultOpen:v=!1,forceOpen:m,sectionRef:x,children:p}){const[b,g]=s.useState(()=>{const j=localStorage.getItem(`settings-section-${a}`);return j!==null?j==="true":v});s.useEffect(()=>{m&&(g(!0),localStorage.setItem(`settings-section-${a}`,"true"))},[m,a]);const A=()=>{const j=!b;g(j),localStorage.setItem(`settings-section-${a}`,String(j))};return e.jsxs("section",{id:a,ref:x,children:[e.jsxs("button",{type:"button",onClick:A,className:"w-full flex items-center gap-2 group cursor-pointer mb-2 py-1 -mx-1 px-1 rounded-lg hover:bg-cc-hover/50 transition-colors","aria-expanded":b,children:[e.jsx("svg",{viewBox:"0 0 16 16",fill:"currentColor",className:`w-3 h-3 text-cc-muted transition-transform duration-150 ${b?"rotate-90":""}`,children:e.jsx("path",{d:"M6 4l4 4-4 4"})}),e.jsx("h2",{className:"text-sm font-semibold text-cc-fg",children:f}),!b&&C&&e.jsx("span",{className:"text-[11px] text-cc-muted ml-auto",children:C})]}),b&&e.jsx("div",{className:"space-y-3 ml-0.5",children:p})]})}function Js({embedded:a=!1}){const[f,C]=s.useState(""),[v,m]=s.useState("claude-sonnet-4-6"),[x,p]=s.useState(!1),[b,g]=s.useState(!1),[A,j]=s.useState(!1),[d,y]=s.useState(!1),[T,M]=s.useState(!0),[R,F]=s.useState(!1),[i,E]=s.useState(""),[V,$]=s.useState(!1),z=k(t=>t.darkMode),G=k(t=>t.toggleDarkMode),L=k(t=>t.diffBase),le=k(t=>t.setDiffBase),de=k(t=>t.notificationSound),ye=k(t=>t.toggleNotificationSound),ue=k(t=>t.notificationDesktop),r=k(t=>t.setNotificationDesktop),h=k(t=>t.updateInfo),se=k(t=>t.setUpdateInfo),ss=k(t=>t.setUpdateOverlayActive),cs=k(t=>t.setEditorTabEnabled),as=typeof Notification<"u",[W,ce]=s.useState("stable"),[me,je]=s.useState(!1),[Ne,at]=s.useState(!1),[ke,rt]=s.useState(!1),[nt,ae]=s.useState(""),[ot,xe]=s.useState(""),[_,we]=s.useState("gemini-live"),[it,lt]=s.useState(""),[Se,Ce]=s.useState(!0),[pe,Ae]=s.useState(!1),[Ee,Pe]=s.useState(!0),[Ue,Ie]=s.useState(!1),[J,Te]=s.useState(""),[dt,ut]=s.useState("general"),[P,mt]=s.useState(null),[Gs,_s]=s.useState(!1),[Bs,zs]=s.useState(!1),[Ws,Ys]=s.useState(null),[Z,xt]=s.useState(""),[he,pt]=s.useState(!1),[X,ht]=s.useState(""),[re,gt]=s.useState(!1),[Oe,ft]=s.useState(!1),[rs,Le]=s.useState(!1),[bt,vt]=s.useState(""),[ns,yt]=s.useState(!1),[os,jt]=s.useState(!1),[l,Nt]=s.useState(null),[u,kt]=s.useState(null),[ne,wt]=s.useState(""),[ee,St]=s.useState(!1),[Re,Fe]=s.useState("Kore"),[is,Ct]=s.useState("Kore"),[Ve,$e]=s.useState(""),[ls,At]=s.useState(""),[Ke,De]=s.useState(""),[ds,Et]=s.useState(""),[us,Pt]=s.useState(!1),[He,Ut]=s.useState(!1),[ms,Me]=s.useState(!1),[It,Tt]=s.useState(""),[ge,xs]=s.useState([]),[ps,Ot]=s.useState(!1),[Lt,Ge]=s.useState(""),[Rt,Ft]=s.useState(""),[K,Vt]=s.useState(null),[hs,_e]=s.useState(!1),[N,O]=s.useState({name:"",email:"",imapHost:"",imapPort:"993",imapSecure:!0,smtpHost:"",smtpPort:"465",smtpSecure:!0,authUser:"",authPass:""}),[$t,Kt]=s.useState(null),[oe,Be]=s.useState(null),[fe,gs]=s.useState([]),[fs,Dt]=s.useState(!1),[Ht,be]=s.useState(""),[Mt,Gt]=s.useState(""),[Y,_t]=s.useState(null),[Bt,ze]=s.useState(!1),[w,q]=s.useState({name:"",provider:"google",serverUrl:"",authUser:"",authPass:""}),[zt,Wt]=s.useState(null),[Q,We]=s.useState(null),[te,Yt]=s.useState(null),[Ye,qt]=s.useState(!1),[H,Qt]=s.useState(null),[ve,bs]=s.useState(0),[qe,Jt]=s.useState(!1),[Qe,Zt]=s.useState(!1),[vs,Xt]=s.useState(!1),es=s.useRef(null),Je=s.useRef({});s.useEffect(()=>{const t=es.current;if(!t)return;const c=new IntersectionObserver(n=>{var D;let S=null;for(const ie of n)ie.isIntersecting&&(!S||ie.boundingClientRect.top<S.boundingClientRect.top)&&(S=ie);(D=S==null?void 0:S.target)!=null&&D.id&&ut(S.target.id)},{root:t,rootMargin:"-10% 0px -70% 0px",threshold:0});for(const n of ct){const S=Je.current[n.id];S&&c.observe(S)}return()=>c.disconnect()},[T]);const ts=s.useCallback(t=>{ut(t),mt(t),setTimeout(()=>mt(null),100),requestAnimationFrame(()=>{const c=Je.current[t];c&&c.scrollIntoView({behavior:"smooth",block:"start"})})},[]);s.useEffect(()=>{o.getSettings().then(t=>{g(t.anthropicApiKeyConfigured),j(t.anthropicApiKeyConfigured),typeof t.openrouterApiKeyConfigured=="boolean"&&y(t.openrouterApiKeyConfigured),o.getProviders().then(c=>{c.some(n=>n.configured&&n.enabled)&&g(!0)}).catch(()=>{}),pt(t.claudeCodeOAuthTokenConfigured),gt(t.openaiApiKeyConfigured),t.claudeCliAuth&&Nt(t.claudeCliAuth),t.codexCliAuth&&kt(t.codexCliAuth),St(t.geminiApiKeyConfigured),t.geminiVoice&&(Fe(t.geminiVoice),Ct(t.geminiVoice)),typeof t.assistantName=="string"&&($e(t.assistantName),At(t.assistantName)),typeof t.userName=="string"&&(De(t.userName),Et(t.userName)),m(t.anthropicModel||"claude-sonnet-4-6"),p(t.editorTabEnabled),cs(t.editorTabEnabled),typeof t.aiValidationEnabled=="boolean"&&Ae(t.aiValidationEnabled),typeof t.aiValidationAutoApprove=="boolean"&&Pe(t.aiValidationAutoApprove),typeof t.aiValidationAutoDeny=="boolean"&&Ie(t.aiValidationAutoDeny),typeof t.hankChatProvider=="string"&&we(t.hankChatProvider),typeof t.hankChatModel=="string"&&lt(t.hankChatModel),typeof t.hankChatAvatarEnabled=="boolean"&&Ce(t.hankChatAvatarEnabled),(t.updateChannel==="stable"||t.updateChannel==="prerelease")&&ce(t.updateChannel),typeof t.dockerAutoUpdate=="boolean"&&je(t.dockerAutoUpdate),typeof t.publicUrl=="string"&&(Te(t.publicUrl),k.getState().setPublicUrl(t.publicUrl))}).catch(t=>E(t instanceof Error?t.message:String(t))).finally(()=>M(!1)),o.getAuthToken().then(t=>Yt(t.token)).catch(()=>{}),Ze(),et()},[]);function Ze(){Ot(!0),fetch("/api/email-accounts",{headers:{...B()}}).then(t=>t.json()).then(t=>xs(t)).catch(()=>{}).finally(()=>Ot(!1))}function B(){const t=localStorage.getItem("auth_token")||sessionStorage.getItem("auth_token");return t?{Authorization:`Bearer ${t}`}:{}}function Xe(){O({name:"",email:"",imapHost:"",imapPort:"993",imapSecure:!0,smtpHost:"",smtpPort:"465",smtpSecure:!0,authUser:"",authPass:""}),Vt(null),_e(!1)}async function ys(){Ge("");const t={name:N.name.trim(),email:N.email.trim(),imap:{host:N.imapHost.trim(),port:parseInt(N.imapPort)||993,secure:N.imapSecure},smtp:{host:N.smtpHost.trim(),port:parseInt(N.smtpPort)||465,secure:N.smtpSecure},auth:{user:N.authUser.trim(),pass:N.authPass}};if(!t.name||!t.email||!t.imap.host||!t.smtp.host||!t.auth.user||!t.auth.pass){Ge("All fields are required.");return}try{const c=K?`/api/email-accounts/${K.id}`:"/api/email-accounts",S=await fetch(c,{method:K?"PUT":"POST",headers:{"Content-Type":"application/json",...B()},body:JSON.stringify(t)});if(!S.ok){const D=await S.json().catch(()=>({}));throw new Error(D.error||"Failed")}Ft(K?"Account updated.":"Account added."),setTimeout(()=>Ft(""),2e3),Xe(),Ze()}catch(c){Ge(c instanceof Error?c.message:String(c))}}async function js(t){if(confirm("Delete this email account?"))try{await fetch(`/api/email-accounts/${t}`,{method:"DELETE",headers:B()}),Ze()}catch{}}async function Ns(t){Kt(t),Be(null);try{const n=await(await fetch(`/api/email-accounts/${t}/test`,{method:"POST",headers:B()})).json();Be({id:t,ok:n.ok,message:n.ok?n.message:n.error})}catch(c){Be({id:t,ok:!1,message:c instanceof Error?c.message:"Connection failed"})}finally{Kt(null)}}function ks(t){Vt(t),O({name:t.name,email:t.email,imapHost:t.imap.host,imapPort:String(t.imap.port),imapSecure:t.imap.secure,smtpHost:t.smtp.host,smtpPort:String(t.smtp.port),smtpSecure:t.smtp.secure,authUser:t.auth.user,authPass:""}),_e(!0)}function et(){Dt(!0),fetch("/api/calendar-accounts",{headers:{...B()}}).then(t=>t.json()).then(t=>gs(t)).catch(()=>{}).finally(()=>Dt(!1))}function tt(){q({name:"",provider:"google",serverUrl:"",authUser:"",authPass:""}),_t(null),ze(!1)}function ws(t){const c={google:{serverUrl:"https://apidata.googleusercontent.com/caldav/v2/"},icloud:{serverUrl:"https://caldav.icloud.com/"},outlook:{serverUrl:"https://outlook.office365.com/caldav/"},caldav:{serverUrl:""}};q(n=>{var S;return{...n,provider:t,serverUrl:((S=c[t])==null?void 0:S.serverUrl)||""}})}async function Ss(){be("");const t=w.provider==="outlook"?"caldav":w.provider,c={name:w.name.trim(),provider:t,serverUrl:w.serverUrl.trim(),auth:{user:w.authUser.trim(),pass:w.authPass}};if(!c.name||!c.auth.user||!c.auth.pass){be("Name, user and password are required.");return}if((w.provider==="caldav"||w.provider==="outlook")&&!c.serverUrl){be("Server URL is required for custom CalDAV.");return}try{const n=Y?`/api/calendar-accounts/${Y.id}`:"/api/calendar-accounts",D=await fetch(n,{method:Y?"PUT":"POST",headers:{"Content-Type":"application/json",...B()},body:JSON.stringify(c)});if(!D.ok){const ie=await D.json().catch(()=>({}));throw new Error(ie.error||"Failed")}Gt(Y?"Account updated.":"Account added."),setTimeout(()=>Gt(""),2e3),tt(),et()}catch(n){be(n instanceof Error?n.message:String(n))}}async function Cs(t){if(confirm("Delete this calendar account?"))try{await fetch(`/api/calendar-accounts/${t}`,{method:"DELETE",headers:B()}),et()}catch{}}async function As(t){Wt(t),We(null);try{const n=await(await fetch(`/api/calendar-accounts/${t}/test`,{method:"POST",headers:B()})).json();We({id:t,ok:n.ok,message:n.ok?n.message:n.error,calendars:n.calendars})}catch(c){We({id:t,ok:!1,message:c instanceof Error?c.message:"Connection failed"})}finally{Wt(null)}}function Es(t){_t(t),q({name:t.name,provider:t.provider,serverUrl:t.serverUrl,authUser:t.auth.user,authPass:""}),ze(!0)}async function st(t){const c=t==="aiValidationEnabled"?pe:t==="aiValidationAutoApprove"?Ee:Ue,n=!c;t==="aiValidationEnabled"?Ae(n):t==="aiValidationAutoApprove"?Pe(n):Ie(n);try{await o.updateSettings({[t]:n})}catch{t==="aiValidationEnabled"?Ae(c):t==="aiValidationAutoApprove"?Pe(c):Ie(c)}}async function Ps(){at(!0),ae(""),xe("");try{const t=await o.forceCheckForUpdate();se(t),t.updateAvailable&&t.latestVersion?ae(`Update v${t.latestVersion} is available.`):ae("You are up to date.")}catch(t){xe(t instanceof Error?t.message:String(t))}finally{at(!1)}}async function Us(){rt(!0),ae(""),xe("");try{localStorage.setItem("heyhank_docker_prompt_pending","1");const t=await o.triggerUpdate();ae(t.message),ss(!0)}catch(t){localStorage.removeItem("heyhank_docker_prompt_pending"),xe(t instanceof Error?t.message:String(t)),rt(!1)}}const U=s.useCallback(t=>c=>{Je.current[t]=c},[]);return e.jsxs("div",{className:`${a?"h-full":"h-[100dvh]"} bg-cc-bg text-cc-fg font-sans-ui antialiased flex flex-col`,children:[e.jsx("div",{className:"shrink-0 max-w-5xl w-full mx-auto px-4 sm:px-8 pt-6 sm:pt-10",children:e.jsxs("div",{className:"flex items-start justify-between gap-3 mb-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-semibold text-cc-fg",children:"Settings"}),e.jsx("p",{className:"mt-1 text-sm text-cc-muted",children:"Configure API access, notifications, appearance, and workspace defaults."})]}),!a&&e.jsx("button",{onClick:()=>{const t=k.getState().currentSessionId;t?Is(t):Ts()},className:"px-3 py-2.5 min-h-[44px] rounded-lg text-sm text-cc-muted hover:text-cc-fg hover:bg-cc-hover transition-colors cursor-pointer",children:"Back"})]})}),e.jsx("div",{className:"sm:hidden shrink-0 border-b border-cc-border",children:e.jsx("nav",{className:"flex gap-1 px-4 py-2 overflow-x-auto [scrollbar-width:none] [&::-webkit-scrollbar]:hidden","aria-label":"Settings categories",children:ct.map(t=>e.jsx("button",{type:"button",onClick:()=>ts(t.id),className:`shrink-0 px-3 py-2 min-h-[44px] rounded-lg text-sm font-medium transition-colors cursor-pointer ${dt===t.id?"text-cc-primary bg-cc-primary/8":"text-cc-muted hover:text-cc-fg hover:bg-cc-hover"}`,children:t.label},t.id))})}),e.jsxs("div",{className:"flex-1 min-h-0 flex max-w-5xl w-full mx-auto",children:[e.jsx("nav",{className:"hidden sm:flex flex-col gap-0.5 w-44 shrink-0 pt-2 pr-6 pl-8 sticky top-0 self-start max-h-[calc(100vh-3rem)] overflow-y-auto","aria-label":"Settings categories",children:ct.map(t=>e.jsx("button",{type:"button",onClick:()=>ts(t.id),className:`text-left px-3 py-2 min-h-[44px] rounded-lg text-sm font-medium transition-colors cursor-pointer ${dt===t.id?"text-cc-primary bg-cc-primary/8":"text-cc-muted hover:text-cc-fg hover:bg-cc-hover"}`,children:t.label},t.id))}),e.jsx("div",{ref:es,className:"flex-1 min-w-0 overflow-y-auto px-4 sm:px-8 sm:pl-0 pb-safe",children:e.jsxs("div",{className:"space-y-10 py-4 sm:py-2",children:[e.jsxs(I,{id:"general",title:"General",defaultOpen:!0,forceOpen:P==="general",sectionRef:U("general"),children:[e.jsxs("button",{type:"button",onClick:G,className:"w-full flex items-center justify-between px-3 py-3 min-h-[44px] rounded-lg text-sm bg-cc-hover text-cc-fg hover:bg-cc-active transition-colors cursor-pointer",children:[e.jsx("span",{children:"Theme"}),e.jsx("span",{className:"text-xs text-cc-muted",children:z?"Dark":"Light"})]}),e.jsxs("button",{type:"button",onClick:()=>p(t=>!t),className:"w-full flex items-center justify-between px-3 py-3 min-h-[44px] rounded-lg text-sm bg-cc-hover text-cc-fg hover:bg-cc-active transition-colors cursor-pointer",children:[e.jsx("span",{children:"Enable Editor tab (CodeMirror)"}),e.jsx("span",{className:"text-xs text-cc-muted",children:x?"On":"Off"})]}),e.jsx("p",{className:"text-xs text-cc-muted px-1",children:"Shows a simple in-app file editor in the session tabs."}),e.jsxs("button",{type:"button",onClick:()=>le(L==="last-commit"?"default-branch":"last-commit"),className:"w-full flex items-center justify-between px-3 py-3 min-h-[44px] rounded-lg text-sm bg-cc-hover text-cc-fg hover:bg-cc-active transition-colors cursor-pointer",children:[e.jsx("span",{children:"Diff compare against"}),e.jsx("span",{className:"text-xs text-cc-muted",children:L==="last-commit"?"Last commit (HEAD)":"Default branch"})]}),e.jsx("p",{className:"text-xs text-cc-muted px-1",children:"Last commit shows only uncommitted changes. Default branch shows all changes since diverging from main."})]}),e.jsxs(I,{id:"connectivity",title:"Connectivity",status:J||"Not configured",forceOpen:P==="connectivity",sectionRef:U("connectivity"),children:[e.jsx("p",{className:"text-xs text-cc-muted",children:"HeyHank needs an externally-reachable HTTPS URL for mobile access (PWA), webhooks (GitHub), and OAuth callbacks."}),e.jsxs("div",{className:"bg-cc-hover/50 rounded-lg p-3 space-y-3",children:[e.jsx("h3",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider",children:"Public URL"}),e.jsx("p",{className:"text-[11px] text-cc-muted",children:"If you have your own domain with a reverse proxy (nginx, Caddy), enter the URL here."}),e.jsx("input",{id:"public-url",type:"url","aria-label":"Public URL",value:J,onChange:t=>Te(t.target.value),placeholder:"https://your-domain.example.com",className:"w-full px-3 py-2.5 min-h-[44px] text-sm bg-cc-bg rounded-lg border border-cc-border text-cc-fg placeholder:text-cc-muted focus:outline-none focus:ring-1 focus:ring-cc-primary font-mono-code"}),e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("button",{type:"button",onClick:async()=>{F(!0),E("");try{const t=await o.updateSettings({publicUrl:J.trim()});Te(t.publicUrl),k.getState().setPublicUrl(t.publicUrl),$(!0),setTimeout(()=>$(!1),1800)}catch(t){E(t instanceof Error?t.message:String(t))}finally{F(!1)}},disabled:R,className:"px-3 py-1.5 rounded-lg text-xs font-medium bg-cc-primary text-white hover:opacity-90 transition-opacity disabled:opacity-50 cursor-pointer",children:R?"Saving...":V?"Saved!":"Save"}),J&&e.jsxs("span",{className:"text-[11px] text-green-500 font-medium",children:["Active: ",J]}),!J&&e.jsxs("span",{className:"text-[11px] text-cc-muted",children:["Not set — using ",typeof window<"u"?window.location.origin:"http://localhost:3456"]})]})]}),e.jsxs("div",{className:"bg-cc-hover/50 rounded-lg p-3 space-y-3",children:[e.jsx("h3",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider",children:"Tailscale (no domain needed)"}),e.jsx("p",{className:"text-[11px] text-cc-muted",children:"No domain? Tailscale Funnel gives you a free HTTPS URL automatically. Install Tailscale on your server, then enable Funnel here."}),e.jsx(Hs,{})]}),e.jsxs("div",{className:"bg-cc-hover/50 rounded-lg p-3 space-y-2",children:[e.jsx("h3",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider",children:"What the Public URL enables"}),e.jsxs("ul",{className:"text-[11px] text-cc-muted space-y-1 list-disc pl-4",children:[e.jsx("li",{children:"Mobile access — install HeyHank as PWA on your phone"}),e.jsx("li",{children:"Webhooks — receive events from GitHub and other services"}),e.jsx("li",{children:"OAuth callbacks — authenticate with external services"}),e.jsx("li",{children:"Federation — connect multiple HeyHank instances"})]})]})]}),e.jsxs(I,{id:"authentication",title:"Authentication",status:te?"Token set":"No token",forceOpen:P==="authentication",sectionRef:U("authentication"),children:[e.jsx("p",{className:"text-xs text-cc-muted",children:"Use the auth token or QR code to connect additional devices (e.g. mobile over Tailscale)."}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1.5",children:"Auth Token"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("div",{className:"flex-1 px-3 py-2.5 min-h-[44px] text-sm bg-cc-bg rounded-lg text-cc-fg font-mono-code select-all break-all flex items-center",children:te?Ye?te:"••••••••••••••••":e.jsx("span",{className:"text-cc-muted",children:"Loading..."})}),e.jsx("button",{type:"button",onClick:()=>qt(t=>!t),className:"px-3 py-2.5 min-h-[44px] rounded-lg text-sm bg-cc-hover hover:bg-cc-active text-cc-fg transition-colors cursor-pointer",title:Ye?"Hide token":"Show token",children:Ye?"Hide":"Show"}),e.jsx("button",{type:"button",onClick:()=>{te&&navigator.clipboard.writeText(te).then(()=>{Xt(!0),setTimeout(()=>Xt(!1),1500)})},disabled:!te,className:"px-3 py-2.5 min-h-[44px] rounded-lg text-sm bg-cc-hover hover:bg-cc-active text-cc-fg transition-colors cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed",title:"Copy token to clipboard",children:vs?"Copied":"Copy"})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium mb-1.5",children:"Mobile Login QR"}),H&&H.length>0?e.jsxs("div",{className:"space-y-3",children:[H.length>1&&e.jsx("div",{className:"flex gap-1",children:H.map((t,c)=>e.jsx("button",{type:"button",onClick:()=>bs(c),className:`px-3 py-1.5 rounded-md text-xs font-medium transition-colors cursor-pointer ${c===ve?"bg-cc-primary text-white":"bg-cc-hover text-cc-muted hover:text-cc-fg"}`,children:t.label},t.label))}),e.jsx("div",{className:"inline-block rounded-lg bg-white p-2",children:e.jsx("img",{src:H[ve].qrDataUrl,alt:`QR code for ${H[ve].label} login`,className:"w-48 h-48"})}),e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-bg text-sm font-mono-code text-cc-fg break-all select-all",children:H[ve].url}),e.jsx("p",{className:"text-xs text-cc-muted",children:"Scan with your phone's camera app — it will open the URL and auto-authenticate."})]}):H&&H.length===0?e.jsx("p",{className:"text-xs text-cc-muted",children:"No remote addresses detected (LAN or Tailscale). Connect to a network to generate a QR code."}):e.jsx("button",{type:"button",onClick:async()=>{Jt(!0);try{const t=await o.getAuthQr();Qt(t.qrCodes)}catch{}finally{Jt(!1)}},disabled:qe,className:`px-3 py-2 min-h-[44px] rounded-lg text-sm font-medium transition-colors ${qe?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-hover hover:bg-cc-active text-cc-fg cursor-pointer"}`,children:qe?"Generating...":"Show QR Code"})]}),e.jsxs("div",{className:"pt-2",children:[e.jsx("button",{type:"button",onClick:async()=>{if(confirm("Regenerate auth token? All existing sessions on other devices will be signed out.")){Zt(!0);try{const t=await o.regenerateAuthToken();Yt(t.token),qt(!0),Qt(null)}catch{}finally{Zt(!1)}}},disabled:Qe,className:`px-3 py-2 min-h-[44px] rounded-lg text-sm font-medium transition-colors ${Qe?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-error/10 hover:bg-cc-error/20 text-cc-error cursor-pointer"}`,children:Qe?"Regenerating...":"Regenerate Token"}),e.jsx("p",{className:"mt-1.5 text-xs text-cc-muted",children:"Creates a new token. All other signed-in devices will need to re-authenticate."})]})]}),e.jsxs(I,{id:"notifications",title:"Notifications",status:de?"Sound on":"Sound off",forceOpen:P==="notifications",sectionRef:U("notifications"),children:[e.jsxs("button",{type:"button",onClick:ye,className:"w-full flex items-center justify-between px-3 py-3 min-h-[44px] rounded-lg text-sm bg-cc-hover text-cc-fg hover:bg-cc-active transition-colors cursor-pointer",children:[e.jsx("span",{children:"Sound"}),e.jsx("span",{className:"text-xs text-cc-muted",children:de?"On":"Off"})]}),as&&e.jsxs("button",{type:"button",onClick:async()=>{if(ue)r(!1);else{if(Notification.permission!=="granted"&&await Notification.requestPermission()!=="granted")return;r(!0)}},className:"w-full flex items-center justify-between px-3 py-3 min-h-[44px] rounded-lg text-sm bg-cc-hover text-cc-fg hover:bg-cc-active transition-colors cursor-pointer",children:[e.jsx("span",{children:"Desktop Alerts"}),e.jsx("span",{className:"text-xs text-cc-muted",children:ue?"On":"Off"})]}),e.jsx(Ds,{})]}),e.jsxs(I,{id:"providers",title:"Providers",defaultOpen:!0,forceOpen:P==="providers",status:b?"Configured":"Not configured",sectionRef:U("providers"),children:[e.jsxs("p",{className:"text-xs text-cc-muted",children:["Connect AI backends to power your agent sessions. Configure CLI backends (Claude Code, Codex) and additional model providers for Claude Code's ",e.jsx("code",{className:"font-mono-code bg-cc-code-bg px-1 py-0.5 rounded text-cc-code-fg",children:"--provider"})," flag."]}),e.jsxs("div",{className:"space-y-3 p-4 bg-cc-bg rounded-lg border border-cc-border",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-medium text-cc-fg",children:"Claude Code"}),(l==null?void 0:l.cliVersion)&&e.jsx("p",{className:"text-xs text-cc-muted mt-0.5",children:l.cliVersion})]}),((l==null?void 0:l.authenticated)??(l==null?void 0:l.loggedIn))||he?e.jsx("span",{className:"px-2 py-0.5 text-xs rounded-full bg-cc-success/15 text-cc-success border border-cc-success/20",children:"Authenticated"}):e.jsx("span",{className:"px-2 py-0.5 text-xs rounded-full bg-cc-error/15 text-cc-error border border-cc-error/20",children:"Not configured"})]}),((l==null?void 0:l.authenticated)??(l==null?void 0:l.loggedIn))&&e.jsxs("div",{className:"px-3 py-2 rounded-lg bg-cc-success/5 border border-cc-success/10 text-xs text-cc-muted",children:[l.method==="cli_login"&&e.jsxs(e.Fragment,{children:["Authenticated via ",e.jsx("strong",{className:"text-cc-fg",children:"CLI login"}),". Sessions authenticate automatically."]}),l.method==="env_api_key"&&e.jsxs(e.Fragment,{children:["Authenticated via ",e.jsx("strong",{className:"text-cc-fg",children:"ANTHROPIC_API_KEY"})," env var."]}),l.method==="env_oauth"&&e.jsxs(e.Fragment,{children:["Authenticated via ",e.jsx("strong",{className:"text-cc-fg",children:"CLAUDE_CODE_OAUTH_TOKEN"})," env var."]}),l.method==="env_auth_token"&&e.jsxs(e.Fragment,{children:["Authenticated via ",e.jsx("strong",{className:"text-cc-fg",children:"ANTHROPIC_AUTH_TOKEN"})," env var."]})]}),!((l==null?void 0:l.authenticated)??(l==null?void 0:l.loggedIn))&&!he&&e.jsxs("div",{className:"px-3 py-2.5 rounded-lg bg-cc-primary/5 border border-cc-primary/15 text-xs text-cc-muted space-y-1.5",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"CLI Login:"})," Run ",e.jsx("code",{className:"font-mono-code bg-cc-code-bg px-1 py-0.5 rounded text-cc-code-fg",children:"claude login"})," on the server."]}),e.jsxs("p",{children:[e.jsx("strong",{children:"OAuth Token:"})," Paste a token from ",e.jsx("code",{className:"font-mono-code bg-cc-code-bg px-1 py-0.5 rounded text-cc-code-fg",children:"claude setup-token"})," below."]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("label",{className:"block text-xs text-cc-muted",htmlFor:"claude-code-token",children:["OAuth Token ",(l==null?void 0:l.authenticated)??(l==null?void 0:l.loggedIn)?"(optional)":""]}),e.jsx("input",{id:"claude-code-token",type:"password",value:he&&!ns&&!Z?"••••••••••••••••":Z,onChange:t=>xt(t.target.value),onFocus:()=>yt(!0),onBlur:()=>yt(!1),placeholder:he?"Enter a new token to replace":"Paste token from claude setup-token",className:"w-full px-3 py-2 text-sm bg-cc-input-bg rounded-lg text-cc-fg placeholder:text-cc-muted focus:outline-none focus:ring-1 focus:ring-cc-primary/40 transition-shadow"})]})]}),e.jsxs("div",{className:"space-y-3 p-4 bg-cc-bg rounded-lg border border-cc-border",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-medium text-cc-fg",children:"OpenAI Codex"}),(u==null?void 0:u.cliVersion)&&e.jsx("p",{className:"text-xs text-cc-muted mt-0.5",children:u.cliVersion})]}),((u==null?void 0:u.authenticated)??(u==null?void 0:u.loggedIn))||re?e.jsx("span",{className:"px-2 py-0.5 text-xs rounded-full bg-cc-success/15 text-cc-success border border-cc-success/20",children:"Authenticated"}):e.jsx("span",{className:"px-2 py-0.5 text-xs rounded-full bg-cc-error/15 text-cc-error border border-cc-error/20",children:"Not configured"})]}),((u==null?void 0:u.authenticated)??(u==null?void 0:u.loggedIn))&&e.jsxs("div",{className:"px-3 py-2 rounded-lg bg-cc-success/5 border border-cc-success/10 text-xs text-cc-muted",children:[u.method==="cli_login"&&e.jsxs(e.Fragment,{children:["Authenticated via ",e.jsx("strong",{className:"text-cc-fg",children:"device login"}),"."]}),u.method==="env_api_key"&&e.jsxs(e.Fragment,{children:["Authenticated via ",e.jsx("strong",{className:"text-cc-fg",children:"OPENAI_API_KEY"})," env var."]})]}),!((u==null?void 0:u.authenticated)??(u==null?void 0:u.loggedIn))&&!re&&e.jsxs("div",{className:"px-3 py-2.5 rounded-lg bg-cc-primary/5 border border-cc-primary/15 text-xs text-cc-muted space-y-1.5",children:[e.jsxs("p",{children:[e.jsx("strong",{children:"Device Login:"})," Run ",e.jsx("code",{className:"font-mono-code bg-cc-code-bg px-1 py-0.5 rounded text-cc-code-fg",children:"codex --login"})," on the server."]}),e.jsxs("p",{children:[e.jsx("strong",{children:"API Key:"})," Enter your key below from ",e.jsx("a",{href:"https://platform.openai.com/api-keys",target:"_blank",rel:"noopener noreferrer",className:"text-cc-primary hover:underline",children:"platform.openai.com"}),"."]})]}),e.jsxs("div",{className:"space-y-1.5",children:[e.jsxs("label",{className:"block text-xs text-cc-muted",htmlFor:"openai-api-key",children:["API Key ",(u==null?void 0:u.authenticated)??(u==null?void 0:u.loggedIn)?"(optional)":""]}),e.jsx("input",{id:"openai-api-key",type:"password",value:re&&!os&&!X?"••••••••••••••••":X,onChange:t=>ht(t.target.value),onFocus:()=>jt(!0),onBlur:()=>jt(!1),placeholder:re?"Enter a new key to replace":"sk-...",className:"w-full px-3 py-2 text-sm bg-cc-input-bg rounded-lg text-cc-fg placeholder:text-cc-muted focus:outline-none focus:ring-1 focus:ring-cc-primary/40 transition-shadow"})]})]}),bt&&e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-error/10 border border-cc-error/20 text-xs text-cc-error",children:bt}),rs&&e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-success/10 border border-cc-success/20 text-xs text-cc-success",children:"Provider settings saved."}),e.jsx("button",{type:"button",disabled:Oe||!Z.trim()&&!X.trim(),onClick:async()=>{ft(!0),vt(""),Le(!1);try{const t={};Z.trim()&&(t.claudeCodeOAuthToken=Z.trim()),X.trim()&&(t.openaiApiKey=X.trim());const c=await o.updateSettings(t);pt(c.claudeCodeOAuthTokenConfigured),gt(c.openaiApiKeyConfigured),c.claudeCliAuth&&Nt(c.claudeCliAuth),c.codexCliAuth&&kt(c.codexCliAuth),xt(""),ht(""),Le(!0),setTimeout(()=>Le(!1),1800)}catch(t){vt(t instanceof Error?t.message:String(t))}finally{ft(!1)}},className:`px-4 py-2 min-h-[44px] rounded-lg text-sm font-medium transition-colors ${Oe||!Z.trim()&&!X.trim()?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-primary-btn hover:bg-cc-primary-btn-hover text-white cursor-pointer"}`,children:Oe?"Saving...":"Save CLI Backend Settings"}),e.jsxs("details",{className:"border-t border-cc-border pt-4 group",children:[e.jsxs("summary",{className:"flex items-center justify-between cursor-pointer list-none",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-sm font-medium text-cc-fg",children:"Additional Providers"}),e.jsxs("p",{className:"text-xs text-cc-muted mt-0.5",children:["Configure model providers for Claude Code's ",e.jsx("code",{className:"font-mono-code bg-cc-code-bg px-1 py-0.5 rounded text-cc-code-fg text-[10px]",children:"--provider"})," flag."]})]}),e.jsx("svg",{viewBox:"0 0 16 16",fill:"currentColor",className:"w-4 h-4 text-cc-muted transition-transform group-open:rotate-180",children:e.jsx("path",{fillRule:"evenodd",d:"M4.22 6.22a.75.75 0 0 1 1.06 0L8 8.94l2.72-2.72a.75.75 0 1 1 1.06 1.06l-3.25 3.25a.75.75 0 0 1-1.06 0L4.22 7.28a.75.75 0 0 1 0-1.06Z"})})]}),e.jsx("div",{className:"mt-4",children:e.jsx($s,{})})]})]}),e.jsxs(I,{id:"gemini",title:"Gemini",status:ee?"Key set":"Not configured",forceOpen:P==="gemini",sectionRef:U("gemini"),children:[e.jsxs("p",{className:"text-xs text-cc-muted",children:["Configure Gemini Live for voice chat. Get an API key from"," ",e.jsx("a",{href:"https://aistudio.google.com/apikey",target:"_blank",rel:"noopener noreferrer",className:"text-cc-primary hover:underline",children:"Google AI Studio"}),"."]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"gemini-api-key",children:"Gemini API Key"}),e.jsx("input",{id:"gemini-api-key",type:"password",value:ee&&!us&&!ne?"••••••••••••••••":ne,onChange:t=>wt(t.target.value),onFocus:()=>Pt(!0),onBlur:()=>Pt(!1),placeholder:ee?"Enter a new key to replace":"AIza...",className:"w-full px-3 py-2.5 min-h-[44px] text-sm bg-cc-bg rounded-lg text-cc-fg placeholder:text-cc-muted focus:outline-none focus:ring-1 focus:ring-cc-primary/40 transition-shadow"}),e.jsx("p",{className:"text-xs text-cc-muted",children:ee?"Gemini API key configured":"Gemini API key not configured"})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"assistant-name",children:"Assistant Name"}),e.jsx("input",{id:"assistant-name",type:"text",value:Ve,onChange:t=>$e(t.target.value),placeholder:"e.g. Jarvis, Friday, Max",className:"w-full px-3 py-2.5 min-h-[44px] text-sm bg-cc-bg rounded-lg text-cc-fg placeholder:text-cc-muted focus:outline-none focus:ring-1 focus:ring-cc-primary/40 transition-shadow"}),e.jsx("p",{className:"text-xs text-cc-muted",children:"Give your voice assistant a custom name. Leave empty for default."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"user-name",children:"Your Name"}),e.jsx("input",{id:"user-name",type:"text",value:Ke,onChange:t=>De(t.target.value),placeholder:"e.g. Markus",className:"w-full px-3 py-2.5 min-h-[44px] text-sm bg-cc-bg rounded-lg text-cc-fg placeholder:text-cc-muted focus:outline-none focus:ring-1 focus:ring-cc-primary/40 transition-shadow"}),e.jsx("p",{className:"text-xs text-cc-muted",children:"Your name so Gemini knows who it's talking to."})]}),e.jsxs("div",{className:"space-y-2",children:[e.jsx("label",{className:"block text-sm font-medium",htmlFor:"gemini-voice",children:"Voice"}),e.jsxs("select",{id:"gemini-voice",value:Re,onChange:t=>Fe(t.target.value),className:"w-full px-3 py-2.5 min-h-[44px] text-sm bg-cc-bg rounded-lg text-cc-fg focus:outline-none focus:ring-1 focus:ring-cc-primary/40 transition-shadow",children:[e.jsx("option",{value:"Kore",children:"Kore (female, firm)"}),e.jsx("option",{value:"Puck",children:"Puck (male, playful)"}),e.jsx("option",{value:"Charon",children:"Charon (male, deep)"}),e.jsx("option",{value:"Fenrir",children:"Fenrir (male, bold)"}),e.jsx("option",{value:"Aoede",children:"Aoede (female, bright)"}),e.jsx("option",{value:"Leda",children:"Leda (female, gentle)"}),e.jsx("option",{value:"Orus",children:"Orus (male, clear)"}),e.jsx("option",{value:"Zephyr",children:"Zephyr (neutral, calm)"})]})]}),It&&e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-error/10 border border-cc-error/20 text-xs text-cc-error",children:It}),ms&&e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-success/10 border border-cc-success/20 text-xs text-cc-success",children:"Gemini settings saved."}),e.jsx("button",{type:"button",disabled:He||!ne.trim()&&Re===is&&Ve===ls&&Ke===ds,onClick:async()=>{Ut(!0),Tt(""),Me(!1);try{const t={};ne.trim()&&(t.geminiApiKey=ne.trim()),t.assistantName=Ve,t.userName=Ke,t.geminiVoice=Re;const c=await o.updateSettings(t);St(c.geminiApiKeyConfigured),c.geminiVoice&&(Fe(c.geminiVoice),Ct(c.geminiVoice)),typeof c.assistantName=="string"&&($e(c.assistantName),At(c.assistantName)),typeof c.userName=="string"&&(De(c.userName),Et(c.userName)),wt(""),Me(!0),setTimeout(()=>Me(!1),1800)}catch(t){Tt(t instanceof Error?t.message:String(t))}finally{Ut(!1)}},className:`px-4 py-2 min-h-[44px] rounded-lg text-sm font-medium transition-colors ${He?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-primary-btn hover:bg-cc-primary-btn-hover text-white cursor-pointer"}`,children:He?"Saving...":"Save Gemini Settings"})]}),e.jsxs(I,{id:"email",title:"Email Accounts",status:`${ge.length} account${ge.length!==1?"s":""}`,forceOpen:P==="email",sectionRef:U("email"),children:[e.jsx("p",{className:"text-xs text-cc-muted",children:"Configure IMAP/SMTP email accounts for the voice assistant. Gemini can read, search, and send emails on your behalf."}),ps?e.jsx("p",{className:"text-xs text-cc-muted",children:"Loading accounts..."}):ge.length===0?e.jsx("p",{className:"text-xs text-cc-muted",children:"No email accounts configured."}):e.jsx("div",{className:"space-y-2",children:ge.map(t=>e.jsxs("div",{className:"flex items-center justify-between px-3 py-2.5 bg-cc-bg rounded-lg",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("div",{className:"text-sm font-medium text-cc-fg truncate",children:t.name}),e.jsx("div",{className:"text-xs text-cc-muted truncate",children:t.email}),e.jsxs("div",{className:"text-xs text-cc-muted",children:["IMAP: ",t.imap.host,":",t.imap.port," | SMTP: ",t.smtp.host,":",t.smtp.port]}),(oe==null?void 0:oe.id)===t.id&&e.jsx("div",{className:`text-xs mt-1 ${oe.ok?"text-cc-success":"text-cc-error"}`,children:oe.message})]}),e.jsxs("div",{className:"flex gap-1.5 ml-2 shrink-0",children:[e.jsx("button",{type:"button",onClick:()=>Ns(t.id),disabled:$t===t.id,className:"px-2 py-1 text-xs rounded bg-cc-hover text-cc-fg hover:bg-cc-border transition-colors",children:$t===t.id?"...":"Test"}),e.jsx("button",{type:"button",onClick:()=>ks(t),className:"px-2 py-1 text-xs rounded bg-cc-hover text-cc-fg hover:bg-cc-border transition-colors",children:"Edit"}),e.jsx("button",{type:"button",onClick:()=>js(t.id),className:"px-2 py-1 text-xs rounded bg-cc-error/10 text-cc-error hover:bg-cc-error/20 transition-colors",children:"Delete"})]})]},t.id))}),hs?e.jsxs("div",{className:"space-y-3 p-4 bg-cc-bg rounded-lg border border-cc-border",children:[e.jsx("h3",{className:"text-sm font-medium text-cc-fg",children:K?`Edit: ${K.name}`:"Add Email Account"}),!K&&e.jsxs("div",{className:"space-y-1",children:[e.jsx("p",{className:"text-xs text-cc-muted font-medium",children:"Quick presets:"}),e.jsx("div",{className:"flex gap-2 flex-wrap",children:[{label:"Gmail",imap:"imap.gmail.com",smtp:"smtp.gmail.com",imapPort:"993",smtpPort:"465",info:`1. Go to myaccount.google.com
2
2
  2. Security → 2-Step Verification (must be ON)
3
3
  3. Search for "App passwords" or go to myaccount.google.com/apppasswords
4
4
  4. Create a new App Password (name: e.g. "Email Agent")
@@ -1 +1 @@
1
- import{r as l,b as d,j as s}from"./index-BgYM4wXw.js";function B({embedded:U}){const[c,h]=l.useState("available"),[p,C]=l.useState([]),[i,g]=l.useState(null),[x,I]=l.useState([]),[r,f]=l.useState([]),[j,y]=l.useState(!1),[N,n]=l.useState(null),[o,L]=l.useState(""),[v,m]=l.useState(null);l.useEffect(()=>{let e=!1;return Promise.all([d.marketplaceListSources(),d.listSkills()]).then(([t,a])=>{e||(C(t),f(a),t.length>0&&g(t[0].id))}).catch(t=>!e&&n(t instanceof Error?t.message:String(t))),()=>{e=!0}},[]),l.useEffect(()=>{if(!i)return;let e=!1;return y(!0),n(null),d.marketplaceListSkills(i).then(t=>{e||I(t)}).catch(t=>{e||n(t instanceof Error?t.message:String(t))}).finally(()=>{e||y(!1)}),()=>{e=!0}},[i]);const E=l.useMemo(()=>new Set(r.map(e=>e.slug)),[r]),u=l.useMemo(()=>{const e=o.trim().toLowerCase();return e?x.filter(t=>t.slug.toLowerCase().includes(e)||t.name.toLowerCase().includes(e)||t.description.toLowerCase().includes(e)):x},[x,o]),b=l.useMemo(()=>{const e=o.trim().toLowerCase();return e?r.filter(t=>t.slug.toLowerCase().includes(e)||t.name.toLowerCase().includes(e)||t.description.toLowerCase().includes(e)):r},[r,o]);async function S(){try{const e=await d.listSkills();f(e)}catch{}}async function w(e,t=!1){if(i){m(e.slug),n(null);try{await d.marketplaceInstall(i,e.slug,t),await S()}catch(a){n(a instanceof Error?a.message:String(a))}finally{m(null)}}}async function k(e){if(confirm(`Uninstall skill "${e}"? This removes the folder from ~/.claude/skills/.`)){m(e),n(null);try{await d.deleteSkill(e),await S()}catch(t){n(t instanceof Error?t.message:String(t))}finally{m(null)}}}const M=p.length>1;return s.jsx("div",{className:"absolute inset-0 overflow-auto bg-cc-bg text-cc-fg",children:s.jsxs("div",{className:"max-w-5xl mx-auto p-6",children:[s.jsxs("header",{className:"mb-4",children:[s.jsx("h1",{className:"text-xl font-semibold mb-1",children:"Skills"}),s.jsxs("p",{className:"text-sm text-cc-muted",children:["Browse and install Claude Code skills, or manage what's already in"," ",s.jsx("code",{className:"text-xs bg-cc-card px-1 py-0.5 rounded",children:"~/.claude/skills/"}),"."]})]}),s.jsxs("div",{role:"tablist","aria-label":"Skills view",className:"mb-4 flex gap-1 border-b border-cc-border",children:[s.jsx("button",{type:"button",role:"tab","aria-selected":c==="available",onClick:()=>h("available"),className:`px-3 py-2 text-sm border-b-2 -mb-px transition-colors ${c==="available"?"border-cc-accent text-cc-fg font-medium":"border-transparent text-cc-muted hover:text-cc-fg"}`,children:"Marketplace"}),s.jsxs("button",{type:"button",role:"tab","aria-selected":c==="installed",onClick:()=>h("installed"),className:`px-3 py-2 text-sm border-b-2 -mb-px transition-colors ${c==="installed"?"border-cc-accent text-cc-fg font-medium":"border-transparent text-cc-muted hover:text-cc-fg"}`,children:["Installed (",r.length,")"]})]}),c==="available"&&M&&s.jsxs("section",{"aria-labelledby":"sources-heading",className:"mb-6",children:[s.jsx("h2",{id:"sources-heading",className:"text-sm font-semibold mb-2",children:"Sources"}),s.jsx("div",{className:"flex flex-wrap gap-2",children:p.map(e=>{const t=e.id===i;return s.jsxs("button",{type:"button",onClick:()=>g(e.id),className:`px-3 py-2 rounded-md border text-left text-sm transition-colors ${t?"border-cc-accent bg-cc-accent/10 text-cc-fg":"border-cc-border bg-cc-card hover:bg-cc-hover text-cc-fg"}`,"aria-pressed":t,children:[s.jsx("div",{className:"font-medium",children:e.name}),s.jsxs("div",{className:"text-xs text-cc-muted",children:["by ",e.owner]})]},e.id)})})]}),s.jsxs("div",{className:"mb-4",children:[s.jsx("label",{className:"sr-only",htmlFor:"skill-search",children:"Search skills"}),s.jsx("input",{id:"skill-search",type:"search",value:o,onChange:e=>L(e.target.value),placeholder:"Search skills…",className:"w-full px-3 py-2 rounded-md border border-cc-border bg-cc-card text-sm focus:outline-none focus:ring-2 focus:ring-cc-accent"})]}),N&&s.jsx("div",{role:"alert",className:"mb-4 px-3 py-2 rounded-md border border-red-500/40 bg-red-500/10 text-sm text-red-400",children:N}),c==="available"&&s.jsxs("section",{"aria-labelledby":"skills-heading",children:[s.jsxs("h2",{id:"skills-heading",className:"text-sm font-semibold mb-2",children:["Available skills",j?" (loading…)":` (${u.length})`]}),j?s.jsx("div",{className:"text-sm text-cc-muted",children:"Fetching skills…"}):u.length===0?s.jsx("div",{className:"text-sm text-cc-muted",children:"No skills match your search."}):s.jsx("ul",{className:"space-y-2",children:u.map(e=>{const t=E.has(e.slug),a=v===e.slug;return s.jsxs("li",{className:"px-3 py-3 rounded-md border border-cc-border bg-cc-card flex items-start gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[s.jsx("span",{className:"font-medium",children:e.name}),s.jsx("code",{className:"text-xs text-cc-muted",children:e.slug}),t&&s.jsx("span",{className:"text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded bg-green-500/15 text-green-400",children:"Installed"})]}),e.description&&s.jsx("p",{className:"text-sm text-cc-muted mt-1 line-clamp-3",children:e.description})]}),s.jsx("div",{className:"flex flex-col gap-1.5 shrink-0",children:t?s.jsxs(s.Fragment,{children:[s.jsx("button",{type:"button",disabled:a,onClick:()=>w(e,!0),className:"px-3 py-1 text-xs rounded border border-cc-border hover:bg-cc-hover disabled:opacity-50",children:a?"Updating…":"Update"}),s.jsx("button",{type:"button",disabled:a,onClick:()=>k(e.slug),className:"px-3 py-1 text-xs rounded border border-red-500/40 text-red-400 hover:bg-red-500/10 disabled:opacity-50",children:a?"Removing…":"Uninstall"})]}):s.jsx("button",{type:"button",disabled:a,onClick:()=>w(e,!1),className:"px-3 py-1 text-xs rounded bg-cc-accent text-white hover:opacity-90 disabled:opacity-50",children:a?"Installing…":"Install"})})]},e.slug)})})]}),c==="installed"&&s.jsxs("section",{"aria-labelledby":"installed-heading",children:[s.jsxs("h2",{id:"installed-heading",className:"text-sm font-semibold mb-2",children:["Installed skills (",b.length,")"]}),b.length===0?s.jsx("div",{className:"text-sm text-cc-muted",children:r.length===0?"No skills installed yet. Switch to the Marketplace tab to browse.":"No installed skills match your search."}):s.jsx("ul",{className:"space-y-2",children:b.map(e=>{const t=v===e.slug;return s.jsxs("li",{className:"px-3 py-3 rounded-md border border-cc-border bg-cc-card flex items-start gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[s.jsx("span",{className:"font-medium",children:e.name}),s.jsx("code",{className:"text-xs text-cc-muted",children:e.slug})]}),e.description&&s.jsx("p",{className:"text-sm text-cc-muted mt-1 line-clamp-3",children:e.description}),s.jsx("div",{className:"text-[11px] text-cc-muted mt-1 truncate",title:e.path,children:e.path})]}),s.jsx("div",{className:"flex flex-col gap-1.5 shrink-0",children:s.jsx("button",{type:"button",disabled:t,onClick:()=>k(e.slug),className:"px-3 py-1 text-xs rounded border border-red-500/40 text-red-400 hover:bg-red-500/10 disabled:opacity-50",children:t?"Removing…":"Uninstall"})})]},e.slug)})})]})]})})}export{B as SkillsMarketplace};
1
+ import{r as l,b as d,j as s}from"./index-C6Q5UQHD.js";function B({embedded:U}){const[c,h]=l.useState("available"),[p,C]=l.useState([]),[i,g]=l.useState(null),[x,I]=l.useState([]),[r,f]=l.useState([]),[j,y]=l.useState(!1),[N,n]=l.useState(null),[o,L]=l.useState(""),[v,m]=l.useState(null);l.useEffect(()=>{let e=!1;return Promise.all([d.marketplaceListSources(),d.listSkills()]).then(([t,a])=>{e||(C(t),f(a),t.length>0&&g(t[0].id))}).catch(t=>!e&&n(t instanceof Error?t.message:String(t))),()=>{e=!0}},[]),l.useEffect(()=>{if(!i)return;let e=!1;return y(!0),n(null),d.marketplaceListSkills(i).then(t=>{e||I(t)}).catch(t=>{e||n(t instanceof Error?t.message:String(t))}).finally(()=>{e||y(!1)}),()=>{e=!0}},[i]);const E=l.useMemo(()=>new Set(r.map(e=>e.slug)),[r]),u=l.useMemo(()=>{const e=o.trim().toLowerCase();return e?x.filter(t=>t.slug.toLowerCase().includes(e)||t.name.toLowerCase().includes(e)||t.description.toLowerCase().includes(e)):x},[x,o]),b=l.useMemo(()=>{const e=o.trim().toLowerCase();return e?r.filter(t=>t.slug.toLowerCase().includes(e)||t.name.toLowerCase().includes(e)||t.description.toLowerCase().includes(e)):r},[r,o]);async function S(){try{const e=await d.listSkills();f(e)}catch{}}async function w(e,t=!1){if(i){m(e.slug),n(null);try{await d.marketplaceInstall(i,e.slug,t),await S()}catch(a){n(a instanceof Error?a.message:String(a))}finally{m(null)}}}async function k(e){if(confirm(`Uninstall skill "${e}"? This removes the folder from ~/.claude/skills/.`)){m(e),n(null);try{await d.deleteSkill(e),await S()}catch(t){n(t instanceof Error?t.message:String(t))}finally{m(null)}}}const M=p.length>1;return s.jsx("div",{className:"absolute inset-0 overflow-auto bg-cc-bg text-cc-fg",children:s.jsxs("div",{className:"max-w-5xl mx-auto p-6",children:[s.jsxs("header",{className:"mb-4",children:[s.jsx("h1",{className:"text-xl font-semibold mb-1",children:"Skills"}),s.jsxs("p",{className:"text-sm text-cc-muted",children:["Browse and install Claude Code skills, or manage what's already in"," ",s.jsx("code",{className:"text-xs bg-cc-card px-1 py-0.5 rounded",children:"~/.claude/skills/"}),"."]})]}),s.jsxs("div",{role:"tablist","aria-label":"Skills view",className:"mb-4 flex gap-1 border-b border-cc-border",children:[s.jsx("button",{type:"button",role:"tab","aria-selected":c==="available",onClick:()=>h("available"),className:`px-3 py-2 text-sm border-b-2 -mb-px transition-colors ${c==="available"?"border-cc-accent text-cc-fg font-medium":"border-transparent text-cc-muted hover:text-cc-fg"}`,children:"Marketplace"}),s.jsxs("button",{type:"button",role:"tab","aria-selected":c==="installed",onClick:()=>h("installed"),className:`px-3 py-2 text-sm border-b-2 -mb-px transition-colors ${c==="installed"?"border-cc-accent text-cc-fg font-medium":"border-transparent text-cc-muted hover:text-cc-fg"}`,children:["Installed (",r.length,")"]})]}),c==="available"&&M&&s.jsxs("section",{"aria-labelledby":"sources-heading",className:"mb-6",children:[s.jsx("h2",{id:"sources-heading",className:"text-sm font-semibold mb-2",children:"Sources"}),s.jsx("div",{className:"flex flex-wrap gap-2",children:p.map(e=>{const t=e.id===i;return s.jsxs("button",{type:"button",onClick:()=>g(e.id),className:`px-3 py-2 rounded-md border text-left text-sm transition-colors ${t?"border-cc-accent bg-cc-accent/10 text-cc-fg":"border-cc-border bg-cc-card hover:bg-cc-hover text-cc-fg"}`,"aria-pressed":t,children:[s.jsx("div",{className:"font-medium",children:e.name}),s.jsxs("div",{className:"text-xs text-cc-muted",children:["by ",e.owner]})]},e.id)})})]}),s.jsxs("div",{className:"mb-4",children:[s.jsx("label",{className:"sr-only",htmlFor:"skill-search",children:"Search skills"}),s.jsx("input",{id:"skill-search",type:"search",value:o,onChange:e=>L(e.target.value),placeholder:"Search skills…",className:"w-full px-3 py-2 rounded-md border border-cc-border bg-cc-card text-sm focus:outline-none focus:ring-2 focus:ring-cc-accent"})]}),N&&s.jsx("div",{role:"alert",className:"mb-4 px-3 py-2 rounded-md border border-red-500/40 bg-red-500/10 text-sm text-red-400",children:N}),c==="available"&&s.jsxs("section",{"aria-labelledby":"skills-heading",children:[s.jsxs("h2",{id:"skills-heading",className:"text-sm font-semibold mb-2",children:["Available skills",j?" (loading…)":` (${u.length})`]}),j?s.jsx("div",{className:"text-sm text-cc-muted",children:"Fetching skills…"}):u.length===0?s.jsx("div",{className:"text-sm text-cc-muted",children:"No skills match your search."}):s.jsx("ul",{className:"space-y-2",children:u.map(e=>{const t=E.has(e.slug),a=v===e.slug;return s.jsxs("li",{className:"px-3 py-3 rounded-md border border-cc-border bg-cc-card flex items-start gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[s.jsx("span",{className:"font-medium",children:e.name}),s.jsx("code",{className:"text-xs text-cc-muted",children:e.slug}),t&&s.jsx("span",{className:"text-[10px] uppercase tracking-wide px-1.5 py-0.5 rounded bg-green-500/15 text-green-400",children:"Installed"})]}),e.description&&s.jsx("p",{className:"text-sm text-cc-muted mt-1 line-clamp-3",children:e.description})]}),s.jsx("div",{className:"flex flex-col gap-1.5 shrink-0",children:t?s.jsxs(s.Fragment,{children:[s.jsx("button",{type:"button",disabled:a,onClick:()=>w(e,!0),className:"px-3 py-1 text-xs rounded border border-cc-border hover:bg-cc-hover disabled:opacity-50",children:a?"Updating…":"Update"}),s.jsx("button",{type:"button",disabled:a,onClick:()=>k(e.slug),className:"px-3 py-1 text-xs rounded border border-red-500/40 text-red-400 hover:bg-red-500/10 disabled:opacity-50",children:a?"Removing…":"Uninstall"})]}):s.jsx("button",{type:"button",disabled:a,onClick:()=>w(e,!1),className:"px-3 py-1 text-xs rounded bg-cc-accent text-white hover:opacity-90 disabled:opacity-50",children:a?"Installing…":"Install"})})]},e.slug)})})]}),c==="installed"&&s.jsxs("section",{"aria-labelledby":"installed-heading",children:[s.jsxs("h2",{id:"installed-heading",className:"text-sm font-semibold mb-2",children:["Installed skills (",b.length,")"]}),b.length===0?s.jsx("div",{className:"text-sm text-cc-muted",children:r.length===0?"No skills installed yet. Switch to the Marketplace tab to browse.":"No installed skills match your search."}):s.jsx("ul",{className:"space-y-2",children:b.map(e=>{const t=v===e.slug;return s.jsxs("li",{className:"px-3 py-3 rounded-md border border-cc-border bg-cc-card flex items-start gap-3",children:[s.jsxs("div",{className:"flex-1 min-w-0",children:[s.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[s.jsx("span",{className:"font-medium",children:e.name}),s.jsx("code",{className:"text-xs text-cc-muted",children:e.slug})]}),e.description&&s.jsx("p",{className:"text-sm text-cc-muted mt-1 line-clamp-3",children:e.description}),s.jsx("div",{className:"text-[11px] text-cc-muted mt-1 truncate",title:e.path,children:e.path})]}),s.jsx("div",{className:"flex flex-col gap-1.5 shrink-0",children:s.jsx("button",{type:"button",disabled:t,onClick:()=>k(e.slug),className:"px-3 py-1 text-xs rounded border border-red-500/40 text-red-400 hover:bg-red-500/10 disabled:opacity-50",children:t?"Removing…":"Uninstall"})})]},e.slug)})})]})]})})}export{B as SkillsMarketplace};
@@ -1,4 +1,4 @@
1
- import{r as d,j as e,b as L}from"./index-BgYM4wXw.js";const Z={instagram:"Instagram",twitter:"X (Twitter)",linkedin:"LinkedIn",facebook:"Facebook",tiktok:"TikTok"},ve=["instagram","twitter","linkedin","facebook","tiktok"];function se(){const t=typeof window<"u"?localStorage.getItem("heyhank_auth_token"):null;return t?{Authorization:`Bearer ${t}`}:{}}async function ye(t){const c=await fetch(t,{headers:se()});if(!c.ok)throw new Error(`${c.status} ${c.statusText}`);return c.json()}async function ee(t,c){const i=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json",...se()},body:c?JSON.stringify(c):void 0});if(!i.ok){const s=await i.json().catch(()=>null);throw new Error((s==null?void 0:s.error)||`${i.status} ${i.statusText}`)}return i.json()}function Ne({showMessage:t}){var B;const[c,i]=d.useState(null),[s,m]=d.useState(null),[j,v]=d.useState(null),[S,P]=d.useState(""),[T,k]=d.useState("role-model"),[C,u]=d.useState([]),A=d.useCallback(async()=>{try{const a=await ye("/api/socialview/status");i(a)}catch(a){t(a instanceof Error?a.message:"Failed to load status",!0)}},[t]);d.useEffect(()=>{A();const a=setInterval(A,5e3);return()=>clearInterval(a)},[A]);async function g(a){v(a);try{await ee(`/api/socialview/${a}/start`),t(`${Z[a]} browser started.`),m(a),await A()}catch(x){t(x instanceof Error?x.message:"Start failed",!0)}finally{v(null)}}async function n(a){v(a);try{await ee(`/api/socialview/${a}/stop`),t(`${Z[a]} browser stopped.`),s===a&&m(null),await A()}catch(x){t(x instanceof Error?x.message:"Stop failed",!0)}finally{v(null)}}async function l(){if(!(!s||!S.trim())){v(s);try{await ee(`/api/socialview/${s}/goto`,{url:S.trim()}),t(`Navigated to ${S}`),P(""),await A()}catch(a){t(a instanceof Error?a.message:"Navigation failed",!0)}finally{v(null)}}}async function o(){if(!s)return;const a=b.find(E=>E.platform===s),x=(a==null?void 0:a.currentUrl)||"(unknown)",N=`Extract from this URL?
1
+ import{r as d,j as e,b as L}from"./index-C6Q5UQHD.js";const Z={instagram:"Instagram",twitter:"X (Twitter)",linkedin:"LinkedIn",facebook:"Facebook",tiktok:"TikTok"},ve=["instagram","twitter","linkedin","facebook","tiktok"];function se(){const t=typeof window<"u"?localStorage.getItem("heyhank_auth_token"):null;return t?{Authorization:`Bearer ${t}`}:{}}async function ye(t){const c=await fetch(t,{headers:se()});if(!c.ok)throw new Error(`${c.status} ${c.statusText}`);return c.json()}async function ee(t,c){const i=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json",...se()},body:c?JSON.stringify(c):void 0});if(!i.ok){const s=await i.json().catch(()=>null);throw new Error((s==null?void 0:s.error)||`${i.status} ${i.statusText}`)}return i.json()}function Ne({showMessage:t}){var B;const[c,i]=d.useState(null),[s,m]=d.useState(null),[j,v]=d.useState(null),[S,P]=d.useState(""),[T,k]=d.useState("role-model"),[C,u]=d.useState([]),A=d.useCallback(async()=>{try{const a=await ye("/api/socialview/status");i(a)}catch(a){t(a instanceof Error?a.message:"Failed to load status",!0)}},[t]);d.useEffect(()=>{A();const a=setInterval(A,5e3);return()=>clearInterval(a)},[A]);async function g(a){v(a);try{await ee(`/api/socialview/${a}/start`),t(`${Z[a]} browser started.`),m(a),await A()}catch(x){t(x instanceof Error?x.message:"Start failed",!0)}finally{v(null)}}async function n(a){v(a);try{await ee(`/api/socialview/${a}/stop`),t(`${Z[a]} browser stopped.`),s===a&&m(null),await A()}catch(x){t(x instanceof Error?x.message:"Stop failed",!0)}finally{v(null)}}async function l(){if(!(!s||!S.trim())){v(s);try{await ee(`/api/socialview/${s}/goto`,{url:S.trim()}),t(`Navigated to ${S}`),P(""),await A()}catch(a){t(a instanceof Error?a.message:"Navigation failed",!0)}finally{v(null)}}}async function o(){if(!s)return;const a=b.find(E=>E.platform===s),x=(a==null?void 0:a.currentUrl)||"(unknown)",N=`Extract from this URL?
2
2
 
3
3
  ${x}
4
4
 
@@ -1 +1 @@
1
- import{r as l,b as i,j as e,u as d,n as N,a as y}from"./index-BgYM4wXw.js";function w({embedded:x=!1}){const[t,r]=l.useState(null),[a,h]=l.useState(!0),[c,o]=l.useState(!1),[g,m]=l.useState(!1);l.useEffect(()=>{i.getTailscaleStatus().then(r).catch(()=>r(null)).finally(()=>h(!1))},[]);async function u(){const s=await i.getTailscaleStatus().catch(()=>null);s&&r(s)}async function p(){o(!0);try{const s=await i.startTailscaleFunnel();r(s),s.funnelUrl&&!s.error&&!s.warning&&d.getState().setPublicUrl(s.funnelUrl)}catch(s){await u(),r(n=>n?{...n,error:s instanceof Error?s.message:String(s)}:null)}finally{o(!1)}}async function b(){o(!0);try{const s=await i.stopTailscaleFunnel();r(s);const n=d.getState().publicUrl;(!n||n===(t==null?void 0:t.funnelUrl))&&d.getState().setPublicUrl("")}catch(s){await u(),r(n=>n?{...n,error:s instanceof Error?s.message:String(s)}:null)}finally{o(!1)}}function f(){t!=null&&t.funnelUrl&&navigator.clipboard.writeText(t.funnelUrl).then(()=>{m(!0),setTimeout(()=>m(!1),1800)}).catch(()=>{})}const j=t?t.installed?t.connected?t.funnelActive?"Funnel active":"Ready":"Not connected":"Not installed":"Loading...",v=t?!t.installed||!t.connected?"text-cc-muted":t.funnelActive?"text-cc-success":"text-amber-500":"text-cc-muted";return e.jsx("div",{className:`${x?"h-full":"h-[100dvh]"} bg-cc-bg text-cc-fg font-sans-ui antialiased overflow-y-auto`,children:e.jsxs("div",{className:"max-w-5xl mx-auto px-4 sm:px-8 py-6 sm:py-10 pb-safe",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3 mb-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-semibold text-cc-fg",children:"Tailscale Settings"}),e.jsx("p",{className:"mt-1 text-sm text-cc-muted",children:"Expose HeyHank over HTTPS with Tailscale Funnel."})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{onClick:()=>{window.location.hash="#/integrations"},className:"px-3 py-2.5 min-h-[44px] rounded-lg text-sm text-cc-muted hover:text-cc-fg hover:bg-cc-hover transition-colors cursor-pointer",children:"Integrations"}),!x&&e.jsx("button",{onClick:()=>{const s=d.getState().currentSessionId;s?N(s):y()},className:"px-3 py-2.5 min-h-[44px] rounded-lg text-sm text-cc-muted hover:text-cc-fg hover:bg-cc-hover transition-colors cursor-pointer",children:"Back"})]})]}),e.jsxs("section",{className:"relative overflow-hidden bg-cc-card border border-cc-border rounded-xl p-4 sm:p-6 mb-4",children:[e.jsx("div",{className:"absolute inset-0 pointer-events-none bg-[radial-gradient(circle_at_top_right,rgba(6,182,212,0.1),transparent_45%)]"}),e.jsxs("div",{className:"relative flex items-start justify-between gap-4 flex-wrap",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"inline-flex items-center gap-2 px-2.5 py-1 rounded-full border border-cc-border bg-cc-hover/60 text-xs text-cc-muted",children:[e.jsx("svg",{className:"w-3.5 h-3.5 text-cc-fg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"})}),e.jsx("span",{children:"Tailscale Integration"})]}),e.jsx("h2",{className:"mt-3 text-lg sm:text-xl font-semibold text-cc-fg",children:"HTTPS access in one click"}),e.jsx("p",{className:"mt-1.5 text-sm text-cc-muted max-w-2xl",children:"Tailscale Funnel exposes HeyHank to the internet over HTTPS with automatic TLS certificates. No configuration needed."}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2 text-[11px]",children:[e.jsx("span",{className:"px-2 py-1 rounded-md bg-cc-hover text-cc-muted",children:"Automatic TLS"}),e.jsx("span",{className:"px-2 py-1 rounded-md bg-cc-hover text-cc-muted",children:"Stable *.ts.net domain"}),e.jsx("span",{className:"px-2 py-1 rounded-md bg-cc-hover text-cc-muted",children:"No API keys needed"})]})]}),e.jsxs("div",{className:"shrink-0 rounded-xl border border-cc-border bg-cc-bg px-3 py-2 text-right min-w-[170px]",children:[e.jsx("p",{className:"text-[11px] text-cc-muted uppercase tracking-wide",children:"Status"}),e.jsx("p",{className:`mt-1 text-sm font-medium ${v}`,children:j}),e.jsx("p",{className:"mt-0.5 text-[11px] text-cc-muted truncate",children:(t==null?void 0:t.dnsName)||"No machine name"})]})]})]}),e.jsxs("div",{className:"bg-cc-card border border-cc-border rounded-xl p-4 sm:p-5 space-y-4",children:[e.jsxs("h2",{className:"text-sm font-semibold text-cc-fg flex items-center gap-2",children:[e.jsx("svg",{className:"w-4 h-4 text-cc-fg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"})}),e.jsx("span",{children:"Tailscale Funnel"})]}),a&&e.jsx("p",{className:"text-sm text-cc-muted",children:"Checking Tailscale status..."}),!a&&!t&&e.jsx("p",{className:"text-sm text-cc-muted",children:"Could not check Tailscale status."}),!a&&t&&!t.installed&&e.jsxs("div",{className:"space-y-3",children:[e.jsx("p",{className:"text-sm text-cc-muted",children:"Tailscale is not installed on this machine. Install it to enable one-click HTTPS."}),e.jsxs("a",{href:"https://tailscale.com/download",target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1.5 px-4 py-2.5 min-h-[44px] rounded-lg text-sm font-medium bg-cc-hover hover:bg-cc-active text-cc-fg transition-colors",children:["Install Tailscale",e.jsxs("svg",{className:"w-3.5 h-3.5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6"}),e.jsx("polyline",{points:"15 3 21 3 21 9"}),e.jsx("line",{x1:"10",y1:"14",x2:"21",y2:"3"})]})]})]}),!a&&t&&t.installed&&!t.connected&&e.jsxs("div",{className:"space-y-3",children:[e.jsx("p",{className:"text-sm text-cc-muted",children:"Tailscale is installed but not connected to a tailnet."}),e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-hover text-xs text-cc-fg font-mono-code",children:"tailscale up"}),e.jsx("p",{className:"text-xs text-cc-muted",children:"Run this command to connect to your Tailscale network."})]}),!a&&t&&t.installed&&t.connected&&!t.funnelActive&&e.jsxs("div",{className:"space-y-3",children:[e.jsxs("p",{className:"text-sm text-cc-muted",children:["Tailscale is connected as ",e.jsx("span",{className:"font-medium text-cc-fg",children:t.dnsName}),". Enable Funnel to expose HeyHank over HTTPS."]}),t.needsOperatorMode&&!t.error&&e.jsxs("div",{className:"space-y-2 px-3 py-3 rounded-lg bg-amber-500/10 border border-amber-500/20",children:[e.jsx("p",{className:"text-xs text-amber-500 font-medium",children:"Setup needed: Tailscale operator mode"}),e.jsx("p",{className:"text-xs text-cc-muted",children:"On Linux, Tailscale requires operator mode to manage Funnel. Run this command first:"}),e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-hover text-xs text-cc-fg font-mono-code",children:"sudo tailscale set --operator=$USER"})]}),e.jsx("button",{type:"button",onClick:p,disabled:c,className:`px-4 py-2.5 min-h-[44px] rounded-lg text-sm font-medium transition-colors ${c?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-primary hover:bg-cc-primary-hover text-white cursor-pointer"}`,children:c?"Starting...":"Enable HTTPS via Tailscale Funnel"})]}),!a&&t&&t.installed&&t.connected&&t.funnelActive&&e.jsxs("div",{className:"space-y-3",children:[e.jsx("p",{className:"text-sm text-cc-muted",children:"Funnel is active. Your HeyHank is accessible at:"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("a",{href:t.funnelUrl||"#",target:"_blank",rel:"noopener noreferrer",className:"flex-1 px-3 py-2.5 min-h-[44px] text-sm bg-cc-bg rounded-lg border border-cc-border text-cc-primary font-mono-code truncate flex items-center hover:underline",children:t.funnelUrl}),e.jsx("button",{type:"button",onClick:f,className:"px-3 py-2.5 min-h-[44px] rounded-lg text-sm bg-cc-hover hover:bg-cc-active text-cc-fg transition-colors cursor-pointer",children:g?"Copied!":"Copy"})]}),e.jsx("p",{className:"text-xs text-cc-muted",children:"This URL has been automatically set as your Public URL in Settings."}),e.jsx("button",{type:"button",onClick:b,disabled:c,className:`px-4 py-2.5 min-h-[44px] rounded-lg text-sm font-medium transition-colors ${c?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-error/10 hover:bg-cc-error/20 text-cc-error cursor-pointer"}`,children:c?"Stopping...":"Disable Funnel"})]}),(t==null?void 0:t.error)&&t.needsOperatorMode&&e.jsxs("div",{className:"space-y-3 px-3 py-3 rounded-lg bg-amber-500/10 border border-amber-500/20",children:[e.jsx("p",{className:"text-sm font-medium text-amber-500",children:"Operator mode required"}),e.jsx("p",{className:"text-xs text-cc-muted",children:"On Linux, Tailscale requires operator mode to manage Funnel without sudo. Run this command once in your terminal:"}),e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-hover text-xs text-cc-fg font-mono-code",children:"sudo tailscale set --operator=$USER"}),e.jsx("p",{className:"text-xs text-cc-muted",children:"After running the command, click Retry to enable Funnel."}),e.jsx("button",{type:"button",onClick:p,disabled:c,className:`px-4 py-2.5 min-h-[44px] rounded-lg text-sm font-medium transition-colors ${c?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-primary hover:bg-cc-primary-hover text-white cursor-pointer"}`,children:c?"Retrying...":"Retry"})]}),(t==null?void 0:t.warning)&&e.jsxs("div",{className:"space-y-2 px-3 py-3 rounded-lg bg-amber-500/10 border border-amber-500/20",children:[e.jsx("p",{className:"text-sm font-medium text-amber-500",children:"URL may not be publicly accessible"}),e.jsx("p",{className:"text-xs text-cc-muted",children:t.warning}),e.jsxs("a",{href:"https://login.tailscale.com/admin/acls",target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1.5 text-xs text-cc-primary hover:underline",children:["Open Tailscale admin console",e.jsxs("svg",{className:"w-3 h-3",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6"}),e.jsx("polyline",{points:"15 3 21 3 21 9"}),e.jsx("line",{x1:"10",y1:"14",x2:"21",y2:"3"})]})]})]}),(t==null?void 0:t.error)&&!t.needsOperatorMode&&e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-error/10 border border-cc-error/20 text-xs text-cc-error",children:t.error})]}),e.jsxs("section",{className:"mt-4 grid grid-cols-1 md:grid-cols-3 gap-3",children:[e.jsxs("div",{className:"bg-cc-card border border-cc-border rounded-xl p-4",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wide text-cc-muted",children:"1. Install"}),e.jsx("p",{className:"mt-1 text-sm text-cc-fg",children:"Install Tailscale on your machine and sign in."})]}),e.jsxs("div",{className:"bg-cc-card border border-cc-border rounded-xl p-4",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wide text-cc-muted",children:"2. Enable"}),e.jsx("p",{className:"mt-1 text-sm text-cc-fg",children:"One click to get an HTTPS URL with automatic TLS."})]}),e.jsxs("div",{className:"bg-cc-card border border-cc-border rounded-xl p-4",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wide text-cc-muted",children:"3. Done"}),e.jsx("p",{className:"mt-1 text-sm text-cc-fg",children:"Webhooks and remote access just work."})]})]})]})})}export{w as TailscalePage};
1
+ import{r as l,b as i,j as e,u as d,n as N,a as y}from"./index-C6Q5UQHD.js";function w({embedded:x=!1}){const[t,r]=l.useState(null),[a,h]=l.useState(!0),[c,o]=l.useState(!1),[g,m]=l.useState(!1);l.useEffect(()=>{i.getTailscaleStatus().then(r).catch(()=>r(null)).finally(()=>h(!1))},[]);async function u(){const s=await i.getTailscaleStatus().catch(()=>null);s&&r(s)}async function p(){o(!0);try{const s=await i.startTailscaleFunnel();r(s),s.funnelUrl&&!s.error&&!s.warning&&d.getState().setPublicUrl(s.funnelUrl)}catch(s){await u(),r(n=>n?{...n,error:s instanceof Error?s.message:String(s)}:null)}finally{o(!1)}}async function b(){o(!0);try{const s=await i.stopTailscaleFunnel();r(s);const n=d.getState().publicUrl;(!n||n===(t==null?void 0:t.funnelUrl))&&d.getState().setPublicUrl("")}catch(s){await u(),r(n=>n?{...n,error:s instanceof Error?s.message:String(s)}:null)}finally{o(!1)}}function f(){t!=null&&t.funnelUrl&&navigator.clipboard.writeText(t.funnelUrl).then(()=>{m(!0),setTimeout(()=>m(!1),1800)}).catch(()=>{})}const j=t?t.installed?t.connected?t.funnelActive?"Funnel active":"Ready":"Not connected":"Not installed":"Loading...",v=t?!t.installed||!t.connected?"text-cc-muted":t.funnelActive?"text-cc-success":"text-amber-500":"text-cc-muted";return e.jsx("div",{className:`${x?"h-full":"h-[100dvh]"} bg-cc-bg text-cc-fg font-sans-ui antialiased overflow-y-auto`,children:e.jsxs("div",{className:"max-w-5xl mx-auto px-4 sm:px-8 py-6 sm:py-10 pb-safe",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3 mb-6",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-semibold text-cc-fg",children:"Tailscale Settings"}),e.jsx("p",{className:"mt-1 text-sm text-cc-muted",children:"Expose HeyHank over HTTPS with Tailscale Funnel."})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{onClick:()=>{window.location.hash="#/integrations"},className:"px-3 py-2.5 min-h-[44px] rounded-lg text-sm text-cc-muted hover:text-cc-fg hover:bg-cc-hover transition-colors cursor-pointer",children:"Integrations"}),!x&&e.jsx("button",{onClick:()=>{const s=d.getState().currentSessionId;s?N(s):y()},className:"px-3 py-2.5 min-h-[44px] rounded-lg text-sm text-cc-muted hover:text-cc-fg hover:bg-cc-hover transition-colors cursor-pointer",children:"Back"})]})]}),e.jsxs("section",{className:"relative overflow-hidden bg-cc-card border border-cc-border rounded-xl p-4 sm:p-6 mb-4",children:[e.jsx("div",{className:"absolute inset-0 pointer-events-none bg-[radial-gradient(circle_at_top_right,rgba(6,182,212,0.1),transparent_45%)]"}),e.jsxs("div",{className:"relative flex items-start justify-between gap-4 flex-wrap",children:[e.jsxs("div",{className:"min-w-0",children:[e.jsxs("div",{className:"inline-flex items-center gap-2 px-2.5 py-1 rounded-full border border-cc-border bg-cc-hover/60 text-xs text-cc-muted",children:[e.jsx("svg",{className:"w-3.5 h-3.5 text-cc-fg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"})}),e.jsx("span",{children:"Tailscale Integration"})]}),e.jsx("h2",{className:"mt-3 text-lg sm:text-xl font-semibold text-cc-fg",children:"HTTPS access in one click"}),e.jsx("p",{className:"mt-1.5 text-sm text-cc-muted max-w-2xl",children:"Tailscale Funnel exposes HeyHank to the internet over HTTPS with automatic TLS certificates. No configuration needed."}),e.jsxs("div",{className:"mt-3 flex flex-wrap gap-2 text-[11px]",children:[e.jsx("span",{className:"px-2 py-1 rounded-md bg-cc-hover text-cc-muted",children:"Automatic TLS"}),e.jsx("span",{className:"px-2 py-1 rounded-md bg-cc-hover text-cc-muted",children:"Stable *.ts.net domain"}),e.jsx("span",{className:"px-2 py-1 rounded-md bg-cc-hover text-cc-muted",children:"No API keys needed"})]})]}),e.jsxs("div",{className:"shrink-0 rounded-xl border border-cc-border bg-cc-bg px-3 py-2 text-right min-w-[170px]",children:[e.jsx("p",{className:"text-[11px] text-cc-muted uppercase tracking-wide",children:"Status"}),e.jsx("p",{className:`mt-1 text-sm font-medium ${v}`,children:j}),e.jsx("p",{className:"mt-0.5 text-[11px] text-cc-muted truncate",children:(t==null?void 0:t.dnsName)||"No machine name"})]})]})]}),e.jsxs("div",{className:"bg-cc-card border border-cc-border rounded-xl p-4 sm:p-5 space-y-4",children:[e.jsxs("h2",{className:"text-sm font-semibold text-cc-fg flex items-center gap-2",children:[e.jsx("svg",{className:"w-4 h-4 text-cc-fg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:e.jsx("path",{d:"M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"})}),e.jsx("span",{children:"Tailscale Funnel"})]}),a&&e.jsx("p",{className:"text-sm text-cc-muted",children:"Checking Tailscale status..."}),!a&&!t&&e.jsx("p",{className:"text-sm text-cc-muted",children:"Could not check Tailscale status."}),!a&&t&&!t.installed&&e.jsxs("div",{className:"space-y-3",children:[e.jsx("p",{className:"text-sm text-cc-muted",children:"Tailscale is not installed on this machine. Install it to enable one-click HTTPS."}),e.jsxs("a",{href:"https://tailscale.com/download",target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1.5 px-4 py-2.5 min-h-[44px] rounded-lg text-sm font-medium bg-cc-hover hover:bg-cc-active text-cc-fg transition-colors",children:["Install Tailscale",e.jsxs("svg",{className:"w-3.5 h-3.5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6"}),e.jsx("polyline",{points:"15 3 21 3 21 9"}),e.jsx("line",{x1:"10",y1:"14",x2:"21",y2:"3"})]})]})]}),!a&&t&&t.installed&&!t.connected&&e.jsxs("div",{className:"space-y-3",children:[e.jsx("p",{className:"text-sm text-cc-muted",children:"Tailscale is installed but not connected to a tailnet."}),e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-hover text-xs text-cc-fg font-mono-code",children:"tailscale up"}),e.jsx("p",{className:"text-xs text-cc-muted",children:"Run this command to connect to your Tailscale network."})]}),!a&&t&&t.installed&&t.connected&&!t.funnelActive&&e.jsxs("div",{className:"space-y-3",children:[e.jsxs("p",{className:"text-sm text-cc-muted",children:["Tailscale is connected as ",e.jsx("span",{className:"font-medium text-cc-fg",children:t.dnsName}),". Enable Funnel to expose HeyHank over HTTPS."]}),t.needsOperatorMode&&!t.error&&e.jsxs("div",{className:"space-y-2 px-3 py-3 rounded-lg bg-amber-500/10 border border-amber-500/20",children:[e.jsx("p",{className:"text-xs text-amber-500 font-medium",children:"Setup needed: Tailscale operator mode"}),e.jsx("p",{className:"text-xs text-cc-muted",children:"On Linux, Tailscale requires operator mode to manage Funnel. Run this command first:"}),e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-hover text-xs text-cc-fg font-mono-code",children:"sudo tailscale set --operator=$USER"})]}),e.jsx("button",{type:"button",onClick:p,disabled:c,className:`px-4 py-2.5 min-h-[44px] rounded-lg text-sm font-medium transition-colors ${c?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-primary hover:bg-cc-primary-hover text-white cursor-pointer"}`,children:c?"Starting...":"Enable HTTPS via Tailscale Funnel"})]}),!a&&t&&t.installed&&t.connected&&t.funnelActive&&e.jsxs("div",{className:"space-y-3",children:[e.jsx("p",{className:"text-sm text-cc-muted",children:"Funnel is active. Your HeyHank is accessible at:"}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("a",{href:t.funnelUrl||"#",target:"_blank",rel:"noopener noreferrer",className:"flex-1 px-3 py-2.5 min-h-[44px] text-sm bg-cc-bg rounded-lg border border-cc-border text-cc-primary font-mono-code truncate flex items-center hover:underline",children:t.funnelUrl}),e.jsx("button",{type:"button",onClick:f,className:"px-3 py-2.5 min-h-[44px] rounded-lg text-sm bg-cc-hover hover:bg-cc-active text-cc-fg transition-colors cursor-pointer",children:g?"Copied!":"Copy"})]}),e.jsx("p",{className:"text-xs text-cc-muted",children:"This URL has been automatically set as your Public URL in Settings."}),e.jsx("button",{type:"button",onClick:b,disabled:c,className:`px-4 py-2.5 min-h-[44px] rounded-lg text-sm font-medium transition-colors ${c?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-error/10 hover:bg-cc-error/20 text-cc-error cursor-pointer"}`,children:c?"Stopping...":"Disable Funnel"})]}),(t==null?void 0:t.error)&&t.needsOperatorMode&&e.jsxs("div",{className:"space-y-3 px-3 py-3 rounded-lg bg-amber-500/10 border border-amber-500/20",children:[e.jsx("p",{className:"text-sm font-medium text-amber-500",children:"Operator mode required"}),e.jsx("p",{className:"text-xs text-cc-muted",children:"On Linux, Tailscale requires operator mode to manage Funnel without sudo. Run this command once in your terminal:"}),e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-hover text-xs text-cc-fg font-mono-code",children:"sudo tailscale set --operator=$USER"}),e.jsx("p",{className:"text-xs text-cc-muted",children:"After running the command, click Retry to enable Funnel."}),e.jsx("button",{type:"button",onClick:p,disabled:c,className:`px-4 py-2.5 min-h-[44px] rounded-lg text-sm font-medium transition-colors ${c?"bg-cc-hover text-cc-muted cursor-not-allowed":"bg-cc-primary hover:bg-cc-primary-hover text-white cursor-pointer"}`,children:c?"Retrying...":"Retry"})]}),(t==null?void 0:t.warning)&&e.jsxs("div",{className:"space-y-2 px-3 py-3 rounded-lg bg-amber-500/10 border border-amber-500/20",children:[e.jsx("p",{className:"text-sm font-medium text-amber-500",children:"URL may not be publicly accessible"}),e.jsx("p",{className:"text-xs text-cc-muted",children:t.warning}),e.jsxs("a",{href:"https://login.tailscale.com/admin/acls",target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center gap-1.5 text-xs text-cc-primary hover:underline",children:["Open Tailscale admin console",e.jsxs("svg",{className:"w-3 h-3",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[e.jsx("path",{d:"M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6"}),e.jsx("polyline",{points:"15 3 21 3 21 9"}),e.jsx("line",{x1:"10",y1:"14",x2:"21",y2:"3"})]})]})]}),(t==null?void 0:t.error)&&!t.needsOperatorMode&&e.jsx("div",{className:"px-3 py-2 rounded-lg bg-cc-error/10 border border-cc-error/20 text-xs text-cc-error",children:t.error})]}),e.jsxs("section",{className:"mt-4 grid grid-cols-1 md:grid-cols-3 gap-3",children:[e.jsxs("div",{className:"bg-cc-card border border-cc-border rounded-xl p-4",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wide text-cc-muted",children:"1. Install"}),e.jsx("p",{className:"mt-1 text-sm text-cc-fg",children:"Install Tailscale on your machine and sign in."})]}),e.jsxs("div",{className:"bg-cc-card border border-cc-border rounded-xl p-4",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wide text-cc-muted",children:"2. Enable"}),e.jsx("p",{className:"mt-1 text-sm text-cc-fg",children:"One click to get an HTTPS URL with automatic TLS."})]}),e.jsxs("div",{className:"bg-cc-card border border-cc-border rounded-xl p-4",children:[e.jsx("p",{className:"text-[11px] uppercase tracking-wide text-cc-muted",children:"3. Done"}),e.jsx("p",{className:"mt-1 text-sm text-cc-fg",children:"Webhooks and remote access just work."})]})]})]})})}export{w as TailscalePage};
@@ -1,4 +1,4 @@
1
- import{r as l,b as x,j as e}from"./index-BgYM4wXw.js";const X=[{code:"en",label:"English",flag:"🇬🇧"},{code:"de",label:"Deutsch",flag:"🇩🇪"},{code:"fr",label:"Français",flag:"🇫🇷"},{code:"it",label:"Italiano",flag:"🇮🇹"},{code:"es",label:"Español",flag:"🇪🇸"},{code:"pt",label:"Português",flag:"🇵🇹"},{code:"nl",label:"Nederlands",flag:"🇳🇱"},{code:"pl",label:"Polski",flag:"🇵🇱"},{code:"cs",label:"Čeština",flag:"🇨🇿"},{code:"hu",label:"Magyar",flag:"🇭🇺"},{code:"ro",label:"Română",flag:"🇷🇴"},{code:"tr",label:"Türkçe",flag:"🇹🇷"},{code:"ru",label:"Русский",flag:"🇷🇺"},{code:"ja",label:"日本語",flag:"🇯🇵"},{code:"zh",label:"中文",flag:"🇨🇳"},{code:"ko",label:"한국어",flag:"🇰🇷"},{code:"ar",label:"العربية",flag:"🇸🇦"}];function Je({embedded:g}){var xe,pe,ue,he,me,ge,be,ve,fe,je,ye,Ne;const[b,f]=l.useState(""),[N,O]=l.useState(""),[_,ee]=l.useState(!1),[te,n]=l.useState(null),[z,Ce]=l.useState(50),[r,j]=l.useState(null),[P,E]=l.useState(!1),[U,se]=l.useState(!1),[ke,W]=l.useState(!1),[A,re]=l.useState(null),[F,ce]=l.useState(!1),[d,v]=l.useState({name:"peoplefone",provider:"peoplefone",username:"",password:"",server:"sip.peoplefone.at",callerId:"",enabled:!0}),[ae,Se]=l.useState([]),[q,Te]=l.useState([]),[u,J]=l.useState(null),[I,D]=l.useState([]),L=l.useRef(null),w=l.useRef(null),[G,C]=l.useState([]),[$,le]=l.useState(!1),[h,k]=l.useState({name:"",phone:"",notes:"",language:"en"}),[R,Z]=l.useState(null),[m,S]=l.useState({name:"",phone:"",notes:"",language:"en"}),[y,Q]=l.useState(null),[B,V]=l.useState("simple"),[H,M]=l.useState(""),[a,p]=l.useState(null),[ne,oe]=l.useState(!1);l.useEffect(()=>{K();const t=setInterval(K,5e3);return()=>clearInterval(t)},[z]),l.useEffect(()=>{x.getContacts().then(t=>C(t.contacts)).catch(t=>{n(t instanceof Error?t.message:"Failed to load contacts"),setTimeout(()=>n(null),5e3)}),x.getTelephonySettings().then(t=>j(t)).catch(t=>{n(t instanceof Error?t.message:"Failed to load settings"),setTimeout(()=>n(null),5e3)})},[]),l.useEffect(()=>{L.current&&(L.current.scrollTop=L.current.scrollHeight)},[I]);async function K(){try{const[t,s]=await Promise.all([x.getActiveCalls(),x.getCallHistory(z)]);Se(t.calls),Te(s.calls)}catch(t){n(t instanceof Error?t.message:"Failed to load call data"),setTimeout(()=>n(null),5e3)}}async function Pe(){if(!(!b.trim()||!N.trim()||_)){ee(!0),n(null);try{const t=await x.startCall({phone:b.trim(),prompt:N.trim()});t.error?n(t.error):(f(""),O(""),ie(t.id),K())}catch(t){n(t instanceof Error?t.message:"Failed to start call")}finally{ee(!1)}}}function ie(t){w.current&&w.current.close(),D([]);const s=window.location.protocol==="https:"?"wss:":"ws:",c=new WebSocket(`${s}//${window.location.host}/ws/telephony/transcript/${t}`);c.onmessage=o=>{try{const Y=JSON.parse(o.data);Y.type==="transcript"&&Y.entry&&D(ze=>[...ze,Y.entry])}catch{}},c.onclose=()=>{w.current=null},w.current=c}async function Ee(t){if(confirm("End this call?"))try{await x.endCall(t),K()}catch(s){n(s instanceof Error?s.message:"Failed to end call"),setTimeout(()=>n(null),5e3)}}async function Ae(){if(!(!h.name.trim()||!h.phone.trim()))try{const t=await x.addContact(h);C(s=>[...s,t]),k({name:"",phone:"",notes:"",language:"en"}),le(!1)}catch(t){n(t instanceof Error?t.message:"Failed to add contact"),setTimeout(()=>n(null),5e3)}}async function Fe(t){if(confirm("Remove this contact?"))try{await x.deleteContact(t),C(s=>s.filter(c=>c.id!==t))}catch(s){n(s instanceof Error?s.message:"Failed to remove contact"),setTimeout(()=>n(null),5e3)}}async function Ie(){if(R)try{const t=await x.updateContact(R,m);C(s=>s.map(c=>c.id===R?t:c)),Z(null)}catch(t){n(t instanceof Error?t.message:"Failed to save contact"),setTimeout(()=>n(null),5e3)}}function De(t){Q(t.id),t.callFlow&&t.callFlow.nodes.length>0?(V("flow"),p(t.callFlow),M(t.script||"")):(V("simple"),M(t.script||""),p(t.callFlow||null))}async function Le(){if(y){oe(!0);try{const t={};B==="simple"?(t.script=H.trim()||void 0,a&&(t.callFlow=a)):(t.callFlow=a,t.script=H.trim()||void 0);const s=await x.updateContact(y,t);C(c=>c.map(o=>o.id===y?{...o,...s}:o))}catch(t){n(t instanceof Error?t.message:"Failed to save script"),setTimeout(()=>n(null),5e3)}oe(!1),Q(null)}}function Ge(t){if(!a)return;const s=`node_${Date.now()}`,c=a.nodes.length,o={id:s,type:t,label:t==="start"?"Start":t==="end"?"End":`${t.charAt(0).toUpperCase()+t.slice(1)} ${c}`,prompt:"",position:{x:100,y:80+c*100}};p({...a,nodes:[...a.nodes,o]})}function T(t,s){a&&p({...a,nodes:a.nodes.map(c=>c.id===t?{...c,...s}:c)})}function $e(t){a&&confirm("Delete this flow node? Connected edges will also be removed.")&&p({...a,nodes:a.nodes.filter(s=>s.id!==t),edges:a.edges.filter(s=>s.from!==t&&s.to!==t)})}function Re(t,s,c){if(!a)return;const o=`edge_${Date.now()}`;p({...a,edges:[...a.edges,{id:o,from:t,to:s,label:""}]})}function Be(t){a&&confirm("Delete this flow edge?")&&p({...a,edges:a.edges.filter(s=>s.id!==t)})}function Ve(){const t=G.find(s=>s.id===y);p({id:`flow_${Date.now()}`,name:t!=null&&t.name?`${t.name} Script`:"Call Script",nodes:[{id:"start_1",type:"start",label:"Start",position:{x:100,y:50}},{id:"say_1",type:"say",label:"Greeting",prompt:"Greet the person naturally",position:{x:100,y:150}},{id:"ask_1",type:"ask",label:"Main Question",prompt:"",expectedResponses:["yes","no"],position:{x:100,y:250}},{id:"end_1",type:"end",label:"Goodbye",prompt:"Thank them and say goodbye",position:{x:100,y:350}}],edges:[{id:"e1",from:"start_1",to:"say_1",label:"begin"},{id:"e2",from:"say_1",to:"ask_1",label:"then"},{id:"e3",from:"ask_1",to:"end_1",label:"default"}]})}async function He(t){E(!0);try{await x.updateTelephonySettings(t);const s=await x.getTelephonySettings();j(s)}catch(s){n(s instanceof Error?s.message:"Failed to save settings"),setTimeout(()=>n(null),5e3)}E(!1)}function i(t){j(s=>s&&{...s,...t}),se(!0),W(!1)}async function Me(){if(r){E(!0);try{await x.updateTelephonySettings({freeswitch:r.freeswitch,defaultVoice:r.defaultVoice,maxCallDurationSeconds:r.maxCallDurationSeconds,geminiBackend:r.geminiBackend,gcpProjectId:r.gcpProjectId,gcpLocation:r.gcpLocation,gcpServiceAccountKey:r.gcpServiceAccountKey,...r.defaultLanguage&&{defaultLanguage:r.defaultLanguage},...r.inboundEnabled!==void 0&&{inboundEnabled:r.inboundEnabled},...r.defaultInboundPrompt&&{defaultInboundPrompt:r.defaultInboundPrompt},...r.defaultInboundVoice&&{defaultInboundVoice:r.defaultInboundVoice},...r.inboundKnowledgeBase!==void 0&&{inboundKnowledgeBase:r.inboundKnowledgeBase},...r.voicePipeline!==void 0&&{voicePipeline:r.voicePipeline}});const t=await x.getTelephonySettings();j(t),se(!1),W(!0),setTimeout(()=>W(!1),3e3)}catch(t){n(t instanceof Error?t.message:"Failed to save settings"),setTimeout(()=>n(null),5e3)}E(!1)}}async function Ke(){re(null);const t=await x.testFreeSwitchConnection();re(t)}async function Oe(){if(!(!d.username||!d.password||!d.server))try{await fetch("/api/telephony/trunks",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(d)});const t=await x.getTelephonySettings();j(t),ce(!1),v({name:"peoplefone",provider:"peoplefone",username:"",password:"",server:"sip.peoplefone.at",callerId:"",enabled:!0})}catch(t){n(t instanceof Error?t.message:"Failed to add trunk"),setTimeout(()=>n(null),5e3)}}async function _e(t){if(confirm("Remove this SIP trunk? Inbound calls via this trunk will stop working."))try{await fetch(`/api/telephony/trunks/${encodeURIComponent(t)}`,{method:"DELETE"});const s=await x.getTelephonySettings();j(s)}catch(s){n(s instanceof Error?s.message:"Failed to remove trunk"),setTimeout(()=>n(null),5e3)}}function de(t){J(t),t.status==="active"||t.status==="dialing"||t.status==="ringing"?ie(t.id):x.getCall(t.id).then(s=>{J({...t,...s}),D(s.transcript||[])}).catch(s=>{n(s instanceof Error?s.message:"Failed to load call details"),setTimeout(()=>n(null),5e3)})}return r===null?e.jsx("div",{className:"h-full flex items-center justify-center",children:e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"w-6 h-6 border-2 border-cc-muted/30 border-t-cc-primary rounded-full animate-spin mx-auto mb-3"}),e.jsx("p",{className:"text-sm text-cc-muted",children:"Loading..."})]})}):e.jsxs("div",{className:"h-full overflow-y-auto bg-cc-bg",children:[te&&e.jsx("div",{className:"fixed top-4 left-1/2 -translate-x-1/2 z-50 px-4 py-2.5 rounded-lg bg-red-600 text-white text-sm shadow-lg max-w-md",role:"alert",children:te}),e.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-8 py-6 sm:py-10 pb-safe",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-lg font-semibold text-cc-fg",children:"Telephony"}),e.jsx("p",{className:"text-xs text-cc-muted mt-1",children:"Make AI-powered phone calls via FreeSWITCH + Gemini Live."})]}),e.jsxs("div",{className:"bg-cc-card border border-cc-border rounded-xl p-4 mb-6",children:[e.jsx("h2",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider mb-3",children:"New Call"}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{children:e.jsx("input",{type:"tel",value:b,onChange:t=>f(t.target.value),placeholder:"+43 664 1234567","aria-label":"Phone number to call",className:"w-full px-3 py-2 text-sm bg-cc-bg border border-cc-border rounded-lg text-cc-fg placeholder:text-cc-muted/60 focus:outline-none focus:border-cc-primary"})}),e.jsx("div",{children:e.jsx("textarea",{value:N,onChange:t=>O(t.target.value),placeholder:"Task for the AI (e.g. 'Reserve a table for 4 at 7pm on Friday')",rows:2,"aria-label":"Call prompt or task for the AI",className:"w-full px-3 py-2 text-sm bg-cc-bg border border-cc-border rounded-lg text-cc-fg placeholder:text-cc-muted/60 focus:outline-none focus:border-cc-primary resize-none"})}),e.jsx("button",{onClick:Pe,disabled:!b.trim()||!N.trim()||_,className:"px-4 py-2 rounded-lg text-xs font-medium bg-green-600 text-white hover:bg-green-500 transition-colors cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed",children:_?e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"w-3 h-3 border-2 border-white/30 border-t-white rounded-full animate-spin"}),"Dialing..."]}):e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx(Ue,{className:"w-3.5 h-3.5"}),"Call"]})})]})]}),e.jsxs("div",{className:"bg-cc-card border border-cc-border rounded-xl p-4 mb-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h2",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider",children:"Contacts"}),e.jsx("button",{onClick:()=>le(!$),className:"text-xs text-cc-primary hover:text-cc-primary/80 transition-colors cursor-pointer",children:$?"Cancel":"+ Add"})]}),$&&e.jsxs("div",{className:"bg-cc-bg rounded-lg p-3 border border-cc-border space-y-2 mb-3",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] text-cc-muted",children:"Name"}),e.jsx("input",{type:"text",value:h.name,onChange:t=>k({...h,name:t.target.value}),placeholder:"e.g. Mama",className:"w-full px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] text-cc-muted",children:"Phone"}),e.jsx("input",{type:"tel",value:h.phone,onChange:t=>k({...h,phone:t.target.value}),placeholder:"+43...",className:"w-full px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg"})]})]}),e.jsxs("div",{className:"grid grid-cols-[1fr_auto] gap-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] text-cc-muted",children:"Notes (optional)"}),e.jsx("input",{type:"text",value:h.notes,onChange:t=>k({...h,notes:t.target.value}),placeholder:"e.g. Mo-Sa 10-18 Uhr",className:"w-full px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] text-cc-muted",children:"Language"}),e.jsx("select",{value:h.language,onChange:t=>k({...h,language:t.target.value}),className:"w-full px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg w-28",children:X.map(t=>e.jsxs("option",{value:t.code,children:[t.flag," ",t.label]},t.code))})]})]}),e.jsx("button",{onClick:Ae,disabled:!h.name.trim()||!h.phone.trim(),className:"px-3 py-1.5 text-xs rounded bg-green-600 text-white hover:bg-green-500 transition-colors cursor-pointer disabled:opacity-50",children:"Add Contact"})]}),G.length===0&&!$?e.jsx("p",{className:"text-xs text-cc-muted",children:"No contacts yet. Add contacts so Gemini can call them by name."}):e.jsx("div",{className:"space-y-1.5",children:G.map(t=>{var s;return e.jsx("div",{className:"bg-cc-bg rounded-lg px-3 py-2 border border-cc-border",children:R===t.id?e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsx("input",{type:"text",value:m.name,onChange:c=>S({...m,name:c.target.value}),className:"px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg"}),e.jsx("input",{type:"tel",value:m.phone,onChange:c=>S({...m,phone:c.target.value}),className:"px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg"})]}),e.jsxs("div",{className:"grid grid-cols-[1fr_auto] gap-2",children:[e.jsx("input",{type:"text",value:m.notes,onChange:c=>S({...m,notes:c.target.value}),placeholder:"Notes",className:"px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg"}),e.jsx("select",{value:m.language,onChange:c=>S({...m,language:c.target.value}),className:"px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg w-28",children:X.map(c=>e.jsxs("option",{value:c.code,children:[c.flag," ",c.label]},c.code))})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:Ie,className:"px-2 py-1 text-[11px] rounded bg-green-600 text-white hover:bg-green-500 cursor-pointer",children:"Save"}),e.jsx("button",{onClick:()=>Z(null),className:"px-2 py-1 text-[11px] rounded bg-cc-hover text-cc-muted hover:text-cc-fg cursor-pointer",children:"Cancel"})]})]}):e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("button",{onClick:()=>{f(t.phone),!N.trim()&&t.script&&O(t.script)},className:"min-w-0 flex-1 text-left cursor-pointer hover:opacity-80",title:"Click to use this number",children:[e.jsx("p",{className:"text-xs font-medium text-cc-fg",children:t.name}),e.jsxs("p",{className:"text-[11px] text-cc-muted",children:[t.phone,t.language&&e.jsxs("span",{className:"ml-1",children:[" ",((s=X.find(c=>c.code===t.language))==null?void 0:s.flag)||""]}),t.notes?` — ${t.notes}`:"",(t.script||t.callFlow)&&e.jsx("span",{className:"ml-1.5 text-green-500 text-[9px]",children:"(script)"})]})]}),e.jsxs("div",{className:"flex items-center gap-1 ml-2 shrink-0",children:[e.jsx("button",{onClick:()=>De(t),className:`px-2 py-1.5 text-[11px] rounded transition-colors cursor-pointer ${t.script||t.callFlow?"text-green-500 hover:text-green-400 hover:bg-green-500/10":"text-cc-muted hover:text-cc-fg hover:bg-cc-hover"}`,title:t.script||t.callFlow?"Edit call script":"Add call script",children:t.script||t.callFlow?"Script":"+ Script"}),e.jsx("button",{onClick:()=>{Z(t.id),S({name:t.name,phone:t.phone,notes:t.notes||"",language:t.language||"en"})},className:"px-3 py-2 min-h-[44px] text-[11px] text-cc-muted hover:text-cc-fg hover:bg-cc-hover rounded transition-colors cursor-pointer",children:"Edit"}),e.jsx("button",{onClick:()=>Fe(t.id),"aria-label":`Remove contact ${t.name}`,className:"px-3 py-2 min-h-[44px] text-[11px] text-red-400 hover:text-red-300 hover:bg-red-500/10 rounded transition-colors cursor-pointer",children:"Remove"})]})]})},t.id)})})]}),y&&e.jsxs("div",{className:"bg-cc-card border border-cc-border rounded-xl p-4 mb-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsxs("div",{children:[e.jsxs("h2",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider",children:["Call Script — ",(xe=G.find(t=>t.id===y))==null?void 0:xe.name]}),e.jsx("p",{className:"text-[10px] text-cc-muted mt-0.5",children:"Define what Gemini should say and how to handle responses during the call."})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsxs("div",{className:"flex bg-cc-bg rounded-lg border border-cc-border overflow-hidden",children:[e.jsx("button",{onClick:()=>V("simple"),className:`px-2.5 py-1 text-[11px] transition-colors cursor-pointer ${B==="simple"?"bg-cc-primary text-white":"text-cc-muted hover:text-cc-fg"}`,children:"Simple"}),e.jsx("button",{onClick:()=>V("flow"),className:`px-2.5 py-1 text-[11px] transition-colors cursor-pointer ${B==="flow"?"bg-cc-primary text-white":"text-cc-muted hover:text-cc-fg"}`,children:"Flow Builder"})]})})]}),B==="simple"?e.jsxs("div",{className:"space-y-2",children:[e.jsx("textarea",{value:H,onChange:t=>M(t.target.value),placeholder:`Example script:
1
+ import{r as l,b as x,j as e}from"./index-C6Q5UQHD.js";const X=[{code:"en",label:"English",flag:"🇬🇧"},{code:"de",label:"Deutsch",flag:"🇩🇪"},{code:"fr",label:"Français",flag:"🇫🇷"},{code:"it",label:"Italiano",flag:"🇮🇹"},{code:"es",label:"Español",flag:"🇪🇸"},{code:"pt",label:"Português",flag:"🇵🇹"},{code:"nl",label:"Nederlands",flag:"🇳🇱"},{code:"pl",label:"Polski",flag:"🇵🇱"},{code:"cs",label:"Čeština",flag:"🇨🇿"},{code:"hu",label:"Magyar",flag:"🇭🇺"},{code:"ro",label:"Română",flag:"🇷🇴"},{code:"tr",label:"Türkçe",flag:"🇹🇷"},{code:"ru",label:"Русский",flag:"🇷🇺"},{code:"ja",label:"日本語",flag:"🇯🇵"},{code:"zh",label:"中文",flag:"🇨🇳"},{code:"ko",label:"한국어",flag:"🇰🇷"},{code:"ar",label:"العربية",flag:"🇸🇦"}];function Je({embedded:g}){var xe,pe,ue,he,me,ge,be,ve,fe,je,ye,Ne;const[b,f]=l.useState(""),[N,O]=l.useState(""),[_,ee]=l.useState(!1),[te,n]=l.useState(null),[z,Ce]=l.useState(50),[r,j]=l.useState(null),[P,E]=l.useState(!1),[U,se]=l.useState(!1),[ke,W]=l.useState(!1),[A,re]=l.useState(null),[F,ce]=l.useState(!1),[d,v]=l.useState({name:"peoplefone",provider:"peoplefone",username:"",password:"",server:"sip.peoplefone.at",callerId:"",enabled:!0}),[ae,Se]=l.useState([]),[q,Te]=l.useState([]),[u,J]=l.useState(null),[I,D]=l.useState([]),L=l.useRef(null),w=l.useRef(null),[G,C]=l.useState([]),[$,le]=l.useState(!1),[h,k]=l.useState({name:"",phone:"",notes:"",language:"en"}),[R,Z]=l.useState(null),[m,S]=l.useState({name:"",phone:"",notes:"",language:"en"}),[y,Q]=l.useState(null),[B,V]=l.useState("simple"),[H,M]=l.useState(""),[a,p]=l.useState(null),[ne,oe]=l.useState(!1);l.useEffect(()=>{K();const t=setInterval(K,5e3);return()=>clearInterval(t)},[z]),l.useEffect(()=>{x.getContacts().then(t=>C(t.contacts)).catch(t=>{n(t instanceof Error?t.message:"Failed to load contacts"),setTimeout(()=>n(null),5e3)}),x.getTelephonySettings().then(t=>j(t)).catch(t=>{n(t instanceof Error?t.message:"Failed to load settings"),setTimeout(()=>n(null),5e3)})},[]),l.useEffect(()=>{L.current&&(L.current.scrollTop=L.current.scrollHeight)},[I]);async function K(){try{const[t,s]=await Promise.all([x.getActiveCalls(),x.getCallHistory(z)]);Se(t.calls),Te(s.calls)}catch(t){n(t instanceof Error?t.message:"Failed to load call data"),setTimeout(()=>n(null),5e3)}}async function Pe(){if(!(!b.trim()||!N.trim()||_)){ee(!0),n(null);try{const t=await x.startCall({phone:b.trim(),prompt:N.trim()});t.error?n(t.error):(f(""),O(""),ie(t.id),K())}catch(t){n(t instanceof Error?t.message:"Failed to start call")}finally{ee(!1)}}}function ie(t){w.current&&w.current.close(),D([]);const s=window.location.protocol==="https:"?"wss:":"ws:",c=new WebSocket(`${s}//${window.location.host}/ws/telephony/transcript/${t}`);c.onmessage=o=>{try{const Y=JSON.parse(o.data);Y.type==="transcript"&&Y.entry&&D(ze=>[...ze,Y.entry])}catch{}},c.onclose=()=>{w.current=null},w.current=c}async function Ee(t){if(confirm("End this call?"))try{await x.endCall(t),K()}catch(s){n(s instanceof Error?s.message:"Failed to end call"),setTimeout(()=>n(null),5e3)}}async function Ae(){if(!(!h.name.trim()||!h.phone.trim()))try{const t=await x.addContact(h);C(s=>[...s,t]),k({name:"",phone:"",notes:"",language:"en"}),le(!1)}catch(t){n(t instanceof Error?t.message:"Failed to add contact"),setTimeout(()=>n(null),5e3)}}async function Fe(t){if(confirm("Remove this contact?"))try{await x.deleteContact(t),C(s=>s.filter(c=>c.id!==t))}catch(s){n(s instanceof Error?s.message:"Failed to remove contact"),setTimeout(()=>n(null),5e3)}}async function Ie(){if(R)try{const t=await x.updateContact(R,m);C(s=>s.map(c=>c.id===R?t:c)),Z(null)}catch(t){n(t instanceof Error?t.message:"Failed to save contact"),setTimeout(()=>n(null),5e3)}}function De(t){Q(t.id),t.callFlow&&t.callFlow.nodes.length>0?(V("flow"),p(t.callFlow),M(t.script||"")):(V("simple"),M(t.script||""),p(t.callFlow||null))}async function Le(){if(y){oe(!0);try{const t={};B==="simple"?(t.script=H.trim()||void 0,a&&(t.callFlow=a)):(t.callFlow=a,t.script=H.trim()||void 0);const s=await x.updateContact(y,t);C(c=>c.map(o=>o.id===y?{...o,...s}:o))}catch(t){n(t instanceof Error?t.message:"Failed to save script"),setTimeout(()=>n(null),5e3)}oe(!1),Q(null)}}function Ge(t){if(!a)return;const s=`node_${Date.now()}`,c=a.nodes.length,o={id:s,type:t,label:t==="start"?"Start":t==="end"?"End":`${t.charAt(0).toUpperCase()+t.slice(1)} ${c}`,prompt:"",position:{x:100,y:80+c*100}};p({...a,nodes:[...a.nodes,o]})}function T(t,s){a&&p({...a,nodes:a.nodes.map(c=>c.id===t?{...c,...s}:c)})}function $e(t){a&&confirm("Delete this flow node? Connected edges will also be removed.")&&p({...a,nodes:a.nodes.filter(s=>s.id!==t),edges:a.edges.filter(s=>s.from!==t&&s.to!==t)})}function Re(t,s,c){if(!a)return;const o=`edge_${Date.now()}`;p({...a,edges:[...a.edges,{id:o,from:t,to:s,label:""}]})}function Be(t){a&&confirm("Delete this flow edge?")&&p({...a,edges:a.edges.filter(s=>s.id!==t)})}function Ve(){const t=G.find(s=>s.id===y);p({id:`flow_${Date.now()}`,name:t!=null&&t.name?`${t.name} Script`:"Call Script",nodes:[{id:"start_1",type:"start",label:"Start",position:{x:100,y:50}},{id:"say_1",type:"say",label:"Greeting",prompt:"Greet the person naturally",position:{x:100,y:150}},{id:"ask_1",type:"ask",label:"Main Question",prompt:"",expectedResponses:["yes","no"],position:{x:100,y:250}},{id:"end_1",type:"end",label:"Goodbye",prompt:"Thank them and say goodbye",position:{x:100,y:350}}],edges:[{id:"e1",from:"start_1",to:"say_1",label:"begin"},{id:"e2",from:"say_1",to:"ask_1",label:"then"},{id:"e3",from:"ask_1",to:"end_1",label:"default"}]})}async function He(t){E(!0);try{await x.updateTelephonySettings(t);const s=await x.getTelephonySettings();j(s)}catch(s){n(s instanceof Error?s.message:"Failed to save settings"),setTimeout(()=>n(null),5e3)}E(!1)}function i(t){j(s=>s&&{...s,...t}),se(!0),W(!1)}async function Me(){if(r){E(!0);try{await x.updateTelephonySettings({freeswitch:r.freeswitch,defaultVoice:r.defaultVoice,maxCallDurationSeconds:r.maxCallDurationSeconds,geminiBackend:r.geminiBackend,gcpProjectId:r.gcpProjectId,gcpLocation:r.gcpLocation,gcpServiceAccountKey:r.gcpServiceAccountKey,...r.defaultLanguage&&{defaultLanguage:r.defaultLanguage},...r.inboundEnabled!==void 0&&{inboundEnabled:r.inboundEnabled},...r.defaultInboundPrompt&&{defaultInboundPrompt:r.defaultInboundPrompt},...r.defaultInboundVoice&&{defaultInboundVoice:r.defaultInboundVoice},...r.inboundKnowledgeBase!==void 0&&{inboundKnowledgeBase:r.inboundKnowledgeBase},...r.voicePipeline!==void 0&&{voicePipeline:r.voicePipeline}});const t=await x.getTelephonySettings();j(t),se(!1),W(!0),setTimeout(()=>W(!1),3e3)}catch(t){n(t instanceof Error?t.message:"Failed to save settings"),setTimeout(()=>n(null),5e3)}E(!1)}}async function Ke(){re(null);const t=await x.testFreeSwitchConnection();re(t)}async function Oe(){if(!(!d.username||!d.password||!d.server))try{await fetch("/api/telephony/trunks",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(d)});const t=await x.getTelephonySettings();j(t),ce(!1),v({name:"peoplefone",provider:"peoplefone",username:"",password:"",server:"sip.peoplefone.at",callerId:"",enabled:!0})}catch(t){n(t instanceof Error?t.message:"Failed to add trunk"),setTimeout(()=>n(null),5e3)}}async function _e(t){if(confirm("Remove this SIP trunk? Inbound calls via this trunk will stop working."))try{await fetch(`/api/telephony/trunks/${encodeURIComponent(t)}`,{method:"DELETE"});const s=await x.getTelephonySettings();j(s)}catch(s){n(s instanceof Error?s.message:"Failed to remove trunk"),setTimeout(()=>n(null),5e3)}}function de(t){J(t),t.status==="active"||t.status==="dialing"||t.status==="ringing"?ie(t.id):x.getCall(t.id).then(s=>{J({...t,...s}),D(s.transcript||[])}).catch(s=>{n(s instanceof Error?s.message:"Failed to load call details"),setTimeout(()=>n(null),5e3)})}return r===null?e.jsx("div",{className:"h-full flex items-center justify-center",children:e.jsxs("div",{className:"text-center",children:[e.jsx("div",{className:"w-6 h-6 border-2 border-cc-muted/30 border-t-cc-primary rounded-full animate-spin mx-auto mb-3"}),e.jsx("p",{className:"text-sm text-cc-muted",children:"Loading..."})]})}):e.jsxs("div",{className:"h-full overflow-y-auto bg-cc-bg",children:[te&&e.jsx("div",{className:"fixed top-4 left-1/2 -translate-x-1/2 z-50 px-4 py-2.5 rounded-lg bg-red-600 text-white text-sm shadow-lg max-w-md",role:"alert",children:te}),e.jsxs("div",{className:"max-w-4xl mx-auto px-4 sm:px-8 py-6 sm:py-10 pb-safe",children:[e.jsxs("div",{className:"mb-8",children:[e.jsx("h1",{className:"text-lg font-semibold text-cc-fg",children:"Telephony"}),e.jsx("p",{className:"text-xs text-cc-muted mt-1",children:"Make AI-powered phone calls via FreeSWITCH + Gemini Live."})]}),e.jsxs("div",{className:"bg-cc-card border border-cc-border rounded-xl p-4 mb-6",children:[e.jsx("h2",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider mb-3",children:"New Call"}),e.jsxs("div",{className:"space-y-3",children:[e.jsx("div",{children:e.jsx("input",{type:"tel",value:b,onChange:t=>f(t.target.value),placeholder:"+43 664 1234567","aria-label":"Phone number to call",className:"w-full px-3 py-2 text-sm bg-cc-bg border border-cc-border rounded-lg text-cc-fg placeholder:text-cc-muted/60 focus:outline-none focus:border-cc-primary"})}),e.jsx("div",{children:e.jsx("textarea",{value:N,onChange:t=>O(t.target.value),placeholder:"Task for the AI (e.g. 'Reserve a table for 4 at 7pm on Friday')",rows:2,"aria-label":"Call prompt or task for the AI",className:"w-full px-3 py-2 text-sm bg-cc-bg border border-cc-border rounded-lg text-cc-fg placeholder:text-cc-muted/60 focus:outline-none focus:border-cc-primary resize-none"})}),e.jsx("button",{onClick:Pe,disabled:!b.trim()||!N.trim()||_,className:"px-4 py-2 rounded-lg text-xs font-medium bg-green-600 text-white hover:bg-green-500 transition-colors cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed",children:_?e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx("span",{className:"w-3 h-3 border-2 border-white/30 border-t-white rounded-full animate-spin"}),"Dialing..."]}):e.jsxs("span",{className:"flex items-center gap-1.5",children:[e.jsx(Ue,{className:"w-3.5 h-3.5"}),"Call"]})})]})]}),e.jsxs("div",{className:"bg-cc-card border border-cc-border rounded-xl p-4 mb-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h2",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider",children:"Contacts"}),e.jsx("button",{onClick:()=>le(!$),className:"text-xs text-cc-primary hover:text-cc-primary/80 transition-colors cursor-pointer",children:$?"Cancel":"+ Add"})]}),$&&e.jsxs("div",{className:"bg-cc-bg rounded-lg p-3 border border-cc-border space-y-2 mb-3",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] text-cc-muted",children:"Name"}),e.jsx("input",{type:"text",value:h.name,onChange:t=>k({...h,name:t.target.value}),placeholder:"e.g. Mama",className:"w-full px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] text-cc-muted",children:"Phone"}),e.jsx("input",{type:"tel",value:h.phone,onChange:t=>k({...h,phone:t.target.value}),placeholder:"+43...",className:"w-full px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg"})]})]}),e.jsxs("div",{className:"grid grid-cols-[1fr_auto] gap-2",children:[e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] text-cc-muted",children:"Notes (optional)"}),e.jsx("input",{type:"text",value:h.notes,onChange:t=>k({...h,notes:t.target.value}),placeholder:"e.g. Mo-Sa 10-18 Uhr",className:"w-full px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg"})]}),e.jsxs("div",{children:[e.jsx("label",{className:"text-[11px] text-cc-muted",children:"Language"}),e.jsx("select",{value:h.language,onChange:t=>k({...h,language:t.target.value}),className:"w-full px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg w-28",children:X.map(t=>e.jsxs("option",{value:t.code,children:[t.flag," ",t.label]},t.code))})]})]}),e.jsx("button",{onClick:Ae,disabled:!h.name.trim()||!h.phone.trim(),className:"px-3 py-1.5 text-xs rounded bg-green-600 text-white hover:bg-green-500 transition-colors cursor-pointer disabled:opacity-50",children:"Add Contact"})]}),G.length===0&&!$?e.jsx("p",{className:"text-xs text-cc-muted",children:"No contacts yet. Add contacts so Gemini can call them by name."}):e.jsx("div",{className:"space-y-1.5",children:G.map(t=>{var s;return e.jsx("div",{className:"bg-cc-bg rounded-lg px-3 py-2 border border-cc-border",children:R===t.id?e.jsxs("div",{className:"space-y-2",children:[e.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[e.jsx("input",{type:"text",value:m.name,onChange:c=>S({...m,name:c.target.value}),className:"px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg"}),e.jsx("input",{type:"tel",value:m.phone,onChange:c=>S({...m,phone:c.target.value}),className:"px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg"})]}),e.jsxs("div",{className:"grid grid-cols-[1fr_auto] gap-2",children:[e.jsx("input",{type:"text",value:m.notes,onChange:c=>S({...m,notes:c.target.value}),placeholder:"Notes",className:"px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg"}),e.jsx("select",{value:m.language,onChange:c=>S({...m,language:c.target.value}),className:"px-2 py-1.5 text-xs bg-cc-hover border border-cc-border rounded text-cc-fg w-28",children:X.map(c=>e.jsxs("option",{value:c.code,children:[c.flag," ",c.label]},c.code))})]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:Ie,className:"px-2 py-1 text-[11px] rounded bg-green-600 text-white hover:bg-green-500 cursor-pointer",children:"Save"}),e.jsx("button",{onClick:()=>Z(null),className:"px-2 py-1 text-[11px] rounded bg-cc-hover text-cc-muted hover:text-cc-fg cursor-pointer",children:"Cancel"})]})]}):e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsxs("button",{onClick:()=>{f(t.phone),!N.trim()&&t.script&&O(t.script)},className:"min-w-0 flex-1 text-left cursor-pointer hover:opacity-80",title:"Click to use this number",children:[e.jsx("p",{className:"text-xs font-medium text-cc-fg",children:t.name}),e.jsxs("p",{className:"text-[11px] text-cc-muted",children:[t.phone,t.language&&e.jsxs("span",{className:"ml-1",children:[" ",((s=X.find(c=>c.code===t.language))==null?void 0:s.flag)||""]}),t.notes?` — ${t.notes}`:"",(t.script||t.callFlow)&&e.jsx("span",{className:"ml-1.5 text-green-500 text-[9px]",children:"(script)"})]})]}),e.jsxs("div",{className:"flex items-center gap-1 ml-2 shrink-0",children:[e.jsx("button",{onClick:()=>De(t),className:`px-2 py-1.5 text-[11px] rounded transition-colors cursor-pointer ${t.script||t.callFlow?"text-green-500 hover:text-green-400 hover:bg-green-500/10":"text-cc-muted hover:text-cc-fg hover:bg-cc-hover"}`,title:t.script||t.callFlow?"Edit call script":"Add call script",children:t.script||t.callFlow?"Script":"+ Script"}),e.jsx("button",{onClick:()=>{Z(t.id),S({name:t.name,phone:t.phone,notes:t.notes||"",language:t.language||"en"})},className:"px-3 py-2 min-h-[44px] text-[11px] text-cc-muted hover:text-cc-fg hover:bg-cc-hover rounded transition-colors cursor-pointer",children:"Edit"}),e.jsx("button",{onClick:()=>Fe(t.id),"aria-label":`Remove contact ${t.name}`,className:"px-3 py-2 min-h-[44px] text-[11px] text-red-400 hover:text-red-300 hover:bg-red-500/10 rounded transition-colors cursor-pointer",children:"Remove"})]})]})},t.id)})})]}),y&&e.jsxs("div",{className:"bg-cc-card border border-cc-border rounded-xl p-4 mb-6",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsxs("div",{children:[e.jsxs("h2",{className:"text-xs font-semibold text-cc-muted uppercase tracking-wider",children:["Call Script — ",(xe=G.find(t=>t.id===y))==null?void 0:xe.name]}),e.jsx("p",{className:"text-[10px] text-cc-muted mt-0.5",children:"Define what Gemini should say and how to handle responses during the call."})]}),e.jsx("div",{className:"flex items-center gap-2",children:e.jsxs("div",{className:"flex bg-cc-bg rounded-lg border border-cc-border overflow-hidden",children:[e.jsx("button",{onClick:()=>V("simple"),className:`px-2.5 py-1 text-[11px] transition-colors cursor-pointer ${B==="simple"?"bg-cc-primary text-white":"text-cc-muted hover:text-cc-fg"}`,children:"Simple"}),e.jsx("button",{onClick:()=>V("flow"),className:`px-2.5 py-1 text-[11px] transition-colors cursor-pointer ${B==="flow"?"bg-cc-primary text-white":"text-cc-muted hover:text-cc-fg"}`,children:"Flow Builder"})]})})]}),B==="simple"?e.jsxs("div",{className:"space-y-2",children:[e.jsx("textarea",{value:H,onChange:t=>M(t.target.value),placeholder:`Example script:
2
2
 
3
3
  1. Greet and introduce yourself
4
4
  2. Ask if they have a table for 4 on Friday at 7pm
@@ -1 +1 @@
1
- import{u as a,r as i,j as e,T as c,F as n}from"./index-BgYM4wXw.js";function m(){const s=a(r=>r.terminalCwd),[l,t]=i.useState(!1);return e.jsxs("div",{className:"h-full bg-cc-bg overflow-y-auto",children:[e.jsxs("div",{className:"max-w-5xl mx-auto px-4 sm:px-8 py-6 sm:py-10 pb-safe h-full flex flex-col",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3 mb-6 shrink-0",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-semibold text-cc-fg",children:"Terminal"}),e.jsx("p",{className:"mt-1 text-sm text-cc-muted",children:"Run shell commands directly in the browser without leaving the dashboard."})]}),e.jsx("button",{type:"button",onClick:()=>t(!0),className:"px-3 py-2 rounded-lg text-sm font-medium bg-cc-primary hover:bg-cc-primary-hover text-white transition-colors cursor-pointer whitespace-nowrap",children:s?"Change Folder":"Choose Folder"})]}),e.jsx("div",{className:"flex-1 min-h-[420px]",children:s?e.jsx(c,{cwd:s,embedded:!0}):e.jsx("div",{className:"h-full bg-cc-card border border-cc-border rounded-xl p-6 sm:p-8 flex items-center justify-center text-center",children:e.jsxs("div",{className:"max-w-md",children:[e.jsx("h2",{className:"text-lg font-semibold text-cc-fg mb-2",children:"No terminal started yet"}),e.jsx("p",{className:"text-sm text-cc-muted",children:"Choose a folder to start a terminal session. You can switch folders anytime."})]})})})]}),l&&e.jsx(n,{initialPath:s||"",onSelect:r=>{a.getState().openTerminal(r),window.location.hash="#/terminal",t(!1)},onClose:()=>t(!1)})]})}export{m as TerminalPage};
1
+ import{u as a,r as i,j as e,T as c,F as n}from"./index-C6Q5UQHD.js";function m(){const s=a(r=>r.terminalCwd),[l,t]=i.useState(!1);return e.jsxs("div",{className:"h-full bg-cc-bg overflow-y-auto",children:[e.jsxs("div",{className:"max-w-5xl mx-auto px-4 sm:px-8 py-6 sm:py-10 pb-safe h-full flex flex-col",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3 mb-6 shrink-0",children:[e.jsxs("div",{children:[e.jsx("h1",{className:"text-xl font-semibold text-cc-fg",children:"Terminal"}),e.jsx("p",{className:"mt-1 text-sm text-cc-muted",children:"Run shell commands directly in the browser without leaving the dashboard."})]}),e.jsx("button",{type:"button",onClick:()=>t(!0),className:"px-3 py-2 rounded-lg text-sm font-medium bg-cc-primary hover:bg-cc-primary-hover text-white transition-colors cursor-pointer whitespace-nowrap",children:s?"Change Folder":"Choose Folder"})]}),e.jsx("div",{className:"flex-1 min-h-[420px]",children:s?e.jsx(c,{cwd:s,embedded:!0}):e.jsx("div",{className:"h-full bg-cc-card border border-cc-border rounded-xl p-6 sm:p-8 flex items-center justify-center text-center",children:e.jsxs("div",{className:"max-w-md",children:[e.jsx("h2",{className:"text-lg font-semibold text-cc-fg mb-2",children:"No terminal started yet"}),e.jsx("p",{className:"text-sm text-cc-muted",children:"Choose a folder to start a terminal session. You can switch folders anytime."})]})})})]}),l&&e.jsx(n,{initialPath:s||"",onSelect:r=>{a.getState().openTerminal(r),window.location.hash="#/terminal",t(!1)},onClose:()=>t(!1)})]})}export{m as TerminalPage};