@rubytech/create-maxy 1.0.697 → 1.0.698

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 (23) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/neo4j/migrations/002-linkedin-types.cypher +103 -0
  3. package/payload/platform/plugins/docs/references/platform.md +1 -1
  4. package/payload/platform/plugins/docs/references/troubleshooting.md +28 -0
  5. package/payload/server/chunk-3VVHVJK2.js +11405 -0
  6. package/payload/server/maxy-edge.js +1 -1
  7. package/payload/server/public/assets/{admin-BsLm49w9.js → admin-CjRb2gH7.js} +1 -1
  8. package/payload/server/public/assets/{data-BKexd229.js → data-sqtkLfgS.js} +1 -1
  9. package/payload/server/public/assets/{file-DZkqmm8M.js → file-Dsaxvh3t.js} +1 -1
  10. package/payload/server/public/assets/{graph-CPqHYozW.js → graph-ih5hzKOO.js} +1 -1
  11. package/payload/server/public/assets/{house-CPxWBrMl.js → house-Bse5AWrO.js} +1 -1
  12. package/payload/server/public/assets/{jsx-runtime-2yRmkrVq.css → jsx-runtime-DDu3Iu4h.css} +1 -1
  13. package/payload/server/public/assets/public-Btb8pJWN.js +5 -0
  14. package/payload/server/public/assets/{share-2-Bauv6ctA.js → share-2-nB3FxYbd.js} +1 -1
  15. package/payload/server/public/assets/{useVoiceRecorder-BTEcf6H3.js → useVoiceRecorder-D2OAQlJy.js} +3 -3
  16. package/payload/server/public/assets/{x-Kc93nSru.js → x-g2pNE8fh.js} +1 -1
  17. package/payload/server/public/data.html +6 -6
  18. package/payload/server/public/graph.html +6 -6
  19. package/payload/server/public/index.html +7 -7
  20. package/payload/server/public/public.html +4 -4
  21. package/payload/server/server.js +70 -26
  22. package/payload/server/public/assets/public-BthX_YNC.js +0 -5
  23. /package/payload/server/public/assets/{jsx-runtime-7o3Lvx89.js → jsx-runtime-rRO5uNvZ.js} +0 -0
@@ -97,7 +97,7 @@ import {
97
97
  vncLog,
98
98
  waitForExit,
99
99
  writeChromiumWrapper
100
- } from "./chunk-IAIGB5WN.js";
100
+ } from "./chunk-3VVHVJK2.js";
101
101
 
102
102
  // ../lib/graph-trash/dist/index.js
103
103
  var require_dist = __commonJS({
@@ -4797,12 +4797,21 @@ app2.post("/", async (c) => {
4797
4797
  role: m.role,
4798
4798
  content: m.content
4799
4799
  }));
4800
- const uiMessages = neo4jMessages.filter((m) => m.content !== GREETING_DIRECTIVE).map((m) => ({
4801
- role: m.role === "user" ? "visitor" : "maxy",
4802
- content: m.content,
4803
- timestamp: new Date(m.createdAt).getTime() || Date.now(),
4804
- ...m.role === "user" ? { senderName: m.senderName } : {}
4805
- }));
4800
+ const uiMessages = [];
4801
+ for (const m of neo4jMessages) {
4802
+ if (m.content === GREETING_DIRECTIVE) continue;
4803
+ const ts = new Date(m.createdAt).getTime();
4804
+ if (!Number.isFinite(ts) || ts === 0) {
4805
+ console.error(`[session] dropped malformed createdAt messageId=${m.messageId ?? "unknown"} raw=${JSON.stringify(m.createdAt)}`);
4806
+ continue;
4807
+ }
4808
+ uiMessages.push({
4809
+ role: m.role === "user" ? "visitor" : "maxy",
4810
+ content: m.content,
4811
+ timestamp: ts,
4812
+ ...m.role === "user" ? { senderName: m.senderName } : {}
4813
+ });
4814
+ }
4806
4815
  const sessionKey2 = crypto.randomUUID();
4807
4816
  registerResumedSession(sessionKey2, accountId, agentSlug, groupInfo.conversationId, agentMessages);
4808
4817
  setGroupContextForSession(sessionKey2, {
@@ -5624,15 +5633,24 @@ app4.get("/messages", async (c) => {
5624
5633
  try {
5625
5634
  const messages = await getMessagesSince(conversationId, since, POLL_LIMIT);
5626
5635
  console.error(`[group] poll id=${conversationId.slice(0, 8)}\u2026 visitor=${visitorId?.slice(0, 8) ?? "unknown"} since=${since} returned=${messages.length}`);
5627
- return c.json({
5628
- messages: messages.map((m) => ({
5636
+ const mapped = [];
5637
+ for (const m of messages) {
5638
+ const ts = new Date(m.createdAt).getTime();
5639
+ if (!Number.isFinite(ts) || ts === 0) {
5640
+ console.error(`[group] dropped malformed createdAt messageId=${m.messageId} raw=${JSON.stringify(m.createdAt)}`);
5641
+ continue;
5642
+ }
5643
+ mapped.push({
5629
5644
  messageId: m.messageId,
5630
5645
  role: m.role === "user" ? "visitor" : "maxy",
5631
5646
  content: m.content,
5632
5647
  senderName: m.senderName,
5633
5648
  senderVisitorId: m.senderVisitorId,
5634
- timestamp: new Date(m.createdAt).getTime() || Date.now()
5635
- })),
5649
+ timestamp: ts
5650
+ });
5651
+ }
5652
+ return c.json({
5653
+ messages: mapped,
5636
5654
  hasMore: messages.length >= POLL_LIMIT
5637
5655
  });
5638
5656
  } catch (err) {
@@ -7593,10 +7611,11 @@ function rotateIfNeeded() {
7593
7611
  }
7594
7612
  var app9 = new Hono();
7595
7613
  app9.post("/", async (c) => {
7596
- const ip = resolveClientIp(
7614
+ const client = resolveClientIp(
7597
7615
  c.env?.incoming?.socket?.remoteAddress,
7598
7616
  c.req.header("x-forwarded-for")
7599
- ) ?? "unknown";
7617
+ );
7618
+ const ip = client.ip || "unknown";
7600
7619
  const rate = checkRateLimit2(ip);
7601
7620
  if (!rate.allow) {
7602
7621
  if (rate.shouldLog) {
@@ -11234,6 +11253,19 @@ function startGraphHealthTimer() {
11234
11253
  }
11235
11254
 
11236
11255
  // server/index.ts
11256
+ function requestIsTlsTerminated(c) {
11257
+ const remote = c.env?.incoming?.socket?.remoteAddress ?? "";
11258
+ const peerIsLoopback = remote === "127.0.0.1" || remote === "::1" || remote === "::ffff:127.0.0.1";
11259
+ if (!peerIsLoopback) return false;
11260
+ const xfp = c.req.header("x-forwarded-proto") ?? "";
11261
+ return xfp.toLowerCase() === "https";
11262
+ }
11263
+ function clientFrom(c) {
11264
+ return resolveClientIp(
11265
+ c.env?.incoming?.socket?.remoteAddress,
11266
+ c.req.header("x-forwarded-for")
11267
+ );
11268
+ }
11237
11269
  var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT || "";
11238
11270
  var BRAND_JSON_PATH = PLATFORM_ROOT6 ? join9(PLATFORM_ROOT6, "config", "brand.json") : "";
11239
11271
  var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
@@ -11355,8 +11387,15 @@ function resolveRemoteAuthOpts() {
11355
11387
  }
11356
11388
  var MAX_LOGIN_BODY = 8 * 1024;
11357
11389
  app33.post("/__remote-auth/login", async (c) => {
11358
- const clientIp = c.var.clientIp || "unknown";
11359
- const rateLimited = checkRateLimit(clientIp);
11390
+ const client = clientFrom(c);
11391
+ const clientIp = client.ip || "unknown";
11392
+ if (!requestIsTlsTerminated(c)) {
11393
+ console.error(
11394
+ `[remote-auth] login-refused-no-tls ip=${clientIp} resolvedKind=${client.kind} xfp=${c.req.header("x-forwarded-proto") ?? ""}`
11395
+ );
11396
+ return c.text("Remote access requires TLS", 400);
11397
+ }
11398
+ const rateLimited = checkRateLimit(client);
11360
11399
  if (rateLimited) {
11361
11400
  const remaining = parseInt(rateLimited.match(/(\d+)s/)?.[1] ?? "0", 10);
11362
11401
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), lockoutSeconds: remaining || void 0 }), 200);
@@ -11374,13 +11413,14 @@ app33.post("/__remote-auth/login", async (c) => {
11374
11413
  }
11375
11414
  const valid = await verifyRemotePassword(password);
11376
11415
  if (!valid) {
11377
- recordFailedAttempt(clientIp);
11416
+ recordFailedAttempt(client);
11378
11417
  console.error(`[remote-auth] login failed ip=${clientIp}`);
11379
11418
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), error: "Invalid credentials", redirect }), 200);
11380
11419
  }
11381
- clearRateLimit(clientIp);
11420
+ clearRateLimit(client);
11382
11421
  const token = createRemoteSession();
11383
11422
  console.error(`[remote-auth] login success ip=${clientIp}`);
11423
+ console.error(`[remote-auth] cookie-flags secure=true sameSite=strict`);
11384
11424
  return new Response(null, {
11385
11425
  status: 302,
11386
11426
  headers: {
@@ -11390,7 +11430,7 @@ app33.post("/__remote-auth/login", async (c) => {
11390
11430
  }
11391
11431
  });
11392
11432
  });
11393
- app33.get("/__remote-auth/logout", () => {
11433
+ app33.get("/__remote-auth/logout", (c) => {
11394
11434
  return new Response(null, {
11395
11435
  status: 302,
11396
11436
  headers: {
@@ -11401,8 +11441,9 @@ app33.get("/__remote-auth/logout", () => {
11401
11441
  });
11402
11442
  });
11403
11443
  app33.post("/__remote-auth/change-password", async (c) => {
11404
- const clientIp = c.var.clientIp || "unknown";
11405
- const rateLimited = checkRateLimit(clientIp);
11444
+ const client = clientFrom(c);
11445
+ const clientIp = client.ip || "unknown";
11446
+ const rateLimited = checkRateLimit(client);
11406
11447
  if (rateLimited) {
11407
11448
  const remaining = parseInt(rateLimited.match(/(\d+)s/)?.[1] ?? "0", 10);
11408
11449
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), lockoutSeconds: remaining || void 0 }), 200);
@@ -11422,7 +11463,7 @@ app33.post("/__remote-auth/change-password", async (c) => {
11422
11463
  }
11423
11464
  const valid = await verifyRemotePassword(currentPassword);
11424
11465
  if (!valid) {
11425
- recordFailedAttempt(clientIp);
11466
+ recordFailedAttempt(client);
11426
11467
  console.error(`[remote-auth] change-password failed (wrong current) ip=${clientIp}`);
11427
11468
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), mode: "change", changeError: "Current password is incorrect", redirect }), 200);
11428
11469
  }
@@ -11441,7 +11482,7 @@ app33.post("/__remote-auth/change-password", async (c) => {
11441
11482
  }
11442
11483
  try {
11443
11484
  await setRemotePassword(newPassword);
11444
- clearRateLimit(clientIp);
11485
+ clearRateLimit(client);
11445
11486
  console.error(`[remote-auth] password changed ip=${clientIp}`);
11446
11487
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), success: "Password changed successfully. Sign in with your new password.", redirect }), 200);
11447
11488
  } catch (err) {
@@ -11533,10 +11574,12 @@ app33.use("*", async (c, next) => {
11533
11574
  await next();
11534
11575
  return;
11535
11576
  }
11577
+ const rawRemote = c.env?.incoming?.socket?.remoteAddress;
11578
+ const rawXff = c.req.header("x-forwarded-for");
11536
11579
  const decision = canAccessAdmin({
11537
11580
  host,
11538
- remoteAddress: c.env?.incoming?.socket?.remoteAddress,
11539
- xForwardedFor: c.req.header("x-forwarded-for"),
11581
+ remoteAddress: rawRemote,
11582
+ xForwardedFor: rawXff,
11540
11583
  cookieHeader: c.req.header("cookie"),
11541
11584
  isPublicHost
11542
11585
  });
@@ -11549,11 +11592,12 @@ app33.use("*", async (c, next) => {
11549
11592
  await next();
11550
11593
  return;
11551
11594
  }
11595
+ const disambig = `remoteAddress="${rawRemote ?? ""}" xff="${rawXff ?? ""}" resolvedKind=${decision.client.kind}`;
11552
11596
  if (decision.reason === "remote-unconfigured") {
11553
- console.error(`[remote-auth] not configured, redirecting to setup ip=${clientIp} path=${path2}`);
11597
+ console.error(`[remote-auth] not configured, redirecting to setup ip=${clientIp} path=${path2} ${disambig}`);
11554
11598
  return c.redirect("/__remote-auth/setup");
11555
11599
  }
11556
- console.error(`[remote-auth] login required ip=${clientIp} path=${path2}`);
11600
+ console.error(`[remote-auth] login required ip=${clientIp} path=${path2} ${disambig}`);
11557
11601
  return c.html(renderLoginPage({ ...resolveRemoteAuthOpts(), redirect: path2 }), 200);
11558
11602
  });
11559
11603
  app33.route("/api/health", health_default);
@@ -1,5 +0,0 @@
1
- import{o as e}from"./chunk-DD-I1_y5.js";import{i as t,o as n,r,t as i}from"./jsx-runtime-7o3Lvx89.js";import{C as a,M as o,N as s,O as c,P as l,S as u,T as d,_ as f,a as p,c as m,g as h,h as g,i as _,j as v,k as y,n as b,o as x,r as S,s as C,t as w,u as T,v as E,x as D,y as O}from"./useVoiceRecorder-BTEcf6H3.js";var k=r(`square-plus`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M8 12h8`,key:`1wcyev`}],[`path`,{d:`M12 8v8`,key:`napkw2`}]]),A=t(),j=e(n(),1),M=`image/jpeg,image/png,image/gif,image/webp,application/pdf,text/plain,text/markdown,text/csv,text/html,text/calendar`,N=new Set(M.split(`,`)),P=20*1024*1024,F=typeof window<`u`&&/^(localhost|127\.0\.0\.1|[a-z0-9-]+\.local)(:|$)/.test(window.location.hostname);function I(){let e=crypto.getRandomValues(new Uint8Array(16));e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=[...e].map(e=>e.toString(16).padStart(2,`0`)).join(``);return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}function L(){let e=window.location.pathname;if(e.startsWith(`/g/`))return;let t=e.match(/^\/([a-z][a-z0-9-]{2,49})$/);return t?t[1]:void 0}function R(){let e=window.location.pathname.match(/^\/g\/([a-z0-9][a-z0-9-]{0,49})$/);return e?e[1]:void 0}function z(e){return[{key:`length`,label:`At least 8 characters`,met:e.length>=8},{key:`number`,label:`Contains a number`,met:/\d/.test(e)},{key:`special`,label:`Contains a special character`,met:/[^A-Za-z0-9]/.test(e)},{key:`whitespace`,label:`No spaces`,met:e.length>0&&!/\s/.test(e)}]}function B(e,t){if(t===`phone`)return e.length>4?e.slice(0,e.length-4).replace(/\d/g,`•`)+` `+e.slice(-4):e;let n=e.indexOf(`@`);return n<=2?e:e.slice(0,2)+`•••`+e.slice(n)}function ee(e){let[t,n]=(0,j.useState)(null),[r,i]=(0,j.useState)(null),[a,o]=(0,j.useState)(`loading`),[s,c]=(0,j.useState)(``),[l,u]=(0,j.useState)(null),[d,f]=(0,j.useState)(null),[p,m]=(0,j.useState)(!1),[h,g]=(0,j.useState)(null),_=(0,j.useMemo)(()=>L(),[]),v=(0,j.useMemo)(()=>R(),[]),[y,b]=(0,j.useState)(null),x=(0,j.useRef)(_||``),S=(0,j.useRef)(null),C=(0,j.useRef)(null),w=(0,j.useRef)(!1),T=(0,j.useRef)(null),[E,D]=(0,j.useState)(`sign-in`),[O,k]=(0,j.useState)(null),A=(0,j.useRef)(null),M=(0,j.useRef)(null);(0,j.useEffect)(()=>{try{let e=sessionStorage.getItem(`maxy_session`);e&&(M.current=e)}catch{}},[]);let N=(0,j.useCallback)(t=>{S.current=t,n(t);try{sessionStorage.setItem(`maxy_session`,t)}catch{}o(`chat`),e(t)},[e]),P=(0,j.useCallback)(()=>{S.current=null;try{sessionStorage.removeItem(`maxy_session`)}catch{}n(null),o(`auth-required`),D(`sign-in`)},[]),z=(0,j.useCallback)(async e=>{try{let t=x.current,n=await fetch(`/api/access/verify-token`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({token:e,agentSlug:t})}),r=await n.json();n.ok?(A.current=r.session_key,k(r.grant),D(`set-password`),window.history.replaceState({},``,window.location.pathname)):D(`link-expired`)}catch{D(`sign-in`)}},[]),B=(0,j.useCallback)(async()=>{if(S.current)return S.current;if(C.current)return C.current;let e=(async()=>{try{let e=M.current,t=await fetch(`/api/session`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({session_id:I(),..._?{agent:_}:{},...v?{group_slug:v}:{},...e?{session_key:e}:{}})});if(!t.ok){let e=await t.json().catch(()=>({error:``}));return F&&console.error(`[session] POST /api/session failed: ${t.status} ${t.statusText}`,e),t.status===404?i(e.error||`Agent not found`):t.status===503&&i(e.error||`Service unavailable`),null}let r=await t.json();if(r.auth_required){r.agent_id&&(x.current=r.agent_id),c(r.displayName||``),r.agentImage&&u(r.agentImage),r.agentImageShape&&f(r.agentImageShape),r.showAgentName&&m(r.showAgentName),r.branding&&g(r.branding),o(`auth-required`);let e=new URLSearchParams(window.location.search).get(`token`);return e?z(e):D(`sign-in`),null}S.current=r.session_key,n(r.session_key),r.displayName&&c(r.displayName),r.agentImage&&u(r.agentImage),r.agentImageShape&&f(r.agentImageShape),r.showAgentName&&m(r.showAgentName),r.branding&&g(r.branding),o(`chat`),r.resumed&&r.messages&&(w.current=!0,T.current=r.messages),r.group&&b({groupSlug:r.groupSlug,groupName:r.groupName,participants:r.participants??[]});try{sessionStorage.setItem(`maxy_session`,r.session_key)}catch{}return r.session_key}catch(e){return F&&console.error(`[session] fetch /api/session threw:`,e),i(`Unable to connect. Please check your connection and try again.`),null}finally{C.current=null}})();return C.current=e,e},[_,v,z]);return{sessionId:t,sessionKeyRef:S,sessionError:r,pageState:a,setPageState:o,agentDisplayName:s,agentImage:l,agentImageShape:d,showAgentName:p,agentSlug:_,branding:h,resolvedSlugRef:x,ensureSession:B,startNewSession:(0,j.useCallback)(async()=>{S.current=null,C.current=null,M.current=null,w.current=!1,T.current=null,n(null),i(null);try{sessionStorage.removeItem(`maxy_session`)}catch{}let t=await B();t&&e(t)},[B,e]),enterChat:N,enterGate:P,resumedRef:w,resumeMessagesRef:T,gateState:E,setGateState:D,grantInfo:O,setGrantInfo:k,gateSessionKeyRef:A,groupContext:y,groupSlug:v}}function te({sessionKeyRef:e,ensureSession:t,sessionError:n,pageState:r,inputRef:i}){let[a,o]=(0,j.useState)([]),[s,c]=(0,j.useState)(!1),l=(0,j.useRef)(!1),u=e=>{l.current=e,c(e)},d=(0,j.useCallback)(async a=>{if(!l.current){u(!0),o([{role:`maxy`,content:``,timestamp:Date.now()}]);try{let n=await fetch(`/api/chat`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({greeting:!0,session_key:a})});if(n.status===401){e.current=null;try{sessionStorage.removeItem(`maxy_session`)}catch{}F&&console.warn(`[greeting] stale session, retrying with fresh session`);let r=await t();if(!r)return;n=await fetch(`/api/chat`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({greeting:!0,session_key:r})})}if(!n.ok){let e=await n.json().catch(()=>({}));throw Error(e.error||`Something went wrong`)}let r=``,i=``,s=()=>{i&&(r+=i,i=``,o(e=>{let t=[...e];return t[0]={...t[0],content:r},t}))},c=setInterval(s,60);try{for await(let e of D(n)){if(e.error)throw Object.assign(Error(e.error),{fromSSE:!0});e.text&&(i+=e.text),e.type===`component`&&(s(),o(t=>{let n=[...t],r={...n[0]},i=[...r.components||[]];return i.push({name:e.name,data:e.data,submitted:!1}),n[0]={...r,components:i},n}))}}finally{clearInterval(c),s()}}catch(e){if(F&&console.error(`[chat] greeting failed:`,e),r===`auth-required`)return;let t=e instanceof Error?e.message:String(e);o([{role:`maxy`,content:e instanceof Error&&e.fromSSE?t:n??`I'm having trouble connecting right now. Try refreshing the page.`,timestamp:Date.now()}])}finally{u(!1),r===`chat`&&i.current?.focus()}}},[e,t,n,r,i]),f=(0,j.useCallback)(async(a,s)=>{let c=s?.hidden??!1,d=s?.files??[];if(!a&&d.length===0||l.current)return;u(!0);let f=d.map(e=>({filename:e.name,mimeType:e.type})),p={role:`visitor`,content:a,attachments:f.length>0?f:void 0,timestamp:Date.now(),hidden:c},m;o(e=>{let t=[...e,p,{role:`maxy`,content:``,timestamp:Date.now()}];return m=t.length-1,t});try{let n=await t();if(!n)throw Error(`session`);let r=e=>{if(d.length>0){let t=new FormData;t.append(`message`,a),t.append(`session_key`,e);for(let e of d)t.append(`attachments`,e);return{body:t,headers:{}}}return{body:JSON.stringify({message:a,session_key:e}),headers:{"Content-Type":`application/json`}}},{body:i,headers:s}=r(n),c=await fetch(`/api/chat`,{method:`POST`,headers:s,body:i});if(c.status===401){e.current=null;try{sessionStorage.removeItem(`maxy_session`)}catch{}F&&console.warn(`[session-expired] stale key cleared, retrying with fresh session`);let n=await t();if(!n)throw Error(`session`);({body:i,headers:s}=r(n)),c=await fetch(`/api/chat`,{method:`POST`,headers:s,body:i})}if(!c.ok){let e=await c.json().catch(()=>({}));throw Error(e.error||`Something went wrong`)}let l=``,u=``,f=()=>{u&&(l+=u,u=``,o(e=>{let t=[...e];return t[m]={...t[m],content:l},t}))},p=setInterval(f,60);try{for await(let e of D(c)){if(e.error)throw Object.assign(Error(e.error),{fromSSE:!0});e.text&&(u+=e.text),e.type===`component`&&(f(),o(t=>{let n=[...t],r={...n[m]},i=[...r.components||[]];return i.push({name:e.name,data:e.data,submitted:!1}),n[m]={...r,components:i},n}))}}finally{clearInterval(p),f()}}catch(e){if(F&&console.error(`[chat] sendMessage failed:`,e),r===`auth-required`)return;let t=e instanceof Error?e.message:String(e),i=e instanceof Error&&e.fromSSE;o(e=>{let r=[...e];return r[m]={...r[m],content:i?t:t===`session`?n??`I'm having trouble connecting right now. Try refreshing the page.`:`Sorry, I hit a snag. Try again in a moment.`},r})}finally{u(!1),r===`chat`&&i.current?.focus()}},[e,t,n,r,i]);return{messages:a,setMessages:o,isStreaming:s,sendMessage:f,sendGreeting:d,handleComponentSubmit:(0,j.useCallback)((e,t,n)=>{o(n=>{let r=[...n],i={...r[e]},a=[...i.components||[]];return a[t]={...a[t],submitted:!0},r[e]={...i,components:a},r}),f(n,{hidden:!0})},[f])}}function ne({sessionKeyRef:e,groupSlug:t,isStreaming:n,setMessages:r}){let i=(0,j.useRef)(new Date().toISOString()),a=(0,j.useRef)(!0);(0,j.useEffect)(()=>{let e=()=>{a.current=document.visibilityState===`visible`};return document.addEventListener(`visibilitychange`,e),()=>document.removeEventListener(`visibilitychange`,e)},[]);let o=(0,j.useCallback)(async()=>{let n=e.current;if(!(!n||!t))try{let e=await fetch(`/api/group/messages?session_key=${encodeURIComponent(n)}&since=${encodeURIComponent(i.current)}`);if(!e.ok)return;let t=await e.json();if(!t.messages||t.messages.length===0)return;let a=t.messages[t.messages.length-1];a.timestamp&&(i.current=new Date(a.timestamp).toISOString()),r(e=>{let n=new Set(e.filter(e=>e.messageId).map(e=>e.messageId)),r=t.messages.filter(e=>!n.has(e.messageId)).map(e=>({role:e.role,content:e.content,timestamp:e.timestamp,senderName:e.senderName??void 0,senderVisitorId:e.senderVisitorId??void 0,messageId:e.messageId}));return r.length===0?e:[...e,...r]})}catch{}},[e,t,r]);(0,j.useEffect)(()=>{if(!t)return;let e,r=!1;function i(){if(r)return;let t=a.current?3e3:3e4;e=setTimeout(async()=>{n||await o(),i()},t)}return i(),()=>{r=!0,clearTimeout(e)}},[t,n,o])}var V=i();function H({value:e,onChange:t,onComplete:n,disabled:r}){let i=(0,j.useRef)([]);function a(n,r){r.key===`Backspace`?(r.preventDefault(),e[n]?t(e.slice(0,n)+e.slice(n+1)):n>0&&(t(e.slice(0,n-1)+e.slice(n)),i.current[n-1]?.focus())):r.key===`ArrowLeft`&&n>0?i.current[n-1]?.focus():r.key===`ArrowRight`&&n<5&&i.current[n+1]?.focus()}function o(r,a){let o=a.nativeEvent.data;if(!o||!/^\d$/.test(o))return;let s=e.split(``);for(s[r]=o;s.length<r;)s.push(``);let c=s.join(``).replace(/\D/g,``).slice(0,6);t(c),c.length===6?n(c):r<5&&i.current[r+1]?.focus()}function s(e){e.preventDefault();let r=e.clipboardData.getData(`text`).replace(/\D/g,``).slice(0,6);r&&(t(r),r.length===6?n(r):i.current[r.length]?.focus())}return(0,V.jsx)(`div`,{className:`gate-otp-field`,children:Array.from({length:6}).map((t,n)=>(0,V.jsx)(`input`,{ref:e=>{i.current[n]=e},type:`text`,inputMode:`numeric`,className:`pin-box${e[n]?` pin-box-filled`:``}`,value:e[n]||``,onKeyDown:e=>a(n,e),onInput:e=>o(n,e),onPaste:s,onFocus:e=>e.target.select(),autoFocus:n===0,autoComplete:`off`,maxLength:1,disabled:r,"aria-label":`Code digit ${n+1}`},n))})}function U({gateState:e,setGateState:t,grantInfo:n,setGrantInfo:r,gateSessionKeyRef:i,resolvedSlugRef:a,onAuthenticated:o}){let[s,c]=(0,j.useState)(``),[l,u]=(0,j.useState)(``),[d,f]=(0,j.useState)(``),[p,m]=(0,j.useState)(!1),[_,v]=(0,j.useState)(``),[y,b]=(0,j.useState)(``),[x,S]=(0,j.useState)(!1),[C,w]=(0,j.useState)(null),[T,E]=(0,j.useState)(null),[D,O]=(0,j.useState)(!1);async function k(e){if(e.preventDefault(),!D){w(null),O(!0);try{let e=a.current,n=await fetch(`/api/access/login`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({contact:s,password:l,agentSlug:e})}),i=await n.json();n.ok?o(i.session_key):n.status===401?i.error?.includes(`setup not complete`)||i.error?.includes(`invitation link`)?(t(`private-agent`),w(null)):w(i.error||`Invalid credentials`):n.status===403?(t(`access-expired`),i.expiresAt&&r(e=>e?{...e,expiresAt:i.expiresAt}:{displayName:null,contactValue:s,contactMethod:`email`,expiresAt:i.expiresAt,status:`expired`})):n.status===429?w(i.error||`Too many attempts. Please try again later.`):w(i.error||`Something went wrong`)}catch{w(`Unable to connect. Please try again.`)}finally{O(!1)}}}async function A(e){if(!D){w(null),O(!0);try{let n=a.current,o=await fetch(`/api/access/verify-otp`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({phone:y,code:e,agentSlug:n})}),s=await o.json();o.ok?(i.current=s.session_key,r(s.grant),t(`set-password`)):o.status===429?t(`otp-failed`):(w(s.error||`Invalid code`),v(``))}catch{w(`Unable to connect. Please try again.`)}finally{O(!1)}}}async function M(e){if(e.preventDefault(),!D){if(w(null),l!==d){w(`Passwords do not match`);return}if(!z(l).every(e=>e.met)){w(`Password does not meet requirements`);return}O(!0);try{let e=i.current;if(!e){w(`Session expired. Please use your invitation link again.`);return}let t=await fetch(`/api/access/create-credentials`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({session_key:e,password:l})}),n=await t.json();t.ok?o(n.session_key):t.status===400&&n.requirements?w(n.requirements.filter(e=>!e.met).map(e=>e.label).join(`, `)):w(n.error||`Something went wrong`)}catch{w(`Unable to connect. Please try again.`)}finally{O(!1)}}}async function N(e){if(e.preventDefault(),!(D||!s)){w(null),O(!0);try{let e=a.current,t=await fetch(`/api/access/forgot-password`,{method:`POST`,headers:{"Content-Type":`application/json`},body:JSON.stringify({contact:s,agentSlug:e})});t.status===429?w((await t.json()).error||`Too many attempts. Please try again later.`):(E(`If an account exists, a reset link has been sent.`),setTimeout(()=>{S(!1),E(null)},4e3))}catch{w(`Unable to connect. Please try again.`)}finally{O(!1)}}}switch(e){case`set-password`:{let e=z(l),t=e.every(e=>e.met),r=l===d,i=t&&r&&d.length>0;return(0,V.jsx)(`div`,{className:`gate-wrap`,children:(0,V.jsxs)(`div`,{className:`gate-card`,children:[n?.expiresAt&&(0,V.jsxs)(`div`,{className:`gate-expiry-badge`,children:[`Access until `,new Date(n.expiresAt).toLocaleDateString(`en-GB`,{day:`numeric`,month:`short`,year:`numeric`})]}),(0,V.jsxs)(`h2`,{className:`gate-title`,children:[`Welcome, `,n?.displayName||`there`]}),(0,V.jsx)(`p`,{className:`gate-subtitle`,children:`Create a password to access this agent in the future.`}),(0,V.jsxs)(`form`,{className:`gate-form`,onSubmit:M,children:[(0,V.jsxs)(`div`,{className:`gate-field`,children:[(0,V.jsx)(`label`,{htmlFor:`gate-display-name`,children:`Display name`}),(0,V.jsx)(`input`,{id:`gate-display-name`,type:`text`,value:n?.displayName||``,disabled:!0})]}),(0,V.jsxs)(`div`,{className:`gate-field gate-pw-row`,children:[(0,V.jsx)(`label`,{htmlFor:`gate-pw`,children:`Password`}),(0,V.jsx)(`div`,{className:`gate-pw-toggle`,children:(0,V.jsx)(h,{checked:p,onChange:m,label:`Show`})}),(0,V.jsx)(`input`,{id:`gate-pw`,type:p?`text`:`password`,value:l,onChange:e=>u(e.target.value),placeholder:`Your password`,autoFocus:!0,autoComplete:`new-password`}),l.length>0&&(0,V.jsx)(`div`,{className:`gate-strength`,children:e.map(e=>(0,V.jsxs)(`span`,{className:`gate-strength-item${e.met?` met`:``}`,children:[e.met?`✓`:`○`,` `,e.label]},e.key))})]}),(0,V.jsxs)(`div`,{className:`gate-field`,children:[(0,V.jsx)(`label`,{htmlFor:`gate-pw-confirm`,children:`Confirm password`}),(0,V.jsx)(`input`,{id:`gate-pw-confirm`,type:p?`text`:`password`,value:d,onChange:e=>f(e.target.value),placeholder:`Confirm your password`,autoComplete:`new-password`}),d.length>0&&!r&&(0,V.jsx)(`div`,{className:`gate-error`,children:`Passwords do not match`})]}),C&&(0,V.jsx)(`div`,{className:`gate-error`,children:C}),(0,V.jsx)(`div`,{className:`gate-submit`,children:(0,V.jsx)(g,{variant:`primary`,type:`submit`,fullWidth:!0,disabled:!i||D,loading:D,children:`Create account & enter chat`})})]})]})})}case`enter-otp`:return(0,V.jsx)(`div`,{className:`gate-wrap`,children:(0,V.jsxs)(`div`,{className:`gate-card`,children:[(0,V.jsx)(`h2`,{className:`gate-title`,children:`Enter your code`}),(0,V.jsxs)(`p`,{className:`gate-subtitle`,children:[`Enter the 6-digit code sent to `,B(y,`phone`)]}),(0,V.jsx)(H,{value:_,onChange:v,onComplete:A,disabled:D}),C&&(0,V.jsx)(`div`,{className:`gate-error`,children:C}),D&&(0,V.jsxs)(`div`,{className:`gate-loading`,children:[(0,V.jsx)(`span`,{className:`spinner`}),`Verifying...`]}),(0,V.jsx)(`div`,{className:`gate-resend`,children:(0,V.jsx)(`button`,{type:`button`,className:`gate-link`,onClick:()=>{t(`sign-in`),v(``),w(null)},children:`Use a different number`})})]})});case`sign-in`:case`private-agent`:return(0,V.jsx)(`div`,{className:`gate-wrap`,children:(0,V.jsxs)(`div`,{className:`gate-card`,children:[(0,V.jsx)(`h2`,{className:`gate-title`,children:e===`private-agent`?`Private Agent`:`Welcome back`}),(0,V.jsx)(`p`,{className:`gate-subtitle`,children:e===`private-agent`?`This agent is invitation-only. If you have an account, sign in below.`:`Sign in to continue your conversation.`}),x?(0,V.jsxs)(`form`,{className:`gate-form`,onSubmit:N,children:[(0,V.jsxs)(`div`,{className:`gate-field`,children:[(0,V.jsx)(`label`,{htmlFor:`gate-forgot-contact`,children:`Email or phone`}),(0,V.jsx)(`input`,{id:`gate-forgot-contact`,type:`text`,value:s,onChange:e=>c(e.target.value),placeholder:`you@example.com`,autoFocus:!0,autoComplete:`email`})]}),C&&(0,V.jsx)(`div`,{className:`gate-error`,children:C}),T&&(0,V.jsx)(`div`,{className:`gate-success`,children:T}),(0,V.jsx)(`div`,{className:`gate-submit`,children:(0,V.jsx)(g,{variant:`primary`,type:`submit`,fullWidth:!0,disabled:!s.trim()||D,loading:D,children:`Send reset link`})}),(0,V.jsx)(`div`,{className:`gate-actions`,children:(0,V.jsx)(`button`,{type:`button`,className:`gate-link`,onClick:()=>{S(!1),w(null),E(null)},children:`Back to sign in`})})]}):(0,V.jsxs)(`form`,{className:`gate-form`,onSubmit:k,children:[(0,V.jsxs)(`div`,{className:`gate-field`,children:[(0,V.jsx)(`label`,{htmlFor:`gate-contact`,children:`Email or phone`}),(0,V.jsx)(`input`,{id:`gate-contact`,type:`text`,value:s,onChange:e=>c(e.target.value),placeholder:`you@example.com`,autoFocus:!0,autoComplete:`email`})]}),(0,V.jsxs)(`div`,{className:`gate-field gate-pw-row`,children:[(0,V.jsx)(`label`,{htmlFor:`gate-login-pw`,children:`Password`}),(0,V.jsx)(`div`,{className:`gate-pw-toggle`,children:(0,V.jsx)(h,{checked:p,onChange:m,label:`Show`})}),(0,V.jsx)(`input`,{id:`gate-login-pw`,type:p?`text`:`password`,value:l,onChange:e=>u(e.target.value),placeholder:`Your password`,autoComplete:`current-password`})]}),C&&(0,V.jsx)(`div`,{className:`gate-error`,children:C}),(0,V.jsx)(`div`,{className:`gate-submit`,children:(0,V.jsx)(g,{variant:`primary`,type:`submit`,fullWidth:!0,disabled:!s.trim()||!l||D,loading:D,children:`Sign in`})}),(0,V.jsx)(`div`,{className:`gate-actions`,children:(0,V.jsx)(`button`,{type:`button`,className:`gate-link`,onClick:()=>{S(!0),w(null)},children:`Forgot password?`})})]}),e===`private-agent`&&(0,V.jsx)(`p`,{className:`gate-hint`,children:`No account? You need an invitation from the agent owner.`})]})});case`access-expired`:return(0,V.jsx)(`div`,{className:`gate-wrap`,children:(0,V.jsxs)(`div`,{className:`gate-card`,children:[(0,V.jsx)(`div`,{className:`gate-icon`,children:`⏰`}),(0,V.jsx)(`h2`,{className:`gate-title`,children:`Access expired`}),(0,V.jsxs)(`p`,{className:`gate-subtitle`,children:[n?.expiresAt?`Your access expired on ${new Date(n.expiresAt).toLocaleDateString(`en-GB`,{day:`numeric`,month:`long`,year:`numeric`})}.`:`Your access to this agent has expired.`,` `,`Contact the agent owner to renew.`]}),(0,V.jsx)(`div`,{className:`gate-actions`,children:(0,V.jsx)(g,{variant:`secondary`,onClick:()=>{t(`sign-in`),w(null),u(``)},children:`Sign in with a different account`})})]})});case`link-expired`:return(0,V.jsx)(`div`,{className:`gate-wrap`,children:(0,V.jsxs)(`div`,{className:`gate-card`,children:[(0,V.jsx)(`div`,{className:`gate-icon`,children:`⚠️`}),(0,V.jsx)(`h2`,{className:`gate-title`,children:`Link expired`}),(0,V.jsx)(`p`,{className:`gate-subtitle`,children:`This invitation link has expired or has already been used. If you already set your password, sign in below. Otherwise, ask the agent owner to send a new invitation.`}),(0,V.jsx)(`div`,{className:`gate-actions`,children:(0,V.jsx)(g,{variant:`primary`,onClick:()=>{t(`sign-in`),w(null)},children:`Go to sign in`})})]})});case`otp-failed`:return(0,V.jsx)(`div`,{className:`gate-wrap`,children:(0,V.jsxs)(`div`,{className:`gate-card`,children:[(0,V.jsx)(`div`,{className:`gate-icon`,children:`⛔`}),(0,V.jsx)(`h2`,{className:`gate-title`,children:`Too many attempts`}),(0,V.jsx)(`p`,{className:`gate-subtitle`,children:`You've entered the wrong code too many times. Ask the agent owner to send a new code.`}),(0,V.jsx)(`div`,{className:`gate-actions`,children:(0,V.jsx)(g,{variant:`secondary`,onClick:()=>{t(`sign-in`),w(null),v(``)},children:`Back to sign in`})})]})})}}var W={"single-select":m,"multi-select":C,"action-buttons":x};function G({name:e,data:t,onSubmit:n,submitted:r}){let i=W[e];return i?(0,V.jsx)(i,{data:t,onSubmit:n,submitted:r}):(console.warn(`[PublicComponentRenderer] Unknown component: "${e}". Registered: ${Object.keys(W).join(`, `)}`),(0,V.jsx)(`div`,{className:`component-card component-card--error`,children:(0,V.jsxs)(`p`,{style:{fontFamily:`var(--font-body)`,fontSize:12,color:`var(--text-secondary)`},children:[`Component “`,e,`” is not available. This may require a platform update.`]})}))}function re({messages:e,isStreaming:t,sessionError:n,selectionMode:r,selectedItems:i,toggleSelectItem:a,onComponentSubmit:s,remainingSuggestions:c,onSuggestionClick:u,isAtBottom:d,setIsAtBottom:f,isGroup:m}){let[_,y]=(0,j.useState)(new Set),[b,x]=(0,j.useState)(new Set),S=(0,j.useRef)(null),C=(0,j.useRef)(null),w=(0,j.useRef)(null),E=(0,j.useRef)(!1),D=(0,j.useRef)(!1),O=(0,j.useRef)(!1),k=(0,j.useRef)(0),A=(0,j.useRef)(!1),M=(0,j.useRef)(new Map);A.current=t,(0,j.useEffect)(()=>{t&&!E.current&&d&&(D.current=!0)},[t,d]),(0,j.useEffect)(()=>{if(!D.current&&!d){E.current=t,O.current=!1;return}if(E.current&&!t&&w.current&&C.current){let e=w.current;if(e.offsetHeight>C.current.clientHeight){D.current=!1,O.current=!0,e.scrollIntoView({behavior:`smooth`,block:`start`}),E.current=t;return}}(d||D.current)&&!O.current&&S.current?.scrollIntoView({behavior:`smooth`}),E.current&&!t&&(D.current=!1),E.current=t},[e,d,t]),(0,j.useEffect)(()=>{let e=C.current;if(!e)return;let t=()=>{let t=e.scrollTop;A.current&&t<k.current&&(D.current=!1),k.current=t,f(e.scrollHeight-e.scrollTop-e.clientHeight<80)};return e.addEventListener(`scroll`,t,{passive:!0}),t(),()=>e.removeEventListener(`scroll`,t)},[f]),(0,j.useEffect)(()=>{function e(){x(e=>{let t=new Set;return M.current.forEach((n,r)=>{n.isConnected&&(_.has(r)?e.has(r)&&t.add(r):n.scrollHeight>n.clientHeight+2&&t.add(r))}),e.size===t.size&&[...e].every(e=>t.has(e))?e:t})}e();let t=new ResizeObserver(e);return M.current.forEach(e=>t.observe(e)),()=>t.disconnect()},[e.length,_]);let N=e.reduce((e,t,n)=>t.role===`maxy`&&!t.hidden?n:e,-1);return(0,V.jsxs)(`div`,{className:`chat-messages-wrap`,children:[r&&(0,V.jsx)(`div`,{className:`selection-overlay-band`}),(0,V.jsxs)(`div`,{className:`chat-messages`,ref:C,children:[n&&e.length===0&&(0,V.jsx)(`div`,{className:`session-error`,children:(0,V.jsx)(`p`,{children:n})}),e.map((n,c)=>{if(n.hidden)return null;let u=t&&c===e.length-1,d=`${n.timestamp}_${n.role}`,f=i.has(d);return(0,V.jsxs)(`div`,{ref:c===N?w:void 0,className:`message ${n.role}${f?` selected`:``}`,children:[r&&!u&&(0,V.jsx)(`div`,{className:`message-select-check`,children:(0,V.jsx)(h,{checked:f,onChange:()=>a(d)})}),(0,V.jsxs)(`div`,{className:`bubble`,children:[m&&n.role===`visitor`&&n.senderName&&(0,V.jsx)(`span`,{className:`bubble-sender`,children:n.senderName}),n.role===`visitor`&&n.content?(()=>{let e=_.has(c),t=b.has(c);return(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(`div`,{ref:e=>{e?M.current.set(c,e):M.current.delete(c)},className:e?`bubble-content`:`bubble-content clamped${t?` overflowing`:``}`,children:n.content}),t&&(0,V.jsx)(`div`,{className:`bubble-expand`,children:(0,V.jsx)(g,{variant:`icon`,className:e?`expanded`:``,onClick:()=>y(e=>{let t=new Set(e);return t.has(c)?t.delete(c):t.add(c),t}),"aria-label":e?`Collapse message`:`Expand message`,children:(0,V.jsx)(l,{size:14})})})]})})():n.content?(0,V.jsx)(T,{content:n.content,timestamp:p(n.timestamp)}):(0,V.jsxs)(`span`,{className:`typing-indicator`,children:[(0,V.jsx)(`span`,{className:`typing-dot`}),(0,V.jsx)(`span`,{className:`typing-dot`}),(0,V.jsx)(`span`,{className:`typing-dot`})]}),n.attachments&&n.attachments.length>0&&(0,V.jsx)(`div`,{className:`message-attachments`,children:n.attachments.map((e,t)=>(0,V.jsxs)(`span`,{className:`message-attachment-chip no-action`,children:[e.mimeType===`application/pdf`?(0,V.jsx)(v,{size:12}):e.mimeType.startsWith(`text/`)?(0,V.jsx)(o,{size:12}):null,(0,V.jsx)(`span`,{children:e.filename})]},t))}),n.role===`visitor`&&(0,V.jsx)(`span`,{className:`message-timestamp`,children:p(n.timestamp)})]}),n.role===`maxy`&&n.components&&n.components.length>0&&(0,V.jsx)(`div`,{className:`public-components`,children:n.components.map((e,t)=>(0,V.jsx)(`div`,{className:`public-component-enter`,children:(0,V.jsx)(G,{name:e.name,data:e.data,onSubmit:e=>s(c,t,e),submitted:e.submitted})},t))})]},c)}),!t&&c.length>0&&(0,V.jsx)(`div`,{className:`chat-suggestions`,children:c.map(e=>(0,V.jsx)(g,{variant:`suggestion`,onClick:()=>u(e),children:e},e))}),(0,V.jsx)(`div`,{ref:S})]}),!d&&(0,V.jsx)(`button`,{className:`scroll-to-bottom`,onClick:()=>S.current?.scrollIntoView({behavior:`smooth`}),"aria-label":`Scroll to bottom`,children:(0,V.jsx)(l,{size:18})})]})}function ie({selectedItems:e,messages:t,copySelected:n,exitSelection:r,showCopyToast:i}){let[a,o]=(0,j.useState)(!1),c=(0,j.useRef)(null),l=(0,j.useRef)(!1);function d(e){let n=e.lastIndexOf(`_`),r=e.slice(0,n),i=e.slice(n+1),a=parseInt(r,10);return t.find(e=>e.timestamp===a&&e.role===i)?.content??``}function f(e,t){return parseInt(e.slice(0,e.lastIndexOf(`_`)),10)-parseInt(t.slice(0,t.lastIndexOf(`_`)),10)}function p(){let e=[...t].sort((e,t)=>e.timestamp-t.timestamp),n=[];for(let t of e){if(t.hidden||!t.content)continue;let e=t.role===`visitor`?`Visitor`:`Maxy`;n.push(`${e}:\n${t.content}`)}return n.join(`
2
-
3
- ---
4
-
5
- `)}j.useEffect(()=>{if(!a)return;let e=e=>{e.target.closest(`.selection-copy-wrap`)||o(!1)};return document.addEventListener(`pointerdown`,e),()=>document.removeEventListener(`pointerdown`,e)},[a]);function m(){c.current!==null&&(clearTimeout(c.current),c.current=null)}return(0,V.jsx)(`div`,{className:`chat-input-area`,children:(0,V.jsxs)(`div`,{className:`selection-bar`,children:[(0,V.jsxs)(`span`,{className:`selection-count`,children:[e.size,` Selected`]}),(0,V.jsxs)(`div`,{className:`selection-copy-wrap`,children:[(0,V.jsxs)(`button`,{type:`button`,className:`selection-copy`,onPointerDown:()=>{if(a){o(!1);return}l.current=!1,c.current=setTimeout(()=>{l.current=!0,o(!0),c.current=null},500)},onPointerUp:m,onPointerLeave:m,onPointerCancel:m,onClick:async()=>{l.current||await n(d,f)},children:[(0,V.jsx)(s,{size:18}),(0,V.jsx)(`span`,{children:`Copy`})]}),a&&(0,V.jsx)(`div`,{className:`copy-menu`,children:(0,V.jsx)(`button`,{type:`button`,className:`copy-menu-item`,onClick:async()=>{let e=p();e&&i(await u(e)),r()},children:`Copy all`})})]}),(0,V.jsx)(`button`,{type:`button`,className:`selection-cancel`,onClick:r,children:`Cancel`})]})})}function ae({input:e,setInput:t,isStreaming:n,pendingFiles:r,setPendingFiles:i,attachError:a,setAttachError:s,isDragOver:l,setIsDragOver:u,inputRef:d,onSubmit:f,onSendVoiceNote:p}){let m=(0,j.useRef)(null),h=w(),x=h.state===`recording`||h.state===`paused`||h.state===`sending`,C=!x&&!n&&!e.trim()&&r.length===0;async function T(){let e=await h.send();if(!e)return;let t=e.type===`audio/ogg`?`.ogg`:e.type===`audio/mp4`?`.m4a`:`.webm`;p(new File([e],`voice-note${t}`,{type:e.type}))}function E(e){s(null);let t=e.find(e=>!N.has(e.type));if(t){s(`Unsupported file type: "${t.type}". Supported: images, PDF, plain text, markdown, CSV, calendar.`);return}let n=e.find(e=>e.size>P);if(n){s(`"${n.name}" exceeds the 20 MB limit.`);return}i(t=>[...t,...e].slice(0,5))}function D(e){e.preventDefault(),u(!0)}function O(){u(!1)}function k(e){e.preventDefault(),u(!1),E([...e.dataTransfer.files])}return(0,V.jsxs)(`div`,{className:`chat-input-area`,children:[(0,V.jsx)(`input`,{ref:m,type:`file`,multiple:!0,accept:M,style:{display:`none`},onChange:e=>{e.target.files&&E([...e.target.files]),e.target.value=``}}),r.length>0&&(0,V.jsx)(`div`,{className:`attachment-strip`,children:r.map((e,t)=>(0,V.jsxs)(`div`,{className:`attachment-chip`,children:[e.type.startsWith(`image/`)?(0,V.jsx)(`img`,{src:URL.createObjectURL(e),alt:e.name,className:`attachment-chip-thumb`}):e.type===`application/pdf`?(0,V.jsx)(v,{size:14}):(0,V.jsx)(o,{size:14}),(0,V.jsx)(`span`,{className:`attachment-chip-name`,children:e.name}),(0,V.jsx)(`button`,{type:`button`,className:`attachment-chip-remove`,onClick:()=>i(e=>e.filter((e,n)=>n!==t)),"aria-label":`Remove ${e.name}`,children:`×`})]},t))}),a&&(0,V.jsx)(`p`,{className:`attach-error`,children:a}),h.state===`error`&&h.errorMessage&&(0,V.jsxs)(`p`,{className:`voice-error`,role:`alert`,children:[(0,V.jsx)(y,{size:14}),h.errorMessage]}),(0,V.jsx)(_,{inputRef:d}),x?(0,V.jsx)(`div`,{className:`chat-form voice-active`,children:(0,V.jsx)(b,{state:h.state,elapsedSeconds:h.elapsedSeconds,waveform:h.waveform,onTogglePause:h.togglePause,onDiscard:h.discard,onSend:T})}):(0,V.jsxs)(`form`,{className:`chat-form${l?` drag-over`:``}`,onSubmit:f,onDragOver:D,onDragLeave:O,onDrop:k,onPaste:e=>{let t=e.clipboardData?.items;if(!t)return;let n=[];for(let e of t){if(e.kind!==`file`)continue;let t=e.getAsFile();if(!t)continue;let r=t.type.split(`/`)[1]?.replace(`jpeg`,`jpg`)||`png`;n.push(new File([t],`pasted-image-${Date.now()}.${r}`,{type:t.type}))}n.length>0&&E(n)},children:[(0,V.jsx)(g,{variant:`icon`,type:`button`,onClick:()=>m.current?.click(),disabled:n,"aria-label":`Attach file`,children:(0,V.jsx)(c,{size:14})}),(0,V.jsx)(S,{ref:d,value:e,onChange:t}),C?(0,V.jsx)(g,{variant:`send`,type:`button`,onClick:h.start,disabled:n,"aria-label":`Record voice note`,children:(0,V.jsx)(y,{size:14})}):(0,V.jsx)(g,{variant:`send`,type:`submit`,disabled:n||!e.trim()&&r.length===0,"aria-label":`Send message`,children:(0,V.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,V.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,V.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]})]})}var K=[];function q(){let[e,t]=(0,j.useState)(``),[n,r]=(0,j.useState)([]),[i,o]=(0,j.useState)(!1),[s,c]=(0,j.useState)(null),[l,u]=(0,j.useState)(K),[p,m]=(0,j.useState)(!0),h=(0,j.useRef)(null),{selectionMode:g,selectedItems:_,copyToast:v,exitSelection:y,enterSelection:b,toggleSelectItem:x,copySelected:S,showCopyToast:C}=a(),w=(0,j.useRef)(()=>{}),T=ee((0,j.useCallback)(e=>{w.current(e)},[])),{sessionId:D,sessionKeyRef:A,sessionError:M,pageState:N,agentDisplayName:P,agentImage:F,agentImageShape:I,showAgentName:L,branding:R,ensureSession:z,startNewSession:B,resumedRef:H,resumeMessagesRef:W,groupContext:G,groupSlug:q}=T,{messages:J,setMessages:Y,isStreaming:X,sendMessage:Z,sendGreeting:Q,handleComponentSubmit:oe}=te({sessionKeyRef:A,ensureSession:z,sessionError:M,pageState:N,inputRef:h});(0,j.useEffect)(()=>{w.current=Q},[Q]),ne({sessionKeyRef:A,groupSlug:q,isStreaming:X,setMessages:Y}),(0,j.useEffect)(()=>{let e=!1;return(async()=>{let t=await z();if(!e&&t){if(H.current&&W.current&&W.current.length>0){Y(W.current.map(e=>({role:e.role,content:e.content,timestamp:e.timestamp}))),W.current=null;return}Q(t)}})(),()=>{e=!0}},[]),(0,j.useEffect)(()=>{N===`chat`&&h.current?.focus()},[N]),(0,j.useEffect)(()=>{if(N!==`chat`)return;history.pushState({maxyChat:!0},``);function e(){history.pushState({maxyChat:!0},``)}return window.addEventListener(`popstate`,e),()=>window.removeEventListener(`popstate`,e)},[N]),(0,j.useEffect)(()=>{if(!R)return;let e=document.documentElement;if(R.primaryColor&&(e.style.setProperty(`--sage`,R.primaryColor),e.style.setProperty(`--sage-hover`,R.primaryColor),e.style.setProperty(`--sage-subtle`,R.primaryColor+`14`),e.style.setProperty(`--sage-glow`,R.primaryColor+`26`)),R.accentColor&&e.style.setProperty(`--visitor-bubble`,R.accentColor),R.backgroundColor&&e.style.setProperty(`--bg`,R.backgroundColor),document.title=R.name,R.primaryColor){let e=document.querySelector(`meta[name="theme-color"]`);e||(e=document.createElement(`meta`),e.name=`theme-color`,document.head.appendChild(e)),e.content=R.primaryColor}if(R.faviconUrl){let e=document.querySelector(`link[rel="icon"]`);e||(e=document.createElement(`link`),e.rel=`icon`,document.head.appendChild(e)),e.href=R.faviconUrl}},[R]),(0,j.useEffect)(()=>{function e(e){e.key===`Escape`&&g&&y()}return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[g,y]);function se(){X||(Y([]),u(K),B())}function $(e){if(!e&&n.length===0||X)return;Y(e=>e.map(e=>e.components?.some(e=>!e.submitted)?{...e,components:e.components.map(e=>e.submitted?e:{...e,submitted:!0})}:e)),u(t=>t.filter(t=>t!==e)),m(!0);let i=[...n];t(``),r([]),c(null),Z(e,{files:i})}function ce(t){t.preventDefault(),$(e.trim()),h.current?.resetHeight()}return(0,V.jsxs)(`div`,{className:`chat-page`,children:[(0,V.jsxs)(`header`,{className:`chat-header`,children:[(0,V.jsx)(`img`,{src:F||R?.logoUrl||O,alt:R?.name||f.productName,className:`chat-logo${F&&I===`circle`?` chat-logo--circle`:``}${F&&I===`rounded`?` chat-logo--rounded`:``}`,onError:e=>{e.target.src=R?.logoUrl||O}}),(0,V.jsxs)(`div`,{className:`chat-header-text`,children:[L!==`none`&&(0,V.jsx)(`h1`,{className:`chat-tagline`,children:G?.groupName||L&&P||R?.name||f.productName}),(0,V.jsx)(`p`,{className:`chat-intro`,children:G?`${G.participants.length} participants`:R?.tagline||``}),(0,V.jsx)(`p`,{className:`chat-ai-indicator`,children:`AI assistant`})]}),N===`chat`&&!g&&(0,V.jsxs)(`div`,{className:`chat-header-actions`,children:[(0,V.jsx)(`button`,{className:`chat-header-action`,onClick:se,disabled:X,title:`New conversation`,"aria-label":`New conversation`,children:(0,V.jsx)(k,{size:16})}),(0,V.jsx)(`button`,{className:`chat-header-action`,onClick:b,title:`Select messages`,"aria-label":`Select messages`,children:(0,V.jsx)(d,{size:16})})]})]}),N===`loading`&&(0,V.jsx)(`div`,{className:`gate-wrap`,children:(0,V.jsx)(`div`,{className:`gate-loading`,children:(0,V.jsx)(`span`,{className:`spinner`})})}),N===`auth-required`&&(0,V.jsx)(U,{gateState:T.gateState,setGateState:T.setGateState,grantInfo:T.grantInfo,setGrantInfo:T.setGrantInfo,gateSessionKeyRef:T.gateSessionKeyRef,resolvedSlugRef:T.resolvedSlugRef,onAuthenticated:T.enterChat}),N===`chat`&&(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(re,{messages:J,isStreaming:X,sessionError:M,selectionMode:g,selectedItems:_,toggleSelectItem:x,onComponentSubmit:oe,remainingSuggestions:l,onSuggestionClick:$,isAtBottom:p,setIsAtBottom:m,isGroup:!!G}),g?(0,V.jsx)(ie,{selectedItems:_,messages:J,copySelected:S,exitSelection:y,showCopyToast:C}):(0,V.jsx)(ae,{input:e,setInput:t,isStreaming:X,pendingFiles:n,setPendingFiles:r,attachError:s,setAttachError:c,isDragOver:i,setIsDragOver:o,inputRef:h,onSubmit:ce,onSendVoiceNote:e=>{t(``),r([]),c(null),Z(`[Voice note]`,{files:[e]})}})]}),v&&(0,V.jsx)(`span`,{className:`copy-toast${v===`failed`?` copy-toast-failed`:``}`,children:v===`copied`?`Copied`:`Copy failed`}),(0,V.jsxs)(`footer`,{className:`chat-footer`,children:[(0,V.jsxs)(`a`,{href:E,children:[f.domain,` `,`↗`]}),D&&(0,V.jsxs)(`span`,{style:{opacity:.35,fontSize:`10px`,fontFamily:`monospace`,marginLeft:`1rem`},children:[`Conversation · `,D.slice(0,8)]})]})]})}(0,A.createRoot)(document.getElementById(`root`)).render((0,V.jsx)(q,{}));