@rubytech/create-maxy 1.0.627 → 1.0.629
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/payload/platform/plugins/cloudflare/scripts/_stream-log.sh +124 -0
- package/payload/platform/plugins/cloudflare/scripts/reset-tunnel.sh +45 -3
- package/payload/platform/plugins/cloudflare/scripts/setup-tunnel.sh +151 -10
- package/payload/platform/plugins/docs/references/plugins-guide.md +2 -0
- package/payload/server/public/assets/admin-CGIu9HnV.js +352 -0
- package/payload/server/public/assets/public-Cizdj15i.js +5 -0
- package/payload/server/public/assets/useVoiceRecorder-DIV9KAk_.css +1 -0
- package/payload/server/public/assets/{useVoiceRecorder-CiYPZu3g.js → useVoiceRecorder-tbj4tUsl.js} +1 -1
- package/payload/server/public/index.html +3 -3
- package/payload/server/public/public.html +3 -3
- package/payload/server/server.js +232 -96
- package/payload/server/public/assets/admin-BxVuKRJZ.js +0 -352
- package/payload/server/public/assets/public-Bgm9WQFZ.js +0 -5
- package/payload/server/public/assets/useVoiceRecorder-BORuG_su.css +0 -1
package/payload/server/server.js
CHANGED
|
@@ -2530,7 +2530,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
|
|
|
2530
2530
|
});
|
|
2531
2531
|
if (!chunk) {
|
|
2532
2532
|
if (i === 1) {
|
|
2533
|
-
await new Promise((
|
|
2533
|
+
await new Promise((resolve29) => setTimeout(resolve29));
|
|
2534
2534
|
maxReadCount = 3;
|
|
2535
2535
|
continue;
|
|
2536
2536
|
}
|
|
@@ -2897,7 +2897,7 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
2897
2897
|
|
|
2898
2898
|
// server/index.ts
|
|
2899
2899
|
import { readFileSync as readFileSync26, existsSync as existsSync26, watchFile } from "fs";
|
|
2900
|
-
import { resolve as
|
|
2900
|
+
import { resolve as resolve28, join as join13, basename as basename6 } from "path";
|
|
2901
2901
|
import { homedir as homedir4 } from "os";
|
|
2902
2902
|
|
|
2903
2903
|
// app/lib/vnc-logger.ts
|
|
@@ -2971,10 +2971,10 @@ var SCRYPT_R = 8;
|
|
|
2971
2971
|
var SCRYPT_P = 1;
|
|
2972
2972
|
var SCRYPT_KEYLEN = 64;
|
|
2973
2973
|
function scryptAsync(password, salt) {
|
|
2974
|
-
return new Promise((
|
|
2974
|
+
return new Promise((resolve29, reject) => {
|
|
2975
2975
|
scrypt(password, salt, SCRYPT_KEYLEN, { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P }, (err, key) => {
|
|
2976
2976
|
if (err) reject(err);
|
|
2977
|
-
else
|
|
2977
|
+
else resolve29(key);
|
|
2978
2978
|
});
|
|
2979
2979
|
});
|
|
2980
2980
|
}
|
|
@@ -5146,7 +5146,7 @@ ${userContent}`;
|
|
|
5146
5146
|
"dontAsk",
|
|
5147
5147
|
prompt
|
|
5148
5148
|
];
|
|
5149
|
-
return new Promise((
|
|
5149
|
+
return new Promise((resolve29) => {
|
|
5150
5150
|
let stdout = "";
|
|
5151
5151
|
let stderr = "";
|
|
5152
5152
|
const spawnFn = _spawnOverride ?? spawn;
|
|
@@ -5164,35 +5164,35 @@ ${userContent}`;
|
|
|
5164
5164
|
const timer = setTimeout(() => {
|
|
5165
5165
|
proc.kill("SIGTERM");
|
|
5166
5166
|
console.error("[persist] autoLabel: haiku subprocess timed out");
|
|
5167
|
-
|
|
5167
|
+
resolve29(null);
|
|
5168
5168
|
}, SESSION_LABEL_TIMEOUT_MS);
|
|
5169
5169
|
proc.on("error", (err) => {
|
|
5170
5170
|
clearTimeout(timer);
|
|
5171
5171
|
console.error(`[persist] autoLabel: subprocess error \u2014 ${err.message}`);
|
|
5172
|
-
|
|
5172
|
+
resolve29(null);
|
|
5173
5173
|
});
|
|
5174
5174
|
proc.on("close", (code) => {
|
|
5175
5175
|
clearTimeout(timer);
|
|
5176
5176
|
if (code !== 0) {
|
|
5177
5177
|
console.error(`[persist] autoLabel: subprocess exited code=${code}${stderr ? ` stderr=${stderr.trim().slice(0, 200)}` : ""}`);
|
|
5178
|
-
|
|
5178
|
+
resolve29(null);
|
|
5179
5179
|
return;
|
|
5180
5180
|
}
|
|
5181
5181
|
const text = stdout.trim();
|
|
5182
5182
|
if (!text) {
|
|
5183
5183
|
console.error("[persist] autoLabel: haiku returned empty response");
|
|
5184
|
-
|
|
5184
|
+
resolve29(null);
|
|
5185
5185
|
return;
|
|
5186
5186
|
}
|
|
5187
5187
|
if (text === "SKIP") {
|
|
5188
5188
|
console.error("[persist] autoLabel: haiku returned SKIP \u2014 messages too vague");
|
|
5189
|
-
|
|
5189
|
+
resolve29(null);
|
|
5190
5190
|
return;
|
|
5191
5191
|
}
|
|
5192
5192
|
const words = text.split(/\s+/).slice(0, SESSION_LABEL_MAX_WORDS);
|
|
5193
5193
|
const label = words.join(" ");
|
|
5194
5194
|
console.error(`[persist] autoLabel: haiku response="${label}"`);
|
|
5195
|
-
|
|
5195
|
+
resolve29(label);
|
|
5196
5196
|
});
|
|
5197
5197
|
});
|
|
5198
5198
|
}
|
|
@@ -7512,12 +7512,30 @@ function consumeStalledSubagents(sessionKey) {
|
|
|
7512
7512
|
delete session.stalledSubagents;
|
|
7513
7513
|
return stalls && stalls.length > 0 ? stalls : void 0;
|
|
7514
7514
|
}
|
|
7515
|
+
function streamLogPathFor(accountId, conversationId) {
|
|
7516
|
+
const logDir = resolve6(ACCOUNTS_DIR, accountId, "logs");
|
|
7517
|
+
const streamLogPath = resolve6(logDir, `claude-agent-stream-${conversationId}.log`);
|
|
7518
|
+
return { logDir, streamLogPath };
|
|
7519
|
+
}
|
|
7520
|
+
function buildSpawnEnv(accountId, accountDir, conversationId) {
|
|
7521
|
+
if (!conversationId) {
|
|
7522
|
+
throw new Error(`buildSpawnEnv: conversationId is required (accountId=${accountId.slice(0, 8)})`);
|
|
7523
|
+
}
|
|
7524
|
+
const { logDir, streamLogPath } = streamLogPathFor(accountId, conversationId);
|
|
7525
|
+
return {
|
|
7526
|
+
...process.env,
|
|
7527
|
+
PLATFORM_ROOT: PLATFORM_ROOT4,
|
|
7528
|
+
ACCOUNT_DIR: accountDir,
|
|
7529
|
+
ACCOUNT_ID: accountId,
|
|
7530
|
+
LOG_DIR: logDir,
|
|
7531
|
+
STREAM_LOG_PATH: streamLogPath
|
|
7532
|
+
};
|
|
7533
|
+
}
|
|
7515
7534
|
function getMcpServers(accountId, conversationId, userId, enabledPlugins) {
|
|
7516
7535
|
if (!conversationId) {
|
|
7517
7536
|
throw new Error(`getMcpServers: conversationId is required (accountId=${accountId.slice(0, 8)})`);
|
|
7518
7537
|
}
|
|
7519
|
-
const LOG_DIR2 =
|
|
7520
|
-
const STREAM_LOG_PATH = resolve6(LOG_DIR2, `claude-agent-stream-${conversationId}.log`);
|
|
7538
|
+
const { logDir: LOG_DIR2, streamLogPath: STREAM_LOG_PATH } = streamLogPathFor(accountId, conversationId);
|
|
7521
7539
|
const baseEnv = { ACCOUNT_ID: accountId, PLATFORM_ROOT: PLATFORM_ROOT4, LOG_DIR: LOG_DIR2, STREAM_LOG_PATH };
|
|
7522
7540
|
const servers = {
|
|
7523
7541
|
"memory": {
|
|
@@ -7846,7 +7864,7 @@ async function fetchMemoryContext(accountId, query, sessionKey, options) {
|
|
|
7846
7864
|
return null;
|
|
7847
7865
|
}
|
|
7848
7866
|
const startMs = Date.now();
|
|
7849
|
-
return new Promise((
|
|
7867
|
+
return new Promise((resolve29) => {
|
|
7850
7868
|
const proc = spawn2(process.execPath, [serverPath], {
|
|
7851
7869
|
env: {
|
|
7852
7870
|
...process.env,
|
|
@@ -7875,7 +7893,7 @@ async function fetchMemoryContext(accountId, query, sessionKey, options) {
|
|
|
7875
7893
|
} else {
|
|
7876
7894
|
console.error(`[fetchMemoryContext] failed: ${reason} (${elapsed}ms)${stderrBuf ? ` stderr: ${stderrBuf.slice(0, 500)}` : ""}`);
|
|
7877
7895
|
}
|
|
7878
|
-
|
|
7896
|
+
resolve29(value);
|
|
7879
7897
|
};
|
|
7880
7898
|
proc.stdout.on("data", (chunk) => {
|
|
7881
7899
|
buffer += chunk.toString();
|
|
@@ -8286,15 +8304,10 @@ async function* runCompactionTurn(accountDir, accountId, systemPrompt, resumeSes
|
|
|
8286
8304
|
const proc = spawn2("claude", args, {
|
|
8287
8305
|
cwd: accountDir,
|
|
8288
8306
|
stdio: ["ignore", "pipe", "pipe"],
|
|
8289
|
-
|
|
8290
|
-
|
|
8291
|
-
|
|
8292
|
-
|
|
8293
|
-
// Task 535: NODE_DEBUG removed. The Claude Code CLI is a bundled Bun
|
|
8294
|
-
// binary and Bun ignores Node's NODE_DEBUG flag, so setting it here was
|
|
8295
|
-
// a no-op that misled future readers. The [subproc-debug-unavailable]
|
|
8296
|
-
// line below records the source-of-silence explicitly.
|
|
8297
|
-
}
|
|
8307
|
+
// Task 556: STREAM_LOG_PATH is inherited by every Bash-tool subprocess
|
|
8308
|
+
// the Claude CLI spawns; opt-in shell scripts tee their cloudflared/etc.
|
|
8309
|
+
// output into the same per-conversation stream log the agent writes to.
|
|
8310
|
+
env: buildSpawnEnv(accountId, accountDir, conversationId)
|
|
8298
8311
|
});
|
|
8299
8312
|
const stderrLog = agentLogStream("claude-agent-compaction-stderr", accountDir, conversationId);
|
|
8300
8313
|
stderrLog.on("error", () => {
|
|
@@ -8305,6 +8318,8 @@ async function* runCompactionTurn(accountDir, accountId, systemPrompt, resumeSes
|
|
|
8305
8318
|
});
|
|
8306
8319
|
teeProcStderrToStreamLog(proc, streamLog);
|
|
8307
8320
|
streamLog.write(`[${isoTs()}] [subproc-debug-unavailable] reason=bundled-bun-binary-ignores-node-debug pid=${proc.pid} cli=claude
|
|
8321
|
+
`);
|
|
8322
|
+
streamLog.write(`[${isoTs()}] [spawn-env] STREAM_LOG_PATH=set pid=${proc.pid} conversationId=${conversationId} site=compaction
|
|
8308
8323
|
`);
|
|
8309
8324
|
streamLog.write(`[${isoTs()}] [compaction-start] resumeSessionId=${resumeSessionId}
|
|
8310
8325
|
`);
|
|
@@ -9176,15 +9191,8 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
|
|
|
9176
9191
|
const proc = spawn2("claude", args, {
|
|
9177
9192
|
cwd: accountDir,
|
|
9178
9193
|
stdio: ["ignore", "pipe", "pipe"],
|
|
9179
|
-
|
|
9180
|
-
|
|
9181
|
-
PLATFORM_ROOT: PLATFORM_ROOT4,
|
|
9182
|
-
ACCOUNT_DIR: accountDir
|
|
9183
|
-
// Task 535: NODE_DEBUG removed. The Claude Code CLI is a bundled Bun
|
|
9184
|
-
// binary and Bun ignores Node's NODE_DEBUG flag, so setting it here was
|
|
9185
|
-
// a no-op that misled future readers. The [subproc-debug-unavailable]
|
|
9186
|
-
// line below records the source-of-silence explicitly.
|
|
9187
|
-
}
|
|
9194
|
+
// Task 556: STREAM_LOG_PATH inherited by Bash-tool subprocesses.
|
|
9195
|
+
env: buildSpawnEnv(accountId, accountDir, spawnConvId)
|
|
9188
9196
|
});
|
|
9189
9197
|
const stderrLog = agentLogStream("claude-agent-stderr", accountDir, spawnConvId);
|
|
9190
9198
|
stderrLog.on("error", () => {
|
|
@@ -9195,6 +9203,8 @@ async function* invokeAdminAgent(message, systemPrompt, accountDir, accountId, a
|
|
|
9195
9203
|
});
|
|
9196
9204
|
teeProcStderrToStreamLog(proc, streamLog);
|
|
9197
9205
|
streamLog.write(`[${isoTs()}] [subproc-debug-unavailable] reason=bundled-bun-binary-ignores-node-debug pid=${proc.pid} cli=claude
|
|
9206
|
+
`);
|
|
9207
|
+
streamLog.write(`[${isoTs()}] [spawn-env] STREAM_LOG_PATH=set pid=${proc.pid} conversationId=${spawnConvId} site=admin
|
|
9198
9208
|
`);
|
|
9199
9209
|
if (sessionKey) {
|
|
9200
9210
|
const prev = activeProcesses.get(sessionKey);
|
|
@@ -9520,15 +9530,8 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
|
|
|
9520
9530
|
const proc = spawn2("claude", args, {
|
|
9521
9531
|
cwd: accountDir,
|
|
9522
9532
|
stdio: ["ignore", "pipe", "pipe"],
|
|
9523
|
-
|
|
9524
|
-
|
|
9525
|
-
PLATFORM_ROOT: PLATFORM_ROOT4,
|
|
9526
|
-
ACCOUNT_DIR: accountDir
|
|
9527
|
-
// Task 535: NODE_DEBUG removed. The Claude Code CLI is a bundled Bun
|
|
9528
|
-
// binary and Bun ignores Node's NODE_DEBUG flag, so setting it here was
|
|
9529
|
-
// a no-op that misled future readers. The [subproc-debug-unavailable]
|
|
9530
|
-
// line below records the source-of-silence explicitly.
|
|
9531
|
-
}
|
|
9533
|
+
// Task 556: STREAM_LOG_PATH inherited by Bash-tool subprocesses.
|
|
9534
|
+
env: buildSpawnEnv(accountId, accountDir, managedConvId)
|
|
9532
9535
|
});
|
|
9533
9536
|
const stderrLog = agentLogStream("claude-agent-stderr", accountDir, managedConvId);
|
|
9534
9537
|
stderrLog.on("error", () => {
|
|
@@ -9536,6 +9539,8 @@ async function* invokeManagedAdminAgent(message, systemPrompt, accountDir, accou
|
|
|
9536
9539
|
proc.stderr?.pipe(stderrLog);
|
|
9537
9540
|
teeProcStderrToStreamLog(proc, streamLog);
|
|
9538
9541
|
streamLog.write(`[${isoTs()}] [subproc-debug-unavailable] reason=bundled-bun-binary-ignores-node-debug pid=${proc.pid} cli=claude
|
|
9542
|
+
`);
|
|
9543
|
+
streamLog.write(`[${isoTs()}] [spawn-env] STREAM_LOG_PATH=set pid=${proc.pid} conversationId=${managedConvId} site=managed
|
|
9539
9544
|
`);
|
|
9540
9545
|
if (sessionKey) {
|
|
9541
9546
|
const prev = activeProcesses.get(sessionKey);
|
|
@@ -26125,7 +26130,7 @@ var credsSaveQueue = Promise.resolve();
|
|
|
26125
26130
|
async function drainCredsSaveQueue(timeoutMs = 5e3) {
|
|
26126
26131
|
console.error(`${TAG4} draining credential save queue\u2026`);
|
|
26127
26132
|
const timer = new Promise(
|
|
26128
|
-
(
|
|
26133
|
+
(resolve29) => setTimeout(() => resolve29("timeout"), timeoutMs)
|
|
26129
26134
|
);
|
|
26130
26135
|
const result = await Promise.race([
|
|
26131
26136
|
credsSaveQueue.then(() => "drained"),
|
|
@@ -26253,11 +26258,11 @@ async function createWaSocket(opts) {
|
|
|
26253
26258
|
return sock;
|
|
26254
26259
|
}
|
|
26255
26260
|
async function waitForConnection(sock) {
|
|
26256
|
-
return new Promise((
|
|
26261
|
+
return new Promise((resolve29, reject) => {
|
|
26257
26262
|
const handler = (update) => {
|
|
26258
26263
|
if (update.connection === "open") {
|
|
26259
26264
|
sock.ev.off("connection.update", handler);
|
|
26260
|
-
|
|
26265
|
+
resolve29();
|
|
26261
26266
|
}
|
|
26262
26267
|
if (update.connection === "close") {
|
|
26263
26268
|
sock.ev.off("connection.update", handler);
|
|
@@ -26371,14 +26376,14 @@ ${inspected}`;
|
|
|
26371
26376
|
return inspect2(err, INSPECT_OPTS2);
|
|
26372
26377
|
}
|
|
26373
26378
|
function withTimeout(label, promise2, timeoutMs) {
|
|
26374
|
-
return new Promise((
|
|
26379
|
+
return new Promise((resolve29, reject) => {
|
|
26375
26380
|
const timer = setTimeout(() => {
|
|
26376
26381
|
reject(new Error(`${label} timed out after ${timeoutMs}ms`));
|
|
26377
26382
|
}, timeoutMs);
|
|
26378
26383
|
promise2.then(
|
|
26379
26384
|
(value) => {
|
|
26380
26385
|
clearTimeout(timer);
|
|
26381
|
-
|
|
26386
|
+
resolve29(value);
|
|
26382
26387
|
},
|
|
26383
26388
|
(err) => {
|
|
26384
26389
|
clearTimeout(timer);
|
|
@@ -27578,11 +27583,11 @@ async function connectWithReconnect(conn) {
|
|
|
27578
27583
|
console.error(
|
|
27579
27584
|
`${TAG12} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${decision.nextAttempts}/${maxAttempts})`
|
|
27580
27585
|
);
|
|
27581
|
-
await new Promise((
|
|
27582
|
-
const timer = setTimeout(
|
|
27586
|
+
await new Promise((resolve29) => {
|
|
27587
|
+
const timer = setTimeout(resolve29, delay);
|
|
27583
27588
|
conn.abortController.signal.addEventListener("abort", () => {
|
|
27584
27589
|
clearTimeout(timer);
|
|
27585
|
-
|
|
27590
|
+
resolve29();
|
|
27586
27591
|
}, { once: true });
|
|
27587
27592
|
});
|
|
27588
27593
|
}
|
|
@@ -27590,16 +27595,16 @@ async function connectWithReconnect(conn) {
|
|
|
27590
27595
|
}
|
|
27591
27596
|
}
|
|
27592
27597
|
function waitForDisconnectEvent(conn) {
|
|
27593
|
-
return new Promise((
|
|
27598
|
+
return new Promise((resolve29) => {
|
|
27594
27599
|
if (!conn.sock) {
|
|
27595
|
-
|
|
27600
|
+
resolve29();
|
|
27596
27601
|
return;
|
|
27597
27602
|
}
|
|
27598
27603
|
const sock = conn.sock;
|
|
27599
27604
|
const handler = (update) => {
|
|
27600
27605
|
if (update.connection === "close") {
|
|
27601
27606
|
sock.ev.off("connection.update", handler);
|
|
27602
|
-
|
|
27607
|
+
resolve29();
|
|
27603
27608
|
}
|
|
27604
27609
|
};
|
|
27605
27610
|
sock.ev.on("connection.update", handler);
|
|
@@ -27809,8 +27814,8 @@ async function handleInboundMessage(conn, msg) {
|
|
|
27809
27814
|
const conversationKey = isGroup ? remoteJid : senderPhone;
|
|
27810
27815
|
const debounceKey = `${conn.accountId}:${conversationKey}:${senderPhone}`;
|
|
27811
27816
|
let resolvePending;
|
|
27812
|
-
const sttPending = new Promise((
|
|
27813
|
-
resolvePending =
|
|
27817
|
+
const sttPending = new Promise((resolve29) => {
|
|
27818
|
+
resolvePending = resolve29;
|
|
27814
27819
|
});
|
|
27815
27820
|
if (conn.debouncer) conn.debouncer.registerPending(debounceKey, sttPending);
|
|
27816
27821
|
try {
|
|
@@ -27917,20 +27922,20 @@ async function probeApiKey() {
|
|
|
27917
27922
|
return result.status;
|
|
27918
27923
|
}
|
|
27919
27924
|
function checkPort(port2, timeoutMs = 500) {
|
|
27920
|
-
return new Promise((
|
|
27925
|
+
return new Promise((resolve29) => {
|
|
27921
27926
|
const socket = createConnection3(port2, "127.0.0.1");
|
|
27922
27927
|
socket.setTimeout(timeoutMs);
|
|
27923
27928
|
socket.once("connect", () => {
|
|
27924
27929
|
socket.destroy();
|
|
27925
|
-
|
|
27930
|
+
resolve29(true);
|
|
27926
27931
|
});
|
|
27927
27932
|
socket.once("error", () => {
|
|
27928
27933
|
socket.destroy();
|
|
27929
|
-
|
|
27934
|
+
resolve29(false);
|
|
27930
27935
|
});
|
|
27931
27936
|
socket.once("timeout", () => {
|
|
27932
27937
|
socket.destroy();
|
|
27933
|
-
|
|
27938
|
+
resolve29(false);
|
|
27934
27939
|
});
|
|
27935
27940
|
});
|
|
27936
27941
|
}
|
|
@@ -30121,8 +30126,8 @@ async function startLogin(opts) {
|
|
|
30121
30126
|
resetActiveLogin(accountId);
|
|
30122
30127
|
let resolveQr = null;
|
|
30123
30128
|
let rejectQr = null;
|
|
30124
|
-
const qrPromise = new Promise((
|
|
30125
|
-
resolveQr =
|
|
30129
|
+
const qrPromise = new Promise((resolve29, reject) => {
|
|
30130
|
+
resolveQr = resolve29;
|
|
30126
30131
|
rejectQr = reject;
|
|
30127
30132
|
});
|
|
30128
30133
|
const qrTimer = setTimeout(
|
|
@@ -31199,6 +31204,106 @@ async function createAdminSession(accountId, thinkingView, userId, userName) {
|
|
|
31199
31204
|
});
|
|
31200
31205
|
}
|
|
31201
31206
|
|
|
31207
|
+
// app/api/admin/chat/route.ts
|
|
31208
|
+
import { resolve as resolve19 } from "path";
|
|
31209
|
+
|
|
31210
|
+
// app/lib/script-stream-tailer.ts
|
|
31211
|
+
import { createReadStream as createReadStream2, statSync as statSync7 } from "fs";
|
|
31212
|
+
import { StringDecoder as StringDecoder2 } from "string_decoder";
|
|
31213
|
+
var SCRIPT_STREAM_RE = /^\[([^\]]+)\] \[(setup-tunnel|reset-tunnel)((?::[^\]]+)?)\] (.*)$/;
|
|
31214
|
+
function parseLine(line) {
|
|
31215
|
+
const m = line.match(SCRIPT_STREAM_RE);
|
|
31216
|
+
if (!m) return void 0;
|
|
31217
|
+
const [, timestamp, scope, tagSuffix, rest] = m;
|
|
31218
|
+
return {
|
|
31219
|
+
type: "script_stream",
|
|
31220
|
+
source: scope + (tagSuffix ?? ""),
|
|
31221
|
+
timestamp,
|
|
31222
|
+
line: rest
|
|
31223
|
+
};
|
|
31224
|
+
}
|
|
31225
|
+
function startScriptStreamTailer(opts) {
|
|
31226
|
+
const { path: path2, onEvent, onError } = opts;
|
|
31227
|
+
let offset;
|
|
31228
|
+
try {
|
|
31229
|
+
offset = statSync7(path2).size;
|
|
31230
|
+
} catch {
|
|
31231
|
+
offset = 0;
|
|
31232
|
+
}
|
|
31233
|
+
const utf8 = new StringDecoder2("utf8");
|
|
31234
|
+
let buffer = "";
|
|
31235
|
+
let stopped = false;
|
|
31236
|
+
let pendingRead = false;
|
|
31237
|
+
let timer;
|
|
31238
|
+
const processLine = (line) => {
|
|
31239
|
+
const event = parseLine(line);
|
|
31240
|
+
if (event) onEvent(event);
|
|
31241
|
+
};
|
|
31242
|
+
const readDelta = async () => {
|
|
31243
|
+
if (pendingRead) return;
|
|
31244
|
+
pendingRead = true;
|
|
31245
|
+
try {
|
|
31246
|
+
let size;
|
|
31247
|
+
try {
|
|
31248
|
+
size = statSync7(path2).size;
|
|
31249
|
+
} catch {
|
|
31250
|
+
return;
|
|
31251
|
+
}
|
|
31252
|
+
if (size === offset) return;
|
|
31253
|
+
if (size < offset) {
|
|
31254
|
+
offset = 0;
|
|
31255
|
+
buffer = "";
|
|
31256
|
+
}
|
|
31257
|
+
await new Promise((res, rej) => {
|
|
31258
|
+
const stream = createReadStream2(path2, { start: offset, end: size - 1 });
|
|
31259
|
+
stream.on("data", (chunk) => {
|
|
31260
|
+
buffer += typeof chunk === "string" ? chunk : utf8.write(chunk);
|
|
31261
|
+
let idx;
|
|
31262
|
+
while ((idx = buffer.indexOf("\n")) !== -1) {
|
|
31263
|
+
const line = buffer.slice(0, idx);
|
|
31264
|
+
buffer = buffer.slice(idx + 1);
|
|
31265
|
+
if (line.length > 0) processLine(line);
|
|
31266
|
+
}
|
|
31267
|
+
});
|
|
31268
|
+
stream.on("end", () => {
|
|
31269
|
+
offset = size;
|
|
31270
|
+
res();
|
|
31271
|
+
});
|
|
31272
|
+
stream.on("error", rej);
|
|
31273
|
+
});
|
|
31274
|
+
} catch (err) {
|
|
31275
|
+
if (onError) onError(err instanceof Error ? err : new Error(String(err)));
|
|
31276
|
+
} finally {
|
|
31277
|
+
pendingRead = false;
|
|
31278
|
+
}
|
|
31279
|
+
};
|
|
31280
|
+
const tick = () => {
|
|
31281
|
+
if (stopped) return;
|
|
31282
|
+
readDelta().catch(() => {
|
|
31283
|
+
}).finally(() => {
|
|
31284
|
+
if (!stopped) timer = setTimeout(tick, 200);
|
|
31285
|
+
});
|
|
31286
|
+
};
|
|
31287
|
+
timer = setTimeout(tick, 0);
|
|
31288
|
+
return {
|
|
31289
|
+
async stop() {
|
|
31290
|
+
if (stopped) return;
|
|
31291
|
+
stopped = true;
|
|
31292
|
+
if (timer) clearTimeout(timer);
|
|
31293
|
+
while (pendingRead) {
|
|
31294
|
+
await new Promise((r) => setImmediate(r));
|
|
31295
|
+
}
|
|
31296
|
+
await readDelta();
|
|
31297
|
+
buffer += utf8.end();
|
|
31298
|
+
if (buffer.length > 0) {
|
|
31299
|
+
const event = parseLine(buffer);
|
|
31300
|
+
if (event) onEvent(event);
|
|
31301
|
+
buffer = "";
|
|
31302
|
+
}
|
|
31303
|
+
}
|
|
31304
|
+
};
|
|
31305
|
+
}
|
|
31306
|
+
|
|
31202
31307
|
// app/api/admin/chat/route.ts
|
|
31203
31308
|
function isComponentDone(parsed) {
|
|
31204
31309
|
return typeof parsed === "object" && parsed !== null && parsed._componentDone === true && typeof parsed.component === "string" && typeof parsed.payload === "string";
|
|
@@ -31390,8 +31495,32 @@ async function POST21(req) {
|
|
|
31390
31495
|
const sseConvId = getConversationIdForSession(session_key);
|
|
31391
31496
|
const sseLog = sseConvId ? agentLogStream("sse-events", account.accountDir, sseConvId) : preConversationLogStream("sse-events", account.accountDir);
|
|
31392
31497
|
const sk = sseConvId?.slice(0, 8) ?? session_key.slice(0, 8);
|
|
31498
|
+
let tailer = null;
|
|
31393
31499
|
const readable = new ReadableStream({
|
|
31394
31500
|
async start(controller) {
|
|
31501
|
+
let controllerOpen = true;
|
|
31502
|
+
if (sseConvId) {
|
|
31503
|
+
const streamLogPath = resolve19(account.accountDir, "logs", `claude-agent-stream-${sseConvId}.log`);
|
|
31504
|
+
tailer = startScriptStreamTailer({
|
|
31505
|
+
path: streamLogPath,
|
|
31506
|
+
onEvent: (event) => {
|
|
31507
|
+
if (!controllerOpen) return;
|
|
31508
|
+
const ts = (/* @__PURE__ */ new Date()).toISOString().slice(11, 23);
|
|
31509
|
+
sseLog.write(`[${ts}] [${sk}] admin: ${JSON.stringify(event)}
|
|
31510
|
+
`);
|
|
31511
|
+
try {
|
|
31512
|
+
controller.enqueue(encoder.encode(`data: ${JSON.stringify(event)}
|
|
31513
|
+
|
|
31514
|
+
`));
|
|
31515
|
+
} catch {
|
|
31516
|
+
controllerOpen = false;
|
|
31517
|
+
}
|
|
31518
|
+
},
|
|
31519
|
+
onError: (err) => {
|
|
31520
|
+
console.error(`[script-stream-tailer] ${streamLogPath}: ${err.message}`);
|
|
31521
|
+
}
|
|
31522
|
+
});
|
|
31523
|
+
}
|
|
31395
31524
|
try {
|
|
31396
31525
|
for await (const event of invokeAgent(
|
|
31397
31526
|
{ type: "admin", skipTopicCheck },
|
|
@@ -31439,6 +31568,13 @@ async function POST21(req) {
|
|
|
31439
31568
|
}
|
|
31440
31569
|
}
|
|
31441
31570
|
} finally {
|
|
31571
|
+
if (tailer) {
|
|
31572
|
+
try {
|
|
31573
|
+
await tailer.stop();
|
|
31574
|
+
} catch {
|
|
31575
|
+
}
|
|
31576
|
+
}
|
|
31577
|
+
controllerOpen = false;
|
|
31442
31578
|
sseLog.end();
|
|
31443
31579
|
try {
|
|
31444
31580
|
controller.close();
|
|
@@ -31498,8 +31634,8 @@ async function POST22(req) {
|
|
|
31498
31634
|
}
|
|
31499
31635
|
|
|
31500
31636
|
// app/api/admin/logs/route.ts
|
|
31501
|
-
import { existsSync as existsSync19, readdirSync as readdirSync5, readFileSync as readFileSync20, statSync as
|
|
31502
|
-
import { resolve as
|
|
31637
|
+
import { existsSync as existsSync19, readdirSync as readdirSync5, readFileSync as readFileSync20, statSync as statSync8 } from "fs";
|
|
31638
|
+
import { resolve as resolve20, basename as basename5 } from "path";
|
|
31503
31639
|
var TAIL_BYTES = 8192;
|
|
31504
31640
|
async function GET9(request) {
|
|
31505
31641
|
const { searchParams } = new URL(request.url);
|
|
@@ -31508,13 +31644,13 @@ async function GET9(request) {
|
|
|
31508
31644
|
const conversationIdParam = searchParams.get("conversationId");
|
|
31509
31645
|
const download = searchParams.get("download") === "1";
|
|
31510
31646
|
const account = resolveAccount();
|
|
31511
|
-
const accountLogDir2 = account ?
|
|
31647
|
+
const accountLogDir2 = account ? resolve20(account.accountDir, "logs") : null;
|
|
31512
31648
|
if (fileParam) {
|
|
31513
31649
|
const safe = basename5(fileParam);
|
|
31514
31650
|
const searched = [];
|
|
31515
31651
|
for (const dir of [accountLogDir2, LOG_DIR]) {
|
|
31516
31652
|
if (!dir) continue;
|
|
31517
|
-
const filePath =
|
|
31653
|
+
const filePath = resolve20(dir, safe);
|
|
31518
31654
|
searched.push(filePath);
|
|
31519
31655
|
try {
|
|
31520
31656
|
const content = readFileSync20(filePath, "utf-8");
|
|
@@ -31556,7 +31692,7 @@ async function GET9(request) {
|
|
|
31556
31692
|
const searched = [];
|
|
31557
31693
|
for (const dir of [accountLogDir2, LOG_DIR]) {
|
|
31558
31694
|
if (!dir) continue;
|
|
31559
|
-
const filePath =
|
|
31695
|
+
const filePath = resolve20(dir, fileName);
|
|
31560
31696
|
searched.push(filePath);
|
|
31561
31697
|
try {
|
|
31562
31698
|
const content = readFileSync20(filePath, "utf-8");
|
|
@@ -31583,10 +31719,10 @@ async function GET9(request) {
|
|
|
31583
31719
|
console.warn(`[admin/logs] readdir-fail dir=${dir} reason=${reason}`);
|
|
31584
31720
|
continue;
|
|
31585
31721
|
}
|
|
31586
|
-
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime:
|
|
31722
|
+
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync8(resolve20(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
|
|
31587
31723
|
seen.add(name);
|
|
31588
31724
|
try {
|
|
31589
|
-
const content = readFileSync20(
|
|
31725
|
+
const content = readFileSync20(resolve20(dir, name));
|
|
31590
31726
|
const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
|
|
31591
31727
|
logs[name] = tail.trim() || "(empty)";
|
|
31592
31728
|
} catch (err) {
|
|
@@ -31624,7 +31760,7 @@ async function GET10() {
|
|
|
31624
31760
|
// app/api/admin/attachment/[attachmentId]/route.ts
|
|
31625
31761
|
import { readFile as readFile3, readdir } from "fs/promises";
|
|
31626
31762
|
import { existsSync as existsSync20 } from "fs";
|
|
31627
|
-
import { resolve as
|
|
31763
|
+
import { resolve as resolve21 } from "path";
|
|
31628
31764
|
async function GET11(req, attachmentId) {
|
|
31629
31765
|
const sessionKey = new URL(req.url).searchParams.get("session_key") ?? "";
|
|
31630
31766
|
if (!validateSession(sessionKey, "admin")) {
|
|
@@ -31637,11 +31773,11 @@ async function GET11(req, attachmentId) {
|
|
|
31637
31773
|
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(attachmentId)) {
|
|
31638
31774
|
return new Response("Not found", { status: 404 });
|
|
31639
31775
|
}
|
|
31640
|
-
const dir =
|
|
31776
|
+
const dir = resolve21(ATTACHMENTS_ROOT, accountId, attachmentId);
|
|
31641
31777
|
if (!existsSync20(dir)) {
|
|
31642
31778
|
return new Response("Not found", { status: 404 });
|
|
31643
31779
|
}
|
|
31644
|
-
const metaPath =
|
|
31780
|
+
const metaPath = resolve21(dir, `${attachmentId}.meta.json`);
|
|
31645
31781
|
if (!existsSync20(metaPath)) {
|
|
31646
31782
|
return new Response("Not found", { status: 404 });
|
|
31647
31783
|
}
|
|
@@ -31656,7 +31792,7 @@ async function GET11(req, attachmentId) {
|
|
|
31656
31792
|
if (!dataFile) {
|
|
31657
31793
|
return new Response("Not found", { status: 404 });
|
|
31658
31794
|
}
|
|
31659
|
-
const filePath =
|
|
31795
|
+
const filePath = resolve21(dir, dataFile);
|
|
31660
31796
|
const buffer = await readFile3(filePath);
|
|
31661
31797
|
return new Response(buffer, {
|
|
31662
31798
|
headers: {
|
|
@@ -31669,7 +31805,7 @@ async function GET11(req, attachmentId) {
|
|
|
31669
31805
|
|
|
31670
31806
|
// app/api/admin/account/route.ts
|
|
31671
31807
|
import { readFileSync as readFileSync21, writeFileSync as writeFileSync15 } from "fs";
|
|
31672
|
-
import { resolve as
|
|
31808
|
+
import { resolve as resolve22 } from "path";
|
|
31673
31809
|
var VALID_CONTEXT_MODES = ["managed", "claude-code"];
|
|
31674
31810
|
async function PATCH(req) {
|
|
31675
31811
|
let body;
|
|
@@ -31692,7 +31828,7 @@ async function PATCH(req) {
|
|
|
31692
31828
|
if (!account) {
|
|
31693
31829
|
return Response.json({ error: "No account configured" }, { status: 500 });
|
|
31694
31830
|
}
|
|
31695
|
-
const configPath2 =
|
|
31831
|
+
const configPath2 = resolve22(account.accountDir, "account.json");
|
|
31696
31832
|
try {
|
|
31697
31833
|
const raw2 = readFileSync21(configPath2, "utf-8");
|
|
31698
31834
|
const config2 = JSON.parse(raw2);
|
|
@@ -31707,14 +31843,14 @@ async function PATCH(req) {
|
|
|
31707
31843
|
}
|
|
31708
31844
|
|
|
31709
31845
|
// app/api/admin/agents/route.ts
|
|
31710
|
-
import { resolve as
|
|
31846
|
+
import { resolve as resolve23 } from "path";
|
|
31711
31847
|
import { readdirSync as readdirSync6, readFileSync as readFileSync22, existsSync as existsSync21 } from "fs";
|
|
31712
31848
|
async function GET12() {
|
|
31713
31849
|
const account = resolveAccount();
|
|
31714
31850
|
if (!account) {
|
|
31715
31851
|
return Response.json({ agents: [] });
|
|
31716
31852
|
}
|
|
31717
|
-
const agentsDir =
|
|
31853
|
+
const agentsDir = resolve23(account.accountDir, "agents");
|
|
31718
31854
|
if (!existsSync21(agentsDir)) {
|
|
31719
31855
|
return Response.json({ agents: [] });
|
|
31720
31856
|
}
|
|
@@ -31724,7 +31860,7 @@ async function GET12() {
|
|
|
31724
31860
|
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
31725
31861
|
if (!entry.isDirectory()) continue;
|
|
31726
31862
|
if (entry.name === "admin") continue;
|
|
31727
|
-
const configPath2 =
|
|
31863
|
+
const configPath2 = resolve23(agentsDir, entry.name, "config.json");
|
|
31728
31864
|
if (!existsSync21(configPath2)) continue;
|
|
31729
31865
|
try {
|
|
31730
31866
|
const config2 = JSON.parse(readFileSync22(configPath2, "utf-8"));
|
|
@@ -31745,7 +31881,7 @@ async function GET12() {
|
|
|
31745
31881
|
}
|
|
31746
31882
|
|
|
31747
31883
|
// app/api/admin/agents/[slug]/route.ts
|
|
31748
|
-
import { resolve as
|
|
31884
|
+
import { resolve as resolve24 } from "path";
|
|
31749
31885
|
import { existsSync as existsSync22, rmSync as rmSync2 } from "fs";
|
|
31750
31886
|
async function DELETE2(_req, { params }) {
|
|
31751
31887
|
const { slug } = await params;
|
|
@@ -31759,7 +31895,7 @@ async function DELETE2(_req, { params }) {
|
|
|
31759
31895
|
if (slug.includes("/") || slug.includes("..") || slug.includes("\\")) {
|
|
31760
31896
|
return Response.json({ error: "Invalid agent slug" }, { status: 400 });
|
|
31761
31897
|
}
|
|
31762
|
-
const agentDir =
|
|
31898
|
+
const agentDir = resolve24(account.accountDir, "agents", slug);
|
|
31763
31899
|
if (!existsSync22(agentDir)) {
|
|
31764
31900
|
return Response.json({ error: "Agent not found" }, { status: 404 });
|
|
31765
31901
|
}
|
|
@@ -31775,8 +31911,8 @@ async function DELETE2(_req, { params }) {
|
|
|
31775
31911
|
|
|
31776
31912
|
// app/api/admin/version/route.ts
|
|
31777
31913
|
import { readFileSync as readFileSync23, existsSync as existsSync23 } from "fs";
|
|
31778
|
-
import { resolve as
|
|
31779
|
-
var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT ??
|
|
31914
|
+
import { resolve as resolve25, join as join10 } from "path";
|
|
31915
|
+
var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT ?? resolve25(process.cwd(), "..");
|
|
31780
31916
|
var brandHostname = "maxy";
|
|
31781
31917
|
var brandNpmPackage = "@rubytech/create-maxy";
|
|
31782
31918
|
var brandJsonPath = join10(PLATFORM_ROOT9, "config", "brand.json");
|
|
@@ -31788,7 +31924,7 @@ if (existsSync23(brandJsonPath)) {
|
|
|
31788
31924
|
} catch {
|
|
31789
31925
|
}
|
|
31790
31926
|
}
|
|
31791
|
-
var VERSION_FILE =
|
|
31927
|
+
var VERSION_FILE = resolve25(PLATFORM_ROOT9, `config/.${brandHostname}-version`);
|
|
31792
31928
|
var NPM_PACKAGE = brandNpmPackage;
|
|
31793
31929
|
var REGISTRY_URL = `https://registry.npmjs.org/${NPM_PACKAGE}/latest`;
|
|
31794
31930
|
var FETCH_TIMEOUT_MS = 5e3;
|
|
@@ -31845,9 +31981,9 @@ async function GET13() {
|
|
|
31845
31981
|
|
|
31846
31982
|
// app/api/admin/version/upgrade/route.ts
|
|
31847
31983
|
import { spawn as spawn4 } from "child_process";
|
|
31848
|
-
import { existsSync as existsSync24, statSync as
|
|
31849
|
-
import { resolve as
|
|
31850
|
-
var PLATFORM_ROOT10 = process.env.MAXY_PLATFORM_ROOT ??
|
|
31984
|
+
import { existsSync as existsSync24, statSync as statSync9, writeFileSync as writeFileSync16, readFileSync as readFileSync24, openSync as openSync4, closeSync as closeSync4 } from "fs";
|
|
31985
|
+
import { resolve as resolve26, join as join11 } from "path";
|
|
31986
|
+
var PLATFORM_ROOT10 = process.env.MAXY_PLATFORM_ROOT ?? resolve26(process.cwd(), "..");
|
|
31851
31987
|
var upgradePkg = "@rubytech/create-maxy";
|
|
31852
31988
|
var upgradeHostname = "maxy";
|
|
31853
31989
|
var brandPath = join11(PLATFORM_ROOT10, "config", "brand.json");
|
|
@@ -31865,7 +32001,7 @@ var LOCK_MAX_AGE_MS = 20 * 60 * 1e3;
|
|
|
31865
32001
|
function isLockFresh() {
|
|
31866
32002
|
if (!existsSync24(LOCK_FILE)) return false;
|
|
31867
32003
|
try {
|
|
31868
|
-
const stat4 =
|
|
32004
|
+
const stat4 = statSync9(LOCK_FILE);
|
|
31869
32005
|
return Date.now() - stat4.mtimeMs < LOCK_MAX_AGE_MS;
|
|
31870
32006
|
} catch {
|
|
31871
32007
|
return false;
|
|
@@ -31907,7 +32043,7 @@ async function POST23(req) {
|
|
|
31907
32043
|
detached: true,
|
|
31908
32044
|
stdio: ["ignore", logFd, logFd],
|
|
31909
32045
|
env: { ...process.env, npm_config_yes: "true" },
|
|
31910
|
-
cwd:
|
|
32046
|
+
cwd: resolve26(process.cwd(), "..")
|
|
31911
32047
|
});
|
|
31912
32048
|
child.unref();
|
|
31913
32049
|
closeSync4(logFd);
|
|
@@ -31924,8 +32060,8 @@ async function POST23(req) {
|
|
|
31924
32060
|
|
|
31925
32061
|
// app/api/admin/version/upgrade/progress/route.ts
|
|
31926
32062
|
import { existsSync as existsSync25, readFileSync as readFileSync25 } from "fs";
|
|
31927
|
-
import { resolve as
|
|
31928
|
-
var PLATFORM_ROOT11 = process.env.MAXY_PLATFORM_ROOT ??
|
|
32063
|
+
import { resolve as resolve27, join as join12 } from "path";
|
|
32064
|
+
var PLATFORM_ROOT11 = process.env.MAXY_PLATFORM_ROOT ?? resolve27(process.cwd(), "..");
|
|
31929
32065
|
var upgradeHostname2 = "maxy";
|
|
31930
32066
|
var brandPath2 = join12(PLATFORM_ROOT11, "config", "brand.json");
|
|
31931
32067
|
if (existsSync25(brandPath2)) {
|
|
@@ -32851,8 +32987,8 @@ app.get("/agent-assets/:slug/:filename", (c) => {
|
|
|
32851
32987
|
console.error(`[agent-assets] no-account slug=${slug} file=${filename}`);
|
|
32852
32988
|
return c.text("Not found", 404);
|
|
32853
32989
|
}
|
|
32854
|
-
const filePath =
|
|
32855
|
-
const expectedDir =
|
|
32990
|
+
const filePath = resolve28(account.accountDir, "agents", slug, "assets", filename);
|
|
32991
|
+
const expectedDir = resolve28(account.accountDir, "agents", slug, "assets");
|
|
32856
32992
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
32857
32993
|
console.error(`[agent-assets] path-traversal-rejected slug=${slug} file=${filename}`);
|
|
32858
32994
|
return c.text("Forbidden", 403);
|
|
@@ -32881,8 +33017,8 @@ app.get("/generated/:filename", (c) => {
|
|
|
32881
33017
|
console.error(`[generated] serve file=${filename} status=404`);
|
|
32882
33018
|
return c.text("Not found", 404);
|
|
32883
33019
|
}
|
|
32884
|
-
const filePath =
|
|
32885
|
-
const expectedDir =
|
|
33020
|
+
const filePath = resolve28(account.accountDir, "generated", filename);
|
|
33021
|
+
const expectedDir = resolve28(account.accountDir, "generated");
|
|
32886
33022
|
if (!filePath.startsWith(expectedDir + "/")) {
|
|
32887
33023
|
console.error(`[generated] serve file=${filename} status=403`);
|
|
32888
33024
|
return c.text("Forbidden", 403);
|
|
@@ -32922,7 +33058,7 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
|
|
|
32922
33058
|
function cachedHtml(file2) {
|
|
32923
33059
|
let html = htmlCache.get(file2);
|
|
32924
33060
|
if (!html) {
|
|
32925
|
-
html = readFileSync26(
|
|
33061
|
+
html = readFileSync26(resolve28(process.cwd(), "public", file2), "utf-8");
|
|
32926
33062
|
html = html.replace("<title>Maxy</title>", `<title>${escapeHtml2(BRAND.productName)}</title>`);
|
|
32927
33063
|
html = html.replace('href="/favicon.ico"', `href="${escapeHtml2(brandFaviconPath)}"`);
|
|
32928
33064
|
html = html.replace("</head>", `${brandScript}
|
|
@@ -33025,7 +33161,7 @@ app.use("/vnc-popout.html", logViewerFetch);
|
|
|
33025
33161
|
app.get("/vnc-popout.html", (c) => {
|
|
33026
33162
|
let html = htmlCache.get("vnc-popout.html");
|
|
33027
33163
|
if (!html) {
|
|
33028
|
-
html = readFileSync26(
|
|
33164
|
+
html = readFileSync26(resolve28(process.cwd(), "public", "vnc-popout.html"), "utf-8");
|
|
33029
33165
|
const name = escapeHtml2(BRAND.productName);
|
|
33030
33166
|
html = html.replace("<title>Browser \u2014 Maxy</title>", `<title>${name}</title>`);
|
|
33031
33167
|
html = html.replace("</head>", ` ${brandScript}
|
|
@@ -33106,7 +33242,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
33106
33242
|
}
|
|
33107
33243
|
init({
|
|
33108
33244
|
configDir: configDirForWhatsApp,
|
|
33109
|
-
platformRoot:
|
|
33245
|
+
platformRoot: resolve28(process.env.MAXY_PLATFORM_ROOT ?? join13(__dirname, "..")),
|
|
33110
33246
|
accountConfig: bootAccountConfig,
|
|
33111
33247
|
onMessage: async (msg) => {
|
|
33112
33248
|
try {
|