@rubytech/create-maxy 1.0.466 → 1.0.468
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/admin/hooks/playwright-file-guard.sh +30 -0
- package/payload/platform/plugins/admin/mcp/dist/index.js +4 -1
- package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js +9 -2
- package/payload/platform/plugins/whatsapp/mcp/dist/index.js.map +1 -1
- package/payload/platform/plugins/whatsapp/skills/manage-whatsapp-config/SKILL.md +10 -0
- package/payload/platform/scripts/seed-neo4j.sh +10 -0
- package/payload/platform/templates/specialists/agents/browser-specialist.md +3 -1
- package/payload/server/public/assets/ChatInput-BZnIVDdt.css +1 -0
- package/payload/server/public/assets/{admin-2dLystkf.js → admin-BWFKvjFU.js} +2 -2
- package/payload/server/public/assets/{public-CXugp78k.js → public-Dqvygu4a.js} +1 -1
- package/payload/server/public/index.html +3 -3
- package/payload/server/public/public.html +3 -3
- package/payload/server/server.js +129 -103
- package/payload/server/public/assets/ChatInput-hIijimc7.css +0 -1
- /package/payload/server/public/assets/{ChatInput-vMpN_V6Z.js → ChatInput-DobbViSh.js} +0 -0
package/payload/server/server.js
CHANGED
|
@@ -2485,7 +2485,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
|
|
|
2485
2485
|
});
|
|
2486
2486
|
if (!chunk) {
|
|
2487
2487
|
if (i === 1) {
|
|
2488
|
-
await new Promise((
|
|
2488
|
+
await new Promise((resolve19) => setTimeout(resolve19));
|
|
2489
2489
|
maxReadCount = 3;
|
|
2490
2490
|
continue;
|
|
2491
2491
|
}
|
|
@@ -2851,8 +2851,8 @@ var serveStatic = (options = { root: "" }) => {
|
|
|
2851
2851
|
};
|
|
2852
2852
|
|
|
2853
2853
|
// server/index.ts
|
|
2854
|
-
import { readFileSync as
|
|
2855
|
-
import { resolve as
|
|
2854
|
+
import { readFileSync as readFileSync20, existsSync as existsSync20, watchFile } from "fs";
|
|
2855
|
+
import { resolve as resolve18, join as join9, basename as basename4 } from "path";
|
|
2856
2856
|
import { homedir as homedir3 } from "os";
|
|
2857
2857
|
|
|
2858
2858
|
// app/api/health/route.ts
|
|
@@ -3091,20 +3091,20 @@ async function probeApiKey() {
|
|
|
3091
3091
|
}
|
|
3092
3092
|
}
|
|
3093
3093
|
function checkPort(port2, timeoutMs = 500) {
|
|
3094
|
-
return new Promise((
|
|
3094
|
+
return new Promise((resolve19) => {
|
|
3095
3095
|
const socket = createConnection(port2, "127.0.0.1");
|
|
3096
3096
|
socket.setTimeout(timeoutMs);
|
|
3097
3097
|
socket.once("connect", () => {
|
|
3098
3098
|
socket.destroy();
|
|
3099
|
-
|
|
3099
|
+
resolve19(true);
|
|
3100
3100
|
});
|
|
3101
3101
|
socket.once("error", () => {
|
|
3102
3102
|
socket.destroy();
|
|
3103
|
-
|
|
3103
|
+
resolve19(false);
|
|
3104
3104
|
});
|
|
3105
3105
|
socket.once("timeout", () => {
|
|
3106
3106
|
socket.destroy();
|
|
3107
|
-
|
|
3107
|
+
resolve19(false);
|
|
3108
3108
|
});
|
|
3109
3109
|
});
|
|
3110
3110
|
}
|
|
@@ -3668,7 +3668,7 @@ ${userContent}`;
|
|
|
3668
3668
|
"dontAsk",
|
|
3669
3669
|
prompt
|
|
3670
3670
|
];
|
|
3671
|
-
return new Promise((
|
|
3671
|
+
return new Promise((resolve19) => {
|
|
3672
3672
|
let stdout = "";
|
|
3673
3673
|
let stderr = "";
|
|
3674
3674
|
const spawnFn = _spawnOverride ?? spawn;
|
|
@@ -3686,35 +3686,35 @@ ${userContent}`;
|
|
|
3686
3686
|
const timer = setTimeout(() => {
|
|
3687
3687
|
proc.kill("SIGTERM");
|
|
3688
3688
|
console.error("[persist] autoLabel: haiku subprocess timed out");
|
|
3689
|
-
|
|
3689
|
+
resolve19(null);
|
|
3690
3690
|
}, SESSION_LABEL_TIMEOUT_MS);
|
|
3691
3691
|
proc.on("error", (err) => {
|
|
3692
3692
|
clearTimeout(timer);
|
|
3693
3693
|
console.error(`[persist] autoLabel: subprocess error \u2014 ${err.message}`);
|
|
3694
|
-
|
|
3694
|
+
resolve19(null);
|
|
3695
3695
|
});
|
|
3696
3696
|
proc.on("close", (code) => {
|
|
3697
3697
|
clearTimeout(timer);
|
|
3698
3698
|
if (code !== 0) {
|
|
3699
3699
|
console.error(`[persist] autoLabel: subprocess exited code=${code}${stderr ? ` stderr=${stderr.trim().slice(0, 200)}` : ""}`);
|
|
3700
|
-
|
|
3700
|
+
resolve19(null);
|
|
3701
3701
|
return;
|
|
3702
3702
|
}
|
|
3703
3703
|
const text = stdout.trim();
|
|
3704
3704
|
if (!text) {
|
|
3705
3705
|
console.error("[persist] autoLabel: haiku returned empty response");
|
|
3706
|
-
|
|
3706
|
+
resolve19(null);
|
|
3707
3707
|
return;
|
|
3708
3708
|
}
|
|
3709
3709
|
if (text === "SKIP") {
|
|
3710
3710
|
console.error("[persist] autoLabel: haiku returned SKIP \u2014 messages too vague");
|
|
3711
|
-
|
|
3711
|
+
resolve19(null);
|
|
3712
3712
|
return;
|
|
3713
3713
|
}
|
|
3714
3714
|
const words = text.split(/\s+/).slice(0, SESSION_LABEL_MAX_WORDS);
|
|
3715
3715
|
const label = words.join(" ");
|
|
3716
3716
|
console.error(`[persist] autoLabel: haiku response="${label}"`);
|
|
3717
|
-
|
|
3717
|
+
resolve19(label);
|
|
3718
3718
|
});
|
|
3719
3719
|
});
|
|
3720
3720
|
}
|
|
@@ -5102,7 +5102,7 @@ function getMcpServers(accountId, enabledPlugins) {
|
|
|
5102
5102
|
// the always-on Chromium instance started by vnc.sh on display :99.
|
|
5103
5103
|
"plugin_playwright_playwright": {
|
|
5104
5104
|
command: "npx",
|
|
5105
|
-
args: ["-y", "@playwright/mcp@latest", "--cdp-endpoint", "http://127.0.0.1:9222"]
|
|
5105
|
+
args: ["-y", "@playwright/mcp@latest", "--cdp-endpoint", "http://127.0.0.1:9222", "--caps", "pdf"]
|
|
5106
5106
|
}
|
|
5107
5107
|
};
|
|
5108
5108
|
if (process.env.TELEGRAM_PUBLIC_BOT_TOKEN) {
|
|
@@ -5345,7 +5345,7 @@ async function fetchMemoryContext(accountId, query, sessionKey, options) {
|
|
|
5345
5345
|
return null;
|
|
5346
5346
|
}
|
|
5347
5347
|
const startMs = Date.now();
|
|
5348
|
-
return new Promise((
|
|
5348
|
+
return new Promise((resolve19) => {
|
|
5349
5349
|
const proc = spawn2(process.execPath, [serverPath], {
|
|
5350
5350
|
env: {
|
|
5351
5351
|
...process.env,
|
|
@@ -5374,7 +5374,7 @@ async function fetchMemoryContext(accountId, query, sessionKey, options) {
|
|
|
5374
5374
|
} else {
|
|
5375
5375
|
console.error(`[fetchMemoryContext] failed: ${reason} (${elapsed}ms)${stderrBuf ? ` stderr: ${stderrBuf.slice(0, 500)}` : ""}`);
|
|
5376
5376
|
}
|
|
5377
|
-
|
|
5377
|
+
resolve19(value);
|
|
5378
5378
|
};
|
|
5379
5379
|
proc.stdout.on("data", (chunk) => {
|
|
5380
5380
|
buffer += chunk.toString();
|
|
@@ -7885,10 +7885,10 @@ var SCRYPT_R = 8;
|
|
|
7885
7885
|
var SCRYPT_P = 1;
|
|
7886
7886
|
var SCRYPT_KEYLEN = 64;
|
|
7887
7887
|
function scryptAsync(password, salt) {
|
|
7888
|
-
return new Promise((
|
|
7888
|
+
return new Promise((resolve19, reject) => {
|
|
7889
7889
|
scrypt(password, salt, SCRYPT_KEYLEN, { N: SCRYPT_N, r: SCRYPT_R, p: SCRYPT_P }, (err, key) => {
|
|
7890
7890
|
if (err) reject(err);
|
|
7891
|
-
else
|
|
7891
|
+
else resolve19(key);
|
|
7892
7892
|
});
|
|
7893
7893
|
});
|
|
7894
7894
|
}
|
|
@@ -9441,7 +9441,7 @@ var credsSaveQueue = Promise.resolve();
|
|
|
9441
9441
|
async function drainCredsSaveQueue(timeoutMs = 5e3) {
|
|
9442
9442
|
console.error(`${TAG2} draining credential save queue\u2026`);
|
|
9443
9443
|
const timer = new Promise(
|
|
9444
|
-
(
|
|
9444
|
+
(resolve19) => setTimeout(() => resolve19("timeout"), timeoutMs)
|
|
9445
9445
|
);
|
|
9446
9446
|
const result = await Promise.race([
|
|
9447
9447
|
credsSaveQueue.then(() => "drained"),
|
|
@@ -9582,11 +9582,11 @@ async function createWaSocket(opts) {
|
|
|
9582
9582
|
return sock;
|
|
9583
9583
|
}
|
|
9584
9584
|
async function waitForConnection(sock) {
|
|
9585
|
-
return new Promise((
|
|
9585
|
+
return new Promise((resolve19, reject) => {
|
|
9586
9586
|
const handler = (update) => {
|
|
9587
9587
|
if (update.connection === "open") {
|
|
9588
9588
|
sock.ev.off("connection.update", handler);
|
|
9589
|
-
|
|
9589
|
+
resolve19();
|
|
9590
9590
|
}
|
|
9591
9591
|
if (update.connection === "close") {
|
|
9592
9592
|
sock.ev.off("connection.update", handler);
|
|
@@ -9771,8 +9771,8 @@ async function startLogin(opts) {
|
|
|
9771
9771
|
resetActiveLogin(accountId);
|
|
9772
9772
|
let resolveQr = null;
|
|
9773
9773
|
let rejectQr = null;
|
|
9774
|
-
const qrPromise = new Promise((
|
|
9775
|
-
resolveQr =
|
|
9774
|
+
const qrPromise = new Promise((resolve19, reject) => {
|
|
9775
|
+
resolveQr = resolve19;
|
|
9776
9776
|
rejectQr = reject;
|
|
9777
9777
|
});
|
|
9778
9778
|
const qrTimer = setTimeout(
|
|
@@ -24755,11 +24755,11 @@ async function connectWithReconnect(conn) {
|
|
|
24755
24755
|
}
|
|
24756
24756
|
const delay = computeBackoff(conn.reconnectAttempts);
|
|
24757
24757
|
console.error(`${TAG8} reconnecting account=${conn.accountId} in ${delay}ms (attempt ${conn.reconnectAttempts}/${maxAttempts})`);
|
|
24758
|
-
await new Promise((
|
|
24759
|
-
const timer = setTimeout(
|
|
24758
|
+
await new Promise((resolve19) => {
|
|
24759
|
+
const timer = setTimeout(resolve19, delay);
|
|
24760
24760
|
conn.abortController.signal.addEventListener("abort", () => {
|
|
24761
24761
|
clearTimeout(timer);
|
|
24762
|
-
|
|
24762
|
+
resolve19();
|
|
24763
24763
|
}, { once: true });
|
|
24764
24764
|
});
|
|
24765
24765
|
if (conn.abortController.signal.aborted) return;
|
|
@@ -24767,14 +24767,14 @@ async function connectWithReconnect(conn) {
|
|
|
24767
24767
|
}
|
|
24768
24768
|
}
|
|
24769
24769
|
function waitForDisconnectEvent(conn) {
|
|
24770
|
-
return new Promise((
|
|
24770
|
+
return new Promise((resolve19) => {
|
|
24771
24771
|
if (!conn.sock) {
|
|
24772
|
-
|
|
24772
|
+
resolve19();
|
|
24773
24773
|
return;
|
|
24774
24774
|
}
|
|
24775
24775
|
conn.sock.ev.on("connection.update", (update) => {
|
|
24776
24776
|
if (update.connection === "close") {
|
|
24777
|
-
|
|
24777
|
+
resolve19();
|
|
24778
24778
|
}
|
|
24779
24779
|
});
|
|
24780
24780
|
});
|
|
@@ -25163,6 +25163,8 @@ function serializeWhatsAppSchema() {
|
|
|
25163
25163
|
}
|
|
25164
25164
|
|
|
25165
25165
|
// app/api/whatsapp/config/route.ts
|
|
25166
|
+
import { resolve as resolve10 } from "path";
|
|
25167
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync11, existsSync as existsSync11 } from "fs";
|
|
25166
25168
|
async function POST14(req) {
|
|
25167
25169
|
try {
|
|
25168
25170
|
const body = await req.json().catch(() => ({}));
|
|
@@ -25209,6 +25211,30 @@ async function POST14(req) {
|
|
|
25209
25211
|
console.error(`[whatsapp:api] config action=get-public-agent slug=${currentSlug ?? "none"}`);
|
|
25210
25212
|
return Response.json({ ok: true, slug: currentSlug });
|
|
25211
25213
|
}
|
|
25214
|
+
case "list-public-agents": {
|
|
25215
|
+
const agentsDir = resolve10(account.accountDir, "agents");
|
|
25216
|
+
const agents = [];
|
|
25217
|
+
if (existsSync11(agentsDir)) {
|
|
25218
|
+
try {
|
|
25219
|
+
const entries = readdirSync2(agentsDir, { withFileTypes: true });
|
|
25220
|
+
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
25221
|
+
if (!entry.isDirectory() || entry.name === "admin") continue;
|
|
25222
|
+
const configPath2 = resolve10(agentsDir, entry.name, "config.json");
|
|
25223
|
+
if (!existsSync11(configPath2)) continue;
|
|
25224
|
+
try {
|
|
25225
|
+
const config2 = JSON.parse(readFileSync11(configPath2, "utf-8"));
|
|
25226
|
+
agents.push({ slug: entry.name, displayName: config2.displayName ?? entry.name });
|
|
25227
|
+
} catch {
|
|
25228
|
+
console.error(`[whatsapp:api] config action=list-public-agents error="failed to parse config.json for agent ${entry.name}" \u2014 skipping`);
|
|
25229
|
+
}
|
|
25230
|
+
}
|
|
25231
|
+
} catch (err) {
|
|
25232
|
+
console.error(`[whatsapp:api] config action=list-public-agents error="failed to scan agents directory: ${String(err)}"`);
|
|
25233
|
+
}
|
|
25234
|
+
}
|
|
25235
|
+
console.error(`[whatsapp:api] config action=list-public-agents count=${agents.length}`);
|
|
25236
|
+
return Response.json({ ok: true, agents });
|
|
25237
|
+
}
|
|
25212
25238
|
case "schema": {
|
|
25213
25239
|
const text = serializeWhatsAppSchema();
|
|
25214
25240
|
console.error(`[whatsapp:api] config action=schema`);
|
|
@@ -25251,7 +25277,7 @@ async function POST14(req) {
|
|
|
25251
25277
|
}
|
|
25252
25278
|
default:
|
|
25253
25279
|
return Response.json(
|
|
25254
|
-
{ ok: false, error: `Unknown action "${action}". Valid actions: add-admin-phone, remove-admin-phone, list-admin-phones, set-public-agent, get-public-agent, update-config, get-config, schema, list-groups.` },
|
|
25280
|
+
{ ok: false, error: `Unknown action "${action}". Valid actions: add-admin-phone, remove-admin-phone, list-admin-phones, set-public-agent, get-public-agent, list-public-agents, update-config, get-config, schema, list-groups.` },
|
|
25255
25281
|
{ status: 400 }
|
|
25256
25282
|
);
|
|
25257
25283
|
}
|
|
@@ -25264,7 +25290,7 @@ async function POST14(req) {
|
|
|
25264
25290
|
// app/api/whatsapp/send-document/route.ts
|
|
25265
25291
|
import { readFile as readFile2, stat as stat2 } from "fs/promises";
|
|
25266
25292
|
import { realpathSync as realpathSync2 } from "fs";
|
|
25267
|
-
import { resolve as
|
|
25293
|
+
import { resolve as resolve11, basename as basename2 } from "path";
|
|
25268
25294
|
var TAG9 = "[whatsapp:api]";
|
|
25269
25295
|
var PLATFORM_ROOT6 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
25270
25296
|
async function POST15(req) {
|
|
@@ -25281,7 +25307,7 @@ async function POST15(req) {
|
|
|
25281
25307
|
{ status: 400 }
|
|
25282
25308
|
);
|
|
25283
25309
|
}
|
|
25284
|
-
const accountDir =
|
|
25310
|
+
const accountDir = resolve11(PLATFORM_ROOT6, "..", "data/accounts", maxyAccountId);
|
|
25285
25311
|
let resolvedPath;
|
|
25286
25312
|
try {
|
|
25287
25313
|
resolvedPath = realpathSync2(filePath);
|
|
@@ -25444,13 +25470,13 @@ async function POST17(req) {
|
|
|
25444
25470
|
}
|
|
25445
25471
|
|
|
25446
25472
|
// app/api/onboarding/set-pin/route.ts
|
|
25447
|
-
import { existsSync as
|
|
25473
|
+
import { existsSync as existsSync12, writeFileSync as writeFileSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync12, unlinkSync as unlinkSync2 } from "fs";
|
|
25448
25474
|
import { createHash } from "crypto";
|
|
25449
25475
|
function hashPin(pin) {
|
|
25450
25476
|
return createHash("sha256").update(pin).digest("hex");
|
|
25451
25477
|
}
|
|
25452
25478
|
async function POST18(req) {
|
|
25453
|
-
if (
|
|
25479
|
+
if (existsSync12(PIN_FILE)) {
|
|
25454
25480
|
return Response.json(
|
|
25455
25481
|
{ error: "PIN is already configured." },
|
|
25456
25482
|
{ status: 409 }
|
|
@@ -25475,7 +25501,7 @@ async function POST18(req) {
|
|
|
25475
25501
|
return Response.json({ ok: true });
|
|
25476
25502
|
}
|
|
25477
25503
|
async function DELETE(req) {
|
|
25478
|
-
if (!
|
|
25504
|
+
if (!existsSync12(PIN_FILE)) {
|
|
25479
25505
|
return Response.json({ error: "No PIN configured." }, { status: 404 });
|
|
25480
25506
|
}
|
|
25481
25507
|
let body;
|
|
@@ -25487,7 +25513,7 @@ async function DELETE(req) {
|
|
|
25487
25513
|
if (!body.currentPin) {
|
|
25488
25514
|
return Response.json({ error: "Current PIN required." }, { status: 400 });
|
|
25489
25515
|
}
|
|
25490
|
-
const storedHash =
|
|
25516
|
+
const storedHash = readFileSync12(PIN_FILE, "utf-8").trim();
|
|
25491
25517
|
if (hashPin(body.currentPin) !== storedHash) {
|
|
25492
25518
|
return Response.json({ error: "Current PIN is incorrect." }, { status: 401 });
|
|
25493
25519
|
}
|
|
@@ -25496,14 +25522,14 @@ async function DELETE(req) {
|
|
|
25496
25522
|
}
|
|
25497
25523
|
|
|
25498
25524
|
// app/api/admin/session/route.ts
|
|
25499
|
-
import { readFileSync as
|
|
25525
|
+
import { readFileSync as readFileSync13, existsSync as existsSync13 } from "fs";
|
|
25500
25526
|
import { createHash as createHash2 } from "crypto";
|
|
25501
25527
|
function hashPin2(pin) {
|
|
25502
25528
|
return createHash2("sha256").update(pin).digest("hex");
|
|
25503
25529
|
}
|
|
25504
25530
|
function getStoredPinHash() {
|
|
25505
|
-
if (
|
|
25506
|
-
return
|
|
25531
|
+
if (existsSync13(PIN_FILE)) {
|
|
25532
|
+
return readFileSync13(PIN_FILE, "utf-8").trim();
|
|
25507
25533
|
}
|
|
25508
25534
|
return null;
|
|
25509
25535
|
}
|
|
@@ -25548,7 +25574,7 @@ async function POST19(req) {
|
|
|
25548
25574
|
}
|
|
25549
25575
|
|
|
25550
25576
|
// app/api/admin/chat/route.ts
|
|
25551
|
-
import { existsSync as
|
|
25577
|
+
import { existsSync as existsSync14, readFileSync as readFileSync14, writeFileSync as writeFileSync9, mkdirSync as mkdirSync6 } from "fs";
|
|
25552
25578
|
import { dirname as dirname2 } from "path";
|
|
25553
25579
|
function isComponentDone(parsed) {
|
|
25554
25580
|
return typeof parsed === "object" && parsed !== null && parsed._componentDone === true && typeof parsed.component === "string" && typeof parsed.payload === "string";
|
|
@@ -25576,7 +25602,7 @@ ${inner.content}`;
|
|
|
25576
25602
|
}
|
|
25577
25603
|
var VOLATILE_STATE_FILE = "/tmp/maxy-agent-create-state.json";
|
|
25578
25604
|
function advanceGateIfNeeded(envelope, accountDir, logFn) {
|
|
25579
|
-
if (!
|
|
25605
|
+
if (!existsSync14(VOLATILE_STATE_FILE)) return;
|
|
25580
25606
|
const { component, payload } = envelope;
|
|
25581
25607
|
let gateFlag = null;
|
|
25582
25608
|
let agentSlug = "";
|
|
@@ -25598,7 +25624,7 @@ function advanceGateIfNeeded(envelope, accountDir, logFn) {
|
|
|
25598
25624
|
if (!gateFlag) return;
|
|
25599
25625
|
let state;
|
|
25600
25626
|
try {
|
|
25601
|
-
state = JSON.parse(
|
|
25627
|
+
state = JSON.parse(readFileSync14(VOLATILE_STATE_FILE, "utf-8"));
|
|
25602
25628
|
} catch (err) {
|
|
25603
25629
|
logFn(`ERROR \u2014 failed to read state file for advancement: ${err instanceof Error ? err.message : String(err)}`);
|
|
25604
25630
|
return;
|
|
@@ -25891,8 +25917,8 @@ async function POST21(req) {
|
|
|
25891
25917
|
}
|
|
25892
25918
|
|
|
25893
25919
|
// app/api/admin/logs/route.ts
|
|
25894
|
-
import { existsSync as
|
|
25895
|
-
import { resolve as
|
|
25920
|
+
import { existsSync as existsSync15, readdirSync as readdirSync3, readFileSync as readFileSync15, statSync as statSync3 } from "fs";
|
|
25921
|
+
import { resolve as resolve12, basename as basename3 } from "path";
|
|
25896
25922
|
var TAIL_BYTES = 8192;
|
|
25897
25923
|
async function GET4(request) {
|
|
25898
25924
|
const { searchParams } = new URL(request.url);
|
|
@@ -25900,14 +25926,14 @@ async function GET4(request) {
|
|
|
25900
25926
|
const typeParam = searchParams.get("type");
|
|
25901
25927
|
const download = searchParams.get("download") === "1";
|
|
25902
25928
|
const account = resolveAccount();
|
|
25903
|
-
const accountLogDir = account ?
|
|
25929
|
+
const accountLogDir = account ? resolve12(account.accountDir, "logs") : null;
|
|
25904
25930
|
if (fileParam) {
|
|
25905
25931
|
const safe = basename3(fileParam);
|
|
25906
25932
|
for (const dir of [accountLogDir, LOG_DIR]) {
|
|
25907
25933
|
if (!dir) continue;
|
|
25908
|
-
const filePath =
|
|
25934
|
+
const filePath = resolve12(dir, safe);
|
|
25909
25935
|
try {
|
|
25910
|
-
const content =
|
|
25936
|
+
const content = readFileSync15(filePath, "utf-8");
|
|
25911
25937
|
const headers = { "Content-Type": "text/plain; charset=utf-8" };
|
|
25912
25938
|
if (download) headers["Content-Disposition"] = `attachment; filename="${safe}"`;
|
|
25913
25939
|
return new Response(content, { headers });
|
|
@@ -25931,9 +25957,9 @@ async function GET4(request) {
|
|
|
25931
25957
|
}
|
|
25932
25958
|
for (const dir of [accountLogDir, LOG_DIR]) {
|
|
25933
25959
|
if (!dir) continue;
|
|
25934
|
-
const filePath =
|
|
25960
|
+
const filePath = resolve12(dir, fileName);
|
|
25935
25961
|
try {
|
|
25936
|
-
const content =
|
|
25962
|
+
const content = readFileSync15(filePath, "utf-8");
|
|
25937
25963
|
const headers = { "Content-Type": "text/plain; charset=utf-8" };
|
|
25938
25964
|
if (download) headers["Content-Disposition"] = `attachment; filename="${fileName}"`;
|
|
25939
25965
|
return new Response(content, { headers });
|
|
@@ -25945,17 +25971,17 @@ async function GET4(request) {
|
|
|
25945
25971
|
const seen = /* @__PURE__ */ new Set();
|
|
25946
25972
|
const logs = {};
|
|
25947
25973
|
for (const dir of [accountLogDir, LOG_DIR]) {
|
|
25948
|
-
if (!dir || !
|
|
25974
|
+
if (!dir || !existsSync15(dir)) continue;
|
|
25949
25975
|
let files;
|
|
25950
25976
|
try {
|
|
25951
|
-
files =
|
|
25977
|
+
files = readdirSync3(dir).filter((f) => f.endsWith(".log"));
|
|
25952
25978
|
} catch {
|
|
25953
25979
|
continue;
|
|
25954
25980
|
}
|
|
25955
|
-
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync3(
|
|
25981
|
+
files.filter((f) => !seen.has(f)).map((f) => ({ name: f, mtime: statSync3(resolve12(dir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime).forEach(({ name }) => {
|
|
25956
25982
|
seen.add(name);
|
|
25957
25983
|
try {
|
|
25958
|
-
const content =
|
|
25984
|
+
const content = readFileSync15(resolve12(dir, name));
|
|
25959
25985
|
const tail = content.length > TAIL_BYTES ? content.subarray(content.length - TAIL_BYTES).toString("utf-8") : content.toString("utf-8");
|
|
25960
25986
|
logs[name] = tail.trim() || "(empty)";
|
|
25961
25987
|
} catch {
|
|
@@ -25990,8 +26016,8 @@ async function GET5() {
|
|
|
25990
26016
|
|
|
25991
26017
|
// app/api/admin/attachment/[attachmentId]/route.ts
|
|
25992
26018
|
import { readFile as readFile3, readdir } from "fs/promises";
|
|
25993
|
-
import { existsSync as
|
|
25994
|
-
import { resolve as
|
|
26019
|
+
import { existsSync as existsSync16 } from "fs";
|
|
26020
|
+
import { resolve as resolve13 } from "path";
|
|
25995
26021
|
async function GET6(req, attachmentId) {
|
|
25996
26022
|
const sessionKey = new URL(req.url).searchParams.get("session_key") ?? "";
|
|
25997
26023
|
if (!validateSession(sessionKey, "admin")) {
|
|
@@ -26004,12 +26030,12 @@ async function GET6(req, attachmentId) {
|
|
|
26004
26030
|
if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/.test(attachmentId)) {
|
|
26005
26031
|
return new Response("Not found", { status: 404 });
|
|
26006
26032
|
}
|
|
26007
|
-
const dir =
|
|
26008
|
-
if (!
|
|
26033
|
+
const dir = resolve13(ATTACHMENTS_ROOT, accountId, attachmentId);
|
|
26034
|
+
if (!existsSync16(dir)) {
|
|
26009
26035
|
return new Response("Not found", { status: 404 });
|
|
26010
26036
|
}
|
|
26011
|
-
const metaPath =
|
|
26012
|
-
if (!
|
|
26037
|
+
const metaPath = resolve13(dir, `${attachmentId}.meta.json`);
|
|
26038
|
+
if (!existsSync16(metaPath)) {
|
|
26013
26039
|
return new Response("Not found", { status: 404 });
|
|
26014
26040
|
}
|
|
26015
26041
|
let meta3;
|
|
@@ -26023,7 +26049,7 @@ async function GET6(req, attachmentId) {
|
|
|
26023
26049
|
if (!dataFile) {
|
|
26024
26050
|
return new Response("Not found", { status: 404 });
|
|
26025
26051
|
}
|
|
26026
|
-
const filePath =
|
|
26052
|
+
const filePath = resolve13(dir, dataFile);
|
|
26027
26053
|
const buffer = await readFile3(filePath);
|
|
26028
26054
|
return new Response(buffer, {
|
|
26029
26055
|
headers: {
|
|
@@ -26035,8 +26061,8 @@ async function GET6(req, attachmentId) {
|
|
|
26035
26061
|
}
|
|
26036
26062
|
|
|
26037
26063
|
// app/api/admin/account/route.ts
|
|
26038
|
-
import { readFileSync as
|
|
26039
|
-
import { resolve as
|
|
26064
|
+
import { readFileSync as readFileSync16, writeFileSync as writeFileSync10 } from "fs";
|
|
26065
|
+
import { resolve as resolve14 } from "path";
|
|
26040
26066
|
var VALID_CONTEXT_MODES = ["managed", "claude-code"];
|
|
26041
26067
|
async function PATCH(req) {
|
|
26042
26068
|
let body;
|
|
@@ -26059,9 +26085,9 @@ async function PATCH(req) {
|
|
|
26059
26085
|
if (!account) {
|
|
26060
26086
|
return Response.json({ error: "No account configured" }, { status: 500 });
|
|
26061
26087
|
}
|
|
26062
|
-
const configPath2 =
|
|
26088
|
+
const configPath2 = resolve14(account.accountDir, "account.json");
|
|
26063
26089
|
try {
|
|
26064
|
-
const raw2 =
|
|
26090
|
+
const raw2 = readFileSync16(configPath2, "utf-8");
|
|
26065
26091
|
const config2 = JSON.parse(raw2);
|
|
26066
26092
|
config2.contextMode = contextMode;
|
|
26067
26093
|
writeFileSync10(configPath2, JSON.stringify(config2, null, 2) + "\n", "utf-8");
|
|
@@ -26074,27 +26100,27 @@ async function PATCH(req) {
|
|
|
26074
26100
|
}
|
|
26075
26101
|
|
|
26076
26102
|
// app/api/admin/agents/route.ts
|
|
26077
|
-
import { resolve as
|
|
26078
|
-
import { readdirSync as
|
|
26103
|
+
import { resolve as resolve15 } from "path";
|
|
26104
|
+
import { readdirSync as readdirSync4, readFileSync as readFileSync17, existsSync as existsSync17 } from "fs";
|
|
26079
26105
|
async function GET7() {
|
|
26080
26106
|
const account = resolveAccount();
|
|
26081
26107
|
if (!account) {
|
|
26082
26108
|
return Response.json({ agents: [] });
|
|
26083
26109
|
}
|
|
26084
|
-
const agentsDir =
|
|
26085
|
-
if (!
|
|
26110
|
+
const agentsDir = resolve15(account.accountDir, "agents");
|
|
26111
|
+
if (!existsSync17(agentsDir)) {
|
|
26086
26112
|
return Response.json({ agents: [] });
|
|
26087
26113
|
}
|
|
26088
26114
|
const agents = [];
|
|
26089
26115
|
try {
|
|
26090
|
-
const entries =
|
|
26116
|
+
const entries = readdirSync4(agentsDir, { withFileTypes: true });
|
|
26091
26117
|
for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
|
|
26092
26118
|
if (!entry.isDirectory()) continue;
|
|
26093
26119
|
if (entry.name === "admin") continue;
|
|
26094
|
-
const configPath2 =
|
|
26095
|
-
if (!
|
|
26120
|
+
const configPath2 = resolve15(agentsDir, entry.name, "config.json");
|
|
26121
|
+
if (!existsSync17(configPath2)) continue;
|
|
26096
26122
|
try {
|
|
26097
|
-
const config2 = JSON.parse(
|
|
26123
|
+
const config2 = JSON.parse(readFileSync17(configPath2, "utf-8"));
|
|
26098
26124
|
agents.push({
|
|
26099
26125
|
slug: entry.name,
|
|
26100
26126
|
displayName: config2.displayName ?? entry.name,
|
|
@@ -26112,29 +26138,29 @@ async function GET7() {
|
|
|
26112
26138
|
}
|
|
26113
26139
|
|
|
26114
26140
|
// app/api/admin/version/route.ts
|
|
26115
|
-
import { readFileSync as
|
|
26116
|
-
import { resolve as
|
|
26117
|
-
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ??
|
|
26141
|
+
import { readFileSync as readFileSync18, existsSync as existsSync18 } from "fs";
|
|
26142
|
+
import { resolve as resolve16, join as join7 } from "path";
|
|
26143
|
+
var PLATFORM_ROOT7 = process.env.MAXY_PLATFORM_ROOT ?? resolve16(process.cwd(), "..");
|
|
26118
26144
|
var brandHostname = "maxy";
|
|
26119
26145
|
var brandNpmPackage = "@rubytech/create-maxy";
|
|
26120
26146
|
var brandJsonPath = join7(PLATFORM_ROOT7, "config", "brand.json");
|
|
26121
|
-
if (
|
|
26147
|
+
if (existsSync18(brandJsonPath)) {
|
|
26122
26148
|
try {
|
|
26123
|
-
const brand = JSON.parse(
|
|
26149
|
+
const brand = JSON.parse(readFileSync18(brandJsonPath, "utf-8"));
|
|
26124
26150
|
if (brand.hostname) brandHostname = brand.hostname;
|
|
26125
26151
|
if (brand.npm?.packageName) brandNpmPackage = brand.npm.packageName;
|
|
26126
26152
|
} catch {
|
|
26127
26153
|
}
|
|
26128
26154
|
}
|
|
26129
|
-
var VERSION_FILE =
|
|
26155
|
+
var VERSION_FILE = resolve16(PLATFORM_ROOT7, `config/.${brandHostname}-version`);
|
|
26130
26156
|
var NPM_PACKAGE = brandNpmPackage;
|
|
26131
26157
|
var REGISTRY_URL = `https://registry.npmjs.org/${NPM_PACKAGE}/latest`;
|
|
26132
26158
|
var CACHE_TTL_MS = 60 * 60 * 1e3;
|
|
26133
26159
|
var FETCH_TIMEOUT_MS = 5e3;
|
|
26134
26160
|
var latestCache = null;
|
|
26135
26161
|
function readInstalled() {
|
|
26136
|
-
if (!
|
|
26137
|
-
const content =
|
|
26162
|
+
if (!existsSync18(VERSION_FILE)) return "unknown";
|
|
26163
|
+
const content = readFileSync18(VERSION_FILE, "utf-8").trim();
|
|
26138
26164
|
return content || "unknown";
|
|
26139
26165
|
}
|
|
26140
26166
|
async function fetchLatest() {
|
|
@@ -26188,15 +26214,15 @@ async function GET8() {
|
|
|
26188
26214
|
|
|
26189
26215
|
// app/api/admin/version/upgrade/route.ts
|
|
26190
26216
|
import { spawn as spawn4 } from "child_process";
|
|
26191
|
-
import { existsSync as
|
|
26192
|
-
import { resolve as
|
|
26193
|
-
var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT ??
|
|
26217
|
+
import { existsSync as existsSync19, statSync as statSync4, writeFileSync as writeFileSync11, readFileSync as readFileSync19, openSync as openSync2, closeSync as closeSync2 } from "fs";
|
|
26218
|
+
import { resolve as resolve17, join as join8 } from "path";
|
|
26219
|
+
var PLATFORM_ROOT8 = process.env.MAXY_PLATFORM_ROOT ?? resolve17(process.cwd(), "..");
|
|
26194
26220
|
var upgradePkg = "@rubytech/create-maxy";
|
|
26195
26221
|
var upgradeHostname = "maxy";
|
|
26196
26222
|
var brandPath = join8(PLATFORM_ROOT8, "config", "brand.json");
|
|
26197
|
-
if (
|
|
26223
|
+
if (existsSync19(brandPath)) {
|
|
26198
26224
|
try {
|
|
26199
|
-
const brand = JSON.parse(
|
|
26225
|
+
const brand = JSON.parse(readFileSync19(brandPath, "utf-8"));
|
|
26200
26226
|
if (brand.npm?.packageName) upgradePkg = brand.npm.packageName;
|
|
26201
26227
|
if (brand.hostname) upgradeHostname = brand.hostname;
|
|
26202
26228
|
} catch {
|
|
@@ -26206,7 +26232,7 @@ var LOCK_FILE = `/tmp/${upgradeHostname}-upgrade.lock`;
|
|
|
26206
26232
|
var LOG_FILE = `/tmp/${upgradeHostname}-upgrade.log`;
|
|
26207
26233
|
var LOCK_MAX_AGE_MS = 3 * 60 * 1e3;
|
|
26208
26234
|
function isLockFresh() {
|
|
26209
|
-
if (!
|
|
26235
|
+
if (!existsSync19(LOCK_FILE)) return false;
|
|
26210
26236
|
try {
|
|
26211
26237
|
const stat3 = statSync4(LOCK_FILE);
|
|
26212
26238
|
return Date.now() - stat3.mtimeMs < LOCK_MAX_AGE_MS;
|
|
@@ -26243,7 +26269,7 @@ async function POST22(req) {
|
|
|
26243
26269
|
detached: true,
|
|
26244
26270
|
stdio: ["ignore", logFd, logFd],
|
|
26245
26271
|
env: { ...process.env, npm_config_yes: "true" },
|
|
26246
|
-
cwd:
|
|
26272
|
+
cwd: resolve17(process.cwd(), "..")
|
|
26247
26273
|
});
|
|
26248
26274
|
child.unref();
|
|
26249
26275
|
closeSync2(logFd);
|
|
@@ -26362,12 +26388,12 @@ async function POST23() {
|
|
|
26362
26388
|
var PLATFORM_ROOT9 = process.env.MAXY_PLATFORM_ROOT || "";
|
|
26363
26389
|
var BRAND_JSON_PATH = PLATFORM_ROOT9 ? join9(PLATFORM_ROOT9, "config", "brand.json") : "";
|
|
26364
26390
|
var BRAND = { productName: "Maxy", hostname: "maxy", configDir: ".maxy", domain: "getmaxy.com" };
|
|
26365
|
-
if (BRAND_JSON_PATH && !
|
|
26391
|
+
if (BRAND_JSON_PATH && !existsSync20(BRAND_JSON_PATH)) {
|
|
26366
26392
|
console.error(`[brand] WARNING: brand.json not found at ${BRAND_JSON_PATH} \u2014 using Maxy defaults`);
|
|
26367
26393
|
}
|
|
26368
|
-
if (BRAND_JSON_PATH &&
|
|
26394
|
+
if (BRAND_JSON_PATH && existsSync20(BRAND_JSON_PATH)) {
|
|
26369
26395
|
try {
|
|
26370
|
-
const parsed = JSON.parse(
|
|
26396
|
+
const parsed = JSON.parse(readFileSync20(BRAND_JSON_PATH, "utf-8"));
|
|
26371
26397
|
BRAND = { ...BRAND, ...parsed };
|
|
26372
26398
|
} catch (err) {
|
|
26373
26399
|
console.error(`[brand] Failed to parse brand.json: ${err.message}`);
|
|
@@ -26382,8 +26408,8 @@ var brandLoginOpts = {
|
|
|
26382
26408
|
var ALIAS_DOMAINS_PATH = join9(homedir3(), BRAND.configDir, "alias-domains.json");
|
|
26383
26409
|
function loadAliasDomains() {
|
|
26384
26410
|
try {
|
|
26385
|
-
if (!
|
|
26386
|
-
const parsed = JSON.parse(
|
|
26411
|
+
if (!existsSync20(ALIAS_DOMAINS_PATH)) return null;
|
|
26412
|
+
const parsed = JSON.parse(readFileSync20(ALIAS_DOMAINS_PATH, "utf-8"));
|
|
26387
26413
|
if (!Array.isArray(parsed)) {
|
|
26388
26414
|
console.error("[alias-domains] malformed alias-domains.json \u2014 expected array");
|
|
26389
26415
|
return null;
|
|
@@ -26723,9 +26749,9 @@ app.get(
|
|
|
26723
26749
|
var htmlCache = /* @__PURE__ */ new Map();
|
|
26724
26750
|
var brandLogoPath = "/brand/maxy-monochrome.png";
|
|
26725
26751
|
var brandIconPath = "/brand/maxy-monochrome.png";
|
|
26726
|
-
if (BRAND_JSON_PATH &&
|
|
26752
|
+
if (BRAND_JSON_PATH && existsSync20(BRAND_JSON_PATH)) {
|
|
26727
26753
|
try {
|
|
26728
|
-
const fullBrand = JSON.parse(
|
|
26754
|
+
const fullBrand = JSON.parse(readFileSync20(BRAND_JSON_PATH, "utf-8"));
|
|
26729
26755
|
if (fullBrand.assets?.logo) brandLogoPath = `/brand/${fullBrand.assets.logo}`;
|
|
26730
26756
|
brandIconPath = fullBrand.assets?.icon ? `/brand/${fullBrand.assets.icon}` : brandLogoPath;
|
|
26731
26757
|
} catch {
|
|
@@ -26742,7 +26768,7 @@ var brandScript = `<script>window.__BRAND__=${JSON.stringify({
|
|
|
26742
26768
|
function cachedHtml(file2) {
|
|
26743
26769
|
let html = htmlCache.get(file2);
|
|
26744
26770
|
if (!html) {
|
|
26745
|
-
html =
|
|
26771
|
+
html = readFileSync20(resolve18(process.cwd(), "public", file2), "utf-8");
|
|
26746
26772
|
html = html.replace("</head>", `${brandScript}
|
|
26747
26773
|
</head>`);
|
|
26748
26774
|
htmlCache.set(file2, html);
|
|
@@ -26754,13 +26780,13 @@ function loadBrandingCache(agentSlug) {
|
|
|
26754
26780
|
const configDir2 = join9(homedir3(), BRAND.configDir);
|
|
26755
26781
|
try {
|
|
26756
26782
|
const accountJsonPath = join9(configDir2, "account.json");
|
|
26757
|
-
if (!
|
|
26758
|
-
const account = JSON.parse(
|
|
26783
|
+
if (!existsSync20(accountJsonPath)) return null;
|
|
26784
|
+
const account = JSON.parse(readFileSync20(accountJsonPath, "utf-8"));
|
|
26759
26785
|
const accountId = account.accountId;
|
|
26760
26786
|
if (!accountId) return null;
|
|
26761
26787
|
const cachePath = join9(configDir2, "branding-cache", accountId, `${agentSlug}.json`);
|
|
26762
|
-
if (!
|
|
26763
|
-
return JSON.parse(
|
|
26788
|
+
if (!existsSync20(cachePath)) return null;
|
|
26789
|
+
return JSON.parse(readFileSync20(cachePath, "utf-8"));
|
|
26764
26790
|
} catch {
|
|
26765
26791
|
return null;
|
|
26766
26792
|
}
|
|
@@ -26769,8 +26795,8 @@ function resolveDefaultSlug() {
|
|
|
26769
26795
|
try {
|
|
26770
26796
|
const configDir2 = join9(homedir3(), BRAND.configDir);
|
|
26771
26797
|
const accountJsonPath = join9(configDir2, "account.json");
|
|
26772
|
-
if (!
|
|
26773
|
-
const account = JSON.parse(
|
|
26798
|
+
if (!existsSync20(accountJsonPath)) return null;
|
|
26799
|
+
const account = JSON.parse(readFileSync20(accountJsonPath, "utf-8"));
|
|
26774
26800
|
return account.defaultAgent || null;
|
|
26775
26801
|
} catch {
|
|
26776
26802
|
return null;
|
|
@@ -26847,7 +26873,7 @@ if (bootAccountConfig?.whatsapp) {
|
|
|
26847
26873
|
}
|
|
26848
26874
|
init({
|
|
26849
26875
|
configDir: configDirForWhatsApp,
|
|
26850
|
-
platformRoot:
|
|
26876
|
+
platformRoot: resolve18(process.env.MAXY_PLATFORM_ROOT ?? join9(__dirname, "..")),
|
|
26851
26877
|
accountConfig: bootAccountConfig,
|
|
26852
26878
|
onMessage: async (msg) => {
|
|
26853
26879
|
try {
|