@rubytech/create-realagent 1.0.634 → 1.0.636

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.
@@ -5,11 +5,11 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Real Agent</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/admin-Cacbe9nP.js"></script>
8
+ <script type="module" crossorigin src="/assets/admin-E3EIZIw0.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-Be6NvmcD.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-rov5CBGT.js">
11
- <link rel="modulepreload" crossorigin href="/assets/useVoiceRecorder-xC0cS-GO.js">
12
- <link rel="stylesheet" crossorigin href="/assets/useVoiceRecorder-baV6L6a0.css">
11
+ <link rel="modulepreload" crossorigin href="/assets/useVoiceRecorder-D4y_EM_A.js">
12
+ <link rel="stylesheet" crossorigin href="/assets/useVoiceRecorder-Cbo-LQPY.css">
13
13
  <link rel="stylesheet" href="/brand-defaults.css">
14
14
  </head>
15
15
  <body>
@@ -5,11 +5,11 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <title>Real Agent</title>
7
7
  <link rel="icon" href="/favicon.ico">
8
- <script type="module" crossorigin src="/assets/public-CBVU1ErT.js"></script>
8
+ <script type="module" crossorigin src="/assets/public-Lwkux_Q4.js"></script>
9
9
  <link rel="modulepreload" crossorigin href="/assets/chunk-Be6NvmcD.js">
10
10
  <link rel="modulepreload" crossorigin href="/assets/preload-helper-rov5CBGT.js">
11
- <link rel="modulepreload" crossorigin href="/assets/useVoiceRecorder-xC0cS-GO.js">
12
- <link rel="stylesheet" crossorigin href="/assets/useVoiceRecorder-baV6L6a0.css">
11
+ <link rel="modulepreload" crossorigin href="/assets/useVoiceRecorder-D4y_EM_A.js">
12
+ <link rel="stylesheet" crossorigin href="/assets/useVoiceRecorder-Cbo-LQPY.css">
13
13
  <link rel="stylesheet" href="/brand-defaults.css">
14
14
  </head>
15
15
  <body>
@@ -1,32 +1,9 @@
1
- var __create = Object.create;
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __getProtoOf = Object.getPrototypeOf;
6
- var __hasOwnProp = Object.prototype.hasOwnProperty;
7
- var __commonJS = (cb, mod) => function __require() {
8
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
9
- };
10
- var __export = (target, all) => {
11
- for (var name in all)
12
- __defProp(target, name, { get: all[name], enumerable: true });
13
- };
14
- var __copyProps = (to, from, except, desc) => {
15
- if (from && typeof from === "object" || typeof from === "function") {
16
- for (let key of __getOwnPropNames(from))
17
- if (!__hasOwnProp.call(to, key) && key !== except)
18
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
19
- }
20
- return to;
21
- };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
- // If the importer is in node compatibility mode or this is not an ESM
24
- // file that has been converted to a CommonJS file using a Babel-
25
- // compatible transform (i.e. "__esModule" has not been set), then set
26
- // "default" to the CommonJS "module.exports" for node compatibility.
27
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
- mod
29
- ));
1
+ import {
2
+ __commonJS,
3
+ __export,
4
+ __toESM,
5
+ readProgressLog
6
+ } from "./chunk-LM5BMENF.js";
30
7
 
31
8
  // ../lib/models/dist/index.js
32
9
  var require_dist = __commonJS({
@@ -2660,8 +2637,8 @@ var createAdaptorServer = (options) => {
2660
2637
  overrideGlobalObjects: options.overrideGlobalObjects,
2661
2638
  autoCleanupIncoming: options.autoCleanupIncoming
2662
2639
  });
2663
- const createServer = options.createServer || createServerHTTP;
2664
- const server = createServer(options.serverOptions || {}, requestListener);
2640
+ const createServer2 = options.createServer || createServerHTTP;
2641
+ const server = createServer2(options.serverOptions || {}, requestListener);
2665
2642
  return server;
2666
2643
  };
2667
2644
  var serve = (options, listeningListener) => {
@@ -3004,7 +2981,7 @@ function validatePasswordStrength(password) {
3004
2981
  { key: "length", label: "At least 8 characters", met: password.length >= 8 },
3005
2982
  { key: "number", label: "Contains a number", met: /\d/.test(password) },
3006
2983
  { key: "special", label: "Contains a special character", met: /[^A-Za-z0-9]/.test(password) },
3007
- { key: "whitespace", label: "No leading or trailing spaces", met: password.length > 0 && password === password.trim() }
2984
+ { key: "whitespace", label: "No spaces", met: password.length > 0 && !/\s/.test(password) }
3008
2985
  ];
3009
2986
  }
3010
2987
  function isPasswordValid(password) {
@@ -3433,7 +3410,7 @@ function renderLoginPage(opts) {
3433
3410
  <div class="strength-item" id="req-length"><span class="strength-icon">\u25CB</span> At least 8 characters</div>
3434
3411
  <div class="strength-item" id="req-number"><span class="strength-icon">\u25CB</span> Contains a number</div>
3435
3412
  <div class="strength-item" id="req-special"><span class="strength-icon">\u25CB</span> Contains a special character</div>
3436
- <div class="strength-item" id="req-spaces"><span class="strength-icon">\u25CB</span> No leading or trailing spaces</div>
3413
+ <div class="strength-item" id="req-spaces"><span class="strength-icon">\u25CB</span> No spaces</div>
3437
3414
  </div>
3438
3415
  <div class="options">
3439
3416
  <label class="check">
@@ -3514,7 +3491,7 @@ function renderLoginPage(opts) {
3514
3491
  { id: 'req-length', test: function(p) { return p.length >= 8; } },
3515
3492
  { id: 'req-number', test: function(p) { return /\\d/.test(p); } },
3516
3493
  { id: 'req-special', test: function(p) { return /[^A-Za-z0-9]/.test(p); } },
3517
- { id: 'req-spaces', test: function(p) { return p.length > 0 && p === p.trim(); } }
3494
+ { id: 'req-spaces', test: function(p) { return p.length > 0 && !/\\s/.test(p); } }
3518
3495
  ];
3519
3496
 
3520
3497
  function check() {
@@ -4359,7 +4336,7 @@ import { spawn as spawn2, spawnSync as spawnSync2 } from "child_process";
4359
4336
  import { randomUUID as randomUUID2 } from "crypto";
4360
4337
  import { resolve as resolve6, join as join4 } from "path";
4361
4338
  import { platform as osPlatform } from "os";
4362
- import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, readdirSync as readdirSync2, existsSync as existsSync6, mkdirSync as mkdirSync4, createWriteStream, statSync as statSync3, unlinkSync as unlinkSync2, cpSync, rmSync, appendFileSync as appendFileSync2 } from "fs";
4339
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync5, readdirSync as readdirSync2, existsSync as existsSync6, mkdirSync as mkdirSync4, createWriteStream, statSync as statSync3, unlinkSync as unlinkSync2, cpSync, rmSync, appendFileSync as appendFileSync2, openSync as openSync2, readSync as readSync2, closeSync as closeSync2 } from "fs";
4363
4340
  import { lookup as dnsLookup } from "dns/promises";
4364
4341
  import { createConnection as netConnect } from "net";
4365
4342
  import { StringDecoder } from "string_decoder";
@@ -8647,7 +8624,7 @@ function clearAgentSessionId(sessionKey, reason) {
8647
8624
  console.error(`[session-store] clearAgentSessionId SKIPPED \u2014 no session entry sessionKey=${sessionKey.slice(0, 12)}\u2026 reason=${reason}`);
8648
8625
  }
8649
8626
  }
8650
- async function* parseClaudeStream(proc, streamLog, adminModel, conversationId) {
8627
+ async function* parseClaudeStream(proc, streamLog, adminModel, conversationId, accountId) {
8651
8628
  const toolIdToName = /* @__PURE__ */ new Map();
8652
8629
  const toolIdToInput = /* @__PURE__ */ new Map();
8653
8630
  const convIdTag = conversationId ? ` conversationId=${conversationId.slice(0, 8)}` : "";
@@ -8801,6 +8778,36 @@ async function* parseClaudeStream(proc, streamLog, adminModel, conversationId) {
8801
8778
  if (failed.length > 0) {
8802
8779
  streamLog.write(`[${isoTs()}] [init] FAILED MCP servers: ${failed.map((s) => s.name).join(", ")}
8803
8780
  `);
8781
+ if (accountId && conversationId) {
8782
+ const { logDir } = streamLogPathFor(accountId, conversationId);
8783
+ const date5 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
8784
+ for (const s of failed) {
8785
+ const stderrPath = resolve6(logDir, `mcp-${s.name}-stderr-${date5}.log`);
8786
+ let tail = "(no stderr file)";
8787
+ try {
8788
+ const stats = statSync3(stderrPath);
8789
+ const readFrom = Math.max(0, stats.size - 512);
8790
+ const bytesToRead = stats.size - readFrom;
8791
+ if (bytesToRead > 0) {
8792
+ const buf = Buffer.alloc(bytesToRead);
8793
+ const fd = openSync2(stderrPath, "r");
8794
+ try {
8795
+ readSync2(fd, buf, 0, bytesToRead, readFrom);
8796
+ } finally {
8797
+ closeSync2(fd);
8798
+ }
8799
+ const text = buf.toString("utf-8").replace(/\n+$/, "");
8800
+ tail = text.length > 0 ? text : "(empty)";
8801
+ } else {
8802
+ tail = "(empty)";
8803
+ }
8804
+ } catch {
8805
+ tail = "(no stderr file)";
8806
+ }
8807
+ streamLog.write(`[${isoTs()}] [mcp-init-error] server=${s.name} tail=${JSON.stringify(tail)}
8808
+ `);
8809
+ }
8810
+ }
8804
8811
  }
8805
8812
  }
8806
8813
  if (tools) {
@@ -9492,7 +9499,7 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
9492
9499
  const toolCalls = [];
9493
9500
  const pendingToolCalls = /* @__PURE__ */ new Map();
9494
9501
  let capturedTokens;
9495
- for await (const event of withSubagentHeartbeat(parseClaudeStream(proc, streamLog, adminModel, spawnConvId), streamLog)) {
9502
+ for await (const event of withSubagentHeartbeat(parseClaudeStream(proc, streamLog, adminModel, spawnConvId, accountId), streamLog)) {
9496
9503
  if (event.type === "session_init") {
9497
9504
  currentAgentSessionId = event.sessionId;
9498
9505
  if (sessionKey) storeAgentSessionId(sessionKey, event.sessionId);
@@ -9829,7 +9836,7 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
9829
9836
  const pendingToolCalls = /* @__PURE__ */ new Map();
9830
9837
  const renderedComponents = [];
9831
9838
  let capturedTokens;
9832
- for await (const event of withSubagentHeartbeat(parseClaudeStream(proc, streamLog, adminModel, managedConvId), streamLog)) {
9839
+ for await (const event of withSubagentHeartbeat(parseClaudeStream(proc, streamLog, adminModel, managedConvId, accountId), streamLog)) {
9833
9840
  if (event.type === "text") {
9834
9841
  responseText += event.content;
9835
9842
  } else if (event.type === "usage") {
@@ -11189,7 +11196,7 @@ function validateRule(input, label, seenIds) {
11189
11196
  }
11190
11197
 
11191
11198
  // app/lib/review-detector/sources.ts
11192
- import { existsSync as existsSync8, readdirSync as readdirSync3, statSync as statSync5, writeFileSync as writeFileSync7, renameSync as renameSync2, mkdirSync as mkdirSync6, openSync as openSync2, readSync as readSync2, closeSync as closeSync2, readFileSync as readFileSync9 } from "fs";
11199
+ import { existsSync as existsSync8, readdirSync as readdirSync3, statSync as statSync5, writeFileSync as writeFileSync7, renameSync as renameSync2, mkdirSync as mkdirSync6, openSync as openSync3, readSync as readSync3, closeSync as closeSync3, readFileSync as readFileSync9 } from "fs";
11193
11200
  import { resolve as resolve8, join as join5, basename, dirname as dirname3 } from "path";
11194
11201
  function tailStatePath(configDir2) {
11195
11202
  return resolve8(configDir2, "review-state.json");
@@ -11313,12 +11320,12 @@ function readNewLines(filepath, prev) {
11313
11320
  truncated
11314
11321
  };
11315
11322
  }
11316
- const fd = openSync2(filepath, "r");
11323
+ const fd = openSync3(filepath, "r");
11317
11324
  try {
11318
11325
  const bufSize = Math.max(0, size - startOffset);
11319
11326
  const buf = Buffer.alloc(bufSize);
11320
11327
  if (bufSize > 0) {
11321
- readSync2(fd, buf, 0, bufSize, startOffset);
11328
+ readSync3(fd, buf, 0, bufSize, startOffset);
11322
11329
  }
11323
11330
  const text = buf.toString("utf-8");
11324
11331
  const lines = text.length > 0 ? text.split("\n") : [];
@@ -11336,7 +11343,7 @@ function readNewLines(filepath, prev) {
11336
11343
  truncated
11337
11344
  };
11338
11345
  } finally {
11339
- closeSync2(fd);
11346
+ closeSync3(fd);
11340
11347
  }
11341
11348
  }
11342
11349
  function countRecentWrites(dir, sinceMs) {
@@ -31118,7 +31125,7 @@ async function POST16(req) {
31118
31125
 
31119
31126
  // app/api/onboarding/claude-auth/route.ts
31120
31127
  import { spawn as spawn3, execFileSync as execFileSync2 } from "child_process";
31121
- import { openSync as openSync3, closeSync as closeSync3, writeFileSync as writeFileSync12, writeSync } from "fs";
31128
+ import { openSync as openSync4, closeSync as closeSync4, writeFileSync as writeFileSync12, writeSync } from "fs";
31122
31129
  function checkAuthStatus() {
31123
31130
  try {
31124
31131
  execFileSync2("claude", ["auth", "status"], { encoding: "utf-8", timeout: 5e3 });
@@ -31189,7 +31196,7 @@ async function POST17(req, remoteAddress) {
31189
31196
  const chromiumWrapper = writeChromiumWrapper();
31190
31197
  const x11Env = buildX11Env(chromiumWrapper, transport);
31191
31198
  vncLog("claude-auth", { action: "start", transport });
31192
- const claudeAuthLogFd = openSync3(logPath("claude-auth"), "a");
31199
+ const claudeAuthLogFd = openSync4(logPath("claude-auth"), "a");
31193
31200
  const claudeProc = spawn3("claude", ["auth", "login"], {
31194
31201
  env: x11Env,
31195
31202
  stdio: ["ignore", "pipe", "pipe"]
@@ -31198,7 +31205,7 @@ async function POST17(req, remoteAddress) {
31198
31205
  const onClaudeOutput = (chunk) => writeSync(claudeAuthLogFd, chunk);
31199
31206
  claudeProc.stdout?.on("data", onClaudeOutput);
31200
31207
  claudeProc.stderr?.on("data", onClaudeOutput);
31201
- claudeProc.once("close", () => closeSync3(claudeAuthLogFd));
31208
+ claudeProc.once("close", () => closeSync4(claudeAuthLogFd));
31202
31209
  await waitForAuthPage(2e4);
31203
31210
  return Response.json({ started: true, transport });
31204
31211
  }
@@ -32284,8 +32291,10 @@ async function GET13() {
32284
32291
 
32285
32292
  // app/api/admin/version/upgrade/route.ts
32286
32293
  import { spawn as spawn4 } from "child_process";
32287
- import { existsSync as existsSync24, statSync as statSync9, writeFileSync as writeFileSync16, readFileSync as readFileSync24, openSync as openSync4, closeSync as closeSync4 } from "fs";
32288
- import { resolve as resolve26, join as join11 } from "path";
32294
+ import { existsSync as existsSync24, statSync as statSync9, writeFileSync as writeFileSync16, readFileSync as readFileSync24, openSync as openSync5, closeSync as closeSync5 } from "fs";
32295
+ import { createServer } from "net";
32296
+ import { resolve as resolve26, join as join11, dirname as dirname8 } from "path";
32297
+ import { fileURLToPath } from "url";
32289
32298
  var PLATFORM_ROOT10 = process.env.MAXY_PLATFORM_ROOT ?? resolve26(process.cwd(), "..");
32290
32299
  var upgradePkg = "@rubytech/create-maxy";
32291
32300
  var upgradeHostname = "maxy";
@@ -32318,6 +32327,27 @@ function isLockFresh() {
32318
32327
  return false;
32319
32328
  }
32320
32329
  }
32330
+ function probePortFree(port2) {
32331
+ return new Promise((resolve29) => {
32332
+ const probe = createServer();
32333
+ probe.once("error", (err) => {
32334
+ resolve29({ error: `${err.code ?? "EADDRINUSE"} on port ${port2}` });
32335
+ });
32336
+ probe.once("listening", () => {
32337
+ probe.close(() => resolve29(true));
32338
+ });
32339
+ probe.listen(port2, "0.0.0.0");
32340
+ });
32341
+ }
32342
+ function resolveSidecarPath() {
32343
+ try {
32344
+ const here = dirname8(fileURLToPath(import.meta.url));
32345
+ const candidate = join11(here, "upgrade-progress-server.js");
32346
+ return existsSync24(candidate) ? candidate : null;
32347
+ } catch {
32348
+ return null;
32349
+ }
32350
+ }
32321
32351
  async function POST23(req) {
32322
32352
  let body;
32323
32353
  try {
@@ -32335,17 +32365,65 @@ async function POST23(req) {
32335
32365
  if (isLockFresh()) {
32336
32366
  return Response.json({ ok: false, error: "upgrade already in progress" }, { status: 409 });
32337
32367
  }
32368
+ const mainPort = parseInt(process.env.PORT ?? "19200", 10);
32369
+ const sidecarPort = mainPort + 99;
32370
+ const portProbe = await probePortFree(sidecarPort);
32371
+ if (portProbe !== true) {
32372
+ console.error(`[admin/version/upgrade] sidecar port probe failed: ${portProbe.error}`);
32373
+ return Response.json(
32374
+ { ok: false, error: `upgrade progress port ${sidecarPort} is already in use (${portProbe.error})` },
32375
+ { status: 500 }
32376
+ );
32377
+ }
32378
+ const sidecarPath = resolveSidecarPath();
32379
+ const installerScope = `upgrade-${upgradeHostname}`;
32380
+ const sidecarScope = `upgrade-progress-${upgradeHostname}`;
32338
32381
  try {
32339
32382
  writeFileSync16(LOCK_FILE, String(Date.now()));
32340
32383
  } catch (err) {
32341
32384
  console.error("[admin/version/upgrade] failed to write lock file:", err);
32342
32385
  }
32386
+ if (!sidecarPath) {
32387
+ console.error("[admin/version/upgrade] progress sidecar binary not found in dist/");
32388
+ return Response.json(
32389
+ { ok: false, error: "progress sidecar binary missing \u2014 rebuild required" },
32390
+ { status: 500 }
32391
+ );
32392
+ }
32393
+ let sidecarPid;
32343
32394
  try {
32344
- const logFd = openSync4(LOG_FILE, "w");
32395
+ const sidecarLogFd = openSync5(LOG_FILE, "a");
32396
+ const sidecar = spawn4("systemd-run", [
32397
+ "--user",
32398
+ "--scope",
32399
+ `--unit=${sidecarScope}`,
32400
+ "--",
32401
+ "node",
32402
+ sidecarPath,
32403
+ `--port=${sidecarPort}`,
32404
+ `--log=${LOG_FILE}`,
32405
+ `--scope=${installerScope}`
32406
+ ], {
32407
+ detached: true,
32408
+ stdio: ["ignore", sidecarLogFd, sidecarLogFd]
32409
+ });
32410
+ sidecar.unref();
32411
+ closeSync5(sidecarLogFd);
32412
+ sidecarPid = sidecar.pid;
32413
+ console.log(`[admin/version/upgrade] spawned progress sidecar (pid ${sidecarPid} port ${sidecarPort})`);
32414
+ } catch (err) {
32415
+ console.error("[admin/version/upgrade] failed to spawn progress sidecar:", err);
32416
+ return Response.json(
32417
+ { ok: false, error: err instanceof Error ? err.message : "failed to spawn progress sidecar" },
32418
+ { status: 500 }
32419
+ );
32420
+ }
32421
+ try {
32422
+ const logFd = openSync5(LOG_FILE, "w");
32345
32423
  const child = spawn4("systemd-run", [
32346
32424
  "--user",
32347
32425
  "--scope",
32348
- `--unit=upgrade-${upgradeHostname}`,
32426
+ `--unit=${installerScope}`,
32349
32427
  "--",
32350
32428
  "npx",
32351
32429
  "-y",
@@ -32357,9 +32435,11 @@ async function POST23(req) {
32357
32435
  cwd: resolve26(process.cwd(), "..")
32358
32436
  });
32359
32437
  child.unref();
32360
- closeSync4(logFd);
32438
+ closeSync5(logFd);
32361
32439
  console.log(`[admin/version/upgrade] spawned upgrade process (pid ${child.pid})`);
32362
- return Response.json({ ok: true, started: true });
32440
+ const host = new URL(req.url).hostname;
32441
+ const progressUrl = `http://${host}:${sidecarPort}/progress`;
32442
+ return Response.json({ ok: true, started: true, progressUrl });
32363
32443
  } catch (err) {
32364
32444
  console.error("[admin/version/upgrade] failed to spawn upgrade process:", err);
32365
32445
  return Response.json(
@@ -32383,40 +32463,8 @@ if (existsSync25(brandPath2)) {
32383
32463
  }
32384
32464
  }
32385
32465
  var LOG_FILE2 = `/tmp/${upgradeHostname2}-upgrade.log`;
32386
- var STEP_RE = /\[(\d+)\/(\d+)\]\s+(.+)/;
32387
- var ANSI_RE = /\x1b\[[0-9;?]*[a-zA-Z]/g;
32388
- var stripAnsi = (s) => s.replace(ANSI_RE, "").replace(/\r/g, "").trimEnd();
32389
- var MAX_SUBSTEPS = 20;
32390
32466
  async function GET14() {
32391
- if (!existsSync25(LOG_FILE2)) {
32392
- return Response.json({ step: 0, total: 0, label: "", started: false, subSteps: [] });
32393
- }
32394
- let content;
32395
- try {
32396
- content = readFileSync25(LOG_FILE2, "utf-8");
32397
- } catch {
32398
- return Response.json({ step: 0, total: 0, label: "", started: false, subSteps: [] });
32399
- }
32400
- const rawLines = content.split("\n");
32401
- let step = 0;
32402
- let total = 0;
32403
- let label = "";
32404
- let markerIdx = -1;
32405
- for (let i = rawLines.length - 1; i >= 0; i--) {
32406
- const match2 = rawLines[i].match(STEP_RE);
32407
- if (match2) {
32408
- step = parseInt(match2[1], 10);
32409
- total = parseInt(match2[2], 10);
32410
- label = match2[3].replace(/\.{3}$/, "").trim();
32411
- markerIdx = i;
32412
- break;
32413
- }
32414
- }
32415
- const subSteps = markerIdx >= 0 ? rawLines.slice(markerIdx + 1).map(stripAnsi).filter((l) => l.length > 0).slice(-MAX_SUBSTEPS) : [];
32416
- const tail = rawLines.slice(-20).join("\n");
32417
- const finished = tail.includes("Open in your browser:");
32418
- const failed = tail.includes("Setup failed:");
32419
- return Response.json({ step, total, label, started: true, finished, failed, subSteps });
32467
+ return Response.json(readProgressLog(LOG_FILE2));
32420
32468
  }
32421
32469
 
32422
32470
  // app/api/admin/sessions/route.ts
@@ -0,0 +1,83 @@
1
+ import {
2
+ readProgressLog
3
+ } from "./chunk-LM5BMENF.js";
4
+
5
+ // server/upgrade-progress-server.ts
6
+ import { createServer } from "http";
7
+ import { spawnSync } from "child_process";
8
+ import { appendFileSync } from "fs";
9
+ function arg(name) {
10
+ const prefix = `--${name}=`;
11
+ const hit = process.argv.find((a) => a.startsWith(prefix));
12
+ return hit?.slice(prefix.length);
13
+ }
14
+ var port = parseInt(arg("port") ?? "0", 10);
15
+ var logPath = arg("log") ?? "";
16
+ var scopeUnit = arg("scope") ?? "";
17
+ if (!port || !logPath || !scopeUnit) {
18
+ console.error(`[progress-server] missing required args: --port=${port} --log=${logPath} --scope=${scopeUnit}`);
19
+ process.exit(2);
20
+ }
21
+ function banner(line) {
22
+ try {
23
+ appendFileSync(logPath, `${line}
24
+ `);
25
+ } catch {
26
+ }
27
+ }
28
+ var server = createServer((req, res) => {
29
+ res.setHeader("Access-Control-Allow-Origin", "*");
30
+ res.setHeader("Access-Control-Allow-Methods", "GET, OPTIONS");
31
+ if (req.method === "OPTIONS") {
32
+ res.statusCode = 204;
33
+ res.end();
34
+ return;
35
+ }
36
+ if (req.url !== "/progress") {
37
+ res.statusCode = 404;
38
+ res.end();
39
+ return;
40
+ }
41
+ const payload = readProgressLog(logPath);
42
+ res.setHeader("Content-Type", "application/json");
43
+ res.statusCode = 200;
44
+ res.end(JSON.stringify(payload));
45
+ });
46
+ server.on("error", (err) => {
47
+ console.error(`[progress-server] listen error: ${err.code ?? ""} ${err.message}`);
48
+ banner(`[progress-server] exiting reason=error code=${err.code ?? "unknown"}`);
49
+ process.exit(1);
50
+ });
51
+ server.listen(port, "0.0.0.0", () => {
52
+ banner(`[progress-server] listening port=${port} log=${logPath} scope=${scopeUnit}`);
53
+ });
54
+ var installerSeenActive = false;
55
+ var WATCHDOG_INTERVAL_MS = 2e3;
56
+ var GRACE_UNTIL = Date.now() + 5e3;
57
+ function shutdown(reason) {
58
+ banner(`[progress-server] exiting reason=${reason}`);
59
+ server.close(() => process.exit(0));
60
+ setTimeout(() => process.exit(0), 500).unref();
61
+ }
62
+ var watchdog = setInterval(() => {
63
+ const result = spawnSync("systemctl", ["--user", "is-active", scopeUnit], { stdio: "pipe" });
64
+ const status = result.stdout?.toString().trim();
65
+ if (status === "active") {
66
+ installerSeenActive = true;
67
+ return;
68
+ }
69
+ if (!installerSeenActive && Date.now() < GRACE_UNTIL) return;
70
+ if (!installerSeenActive) {
71
+ banner(`[progress-server] exiting reason=scope-inactive (installer never reached active)`);
72
+ }
73
+ clearInterval(watchdog);
74
+ shutdown("scope-inactive");
75
+ }, WATCHDOG_INTERVAL_MS);
76
+ process.on("SIGTERM", () => {
77
+ clearInterval(watchdog);
78
+ shutdown("sigterm");
79
+ });
80
+ process.on("SIGINT", () => {
81
+ clearInterval(watchdog);
82
+ shutdown("sigint");
83
+ });
@@ -1,5 +0,0 @@
1
- import{o as e}from"./chunk-Be6NvmcD.js";import{A as t,B as n,C as r,D as i,F as a,L as o,M as s,N as c,P as l,R as u,S as d,_ as f,a as p,b as m,c as h,g,h as _,i as v,j as y,n as b,o as x,r as S,s as C,t as w,u as T,v as E,w as D,y as O}from"./useVoiceRecorder-xC0cS-GO.js";var k=o(`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=u(),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 leading or trailing spaces`,met:e.length>0&&e===e.trim()}]}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 V(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 ee({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)},f=(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]),p=(0,j.useCallback)(async(a,s)=>{let c=s?.hidden??!1,f=s?.files??[];if(!a&&f.length===0||l.current)return;u(!0);let p=f.map(e=>({filename:e.name,mimeType:e.type})),m={role:`visitor`,content:a,attachments:p.length>0?p:void 0,timestamp:Date.now(),hidden:c},h;o(e=>{let t=[...e,m,{role:`maxy`,content:``,timestamp:Date.now()}];return h=t.length-1,t});try{let n=await t();if(!n)throw Error(`session`);let r=e=>{if(f.length>0){let t=new FormData;t.append(`message`,a),t.append(`session_key`,e);for(let e of f)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=``,p=()=>{u&&(l+=u,u=``,o(e=>{let t=[...e];return t[h]={...t[h],content:l},t}))},m=setInterval(p,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`&&(p(),o(t=>{let n=[...t],r={...n[h]},i=[...r.components||[]];return i.push({name:e.name,data:e.data,submitted:!1}),n[h]={...r,components:i},n}))}}finally{clearInterval(m),p()}}catch(e){if(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[h]={...r[h],content:i?t:t===`session`?n??`I'm having trouble connecting right now. Try refreshing the page.`:`Sorry, I hit a snag. Try again in a moment.`},r})}finally{u(!1),r===`chat`&&i.current?.focus()}},[e,t,n,r,i]);return{messages:a,setMessages:o,isStreaming:s,sendMessage:p,sendGreeting:f,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}),p(n,{hidden:!0})},[p])}}function te({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 H=f();function U({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,H.jsx)(`div`,{className:`gate-otp-field`,children:Array.from({length:6}).map((t,n)=>(0,H.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 ne({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),[h,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,H.jsx)(`div`,{className:`gate-wrap`,children:(0,H.jsxs)(`div`,{className:`gate-card`,children:[n?.expiresAt&&(0,H.jsxs)(`div`,{className:`gate-expiry-badge`,children:[`Access until `,new Date(n.expiresAt).toLocaleDateString(`en-GB`,{day:`numeric`,month:`short`,year:`numeric`})]}),(0,H.jsxs)(`h2`,{className:`gate-title`,children:[`Welcome, `,n?.displayName||`there`]}),(0,H.jsx)(`p`,{className:`gate-subtitle`,children:`Create a password to access this agent in the future.`}),(0,H.jsxs)(`form`,{className:`gate-form`,onSubmit:M,children:[(0,H.jsxs)(`div`,{className:`gate-field`,children:[(0,H.jsx)(`label`,{htmlFor:`gate-display-name`,children:`Display name`}),(0,H.jsx)(`input`,{id:`gate-display-name`,type:`text`,value:n?.displayName||``,disabled:!0})]}),(0,H.jsxs)(`div`,{className:`gate-field gate-pw-row`,children:[(0,H.jsx)(`label`,{htmlFor:`gate-pw`,children:`Password`}),(0,H.jsx)(`div`,{className:`gate-pw-toggle`,children:(0,H.jsx)(g,{checked:p,onChange:m,label:`Show`})}),(0,H.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,H.jsx)(`div`,{className:`gate-strength`,children:e.map(e=>(0,H.jsxs)(`span`,{className:`gate-strength-item${e.met?` met`:``}`,children:[e.met?`✓`:`○`,` `,e.label]},e.key))})]}),(0,H.jsxs)(`div`,{className:`gate-field`,children:[(0,H.jsx)(`label`,{htmlFor:`gate-pw-confirm`,children:`Confirm password`}),(0,H.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,H.jsx)(`div`,{className:`gate-error`,children:`Passwords do not match`})]}),C&&(0,H.jsx)(`div`,{className:`gate-error`,children:C}),(0,H.jsx)(`div`,{className:`gate-submit`,children:(0,H.jsx)(_,{variant:`primary`,type:`submit`,fullWidth:!0,disabled:!i||D,loading:D,children:`Create account & enter chat`})})]})]})})}case`enter-otp`:return(0,H.jsx)(`div`,{className:`gate-wrap`,children:(0,H.jsxs)(`div`,{className:`gate-card`,children:[(0,H.jsx)(`h2`,{className:`gate-title`,children:`Enter your code`}),(0,H.jsxs)(`p`,{className:`gate-subtitle`,children:[`Enter the 6-digit code sent to `,B(y,`phone`)]}),(0,H.jsx)(U,{value:h,onChange:v,onComplete:A,disabled:D}),C&&(0,H.jsx)(`div`,{className:`gate-error`,children:C}),D&&(0,H.jsxs)(`div`,{className:`gate-loading`,children:[(0,H.jsx)(`span`,{className:`spinner`}),`Verifying...`]}),(0,H.jsx)(`div`,{className:`gate-resend`,children:(0,H.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,H.jsx)(`div`,{className:`gate-wrap`,children:(0,H.jsxs)(`div`,{className:`gate-card`,children:[(0,H.jsx)(`h2`,{className:`gate-title`,children:e===`private-agent`?`Private Agent`:`Welcome back`}),(0,H.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,H.jsxs)(`form`,{className:`gate-form`,onSubmit:N,children:[(0,H.jsxs)(`div`,{className:`gate-field`,children:[(0,H.jsx)(`label`,{htmlFor:`gate-forgot-contact`,children:`Email or phone`}),(0,H.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,H.jsx)(`div`,{className:`gate-error`,children:C}),T&&(0,H.jsx)(`div`,{className:`gate-success`,children:T}),(0,H.jsx)(`div`,{className:`gate-submit`,children:(0,H.jsx)(_,{variant:`primary`,type:`submit`,fullWidth:!0,disabled:!s.trim()||D,loading:D,children:`Send reset link`})}),(0,H.jsx)(`div`,{className:`gate-actions`,children:(0,H.jsx)(`button`,{type:`button`,className:`gate-link`,onClick:()=>{S(!1),w(null),E(null)},children:`Back to sign in`})})]}):(0,H.jsxs)(`form`,{className:`gate-form`,onSubmit:k,children:[(0,H.jsxs)(`div`,{className:`gate-field`,children:[(0,H.jsx)(`label`,{htmlFor:`gate-contact`,children:`Email or phone`}),(0,H.jsx)(`input`,{id:`gate-contact`,type:`text`,value:s,onChange:e=>c(e.target.value),placeholder:`you@example.com`,autoFocus:!0,autoComplete:`email`})]}),(0,H.jsxs)(`div`,{className:`gate-field gate-pw-row`,children:[(0,H.jsx)(`label`,{htmlFor:`gate-login-pw`,children:`Password`}),(0,H.jsx)(`div`,{className:`gate-pw-toggle`,children:(0,H.jsx)(g,{checked:p,onChange:m,label:`Show`})}),(0,H.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,H.jsx)(`div`,{className:`gate-error`,children:C}),(0,H.jsx)(`div`,{className:`gate-submit`,children:(0,H.jsx)(_,{variant:`primary`,type:`submit`,fullWidth:!0,disabled:!s.trim()||!l||D,loading:D,children:`Sign in`})}),(0,H.jsx)(`div`,{className:`gate-actions`,children:(0,H.jsx)(`button`,{type:`button`,className:`gate-link`,onClick:()=>{S(!0),w(null)},children:`Forgot password?`})})]}),e===`private-agent`&&(0,H.jsx)(`p`,{className:`gate-hint`,children:`No account? You need an invitation from the agent owner.`})]})});case`access-expired`:return(0,H.jsx)(`div`,{className:`gate-wrap`,children:(0,H.jsxs)(`div`,{className:`gate-card`,children:[(0,H.jsx)(`div`,{className:`gate-icon`,children:`⏰`}),(0,H.jsx)(`h2`,{className:`gate-title`,children:`Access expired`}),(0,H.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,H.jsx)(`div`,{className:`gate-actions`,children:(0,H.jsx)(_,{variant:`secondary`,onClick:()=>{t(`sign-in`),w(null),u(``)},children:`Sign in with a different account`})})]})});case`link-expired`:return(0,H.jsx)(`div`,{className:`gate-wrap`,children:(0,H.jsxs)(`div`,{className:`gate-card`,children:[(0,H.jsx)(`div`,{className:`gate-icon`,children:`⚠️`}),(0,H.jsx)(`h2`,{className:`gate-title`,children:`Link expired`}),(0,H.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,H.jsx)(`div`,{className:`gate-actions`,children:(0,H.jsx)(_,{variant:`primary`,onClick:()=>{t(`sign-in`),w(null)},children:`Go to sign in`})})]})});case`otp-failed`:return(0,H.jsx)(`div`,{className:`gate-wrap`,children:(0,H.jsxs)(`div`,{className:`gate-card`,children:[(0,H.jsx)(`div`,{className:`gate-icon`,children:`⛔`}),(0,H.jsx)(`h2`,{className:`gate-title`,children:`Too many attempts`}),(0,H.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,H.jsx)(`div`,{className:`gate-actions`,children:(0,H.jsx)(_,{variant:`secondary`,onClick:()=>{t(`sign-in`),w(null),v(``)},children:`Back to sign in`})})]})})}}var W={"single-select":h,"multi-select":C,"action-buttons":x};function G({name:e,data:t,onSubmit:n,submitted:r}){let i=W[e];return i?(0,H.jsx)(i,{data:t,onSubmit:n,submitted:r}):(console.warn(`[PublicComponentRenderer] Unknown component: "${e}". Registered: ${Object.keys(W).join(`, `)}`),(0,H.jsx)(`div`,{className:`component-card component-card--error`,children:(0,H.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:o,onComponentSubmit:l,remainingSuggestions:u,onSuggestionClick:d,isAtBottom:f,setIsAtBottom:m,isGroup:h}){let[v,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&&f&&(D.current=!0)},[t,f]),(0,j.useEffect)(()=>{if(!D.current&&!f){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}}(f||D.current)&&!O.current&&S.current?.scrollIntoView({behavior:`smooth`}),E.current&&!t&&(D.current=!1),E.current=t},[e,f,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,m(e.scrollHeight-e.scrollTop-e.clientHeight<80)};return e.addEventListener(`scroll`,t,{passive:!0}),t(),()=>e.removeEventListener(`scroll`,t)},[m]),(0,j.useEffect)(()=>{function e(){x(e=>{let t=new Set;return M.current.forEach((n,r)=>{n.isConnected&&(v.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,v]);let N=e.reduce((e,t,n)=>t.role===`maxy`&&!t.hidden?n:e,-1);return(0,H.jsxs)(`div`,{className:`chat-messages-wrap`,children:[r&&(0,H.jsx)(`div`,{className:`selection-overlay-band`}),(0,H.jsxs)(`div`,{className:`chat-messages`,ref:C,children:[n&&e.length===0&&(0,H.jsx)(`div`,{className:`session-error`,children:(0,H.jsx)(`p`,{children:n})}),e.map((n,u)=>{if(n.hidden)return null;let d=t&&u===e.length-1,f=`${n.timestamp}_${n.role}`,m=i.has(f);return(0,H.jsxs)(`div`,{ref:u===N?w:void 0,className:`message ${n.role}${m?` selected`:``}`,children:[r&&!d&&(0,H.jsx)(`div`,{className:`message-select-check`,children:(0,H.jsx)(g,{checked:m,onChange:()=>o(f)})}),(0,H.jsxs)(`div`,{className:`bubble`,children:[h&&n.role===`visitor`&&n.senderName&&(0,H.jsx)(`span`,{className:`bubble-sender`,children:n.senderName}),n.role===`visitor`&&n.content?(()=>{let e=v.has(u),t=b.has(u);return(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(`div`,{ref:e=>{e?M.current.set(u,e):M.current.delete(u)},className:e?`bubble-content`:`bubble-content clamped${t?` overflowing`:``}`,children:n.content}),t&&(0,H.jsx)(`div`,{className:`bubble-expand`,children:(0,H.jsx)(_,{variant:`icon`,className:e?`expanded`:``,onClick:()=>y(e=>{let t=new Set(e);return t.has(u)?t.delete(u):t.add(u),t}),"aria-label":e?`Collapse message`:`Expand message`,children:(0,H.jsx)(a,{size:14})})})]})})():n.content?(0,H.jsx)(T,{content:n.content,timestamp:p(n.timestamp)}):(0,H.jsxs)(`span`,{className:`typing-indicator`,children:[(0,H.jsx)(`span`,{className:`typing-dot`}),(0,H.jsx)(`span`,{className:`typing-dot`}),(0,H.jsx)(`span`,{className:`typing-dot`})]}),n.attachments&&n.attachments.length>0&&(0,H.jsx)(`div`,{className:`message-attachments`,children:n.attachments.map((e,t)=>(0,H.jsxs)(`span`,{className:`message-attachment-chip no-action`,children:[e.mimeType===`application/pdf`?(0,H.jsx)(s,{size:12}):e.mimeType.startsWith(`text/`)?(0,H.jsx)(c,{size:12}):null,(0,H.jsx)(`span`,{children:e.filename})]},t))}),n.role===`visitor`&&(0,H.jsx)(`span`,{className:`message-timestamp`,children:p(n.timestamp)})]}),n.role===`maxy`&&n.components&&n.components.length>0&&(0,H.jsx)(`div`,{className:`public-components`,children:n.components.map((e,t)=>(0,H.jsx)(`div`,{className:`public-component-enter`,children:(0,H.jsx)(G,{name:e.name,data:e.data,onSubmit:e=>l(u,t,e),submitted:e.submitted})},t))})]},u)}),!t&&u.length>0&&(0,H.jsx)(`div`,{className:`chat-suggestions`,children:u.map(e=>(0,H.jsx)(_,{variant:`suggestion`,onClick:()=>d(e),children:e},e))}),(0,H.jsx)(`div`,{ref:S})]}),!f&&(0,H.jsx)(`button`,{className:`scroll-to-bottom`,onClick:()=>S.current?.scrollIntoView({behavior:`smooth`}),"aria-label":`Scroll to bottom`,children:(0,H.jsx)(a,{size:18})})]})}function ie({selectedItems:e,messages:t,copySelected:n,exitSelection:i,showCopyToast:a}){let[o,s]=(0,j.useState)(!1),c=(0,j.useRef)(null),u=(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(!o)return;let e=e=>{e.target.closest(`.selection-copy-wrap`)||s(!1)};return document.addEventListener(`pointerdown`,e),()=>document.removeEventListener(`pointerdown`,e)},[o]);function m(){c.current!==null&&(clearTimeout(c.current),c.current=null)}return(0,H.jsx)(`div`,{className:`chat-input-area`,children:(0,H.jsxs)(`div`,{className:`selection-bar`,children:[(0,H.jsxs)(`span`,{className:`selection-count`,children:[e.size,` Selected`]}),(0,H.jsxs)(`div`,{className:`selection-copy-wrap`,children:[(0,H.jsxs)(`button`,{type:`button`,className:`selection-copy`,onPointerDown:()=>{if(o){s(!1);return}u.current=!1,c.current=setTimeout(()=>{u.current=!0,s(!0),c.current=null},500)},onPointerUp:m,onPointerLeave:m,onPointerCancel:m,onClick:async()=>{u.current||await n(d,f)},children:[(0,H.jsx)(l,{size:18}),(0,H.jsx)(`span`,{children:`Copy`})]}),o&&(0,H.jsx)(`div`,{className:`copy-menu`,children:(0,H.jsx)(`button`,{type:`button`,className:`copy-menu-item`,onClick:async()=>{let e=p();e&&a(await r(e)),i()},children:`Copy all`})})]}),(0,H.jsx)(`button`,{type:`button`,className:`selection-cancel`,onClick:i,children:`Cancel`})]})})}function ae({input:e,setInput:n,isStreaming:r,pendingFiles:i,setPendingFiles:a,attachError:o,setAttachError:l,isDragOver:u,setIsDragOver:d,inputRef:f,onSubmit:p,onSendVoiceNote:m}){let h=(0,j.useRef)(null),g=w(),x=g.state===`recording`||g.state===`paused`||g.state===`sending`,C=!x&&!r&&!e.trim()&&i.length===0;async function T(){let e=await g.send();if(!e)return;let t=e.type===`audio/ogg`?`.ogg`:e.type===`audio/mp4`?`.m4a`:`.webm`;m(new File([e],`voice-note${t}`,{type:e.type}))}function E(e){l(null);let t=e.find(e=>!N.has(e.type));if(t){l(`Unsupported file type: "${t.type}". Supported: images, PDF, plain text, markdown, CSV, calendar.`);return}let n=e.find(e=>e.size>P);if(n){l(`"${n.name}" exceeds the 20 MB limit.`);return}a(t=>[...t,...e].slice(0,5))}function D(e){e.preventDefault(),d(!0)}function O(){d(!1)}function k(e){e.preventDefault(),d(!1),E([...e.dataTransfer.files])}return(0,H.jsxs)(`div`,{className:`chat-input-area`,children:[(0,H.jsx)(`input`,{ref:h,type:`file`,multiple:!0,accept:M,style:{display:`none`},onChange:e=>{e.target.files&&E([...e.target.files]),e.target.value=``}}),i.length>0&&(0,H.jsx)(`div`,{className:`attachment-strip`,children:i.map((e,t)=>(0,H.jsxs)(`div`,{className:`attachment-chip`,children:[e.type.startsWith(`image/`)?(0,H.jsx)(`img`,{src:URL.createObjectURL(e),alt:e.name,className:`attachment-chip-thumb`}):e.type===`application/pdf`?(0,H.jsx)(s,{size:14}):(0,H.jsx)(c,{size:14}),(0,H.jsx)(`span`,{className:`attachment-chip-name`,children:e.name}),(0,H.jsx)(`button`,{type:`button`,className:`attachment-chip-remove`,onClick:()=>a(e=>e.filter((e,n)=>n!==t)),"aria-label":`Remove ${e.name}`,children:`×`})]},t))}),o&&(0,H.jsx)(`p`,{className:`attach-error`,children:o}),g.state===`error`&&g.errorMessage&&(0,H.jsxs)(`p`,{className:`voice-error`,role:`alert`,children:[(0,H.jsx)(y,{size:14}),g.errorMessage]}),(0,H.jsx)(v,{inputRef:f}),x?(0,H.jsx)(`div`,{className:`chat-form voice-active`,children:(0,H.jsx)(b,{state:g.state,elapsedSeconds:g.elapsedSeconds,waveform:g.waveform,onTogglePause:g.togglePause,onDiscard:g.discard,onSend:T})}):(0,H.jsxs)(`form`,{className:`chat-form${u?` drag-over`:``}`,onSubmit:p,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,H.jsx)(_,{variant:`icon`,type:`button`,onClick:()=>h.current?.click(),disabled:r,"aria-label":`Attach file`,children:(0,H.jsx)(t,{size:14})}),(0,H.jsx)(S,{ref:f,value:e,onChange:n}),C?(0,H.jsx)(_,{variant:`send`,type:`button`,onClick:g.start,disabled:r,"aria-label":`Record voice note`,children:(0,H.jsx)(y,{size:14})}):(0,H.jsx)(_,{variant:`send`,type:`submit`,disabled:r||!e.trim()&&i.length===0,"aria-label":`Send message`,children:(0,H.jsxs)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:`2`,strokeLinecap:`round`,strokeLinejoin:`round`,children:[(0,H.jsx)(`line`,{x1:`5`,y1:`12`,x2:`19`,y2:`12`}),(0,H.jsx)(`polyline`,{points:`12 5 19 12 12 19`})]})})]})]})}var K=[];function q(){let[e,t]=(0,j.useState)(``),[n,r]=(0,j.useState)([]),[a,o]=(0,j.useState)(!1),[s,c]=(0,j.useState)(null),[l,u]=(0,j.useState)(K),[d,f]=(0,j.useState)(!0),p=(0,j.useRef)(null),{selectionMode:h,selectedItems:g,copyToast:_,exitSelection:v,enterSelection:y,toggleSelectItem:b,copySelected:x,showCopyToast:S}=D(),C=(0,j.useRef)(()=>{}),w=V((0,j.useCallback)(e=>{C.current(e)},[])),{sessionId:T,sessionKeyRef:A,sessionError:M,pageState:N,agentDisplayName:P,agentImage:F,agentImageShape:I,showAgentName:L,branding:R,ensureSession:z,startNewSession:B,resumedRef:U,resumeMessagesRef:W,groupContext:G,groupSlug:q}=w,{messages:J,setMessages:Y,isStreaming:X,sendMessage:Z,sendGreeting:Q,handleComponentSubmit:oe}=ee({sessionKeyRef:A,ensureSession:z,sessionError:M,pageState:N,inputRef:p});(0,j.useEffect)(()=>{C.current=Q},[Q]),te({sessionKeyRef:A,groupSlug:q,isStreaming:X,setMessages:Y}),(0,j.useEffect)(()=>{let e=!1;return(async()=>{let t=await z();if(!e&&t){if(U.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`&&p.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`&&h&&v()}return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[h,v]);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)),f(!0);let i=[...n];t(``),r([]),c(null),Z(e,{files:i})}function ce(t){t.preventDefault(),$(e.trim()),p.current?.resetHeight()}return(0,H.jsxs)(`div`,{className:`chat-page`,children:[(0,H.jsxs)(`header`,{className:`chat-header`,children:[(0,H.jsx)(`img`,{src:F||R?.logoUrl||m,alt:R?.name||E.productName,className:`chat-logo${F&&I===`circle`?` chat-logo--circle`:``}${F&&I===`rounded`?` chat-logo--rounded`:``}`,onError:e=>{e.target.src=R?.logoUrl||m}}),(0,H.jsxs)(`div`,{className:`chat-header-text`,children:[L!==`none`&&(0,H.jsx)(`h1`,{className:`chat-tagline`,children:G?.groupName||L&&P||R?.name||E.productName}),(0,H.jsx)(`p`,{className:`chat-intro`,children:G?`${G.participants.length} participants`:R?.tagline||``}),(0,H.jsx)(`p`,{className:`chat-ai-indicator`,children:`AI assistant`})]}),N===`chat`&&!h&&(0,H.jsxs)(`div`,{className:`chat-header-actions`,children:[(0,H.jsx)(`button`,{className:`chat-header-action`,onClick:se,disabled:X,title:`New conversation`,"aria-label":`New conversation`,children:(0,H.jsx)(k,{size:16})}),(0,H.jsx)(`button`,{className:`chat-header-action`,onClick:y,title:`Select messages`,"aria-label":`Select messages`,children:(0,H.jsx)(i,{size:16})})]})]}),N===`loading`&&(0,H.jsx)(`div`,{className:`gate-wrap`,children:(0,H.jsx)(`div`,{className:`gate-loading`,children:(0,H.jsx)(`span`,{className:`spinner`})})}),N===`auth-required`&&(0,H.jsx)(ne,{gateState:w.gateState,setGateState:w.setGateState,grantInfo:w.grantInfo,setGrantInfo:w.setGrantInfo,gateSessionKeyRef:w.gateSessionKeyRef,resolvedSlugRef:w.resolvedSlugRef,onAuthenticated:w.enterChat}),N===`chat`&&(0,H.jsxs)(H.Fragment,{children:[(0,H.jsx)(re,{messages:J,isStreaming:X,sessionError:M,selectionMode:h,selectedItems:g,toggleSelectItem:b,onComponentSubmit:oe,remainingSuggestions:l,onSuggestionClick:$,isAtBottom:d,setIsAtBottom:f,isGroup:!!G}),h?(0,H.jsx)(ie,{selectedItems:g,messages:J,copySelected:x,exitSelection:v,showCopyToast:S}):(0,H.jsx)(ae,{input:e,setInput:t,isStreaming:X,pendingFiles:n,setPendingFiles:r,attachError:s,setAttachError:c,isDragOver:a,setIsDragOver:o,inputRef:p,onSubmit:ce,onSendVoiceNote:e=>{t(``),r([]),c(null),Z(`[Voice note]`,{files:[e]})}})]}),_&&(0,H.jsx)(`span`,{className:`copy-toast${_===`failed`?` copy-toast-failed`:``}`,children:_===`copied`?`Copied`:`Copy failed`}),(0,H.jsxs)(`footer`,{className:`chat-footer`,children:[(0,H.jsxs)(`a`,{href:O,children:[E.domain,` `,`↗`]}),T&&(0,H.jsxs)(`span`,{style:{opacity:.35,fontSize:`10px`,fontFamily:`monospace`,marginLeft:`1rem`},children:[`Conversation · `,T.slice(0,8)]})]})]})}(0,A.createRoot)(document.getElementById(`root`)).render((0,H.jsx)(q,{}));