@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.
- package/dist/index.js +26 -0
- package/package.json +1 -1
- package/payload/platform/lib/graph-mcp/dist/index.js +98 -8
- package/payload/platform/lib/graph-mcp/dist/index.js.map +1 -1
- package/payload/platform/lib/graph-mcp/src/index.ts +115 -12
- package/payload/platform/plugins/admin/mcp/dist/index.js +6 -7
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/docs/references/plugins-guide.md +8 -0
- package/payload/platform/plugins/memory/references/graph-primitives.md +15 -0
- package/payload/server/chunk-LM5BMENF.js +77 -0
- package/payload/server/index.js +7225 -0
- package/payload/server/public/assets/{admin-Cacbe9nP.js → admin-E3EIZIw0.js} +30 -30
- package/payload/server/public/assets/public-Lwkux_Q4.js +5 -0
- package/payload/server/public/assets/useVoiceRecorder-Cbo-LQPY.css +1 -0
- package/payload/server/public/assets/{useVoiceRecorder-xC0cS-GO.js → useVoiceRecorder-D4y_EM_A.js} +2 -2
- package/payload/server/public/index.html +3 -3
- package/payload/server/public/public.html +3 -3
- package/payload/server/server.js +132 -84
- package/payload/server/upgrade-progress-server.js +83 -0
- package/payload/server/public/assets/public-CBVU1ErT.js +0 -5
- package/payload/server/public/assets/useVoiceRecorder-baV6L6a0.css +0 -1
|
@@ -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-
|
|
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-
|
|
12
|
-
<link rel="stylesheet" crossorigin href="/assets/useVoiceRecorder-
|
|
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-
|
|
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-
|
|
12
|
-
<link rel="stylesheet" crossorigin href="/assets/useVoiceRecorder-
|
|
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>
|
package/payload/server/server.js
CHANGED
|
@@ -1,32 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
|
|
2664
|
-
const server =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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", () =>
|
|
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
|
|
32288
|
-
import {
|
|
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
|
|
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
|
|
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
|
-
|
|
32438
|
+
closeSync5(logFd);
|
|
32361
32439
|
console.log(`[admin/version/upgrade] spawned upgrade process (pid ${child.pid})`);
|
|
32362
|
-
|
|
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
|
-
|
|
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,{}));
|