@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.
- package/package.json +1 -1
- package/payload/platform/neo4j/migrations/002-linkedin-types.cypher +103 -0
- package/payload/platform/plugins/docs/references/platform.md +1 -1
- package/payload/platform/plugins/docs/references/troubleshooting.md +28 -0
- package/payload/server/chunk-3VVHVJK2.js +11405 -0
- package/payload/server/maxy-edge.js +1 -1
- package/payload/server/public/assets/{admin-BsLm49w9.js → admin-CjRb2gH7.js} +1 -1
- package/payload/server/public/assets/{data-BKexd229.js → data-sqtkLfgS.js} +1 -1
- package/payload/server/public/assets/{file-DZkqmm8M.js → file-Dsaxvh3t.js} +1 -1
- package/payload/server/public/assets/{graph-CPqHYozW.js → graph-ih5hzKOO.js} +1 -1
- package/payload/server/public/assets/{house-CPxWBrMl.js → house-Bse5AWrO.js} +1 -1
- package/payload/server/public/assets/{jsx-runtime-2yRmkrVq.css → jsx-runtime-DDu3Iu4h.css} +1 -1
- package/payload/server/public/assets/public-Btb8pJWN.js +5 -0
- package/payload/server/public/assets/{share-2-Bauv6ctA.js → share-2-nB3FxYbd.js} +1 -1
- package/payload/server/public/assets/{useVoiceRecorder-BTEcf6H3.js → useVoiceRecorder-D2OAQlJy.js} +3 -3
- package/payload/server/public/assets/{x-Kc93nSru.js → x-g2pNE8fh.js} +1 -1
- package/payload/server/public/data.html +6 -6
- package/payload/server/public/graph.html +6 -6
- package/payload/server/public/index.html +7 -7
- package/payload/server/public/public.html +4 -4
- package/payload/server/server.js +70 -26
- package/payload/server/public/assets/public-BthX_YNC.js +0 -5
- /package/payload/server/public/assets/{jsx-runtime-7o3Lvx89.js → jsx-runtime-rRO5uNvZ.js} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -97,7 +97,7 @@ import {
|
|
|
97
97
|
vncLog,
|
|
98
98
|
waitForExit,
|
|
99
99
|
writeChromiumWrapper
|
|
100
|
-
} from "./chunk-
|
|
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 =
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
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
|
-
|
|
5628
|
-
|
|
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:
|
|
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
|
|
7614
|
+
const client = resolveClientIp(
|
|
7597
7615
|
c.env?.incoming?.socket?.remoteAddress,
|
|
7598
7616
|
c.req.header("x-forwarded-for")
|
|
7599
|
-
)
|
|
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
|
|
11359
|
-
const
|
|
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(
|
|
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(
|
|
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
|
|
11405
|
-
const
|
|
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(
|
|
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(
|
|
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:
|
|
11539
|
-
xForwardedFor:
|
|
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,{}));
|
|
File without changes
|